diff --git a/[refs] b/[refs] index 7b37efc5d27e..33cec1d4416b 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 9ba5aa3126873a9c29999b78de20a52c5f87d389 +refs/heads/master: 789fc0adbaf3a3ca95a3894aedacfc01863e8ae3 diff --git a/trunk/.gitignore b/trunk/.gitignore index 9eb4b7711499..e1d5c17c12c2 100644 --- a/trunk/.gitignore +++ b/trunk/.gitignore @@ -20,7 +20,6 @@ # Top-level generic files # tags -TAGS vmlinux* System.map Module.symvers diff --git a/trunk/CREDITS b/trunk/CREDITS index ccd4f9f4dd71..5329ead9c672 100644 --- a/trunk/CREDITS +++ b/trunk/CREDITS @@ -45,7 +45,7 @@ S: Longford, Ireland S: Sydney, Australia N: Tigran A. Aivazian -E: tigran@aivazian.fsnet.co.uk +E: tigran@veritas.com W: http://www.moses.uklinux.net/patches D: BFS filesystem D: Intel IA32 CPU microcode update support @@ -3511,12 +3511,14 @@ D: The Linux Support Team Erlangen N: David Weinehall E: tao@acc.umu.se -P: 1024D/DC47CA16 7ACE 0FB0 7A74 F994 9B36 E1D1 D14E 8526 DC47 CA16 W: http://www.acc.umu.se/~tao/ -D: v2.0 kernel maintainer +W: http://www.acc.umu.se/~mcalinux/ D: Fixes for the NE/2-driver D: Miscellaneous MCA-support D: Cleanup of the Config-files +S: Axtorpsvagen 40:20 +S: S-903 37 UMEA +S: Sweden N: Matt Welsh E: mdw@metalab.unc.edu diff --git a/trunk/Documentation/ABI/testing/sysfs-power b/trunk/Documentation/ABI/testing/sysfs-power index dcff4d0623ad..d882f8093871 100644 --- a/trunk/Documentation/ABI/testing/sysfs-power +++ b/trunk/Documentation/ABI/testing/sysfs-power @@ -21,7 +21,7 @@ Description: these states. What: /sys/power/disk -Date: September 2006 +Date: August 2006 Contact: Rafael J. Wysocki Description: The /sys/power/disk file controls the operating mode of the @@ -39,19 +39,6 @@ Description: 'reboot' - the memory image will be saved by the kernel and the system will be rebooted. - Additionally, /sys/power/disk can be used to turn on one of the - two testing modes of the suspend-to-disk mechanism: 'testproc' - or 'test'. If the suspend-to-disk mechanism is in the - 'testproc' mode, writing 'disk' to /sys/power/state will cause - the kernel to disable nonboot CPUs and freeze tasks, wait for 5 - seconds, unfreeze tasks and enable nonboot CPUs. If it is in - the 'test' mode, writing 'disk' to /sys/power/state will cause - the kernel to disable nonboot CPUs and freeze tasks, shrink - memory, suspend devices, wait for 5 seconds, resume devices, - unfreeze tasks and enable nonboot CPUs. Then, we are able to - look in the log messages and work out, for example, which code - is being slow and which device drivers are misbehaving. - The suspend-to-disk method may be chosen by writing to this file one of the accepted strings: @@ -59,8 +46,6 @@ Description: 'platform' 'shutdown' 'reboot' - 'testproc' - 'test' It will only change to 'firmware' or 'platform' if the system supports that. diff --git a/trunk/Documentation/Changes b/trunk/Documentation/Changes index 73a8617f1861..abee7f58c1ed 100644 --- a/trunk/Documentation/Changes +++ b/trunk/Documentation/Changes @@ -201,7 +201,7 @@ udev ---- udev is a userspace application for populating /dev dynamically with only entries for devices actually present. udev replaces the basic -functionality of devfs, while allowing persistent device naming for +functionality of devfs, while allowing persistant device naming for devices. FUSE diff --git a/trunk/Documentation/DMA-API.txt b/trunk/Documentation/DMA-API.txt index 05431621c861..2ffb0d62f0fe 100644 --- a/trunk/Documentation/DMA-API.txt +++ b/trunk/Documentation/DMA-API.txt @@ -489,7 +489,7 @@ size is the size of the area (must be multiples of PAGE_SIZE). flags can be or'd together and are DMA_MEMORY_MAP - request that the memory returned from -dma_alloc_coherent() be directly writable. +dma_alloc_coherent() be directly writeable. DMA_MEMORY_IO - request that the memory returned from dma_alloc_coherent() be addressable using read/write/memcpy_toio etc. diff --git a/trunk/Documentation/DMA-ISA-LPC.txt b/trunk/Documentation/DMA-ISA-LPC.txt index e767805b4182..705f6be92bdb 100644 --- a/trunk/Documentation/DMA-ISA-LPC.txt +++ b/trunk/Documentation/DMA-ISA-LPC.txt @@ -110,7 +110,7 @@ lock. Once the DMA transfer is finished (or timed out) you should disable the channel again. You should also check get_dma_residue() to make -sure that all data has been transferred. +sure that all data has been transfered. Example: diff --git a/trunk/Documentation/DocBook/Makefile b/trunk/Documentation/DocBook/Makefile index db9499adbed4..66e1cf733571 100644 --- a/trunk/Documentation/DocBook/Makefile +++ b/trunk/Documentation/DocBook/Makefile @@ -9,7 +9,7 @@ DOCBOOKS := wanbook.xml z8530book.xml mcabook.xml videobook.xml \ kernel-hacking.xml kernel-locking.xml deviceiobook.xml \ procfs-guide.xml writing_usb_driver.xml \ - kernel-api.xml filesystems.xml lsm.xml usb.xml \ + kernel-api.xml journal-api.xml lsm.xml usb.xml \ gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \ genericirq.xml diff --git a/trunk/Documentation/DocBook/filesystems.tmpl b/trunk/Documentation/DocBook/journal-api.tmpl similarity index 78% rename from trunk/Documentation/DocBook/filesystems.tmpl rename to trunk/Documentation/DocBook/journal-api.tmpl index 39fa2aba7f9b..2077f9a28c19 100644 --- a/trunk/Documentation/DocBook/filesystems.tmpl +++ b/trunk/Documentation/DocBook/journal-api.tmpl @@ -2,106 +2,9 @@ - + - Linux Filesystems API - - - - This documentation 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., 59 Temple Place, Suite 330, Boston, - MA 02111-1307 USA - - - - For more details see the file COPYING in the source - distribution of Linux. - - - - - - - - The Linux VFS - The Filesystem types -!Iinclude/linux/fs.h - - The Directory Cache -!Efs/dcache.c -!Iinclude/linux/dcache.h - - Inode Handling -!Efs/inode.c -!Efs/bad_inode.c - - Registration and Superblocks -!Efs/super.c - - File Locks -!Efs/locks.c -!Ifs/locks.c - - Other Functions -!Efs/mpage.c -!Efs/namei.c -!Efs/buffer.c -!Efs/bio.c -!Efs/seq_file.c -!Efs/filesystems.c -!Efs/fs-writeback.c -!Efs/block_dev.c - - - - - The proc filesystem - - sysctl interface -!Ekernel/sysctl.c - - - proc filesystem interface -!Ifs/proc/base.c - - - - - The Filesystem for Exporting Kernel Objects -!Efs/sysfs/file.c -!Efs/sysfs/symlink.c -!Efs/sysfs/bin.c - - - - The debugfs filesystem - - debugfs interface -!Efs/debugfs/inode.c -!Efs/debugfs/file.c - - - - - The Linux Journalling API - Roger @@ -111,9 +14,9 @@ rgammans@computer-surgery.co.uk - + - + Stephen @@ -130,21 +33,50 @@ 2002 Roger Gammans - - The Linux Journalling API + + + This documentation 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., 59 Temple Place, Suite 330, Boston, + MA 02111-1307 USA + + + + For more details see the file COPYING in the source + distribution of Linux. + + + - + + + Overview - + Details -The journalling layer is easy to use. You need to +The journalling layer is easy to use. You need to first of all create a journal_t data structure. There are two calls to do this dependent on how you decide to allocate the physical -media on which the journal resides. The journal_init_inode() call +media on which the journal resides. The journal_init_inode() call is for journals stored in filesystem inodes, or the journal_init_dev() -call can be use for journal stored on a raw device (in a continuous range +call can be use for journal stored on a raw device (in a continuous range of blocks). A journal_t is a typedef for a struct pointer, so when you are finally finished make sure you call journal_destroy() on it to free up any used kernel memory. @@ -159,26 +91,27 @@ need to call journal_create(). Most of the time however your journal file will already have been created, but before you load it you must call journal_wipe() to empty the journal file. -Hang on, you say , what if the filesystem wasn't cleanly umount()'d . Well, it is the +Hang on, you say , what if the filesystem wasn't cleanly umount()'d . Well, it is the job of the client file system to detect this and skip the call to journal_wipe(). In either case the next call should be to journal_load() which prepares the -journal file for use. Note that journal_wipe(..,0) calls journal_skip_recovery() +journal file for use. Note that journal_wipe(..,0) calls journal_skip_recovery() for you if it detects any outstanding transactions in the journal and similarly journal_load() will call journal_recover() if necessary. I would advise reading fs/ext3/super.c for examples on this stage. -[RGG: Why is the journal_wipe() call necessary - doesn't this needlessly -complicate the API. Or isn't a good idea for the journal layer to hide +[RGG: Why is the journal_wipe() call necessary - doesn't this needlessly +complicate the API. Or isn't a good idea for the journal layer to hide dirty mounts from the client fs] -Now you can go ahead and start modifying the underlying +Now you can go ahead and start modifying the underlying filesystem. Almost. + You still need to actually journal your filesystem changes, this @@ -205,10 +138,10 @@ individual buffers (blocks). Before you start to modify a buffer you need to call journal_get_{create,write,undo}_access() as appropriate, this allows the journalling layer to copy the unmodified data if it needs to. After all the buffer may be part of a previously uncommitted -transaction. +transaction. At this point you are at last ready to modify a buffer, and once you are have done so you need to call journal_dirty_{meta,}data(). -Or if you've asked for access to a buffer you now know is now longer +Or if you've asked for access to a buffer you now know is now longer required to be pushed back on the device you can call journal_forget() in much the same way as you might have used bforget() in the past. @@ -223,6 +156,7 @@ Then at umount time , in your put_super() (2.4) or write_super() (2.5) you can then call journal_destroy() to clean up your in-core journal object. + Unfortunately there a couple of ways the journal layer can cause a deadlock. The first thing to note is that each task can only have @@ -230,19 +164,19 @@ a single outstanding transaction at any one time, remember nothing commits until the outermost journal_stop(). This means you must complete the transaction at the end of each file/inode/address etc. operation you perform, so that the journalling system isn't re-entered -on another journal. Since transactions can't be nested/batched +on another journal. Since transactions can't be nested/batched across differing journals, and another filesystem other than yours (say ext3) may be modified in a later syscall. -The second case to bear in mind is that journal_start() can -block if there isn't enough space in the journal for your transaction +The second case to bear in mind is that journal_start() can +block if there isn't enough space in the journal for your transaction (based on the passed nblocks param) - when it blocks it merely(!) needs to -wait for transactions to complete and be committed from other tasks, -so essentially we are waiting for journal_stop(). So to avoid +wait for transactions to complete and be committed from other tasks, +so essentially we are waiting for journal_stop(). So to avoid deadlocks you must treat journal_start/stop() as if they -were semaphores and include them in your semaphore ordering rules to prevent +were semaphores and include them in your semaphore ordering rules to prevent deadlocks. Note that journal_extend() has similar blocking behaviour to journal_start() so you can deadlock here just as easily as on journal_start(). @@ -250,7 +184,7 @@ journal_start() so you can deadlock here just as easily as on journal_start(). Try to reserve the right number of blocks the first time. ;-). This will be the maximum number of blocks you are going to touch in this transaction. -I advise having a look at at least ext3_jbd.h to see the basis on which +I advise having a look at at least ext3_jbd.h to see the basis on which ext3 uses to make these decisions. @@ -259,13 +193,13 @@ Another wriggle to watch out for is your on-disk block allocation strategy. why? Because, if you undo a delete, you need to ensure you haven't reused any of the freed blocks in a later transaction. One simple way of doing this is make sure any blocks you allocate only have checkpointed transactions -listed against them. Ext3 does this in ext3_test_allocatable(). +listed against them. Ext3 does this in ext3_test_allocatable(). Lock is also providing through journal_{un,}lock_updates(), ext3 uses this when it wants a window with a clean and stable fs for a moment. -eg. +eg. @@ -296,19 +230,19 @@ extend it like this:- struct journal_callback for_jbd; // Stuff for myfs allocated together. myfs_inode* i_commited; - + } -this would be useful if you needed to know when data was committed to a +this would be useful if you needed to know when data was committed to a particular inode. - + - - Summary + +Summary Using the journal is a matter of wrapping the different context changes, being each mount, each modification (transaction) and each changed buffer @@ -326,15 +260,15 @@ an example. if (clean) journal_wipe(); journal_load(); - foreach(transaction) { /*transactions must be + foreach(transaction) { /*transactions must be completed before - a syscall returns to + a syscall returns to userspace*/ handle_t * xct=journal_start(my_jnrl); foreach(bh) { journal_get_{create,write,undo}_access(xact,bh); - if ( myfs_modify(bh) ) { /* returns true + if ( myfs_modify(bh) ) { /* returns true if makes changes */ journal_dirty_{meta,}data(xact,bh); } else { @@ -345,57 +279,55 @@ an example. } journal_destroy(my_jrnl); - + - + - + Data Types - + The journalling layer uses typedefs to 'hide' the concrete definitions of the structures used. As a client of the JBD layer you can just rely on the using the pointer as a magic cookie of some sort. - + Obviously the hiding is not enforced as this is 'C'. - - Structures + + Structures !Iinclude/linux/jbd.h - - + + - + Functions - + The functions here are split into two groups those that affect a journal as a whole, and those which are used to manage transactions - - Journal Level + + Journal Level !Efs/jbd/journal.c !Ifs/jbd/recovery.c - - Transasction Level -!Efs/jbd/transaction.c - - - + + Transasction Level +!Efs/jbd/transaction.c + + + See also - + - Journaling the Linux ext2fs Filesystem, LinuxExpo 98, Stephen Tweedie + Journaling the Linux ext2fs Filesystem,LinuxExpo 98, Stephen Tweedie - - - + + + - Ext3 Journalling FileSystem, OLS 2000, Dr. Stephen Tweedie + Ext3 Journalling FileSystem , OLS 2000, Dr. Stephen Tweedie - - - - + + diff --git a/trunk/Documentation/DocBook/kernel-api.tmpl b/trunk/Documentation/DocBook/kernel-api.tmpl index a166675c4303..2b5ac604948c 100644 --- a/trunk/Documentation/DocBook/kernel-api.tmpl +++ b/trunk/Documentation/DocBook/kernel-api.tmpl @@ -182,6 +182,66 @@ X!Ilib/string.c + + The Linux VFS + The Filesystem types +!Iinclude/linux/fs.h + + The Directory Cache +!Efs/dcache.c +!Iinclude/linux/dcache.h + + Inode Handling +!Efs/inode.c +!Efs/bad_inode.c + + Registration and Superblocks +!Efs/super.c + + File Locks +!Efs/locks.c +!Ifs/locks.c + + Other Functions +!Efs/mpage.c +!Efs/namei.c +!Efs/buffer.c +!Efs/bio.c +!Efs/seq_file.c +!Efs/filesystems.c +!Efs/fs-writeback.c +!Efs/block_dev.c + + + + + The proc filesystem + + sysctl interface +!Ekernel/sysctl.c + + + proc filesystem interface +!Ifs/proc/base.c + + + + + The Filesystem for Exporting Kernel Objects +!Efs/sysfs/file.c +!Efs/sysfs/symlink.c +!Efs/sysfs/bin.c + + + + The debugfs filesystem + + debugfs interface +!Efs/debugfs/inode.c +!Efs/debugfs/file.c + + + relay interface support diff --git a/trunk/Documentation/DocBook/writing_usb_driver.tmpl b/trunk/Documentation/DocBook/writing_usb_driver.tmpl index d4188d4ff535..07cd34c1940b 100644 --- a/trunk/Documentation/DocBook/writing_usb_driver.tmpl +++ b/trunk/Documentation/DocBook/writing_usb_driver.tmpl @@ -345,7 +345,8 @@ static inline void skel_delete (struct usb_skel *dev) usb_buffer_free (dev->udev, dev->bulk_out_size, dev->bulk_out_buffer, dev->write_urb->transfer_dma); - usb_free_urb (dev->write_urb); + if (dev->write_urb != NULL) + usb_free_urb (dev->write_urb); kfree (dev); } diff --git a/trunk/Documentation/HOWTO b/trunk/Documentation/HOWTO index 8d51c148f721..d6f3dd1a3464 100644 --- a/trunk/Documentation/HOWTO +++ b/trunk/Documentation/HOWTO @@ -395,26 +395,6 @@ bugme-janitor mailing list (every change in the bugzilla is mailed here) -Managing bug reports --------------------- - -One of the best ways to put into practice your hacking skills is by fixing -bugs reported by other people. Not only you will help to make the kernel -more stable, you'll learn to fix real world problems and you will improve -your skills, and other developers will be aware of your presence. Fixing -bugs is one of the best ways to get merits among other developers, because -not many people like wasting time fixing other people's bugs. - -To work in the already reported bug reports, go to http://bugzilla.kernel.org. -If you want to be advised of the future bug reports, you can subscribe to the -bugme-new mailing list (only new bug reports are mailed here) or to the -bugme-janitor mailing list (every change in the bugzilla is mailed here) - - http://lists.osdl.org/mailman/listinfo/bugme-new - http://lists.osdl.org/mailman/listinfo/bugme-janitors - - - Mailing lists ------------- diff --git a/trunk/Documentation/MSI-HOWTO.txt b/trunk/Documentation/MSI-HOWTO.txt index d389388c733e..c70306abb7b2 100644 --- a/trunk/Documentation/MSI-HOWTO.txt +++ b/trunk/Documentation/MSI-HOWTO.txt @@ -219,7 +219,7 @@ into the field vector of each element contained in a second argument. Note that the pre-assigned IOAPIC dev->irq is valid only if the device operates in PIN-IRQ assertion mode. In MSI-X mode, any attempt at using dev->irq by the device driver to request for interrupt service -may result in unpredictable behavior. +may result unpredictabe behavior. For each MSI-X vector granted, a device driver is responsible for calling other functions like request_irq(), enable_irq(), etc. to enable @@ -470,68 +470,7 @@ LOC: 324553 325068 ERR: 0 MIS: 0 -6. MSI quirks - -Several PCI chipsets or devices are known to not support MSI. -The PCI stack provides 3 possible levels of MSI disabling: -* on a single device -* on all devices behind a specific bridge -* globally - -6.1. Disabling MSI on a single device - -Under some circumstances, it might be required to disable MSI on a -single device, It may be achived by either not calling pci_enable_msi() -or all, or setting the pci_dev->no_msi flag before (most of the time -in a quirk). - -6.2. Disabling MSI below a bridge - -The vast majority of MSI quirks are required by PCI bridges not -being able to route MSI between busses. In this case, MSI have to be -disabled on all devices behind this bridge. It is achieves by setting -the PCI_BUS_FLAGS_NO_MSI flag in the pci_bus->bus_flags of the bridge -subordinate bus. There is no need to set the same flag on bridges that -are below the broken brigde. When pci_enable_msi() is called to enable -MSI on a device, pci_msi_supported() takes care of checking the NO_MSI -flag in all parent busses of the device. - -Some bridges actually support dynamic MSI support enabling/disabling -by changing some bits in their PCI configuration space (especially -the Hypertransport chipsets such as the nVidia nForce and Serverworks -HT2000). It may then be required to update the NO_MSI flag on the -corresponding devices in the sysfs hierarchy. To enable MSI support -on device "0000:00:0e", do: - - echo 1 > /sys/bus/pci/devices/0000:00:0e/msi_bus - -To disable MSI support, echo 0 instead of 1. Note that it should be -used with caution since changing this value might break interrupts. - -6.3. Disabling MSI globally - -Some extreme cases may require to disable MSI globally on the system. -For now, the only known case is a Serverworks PCI-X chipsets (MSI are -not supported on several busses that are not all connected to the -chipset in the Linux PCI hierarchy). In the vast majority of other -cases, disabling only behind a specific bridge is enough. - -For debugging purpose, the user may also pass pci=nomsi on the kernel -command-line to explicitly disable MSI globally. But, once the appro- -priate quirks are added to the kernel, this option should not be -required anymore. - -6.4. Finding why MSI cannot be enabled on a device - -Assuming that MSI are not enabled on a device, you should look at -dmesg to find messages that quirks may output when disabling MSI -on some devices, some bridges or even globally. -Then, lspci -t gives the list of bridges above a device. Reading -/sys/bus/pci/devices/0000:00:0e/msi_bus will tell you whether MSI -are enabled (1) or disabled (0). In 0 is found in a single bridge -msi_bus file above the device, MSI cannot be enabled. - -7. FAQ +6. FAQ Q1. Are there any limitations on using the MSI? diff --git a/trunk/Documentation/accounting/getdelays.c b/trunk/Documentation/accounting/getdelays.c index bf2b0e2f87e1..b11792abd6b6 100644 --- a/trunk/Documentation/accounting/getdelays.c +++ b/trunk/Documentation/accounting/getdelays.c @@ -49,7 +49,7 @@ __u64 stime, utime; } /* Maximum size of response requested or message sent */ -#define MAX_MSG_SIZE 1024 +#define MAX_MSG_SIZE 256 /* Maximum number of cpus expected to be specified in a cpumask */ #define MAX_CPUS 32 /* Maximum length of pathname to log file */ diff --git a/trunk/Documentation/accounting/taskstats.txt b/trunk/Documentation/accounting/taskstats.txt index ff06b738bb88..92ebf29e9041 100644 --- a/trunk/Documentation/accounting/taskstats.txt +++ b/trunk/Documentation/accounting/taskstats.txt @@ -96,9 +96,9 @@ a) TASKSTATS_TYPE_AGGR_PID/TGID : attribute containing no payload but indicates a pid/tgid will be followed by some stats. b) TASKSTATS_TYPE_PID/TGID: attribute whose payload is the pid/tgid whose stats -are being returned. +is being returned. -c) TASKSTATS_TYPE_STATS: attribute with a struct taskstats as payload. The +c) TASKSTATS_TYPE_STATS: attribute with a struct taskstsats as payload. The same structure is used for both per-pid and per-tgid stats. 3. New message sent by kernel whenever a task exits. The payload consists of a @@ -122,12 +122,12 @@ of atomicity). However, maintaining per-process, in addition to per-task stats, within the kernel has space and time overheads. To address this, the taskstats code -accumulates each exiting task's statistics into a process-wide data structure. -When the last task of a process exits, the process level data accumulated also +accumalates each exiting task's statistics into a process-wide data structure. +When the last task of a process exits, the process level data accumalated also gets sent to userspace (along with the per-task data). When a user queries to get per-tgid data, the sum of all other live threads in -the group is added up and added to the accumulated total for previously exited +the group is added up and added to the accumalated total for previously exited threads of the same thread group. Extending taskstats diff --git a/trunk/Documentation/block/biodoc.txt b/trunk/Documentation/block/biodoc.txt index c6c9a9c10d7f..34bf8f60d8f8 100644 --- a/trunk/Documentation/block/biodoc.txt +++ b/trunk/Documentation/block/biodoc.txt @@ -183,7 +183,7 @@ it, the pci dma mapping routines and associated data structures have now been modified to accomplish a direct page -> bus translation, without requiring a virtual address mapping (unlike the earlier scheme of virtual address -> bus translation). So this works uniformly for high-memory pages (which -do not have a corresponding kernel virtual address space mapping) and +do not have a correponding kernel virtual address space mapping) and low-memory pages. Note: Please refer to DMA-mapping.txt for a discussion on PCI high mem DMA @@ -391,7 +391,7 @@ forced such requests to be broken up into small chunks before being passed on to the generic block layer, only to be merged by the i/o scheduler when the underlying device was capable of handling the i/o in one shot. Also, using the buffer head as an i/o structure for i/os that didn't originate -from the buffer cache unnecessarily added to the weight of the descriptors +from the buffer cache unecessarily added to the weight of the descriptors which were generated for each such chunk. The following were some of the goals and expectations considered in the @@ -403,14 +403,14 @@ i. Should be appropriate as a descriptor for both raw and buffered i/o - for raw i/o. ii. Ability to represent high-memory buffers (which do not have a virtual address mapping in kernel address space). -iii.Ability to represent large i/os w/o unnecessarily breaking them up (i.e +iii.Ability to represent large i/os w/o unecessarily breaking them up (i.e greater than PAGE_SIZE chunks in one shot) iv. At the same time, ability to retain independent identity of i/os from different sources or i/o units requiring individual completion (e.g. for latency reasons) v. Ability to represent an i/o involving multiple physical memory segments (including non-page aligned page fragments, as specified via readv/writev) - without unnecessarily breaking it up, if the underlying device is capable of + without unecessarily breaking it up, if the underlying device is capable of handling it. vi. Preferably should be based on a memory descriptor structure that can be passed around different types of subsystems or layers, maybe even @@ -1013,7 +1013,7 @@ Characteristics: i. Binary tree AS and deadline i/o schedulers use red black binary trees for disk position sorting and searching, and a fifo linked list for time-based searching. This -gives good scalability and good availability of information. Requests are +gives good scalability and good availablility of information. Requests are almost always dispatched in disk sort order, so a cache is kept of the next request in sort order to prevent binary tree lookups. diff --git a/trunk/Documentation/cpu-freq/cpufreq-nforce2.txt b/trunk/Documentation/cpu-freq/cpufreq-nforce2.txt index babce1315026..9188337d8f6b 100644 --- a/trunk/Documentation/cpu-freq/cpufreq-nforce2.txt +++ b/trunk/Documentation/cpu-freq/cpufreq-nforce2.txt @@ -1,7 +1,7 @@ -The cpufreq-nforce2 driver changes the FSB on nVidia nForce2 platforms. +The cpufreq-nforce2 driver changes the FSB on nVidia nForce2 plattforms. -This works better than on other platforms, because the FSB of the CPU +This works better than on other plattforms, because the FSB of the CPU can be controlled independently from the PCI/AGP clock. The module has two options: diff --git a/trunk/Documentation/cpu-hotplug.txt b/trunk/Documentation/cpu-hotplug.txt index cc60d29b954c..bc107cb157a8 100644 --- a/trunk/Documentation/cpu-hotplug.txt +++ b/trunk/Documentation/cpu-hotplug.txt @@ -46,7 +46,7 @@ maxcpus=n Restrict boot time cpus to n. Say if you have 4 cpus, using maxcpus=2 will only boot 2. You can choose to bring the other cpus later online, read FAQ's for more info. -additional_cpus=n (*) Use this to limit hotpluggable cpus. This option sets +additional_cpus*=n Use this to limit hotpluggable cpus. This option sets cpu_possible_map = cpu_present_map + additional_cpus (*) Option valid only for following architectures @@ -54,8 +54,8 @@ additional_cpus=n (*) Use this to limit hotpluggable cpus. This option sets ia64 and x86_64 use the number of disabled local apics in ACPI tables MADT to determine the number of potentially hot-pluggable cpus. The implementation -should only rely on this to count the # of cpus, but *MUST* not rely on the -apicid values in those tables for disabled apics. In the event BIOS doesn't +should only rely on this to count the #of cpus, but *MUST* not rely on the +apicid values in those tables for disabled apics. In the event BIOS doesnt mark such hot-pluggable cpus as disabled entries, one could use this parameter "additional_cpus=x" to represent those cpus in the cpu_possible_map. @@ -101,15 +101,15 @@ cpu_possible_map/for_each_possible_cpu() to iterate. Never use anything other than cpumask_t to represent bitmap of CPUs. - #include +#include - for_each_possible_cpu - Iterate over cpu_possible_map - for_each_online_cpu - Iterate over cpu_online_map - for_each_present_cpu - Iterate over cpu_present_map - for_each_cpu_mask(x,mask) - Iterate over some random collection of cpu mask. +for_each_possible_cpu - Iterate over cpu_possible_map +for_each_online_cpu - Iterate over cpu_online_map +for_each_present_cpu - Iterate over cpu_present_map +for_each_cpu_mask(x,mask) - Iterate over some random collection of cpu mask. - #include - lock_cpu_hotplug() and unlock_cpu_hotplug(): +#include +lock_cpu_hotplug() and unlock_cpu_hotplug(): The above calls are used to inhibit cpu hotplug operations. While holding the cpucontrol mutex, cpu_online_map will not change. If you merely need to avoid @@ -120,7 +120,7 @@ will work as long as stop_machine_run() is used to take a cpu down. CPU Hotplug - Frequently Asked Questions. -Q: How to enable my kernel to support CPU hotplug? +Q: How to i enable my kernel to support CPU hotplug? A: When doing make defconfig, Enable CPU hotplug support "Processor type and Features" -> Support for Hotpluggable CPUs @@ -141,39 +141,39 @@ A: You should now notice an entry in sysfs. Check if sysfs is mounted, using the "mount" command. You should notice an entry as shown below in the output. - .... - none on /sys type sysfs (rw) - .... +.... +none on /sys type sysfs (rw) +.... -If this is not mounted, do the following. +if this is not mounted, do the following. - #mkdir /sysfs - #mount -t sysfs sys /sys +#mkdir /sysfs +#mount -t sysfs sys /sys -Now you should see entries for all present cpu, the following is an example +now you should see entries for all present cpu, the following is an example in a 8-way system. - #pwd - #/sys/devices/system/cpu - #ls -l - total 0 - drwxr-xr-x 10 root root 0 Sep 19 07:44 . - drwxr-xr-x 13 root root 0 Sep 19 07:45 .. - drwxr-xr-x 3 root root 0 Sep 19 07:44 cpu0 - drwxr-xr-x 3 root root 0 Sep 19 07:44 cpu1 - drwxr-xr-x 3 root root 0 Sep 19 07:44 cpu2 - drwxr-xr-x 3 root root 0 Sep 19 07:44 cpu3 - drwxr-xr-x 3 root root 0 Sep 19 07:44 cpu4 - drwxr-xr-x 3 root root 0 Sep 19 07:44 cpu5 - drwxr-xr-x 3 root root 0 Sep 19 07:44 cpu6 - drwxr-xr-x 3 root root 0 Sep 19 07:48 cpu7 +#pwd +#/sys/devices/system/cpu +#ls -l +total 0 +drwxr-xr-x 10 root root 0 Sep 19 07:44 . +drwxr-xr-x 13 root root 0 Sep 19 07:45 .. +drwxr-xr-x 3 root root 0 Sep 19 07:44 cpu0 +drwxr-xr-x 3 root root 0 Sep 19 07:44 cpu1 +drwxr-xr-x 3 root root 0 Sep 19 07:44 cpu2 +drwxr-xr-x 3 root root 0 Sep 19 07:44 cpu3 +drwxr-xr-x 3 root root 0 Sep 19 07:44 cpu4 +drwxr-xr-x 3 root root 0 Sep 19 07:44 cpu5 +drwxr-xr-x 3 root root 0 Sep 19 07:44 cpu6 +drwxr-xr-x 3 root root 0 Sep 19 07:48 cpu7 Under each directory you would find an "online" file which is the control file to logically online/offline a processor. Q: Does hot-add/hot-remove refer to physical add/remove of cpus? A: The usage of hot-add/remove may not be very consistently used in the code. -CONFIG_HOTPLUG_CPU enables logical online/offline capability in the kernel. +CONFIG_CPU_HOTPLUG enables logical online/offline capability in the kernel. To support physical addition/removal, one would need some BIOS hooks and the platform should have something like an attention button in PCI hotplug. CONFIG_ACPI_HOTPLUG_CPU enables ACPI support for physical add/remove of CPUs. @@ -181,17 +181,17 @@ CONFIG_ACPI_HOTPLUG_CPU enables ACPI support for physical add/remove of CPUs. Q: How do i logically offline a CPU? A: Do the following. - #echo 0 > /sys/devices/system/cpu/cpuX/online +#echo 0 > /sys/devices/system/cpu/cpuX/online -Once the logical offline is successful, check +once the logical offline is successful, check - #cat /proc/interrupts +#cat /proc/interrupts -You should now not see the CPU that you removed. Also online file will report +you should now not see the CPU that you removed. Also online file will report the state as 0 when a cpu if offline and 1 when its online. - #To display the current cpu state. - #cat /sys/devices/system/cpu/cpuX/online +#To display the current cpu state. +#cat /sys/devices/system/cpu/cpuX/online Q: Why cant i remove CPU0 on some systems? A: Some architectures may have some special dependency on a certain CPU. @@ -234,8 +234,8 @@ Q: If i have some kernel code that needs to be aware of CPU arrival and departure, how to i arrange for proper notification? A: This is what you would need in your kernel code to receive notifications. - #include - static int __cpuinit foobar_cpu_callback(struct notifier_block *nfb, + #include + static int __cpuinit foobar_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { unsigned int cpu = (unsigned long)hcpu; @@ -279,10 +279,10 @@ Q: I don't see my action being called for all CPUs already up and running? A: Yes, CPU notifiers are called only when new CPUs are on-lined or offlined. If you need to perform some action for each cpu already in the system, then - for_each_online_cpu(i) { + for_each_online_cpu(i) { foobar_cpu_callback(&foobar_cpu_notifier, CPU_UP_PREPARE, i); - foobar_cpu_callback(&foobar_cpu_notifier, CPU_ONLINE, i); - } + foobar_cpu_callback(&foobar-cpu_notifier, CPU_ONLINE, i); + } Q: If i would like to develop cpu hotplug support for a new architecture, what do i need at a minimum? @@ -307,38 +307,38 @@ Q: I need to ensure that a particular cpu is not removed when there is some work specific to this cpu is in progress. A: First switch the current thread context to preferred cpu - int my_func_on_cpu(int cpu) - { - cpumask_t saved_mask, new_mask = CPU_MASK_NONE; - int curr_cpu, err = 0; - - saved_mask = current->cpus_allowed; - cpu_set(cpu, new_mask); - err = set_cpus_allowed(current, new_mask); - - if (err) - return err; - - /* - * If we got scheduled out just after the return from - * set_cpus_allowed() before running the work, this ensures - * we stay locked. - */ - curr_cpu = get_cpu(); - - if (curr_cpu != cpu) { - err = -EAGAIN; - goto ret; - } else { - /* - * Do work : But cant sleep, since get_cpu() disables preempt - */ - } - ret: - put_cpu(); - set_cpus_allowed(current, saved_mask); - return err; - } + int my_func_on_cpu(int cpu) + { + cpumask_t saved_mask, new_mask = CPU_MASK_NONE; + int curr_cpu, err = 0; + + saved_mask = current->cpus_allowed; + cpu_set(cpu, new_mask); + err = set_cpus_allowed(current, new_mask); + + if (err) + return err; + + /* + * If we got scheduled out just after the return from + * set_cpus_allowed() before running the work, this ensures + * we stay locked. + */ + curr_cpu = get_cpu(); + + if (curr_cpu != cpu) { + err = -EAGAIN; + goto ret; + } else { + /* + * Do work : But cant sleep, since get_cpu() disables preempt + */ + } + ret: + put_cpu(); + set_cpus_allowed(current, saved_mask); + return err; + } Q: How do we determine how many CPUs are available for hotplug. diff --git a/trunk/Documentation/devices.txt b/trunk/Documentation/devices.txt index 70690f1a14af..28c4f79662c2 100644 --- a/trunk/Documentation/devices.txt +++ b/trunk/Documentation/devices.txt @@ -92,7 +92,7 @@ Your cooperation is appreciated. 7 = /dev/full Returns ENOSPC on write 8 = /dev/random Nondeterministic random number gen. 9 = /dev/urandom Faster, less secure random number gen. - 10 = /dev/aio Asynchronous I/O notification interface + 10 = /dev/aio Asyncronous 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 @@ -1093,7 +1093,7 @@ Your cooperation is appreciated. 55 char DSP56001 digital signal processor 0 = /dev/dsp56k First DSP56001 - 55 block Mylex DAC960 PCI RAID controller; eighth controller + 55 block Mylex DAC960 PCI RAID controller; eigth controller 0 = /dev/rd/c7d0 First disk, whole disk 8 = /dev/rd/c7d1 Second disk, whole disk ... @@ -1456,7 +1456,7 @@ Your cooperation is appreciated. 1 = /dev/cum1 Callout device for ttyM1 ... - 79 block Compaq Intelligent Drive Array, eighth controller + 79 block Compaq Intelligent Drive Array, eigth controller 0 = /dev/ida/c7d0 First logical drive whole disk 16 = /dev/ida/c7d1 Second logical drive whole disk ... @@ -1900,7 +1900,7 @@ Your cooperation is appreciated. 1 = /dev/av1 Second A/V card ... -111 block Compaq Next Generation Drive Array, eighth controller +111 block Compaq Next Generation Drive Array, eigth controller 0 = /dev/cciss/c7d0 First logical drive, whole disk 16 = /dev/cciss/c7d1 Second logical drive, whole disk ... diff --git a/trunk/Documentation/driver-model/platform.txt b/trunk/Documentation/driver-model/platform.txt index 9f0bc3bfd776..5eee3e0bfc4c 100644 --- a/trunk/Documentation/driver-model/platform.txt +++ b/trunk/Documentation/driver-model/platform.txt @@ -1,131 +1,99 @@ Platform Devices and Drivers ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -See for the driver model interface to the -platform bus: platform_device, and platform_driver. This pseudo-bus -is used to connect devices on busses with minimal infrastructure, -like those used to integrate peripherals on many system-on-chip -processors, or some "legacy" PC interconnects; as opposed to large -formally specified ones like PCI or USB. - Platform devices ~~~~~~~~~~~~~~~~ Platform devices are devices that typically appear as autonomous entities in the system. This includes legacy port-based devices and -host bridges to peripheral buses, and most controllers integrated -into system-on-chip platforms. What they usually have in common -is direct addressing from a CPU bus. Rarely, a platform_device will -be connected through a segment of some other kind of bus; but its -registers will still be directly addressible. +host bridges to peripheral buses. -Platform devices are given a name, used in driver binding, and a -list of resources such as addresses and IRQs. -struct platform_device { - const char *name; - u32 id; - struct device dev; - u32 num_resources; - struct resource *resource; -}; +Platform drivers +~~~~~~~~~~~~~~~~ +Drivers for platform devices are typically very simple and +unstructured. Either the device was present at a particular I/O port +and the driver was loaded, or it was not. There was no possibility +of hotplugging or alternative discovery besides probing at a specific +I/O address and expecting a specific response. -Platform drivers +Other Architectures, Modern Firmware, and new Platforms +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +These devices are not always at the legacy I/O ports. This is true on +other architectures and on some modern architectures. In most cases, +the drivers are modified to discover the devices at other well-known +ports for the given platform. However, the firmware in these systems +does usually know where exactly these devices reside, and in some +cases, it's the only way of discovering them. + + +The Platform Bus +~~~~~~~~~~~~~~~~ +A platform bus has been created to deal with these issues. First and +foremost, it groups all the legacy devices under a common bus, and +gives them a common parent if they don't already have one. + +But, besides the organizational benefits, the platform bus can also +accommodate firmware-based enumeration. + + +Device Discovery ~~~~~~~~~~~~~~~~ -Platform drivers follow the standard driver model convention, where -discovery/enumeration is handled outside the drivers, and drivers -provide probe() and remove() methods. They support power management -and shutdown notifications using the standard conventions. - -struct platform_driver { - int (*probe)(struct platform_device *); - int (*remove)(struct platform_device *); - void (*shutdown)(struct platform_device *); - int (*suspend)(struct platform_device *, pm_message_t state); - int (*suspend_late)(struct platform_device *, pm_message_t state); - int (*resume_early)(struct platform_device *); - int (*resume)(struct platform_device *); - struct device_driver driver; -}; - -Note that probe() should general verify that the specified device hardware -actually exists; sometimes platform setup code can't be sure. The probing -can use device resources, including clocks, and device platform_data. - -Platform drivers register themselves the normal way: - - int platform_driver_register(struct platform_driver *drv); - -Or, in common situations where the device is known not to be hot-pluggable, -the probe() routine can live in an init section to reduce the driver's -runtime memory footprint: - - int platform_driver_probe(struct platform_driver *drv, - int (*probe)(struct platform_device *)) - - -Device Enumeration -~~~~~~~~~~~~~~~~~~ -As a rule, platform specific (and often board-specific) setup code wil -register platform devices: - - int platform_device_register(struct platform_device *pdev); - - int platform_add_devices(struct platform_device **pdevs, int ndev); - -The general rule is to register only those devices that actually exist, -but in some cases extra devices might be registered. For example, a kernel -might be configured to work with an external network adapter that might not -be populated on all boards, or likewise to work with an integrated controller -that some boards might not hook up to any peripherals. - -In some cases, boot firmware will export tables describing the devices -that are populated on a given board. Without such tables, often the -only way for system setup code to set up the correct devices is to build -a kernel for a specific target board. Such board-specific kernels are -common with embedded and custom systems development. - -In many cases, the memory and IRQ resources associated with the platform -device are not enough to let the device's driver work. Board setup code -will often provide additional information using the device's platform_data -field to hold additional information. - -Embedded systems frequently need one or more clocks for platform devices, -which are normally kept off until they're actively needed (to save power). -System setup also associates those clocks with the device, so that that -calls to clk_get(&pdev->dev, clock_name) return them as needed. - - -Device Naming and Driver Binding -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The platform_device.dev.bus_id is the canonical name for the devices. -It's built from two components: - - * platform_device.name ... which is also used to for driver matching. - - * platform_device.id ... the device instance number, or else "-1" - to indicate there's only one. - -These are catenated, so name/id "serial"/0 indicates bus_id "serial.0", and -"serial/3" indicates bus_id "serial.3"; both would use the platform_driver -named "serial". While "my_rtc"/-1 would be bus_id "my_rtc" (no instance id) -and use the platform_driver called "my_rtc". - -Driver binding is performed automatically by the driver core, invoking -driver probe() after finding a match between device and driver. If the -probe() succeeds, the driver and device are bound as usual. There are -three different ways to find such a match: - - - Whenever a device is registered, the drivers for that bus are - checked for matches. Platform devices should be registered very - early during system boot. - - - When a driver is registered using platform_driver_register(), all - unbound devices on that bus are checked for matches. Drivers - usually register later during booting, or by module loading. - - - Registering a driver using platform_driver_probe() works just like - using platform_driver_register(), except that the the driver won't - be probed later if another device registers. (Which is OK, since - this interface is only for use with non-hotpluggable devices.) +The platform bus has no concept of probing for devices. Devices +discovery is left up to either the legacy drivers or the +firmware. These entities are expected to notify the platform of +devices that it discovers via the bus's add() callback: + + platform_bus.add(parent,bus_id). + + +Bus IDs +~~~~~~~ +Bus IDs are the canonical names for the devices. There is no globally +standard addressing mechanism for legacy devices. In the IA-32 world, +we have Pnp IDs to use, as well as the legacy I/O ports. However, +neither tell what the device really is or have any meaning on other +platforms. + +Since both PnP IDs and the legacy I/O ports (and other standard I/O +ports for specific devices) have a 1:1 mapping, we map the +platform-specific name or identifier to a generic name (at least +within the scope of the kernel). + +For example, a serial driver might find a device at I/O 0x3f8. The +ACPI firmware might also discover a device with PnP ID (_HID) +PNP0501. Both correspond to the same device and should be mapped to the +canonical name 'serial'. + +The bus_id field should be a concatenation of the canonical name and +the instance of that type of device. For example, the device at I/O +port 0x3f8 should have a bus_id of "serial0". This places the +responsibility of enumerating devices of a particular type up to the +discovery mechanism. But, they are the entity that should know best +(as opposed to the platform bus driver). + + +Drivers +~~~~~~~ +Drivers for platform devices should have a name that is the same as +the canonical name of the devices they support. This allows the +platform bus driver to do simple matching with the basic data +structures to determine if a driver supports a certain device. + +For example, a legacy serial driver should have a name of 'serial' and +register itself with the platform bus. + + +Driver Binding +~~~~~~~~~~~~~~ +Legacy drivers assume they are bound to the device once they start up +and probe an I/O port. Divorcing them from this will be a difficult +process. However, that shouldn't prevent us from implementing +firmware-based enumeration. + +The firmware should notify the platform bus about devices before the +legacy drivers have had a chance to load. Once the drivers are loaded, +they driver model core will attempt to bind the driver to any +previously-discovered devices. Once that has happened, it will be free +to discover any other devices it pleases. diff --git a/trunk/Documentation/driver-model/porting.txt b/trunk/Documentation/driver-model/porting.txt index 92d86f7271b4..98b233cb8b36 100644 --- a/trunk/Documentation/driver-model/porting.txt +++ b/trunk/Documentation/driver-model/porting.txt @@ -92,7 +92,7 @@ struct device represents a single device. It mainly contains metadata describing the relationship the device has to other entities. -- Embed a struct device in the bus-specific device type. +- Embedd a struct device in the bus-specific device type. struct pci_dev { diff --git a/trunk/Documentation/dvb/ci.txt b/trunk/Documentation/dvb/ci.txt index 2ecd834585e6..531239b29082 100644 --- a/trunk/Documentation/dvb/ci.txt +++ b/trunk/Documentation/dvb/ci.txt @@ -71,7 +71,7 @@ eliminating the need for any additional ioctls. The disadvantage is that the driver/hardware has to manage the rest. For the application programmer it would be as simple as sending/receiving an array to/from the CI ioctls as defined in the Linux DVB API. No changes -have been made in the API to accommodate this feature. +have been made in the API to accomodate this feature. * Why the need for another CI interface ? @@ -102,7 +102,7 @@ This CI interface follows the CI high level interface, which is not implemented by most applications. Hence this area is revisited. This CI interface is quite different in the case that it tries to -accommodate all other CI based devices, that fall into the other categories. +accomodate all other CI based devices, that fall into the other categories This means that this CI interface handles the EN50221 style tags in the Application layer only and no session management is taken care of by the diff --git a/trunk/Documentation/eisa.txt b/trunk/Documentation/eisa.txt index 60e361ba08c0..6a099edadd62 100644 --- a/trunk/Documentation/eisa.txt +++ b/trunk/Documentation/eisa.txt @@ -62,7 +62,7 @@ res : root device I/O resource bus_base_addr : slot 0 address on this bus slots : max slot number to probe force_probe : Probe even when slot 0 is empty (no EISA mainboard) -dma_mask : Default DMA mask. Usually the bridge device dma_mask. +dma_mask : Default DMA mask. Usualy the bridge device dma_mask. bus_nr : unique bus id, set by eisa_root_register ** Driver : diff --git a/trunk/Documentation/feature-removal-schedule.txt b/trunk/Documentation/feature-removal-schedule.txt index d52c4aaaf17f..24f3c63b3017 100644 --- a/trunk/Documentation/feature-removal-schedule.txt +++ b/trunk/Documentation/feature-removal-schedule.txt @@ -53,6 +53,18 @@ Who: Mauro Carvalho Chehab --------------------------- +What: sys_sysctl +When: January 2007 +Why: The same information is available through /proc/sys and that is the + interface user space prefers to use. And there do not appear to be + any existing user in user space of sys_sysctl. The additional + maintenance overhead of keeping a set of binary names gets + in the way of doing a good job of maintaining this interface. + +Who: Eric Biederman + +--------------------------- + What: PCMCIA control ioctl (needed for pcmcia-cs [cardmgr, cardctl]) When: November 2005 Files: drivers/pcmcia/: pcmcia_ioctl.c @@ -243,7 +255,7 @@ Who: Stephen Hemminger What: PHYSDEVPATH, PHYSDEVBUS, PHYSDEVDRIVER in the uevent environment -When: October 2008 +When: Oktober 2008 Why: The stacking of class devices makes these values misleading and inconsistent. Class devices should not carry any of these properties, and bus diff --git a/trunk/Documentation/filesystems/00-INDEX b/trunk/Documentation/filesystems/00-INDEX index 4dc28cc93503..3c384c0cf86e 100644 --- a/trunk/Documentation/filesystems/00-INDEX +++ b/trunk/Documentation/filesystems/00-INDEX @@ -34,8 +34,6 @@ ext2.txt - info, mount options and specifications for the Ext2 filesystem. ext3.txt - info, mount options and specifications for the Ext3 filesystem. -ext4.txt - - info, mount options and specifications for the Ext4 filesystem. files.txt - info on file management in the Linux kernel. fuse.txt diff --git a/trunk/Documentation/filesystems/adfs.txt b/trunk/Documentation/filesystems/adfs.txt index 9e8811f92b84..060abb0c7004 100644 --- a/trunk/Documentation/filesystems/adfs.txt +++ b/trunk/Documentation/filesystems/adfs.txt @@ -3,7 +3,7 @@ Mount options for ADFS uid=nnn All files in the partition will be owned by user id nnn. Default 0 (root). - gid=nnn All files in the partition will be in group + gid=nnn All files in the partition willbe in group nnn. Default 0 (root). ownmask=nnn The permission mask for ADFS 'owner' permissions will be nnn. Default 0700. diff --git a/trunk/Documentation/filesystems/configfs/configfs.txt b/trunk/Documentation/filesystems/configfs/configfs.txt index b34cdb50eab4..c3a7afb5eabf 100644 --- a/trunk/Documentation/filesystems/configfs/configfs.txt +++ b/trunk/Documentation/filesystems/configfs/configfs.txt @@ -209,7 +209,7 @@ will happen for write(2). [struct config_group] -A config_item cannot live in a vacuum. The only way one can be created +A config_item cannot live in a vaccum. The only way one can be created is via mkdir(2) on a config_group. This will trigger creation of a child item. @@ -275,7 +275,7 @@ directory is not empty. [struct configfs_subsystem] -A subsystem must register itself, usually at module_init time. This +A subsystem must register itself, ususally at module_init time. This tells configfs to make the subsystem appear in the file tree. struct configfs_subsystem { diff --git a/trunk/Documentation/filesystems/ext4.txt b/trunk/Documentation/filesystems/ext4.txt deleted file mode 100644 index 6a4adcae9f9a..000000000000 --- a/trunk/Documentation/filesystems/ext4.txt +++ /dev/null @@ -1,236 +0,0 @@ - -Ext4 Filesystem -=============== - -This is a development version of the ext4 filesystem, an advanced level -of the ext3 filesystem which incorporates scalability and reliability -enhancements for supporting large filesystems (64 bit) in keeping with -increasing disk capacities and state-of-the-art feature requirements. - -Mailing list: linux-ext4@vger.kernel.org - - -1. Quick usage instructions: -=========================== - - - Grab updated e2fsprogs from - ftp://ftp.kernel.org/pub/linux/kernel/people/tytso/e2fsprogs-interim/ - This is a patchset on top of e2fsprogs-1.39, which can be found at - ftp://ftp.kernel.org/pub/linux/kernel/people/tytso/e2fsprogs/ - - - It's still mke2fs -j /dev/hda1 - - - mount /dev/hda1 /wherever -t ext4dev - - - To enable extents, - - mount /dev/hda1 /wherever -t ext4dev -o extents - - - The filesystem is compatible with the ext3 driver until you add a file - which has extents (ie: `mount -o extents', then create a file). - - NOTE: The "extents" mount flag is temporary. It will soon go away and - extents will be enabled by the "-o extents" flag to mke2fs or tune2fs - - - When comparing performance with other filesystems, remember that - ext3/4 by default offers higher data integrity guarantees than most. So - when comparing with a metadata-only journalling filesystem, use `mount -o - data=writeback'. And you might as well use `mount -o nobh' too along - with it. Making the journal larger than the mke2fs default often helps - performance with metadata-intensive workloads. - -2. Features -=========== - -2.1 Currently available - -* ability to use filesystems > 16TB -* extent format reduces metadata overhead (RAM, IO for access, transactions) -* extent format more robust in face of on-disk corruption due to magics, -* internal redunancy in tree - -2.1 Previously available, soon to be enabled by default by "mkefs.ext4": - -* dir_index and resize inode will be on by default -* large inodes will be used by default for fast EAs, nsec timestamps, etc - -2.2 Candidate features for future inclusion - -There are several under discussion, whether they all make it in is -partly a function of how much time everyone has to work on them: - -* improved file allocation (multi-block alloc, delayed alloc; basically done) -* fix 32000 subdirectory limit (patch exists, needs some e2fsck work) -* nsec timestamps for mtime, atime, ctime, create time (patch exists, - needs some e2fsck work) -* inode version field on disk (NFSv4, Lustre; prototype exists) -* reduced mke2fs/e2fsck time via uninitialized groups (prototype exists) -* journal checksumming for robustness, performance (prototype exists) -* persistent file preallocation (e.g for streaming media, databases) - -Features like metadata checksumming have been discussed and planned for -a bit but no patches exist yet so I'm not sure they're in the near-term -roadmap. - -The big performance win will come with mballoc and delalloc. CFS has -been using mballoc for a few years already with Lustre, and IBM + Bull -did a lot of benchmarking on it. The reason it isn't in the first set of -patches is partly a manageability issue, and partly because it doesn't -directly affect the on-disk format (outside of much better allocation) -so it isn't critical to get into the first round of changes. I believe -Alex is working on a new set of patches right now. - -3. Options -========== - -When mounting an ext4 filesystem, the following option are accepted: -(*) == default - -extents ext4 will use extents to address file data. The - file system will no longer be mountable by ext3. - -journal=update Update the ext4 file system's journal to the current - format. - -journal=inum When a journal already exists, this option is ignored. - Otherwise, it specifies the number of the inode which - will represent the ext4 file system's journal file. - -journal_dev=devnum When the external journal device's major/minor numbers - have changed, this option allows the user to specify - the new journal location. The journal device is - identified through its new major/minor numbers encoded - in devnum. - -noload Don't load the journal on mounting. - -data=journal All data are committed into the journal prior to being - written into the main file system. - -data=ordered (*) All data are forced directly out to the main file - system prior to its metadata being committed to the - journal. - -data=writeback Data ordering is not preserved, data may be written - into the main file system after its metadata has been - committed to the journal. - -commit=nrsec (*) Ext4 can be told to sync all its data and metadata - every 'nrsec' seconds. The default value is 5 seconds. - This means that if you lose your power, you will lose - as much as the latest 5 seconds of work (your - filesystem will not be damaged though, thanks to the - journaling). This default value (or any low value) - will hurt performance, but it's good for data-safety. - Setting it to 0 will have the same effect as leaving - it at the default (5 seconds). - Setting it to very large values will improve - performance. - -barrier=1 This enables/disables barriers. barrier=0 disables - it, barrier=1 enables it. - -orlov (*) This enables the new Orlov block allocator. It is - enabled by default. - -oldalloc This disables the Orlov block allocator and enables - the old block allocator. Orlov should have better - performance - we'd like to get some feedback if it's - the contrary for you. - -user_xattr Enables Extended User Attributes. Additionally, you - need to have extended attribute support enabled in the - kernel configuration (CONFIG_EXT4_FS_XATTR). See the - attr(5) manual page and http://acl.bestbits.at/ to - learn more about extended attributes. - -nouser_xattr Disables Extended User Attributes. - -acl Enables POSIX Access Control Lists support. - Additionally, you need to have ACL support enabled in - the kernel configuration (CONFIG_EXT4_FS_POSIX_ACL). - See the acl(5) manual page and http://acl.bestbits.at/ - for more information. - -noacl This option disables POSIX Access Control List - support. - -reservation - -noreservation - -bsddf (*) Make 'df' act like BSD. -minixdf Make 'df' act like Minix. - -check=none Don't do extra checking of bitmaps on mount. -nocheck - -debug Extra debugging information is sent to syslog. - -errors=remount-ro(*) Remount the filesystem read-only on an error. -errors=continue Keep going on a filesystem error. -errors=panic Panic and halt the machine if an error occurs. - -grpid Give objects the same group ID as their creator. -bsdgroups - -nogrpid (*) New objects have the group ID of their creator. -sysvgroups - -resgid=n The group ID which may use the reserved blocks. - -resuid=n The user ID which may use the reserved blocks. - -sb=n Use alternate superblock at this location. - -quota -noquota -grpquota -usrquota - -bh (*) ext4 associates buffer heads to data pages to -nobh (a) cache disk block mapping information - (b) link pages into transaction to provide - ordering guarantees. - "bh" option forces use of buffer heads. - "nobh" option tries to avoid associating buffer - heads (supported only for "writeback" mode). - - -Data Mode ---------- -There are 3 different data modes: - -* writeback mode -In data=writeback mode, ext4 does not journal data at all. This mode provides -a similar level of journaling as that of XFS, JFS, and ReiserFS in its default -mode - metadata journaling. A crash+recovery can cause incorrect data to -appear in files which were written shortly before the crash. This mode will -typically provide the best ext4 performance. - -* ordered mode -In data=ordered mode, ext4 only officially journals metadata, but it logically -groups metadata and data blocks into a single unit called a transaction. When -it's time to write the new metadata out to disk, the associated data blocks -are written first. In general, this mode performs slightly slower than -writeback but significantly faster than journal mode. - -* journal mode -data=journal mode provides full data and metadata journaling. All new data is -written to the journal first, and then to its final location. -In the event of a crash, the journal can be replayed, bringing both data and -metadata into a consistent state. This mode is the slowest except when data -needs to be read from and written to disk at the same time where it -outperforms all others modes. - -References -========== - -kernel source: - - -programs: http://e2fsprogs.sourceforge.net/ - http://ext2resize.sourceforge.net - -useful links: http://fedoraproject.org/wiki/ext3-devel - http://www.bullopensource.org/ext4/ diff --git a/trunk/Documentation/filesystems/fuse.txt b/trunk/Documentation/filesystems/fuse.txt index 3d7447738958..a584f05403a4 100644 --- a/trunk/Documentation/filesystems/fuse.txt +++ b/trunk/Documentation/filesystems/fuse.txt @@ -111,7 +111,7 @@ For each connection the following files exist within this directory: 'waiting' - The number of requests which are waiting to be transferred to + The number of requests which are waiting to be transfered to userspace or being processed by the filesystem daemon. If there is no filesystem activity and 'waiting' is non-zero, then the filesystem is hung or deadlocked. @@ -136,7 +136,7 @@ following will happen: 2) If the request is not yet sent to userspace AND the signal is not fatal, then an 'interrupted' flag is set for the request. When - the request has been successfully transferred to userspace and + the request has been successfully transfered to userspace and this flag is set, an INTERRUPT request is queued. 3) If the request is already sent to userspace, then an INTERRUPT diff --git a/trunk/Documentation/filesystems/hpfs.txt b/trunk/Documentation/filesystems/hpfs.txt index 38aba03efc5e..33dc360c8e89 100644 --- a/trunk/Documentation/filesystems/hpfs.txt +++ b/trunk/Documentation/filesystems/hpfs.txt @@ -274,7 +274,7 @@ History Fixed race-condition in buffer code - it is in all filesystems in Linux; when reading device (cat /dev/hda) while creating files on it, files could be damaged -2.02 Workaround for bug in breada in Linux. breada could cause accesses beyond +2.02 Woraround for bug in breada in Linux. breada could cause accesses beyond end of partition 2.03 Char, block devices and pipes are correctly created Fixed non-crashing race in unlink (Alexander Viro) diff --git a/trunk/Documentation/filesystems/ntfs.txt b/trunk/Documentation/filesystems/ntfs.txt index 13ba649bda75..35f105b29e3e 100644 --- a/trunk/Documentation/filesystems/ntfs.txt +++ b/trunk/Documentation/filesystems/ntfs.txt @@ -337,7 +337,7 @@ Finally, for a mirrored volume, i.e. raid level 1, the table would look like this (note all values are in 512-byte sectors): --- cut here --- -# Ofs Size Raid Log Number Region Should Number Source Start Target Start +# Ofs Size Raid Log Number Region Should Number Source Start Taget Start # in of the type type of log size sync? of Device in Device in # vol volume params mirrors Device Device 0 2056320 mirror core 2 16 nosync 2 /dev/hda1 0 /dev/hdb1 0 @@ -599,7 +599,7 @@ Note, a technical ChangeLog aimed at kernel hackers is in fs/ntfs/ChangeLog. - Major bug fixes for reading files and volumes in corner cases which were being hit by Windows 2k/XP users. 2.1.2: - - Major bug fixes alleviating the hangs in statfs experienced by some + - Major bug fixes aleviating the hangs in statfs experienced by some users. 2.1.1: - Update handling of compressed files so people no longer get the diff --git a/trunk/Documentation/filesystems/ocfs2.txt b/trunk/Documentation/filesystems/ocfs2.txt index af6defd10cb6..4389c684a80a 100644 --- a/trunk/Documentation/filesystems/ocfs2.txt +++ b/trunk/Documentation/filesystems/ocfs2.txt @@ -30,7 +30,7 @@ Caveats Features which OCFS2 does not support yet: - sparse files - extended attributes - - shared writable mmap + - shared writeable mmap - loopback is supported, but data written will not be cluster coherent. - quotas diff --git a/trunk/Documentation/filesystems/proc.txt b/trunk/Documentation/filesystems/proc.txt index 72af5de1effb..3355e6920105 100644 --- a/trunk/Documentation/filesystems/proc.txt +++ b/trunk/Documentation/filesystems/proc.txt @@ -1220,9 +1220,9 @@ applications are using mlock(), or if you are running with no swap then you probably should increase the lower_zone_protection setting. The units of this tunable are fairly vague. It is approximately equal -to "megabytes," so setting lower_zone_protection=100 will protect around 100 +to "megabytes". So setting lower_zone_protection=100 will protect around 100 megabytes of the lowmem zone from user allocations. It will also make -those 100 megabytes unavailable for use by applications and by +those 100 megabytes unavaliable for use by applications and by pagecache, so there is a cost. The effects of this tunable may be observed by monitoring @@ -1538,10 +1538,10 @@ TCP settings tcp_ecn ------- -This file controls the use of the ECN bit in the IPv4 headers. This is a new +This file controls the use of the ECN bit in the IPv4 headers, this is a new feature about Explicit Congestion Notification, but some routers and firewalls -block traffic that has this bit set, so it could be necessary to echo 0 to -/proc/sys/net/ipv4/tcp_ecn if you want to talk to these sites. For more info +block trafic that has this bit set, so it could be necessary to echo 0 to +/proc/sys/net/ipv4/tcp_ecn, if you want to talk to this sites. For more info you could read RFC2481. tcp_retrans_collapse diff --git a/trunk/Documentation/filesystems/spufs.txt b/trunk/Documentation/filesystems/spufs.txt index 1343d118a9b2..982645a1981d 100644 --- a/trunk/Documentation/filesystems/spufs.txt +++ b/trunk/Documentation/filesystems/spufs.txt @@ -210,7 +210,7 @@ FILES /signal2 The two signal notification channels of an SPU. These are read-write files that operate on a 32 bit word. Writing to one of these files - triggers an interrupt on the SPU. The value written to the signal + triggers an interrupt on the SPU. The value writting to the signal files can be read from the SPU through a channel read or from host user space through the file. After the value has been read by the SPU, it is reset to zero. The possible operations on an open signal1 or sig- diff --git a/trunk/Documentation/filesystems/udf.txt b/trunk/Documentation/filesystems/udf.txt index fde829a756e6..511b4230c053 100644 --- a/trunk/Documentation/filesystems/udf.txt +++ b/trunk/Documentation/filesystems/udf.txt @@ -7,17 +7,8 @@ If you encounter problems with reading UDF discs using this driver, please report them to linux_udf@hpesjro.fc.hp.com, which is the developer's list. -Write support requires a block driver which supports writing. Currently -dvd+rw drives and media support true random sector writes, and so a udf -filesystem on such devices can be directly mounted read/write. CD-RW -media however, does not support this. Instead the media can be formatted -for packet mode using the utility cdrwtool, then the pktcdvd driver can -be bound to the underlying cd device to provide the required buffering -and read-modify-write cycles to allow the filesystem random sector writes -while providing the hardware with only full packet writes. While not -required for dvd+rw media, use of the pktcdvd driver often enhances -performance due to very poor read-modify-write support supplied internally -by drive firmware. +Write support requires a block driver which supports writing. The current +scsi and ide cdrom drivers do not support writing. ------------------------------------------------------------------------------- The following mount options are supported: diff --git a/trunk/Documentation/fujitsu/frv/gdbstub.txt b/trunk/Documentation/fujitsu/frv/gdbstub.txt index 9304fb36ae8a..6ce5aa9abbc5 100644 --- a/trunk/Documentation/fujitsu/frv/gdbstub.txt +++ b/trunk/Documentation/fujitsu/frv/gdbstub.txt @@ -59,7 +59,7 @@ the following things on the "Kernel Hacking" tab: Then build as usual, download to the board and execute. Note that if "Immediate activation" was selected, then the kernel will wait for GDB to attach. If not, then the kernel will boot immediately and GDB will have to -interrupt it or wait for an exception to occur before doing anything with +interupt it or wait for an exception to occur if before doing anything with the kernel. diff --git a/trunk/Documentation/fujitsu/frv/kernel-ABI.txt b/trunk/Documentation/fujitsu/frv/kernel-ABI.txt index aaa1cec86f0b..8b0a5fc8bfd9 100644 --- a/trunk/Documentation/fujitsu/frv/kernel-ABI.txt +++ b/trunk/Documentation/fujitsu/frv/kernel-ABI.txt @@ -156,7 +156,7 @@ with the main kernel in this regard. Hence the debug mode code (gdbstub) is almost completely self-contained. The only external code used is the sprintf family of functions. -Furthermore, break.S is so complicated because single-step mode does not +Futhermore, break.S is so complicated because single-step mode does not switch off on entry to an exception. That means unless manually disabled, single-stepping will blithely go on stepping into things like interrupts. See gdbstub.txt for more information. diff --git a/trunk/Documentation/hwmon/adm9240 b/trunk/Documentation/hwmon/adm9240 index 2c6f1fed4618..35f618f32896 100644 --- a/trunk/Documentation/hwmon/adm9240 +++ b/trunk/Documentation/hwmon/adm9240 @@ -24,7 +24,7 @@ Authors: Frodo Looijaard , Philip Edelbrock , Michiel Rook , - Grant Coady with guidance + Grant Coady with guidance from Jean Delvare Interface diff --git a/trunk/Documentation/hwmon/f71805f b/trunk/Documentation/hwmon/f71805f index 2ca69df669c3..28c5b7d1eb90 100644 --- a/trunk/Documentation/hwmon/f71805f +++ b/trunk/Documentation/hwmon/f71805f @@ -17,7 +17,7 @@ Thanks to Kris Chen from Fintek for answering technical questions and providing additional documentation. Thanks to Chris Lin from Jetway for providing wiring schematics and -answering technical questions. +anwsering technical questions. Description diff --git a/trunk/Documentation/hwmon/k8temp b/trunk/Documentation/hwmon/k8temp index 30d123b8d920..bab445ab0f52 100644 --- a/trunk/Documentation/hwmon/k8temp +++ b/trunk/Documentation/hwmon/k8temp @@ -2,7 +2,7 @@ Kernel driver k8temp ==================== Supported chips: - * AMD Athlon64/FX or Opteron CPUs + * AMD K8 CPU Prefix: 'k8temp' Addresses scanned: PCI space Datasheet: http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/32559.pdf @@ -13,13 +13,10 @@ Contact: Rudolf Marek Description ----------- -This driver permits reading temperature sensor(s) embedded inside AMD K8 -family CPUs (Athlon64/FX, Opteron). Official documentation says that it works -from revision F of K8 core, but in fact it seems to be implemented for all -revisions of K8 except the first two revisions (SH-B0 and SH-B3). - -Please note that you will need at least lm-sensors 2.10.1 for proper userspace -support. +This driver permits reading temperature sensor(s) embedded inside AMD K8 CPUs. +Official documentation says that it works from revision F of K8 core, but +in fact it seems to be implemented for all revisions of K8 except the first +two revisions (SH-B0 and SH-B3). There can be up to four temperature sensors inside single CPU. The driver will auto-detect the sensors and will display only temperatures from diff --git a/trunk/Documentation/hwmon/smsc47m1 b/trunk/Documentation/hwmon/smsc47m1 index 04a11124f667..c15bbe68264e 100644 --- a/trunk/Documentation/hwmon/smsc47m1 +++ b/trunk/Documentation/hwmon/smsc47m1 @@ -2,14 +2,12 @@ Kernel driver smsc47m1 ====================== Supported chips: - * SMSC LPC47B27x, LPC47M112, LPC47M10x, LPC47M13x, LPC47M14x, - LPC47M15x and LPC47M192 + * SMSC LPC47B27x, LPC47M10x, LPC47M13x, LPC47M14x, LPC47M15x and LPC47M192 Addresses scanned: none, address read from Super I/O config space Prefix: 'smsc47m1' Datasheets: http://www.smsc.com/main/datasheets/47b27x.pdf http://www.smsc.com/main/datasheets/47m10x.pdf - http://www.smsc.com/main/datasheets/47m112.pdf http://www.smsc.com/main/tools/discontinued/47m13x.pdf http://www.smsc.com/main/datasheets/47m14x.pdf http://www.smsc.com/main/tools/discontinued/47m15x.pdf diff --git a/trunk/Documentation/hwmon/w83627ehf b/trunk/Documentation/hwmon/w83627ehf index caa610a297e8..fae3b781d82d 100644 --- a/trunk/Documentation/hwmon/w83627ehf +++ b/trunk/Documentation/hwmon/w83627ehf @@ -26,7 +26,7 @@ fan control mode). Temperatures are measured in degrees Celsius and measurement resolution is 1 degC for temp1 and 0.5 degC for temp2 and temp3. An alarm is triggered when the temperature gets higher than high limit; it stays on until the temperature -falls below the hysteresis value. +falls below the Hysteresis value. Fan rotation speeds are reported in RPM (rotations per minute). An alarm is triggered if the rotation speed has dropped below a programmable limit. Fan @@ -67,9 +67,9 @@ Thermal Cruise mode If the temperature is in the range defined by: -pwm[1-4]_target - set target temperature, unit millidegree Celsius +pwm[1-4]_target - set target temperature, unit millidegree Celcius (range 0 - 127000) -pwm[1-4]_tolerance - tolerance, unit millidegree Celsius (range 0 - 15000) +pwm[1-4]_tolerance - tolerance, unit millidegree Celcius (range 0 - 15000) there are no changes to fan speed. Once the temperature leaves the interval, fan speed increases (temp is higher) or decreases if lower than desired. diff --git a/trunk/Documentation/ibm-acpi.txt b/trunk/Documentation/ibm-acpi.txt index e50595bfd8ea..71aa40345272 100644 --- a/trunk/Documentation/ibm-acpi.txt +++ b/trunk/Documentation/ibm-acpi.txt @@ -30,10 +30,9 @@ detailed description): - ACPI sounds - temperature sensors - Experimental: embedded controller register dump - - LCD brightness control - - Volume control + - Experimental: LCD brightness control + - Experimental: volume control - Experimental: fan speed, fan enable/disable - - Experimental: WAN enable and disable A compatibility table by model and feature is maintained on the web site, http://ibm-acpi.sf.net/. I appreciate any success or failure @@ -53,7 +52,40 @@ Installation If you are compiling this driver as included in the Linux kernel sources, simply enable the CONFIG_ACPI_IBM option (Power Management / -ACPI / IBM ThinkPad Laptop Extras). +ACPI / IBM ThinkPad Laptop Extras). The rest of this section describes +how to install this driver when downloaded from the web site. + +First, you need to get a kernel with ACPI support up and running. +Please refer to http://acpi.sourceforge.net/ for help with this +step. How successful you will be depends a lot on you ThinkPad model, +the kernel you are using and any additional patches applied. The +kernel provided with your distribution may not be good enough. I +needed to compile a 2.6.7 kernel with the 20040715 ACPI patch to get +ACPI working reliably on my ThinkPad X40. Old ThinkPad models may not +be supported at all. + +Assuming you have the basic ACPI support working (e.g. you can see the +/proc/acpi directory), follow the following steps to install this +driver: + + - unpack the archive: + + tar xzvf ibm-acpi-x.y.tar.gz; cd ibm-acpi-x.y + + - compile the driver: + + make + + - install the module in your kernel modules directory: + + make install + + - load the module: + + modprobe ibm_acpi + +After loading the module, check the "dmesg" output for any error messages. + Features -------- @@ -491,8 +523,13 @@ registers contain the current battery capacity, etc. If you experiment with this, do send me your results (including some complete dumps with a description of the conditions when they were taken.) -LCD brightness control -- /proc/acpi/ibm/brightness ---------------------------------------------------- +EXPERIMENTAL: LCD brightness control -- /proc/acpi/ibm/brightness +----------------------------------------------------------------- + +This feature is marked EXPERIMENTAL because the implementation +directly accesses hardware registers and may not work as expected. USE +WITH CAUTION! To use this feature, you need to supply the +experimental=1 parameter when loading the module. This feature allows software control of the LCD brightness on ThinkPad models which don't have a hardware brightness slider. The available @@ -505,8 +542,13 @@ commands are: The number range is 0 to 7, although not all of them may be distinct. The current brightness level is shown in the file. -Volume control -- /proc/acpi/ibm/volume ---------------------------------------- +EXPERIMENTAL: Volume control -- /proc/acpi/ibm/volume +----------------------------------------------------- + +This feature is marked EXPERIMENTAL because the implementation +directly accesses hardware registers and may not work as expected. USE +WITH CAUTION! To use this feature, you need to supply the +experimental=1 parameter when loading the module. This feature allows volume control on ThinkPad models which don't have a hardware volume knob. The available commands are: @@ -569,23 +611,6 @@ with the following command: echo 'level ' > /proc/acpi/ibm/thermal -EXPERIMENTAL: WAN -- /proc/acpi/ibm/wan ---------------------------------------- - -This feature is marked EXPERIMENTAL because the implementation -directly accesses hardware registers and may not work as expected. USE -WITH CAUTION! To use this feature, you need to supply the -experimental=1 parameter when loading the module. - -This feature shows the presence and current state of a WAN (Sierra -Wireless EV-DO) device. If WAN is installed, the following commands can -be used: - - echo enable > /proc/acpi/ibm/wan - echo disable > /proc/acpi/ibm/wan - -It was tested on a Lenovo Thinkpad X60. It should probably work on other -Thinkpad models which come with this module installed. Multiple Commands, Module Parameters ------------------------------------ diff --git a/trunk/Documentation/ide.txt b/trunk/Documentation/ide.txt index 786c3a766995..0bf38baa2db9 100644 --- a/trunk/Documentation/ide.txt +++ b/trunk/Documentation/ide.txt @@ -390,5 +390,5 @@ mlord@pobox.com Wed Apr 17 22:52:44 CEST 2002 edited by Marcin Dalecki, the current maintainer. -Wed Aug 20 22:31:29 CEST 2003 updated ide boot options to current ide.c +Wed Aug 20 22:31:29 CEST 2003 updated ide boot uptions to current ide.c comments at 2.6.0-test4 time. Maciej Soltysiak diff --git a/trunk/Documentation/input/amijoy.txt b/trunk/Documentation/input/amijoy.txt index 7dc4f175943c..4f0e89df5c51 100644 --- a/trunk/Documentation/input/amijoy.txt +++ b/trunk/Documentation/input/amijoy.txt @@ -91,8 +91,8 @@ JOY1DAT Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 X7 X6 X5 X4 X3 X2 X1 X0 | 1 | M0HQ | JOY0DAT Horizontal Clock (quadrature) | | 2 | M0V | JOY0DAT Vertical Clock | | 3 | M0VQ | JOY0DAT Vertical Clock (quadrature) | - | 4 | M1V | JOY1DAT Horizontal Clock | - | 5 | M1VQ | JOY1DAT Horizontal Clock (quadrature) | + | 4 | M1V | JOY1DAT Horizontall Clock | + | 5 | M1VQ | JOY1DAT Horizontall Clock (quadrature) | | 6 | M1V | JOY1DAT Vertical Clock | | 7 | M1VQ | JOY1DAT Vertical Clock (quadrature) | +--------+----------+-----------------------------------------+ diff --git a/trunk/Documentation/input/atarikbd.txt b/trunk/Documentation/input/atarikbd.txt index 668f4d0d97d6..1e7e5853ba4c 100644 --- a/trunk/Documentation/input/atarikbd.txt +++ b/trunk/Documentation/input/atarikbd.txt @@ -103,7 +103,7 @@ LEFT=0x74 & RIGHT=0x75). 5.1 Joystick Event Reporting -In this mode, the ikbd generates a record whenever the joystick position is +In this mode, the ikbd generates a record whever the joystick position is changed (i.e. for each opening or closing of a joystick switch or trigger). The joystick event record is two bytes of the form: @@ -277,8 +277,8 @@ default to 1 at RESET (or power-up). 9.7 SET MOUSE SCALE 0x0C - X ; horizontal mouse ticks per internal X - Y ; vertical mouse ticks per internal Y + X ; horizontal mouse ticks per internel X + Y ; vertical mouse ticks per internel Y This command sets the scale factor for the ABSOLUTE MOUSE POSITIONING mode. In this mode, the specified number of mouse phase changes ('clicks') must @@ -323,7 +323,7 @@ mouse position. 0x0F This command makes the origin of the Y axis to be at the bottom of the -logical coordinate system internal to the ikbd for all relative or absolute +logical coordinate system internel to the ikbd for all relative or absolute mouse motion. This causes mouse motion toward the user to be negative in sign and away from the user to be positive. @@ -597,8 +597,8 @@ mode or FIRE BUTTON MONITORING mode. 10. SCAN CODES -The key scan codes returned by the ikbd are chosen to simplify the -implementation of GSX. +The key scan codes return by the ikbd are chosen to simplify the +implementaion of GSX. GSX Standard Keyboard Mapping. diff --git a/trunk/Documentation/input/xpad.txt b/trunk/Documentation/input/xpad.txt index 5427bdf225ed..b9111a703ce0 100644 --- a/trunk/Documentation/input/xpad.txt +++ b/trunk/Documentation/input/xpad.txt @@ -3,37 +3,20 @@ xpad - Linux USB driver for X-Box gamepads This is the very first release of a driver for X-Box gamepads. Basically, this was hacked away in just a few hours, so don't expect miracles. - In particular, there is currently NO support for the rumble pack. You won't find many ff-aware linux applications anyway. -0. Notes --------- - -Driver updated for kernel 2.6.17.11. (Based on a patch for 2.6.11.4.) - -The number of buttons/axes reported varies based on 3 things: -- if you are using a known controller -- if you are using a known dance pad -- if using an unknown device (one not listed below), what you set in the - module configuration for "Map D-PAD to buttons rather than axes for unknown - pads" (module option dpad_to_buttons) - -If you set dpad_to_buttons to 0 and you are using an unknown device (one -not listed below), the driver will map the directional pad to axes (X/Y), -if you said N it will map the d-pad to buttons, which is needed for dance -style games to function correctly. The default is Y. +0. Status +--------- -dpad_to_buttons has no effect for known pads. +For now, this driver has only been tested on just one Linux-Box. +This one is running a 2.4.18 kernel with usb-uhci on an amd athlon 600. -0.1 Normal Controllers ----------------------- -With a normal controller, the directional pad is mapped to its own X/Y axes. -The jstest-program from joystick-1.2.15 (jstest-version 2.1.0) will report 8 -axes and 10 buttons. +The jstest-program from joystick-1.2.15 (jstest-version 2.1.0) reports +8 axes and 10 buttons. -All 8 axes work, though they all have the same range (-32768..32767) +Alls 8 axes work, though they all have the same range (-32768..32767) and the zero-setting is not correct for the triggers (I don't know if that is some limitation of jstest, since the input device setup should be fine. I didn't have a look at jstest itself yet). @@ -47,50 +30,16 @@ in game functionality were OK. However, I find it rather difficult to play first person shooters with a pad. Your mileage may vary. -0.2 Xbox Dance Pads -------------------- -When using a known dance pad, jstest will report 6 axes and 14 buttons. - -For dance style pads (like the redoctane pad) several changes -have been made. The old driver would map the d-pad to axes, resulting -in the driver being unable to report when the user was pressing both -left+right or up+down, making DDR style games unplayable. - -Known dance pads automatically map the d-pad to buttons and will work -correctly out of the box. - -If your dance pad is recognized by the driver but is using axes instead -of buttons, see section 0.3 - Unknown Controllers - -I've tested this with Stepmania, and it works quite well. - - -0.3 Unkown Controllers ----------------------- -If you have an unkown xbox controller, it should work just fine with -the default settings. - -HOWEVER if you have an unknown dance pad not listed below, it will not -work UNLESS you set "dpad_to_buttons" to 1 in the module configuration. - -PLEASE if you have an unkown controller, email Dom with -a dump from /proc/bus/usb and a description of the pad (manufacturer, country, -whether it is a dance pad or normal controller) so that we can add your pad -to the list of supported devices, ensuring that it will work out of the -box in the future. - - 1. USB adapter -------------- Before you can actually use the driver, you need to get yourself an -adapter cable to connect the X-Box controller to your Linux-Box. You -can buy these online fairly cheap, or build your own. +adapter cable to connect the X-Box controller to your Linux-Box. -Such a cable is pretty easy to build. The Controller itself is a USB -compound device (a hub with three ports for two expansion slots and -the controller device) with the only difference in a nonstandard connector -(5 pins vs. 4 on standard USB connector). +Such a cable is pretty easy to build. The Controller itself is a USB compound +device (a hub with three ports for two expansion slots and the controller +device) with the only difference in a nonstandard connector (5 pins vs. 4 on +standard USB connector). You just need to solder a USB connector onto the cable and keep the yellow wire unconnected. The other pins have the same order on both @@ -102,36 +51,36 @@ original one. You can buy an extension cable and cut that instead. That way, you can still use the controller with your X-Box, if you have one ;) -2. Driver Installation +2. driver installation ---------------------- Once you have the adapter cable and the controller is connected, you need to load your USB subsystem and should cat /proc/bus/usb/devices. There should be an entry like the one at the end [4]. -Currently (as of version 0.0.6), the following devices are included: +Currently (as of version 0.0.4), the following three devices are included: original Microsoft XBOX controller (US), vendor=0x045e, product=0x0202 - smaller Microsoft XBOX controller (US), vendor=0x045e, product=0x0289 original Microsoft XBOX controller (Japan), vendor=0x045e, product=0x0285 InterAct PowerPad Pro (Germany), vendor=0x05fd, product=0x107a - RedOctane Xbox Dance Pad (US), vendor=0x0c12, product=0x8809 -The driver should work with xbox pads not listed above as well, however -you will need to do something extra for dance pads to work. +If you have another controller that is not listed above and is not recognized +by the driver, please drop me a line with the appropriate info (that is, include +the name, vendor and product ID, as well as the country where you bought it; +sending the whole dump out of /proc/bus/usb/devices along would be even better). -If you have a controller not listed above, see 0.3 - Unknown Controllers +In theory, the driver should work with other controllers than mine +(InterAct PowerPad pro, bought in Germany) just fine, but I cannot test this +for I only have this one controller. If you compiled and installed the driver, test the functionality: > modprobe xpad > modprobe joydev > jstest /dev/js0 -If you're using a normal controller, there should be a single line showing -18 inputs (8 axes, 10 buttons), and its values should change if you move -the sticks and push the buttons. If you're using a dance pad, it should -show 20 inputs (6 axes, 14 buttons). +There should be a single line showing 18 inputs (8 axes, 10 buttons), and +it's values should change if you move the sticks and push the buttons. -It works? Voila, you're done ;) +It works? Voila, your done ;) 3. Thanks @@ -162,22 +111,6 @@ I: If#= 0 Alt= 0 #EPs= 2 Cls=58(unk. ) Sub=42 Prot=00 Driver=(none) E: Ad=81(I) Atr=03(Int.) MxPS= 32 Ivl= 10ms E: Ad=02(O) Atr=03(Int.) MxPS= 32 Ivl= 10ms -5. /proc/bus/usb/devices - dump from Redoctane Xbox Dance Pad (US): - -T: Bus=01 Lev=02 Prnt=09 Port=00 Cnt=01 Dev#= 10 Spd=12 MxCh= 0 -D: Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1 -P: Vendor=0c12 ProdID=8809 Rev= 0.01 -S: Product=XBOX DDR -C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=100mA -I: If#= 0 Alt= 0 #EPs= 2 Cls=58(unk. ) Sub=42 Prot=00 Driver=xpad -E: Ad=82(I) Atr=03(Int.) MxPS= 32 Ivl=4ms -E: Ad=02(O) Atr=03(Int.) MxPS= 32 Ivl=4ms - -- Marko Friedemann 2002-07-16 - - original doc - -Dominic Cerquetti -2005-03-19 - - added stuff for dance pads, new d-pad->axes mappings diff --git a/trunk/Documentation/input/yealink.txt b/trunk/Documentation/input/yealink.txt index 5360e434486c..0a8c97e87d47 100644 --- a/trunk/Documentation/input/yealink.txt +++ b/trunk/Documentation/input/yealink.txt @@ -134,7 +134,7 @@ Reading /sys/../lineX will return the format string with its current value: 888888888888 Linux Rocks! -Writing to /sys/../lineX will set the corresponding LCD line. +Writing to /sys/../lineX will set the coresponding LCD line. - Excess characters are ignored. - If less characters are written than allowed, the remaining digits are unchanged. diff --git a/trunk/Documentation/ioctl/cdrom.txt b/trunk/Documentation/ioctl/cdrom.txt index 62d4af44ec4a..8ec32cc49eb1 100644 --- a/trunk/Documentation/ioctl/cdrom.txt +++ b/trunk/Documentation/ioctl/cdrom.txt @@ -735,7 +735,7 @@ CDROM_DISC_STATUS Get disc type, etc. Ok, this is where problems start. The current interface for the CDROM_DISC_STATUS ioctl is flawed. It makes the false assumption that CDs are all CDS_DATA_1 or all CDS_AUDIO, etc. - Unfortunately, while this is often the case, it is also + Unfortunatly, while this is often the case, it is also very common for CDs to have some tracks with data, and some tracks with audio. Just because I feel like it, I declare the following to be the best way to cope. If the CD has diff --git a/trunk/Documentation/kbuild/makefiles.txt b/trunk/Documentation/kbuild/makefiles.txt index 4b3d6710c504..50f4eddf899c 100644 --- a/trunk/Documentation/kbuild/makefiles.txt +++ b/trunk/Documentation/kbuild/makefiles.txt @@ -227,9 +227,9 @@ more details, with real examples. be included in a library, lib.a. All objects listed with lib-y are combined in a single library for that directory. - Objects that are listed in obj-y and additionally listed in - lib-y will not be included in the library, since they will - be accessible anyway. + Objects that are listed in obj-y and additionaly listed in + lib-y will not be included in the library, since they will anyway + be accessible. For consistency, objects listed in lib-m will be included in lib.a. Note that the same kbuild makefile may list files to be built-in @@ -535,7 +535,7 @@ Both possibilities are described in the following. Host programs can be made up based on composite objects. The syntax used to define composite objects for host programs is similar to the syntax used for kernel objects. - $(-objs) lists all objects used to link the final + $(-objs) lists all objects used to link the final executable. Example: @@ -1022,7 +1022,7 @@ When kbuild executes, the following steps are followed (roughly): In this example, there are two possible targets, requiring different options to the linker. The linker options are specified using the LDFLAGS_$@ syntax - one for each potential target. - $(targets) are assigned all potential targets, by which kbuild knows + $(targets) are assinged all potential targets, by which kbuild knows the targets and will: 1) check for commandline changes 2) delete target during make clean diff --git a/trunk/Documentation/kernel-doc-nano-HOWTO.txt b/trunk/Documentation/kernel-doc-nano-HOWTO.txt index 284e7e198e93..c65233d430f0 100644 --- a/trunk/Documentation/kernel-doc-nano-HOWTO.txt +++ b/trunk/Documentation/kernel-doc-nano-HOWTO.txt @@ -17,7 +17,7 @@ are: special place-holders for where the extracted documentation should go. -- scripts/basic/docproc.c +- scripts/docproc.c This is a program for converting SGML template files into SGML files. When a file is referenced it is searched for symbols diff --git a/trunk/Documentation/kernel-parameters.txt b/trunk/Documentation/kernel-parameters.txt index 67473849f20e..ff571f9298e0 100644 --- a/trunk/Documentation/kernel-parameters.txt +++ b/trunk/Documentation/kernel-parameters.txt @@ -164,10 +164,6 @@ and is between 256 and 4096 characters. It is defined in the file acpi_skip_timer_override [HW,ACPI] Recognize and ignore IRQ0/pin2 Interrupt Override. For broken nForce2 BIOS resulting in XT-PIC timer. - acpi_use_timer_override [HW,ACPI} - Use timer override. For some broken Nvidia NF5 boards - that require a timer override, but don't have - HPET acpi_dbg_layer= [HW,ACPI] Format: @@ -1235,11 +1231,6 @@ and is between 256 and 4096 characters. It is defined in the file machine check when some devices' config space is read. But various workarounds are disabled and some IOMMU drivers will not work. - bfsort Sort PCI devices into breadth-first order. - This sorting is done to get a device - order compatible with older (<= 2.4) kernels. - nobfsort Don't sort PCI devices into breadth-first order. - pcmv= [HW,PCMCIA] BadgePAD 4 pd. [PARIDE] diff --git a/trunk/Documentation/keys.txt b/trunk/Documentation/keys.txt index 60c665d9cfaa..3da586bc7859 100644 --- a/trunk/Documentation/keys.txt +++ b/trunk/Documentation/keys.txt @@ -304,7 +304,7 @@ about the status of the key service: R Revoked D Dead Q Contributes to user's quota - U Under construction by callback to userspace + U Under contruction by callback to userspace N Negative key This file must be enabled at kernel configuration time as it allows anyone diff --git a/trunk/Documentation/kprobes.txt b/trunk/Documentation/kprobes.txt index d71fafffce90..ba26201d5023 100644 --- a/trunk/Documentation/kprobes.txt +++ b/trunk/Documentation/kprobes.txt @@ -442,10 +442,9 @@ static int __init kprobe_init(void) kp.fault_handler = handler_fault; kp.symbol_name = "do_fork"; - ret = register_kprobe(&kp); - if (ret < 0) { + if ((ret = register_kprobe(&kp) < 0)) { printk("register_kprobe failed, returned %d\n", ret); - return ret; + return -1; } printk("kprobe registered\n"); return 0; diff --git a/trunk/Documentation/laptop-mode.txt b/trunk/Documentation/laptop-mode.txt index 6f639e3473af..c487186eb2b9 100644 --- a/trunk/Documentation/laptop-mode.txt +++ b/trunk/Documentation/laptop-mode.txt @@ -121,7 +121,7 @@ contains the following options: MAX_AGE: Maximum time, in seconds, of hard drive spindown time that you are -comfortable with. Worst case, it's possible that you could lose this +confortable with. Worst case, it's possible that you could lose this amount of work if your battery fails while you're in laptop mode. MINIMUM_BATTERY_MINUTES: @@ -235,7 +235,7 @@ It should be installed as /etc/default/laptop-mode on Debian, and as --------------------CONFIG FILE BEGIN------------------------------------------- # Maximum time, in seconds, of hard drive spindown time that you are -# comfortable with. Worst case, it's possible that you could lose this +# confortable with. Worst case, it's possible that you could lose this # amount of work if your battery fails you while in laptop mode. #MAX_AGE=600 @@ -350,7 +350,7 @@ fi # set defaults instead: # Maximum time, in seconds, of hard drive spindown time that you are -# comfortable with. Worst case, it's possible that you could lose this +# confortable with. Worst case, it's possible that you could lose this # amount of work if your battery fails you while in laptop mode. MAX_AGE=${MAX_AGE:-'600'} @@ -699,7 +699,7 @@ ACPI integration Dax Kelson submitted this so that the ACPI acpid daemon will kick off the laptop_mode script and run hdparm. The part that automatically disables laptop mode when the battery is low was -written by Jan Topinski. +writen by Jan Topinski. -----------------/etc/acpi/events/ac_adapter BEGIN------------------------------ event=ac_adapter diff --git a/trunk/Documentation/lockdep-design.txt b/trunk/Documentation/lockdep-design.txt index 488773018152..dab123db5a4f 100644 --- a/trunk/Documentation/lockdep-design.txt +++ b/trunk/Documentation/lockdep-design.txt @@ -50,10 +50,10 @@ The bit position indicates hardirq, softirq, hardirq-read, softirq-read respectively, and the character displayed in each indicates: - '.' acquired while irqs disabled + '.' acquired while irqs enabled '+' acquired in irq context - '-' acquired with irqs enabled - '?' read acquired in irq context with irqs enabled. + '-' acquired in process context with irqs disabled + '?' read-acquired both with irqs enabled and in irq context Unused mutexes cannot be part of the cause of an error. diff --git a/trunk/Documentation/memory-barriers.txt b/trunk/Documentation/memory-barriers.txt index 58408dd023c7..994355b0cd19 100644 --- a/trunk/Documentation/memory-barriers.txt +++ b/trunk/Documentation/memory-barriers.txt @@ -212,7 +212,7 @@ There are some minimal guarantees that may be expected of a CPU: STORE *X = c, d = LOAD *X - (Loads and stores overlap if they are targeted at overlapping pieces of + (Loads and stores overlap if they are targetted at overlapping pieces of memory). And there are a number of things that _must_ or _must_not_ be assumed: @@ -1016,7 +1016,7 @@ There are some more advanced barrier functions: (*) set_mb(var, value) - This assigns the value to the variable and then inserts a full memory + This assigns the value to the variable and then inserts at least a write barrier after it, depending on the function. It isn't guaranteed to insert anything more than a compiler barrier in a UP compilation. @@ -1898,7 +1898,7 @@ queue before processing any further requests: smp_wmb(); - p = &v; q = p; + p = &b; q = p; diff --git a/trunk/Documentation/mips/time.README b/trunk/Documentation/mips/time.README index a4ce603ed3b3..69ddc5c14b79 100644 --- a/trunk/Documentation/mips/time.README +++ b/trunk/Documentation/mips/time.README @@ -38,14 +38,19 @@ The new time code provide the following services: a) Implements functions required by Linux common code: time_init + do_gettimeofday + do_settimeofday b) provides an abstraction of RTC and null RTC implementation as default. extern unsigned long (*rtc_get_time)(void); extern int (*rtc_set_time)(unsigned long); - c) high-level and low-level timer interrupt routines where the timer - interrupt source may or may not be the CPU timer. The high-level - routine is dispatched through do_IRQ() while the low-level is + c) a set of gettimeoffset functions for different CPUs and different + needs. + + d) high-level and low-level timer interrupt routines where the timer + interrupt source may or may not be the CPU timer. The high-level + routine is dispatched through do_IRQ() while the low-level is dispatched in assemably code (usually int-handler.S) @@ -58,7 +63,7 @@ the following functions or values: a) board_time_init - a function pointer. Invoked at the beginnig of time_init(). It is optional. 1. (optional) set up RTC routines - 2. (optional) calibrate and set the mips_hpt_frequency + 2. (optional) calibrate and set the mips_counter_frequency b) plat_timer_setup - a function pointer. Invoked at the end of time_init() 1. (optional) over-ride any decisions made in time_init() @@ -67,8 +72,9 @@ the following functions or values: c) (optional) board-specific RTC routines. - d) (optional) mips_hpt_frequency - It must be definied if the board - is using CPU counter for timer interrupt. + d) (optional) mips_counter_frequency - It must be definied if the board + is using CPU counter for timer interrupt or it is using fixed rate + gettimeoffset(). PORTING GUIDE @@ -83,12 +89,22 @@ Step 1: decide how you like to implement the time services. If the answer is no, you need a timer to provide the timer interrupt at 100 HZ speed. + You cannot use the fast gettimeoffset functions, i.e., + + unsigned long fixed_rate_gettimeoffset(void); + unsigned long calibrate_div32_gettimeoffset(void); + unsigned long calibrate_div64_gettimeoffset(void); + + You can use null_gettimeoffset() will gives the same time resolution as + jiffy. Or you can implement your own gettimeoffset (probably based on + some ad hoc hardware on your machine.) + c) The following sub steps assume your CPU has counter register. Do you plan to use the CPU counter register as the timer interrupt or use an exnternal timer? In order to use CPU counter register as the timer interrupt source, you - must know the counter speed (mips_hpt_frequency). It is usually the + must know the counter speed (mips_counter_frequency). It is usually the same as the CPU speed or an integral divisor of it. d) decide on whether you want to use high-level or low-level timer @@ -105,10 +121,10 @@ Step 3: implement rtc routines, board_time_init() and plat_timer_setup() if needed. board_time_init() - - a) (optional) set up RTC routines, - b) (optional) calibrate and set the mips_hpt_frequency - (only needed if you intended to use cpu counter as timer interrupt - source) + a) (optional) set up RTC routines, + b) (optional) calibrate and set the mips_counter_frequency + (only needed if you intended to use fixed_rate_gettimeoffset + or use cpu counter as timer interrupt source) plat_timer_setup() - a) (optional) over-write any choices made above by time_init(). @@ -138,8 +154,8 @@ for some of the functions in time.c. For example, you may define your own timer interrupt routine, which does some of its own processing and then calls timer_interrupt(). -You can also over-ride any of the built-in functions (RTC routines -and/or timer interrupt routine). +You can also over-ride any of the built-in functions (gettimeoffset, +RTC routines and/or timer interrupt routine). PORTING NOTES FOR SMP @@ -171,3 +187,10 @@ You need to decide on your timer interrupt sources. You can also do the low-level version of those interrupt routines, following similar dispatching routes described above. + +Note about do_gettimeoffset(): + + It is very likely the CPU counter registers are not sync'ed up in a SMP box. + Therefore you cannot really use the many of the existing routines that + are based on CPU counter. You should wirte your own gettimeoffset rouinte + if you want intra-jiffy resolution. diff --git a/trunk/Documentation/networking/NAPI_HOWTO.txt b/trunk/Documentation/networking/NAPI_HOWTO.txt index fb8dc6422a52..93af3e87c65b 100644 --- a/trunk/Documentation/networking/NAPI_HOWTO.txt +++ b/trunk/Documentation/networking/NAPI_HOWTO.txt @@ -95,8 +95,8 @@ There are two types of event register ACK mechanisms. Move all to dev->poll() C) Ability to detect new work correctly. -NAPI works by shutting down event interrupts when there's work and -turning them on when there's none. +NAPI works by shutting down event interrupts when theres work and +turning them on when theres none. New packets might show up in the small window while interrupts were being re-enabled (refer to appendix 2). A packet might sneak in during the period we are enabling interrupts. We only get to know about such a packet when the @@ -114,7 +114,7 @@ Locking rules and environmental guarantees only one CPU can pick the initial interrupt and hence the initial netif_rx_schedule(dev); - The core layer invokes devices to send packets in a round robin format. -This implies receive is totally lockless because of the guarantee that only +This implies receive is totaly lockless because of the guarantee only that one CPU is executing it. - contention can only be the result of some other CPU accessing the rx ring. This happens only in close() and suspend() (when these methods @@ -510,7 +510,7 @@ static int my_poll (struct net_device *dev, int *budget) an interrupt will be generated */ goto done; } - /* done! at least that's what it looks like ;-> + /* done! at least thats what it looks like ;-> if new packets came in after our last check on status bits they'll be caught by the while check and we go back and clear them since we havent exceeded our quota */ @@ -535,11 +535,11 @@ done: * 1. it can race with disabling irqs in irq handler (which are done to * schedule polls) * 2. it can race with dis/enabling irqs in other poll threads - * 3. if an irq raised after the beginning of the outer beginning - * loop (marked in the code above), it will be immediately + * 3. if an irq raised after the begining of the outer beginning + * loop(marked in the code above), it will be immediately * triggered here. * - * Summarizing: the logic may result in some redundant irqs both + * Summarizing: the logic may results in some redundant irqs both * due to races in masking and due to too late acking of already * processed irqs. The good news: no events are ever lost. */ @@ -601,7 +601,7 @@ a) 5) dev->close() and dev->suspend() issues ========================================== -The driver writer needn't worry about this; the top net layer takes +The driver writter neednt worry about this. The top net layer takes care of it. 6) Adding new Stats to /proc @@ -622,9 +622,9 @@ FC should be programmed to apply in the case when the system cant pull out packets fast enough i.e send a pause only when you run out of rx buffers. Note FC in itself is a good solution but we have found it to not be much of a commodity feature (both in NICs and switches) and hence falls -under the same category as using NIC based mitigation. Also, experiments -indicate that it's much harder to resolve the resource allocation -issue (aka lazy receiving that NAPI offers) and hence quantify its usefulness +under the same category as using NIC based mitigation. Also experiments +indicate that its much harder to resolve the resource allocation +issue (aka lazy receiving that NAPI offers) and hence quantify its usefullness proved harder. In any case, FC works even better with NAPI but is not necessary. @@ -678,10 +678,10 @@ routine: CSR5 bit of interest is only the rx status. If you look at the last if statement: you just finished grabbing all the packets from the rx ring .. you check if -status bit says there are more packets just in ... it says none; you then +status bit says theres more packets just in ... it says none; you then enable rx interrupts again; if a new packet just came in during this check, we are counting that CSR5 will be set in that small window of opportunity -and that by re-enabling interrupts, we would actually trigger an interrupt +and that by re-enabling interrupts, we would actually triger an interrupt to register the new packet for processing. [The above description nay be very verbose, if you have better wording diff --git a/trunk/Documentation/networking/cs89x0.txt b/trunk/Documentation/networking/cs89x0.txt index 6387d3decf85..64896470e279 100644 --- a/trunk/Documentation/networking/cs89x0.txt +++ b/trunk/Documentation/networking/cs89x0.txt @@ -248,7 +248,7 @@ c) The driver's hardware probe routine is designed to avoid with device probing. To avoid this behaviour, add one to the `io=' module parameter. This doesn't actually change the I/O address, but it is a flag to tell the driver - to partially initialise the hardware before trying to + topartially initialise the hardware before trying to identify the card. This could be dangerous if you are not sure that there is a cs89x0 card at the provided address. @@ -620,8 +620,8 @@ I/O Address Device IRQ Device 12 Mouse (PS/2) Memory Address Device 13 Math Coprocessor -------------- --------------------- 14 Hard Disk controller -A000-BFFF EGA Graphics Adapter -A000-C7FF VGA Graphics Adapter +A000-BFFF EGA Graphics Adpater +A000-C7FF VGA Graphics Adpater B000-BFFF Mono Graphics Adapter B800-BFFF Color Graphics Adapter E000-FFFF AT BIOS diff --git a/trunk/Documentation/networking/iphase.txt b/trunk/Documentation/networking/iphase.txt index 55eac4a784e2..493203a080a8 100644 --- a/trunk/Documentation/networking/iphase.txt +++ b/trunk/Documentation/networking/iphase.txt @@ -81,7 +81,7 @@ Installation 1M. The RAM size decides the number of buffers and buffer size. The default size and number of buffers are set as following: - Total Rx RAM Tx RAM Rx Buf Tx Buf Rx buf Tx buf + Totol Rx RAM Tx RAM Rx Buf Tx Buf Rx buf Tx buf RAM size size size size size cnt cnt -------- ------ ------ ------ ------ ------ ------ 128K 64K 64K 10K 10K 6 6 diff --git a/trunk/Documentation/networking/packet_mmap.txt b/trunk/Documentation/networking/packet_mmap.txt index 5a232d946be3..12a008a5c221 100644 --- a/trunk/Documentation/networking/packet_mmap.txt +++ b/trunk/Documentation/networking/packet_mmap.txt @@ -284,7 +284,7 @@ the necessary memory, so normally limits can be reached. ------------------- If you check the source code you will see that what I draw here as a frame -is not only the link level frame. At the beginning of each frame there is a +is not only the link level frame. At the begining of each frame there is a header called struct tpacket_hdr used in PACKET_MMAP to hold link level's frame meta information like timestamp. So what we draw here a frame it's really the following (from include/linux/if_packet.h): diff --git a/trunk/Documentation/networking/pktgen.txt b/trunk/Documentation/networking/pktgen.txt index c6cf4a3c16e0..c8eee23be8c0 100644 --- a/trunk/Documentation/networking/pktgen.txt +++ b/trunk/Documentation/networking/pktgen.txt @@ -63,8 +63,8 @@ Current: Result: OK: 13101142(c12220741+d880401) usec, 10000000 (60byte,0frags) 763292pps 390Mb/sec (390805504bps) errors: 39664 -Configuring threads and devices -================================ +Confguring threads and devices +============================== This is done via the /proc interface easiest done via pgset in the scripts Examples: @@ -116,7 +116,7 @@ Examples: there must be no spaces between the arguments. Leading zeros are required. Do not set the bottom of stack bit, - that's done automatically. If you do + thats done automatically. If you do set the bottom of stack bit, that indicates that you want to randomly generate that address and the flag diff --git a/trunk/Documentation/networking/proc_net_tcp.txt b/trunk/Documentation/networking/proc_net_tcp.txt index 5e21f7cb6383..59cb915c3713 100644 --- a/trunk/Documentation/networking/proc_net_tcp.txt +++ b/trunk/Documentation/networking/proc_net_tcp.txt @@ -25,7 +25,7 @@ up into 3 parts because of the length of the line): 1000 0 54165785 4 cd1e6040 25 4 27 3 -1 | | | | | | | | | |--> slow start size threshold, - | | | | | | | | | or -1 if the threshold + | | | | | | | | | or -1 if the treshold | | | | | | | | | is >= 0xFFFF | | | | | | | | |----> sending congestion window | | | | | | | |-------> (ack.quick<<1)|ack.pingpong diff --git a/trunk/Documentation/networking/sk98lin.txt b/trunk/Documentation/networking/sk98lin.txt index 8590a954df1d..4e1cc745ec63 100644 --- a/trunk/Documentation/networking/sk98lin.txt +++ b/trunk/Documentation/networking/sk98lin.txt @@ -346,7 +346,7 @@ Possible modes: depending on the load of the system. If the driver detects that the system load is too high, the driver tries to shield the system against too much network load by enabling interrupt moderation. If - at a later - time - the CPU utilization decreases again (or if the network load is + time - the CPU utilizaton decreases again (or if the network load is negligible) the interrupt moderation will automatically be disabled. Interrupt moderation should be used when the driver has to handle one or more diff --git a/trunk/Documentation/networking/slicecom.txt b/trunk/Documentation/networking/slicecom.txt index 32d3b916afad..2f04c9267f89 100644 --- a/trunk/Documentation/networking/slicecom.txt +++ b/trunk/Documentation/networking/slicecom.txt @@ -126,7 +126,7 @@ comx0/boardnum - board number of the SliceCom in the PC (using the 'natural' Though the options below are to be set on a single interface, they apply to the whole board. The restriction, to use them on 'UP' interfaces, is because the -command sequence below could lead to unpredictable results. +command sequence below could lead to unpredicable results. # echo 0 >boardnum # echo internal >clock_source diff --git a/trunk/Documentation/networking/wan-router.txt b/trunk/Documentation/networking/wan-router.txt index 653978dcea7f..0cf654147634 100644 --- a/trunk/Documentation/networking/wan-router.txt +++ b/trunk/Documentation/networking/wan-router.txt @@ -412,7 +412,7 @@ beta-2.1.4 Jul 2000 o Dynamic interface configuration: beta3-2.1.4 Jul 2000 o X25 M_BIT Problem fix. o Added the Multi-Port PPP - Updated utilities for the Multi-Port PPP. + Updated utilites for the Multi-Port PPP. 2.1.4 Aut 2000 o In X25API: @@ -444,13 +444,13 @@ beta1-2.1.5 Nov 15 2000 o Cpipemon - Added set FT1 commands to the cpipemon. Thus CSU/DSU - configuration can be performed using cpipemon. + configuraiton can be performed using cpipemon. All systems that cannot run cfgft1 GUI utility should use cpipemon to configure the on board CSU/DSU. o Keyboard Led Monitor/Debugger - - A new utility /usr/sbin/wpkbdmon uses keyboard leds + - A new utilty /usr/sbin/wpkbdmon uses keyboard leds to convey operational statistic information of the Sangoma WANPIPE cards. NUM_LOCK = Line State (On=connected, Off=disconnected) @@ -464,7 +464,7 @@ beta1-2.1.5 Nov 15 2000 - Appropriate number of devices are dynamically loaded based on the number of Sangoma cards found. - Note: The kernel configuration option + Note: The kernel configuraiton option CONFIG_WANPIPE_CARDS has been taken out. o Fixed the Frame Relay and Chdlc network interfaces so they are diff --git a/trunk/Documentation/pnp.txt b/trunk/Documentation/pnp.txt index 28037aa1846c..9ff966bf76e6 100644 --- a/trunk/Documentation/pnp.txt +++ b/trunk/Documentation/pnp.txt @@ -184,7 +184,7 @@ static const struct pnp_id pnp_dev_table[] = { Please note that the character 'X' can be used as a wild card in the function portion (last four characters). ex: - /* Unknown PnP modems */ + /* Unkown PnP modems */ { "PNPCXXX", UNKNOWN_DEV }, Supported PnP card IDs can optionally be defined. diff --git a/trunk/Documentation/power/interface.txt b/trunk/Documentation/power/interface.txt index 74311d7e0f3c..a66bec222b16 100644 --- a/trunk/Documentation/power/interface.txt +++ b/trunk/Documentation/power/interface.txt @@ -30,17 +30,6 @@ testing). The system will support either 'firmware' or 'platform', and that is known a priori. But, the user may choose 'shutdown' or 'reboot' as alternatives. -Additionally, /sys/power/disk can be used to turn on one of the two testing -modes of the suspend-to-disk mechanism: 'testproc' or 'test'. If the -suspend-to-disk mechanism is in the 'testproc' mode, writing 'disk' to -/sys/power/state will cause the kernel to disable nonboot CPUs and freeze -tasks, wait for 5 seconds, unfreeze tasks and enable nonboot CPUs. If it is -in the 'test' mode, writing 'disk' to /sys/power/state will cause the kernel -to disable nonboot CPUs and freeze tasks, shrink memory, suspend devices, wait -for 5 seconds, resume devices, unfreeze tasks and enable nonboot CPUs. Then, -we are able to look in the log messages and work out, for example, which code -is being slow and which device drivers are misbehaving. - Reading from this file will display what the mode is currently set to. Writing to this file will accept one of @@ -48,8 +37,6 @@ to. Writing to this file will accept one of 'platform' 'shutdown' 'reboot' - 'testproc' - 'test' It will only change to 'firmware' or 'platform' if the system supports it. diff --git a/trunk/Documentation/power/pci.txt b/trunk/Documentation/power/pci.txt index c750f9f2e76e..24edf25b3bb7 100644 --- a/trunk/Documentation/power/pci.txt +++ b/trunk/Documentation/power/pci.txt @@ -153,7 +153,7 @@ Description: events, which is implicit if it doesn't even support it in the first place). - Note that the PMC Register in the device's PM Capabilities has a bitmask + Note that the PMC Register in the device's PM Capabilties has a bitmask of the states it supports generating PME# from. D3hot is bit 3 and D3cold is bit 4. So, while a value of 4 as the state may not seem semantically correct, it is. @@ -268,7 +268,7 @@ to wake the system up. (However, it is possible that a device may support some non-standard way of generating a wake event on sleep.) Bits 15:11 of the PMC (Power Mgmt Capabilities) Register in a device's -PM Capabilities describe what power states the device supports generating a +PM Capabilties describe what power states the device supports generating a wake event from: +------------------+ diff --git a/trunk/Documentation/power/states.txt b/trunk/Documentation/power/states.txt index 0931a330d362..3e5e5d3ff419 100644 --- a/trunk/Documentation/power/states.txt +++ b/trunk/Documentation/power/states.txt @@ -62,7 +62,7 @@ setup via another operating system for it to use. Despite the inconvenience, this method requires minimal work by the kernel, since the firmware will also handle restoring memory contents on resume. -If the kernel is responsible for persistently saving state, a mechanism +If the kernel is responsible for persistantly saving state, a mechanism called 'swsusp' (Swap Suspend) is used to write memory contents to free swap space. swsusp has some restrictive requirements, but should work in most cases. Some, albeit outdated, documentation can be found diff --git a/trunk/Documentation/power/swsusp.txt b/trunk/Documentation/power/swsusp.txt index e635e6f1e316..9ea2208b43b5 100644 --- a/trunk/Documentation/power/swsusp.txt +++ b/trunk/Documentation/power/swsusp.txt @@ -153,7 +153,7 @@ add: If the thread is needed for writing the image to storage, you should instead set the PF_NOFREEZE process flag when creating the thread (and -be very careful). +be very carefull). Q: What is the difference between "platform", "shutdown" and diff --git a/trunk/Documentation/powerpc/booting-without-of.txt b/trunk/Documentation/powerpc/booting-without-of.txt index 4ac2d641fcb6..27b457c09729 100644 --- a/trunk/Documentation/powerpc/booting-without-of.txt +++ b/trunk/Documentation/powerpc/booting-without-of.txt @@ -33,13 +33,13 @@ - Change version 16 format to always align property data to 4 bytes. Since tokens are already aligned, that means no specific - required alignment between property size + required alignement between property size and property data. The old style variable alignment would make it impossible to do "simple" insertion of properties using memove (thanks Milton for noticing). Updated kernel patch as well - - Correct a few more alignment constraints + - Correct a few more alignement constraints - Add a chapter about the device-tree compiler and the textural representation of the tree that can be "compiled" by dtc. @@ -854,7 +854,7 @@ address which can extend beyond that limit. console device if any. Typically, if you have serial devices on your board, you may want to put the full path to the one set as the default console in the firmware here, for the kernel to pick - it up as its own default console. If you look at the function + it up as it's own default console. If you look at the funciton set_preferred_console() in arch/ppc64/kernel/setup.c, you'll see that the kernel tries to find out the default console and has knowledge of various types like 8250 serial ports. You may want @@ -1124,7 +1124,7 @@ should have the following properties: - interrupt-parent : contains the phandle of the interrupt controller which handles interrupts for this device - interrupts : a list of tuples representing the interrupt - number and the interrupt sense and level for each interrupt + number and the interrupt sense and level for each interupt for this device. This information is used by the kernel to build the interrupt table diff --git a/trunk/Documentation/robust-futex-ABI.txt b/trunk/Documentation/robust-futex-ABI.txt index 535f69fab45f..8529a17ffaa1 100644 --- a/trunk/Documentation/robust-futex-ABI.txt +++ b/trunk/Documentation/robust-futex-ABI.txt @@ -170,7 +170,7 @@ any point: 1) the 'head' pointer or an subsequent linked list pointer is not a valid address of a user space word 2) the calculated location of the 'lock word' (address plus - 'offset') is not the valid address of a 32 bit user space + 'offset') is not the valud address of a 32 bit user space word 3) if the list contains more than 1 million (subject to future kernel configuration changes) elements. diff --git a/trunk/Documentation/robust-futexes.txt b/trunk/Documentation/robust-futexes.txt index 0a9446a53bd1..76e8064b8c3a 100644 --- a/trunk/Documentation/robust-futexes.txt +++ b/trunk/Documentation/robust-futexes.txt @@ -181,7 +181,7 @@ for new threads, without the need of another syscall.] So there is virtually zero overhead for tasks not using robust futexes, and even for robust futex users, there is only one extra syscall per thread lifetime, and the cleanup operation, if it happens, is fast and -straightforward. The kernel doesn't have any internal distinction between +straightforward. The kernel doesnt have any internal distinction between robust and normal futexes. If a futex is found to be held at exit time, the kernel sets the diff --git a/trunk/Documentation/rtc.txt b/trunk/Documentation/rtc.txt index 7cf1ec5bcdd3..2a58f985795a 100644 --- a/trunk/Documentation/rtc.txt +++ b/trunk/Documentation/rtc.txt @@ -1,49 +1,12 @@ - Real Time Clock (RTC) Drivers for Linux - ======================================= - -When Linux developers talk about a "Real Time Clock", they usually mean -something that tracks wall clock time and is battery backed so that it -works even with system power off. Such clocks will normally not track -the local time zone or daylight savings time -- unless they dual boot -with MS-Windows -- but will instead be set to Coordinated Universal Time -(UTC, formerly "Greenwich Mean Time"). - -The newest non-PC hardware tends to just count seconds, like the time(2) -system call reports, but RTCs also very commonly represent time using -the Gregorian calendar and 24 hour time, as reported by gmtime(3). - -Linux has two largely-compatible userspace RTC API families you may -need to know about: - - * /dev/rtc ... is the RTC provided by PC compatible systems, - so it's not very portable to non-x86 systems. - - * /dev/rtc0, /dev/rtc1 ... are part of a framework that's - supported by a wide variety of RTC chips on all systems. - -Programmers need to understand that the PC/AT functionality is not -always available, and some systems can do much more. That is, the -RTCs use the same API to make requests in both RTC frameworks (using -different filenames of course), but the hardware may not offer the -same functionality. For example, not every RTC is hooked up to an -IRQ, so they can't all issue alarms; and where standard PC RTCs can -only issue an alarm up to 24 hours in the future, other hardware may -be able to schedule one any time in the upcoming century. - - - Old PC/AT-Compatible driver: /dev/rtc - -------------------------------------- + Real Time Clock Driver for Linux + ================================ All PCs (even Alpha machines) have a Real Time Clock built into them. Usually they are built into the chipset of the computer, but some may actually have a Motorola MC146818 (or clone) on the board. This is the clock that keeps the date and time while your computer is turned off. -ACPI has standardized that MC146818 functionality, and extended it in -a few ways (enabling longer alarm periods, and wake-from-hibernate). -That functionality is NOT exposed in the old driver. - However it can also be used to generate signals from a slow 2Hz to a relatively fast 8192Hz, in increments of powers of two. These signals are reported by interrupt number 8. (Oh! So *that* is what IRQ 8 is @@ -100,331 +63,223 @@ Rather than write 50 pages describing the ioctl() and so on, it is perhaps more useful to include a small test program that demonstrates how to use them, and demonstrates the features of the driver. This is probably a lot more useful to people interested in writing applications -that will be using this driver. See the code at the end of this document. - -(The original /dev/rtc driver was written by Paul Gortmaker.) - - - New portable "RTC Class" drivers: /dev/rtcN - -------------------------------------------- - -Because Linux supports many non-ACPI and non-PC platforms, some of which -have more than one RTC style clock, it needed a more portable solution -than expecting a single battery-backed MC146818 clone on every system. -Accordingly, a new "RTC Class" framework has been defined. It offers -three different userspace interfaces: - - * /dev/rtcN ... much the same as the older /dev/rtc interface - - * /sys/class/rtc/rtcN ... sysfs attributes support readonly - access to some RTC attributes. - - * /proc/driver/rtc ... the first RTC (rtc0) may expose itself - using a procfs interface. More information is (currently) shown - here than through sysfs. - -The RTC Class framework supports a wide variety of RTCs, ranging from those -integrated into embeddable system-on-chip (SOC) processors to discrete chips -using I2C, SPI, or some other bus to communicate with the host CPU. There's -even support for PC-style RTCs ... including the features exposed on newer PCs -through ACPI. - -The new framework also removes the "one RTC per system" restriction. For -example, maybe the low-power battery-backed RTC is a discrete I2C chip, but -a high functionality RTC is integrated into the SOC. That system might read -the system clock from the discrete RTC, but use the integrated one for all -other tasks, because of its greater functionality. - -The ioctl() calls supported by /dev/rtc are also supported by the RTC class -framework. However, because the chips and systems are not standardized, -some PC/AT functionality might not be provided. And in the same way, some -newer features -- including those enabled by ACPI -- are exposed by the -RTC class framework, but can't be supported by the older driver. - - * RTC_RD_TIME, RTC_SET_TIME ... every RTC supports at least reading - time, returning the result as a Gregorian calendar date and 24 hour - wall clock time. To be most useful, this time may also be updated. - - * RTC_AIE_ON, RTC_AIE_OFF, RTC_ALM_SET, RTC_ALM_READ ... when the RTC - is connected to an IRQ line, it can often issue an alarm IRQ up to - 24 hours in the future. - - * RTC_WKALM_SET, RTC_WKALM_READ ... RTCs that can issue alarms beyond - the next 24 hours use a slightly more powerful API, which supports - setting the longer alarm time and enabling its IRQ using a single - request (using the same model as EFI firmware). - - * RTC_UIE_ON, RTC_UIE_OFF ... if the RTC offers IRQs, it probably - also offers update IRQs whenever the "seconds" counter changes. - If needed, the RTC framework can emulate this mechanism. - - * RTC_PIE_ON, RTC_PIE_OFF, RTC_IRQP_SET, RTC_IRQP_READ ... another - feature often accessible with an IRQ line is a periodic IRQ, issued - at settable frequencies (usually 2^N Hz). - -In many cases, the RTC alarm can be a system wake event, used to force -Linux out of a low power sleep state (or hibernation) back to a fully -operational state. For example, a system could enter a deep power saving -state until it's time to execute some scheduled tasks. +that will be using this driver. + Paul Gortmaker -------------------- 8< ---------------- 8< ----------------------------- /* - * Real Time Clock Driver Test/Example Program + * Real Time Clock Driver Test/Example Program * - * Compile with: - * gcc -s -Wall -Wstrict-prototypes rtctest.c -o rtctest + * Compile with: + * gcc -s -Wall -Wstrict-prototypes rtctest.c -o rtctest * - * Copyright (C) 1996, Paul Gortmaker. + * Copyright (C) 1996, Paul Gortmaker. * - * Released under the GNU General Public License, version 2, - * included herein by reference. + * Released under the GNU General Public License, version 2, + * included herein by reference. * */ #include +#include #include #include #include #include #include #include -#include #include +int main(void) { -/* - * This expects the new RTC class driver framework, working with - * clocks that will often not be clones of what the PC-AT had. - * Use the command line to specify another RTC if you need one. - */ -static const char default_rtc[] = "/dev/rtc0"; - - -int main(int argc, char **argv) -{ - int i, fd, retval, irqcount = 0; - unsigned long tmp, data; - struct rtc_time rtc_tm; - const char *rtc = default_rtc; - - switch (argc) { - case 2: - rtc = argv[1]; - /* FALLTHROUGH */ - case 1: - break; - default: - fprintf(stderr, "usage: rtctest [rtcdev]\n"); - return 1; - } +int i, fd, retval, irqcount = 0; +unsigned long tmp, data; +struct rtc_time rtc_tm; - fd = open(rtc, O_RDONLY); +fd = open ("/dev/rtc", O_RDONLY); - if (fd == -1) { - perror(rtc); - exit(errno); - } +if (fd == -1) { + perror("/dev/rtc"); + exit(errno); +} + +fprintf(stderr, "\n\t\t\tRTC Driver Test Example.\n\n"); - fprintf(stderr, "\n\t\t\tRTC Driver Test Example.\n\n"); +/* Turn on update interrupts (one per second) */ +retval = ioctl(fd, RTC_UIE_ON, 0); +if (retval == -1) { + perror("ioctl"); + exit(errno); +} - /* Turn on update interrupts (one per second) */ - retval = ioctl(fd, RTC_UIE_ON, 0); +fprintf(stderr, "Counting 5 update (1/sec) interrupts from reading /dev/rtc:"); +fflush(stderr); +for (i=1; i<6; i++) { + /* This read will block */ + retval = read(fd, &data, sizeof(unsigned long)); if (retval == -1) { - if (errno == ENOTTY) { - fprintf(stderr, - "\n...Update IRQs not supported.\n"); - goto test_READ; - } - perror("ioctl"); + perror("read"); exit(errno); } - - fprintf(stderr, "Counting 5 update (1/sec) interrupts from reading %s:", - rtc); + fprintf(stderr, " %d",i); fflush(stderr); - for (i=1; i<6; i++) { - /* This read will block */ - retval = read(fd, &data, sizeof(unsigned long)); - if (retval == -1) { - perror("read"); - exit(errno); - } - fprintf(stderr, " %d",i); - fflush(stderr); - irqcount++; - } + irqcount++; +} - fprintf(stderr, "\nAgain, from using select(2) on /dev/rtc:"); - fflush(stderr); - for (i=1; i<6; i++) { - struct timeval tv = {5, 0}; /* 5 second timeout on select */ - fd_set readfds; - - FD_ZERO(&readfds); - FD_SET(fd, &readfds); - /* The select will wait until an RTC interrupt happens. */ - retval = select(fd+1, &readfds, NULL, NULL, &tv); - if (retval == -1) { - perror("select"); - exit(errno); - } - /* This read won't block unlike the select-less case above. */ - retval = read(fd, &data, sizeof(unsigned long)); - if (retval == -1) { - perror("read"); - exit(errno); - } - fprintf(stderr, " %d",i); - fflush(stderr); - irqcount++; - } +fprintf(stderr, "\nAgain, from using select(2) on /dev/rtc:"); +fflush(stderr); +for (i=1; i<6; i++) { + struct timeval tv = {5, 0}; /* 5 second timeout on select */ + fd_set readfds; - /* Turn off update interrupts */ - retval = ioctl(fd, RTC_UIE_OFF, 0); + FD_ZERO(&readfds); + FD_SET(fd, &readfds); + /* The select will wait until an RTC interrupt happens. */ + retval = select(fd+1, &readfds, NULL, NULL, &tv); if (retval == -1) { - perror("ioctl"); + perror("select"); exit(errno); } - -test_READ: - /* Read the RTC time/date */ - retval = ioctl(fd, RTC_RD_TIME, &rtc_tm); + /* This read won't block unlike the select-less case above. */ + retval = read(fd, &data, sizeof(unsigned long)); if (retval == -1) { - perror("ioctl"); + perror("read"); exit(errno); } + fprintf(stderr, " %d",i); + fflush(stderr); + irqcount++; +} - fprintf(stderr, "\n\nCurrent RTC date/time is %d-%d-%d, %02d:%02d:%02d.\n", - rtc_tm.tm_mday, rtc_tm.tm_mon + 1, rtc_tm.tm_year + 1900, - rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec); +/* Turn off update interrupts */ +retval = ioctl(fd, RTC_UIE_OFF, 0); +if (retval == -1) { + perror("ioctl"); + exit(errno); +} - /* Set the alarm to 5 sec in the future, and check for rollover */ - rtc_tm.tm_sec += 5; - if (rtc_tm.tm_sec >= 60) { - rtc_tm.tm_sec %= 60; - rtc_tm.tm_min++; - } - if (rtc_tm.tm_min == 60) { - rtc_tm.tm_min = 0; - rtc_tm.tm_hour++; - } - if (rtc_tm.tm_hour == 24) - rtc_tm.tm_hour = 0; +/* Read the RTC time/date */ +retval = ioctl(fd, RTC_RD_TIME, &rtc_tm); +if (retval == -1) { + perror("ioctl"); + exit(errno); +} - retval = ioctl(fd, RTC_ALM_SET, &rtc_tm); - if (retval == -1) { - if (errno == ENOTTY) { - fprintf(stderr, - "\n...Alarm IRQs not supported.\n"); - goto test_PIE; - } - perror("ioctl"); - exit(errno); - } +fprintf(stderr, "\n\nCurrent RTC date/time is %d-%d-%d, %02d:%02d:%02d.\n", + rtc_tm.tm_mday, rtc_tm.tm_mon + 1, rtc_tm.tm_year + 1900, + rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec); - /* Read the current alarm settings */ - retval = ioctl(fd, RTC_ALM_READ, &rtc_tm); - if (retval == -1) { - perror("ioctl"); - exit(errno); - } +/* Set the alarm to 5 sec in the future, and check for rollover */ +rtc_tm.tm_sec += 5; +if (rtc_tm.tm_sec >= 60) { + rtc_tm.tm_sec %= 60; + rtc_tm.tm_min++; +} +if (rtc_tm.tm_min == 60) { + rtc_tm.tm_min = 0; + rtc_tm.tm_hour++; +} +if (rtc_tm.tm_hour == 24) + rtc_tm.tm_hour = 0; - fprintf(stderr, "Alarm time now set to %02d:%02d:%02d.\n", - rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec); +retval = ioctl(fd, RTC_ALM_SET, &rtc_tm); +if (retval == -1) { + perror("ioctl"); + exit(errno); +} - /* Enable alarm interrupts */ - retval = ioctl(fd, RTC_AIE_ON, 0); - if (retval == -1) { - perror("ioctl"); - exit(errno); - } +/* Read the current alarm settings */ +retval = ioctl(fd, RTC_ALM_READ, &rtc_tm); +if (retval == -1) { + perror("ioctl"); + exit(errno); +} - fprintf(stderr, "Waiting 5 seconds for alarm..."); - fflush(stderr); - /* This blocks until the alarm ring causes an interrupt */ - retval = read(fd, &data, sizeof(unsigned long)); - if (retval == -1) { - perror("read"); - exit(errno); - } - irqcount++; - fprintf(stderr, " okay. Alarm rang.\n"); +fprintf(stderr, "Alarm time now set to %02d:%02d:%02d.\n", + rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec); - /* Disable alarm interrupts */ - retval = ioctl(fd, RTC_AIE_OFF, 0); +/* Enable alarm interrupts */ +retval = ioctl(fd, RTC_AIE_ON, 0); +if (retval == -1) { + perror("ioctl"); + exit(errno); +} + +fprintf(stderr, "Waiting 5 seconds for alarm..."); +fflush(stderr); +/* This blocks until the alarm ring causes an interrupt */ +retval = read(fd, &data, sizeof(unsigned long)); +if (retval == -1) { + perror("read"); + exit(errno); +} +irqcount++; +fprintf(stderr, " okay. Alarm rang.\n"); + +/* Disable alarm interrupts */ +retval = ioctl(fd, RTC_AIE_OFF, 0); +if (retval == -1) { + perror("ioctl"); + exit(errno); +} + +/* Read periodic IRQ rate */ +retval = ioctl(fd, RTC_IRQP_READ, &tmp); +if (retval == -1) { + perror("ioctl"); + exit(errno); +} +fprintf(stderr, "\nPeriodic IRQ rate was %ldHz.\n", tmp); + +fprintf(stderr, "Counting 20 interrupts at:"); +fflush(stderr); + +/* The frequencies 128Hz, 256Hz, ... 8192Hz are only allowed for root. */ +for (tmp=2; tmp<=64; tmp*=2) { + + retval = ioctl(fd, RTC_IRQP_SET, tmp); if (retval == -1) { perror("ioctl"); exit(errno); } -test_PIE: - /* Read periodic IRQ rate */ - retval = ioctl(fd, RTC_IRQP_READ, &tmp); + fprintf(stderr, "\n%ldHz:\t", tmp); + fflush(stderr); + + /* Enable periodic interrupts */ + retval = ioctl(fd, RTC_PIE_ON, 0); if (retval == -1) { - /* not all RTCs support periodic IRQs */ - if (errno == ENOTTY) { - fprintf(stderr, "\nNo periodic IRQ support\n"); - return 0; - } perror("ioctl"); exit(errno); } - fprintf(stderr, "\nPeriodic IRQ rate is %ldHz.\n", tmp); - - fprintf(stderr, "Counting 20 interrupts at:"); - fflush(stderr); - - /* The frequencies 128Hz, 256Hz, ... 8192Hz are only allowed for root. */ - for (tmp=2; tmp<=64; tmp*=2) { - retval = ioctl(fd, RTC_IRQP_SET, tmp); + for (i=1; i<21; i++) { + /* This blocks */ + retval = read(fd, &data, sizeof(unsigned long)); if (retval == -1) { - /* not all RTCs can change their periodic IRQ rate */ - if (errno == ENOTTY) { - fprintf(stderr, - "\n...Periodic IRQ rate is fixed\n"); - goto done; - } - perror("ioctl"); - exit(errno); + perror("read"); + exit(errno); } - - fprintf(stderr, "\n%ldHz:\t", tmp); + fprintf(stderr, " %d",i); fflush(stderr); + irqcount++; + } - /* Enable periodic interrupts */ - retval = ioctl(fd, RTC_PIE_ON, 0); - if (retval == -1) { - perror("ioctl"); - exit(errno); - } - - for (i=1; i<21; i++) { - /* This blocks */ - retval = read(fd, &data, sizeof(unsigned long)); - if (retval == -1) { - perror("read"); - exit(errno); - } - fprintf(stderr, " %d",i); - fflush(stderr); - irqcount++; - } - - /* Disable periodic interrupts */ - retval = ioctl(fd, RTC_PIE_OFF, 0); - if (retval == -1) { - perror("ioctl"); - exit(errno); - } + /* Disable periodic interrupts */ + retval = ioctl(fd, RTC_PIE_OFF, 0); + if (retval == -1) { + perror("ioctl"); + exit(errno); } +} -done: - fprintf(stderr, "\n\n\t\t\t *** Test complete ***\n"); +fprintf(stderr, "\n\n\t\t\t *** Test complete ***\n"); +fprintf(stderr, "\nTyping \"cat /proc/interrupts\" will show %d more events on IRQ 8.\n\n", + irqcount); - close(fd); +close(fd); +return 0; - return 0; -} +} /* end main */ diff --git a/trunk/Documentation/s390/CommonIO b/trunk/Documentation/s390/CommonIO index d684a6ac69a8..59d1166d41ee 100644 --- a/trunk/Documentation/s390/CommonIO +++ b/trunk/Documentation/s390/CommonIO @@ -66,7 +66,7 @@ Command line parameters When a device is un-ignored, device recognition and sensing is performed and the device driver will be notified if possible, so the device will become - available to the system. Note that un-ignoring is performed asynchronously. + available to the system. You can also add ranges of devices to be ignored by piping to /proc/cio_ignore; "add , , ..." will ignore the diff --git a/trunk/Documentation/s390/cds.txt b/trunk/Documentation/s390/cds.txt index 32a96cc39215..d80e5733827d 100644 --- a/trunk/Documentation/s390/cds.txt +++ b/trunk/Documentation/s390/cds.txt @@ -174,10 +174,14 @@ read_dev_chars() - Read Device Characteristics This routine returns the characteristics for the device specified. -The function is meant to be called with the device already enabled; that is, +The function is meant to be called with an irq handler in place; that is, at earliest during set_online() processing. -The ccw_device must not be locked prior to calling read_dev_chars(). +While the request is processed synchronously, the device interrupt +handler is called for final ending status. In case of error situations the +interrupt handler may recover appropriately. The device irq handler can +recognize the corresponding interrupts by the interruption parameter be +0x00524443. The ccw_device must not be locked prior to calling read_dev_chars(). The function may be called enabled or disabled. @@ -406,7 +410,26 @@ individual flag meanings. Usage Notes : -ccw_device_start() must be called disabled and with the ccw device lock held. +Prior to call ccw_device_start() the device driver must assure disabled state, +i.e. the I/O mask value in the PSW must be disabled. This can be accomplished +by calling local_save_flags( flags). The current PSW flags are preserved and +can be restored by local_irq_restore( flags) at a later time. + +If the device driver violates this rule while running in a uni-processor +environment an interrupt might be presented prior to the ccw_device_start() +routine returning to the device driver main path. In this case we will end in a +deadlock situation as the interrupt handler will try to obtain the irq +lock the device driver still owns (see below) ! + +The driver must assure to hold the device specific lock. This can be +accomplished by + +(i) spin_lock(get_ccwdev_lock(cdev)), or +(ii) spin_lock_irqsave(get_ccwdev_lock(cdev), flags) + +Option (i) should be used if the calling routine is running disabled for +I/O interrupts (see above) already. Option (ii) obtains the device gate und +puts the CPU into I/O disabled state by preserving the current PSW flags. The device driver is allowed to issue the next ccw_device_start() call from within its interrupt handler already. It is not required to schedule a @@ -465,7 +488,7 @@ int ccw_device_resume(struct ccw_device *cdev); cdev - ccw_device the resume operation is requested for -The ccw_device_resume() function returns: +The resume_IO() function returns: 0 - suspended channel program is resumed -EBUSY - status pending @@ -484,8 +507,6 @@ a long-running channel program or the device might require to initially issue a halt subchannel (HSCH) I/O command. For those purposes the ccw_device_halt() command is provided. -ccw_device_halt() must be called disabled and with the ccw device lock held. - int ccw_device_halt(struct ccw_device *cdev, unsigned long intparm); @@ -496,7 +517,7 @@ intparm : interruption parameter; value is only used if no I/O The ccw_device_halt() function returns : - 0 - request successfully initiated + 0 - successful completion or request successfully initiated -EBUSY - the device is currently busy, or status pending. -ENODEV - cdev invalid. -EINVAL - The device is not operational or the ccw device is not online. @@ -512,23 +533,6 @@ can then perform an appropriate action. Prior to interrupt of an outstanding read to a network device (with or without PCI flag) a ccw_device_halt() is required to end the pending operation. -ccw_device_clear() - Terminage I/O Request Processing - -In order to terminate all I/O processing at the subchannel, the clear subchannel -(CSCH) command is used. It can be issued via ccw_device_clear(). - -ccw_device_clear() must be called disabled and with the ccw device lock held. - -int ccw_device_clear(struct ccw_device *cdev, unsigned long intparm); - -cdev: ccw_device the clear operation is requested for -intparm: interruption parameter (see ccw_device_halt()) - -The ccw_device_clear() function returns: - - 0 - request successfully initiated --ENODEV - cdev invalid --EINVAL - The device is not operational or the ccw device is not online. Miscellaneous Support Routines diff --git a/trunk/Documentation/s390/crypto/crypto-API.txt b/trunk/Documentation/s390/crypto/crypto-API.txt index 41a8b07da05a..29dee792c887 100644 --- a/trunk/Documentation/s390/crypto/crypto-API.txt +++ b/trunk/Documentation/s390/crypto/crypto-API.txt @@ -75,8 +75,8 @@ name of the respective module is given in square brackets. - SHA1 Digest Algorithm [sha1 -> sha1_z990] - DES Encrypt/Decrypt Algorithm (64bit key) [des -> des_z990] -- Triple DES Encrypt/Decrypt Algorithm (128bit key) [des3_ede128 -> des_z990] -- Triple DES Encrypt/Decrypt Algorithm (192bit key) [des3_ede -> des_z990] +- Tripple DES Encrypt/Decrypt Algorithm (128bit key) [des3_ede128 -> des_z990] +- Tripple DES Encrypt/Decrypt Algorithm (192bit key) [des3_ede -> des_z990] In order to load, for example, the sha1_z990 module when the sha1 algorithm is requested (see 3.2.) add 'alias sha1 sha1_z990' to /etc/modprobe.conf. diff --git a/trunk/Documentation/s390/driver-model.txt b/trunk/Documentation/s390/driver-model.txt index 77bf450ec39b..62c082387aea 100644 --- a/trunk/Documentation/s390/driver-model.txt +++ b/trunk/Documentation/s390/driver-model.txt @@ -239,9 +239,6 @@ status - Can be 'online' or 'offline'. type - The physical type of the channel path. -shared - Whether the channel path is shared. - -cmg - The channel measurement group. 3. System devices ----------------- diff --git a/trunk/Documentation/scsi/ChangeLog.megaraid_sas b/trunk/Documentation/scsi/ChangeLog.megaraid_sas index 5eb927544990..d9e5960dafd5 100644 --- a/trunk/Documentation/scsi/ChangeLog.megaraid_sas +++ b/trunk/Documentation/scsi/ChangeLog.megaraid_sas @@ -1,49 +1,4 @@ -1 Release Date : Mon Oct 02 11:21:32 PDT 2006 - Sumant Patro -2 Current Version : 00.00.03.05 -3 Older Version : 00.00.03.04 - -i. PCI_DEVICE macro used - - Convert the pci_device_id-table of the megaraid_sas-driver to the PCI_DEVICE-macro, to safe some lines. - - - Henrik Kretzschmar -ii. All compiler warnings removed -iii. megasas_ctrl_info struct reverted to 3.02 release -iv. Default value of megasas_dbg_lvl set to 0 -v. Removing in megasas_exit the sysfs entry created for megasas_dbg_lvl -vi. In megasas_teardown_frame_pool(), cmd->frame was passed instead of - cmd->sense to pci_pool_free. Fixed. Bug was pointed out by - Eric Sesterhenn - -1 Release Date : Wed Sep 13 14:22:51 PDT 2006 - Sumant Patro -2 Current Version : 00.00.03.04 -3 Older Version : 00.00.03.03 - -i. Added Reboot notify -ii. Reduced by 1 max cmds sent to FW from Driver to make the reply_q_sz same - as Max Cmds FW can support - -1 Release Date : Tue Aug 22 16:33:14 PDT 2006 - Sumant Patro -2 Current Version : 00.00.03.03 -3 Older Version : 00.00.03.02 - -i. Send stop adapter to FW & Dump pending FW cmds before declaring adapter dead. - New varible added to set dbg level. -ii. Disable interrupt made as fn pointer as they are different for 1068 / 1078 -iii. Frame count optimization. Main frame can contain 2 SGE for 64 bit SGLs and - 3 SGE for 32 bit SGL -iv. Tasklet added for cmd completion -v. If FW in operational state before firing INIT, now we send RESET Flag to FW instead of just READY. This is used to do soft reset. -vi. megasas_ctrl_prop structure updated (based on FW struct) -vii. Added print : FW now in Ready State during initialization - -1 Release Date : Sun Aug 06 22:49:52 PDT 2006 - Sumant Patro -2 Current Version : 00.00.03.02 -3 Older Version : 00.00.03.01 - -i. Added FW tranistion state for Hotplug scenario - 1 Release Date : Sun May 14 22:49:52 PDT 2006 - Sumant Patro 2 Current Version : 00.00.03.01 3 Older Version : 00.00.02.04 diff --git a/trunk/Documentation/scsi/aic79xx.txt b/trunk/Documentation/scsi/aic79xx.txt index 6aa9a891f3d0..904d49e90ef2 100644 --- a/trunk/Documentation/scsi/aic79xx.txt +++ b/trunk/Documentation/scsi/aic79xx.txt @@ -127,7 +127,7 @@ The following information is available in this file: - Correct a reference to free'ed memory during controller shutdown. - Reset the bus on an SE->LVD change. This is required - to reset our transceivers. + to reset our transcievers. 1.3.5 (March 24th, 2003) - Fix a few register window mode bugs. @@ -169,7 +169,7 @@ The following information is available in this file: 1.3.0 (January 21st, 2003) - Full regression testing for all U320 products completed. - Added abort and target/lun reset error recovery handler and - interrupt coalescing. + interrupt coalessing. 1.2.0 (November 14th, 2002) - Added support for Domain Validation diff --git a/trunk/Documentation/scsi/aic7xxx_old.txt b/trunk/Documentation/scsi/aic7xxx_old.txt index 05667e7308d4..c92f4473193b 100644 --- a/trunk/Documentation/scsi/aic7xxx_old.txt +++ b/trunk/Documentation/scsi/aic7xxx_old.txt @@ -256,7 +256,7 @@ linux-1.1.x and fairly stable since linux-1.2.x, and are also in FreeBSD En/Disable High Byte LVD Termination The upper 2 bits that deal with LVD termination only apply to Ultra2 - controllers. Furthermore, due to the current Ultra2 controller + controllers. Futhermore, due to the current Ultra2 controller designs, these bits are tied together such that setting either bit enables both low and high byte LVD termination. It is not possible to only set high or low byte LVD termination in this manner. This is @@ -436,7 +436,7 @@ linux-1.1.x and fairly stable since linux-1.2.x, and are also in FreeBSD the commas to periods, insmod won't interpret this as more than one string and write junk into our binary image. I consider it a bug in the insmod program that even if you wrap your string in quotes (quotes - that pass the shell mind you and that insmod sees) it still treats + that pass the shell mind you and that insmod sees) it still treates a comma inside of those quotes as starting a new variable, resulting in memory scribbles if you don't switch the commas to periods. diff --git a/trunk/Documentation/scsi/ibmmca.txt b/trunk/Documentation/scsi/ibmmca.txt index 9707941704e3..35f6b8ed2295 100644 --- a/trunk/Documentation/scsi/ibmmca.txt +++ b/trunk/Documentation/scsi/ibmmca.txt @@ -461,7 +461,7 @@ This needs the RD-Bit to be disabled on IM_OTHER_SCSI_CMD_CMD which allows data to be written from the system to the device. It is a necessary step to be allowed to set blocksize of SCSI-tape-drives and - the tape-speed, without confusing the SCSI-Subsystem. + the tape-speed, whithout confusing the SCSI-Subsystem. 2) The recognition of a tape is included in the check_devices routine. This is done by checking for TYPE_TAPE, that is already defined in the kernel-scsi-environment. The markup of a tape is done in the @@ -710,8 +710,8 @@ of troubles with some controllers and after I wanted to apply some extensions, it jumped out in the same situation, on my w/cache, as like on D. Weinehalls' Model 56, having integrated SCSI. This gave me the - decisive hint to move the code-part out and declare it global. Now - it seems to work far better and more stable. Let us see what + descissive hint to move the code-part out and declare it global. Now, + it seems to work by far much better an more stable. Let us see, what the world thinks of it... 3) By the way, only Sony DAT-drives seem to show density code 0x13. A test with a HP drive gave right results, so the problem is vendor- @@ -822,10 +822,10 @@ A long period of collecting bugreports from all corners of the world now lead to the following corrections to the code: 1) SCSI-2 F/W support crashed with a COMMAND ERROR. The reason for this - was that it is possible to disable Fast-SCSI for the external bus. - The feature-control command, where this crash appeared regularly, tried + was, that it is possible to disbale Fast-SCSI for the external bus. + The feature-control command, where this crash appeared regularly tried to set the maximum speed of 10MHz synchronous transfer speed and that - reports a COMMAND ERROR if external bus Fast-SCSI is disabled. Now, + reports a COMMAND ERROR, if external bus Fast-SCSI is disabled. Now, the feature-command probes down from maximum speed until the adapter stops to complain, which is at the same time the maximum possible speed selected in the reference program. So, F/W external can run at @@ -920,7 +920,7 @@ completed in such a way, that they are now completely conform to the demands in the technical description of IBM. Main candidates were the DEVICE_INQUIRY, REQUEST_SENSE and DEVICE_CAPACITY commands. They must - be transferred by bypassing the internal command buffer of the adapter + be tranferred by bypassing the internal command buffer of the adapter or else the response can be a random result. GET_POS_INFO would be more safe in usage, if one could use the SUPRESS_EXCEPTION_SHORT, but this is not allowed by the technical references of IBM. (Sorry, folks, the diff --git a/trunk/Documentation/scsi/in2000.txt b/trunk/Documentation/scsi/in2000.txt index c3e2a90475d2..80f104042645 100644 --- a/trunk/Documentation/scsi/in2000.txt +++ b/trunk/Documentation/scsi/in2000.txt @@ -24,7 +24,7 @@ UPDATE NEWS: version 1.32 - 28 Mar 98 UPDATE NEWS: version 1.31 - 6 Jul 97 Fixed a bug that caused incorrect SCSI status bytes to be - returned from commands sent to LUNs greater than 0. This + returned from commands sent to LUN's greater than 0. This means that CDROM changers work now! Fixed a bug in the handling of command-line arguments when loaded as a module. Also put all the header data in in2000.h where it belongs. diff --git a/trunk/Documentation/scsi/libsas.txt b/trunk/Documentation/scsi/libsas.txt index aa54f54c4a50..9e2078b2a615 100644 --- a/trunk/Documentation/scsi/libsas.txt +++ b/trunk/Documentation/scsi/libsas.txt @@ -393,7 +393,7 @@ struct sas_task { task_proto -- _one_ of enum sas_proto scatter -- pointer to scatter gather list array num_scatter -- number of elements in scatter - total_xfer_len -- total number of bytes expected to be transferred + total_xfer_len -- total number of bytes expected to be transfered data_dir -- PCI_DMA_... task_done -- callback when the task has finished execution }; diff --git a/trunk/Documentation/scsi/ncr53c8xx.txt b/trunk/Documentation/scsi/ncr53c8xx.txt index caf10b155185..58ad8db333d9 100644 --- a/trunk/Documentation/scsi/ncr53c8xx.txt +++ b/trunk/Documentation/scsi/ncr53c8xx.txt @@ -115,7 +115,7 @@ SCSI standard documentations are available at SYMBIOS ftp server: ftp://ftp.symbios.com/ -Useful SCSI tools written by Eric Youngdale are available at tsx-11: +Usefull SCSI tools written by Eric Youngdale are available at tsx-11: ftp://tsx-11.mit.edu/pub/linux/ALPHA/scsi/scsiinfo-X.Y.tar.gz ftp://tsx-11.mit.edu/pub/linux/ALPHA/scsi/scsidev-X.Y.tar.gz diff --git a/trunk/Documentation/scsi/scsi-changer.txt b/trunk/Documentation/scsi/scsi-changer.txt index 032399b16a53..d74bbd29eb3a 100644 --- a/trunk/Documentation/scsi/scsi-changer.txt +++ b/trunk/Documentation/scsi/scsi-changer.txt @@ -88,7 +88,7 @@ If the module finds the changer, it prints some messages about the device [ try "dmesg" if you don't see anything ] and should show up in /proc/devices. If not.... some changers use ID ? / LUN 0 for the device and ID ? / LUN 1 for the robot mechanism. But Linux does *not* -look for LUNs other than 0 as default, because there are too many +look for LUN's other than 0 as default, becauce there are to many broken devices. So you can try: 1) echo "scsi add-single-device 0 0 ID 1" > /proc/scsi/scsi @@ -107,7 +107,7 @@ because the kernel will translate the error codes into human-readable strings then. You can display these messages with the dmesg command (or check the -logfiles). If you email me some question because of a problem with the +logfiles). If you email me some question becauce of a problem with the driver, please include these messages. diff --git a/trunk/Documentation/scsi/scsi_eh.txt b/trunk/Documentation/scsi/scsi_eh.txt index 7acbebb17fa6..b964eef2f62f 100644 --- a/trunk/Documentation/scsi/scsi_eh.txt +++ b/trunk/Documentation/scsi/scsi_eh.txt @@ -75,7 +75,7 @@ with the command. - otherwise scsi_eh_scmd_add(scmd, 0) is invoked for the command. See - [1-3] for details of this function. + [1-3] for details of this funciton. [1-2-2] Completing a scmd w/ timeout diff --git a/trunk/Documentation/scsi/st.txt b/trunk/Documentation/scsi/st.txt index 3c12422f7f41..5ff65b184265 100644 --- a/trunk/Documentation/scsi/st.txt +++ b/trunk/Documentation/scsi/st.txt @@ -261,7 +261,7 @@ pairs are separated with a comma (no spaces allowed). A colon can be used instead of the equal mark. The definition is prepended by the string st=. Here is an example: - st=buffer_kbs:64,write_threshold_kbs:60 + st=buffer_kbs:64,write_threhold_kbs:60 The following syntax used by the old kernel versions is also supported: diff --git a/trunk/Documentation/scsi/sym53c8xx_2.txt b/trunk/Documentation/scsi/sym53c8xx_2.txt index 2c1745a9df00..26c8a08ca3ea 100644 --- a/trunk/Documentation/scsi/sym53c8xx_2.txt +++ b/trunk/Documentation/scsi/sym53c8xx_2.txt @@ -609,7 +609,7 @@ appropriate mailing lists or news-groups. Send me a copy in order to be sure I will receive it. Obviously, a bug in the driver code is possible. - My current email address: Gerard Roudier + My cyrrent email address: Gerard Roudier Allowing disconnections is important if you use several devices on your SCSI bus but often causes problems with buggy devices. diff --git a/trunk/Documentation/sharedsubtree.txt b/trunk/Documentation/sharedsubtree.txt index ccf1cebe744f..2d8f403eb6eb 100644 --- a/trunk/Documentation/sharedsubtree.txt +++ b/trunk/Documentation/sharedsubtree.txt @@ -942,13 +942,13 @@ replicas continue to be exactly same. ->mnt_slave ->mnt_master - ->mnt_share links together all the mount to/from which this vfsmount + ->mnt_share links togather all the mount to/from which this vfsmount send/receives propagation events. ->mnt_slave_list links all the mounts to which this vfsmount propagates to. - ->mnt_slave links together all the slaves that its master vfsmount + ->mnt_slave links togather all the slaves that its master vfsmount propagates to. ->mnt_master points to the master vfsmount from which this vfsmount diff --git a/trunk/Documentation/sound/alsa/ALSA-Configuration.txt b/trunk/Documentation/sound/alsa/ALSA-Configuration.txt index 9fef210ab50a..138673a907f5 100644 --- a/trunk/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/trunk/Documentation/sound/alsa/ALSA-Configuration.txt @@ -753,7 +753,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. position_fix - Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size) single_cmd - Use single immediate commands to communicate with codecs (for debugging only) - enable_msi - Enable Message Signaled Interrupt (MSI) (default = off) + disable_msi - Disable Message Signaled Interrupt (MSI) This module supports one card and autoprobe. @@ -955,7 +955,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. dmx6fire, dsp24, dsp24_value, dsp24_71, ez8, phase88, mediastation omni - Omni I/O support for MidiMan M-Audio Delta44/66 - cs8427_timeout - reset timeout for the CS8427 chip (S/PDIF transceiver) + cs8427_timeout - reset timeout for the CS8427 chip (S/PDIF transciever) in msec resolution, default value is 500 (0.5 sec) This module supports multiple cards and autoprobe. Note: The consumer part diff --git a/trunk/Documentation/sound/alsa/Audigy-mixer.txt b/trunk/Documentation/sound/alsa/Audigy-mixer.txt index 7f10dc6ff28c..5132fd95e074 100644 --- a/trunk/Documentation/sound/alsa/Audigy-mixer.txt +++ b/trunk/Documentation/sound/alsa/Audigy-mixer.txt @@ -6,7 +6,7 @@ This is based on SB-Live-mixer.txt. The EMU10K2 chips have a DSP part which can be programmed to support various ways of sample processing, which is described here. -(This article does not deal with the overall functionality of the +(This acticle does not deal with the overall functionality of the EMU10K2 chips. See the manuals section for further details.) The ALSA driver programs this portion of chip by default code diff --git a/trunk/Documentation/sound/alsa/SB-Live-mixer.txt b/trunk/Documentation/sound/alsa/SB-Live-mixer.txt index f5639d40521d..651adaf60473 100644 --- a/trunk/Documentation/sound/alsa/SB-Live-mixer.txt +++ b/trunk/Documentation/sound/alsa/SB-Live-mixer.txt @@ -5,7 +5,7 @@ The EMU10K1 chips have a DSP part which can be programmed to support various ways of sample processing, which is described here. -(This article does not deal with the overall functionality of the +(This acticle does not deal with the overall functionality of the EMU10K1 chips. See the manuals section for further details.) The ALSA driver programs this portion of chip by default code diff --git a/trunk/Documentation/stable_kernel_rules.txt b/trunk/Documentation/stable_kernel_rules.txt index c815c5206e84..02a481225b0d 100644 --- a/trunk/Documentation/stable_kernel_rules.txt +++ b/trunk/Documentation/stable_kernel_rules.txt @@ -50,7 +50,7 @@ Review cycle: Contact the kernel security team for more details on this procedure. -Review committee: +Review committe: - This is made up of a number of kernel developers who have volunteered for this task, and a few that haven't. diff --git a/trunk/Documentation/sysctl/fs.txt b/trunk/Documentation/sysctl/fs.txt index aa986a35e994..5c3a51905969 100644 --- a/trunk/Documentation/sysctl/fs.txt +++ b/trunk/Documentation/sysctl/fs.txt @@ -146,7 +146,7 @@ or otherwise protected/tainted binaries. The modes are readable by root only. This allows the end user to remove such a dump but not access it directly. For security reasons core dumps in this mode will not overwrite one another or - other files. This mode is appropriate when administrators are + other files. This mode is appropriate when adminstrators are attempting to debug problems in a normal environment. ============================================================== diff --git a/trunk/Documentation/sysctl/kernel.txt b/trunk/Documentation/sysctl/kernel.txt index 0bc7f1e3c9e6..89bf8c20a586 100644 --- a/trunk/Documentation/sysctl/kernel.txt +++ b/trunk/Documentation/sysctl/kernel.txt @@ -86,7 +86,7 @@ valid for 30 seconds. core_pattern: core_pattern is used to specify a core dumpfile pattern name. -. max length 128 characters; default value is "core" +. max length 64 characters; default value is "core" . core_pattern is used as a pattern template for the output filename; certain string patterns (beginning with '%') are substituted with their actual values. @@ -105,9 +105,6 @@ core_pattern is used to specify a core dumpfile pattern name. %h hostname %e executable filename % both are dropped -. If the first character of the pattern is a '|', the kernel will treat - the rest of the pattern as a command to run. The core dump will be - written to the standard input of that program instead of to a file. ============================================================== diff --git a/trunk/Documentation/sysctl/vm.txt b/trunk/Documentation/sysctl/vm.txt index e96a341eb7e4..20d0d797f539 100644 --- a/trunk/Documentation/sysctl/vm.txt +++ b/trunk/Documentation/sysctl/vm.txt @@ -129,7 +129,7 @@ the high water marks for each per cpu page list. zone_reclaim_mode: -Zone_reclaim_mode allows someone to set more or less aggressive approaches to +Zone_reclaim_mode allows to set more or less agressive approaches to reclaim memory when a zone runs out of memory. If it is set to zero then no zone reclaim occurs. Allocations will be satisfied from other zones / nodes in the system. diff --git a/trunk/Documentation/uml/UserModeLinux-HOWTO.txt b/trunk/Documentation/uml/UserModeLinux-HOWTO.txt index 628013f944c4..b60590eca18f 100644 --- a/trunk/Documentation/uml/UserModeLinux-HOWTO.txt +++ b/trunk/Documentation/uml/UserModeLinux-HOWTO.txt @@ -1477,7 +1477,7 @@ - Making it world-writable looks bad, but it seems not to be + Making it world-writeable looks bad, but it seems not to be exploitable as a security hole. However, it does allow anyone to cre- ate useless tap devices (useless because they can't configure them), which is a DOS attack. A somewhat more secure alternative would to be diff --git a/trunk/Documentation/usb/hiddev.txt b/trunk/Documentation/usb/hiddev.txt index 6e8c9f1d2f22..6a790754e963 100644 --- a/trunk/Documentation/usb/hiddev.txt +++ b/trunk/Documentation/usb/hiddev.txt @@ -8,7 +8,7 @@ interfaces, but have similar sorts of communication needs. The two big examples for this are power devices (especially uninterruptable power supplies) and monitor control on higher end monitors. -To support these disparate requirements, the Linux USB system provides +To support these disparite requirements, the Linux USB system provides HID events to two separate interfaces: * the input subsystem, which converts HID events into normal input device interfaces (such as keyboard, mouse and joystick) and a diff --git a/trunk/Documentation/usb/rio.txt b/trunk/Documentation/usb/rio.txt index aee715af7db7..ab21db454694 100644 --- a/trunk/Documentation/usb/rio.txt +++ b/trunk/Documentation/usb/rio.txt @@ -24,10 +24,10 @@ are in no way responsible for any damage that may occur, no matter how inconsequential. It seems that the Rio has a problem when sending .mp3 with low batteries. -I suggest when the batteries are low and you want to transfer stuff that you +I suggest when the batteries are low and want to transfer stuff that you replace it with a fresh one. In my case, what happened is I lost two 16kb blocks (they are no longer usable to store information to it). But I don't -know if that's normal or not; it could simply be a problem with the flash +know if thats normal or not. It could simply be a problem with the flash memory. In an extreme case, I left my Rio playing overnight and the batteries wore diff --git a/trunk/Documentation/usb/usb-serial.txt b/trunk/Documentation/usb/usb-serial.txt index d61f6e7865de..8dc2bacc8f1f 100644 --- a/trunk/Documentation/usb/usb-serial.txt +++ b/trunk/Documentation/usb/usb-serial.txt @@ -175,7 +175,7 @@ Keyspan USA-series Serial Adapters Current status: The USA-18X, USA-28X, USA-19, USA-19W and USA-49W are supported and - have been pretty thoroughly tested at various baud rates with 8-N-1 + have been pretty throughly tested at various baud rates with 8-N-1 character settings. Other character lengths and parity setups are presently untested. @@ -253,7 +253,7 @@ Cypress M8 CY4601 Family Serial Driver together without hacking the adapter to set the line high. The driver is smp safe. Performance with the driver is rather low when using - it for transferring files. This is being worked on, but I would be willing to + it for transfering files. This is being worked on, but I would be willing to accept patches. An urb queue or packet buffer would likely fit the bill here. If you have any questions, problems, patches, feature requests, etc. you can @@ -297,7 +297,7 @@ Belkin USB Serial Adapter F5U103 Parity N,E,O,M,S Handshake None, Software (XON/XOFF), Hardware (CTSRTS,CTSDTR)* Break Set and clear - Line control Input/Output query and control ** + Line contrl Input/Output query and control ** * Hardware input flow control is only enabled for firmware levels above 2.06. Read source code comments describing Belkin @@ -309,7 +309,7 @@ Belkin USB Serial Adapter F5U103 automatic hardware flow control. TO DO List: - -- Add true modem control line query capability. Currently tracks the + -- Add true modem contol line query capability. Currently tracks the states reported by the interrupt and the states requested. -- Add error reporting back to application for UART error conditions. -- Add support for flush ioctls. @@ -428,6 +428,12 @@ Options supported: See http://www.uuhaus.de/linux/palmconnect.html for up-to-date information on this driver. +AIRcable USB Dongle Bluetooth driver + If there is the cdc_acm driver loaded in the system, you will find that the + cdc_acm claims the device before AIRcable can. This is simply corrected + by unloading both modules and then loading the aircable module before + cdc_acm module + Generic Serial driver If your device is not one of the above listed devices, compatible with diff --git a/trunk/Documentation/video4linux/CARDLIST.cx88 b/trunk/Documentation/video4linux/CARDLIST.cx88 index 8755b3e7b09e..126e59d935cd 100644 --- a/trunk/Documentation/video4linux/CARDLIST.cx88 +++ b/trunk/Documentation/video4linux/CARDLIST.cx88 @@ -51,7 +51,7 @@ 50 -> NPG Tech Real TV FM Top 10 [14f1:0842] 51 -> WinFast DTV2000 H [107d:665e] 52 -> Geniatech DVB-S [14f1:0084] - 53 -> Hauppauge WinTV-HVR3000 TriMode Analog/DVB-S/DVB-T [0070:1404,0070:1400,0070:1401,0070:1402] + 53 -> Hauppauge WinTV-HVR3000 TriMode Analog/DVB-S/DVB-T [0070:1404] 54 -> Norwood Micro TV Tuner 55 -> Shenzhen Tungsten Ages Tech TE-DTV-250 / Swann OEM [c180:c980] 56 -> Hauppauge WinTV-HVR1300 DVB-T/Hybrid MPEG Encoder [0070:9600,0070:9601,0070:9602] diff --git a/trunk/Documentation/watchdog/watchdog-api.txt b/trunk/Documentation/watchdog/watchdog-api.txt index 8d16f6f3c4ec..7e8ae83e9847 100644 --- a/trunk/Documentation/watchdog/watchdog-api.txt +++ b/trunk/Documentation/watchdog/watchdog-api.txt @@ -214,7 +214,7 @@ returned value is the temperature in degrees fahrenheit. Finally the SETOPTIONS ioctl can be used to control some aspects of the cards operation; right now the pcwd driver is the only one -supporting this ioctl. +supporting thiss ioctl. int options = 0; ioctl(fd, WDIOC_SETOPTIONS, options); diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 846e77a78710..17becb9b1a96 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -155,16 +155,16 @@ L: netdev@vger.kernel.org S: Maintained 9P FILE SYSTEM -P: Eric Van Hensbergen -M: ericvh@gmail.com -P: Ron Minnich -M: rminnich@lanl.gov -P: Latchesar Ionkov -M: lucho@ionkov.net -L: v9fs-developer@lists.sourceforge.net -W: http://v9fs.sf.net -T: git kernel.org:/pub/scm/linux/kernel/ericvh/v9fs.git -S: Maintained +P: Eric Van Hensbergen +M: ericvh@gmail.com +P: Ron Minnich +M: rminnich@lanl.gov +P: Latchesar Ionkov +M: lucho@ionkov.net +L: v9fs-developer@lists.sourceforge.net +W: http://v9fs.sf.net +T: git kernel.org:/pub/scm/linux/kernel/ericvh/v9fs.git +S: Maintained A2232 SERIAL BOARD DRIVER P: Enver Haase @@ -290,8 +290,8 @@ M: ink@jurassic.park.msu.ru S: Maintained for 2.4; PCI support for 2.6. AMD GEODE PROCESSOR/CHIPSET SUPPORT -P: Jordan Crouse -M: info-linux@geode.amd.com +P: Jordan Crouse +M: info-linux@geode.amd.com L: info-linux@geode.amd.com W: http://www.amd.com/us-en/ConnectivitySolutions/TechnicalResources/0,,50_2334_2452_11363,00.html S: Supported @@ -353,12 +353,6 @@ P: Richard Purdie M: rpurdie@rpsys.net S: Maintained -ARM/HP JORNADA 7XX MACHINE SUPPORT -P: Kristoffer Ericson -M: kristoffer_e1@hotmail.com -W: www.jlime.com -S: Maintained - ARM/TOSA MACHINE SUPPORT P: Dirk Opfer M: dirk@opfer-online.de @@ -499,7 +493,7 @@ S: Maintained BFS FILE SYSTEM P: Tigran A. Aivazian -M: tigran@aivazian.fsnet.co.uk +M: tigran@veritas.com L: linux-kernel@vger.kernel.org S: Maintained @@ -601,13 +595,13 @@ M: maxk@qualcomm.com S: Maintained BONDING DRIVER -P: Chad Tindel -M: ctindel@users.sourceforge.net -P: Jay Vosburgh -M: fubar@us.ibm.com -L: bonding-devel@lists.sourceforge.net -W: http://sourceforge.net/projects/bonding/ -S: Supported +P: Chad Tindel +M: ctindel@users.sourceforge.net +P: Jay Vosburgh +M: fubar@us.ibm.com +L: bonding-devel@lists.sourceforge.net +W: http://sourceforge.net/projects/bonding/ +S: Supported BROADBAND PROCESSOR ARCHITECTURE P: Arnd Bergmann @@ -647,7 +641,7 @@ CALGARY x86-64 IOMMU P: Muli Ben-Yehuda M: muli@il.ibm.com P: Jon D. Mason -M: jdmason@kudzu.us +M: jdmason@us.ibm.com L: linux-kernel@vger.kernel.org L: discuss@x86-64.org S: Maintained @@ -744,8 +738,8 @@ W: http://www.bullopensource.org/cpuset/ S: Supported CRAMFS FILESYSTEM -W: http://sourceforge.net/projects/cramfs/ -S: Orphan +W: http://sourceforge.net/projects/cramfs/ +S: Orphan CRIS PORT P: Mikael Starvik @@ -911,8 +905,7 @@ P: David Teigland M: teigland@redhat.com L: cluster-devel@redhat.com W: http://sources.redhat.com/cluster/ -T: git kernel.org:/pub/scm/linux/kernel/git/steve/gfs2-2.6-fixes.git -T: git kernel.org:/pub/scm/linux/kernel/git/steve/gfs2-2.6-nmw.git +T: git kernel.org:/pub/scm/linux/kernel/git/steve/gfs-2.6.git S: Supported DAVICOM FAST ETHERNET (DMFE) NETWORK DRIVER @@ -1054,11 +1047,11 @@ W: http://sourceforge.net/projects/emu10k1/ S: Maintained EMULEX LPFC FC SCSI DRIVER -P: James Smart -M: james.smart@emulex.com -L: linux-scsi@vger.kernel.org -W: http://sourceforge.net/projects/lpfcxxxx -S: Supported +P: James Smart +M: james.smart@emulex.com +L: linux-scsi@vger.kernel.org +W: http://sourceforge.net/projects/lpfcxxxx +S: Supported EPSON 1355 FRAMEBUFFER DRIVER P: Christopher Hoover @@ -1195,8 +1188,7 @@ P: Steven Whitehouse M: swhiteho@redhat.com L: cluster-devel@redhat.com W: http://sources.redhat.com/cluster/ -T: git kernel.org:/pub/scm/linux/kernel/git/steve/gfs2-2.6-fixes.git -T: git kernel.org:/pub/scm/linux/kernel/git/steve/gfs2-2.6-nmw.git +T: git kernel.org:/pub/scm/linux/kernel/git/steve/gfs-2.6.git S: Supported GIGASET ISDN DRIVERS @@ -1495,16 +1487,16 @@ L: linux-kernel@vger.kernel.org S: Maintained INTEL FRAMEBUFFER DRIVER (excluding 810 and 815) -P: Sylvain Meyer -M: sylvain.meyer@worldonline.fr -L: linux-fbdev-devel@lists.sourceforge.net -S: Maintained +P: Sylvain Meyer +M: sylvain.meyer@worldonline.fr +L: linux-fbdev-devel@lists.sourceforge.net +S: Maintained INTEL 810/815 FRAMEBUFFER DRIVER -P: Antonino Daplas -M: adaplas@pol.net -L: linux-fbdev-devel@lists.sourceforge.net -S: Maintained +P: Antonino Daplas +M: adaplas@pol.net +L: linux-fbdev-devel@lists.sourceforge.net +S: Maintained INTEL APIC/IOAPIC, LOWLEVEL X86 SMP SUPPORT P: Ingo Molnar @@ -1519,7 +1511,7 @@ S: Maintained INTEL IA32 MICROCODE UPDATE SUPPORT P: Tigran Aivazian -M: tigran@aivazian.fsnet.co.uk +M: tigran@veritas.com S: Maintained INTEL IXP4XX RANDOM NUMBER GENERATOR SUPPORT @@ -1674,12 +1666,6 @@ M: sct@redhat.com, akpm@osdl.org L: ext2-devel@lists.sourceforge.net S: Maintained -K8TEMP HARDWARE MONITORING DRIVER -P: Rudolf Marek -M: r.marek@assembler.cz -L: lm-sensors@lm-sensors.org -S: Maintained - KCONFIG P: Roman Zippel M: zippel@linux-m68k.org @@ -1830,11 +1816,11 @@ L: linuxppc-embedded@ozlabs.org S: Maintained LINUX FOR POWERPC EMBEDDED PPC83XX AND PPC85XX -P: Kumar Gala -M: galak@kernel.crashing.org -W: http://www.penguinppc.org/ -L: linuxppc-embedded@ozlabs.org -S: Maintained +P: Kumar Gala +M: galak@kernel.crashing.org +W: http://www.penguinppc.org/ +L: linuxppc-embedded@ozlabs.org +S: Maintained LINUX FOR POWERPC PA SEMI PWRFICIENT P: Olof Johansson @@ -1933,10 +1919,10 @@ W: http://www.syskonnect.com S: Supported MAN-PAGES: MANUAL PAGES FOR LINUX -- Sections 2, 3, 4, 5, and 7 -P: Michael Kerrisk -M: mtk-manpages@gmx.net -W: ftp://ftp.kernel.org/pub/linux/docs/manpages -S: Maintained +P: Michael Kerrisk +M: mtk-manpages@gmx.net +W: ftp://ftp.kernel.org/pub/linux/docs/manpages +S: Maintained MARVELL MV643XX ETHERNET DRIVER P: Dale Farnsworth @@ -1953,11 +1939,11 @@ L: linux-fbdev-devel@lists.sourceforge.net S: Maintained MEGARAID SCSI DRIVERS -P: Neela Syam Kolli -M: Neela.Kolli@engenio.com -S: linux-scsi@vger.kernel.org -W: http://megaraid.lsilogic.com -S: Maintained +P: Neela Syam Kolli +M: Neela.Kolli@engenio.com +S: linux-scsi@vger.kernel.org +W: http://megaraid.lsilogic.com +S: Maintained MEMORY MANAGEMENT L: linux-mm@kvack.org @@ -2010,13 +1996,6 @@ M: rubini@ipvvis.unipv.it L: linux-kernel@vger.kernel.org S: Maintained -MSI LAPTOP SUPPORT -P: Lennart Poettering -M: mzxreary@0pointer.de -L: https://tango.0pointer.de/mailman/listinfo/s270-linux -W: http://0pointer.de/lennart/tchibo.html -S: Maintained - MTRR AND SIMILAR SUPPORT [i386] P: Richard Gooch M: rgooch@atnf.csiro.au @@ -2024,11 +2003,8 @@ L: linux-kernel@vger.kernel.org W: http://www.atnf.csiro.au/~rgooch/linux/kernel-patches.html S: Maintained -MULTIMEDIA CARD (MMC) AND SECURE DIGITAL (SD) SUBSYSTEM -P: Pierre Ossman -M: drzeus-mmc@drzeus.cx -L: linux-kernel@vger.kernel.org -S: Maintained +MULTIMEDIA CARD (MMC) SUBSYSTEM +S: Orphan MULTISOUND SOUND DRIVER P: Andrew Veliath @@ -2064,13 +2040,11 @@ P: Marc Boucher P: James Morris P: Harald Welte P: Jozsef Kadlecsik -P: Patrick McHardy -M: kaber@trash.net -L: netfilter-devel@lists.netfilter.org -L: netfilter@lists.netfilter.org -L: coreteam@netfilter.org +M: coreteam@netfilter.org W: http://www.netfilter.org/ W: http://www.iptables.org/ +L: netfilter@lists.netfilter.org +L: netfilter-devel@lists.netfilter.org S: Supported NETLABEL @@ -2186,10 +2160,10 @@ T: git kernel.org:/pub/scm/linux/kernel/git/aia21/ntfs-2.6.git S: Maintained NVIDIA (rivafb and nvidiafb) FRAMEBUFFER DRIVER -P: Antonino Daplas -M: adaplas@pol.net -L: linux-fbdev-devel@lists.sourceforge.net -S: Maintained +P: Antonino Daplas +M: adaplas@pol.net +L: linux-fbdev-devel@lists.sourceforge.net +S: Maintained OPENCORES I2C BUS DRIVER P: Peter Korsgaard @@ -2287,17 +2261,6 @@ T: git kernel.org:/pub/scm/linux/kernel/git/kyle/parisc-2.6.git T: cvs cvs.parisc-linux.org:/var/cvs/linux-2.6 S: Maintained -PC87360 HARDWARE MONITORING DRIVER -P: Jim Cromie -M: jim.cromie@gmail.com -L: lm-sensors@lm-sensors.org -S: Maintained - -PC8736x GPIO DRIVER -P: Jim Cromie -M: jim.cromie@gmail.com -S: Maintained - PCI ERROR RECOVERY P: Linas Vepstas M: linas@austin.ibm.com @@ -2321,8 +2284,8 @@ T: quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/ S: Supported PCI HOTPLUG CORE -P: Kristen Carlson Accardi -M: kristen.c.accardi@intel.com +P: Greg Kroah-Hartman +M: gregkh@suse.de S: Supported PCI HOTPLUG COMPAQ DRIVER @@ -2539,10 +2502,10 @@ RISCOM8 DRIVER S: Orphan S3 SAVAGE FRAMEBUFFER DRIVER -P: Antonino Daplas -M: adaplas@pol.net -L: linux-fbdev-devel@lists.sourceforge.net -S: Maintained +P: Antonino Daplas +M: adaplas@pol.net +L: linux-fbdev-devel@lists.sourceforge.net +S: Maintained S390 P: Martin Schwidefsky @@ -2623,25 +2586,16 @@ L: linux-scsi@vger.kernel.org S: Maintained SCTP PROTOCOL -P: Sridhar Samudrala -M: sri@us.ibm.com -L: lksctp-developers@lists.sourceforge.net -S: Supported +P: Sridhar Samudrala +M: sri@us.ibm.com +L: lksctp-developers@lists.sourceforge.net +S: Supported SCx200 CPU SUPPORT -P: Jim Cromie -M: jim.cromie@gmail.com -S: Odd Fixes - -SCx200 GPIO DRIVER -P: Jim Cromie -M: jim.cromie@gmail.com -S: Maintained - -SCx200 HRT CLOCKSOURCE DRIVER -P: Jim Cromie -M: jim.cromie@gmail.com -S: Maintained +P: Christer Weinigel +M: christer@weinigel.se +W: http://www.weinigel.se +S: Supported SECURITY CONTACT P: Security Officers @@ -2794,9 +2748,9 @@ L: tpmdd-devel@lists.sourceforge.net S: Maintained Telecom Clock Driver for MCPL0010 -P: Mark Gross -M: mark.gross@intel.com -S: Supported +P: Mark Gross +M: mark.gross@intel.com +S: Supported TENSILICA XTENSA PORT (xtensa): P: Chris Zankel @@ -2806,7 +2760,14 @@ S: Maintained UltraSPARC (sparc64): P: David S. Miller M: davem@davemloft.net +P: Eddie C. Dost +M: ecd@brainaid.de +P: Jakub Jelinek +M: jj@sunsite.ms.mff.cuni.cz +P: Anton Blanchard +M: anton@samba.org L: sparclinux@vger.kernel.org +L: ultralinux@vger.kernel.org T: git kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6.git S: Maintained @@ -2943,9 +2904,9 @@ L: linux-kernel@vger.kernel.org S: Maintained TI PARALLEL LINK CABLE DRIVER -P: Romain Lievin -M: roms@lpg.ticalc.org -S: Maintained +P: Romain Lievin +M: roms@lpg.ticalc.org +S: Maintained TIPC NETWORK LAYER P: Per Liden @@ -2995,12 +2956,12 @@ L: linux-kernel@vger.kernel.org S: Maintained TRIVIAL PATCHES -P: Adrian Bunk -M: trivial@kernel.org -L: linux-kernel@vger.kernel.org -W: http://www.kernel.org/pub/linux/kernel/people/bunk/trivial/ -T: git kernel.org:/pub/scm/linux/kernel/git/bunk/trivial.git -S: Maintained +P: Adrian Bunk +M: trivial@kernel.org +L: linux-kernel@vger.kernel.org +W: http://www.kernel.org/pub/linux/kernel/people/bunk/trivial/ +T: git kernel.org:/pub/scm/linux/kernel/git/bunk/trivial.git +S: Maintained TMS380 TOKEN-RING NETWORK DRIVER P: Adam Fritzler @@ -3078,13 +3039,6 @@ L: video4linux-list@redhat.com W: http://www.linux-projects.org S: Maintained -USB GADGET/PERIPHERAL SUBSYSTEM -P: David Brownell -M: dbrownell@users.sourceforge.net -L: linux-usb-devel@lists.sourceforge.net -W: http://www.linux-usb.org/gadget -S: Maintained - USB HID/HIDBP DRIVERS P: Vojtech Pavlik M: vojtech@suse.cz @@ -3268,11 +3222,10 @@ L: linux-usb-users@lists.sourceforge.net L: linux-usb-devel@lists.sourceforge.net S: Maintained -USB "USBNET" DRIVER FRAMEWORK +USB "USBNET" DRIVER P: David Brownell M: dbrownell@users.sourceforge.net L: linux-usb-devel@lists.sourceforge.net -W: http://www.linux-usb.org/usbnet S: Maintained USB W996[87]CF DRIVER diff --git a/trunk/Makefile b/trunk/Makefile index aef96259051f..adb2c748e105 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1,6 +1,6 @@ VERSION = 2 PATCHLEVEL = 6 -SUBLEVEL = 19 +SUBLEVEL = 18 EXTRAVERSION = NAME=Avast! A bilge rat! @@ -499,7 +499,6 @@ endif ifdef CONFIG_UNWIND_INFO CFLAGS += -fasynchronous-unwind-tables -LDFLAGS_vmlinux += --eh-frame-hdr endif ifdef CONFIG_DEBUG_INFO @@ -742,9 +741,6 @@ endif # ifdef CONFIG_KALLSYMS # vmlinux image - including updated kernel symbols vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) FORCE -ifdef CONFIG_HEADERS_CHECK - $(Q)$(MAKE) -f $(srctree)/Makefile headers_check -endif $(call if_changed_rule,vmlinux__) $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost $@ $(Q)rm -f .old_version @@ -936,7 +932,7 @@ headers_install_all: include/linux/version.h scripts_basic FORCE PHONY += headers_install headers_install: include/linux/version.h scripts_basic FORCE - @if [ ! -r $(srctree)/include/asm-$(ARCH)/Kbuild ]; then \ + @if [ ! -r include/asm-$(ARCH)/Kbuild ]; then \ echo '*** Error: Headers not exportable for this architecture ($(ARCH))'; \ exit 1 ; fi $(Q)$(MAKE) $(build)=scripts scripts/unifdef @@ -1320,8 +1316,7 @@ define xtags $(all-sources) | xargs $1 -a \ -I __initdata,__exitdata,__acquires,__releases \ -I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL \ - --extra=+f --c-kinds=+px \ - --regex-asm='/ENTRY\(([^)]*)\).*/\1/'; \ + --extra=+f --c-kinds=+px; \ $(all-kconfigs) | xargs $1 -a \ --langdef=kconfig \ --language-force=kconfig \ diff --git a/trunk/arch/alpha/kernel/alpha_ksyms.c b/trunk/arch/alpha/kernel/alpha_ksyms.c index e9762a33b043..8b02420f732e 100644 --- a/trunk/arch/alpha/kernel/alpha_ksyms.c +++ b/trunk/arch/alpha/kernel/alpha_ksyms.c @@ -6,13 +6,40 @@ */ #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include #include +#include #include +#include #include +#include #include +#include #include +#include +#include +#include +#include +#include -#include +#include + +extern struct hwrpb_struct *hwrpb; +extern spinlock_t rtc_lock; /* these are C runtime functions with special calling conventions: */ extern void __divl (void); @@ -25,9 +52,14 @@ extern void __divqu (void); extern void __remqu (void); EXPORT_SYMBOL(alpha_mv); +EXPORT_SYMBOL(screen_info); +EXPORT_SYMBOL(perf_irq); EXPORT_SYMBOL(callback_getenv); EXPORT_SYMBOL(callback_setenv); EXPORT_SYMBOL(callback_save_env); +#ifdef CONFIG_ALPHA_GENERIC +EXPORT_SYMBOL(alpha_using_srm); +#endif /* CONFIG_ALPHA_GENERIC */ /* platform dependent support */ EXPORT_SYMBOL(strcat); @@ -45,14 +77,47 @@ EXPORT_SYMBOL(__constant_c_memset); EXPORT_SYMBOL(copy_page); EXPORT_SYMBOL(clear_page); +EXPORT_SYMBOL(__direct_map_base); +EXPORT_SYMBOL(__direct_map_size); + +#ifdef CONFIG_PCI +EXPORT_SYMBOL(pci_alloc_consistent); +EXPORT_SYMBOL(pci_free_consistent); +EXPORT_SYMBOL(pci_map_single); +EXPORT_SYMBOL(pci_map_page); +EXPORT_SYMBOL(pci_unmap_single); +EXPORT_SYMBOL(pci_unmap_page); +EXPORT_SYMBOL(pci_map_sg); +EXPORT_SYMBOL(pci_unmap_sg); +EXPORT_SYMBOL(pci_dma_supported); +EXPORT_SYMBOL(pci_dac_dma_supported); +EXPORT_SYMBOL(pci_dac_page_to_dma); +EXPORT_SYMBOL(pci_dac_dma_to_page); +EXPORT_SYMBOL(pci_dac_dma_to_offset); +EXPORT_SYMBOL(alpha_gendev_to_pci); +#endif +EXPORT_SYMBOL(dma_set_mask); + +EXPORT_SYMBOL(dump_thread); +EXPORT_SYMBOL(dump_elf_thread); +EXPORT_SYMBOL(dump_elf_task); +EXPORT_SYMBOL(dump_elf_task_fp); +EXPORT_SYMBOL(hwrpb); +EXPORT_SYMBOL(start_thread); EXPORT_SYMBOL(alpha_read_fp_reg); EXPORT_SYMBOL(alpha_read_fp_reg_s); EXPORT_SYMBOL(alpha_write_fp_reg); EXPORT_SYMBOL(alpha_write_fp_reg_s); -/* entry.S */ +/* In-kernel system calls. */ EXPORT_SYMBOL(kernel_thread); +EXPORT_SYMBOL(sys_dup); +EXPORT_SYMBOL(sys_exit); +EXPORT_SYMBOL(sys_write); +EXPORT_SYMBOL(sys_lseek); EXPORT_SYMBOL(kernel_execve); +EXPORT_SYMBOL(sys_setsid); +EXPORT_SYMBOL(sys_wait4); /* Networking helper routines. */ EXPORT_SYMBOL(csum_tcpudp_magic); @@ -69,6 +134,10 @@ EXPORT_SYMBOL(alpha_fp_emul_imprecise); EXPORT_SYMBOL(alpha_fp_emul); #endif +#ifdef CONFIG_ALPHA_BROKEN_IRQ_MASK +EXPORT_SYMBOL(__min_ipl); +#endif + /* * The following are specially called from the uaccess assembly stubs. */ @@ -91,9 +160,26 @@ EXPORT_SYMBOL(up); */ #ifdef CONFIG_SMP +EXPORT_SYMBOL(flush_tlb_mm); +EXPORT_SYMBOL(flush_tlb_range); +EXPORT_SYMBOL(flush_tlb_page); +EXPORT_SYMBOL(smp_imb); +EXPORT_SYMBOL(cpu_data); +EXPORT_SYMBOL(smp_num_cpus); +EXPORT_SYMBOL(smp_call_function); +EXPORT_SYMBOL(smp_call_function_on_cpu); EXPORT_SYMBOL(_atomic_dec_and_lock); #endif /* CONFIG_SMP */ +/* + * NUMA specific symbols + */ +#ifdef CONFIG_DISCONTIGMEM +EXPORT_SYMBOL(node_data); +#endif /* CONFIG_DISCONTIGMEM */ + +EXPORT_SYMBOL(rtc_lock); + /* * The following are special because they're not called * explicitly (the C compiler or assembler generates them in @@ -114,3 +200,8 @@ EXPORT_SYMBOL(__remqu); EXPORT_SYMBOL(memcpy); EXPORT_SYMBOL(memset); EXPORT_SYMBOL(memchr); + +#ifdef CONFIG_ALPHA_IRONGATE +EXPORT_SYMBOL(irongate_ioremap); +EXPORT_SYMBOL(irongate_iounmap); +#endif diff --git a/trunk/arch/alpha/kernel/core_apecs.c b/trunk/arch/alpha/kernel/core_apecs.c index ca46b2c24457..a27ba12ba35e 100644 --- a/trunk/arch/alpha/kernel/core_apecs.c +++ b/trunk/arch/alpha/kernel/core_apecs.c @@ -387,7 +387,8 @@ apecs_pci_clr_err(void) } void -apecs_machine_check(unsigned long vector, unsigned long la_ptr) +apecs_machine_check(unsigned long vector, unsigned long la_ptr, + struct pt_regs * regs) { struct el_common *mchk_header; struct el_apecs_procdata *mchk_procdata; @@ -411,7 +412,7 @@ apecs_machine_check(unsigned long vector, unsigned long la_ptr) wrmces(0x7); /* reset machine check pending flag */ mb(); - process_mcheck_info(vector, la_ptr, "APECS", + process_mcheck_info(vector, la_ptr, regs, "APECS", (mcheck_expected(0) && (mchk_sysdata->epic_dcsr & 0x0c00UL))); } diff --git a/trunk/arch/alpha/kernel/core_cia.c b/trunk/arch/alpha/kernel/core_cia.c index 1d6ee6c985f9..fd563064363c 100644 --- a/trunk/arch/alpha/kernel/core_cia.c +++ b/trunk/arch/alpha/kernel/core_cia.c @@ -1192,7 +1192,8 @@ cia_decode_mchk(unsigned long la_ptr) } void -cia_machine_check(unsigned long vector, unsigned long la_ptr) +cia_machine_check(unsigned long vector, unsigned long la_ptr, + struct pt_regs * regs) { int expected; @@ -1207,5 +1208,5 @@ cia_machine_check(unsigned long vector, unsigned long la_ptr) expected = mcheck_expected(0); if (!expected && vector == 0x660) expected = cia_decode_mchk(la_ptr); - process_mcheck_info(vector, la_ptr, "CIA", expected); + process_mcheck_info(vector, la_ptr, regs, "CIA", expected); } diff --git a/trunk/arch/alpha/kernel/core_irongate.c b/trunk/arch/alpha/kernel/core_irongate.c index e4a0bcf1d28b..138d497d1cca 100644 --- a/trunk/arch/alpha/kernel/core_irongate.c +++ b/trunk/arch/alpha/kernel/core_irongate.c @@ -404,7 +404,6 @@ irongate_ioremap(unsigned long addr, unsigned long size) #endif return (void __iomem *)vaddr; } -EXPORT_SYMBOL(irongate_ioremap); void irongate_iounmap(volatile void __iomem *xaddr) @@ -415,4 +414,3 @@ irongate_iounmap(volatile void __iomem *xaddr) if (addr) return vfree((void *)(PAGE_MASK & addr)); } -EXPORT_SYMBOL(irongate_iounmap); diff --git a/trunk/arch/alpha/kernel/core_lca.c b/trunk/arch/alpha/kernel/core_lca.c index 4843f6ec9f3a..6a5a9145c676 100644 --- a/trunk/arch/alpha/kernel/core_lca.c +++ b/trunk/arch/alpha/kernel/core_lca.c @@ -19,7 +19,6 @@ #include #include -#include #include #include "proto.h" @@ -387,7 +386,8 @@ ioc_error(__u32 stat0, __u32 stat1) } void -lca_machine_check(unsigned long vector, unsigned long la_ptr) +lca_machine_check(unsigned long vector, unsigned long la_ptr, + struct pt_regs *regs) { const char * reason; union el_lca el; @@ -397,7 +397,7 @@ lca_machine_check(unsigned long vector, unsigned long la_ptr) wrmces(rdmces()); /* reset machine check pending flag */ printk(KERN_CRIT "LCA machine check: vector=%#lx pc=%#lx code=%#x\n", - vector, get_irq_regs()->pc, (unsigned int) el.c->code); + vector, regs->pc, (unsigned int) el.c->code); /* * The first quadword after the common header always seems to diff --git a/trunk/arch/alpha/kernel/core_mcpcia.c b/trunk/arch/alpha/kernel/core_mcpcia.c index 8d019071190a..28849c894153 100644 --- a/trunk/arch/alpha/kernel/core_mcpcia.c +++ b/trunk/arch/alpha/kernel/core_mcpcia.c @@ -572,7 +572,8 @@ mcpcia_print_system_area(unsigned long la_ptr) } void -mcpcia_machine_check(unsigned long vector, unsigned long la_ptr) +mcpcia_machine_check(unsigned long vector, unsigned long la_ptr, + struct pt_regs * regs) { struct el_common *mchk_header; struct el_MCPCIA_uncorrected_frame_mcheck *mchk_logout; @@ -609,7 +610,7 @@ mcpcia_machine_check(unsigned long vector, unsigned long la_ptr) wrmces(0x7); mb(); - process_mcheck_info(vector, la_ptr, "MCPCIA", expected != 0); + process_mcheck_info(vector, la_ptr, regs, "MCPCIA", expected != 0); if (!expected && vector != 0x620 && vector != 0x630) { mcpcia_print_uncorrectable(mchk_logout); mcpcia_print_system_area(la_ptr); diff --git a/trunk/arch/alpha/kernel/core_polaris.c b/trunk/arch/alpha/kernel/core_polaris.c index c5a271d37abd..277674a500ff 100644 --- a/trunk/arch/alpha/kernel/core_polaris.c +++ b/trunk/arch/alpha/kernel/core_polaris.c @@ -187,7 +187,8 @@ polaris_pci_clr_err(void) } void -polaris_machine_check(unsigned long vector, unsigned long la_ptr) +polaris_machine_check(unsigned long vector, unsigned long la_ptr, + struct pt_regs * regs) { /* Clear the error before any reporting. */ mb(); @@ -197,6 +198,6 @@ polaris_machine_check(unsigned long vector, unsigned long la_ptr) wrmces(0x7); mb(); - process_mcheck_info(vector, la_ptr, "POLARIS", + process_mcheck_info(vector, la_ptr, regs, "POLARIS", mcheck_expected(0)); } diff --git a/trunk/arch/alpha/kernel/core_t2.c b/trunk/arch/alpha/kernel/core_t2.c index f5ca5255eb06..ecce09e3626a 100644 --- a/trunk/arch/alpha/kernel/core_t2.c +++ b/trunk/arch/alpha/kernel/core_t2.c @@ -551,7 +551,8 @@ t2_clear_errors(int cpu) * Hence all the taken/expected/any_expected/last_taken stuff... */ void -t2_machine_check(unsigned long vector, unsigned long la_ptr) +t2_machine_check(unsigned long vector, unsigned long la_ptr, + struct pt_regs * regs) { int cpu = smp_processor_id(); #ifdef CONFIG_VERBOSE_MCHECK @@ -617,5 +618,5 @@ t2_machine_check(unsigned long vector, unsigned long la_ptr) } #endif - process_mcheck_info(vector, la_ptr, "T2", mcheck_expected(cpu)); + process_mcheck_info(vector, la_ptr, regs, "T2", mcheck_expected(cpu)); } diff --git a/trunk/arch/alpha/kernel/core_tsunami.c b/trunk/arch/alpha/kernel/core_tsunami.c index ce623c6e55e1..8aa305bd6a2c 100644 --- a/trunk/arch/alpha/kernel/core_tsunami.c +++ b/trunk/arch/alpha/kernel/core_tsunami.c @@ -443,7 +443,8 @@ tsunami_pci_clr_err(void) } void -tsunami_machine_check(unsigned long vector, unsigned long la_ptr) +tsunami_machine_check(unsigned long vector, unsigned long la_ptr, + struct pt_regs * regs) { /* Clear error before any reporting. */ mb(); @@ -453,6 +454,6 @@ tsunami_machine_check(unsigned long vector, unsigned long la_ptr) wrmces(0x7); mb(); - process_mcheck_info(vector, la_ptr, "TSUNAMI", + process_mcheck_info(vector, la_ptr, regs, "TSUNAMI", mcheck_expected(smp_processor_id())); } diff --git a/trunk/arch/alpha/kernel/core_wildfire.c b/trunk/arch/alpha/kernel/core_wildfire.c index 7e072443d7fd..2b767a1bad96 100644 --- a/trunk/arch/alpha/kernel/core_wildfire.c +++ b/trunk/arch/alpha/kernel/core_wildfire.c @@ -322,7 +322,8 @@ wildfire_init_arch(void) } void -wildfire_machine_check(unsigned long vector, unsigned long la_ptr) +wildfire_machine_check(unsigned long vector, unsigned long la_ptr, + struct pt_regs * regs) { mb(); mb(); /* magic */ @@ -331,7 +332,7 @@ wildfire_machine_check(unsigned long vector, unsigned long la_ptr) wrmces(0x7); mb(); - process_mcheck_info(vector, la_ptr, "WILDFIRE", + process_mcheck_info(vector, la_ptr, regs, "WILDFIRE", mcheck_expected(smp_processor_id())); } diff --git a/trunk/arch/alpha/kernel/err_ev6.c b/trunk/arch/alpha/kernel/err_ev6.c index 69b5f4ea7355..64f59f2fcf5c 100644 --- a/trunk/arch/alpha/kernel/err_ev6.c +++ b/trunk/arch/alpha/kernel/err_ev6.c @@ -11,7 +11,6 @@ #include #include -#include #include #include #include @@ -230,7 +229,7 @@ ev6_process_logout_frame(struct el_common *mchk_header, int print) } void -ev6_machine_check(u64 vector, u64 la_ptr) +ev6_machine_check(u64 vector, u64 la_ptr, struct pt_regs *regs) { struct el_common *mchk_header = (struct el_common *)la_ptr; @@ -261,7 +260,7 @@ ev6_machine_check(u64 vector, u64 la_ptr) (unsigned int)vector, (int)smp_processor_id()); ev6_process_logout_frame(mchk_header, 1); - dik_show_regs(get_irq_regs(), NULL); + dik_show_regs(regs, NULL); err_print_prefix = saved_err_prefix; } diff --git a/trunk/arch/alpha/kernel/err_ev7.c b/trunk/arch/alpha/kernel/err_ev7.c index 95463ab1cf35..fed6b3d1b803 100644 --- a/trunk/arch/alpha/kernel/err_ev7.c +++ b/trunk/arch/alpha/kernel/err_ev7.c @@ -118,7 +118,7 @@ ev7_collect_logout_frame_subpackets(struct el_subpacket *el_ptr, } void -ev7_machine_check(u64 vector, u64 la_ptr) +ev7_machine_check(u64 vector, u64 la_ptr, struct pt_regs *regs) { struct el_subpacket *el_ptr = (struct el_subpacket *)la_ptr; char *saved_err_prefix = err_print_prefix; diff --git a/trunk/arch/alpha/kernel/err_impl.h b/trunk/arch/alpha/kernel/err_impl.h index 3c12258158e6..64e9b73809fa 100644 --- a/trunk/arch/alpha/kernel/err_impl.h +++ b/trunk/arch/alpha/kernel/err_impl.h @@ -60,26 +60,26 @@ extern struct ev7_lf_subpackets * ev7_collect_logout_frame_subpackets(struct el_subpacket *, struct ev7_lf_subpackets *); extern void ev7_register_error_handlers(void); -extern void ev7_machine_check(u64, u64); +extern void ev7_machine_check(u64, u64, struct pt_regs *); /* * err_ev6.c */ extern void ev6_register_error_handlers(void); extern int ev6_process_logout_frame(struct el_common *, int); -extern void ev6_machine_check(u64, u64); +extern void ev6_machine_check(u64, u64, struct pt_regs *); /* * err_marvel.c */ -extern void marvel_machine_check(u64, u64); +extern void marvel_machine_check(u64, u64, struct pt_regs *); extern void marvel_register_error_handlers(void); /* * err_titan.c */ extern int titan_process_logout_frame(struct el_common *, int); -extern void titan_machine_check(u64, u64); +extern void titan_machine_check(u64, u64, struct pt_regs *); extern void titan_register_error_handlers(void); extern int privateer_process_logout_frame(struct el_common *, int); -extern void privateer_machine_check(u64, u64); +extern void privateer_machine_check(u64, u64, struct pt_regs *); diff --git a/trunk/arch/alpha/kernel/err_marvel.c b/trunk/arch/alpha/kernel/err_marvel.c index f2956ac8dccc..70b38b1d2af3 100644 --- a/trunk/arch/alpha/kernel/err_marvel.c +++ b/trunk/arch/alpha/kernel/err_marvel.c @@ -1042,7 +1042,7 @@ marvel_process_logout_frame(struct ev7_lf_subpackets *lf_subpackets, int print) } void -marvel_machine_check(u64 vector, u64 la_ptr) +marvel_machine_check(u64 vector, u64 la_ptr, struct pt_regs *regs) { struct el_subpacket *el_ptr = (struct el_subpacket *)la_ptr; int (*process_frame)(struct ev7_lf_subpackets *, int) = NULL; @@ -1077,7 +1077,7 @@ marvel_machine_check(u64 vector, u64 la_ptr) default: /* Don't know it - pass it up. */ - ev7_machine_check(vector, la_ptr); + ev7_machine_check(vector, la_ptr, regs); return; } diff --git a/trunk/arch/alpha/kernel/err_titan.c b/trunk/arch/alpha/kernel/err_titan.c index febe71c6869f..7e6720d45f02 100644 --- a/trunk/arch/alpha/kernel/err_titan.c +++ b/trunk/arch/alpha/kernel/err_titan.c @@ -379,7 +379,7 @@ titan_process_logout_frame(struct el_common *mchk_header, int print) } void -titan_machine_check(u64 vector, u64 la_ptr) +titan_machine_check(u64 vector, u64 la_ptr, struct pt_regs *regs) { struct el_common *mchk_header = (struct el_common *)la_ptr; struct el_TITAN_sysdata_mcheck *tmchk = @@ -408,7 +408,7 @@ titan_machine_check(u64 vector, u64 la_ptr) * Only handle system errors here */ if ((vector != SCB_Q_SYSMCHK) && (vector != SCB_Q_SYSERR)) { - ev6_machine_check(vector, la_ptr); + ev6_machine_check(vector, la_ptr, regs); return; } @@ -442,7 +442,7 @@ titan_machine_check(u64 vector, u64 la_ptr) #ifdef CONFIG_VERBOSE_MCHECK titan_process_logout_frame(mchk_header, alpha_verbose_mcheck); if (alpha_verbose_mcheck) - dik_show_regs(get_irq_regs(), NULL); + dik_show_regs(regs, NULL); #endif /* CONFIG_VERBOSE_MCHECK */ err_print_prefix = saved_err_prefix; @@ -452,7 +452,7 @@ titan_machine_check(u64 vector, u64 la_ptr) * machine checks to interrupts */ irqmask = tmchk->c_dirx & TITAN_MCHECK_INTERRUPT_MASK; - titan_dispatch_irqs(irqmask); + titan_dispatch_irqs(irqmask, regs); } @@ -701,7 +701,7 @@ privateer_process_logout_frame(struct el_common *mchk_header, int print) } void -privateer_machine_check(u64 vector, u64 la_ptr) +privateer_machine_check(u64 vector, u64 la_ptr, struct pt_regs *regs) { struct el_common *mchk_header = (struct el_common *)la_ptr; struct el_TITAN_sysdata_mcheck *tmchk = @@ -723,7 +723,7 @@ privateer_machine_check(u64 vector, u64 la_ptr) * Only handle system events here. */ if (vector != SCB_Q_SYSEVENT) - return titan_machine_check(vector, la_ptr); + return titan_machine_check(vector, la_ptr, regs); /* * Report the event - System Events should be reported even if no @@ -746,7 +746,7 @@ privateer_machine_check(u64 vector, u64 la_ptr) /* * Dispatch the interrupt(s). */ - titan_dispatch_irqs(irqmask); + titan_dispatch_irqs(irqmask, regs); /* * Release the logout frame. diff --git a/trunk/arch/alpha/kernel/irq.c b/trunk/arch/alpha/kernel/irq.c index facf82a5499a..729c475d2269 100644 --- a/trunk/arch/alpha/kernel/irq.c +++ b/trunk/arch/alpha/kernel/irq.c @@ -127,7 +127,7 @@ show_interrupts(struct seq_file *p, void *v) #define MAX_ILLEGAL_IRQS 16 void -handle_irq(int irq) +handle_irq(int irq, struct pt_regs * regs) { /* * We ack quickly, we don't want the irq controller @@ -157,6 +157,6 @@ handle_irq(int irq) * at IPL 0. */ local_irq_disable(); - __do_IRQ(irq); + __do_IRQ(irq, regs); irq_exit(); } diff --git a/trunk/arch/alpha/kernel/irq_alpha.c b/trunk/arch/alpha/kernel/irq_alpha.c index e16aeb6e79ef..ddf5cf8dcb0b 100644 --- a/trunk/arch/alpha/kernel/irq_alpha.c +++ b/trunk/arch/alpha/kernel/irq_alpha.c @@ -6,7 +6,6 @@ #include #include #include -#include #include #include @@ -17,7 +16,6 @@ /* Hack minimum IPL during interrupt processing for broken hardware. */ #ifdef CONFIG_ALPHA_BROKEN_IRQ_MASK int __min_ipl; -EXPORT_SYMBOL(__min_ipl); #endif /* @@ -32,7 +30,6 @@ dummy_perf(unsigned long vector, struct pt_regs *regs) } void (*perf_irq)(unsigned long, struct pt_regs *) = dummy_perf; -EXPORT_SYMBOL(perf_irq); /* * The main interrupt entry point. @@ -42,7 +39,6 @@ asmlinkage void do_entInt(unsigned long type, unsigned long vector, unsigned long la_ptr, struct pt_regs *regs) { - struct pt_regs *old_regs; switch (type) { case 0: #ifdef CONFIG_SMP @@ -55,7 +51,6 @@ do_entInt(unsigned long type, unsigned long vector, #endif break; case 1: - old_regs = set_irq_regs(regs); #ifdef CONFIG_SMP { long cpu; @@ -66,23 +61,18 @@ do_entInt(unsigned long type, unsigned long vector, if (cpu != boot_cpuid) { kstat_cpu(cpu).irqs[RTC_IRQ]++; } else { - handle_irq(RTC_IRQ); + handle_irq(RTC_IRQ, regs); } } #else - handle_irq(RTC_IRQ); + handle_irq(RTC_IRQ, regs); #endif - set_irq_regs(old_regs); return; case 2: - old_regs = set_irq_regs(regs); - alpha_mv.machine_check(vector, la_ptr); - set_irq_regs(old_regs); + alpha_mv.machine_check(vector, la_ptr, regs); return; case 3: - old_regs = set_irq_regs(regs); - alpha_mv.device_interrupt(vector); - set_irq_regs(old_regs); + alpha_mv.device_interrupt(vector, regs); return; case 4: perf_irq(la_ptr, regs); @@ -130,7 +120,8 @@ struct mcheck_info __mcheck_info; void process_mcheck_info(unsigned long vector, unsigned long la_ptr, - const char *machine, int expected) + struct pt_regs *regs, const char *machine, + int expected) { struct el_common *mchk_header; const char *reason; @@ -157,7 +148,7 @@ process_mcheck_info(unsigned long vector, unsigned long la_ptr, mchk_header = (struct el_common *)la_ptr; printk(KERN_CRIT "%s machine check: vector=0x%lx pc=0x%lx code=0x%x\n", - machine, vector, get_irq_regs()->pc, mchk_header->code); + machine, vector, regs->pc, mchk_header->code); switch (mchk_header->code) { /* Machine check reasons. Defined according to PALcode sources. */ @@ -198,7 +189,7 @@ process_mcheck_info(unsigned long vector, unsigned long la_ptr, printk(KERN_CRIT "machine check type: %s%s\n", reason, mchk_header->retry ? " (retryable)" : ""); - dik_show_regs(get_irq_regs(), NULL); + dik_show_regs(regs, NULL); #ifdef CONFIG_VERBOSE_MCHECK if (alpha_verbose_mcheck > 1) { diff --git a/trunk/arch/alpha/kernel/irq_i8259.c b/trunk/arch/alpha/kernel/irq_i8259.c index 9405bee9894e..ebbadbc0c36a 100644 --- a/trunk/arch/alpha/kernel/irq_i8259.c +++ b/trunk/arch/alpha/kernel/irq_i8259.c @@ -137,7 +137,7 @@ init_i8259a_irqs(void) #if defined(IACK_SC) void -isa_device_interrupt(unsigned long vector) +isa_device_interrupt(unsigned long vector, struct pt_regs *regs) { /* * Generate a PCI interrupt acknowledge cycle. The PIC will @@ -147,13 +147,13 @@ isa_device_interrupt(unsigned long vector) */ int j = *(vuip) IACK_SC; j &= 0xff; - handle_irq(j); + handle_irq(j, regs); } #endif #if defined(CONFIG_ALPHA_GENERIC) || !defined(IACK_SC) void -isa_no_iack_sc_device_interrupt(unsigned long vector) +isa_no_iack_sc_device_interrupt(unsigned long vector, struct pt_regs *regs) { unsigned long pic; @@ -176,7 +176,7 @@ isa_no_iack_sc_device_interrupt(unsigned long vector) while (pic) { int j = ffz(~pic); pic &= pic - 1; - handle_irq(j); + handle_irq(j, regs); } } #endif diff --git a/trunk/arch/alpha/kernel/irq_impl.h b/trunk/arch/alpha/kernel/irq_impl.h index cc9a8a7aa279..f201d8ffc0d9 100644 --- a/trunk/arch/alpha/kernel/irq_impl.h +++ b/trunk/arch/alpha/kernel/irq_impl.h @@ -15,10 +15,10 @@ #define RTC_IRQ 8 -extern void isa_device_interrupt(unsigned long); -extern void isa_no_iack_sc_device_interrupt(unsigned long); -extern void srm_device_interrupt(unsigned long); -extern void pyxis_device_interrupt(unsigned long); +extern void isa_device_interrupt(unsigned long, struct pt_regs *); +extern void isa_no_iack_sc_device_interrupt(unsigned long, struct pt_regs *); +extern void srm_device_interrupt(unsigned long, struct pt_regs *); +extern void pyxis_device_interrupt(unsigned long, struct pt_regs *); extern struct irqaction timer_irqaction; extern struct irqaction isa_cascade_irqaction; @@ -39,4 +39,4 @@ extern void i8259a_end_irq(unsigned int); extern struct hw_interrupt_type i8259a_irq_type; extern void init_i8259a_irqs(void); -extern void handle_irq(int irq); +extern void handle_irq(int irq, struct pt_regs * regs); diff --git a/trunk/arch/alpha/kernel/irq_pyxis.c b/trunk/arch/alpha/kernel/irq_pyxis.c index d53edbccbfe5..3b581415bab0 100644 --- a/trunk/arch/alpha/kernel/irq_pyxis.c +++ b/trunk/arch/alpha/kernel/irq_pyxis.c @@ -81,7 +81,7 @@ static struct hw_interrupt_type pyxis_irq_type = { }; void -pyxis_device_interrupt(unsigned long vector) +pyxis_device_interrupt(unsigned long vector, struct pt_regs *regs) { unsigned long pld; unsigned int i; @@ -98,9 +98,9 @@ pyxis_device_interrupt(unsigned long vector) i = ffz(~pld); pld &= pld - 1; /* clear least bit set */ if (i == 7) - isa_device_interrupt(vector); + isa_device_interrupt(vector, regs); else - handle_irq(16+i); + handle_irq(16+i, regs); } } diff --git a/trunk/arch/alpha/kernel/irq_srm.c b/trunk/arch/alpha/kernel/irq_srm.c index 32212014fbe9..8e4d121f84cc 100644 --- a/trunk/arch/alpha/kernel/irq_srm.c +++ b/trunk/arch/alpha/kernel/irq_srm.c @@ -72,8 +72,8 @@ init_srm_irqs(long max, unsigned long ignore_mask) } void -srm_device_interrupt(unsigned long vector) +srm_device_interrupt(unsigned long vector, struct pt_regs * regs) { int irq = (vector - 0x800) >> 4; - handle_irq(irq); + handle_irq(irq, regs); } diff --git a/trunk/arch/alpha/kernel/pci-noop.c b/trunk/arch/alpha/kernel/pci-noop.c index 174b729c504b..fff5cf93e816 100644 --- a/trunk/arch/alpha/kernel/pci-noop.c +++ b/trunk/arch/alpha/kernel/pci-noop.c @@ -201,7 +201,6 @@ dma_set_mask(struct device *dev, u64 mask) return 0; } -EXPORT_SYMBOL(dma_set_mask); void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) { diff --git a/trunk/arch/alpha/kernel/pci_iommu.c b/trunk/arch/alpha/kernel/pci_iommu.c index 6e7d1fe6e935..c468e312e5f8 100644 --- a/trunk/arch/alpha/kernel/pci_iommu.c +++ b/trunk/arch/alpha/kernel/pci_iommu.c @@ -300,7 +300,6 @@ pci_map_single(struct pci_dev *pdev, void *cpu_addr, size_t size, int dir) dac_allowed = pdev ? pci_dac_dma_supported(pdev, pdev->dma_mask) : 0; return pci_map_single_1(pdev, cpu_addr, size, dac_allowed); } -EXPORT_SYMBOL(pci_map_single); dma_addr_t pci_map_page(struct pci_dev *pdev, struct page *page, unsigned long offset, @@ -315,7 +314,6 @@ pci_map_page(struct pci_dev *pdev, struct page *page, unsigned long offset, return pci_map_single_1(pdev, (char *)page_address(page) + offset, size, dac_allowed); } -EXPORT_SYMBOL(pci_map_page); /* Unmap a single streaming mode DMA translation. The DMA_ADDR and SIZE must match what was provided for in a previous pci_map_single @@ -381,7 +379,6 @@ pci_unmap_single(struct pci_dev *pdev, dma_addr_t dma_addr, size_t size, DBGA2("pci_unmap_single: sg [%lx,%lx] np %ld from %p\n", dma_addr, size, npages, __builtin_return_address(0)); } -EXPORT_SYMBOL(pci_unmap_single); void pci_unmap_page(struct pci_dev *pdev, dma_addr_t dma_addr, @@ -389,7 +386,6 @@ pci_unmap_page(struct pci_dev *pdev, dma_addr_t dma_addr, { pci_unmap_single(pdev, dma_addr, size, direction); } -EXPORT_SYMBOL(pci_unmap_page); /* Allocate and map kernel buffer using consistent mode DMA for PCI device. Returns non-NULL cpu-view pointer to the buffer if @@ -431,7 +427,6 @@ pci_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_addrp) return cpu_addr; } -EXPORT_SYMBOL(pci_alloc_consistent); /* Free and unmap a consistent DMA buffer. CPU_ADDR and DMA_ADDR must be values that were returned from pci_alloc_consistent. SIZE must @@ -449,7 +444,7 @@ pci_free_consistent(struct pci_dev *pdev, size_t size, void *cpu_addr, DBGA2("pci_free_consistent: [%x,%lx] from %p\n", dma_addr, size, __builtin_return_address(0)); } -EXPORT_SYMBOL(pci_free_consistent); + /* Classify the elements of the scatterlist. Write dma_address of each element with: @@ -677,7 +672,6 @@ pci_map_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents, pci_unmap_sg(pdev, start, out - start, direction); return 0; } -EXPORT_SYMBOL(pci_map_sg); /* Unmap a set of streaming mode DMA translations. Again, cpu read rules concerning calls here are the same as for pci_unmap_single() @@ -758,7 +752,6 @@ pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents, DBGA("pci_unmap_sg: %ld entries\n", nents - (end - sg)); } -EXPORT_SYMBOL(pci_unmap_sg); /* Return whether the given PCI device DMA address mask can be @@ -793,7 +786,6 @@ pci_dma_supported(struct pci_dev *pdev, u64 mask) return 0; } -EXPORT_SYMBOL(pci_dma_supported); /* @@ -916,7 +908,6 @@ pci_dac_dma_supported(struct pci_dev *dev, u64 mask) return ok; } -EXPORT_SYMBOL(pci_dac_dma_supported); dma64_addr_t pci_dac_page_to_dma(struct pci_dev *pdev, struct page *page, @@ -926,7 +917,6 @@ pci_dac_page_to_dma(struct pci_dev *pdev, struct page *page, + __pa(page_address(page)) + (dma64_addr_t) offset); } -EXPORT_SYMBOL(pci_dac_page_to_dma); struct page * pci_dac_dma_to_page(struct pci_dev *pdev, dma64_addr_t dma_addr) @@ -934,14 +924,13 @@ pci_dac_dma_to_page(struct pci_dev *pdev, dma64_addr_t dma_addr) unsigned long paddr = (dma_addr & PAGE_MASK) - alpha_mv.pci_dac_offset; return virt_to_page(__va(paddr)); } -EXPORT_SYMBOL(pci_dac_dma_to_page); unsigned long pci_dac_dma_to_offset(struct pci_dev *pdev, dma64_addr_t dma_addr) { return (dma_addr & ~PAGE_MASK); } -EXPORT_SYMBOL(pci_dac_dma_to_offset); + /* Helper for generic DMA-mapping functions. */ @@ -968,7 +957,6 @@ alpha_gendev_to_pci(struct device *dev) /* This assumes ISA bus master with dma_mask 0xffffff. */ return NULL; } -EXPORT_SYMBOL(alpha_gendev_to_pci); int dma_set_mask(struct device *dev, u64 mask) @@ -981,4 +969,3 @@ dma_set_mask(struct device *dev, u64 mask) return 0; } -EXPORT_SYMBOL(dma_set_mask); diff --git a/trunk/arch/alpha/kernel/process.c b/trunk/arch/alpha/kernel/process.c index 3370e6faeae0..b3a8a2980365 100644 --- a/trunk/arch/alpha/kernel/process.c +++ b/trunk/arch/alpha/kernel/process.c @@ -205,7 +205,6 @@ start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp) regs->ps = 8; wrusp(sp); } -EXPORT_SYMBOL(start_thread); /* * Free current thread data structures etc.. @@ -377,7 +376,6 @@ dump_thread(struct pt_regs * pt, struct user * dump) dump->regs[EF_A2] = pt->r18; memcpy((char *)dump->regs + EF_SIZE, sw->fp, 32 * 8); } -EXPORT_SYMBOL(dump_thread); /* * Fill in the user structure for a ELF core dump. @@ -426,7 +424,6 @@ dump_elf_thread(elf_greg_t *dest, struct pt_regs *pt, struct thread_info *ti) useful value of the thread's UNIQUE field. */ dest[32] = ti->pcb.unique; } -EXPORT_SYMBOL(dump_elf_thread); int dump_elf_task(elf_greg_t *dest, struct task_struct *task) @@ -434,7 +431,6 @@ dump_elf_task(elf_greg_t *dest, struct task_struct *task) dump_elf_thread(dest, task_pt_regs(task), task_thread_info(task)); return 1; } -EXPORT_SYMBOL(dump_elf_task); int dump_elf_task_fp(elf_fpreg_t *dest, struct task_struct *task) @@ -443,7 +439,6 @@ dump_elf_task_fp(elf_fpreg_t *dest, struct task_struct *task) memcpy(dest, sw->fp, 32 * 8); return 1; } -EXPORT_SYMBOL(dump_elf_task_fp); /* * sys_execve() executes a new program. diff --git a/trunk/arch/alpha/kernel/proto.h b/trunk/arch/alpha/kernel/proto.h index 95912ecc65e1..21f71287b6f5 100644 --- a/trunk/arch/alpha/kernel/proto.h +++ b/trunk/arch/alpha/kernel/proto.h @@ -20,7 +20,7 @@ struct pci_controller; extern struct pci_ops apecs_pci_ops; extern void apecs_init_arch(void); extern void apecs_pci_clr_err(void); -extern void apecs_machine_check(u64, u64); +extern void apecs_machine_check(u64, u64, struct pt_regs *); extern void apecs_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t); /* core_cia.c */ @@ -29,27 +29,27 @@ extern void cia_init_pci(void); extern void cia_init_arch(void); extern void pyxis_init_arch(void); extern void cia_kill_arch(int); -extern void cia_machine_check(u64, u64); +extern void cia_machine_check(u64, u64, struct pt_regs *); extern void cia_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t); /* core_irongate.c */ extern struct pci_ops irongate_pci_ops; extern int irongate_pci_clr_err(void); extern void irongate_init_arch(void); -extern void irongate_machine_check(u64, u64); +extern void irongate_machine_check(u64, u64, struct pt_regs *); #define irongate_pci_tbi ((void *)0) /* core_lca.c */ extern struct pci_ops lca_pci_ops; extern void lca_init_arch(void); -extern void lca_machine_check(u64, u64); +extern void lca_machine_check(u64, u64, struct pt_regs *); extern void lca_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t); /* core_marvel.c */ extern struct pci_ops marvel_pci_ops; extern void marvel_init_arch(void); extern void marvel_kill_arch(int); -extern void marvel_machine_check(u64, u64); +extern void marvel_machine_check(u64, u64, struct pt_regs *); extern void marvel_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t); extern int marvel_pa_to_nid(unsigned long); extern int marvel_cpuid_to_nid(int); @@ -64,7 +64,7 @@ void io7_clear_errors(struct io7 *io7); extern struct pci_ops mcpcia_pci_ops; extern void mcpcia_init_arch(void); extern void mcpcia_init_hoses(void); -extern void mcpcia_machine_check(u64, u64); +extern void mcpcia_machine_check(u64, u64, struct pt_regs *); extern void mcpcia_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t); /* core_polaris.c */ @@ -72,21 +72,21 @@ extern struct pci_ops polaris_pci_ops; extern int polaris_read_config_dword(struct pci_dev *, int, u32 *); extern int polaris_write_config_dword(struct pci_dev *, int, u32); extern void polaris_init_arch(void); -extern void polaris_machine_check(u64, u64); +extern void polaris_machine_check(u64, u64, struct pt_regs *); #define polaris_pci_tbi ((void *)0) /* core_t2.c */ extern struct pci_ops t2_pci_ops; extern void t2_init_arch(void); extern void t2_kill_arch(int); -extern void t2_machine_check(u64, u64); +extern void t2_machine_check(u64, u64, struct pt_regs *); extern void t2_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t); /* core_titan.c */ extern struct pci_ops titan_pci_ops; extern void titan_init_arch(void); extern void titan_kill_arch(int); -extern void titan_machine_check(u64, u64); +extern void titan_machine_check(u64, u64, struct pt_regs *); extern void titan_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t); extern struct _alpha_agp_info *titan_agp_info(void); @@ -94,14 +94,14 @@ extern struct _alpha_agp_info *titan_agp_info(void); extern struct pci_ops tsunami_pci_ops; extern void tsunami_init_arch(void); extern void tsunami_kill_arch(int); -extern void tsunami_machine_check(u64, u64); +extern void tsunami_machine_check(u64, u64, struct pt_regs *); extern void tsunami_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t); /* core_wildfire.c */ extern struct pci_ops wildfire_pci_ops; extern void wildfire_init_arch(void); extern void wildfire_kill_arch(int); -extern void wildfire_machine_check(u64, u64); +extern void wildfire_machine_check(u64, u64, struct pt_regs *); extern void wildfire_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t); extern int wildfire_pa_to_nid(unsigned long); extern int wildfire_cpuid_to_nid(int); @@ -133,7 +133,7 @@ extern void smp_percpu_timer_interrupt(struct pt_regs *); /* extern void reset_for_srm(void); */ /* time.c */ -extern irqreturn_t timer_interrupt(int irq, void *dev); +extern irqreturn_t timer_interrupt(int irq, void *dev, struct pt_regs * regs); extern void common_init_rtc(void); extern unsigned long est_cycle_freq; @@ -177,7 +177,7 @@ extern void dik_show_regs(struct pt_regs *regs, unsigned long *r9_15); extern void die_if_kernel(char *, struct pt_regs *, long, unsigned long *); /* sys_titan.c */ -extern void titan_dispatch_irqs(u64); +extern void titan_dispatch_irqs(u64, struct pt_regs *); /* ../mm/init.c */ extern void switch_to_system_map(void); @@ -214,4 +214,5 @@ extern struct mcheck_info #endif extern void process_mcheck_info(unsigned long vector, unsigned long la_ptr, - const char *machine, int expected); + struct pt_regs *regs, const char *machine, + int expected); diff --git a/trunk/arch/alpha/kernel/setup.c b/trunk/arch/alpha/kernel/setup.c index 1aea7c7c683c..a94e6d93e2ee 100644 --- a/trunk/arch/alpha/kernel/setup.c +++ b/trunk/arch/alpha/kernel/setup.c @@ -66,7 +66,6 @@ static struct notifier_block alpha_panic_block = { struct hwrpb_struct *hwrpb; -EXPORT_SYMBOL(hwrpb); unsigned long srm_hae; int alpha_l1i_cacheshape; @@ -112,7 +111,6 @@ unsigned long alpha_agpgart_size = DEFAULT_AGP_APER_SIZE; #ifdef CONFIG_ALPHA_GENERIC struct alpha_machine_vector alpha_mv; int alpha_using_srm; -EXPORT_SYMBOL(alpha_using_srm); #endif static struct alpha_machine_vector *get_sysvec(unsigned long, unsigned long, @@ -139,8 +137,6 @@ struct screen_info screen_info = { .orig_video_points = 16 }; -EXPORT_SYMBOL(screen_info); - /* * The direct map I/O window, if any. This should be the same * for all busses, since it's used by virt_to_bus. @@ -148,8 +144,6 @@ EXPORT_SYMBOL(screen_info); unsigned long __direct_map_base; unsigned long __direct_map_size; -EXPORT_SYMBOL(__direct_map_base); -EXPORT_SYMBOL(__direct_map_size); /* * Declare all of the machine vectors. diff --git a/trunk/arch/alpha/kernel/smp.c b/trunk/arch/alpha/kernel/smp.c index d1ec4f51df1a..4dc273e537fd 100644 --- a/trunk/arch/alpha/kernel/smp.c +++ b/trunk/arch/alpha/kernel/smp.c @@ -52,7 +52,6 @@ /* A collection of per-processor data. */ struct cpuinfo_alpha cpu_data[NR_CPUS]; -EXPORT_SYMBOL(cpu_data); /* A collection of single bit ipi messages. */ static struct { @@ -75,7 +74,6 @@ EXPORT_SYMBOL(cpu_online_map); int smp_num_probed; /* Internal processor count */ int smp_num_cpus = 1; /* Number that came online. */ -EXPORT_SYMBOL(smp_num_cpus); extern void calibrate_delay(void); @@ -517,15 +515,12 @@ smp_cpus_done(unsigned int max_cpus) void smp_percpu_timer_interrupt(struct pt_regs *regs) { - struct pt_regs *old_regs; int cpu = smp_processor_id(); unsigned long user = user_mode(regs); struct cpuinfo_alpha *data = &cpu_data[cpu]; - old_regs = set_irq_regs(regs); - /* Record kernel PC. */ - profile_tick(CPU_PROFILING); + profile_tick(CPU_PROFILING, regs); if (!--data->prof_counter) { /* We need to make like a normal interrupt -- otherwise @@ -539,7 +534,6 @@ smp_percpu_timer_interrupt(struct pt_regs *regs) irq_exit(); } - set_irq_regs(old_regs); } int __init @@ -792,7 +786,6 @@ smp_call_function_on_cpu (void (*func) (void *info), void *info, int retry, return 0; } -EXPORT_SYMBOL(smp_call_function_on_cpu); int smp_call_function (void (*func) (void *info), void *info, int retry, int wait) @@ -800,7 +793,6 @@ smp_call_function (void (*func) (void *info), void *info, int retry, int wait) return smp_call_function_on_cpu (func, info, retry, wait, cpu_online_map); } -EXPORT_SYMBOL(smp_call_function); static void ipi_imb(void *ignored) @@ -815,7 +807,6 @@ smp_imb(void) if (on_each_cpu(ipi_imb, NULL, 1, 1)) printk(KERN_CRIT "smp_imb: timed out\n"); } -EXPORT_SYMBOL(smp_imb); static void ipi_flush_tlb_all(void *ignored) @@ -871,7 +862,6 @@ flush_tlb_mm(struct mm_struct *mm) preempt_enable(); } -EXPORT_SYMBOL(flush_tlb_mm); struct flush_tlb_page_struct { struct vm_area_struct *vma; @@ -924,7 +914,6 @@ flush_tlb_page(struct vm_area_struct *vma, unsigned long addr) preempt_enable(); } -EXPORT_SYMBOL(flush_tlb_page); void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) @@ -932,7 +921,6 @@ flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long e /* On the Alpha we always flush the whole user tlb. */ flush_tlb_mm(vma->vm_mm); } -EXPORT_SYMBOL(flush_tlb_range); static void ipi_flush_icache_page(void *x) diff --git a/trunk/arch/alpha/kernel/srm_env.c b/trunk/arch/alpha/kernel/srm_env.c index f7dd081d57ff..990ac61028f8 100644 --- a/trunk/arch/alpha/kernel/srm_env.c +++ b/trunk/arch/alpha/kernel/srm_env.c @@ -2,7 +2,7 @@ * srm_env.c - Access to SRM environment * variables through linux' procfs * - * (C) 2001,2002,2006 by Jan-Benedict Glaw + * Copyright (C) 2001-2002 Jan-Benedict Glaw * * This driver is at all a modified version of Erik Mouw's * Documentation/DocBook/procfs_example.c, so: thank @@ -21,7 +21,7 @@ * 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, @@ -29,6 +29,33 @@ * */ +/* + * Changelog + * ~~~~~~~~~ + * + * Thu, 22 Aug 2002 15:10:43 +0200 + * - Update Config.help entry. I got a number of emails asking + * me to tell their senders if they could make use of this + * piece of code... So: "SRM is something like BIOS for your + * Alpha" + * - Update code formatting a bit to better conform CodingStyle + * rules. + * - So this is v0.0.5, with no changes (except formatting) + * + * Wed, 22 May 2002 00:11:21 +0200 + * - Fix typo on comment (SRC -> SRM) + * - Call this "Version 0.0.4" + * + * Tue, 9 Apr 2002 18:44:40 +0200 + * - Implement access by variable name and additionally + * by number. This is done by creating two subdirectories + * where one holds all names (like the old directory + * did) and the other holding 256 files named like "0", + * "1" and so on. + * - Call this "Version 0.0.3" + * + */ + #include #include #include @@ -40,7 +67,7 @@ #define BASE_DIR "srm_environment" /* Subdir in /proc/ */ #define NAMED_DIR "named_variables" /* Subdir for known variables */ #define NUMBERED_DIR "numbered_variables" /* Subdir for all variables */ -#define VERSION "0.0.6" /* Module version */ +#define VERSION "0.0.5" /* Module version */ #define NAME "srm_env" /* Module name */ MODULE_AUTHOR("Jan-Benedict Glaw "); @@ -79,6 +106,7 @@ static srm_env_t srm_named_entries[] = { static srm_env_t srm_numbered_entries[256]; + static int srm_env_read(char *page, char **start, off_t off, int count, int *eof, void *data) @@ -87,23 +115,21 @@ srm_env_read(char *page, char **start, off_t off, int count, int *eof, unsigned long ret; srm_env_t *entry; - if (off != 0) { - *eof = 1; - return 0; - } + if(off != 0) + return -EFAULT; entry = (srm_env_t *) data; ret = callback_getenv(entry->id, page, count); - if ((ret >> 61) == 0) { + if((ret >> 61) == 0) nbytes = (int) ret; - *eof = 1; - } else + else nbytes = -EFAULT; return nbytes; } + static int srm_env_write(struct file *file, const char __user *buffer, unsigned long count, void *data) @@ -129,7 +155,7 @@ srm_env_write(struct file *file, const char __user *buffer, unsigned long count, ret1 = callback_setenv(entry->id, buf, count); if ((ret1 >> 61) == 0) { - do + do ret2 = callback_save_env(); while((ret2 >> 61) == 1); res = (int) ret1; @@ -146,14 +172,14 @@ srm_env_cleanup(void) srm_env_t *entry; unsigned long var_num; - if (base_dir) { + if(base_dir) { /* * Remove named entries */ - if (named_dir) { + if(named_dir) { entry = srm_named_entries; - while (entry->name != NULL && entry->id != 0) { - if (entry->proc_entry) { + while(entry->name != NULL && entry->id != 0) { + if(entry->proc_entry) { remove_proc_entry(entry->name, named_dir); entry->proc_entry = NULL; @@ -166,11 +192,11 @@ srm_env_cleanup(void) /* * Remove numbered entries */ - if (numbered_dir) { - for (var_num = 0; var_num <= 255; var_num++) { + if(numbered_dir) { + for(var_num = 0; var_num <= 255; var_num++) { entry = &srm_numbered_entries[var_num]; - if (entry->proc_entry) { + if(entry->proc_entry) { remove_proc_entry(entry->name, numbered_dir); entry->proc_entry = NULL; @@ -186,6 +212,7 @@ srm_env_cleanup(void) return; } + static int __init srm_env_init(void) { @@ -195,7 +222,7 @@ srm_env_init(void) /* * Check system */ - if (!alpha_using_srm) { + if(!alpha_using_srm) { printk(KERN_INFO "%s: This Alpha system doesn't " "know about SRM (or you've booted " "SRM->MILO->Linux, which gets " @@ -206,14 +233,14 @@ srm_env_init(void) /* * Init numbers */ - for (var_num = 0; var_num <= 255; var_num++) + for(var_num = 0; var_num <= 255; var_num++) sprintf(number[var_num], "%ld", var_num); /* * Create base directory */ base_dir = proc_mkdir(BASE_DIR, NULL); - if (!base_dir) { + if(base_dir == NULL) { printk(KERN_ERR "Couldn't create base dir /proc/%s\n", BASE_DIR); goto cleanup; @@ -224,7 +251,7 @@ srm_env_init(void) * Create per-name subdirectory */ named_dir = proc_mkdir(NAMED_DIR, base_dir); - if (!named_dir) { + if(named_dir == NULL) { printk(KERN_ERR "Couldn't create dir /proc/%s/%s\n", BASE_DIR, NAMED_DIR); goto cleanup; @@ -235,7 +262,7 @@ srm_env_init(void) * Create per-number subdirectory */ numbered_dir = proc_mkdir(NUMBERED_DIR, base_dir); - if (!numbered_dir) { + if(numbered_dir == NULL) { printk(KERN_ERR "Couldn't create dir /proc/%s/%s\n", BASE_DIR, NUMBERED_DIR); goto cleanup; @@ -247,10 +274,10 @@ srm_env_init(void) * Create all named nodes */ entry = srm_named_entries; - while (entry->name && entry->id) { + while(entry->name != NULL && entry->id != 0) { entry->proc_entry = create_proc_entry(entry->name, 0644, named_dir); - if (!entry->proc_entry) + if(entry->proc_entry == NULL) goto cleanup; entry->proc_entry->data = (void *) entry; @@ -264,13 +291,13 @@ srm_env_init(void) /* * Create all numbered nodes */ - for (var_num = 0; var_num <= 255; var_num++) { + for(var_num = 0; var_num <= 255; var_num++) { entry = &srm_numbered_entries[var_num]; entry->name = number[var_num]; entry->proc_entry = create_proc_entry(entry->name, 0644, numbered_dir); - if (!entry->proc_entry) + if(entry->proc_entry == NULL) goto cleanup; entry->id = var_num; @@ -291,6 +318,7 @@ srm_env_init(void) return -ENOMEM; } + static void __exit srm_env_exit(void) { @@ -300,5 +328,7 @@ srm_env_exit(void) return; } + module_init(srm_env_init); module_exit(srm_env_exit); + diff --git a/trunk/arch/alpha/kernel/sys_alcor.c b/trunk/arch/alpha/kernel/sys_alcor.c index 49bedfbbd31b..d6926b7b1e99 100644 --- a/trunk/arch/alpha/kernel/sys_alcor.c +++ b/trunk/arch/alpha/kernel/sys_alcor.c @@ -100,7 +100,7 @@ static struct hw_interrupt_type alcor_irq_type = { }; static void -alcor_device_interrupt(unsigned long vector) +alcor_device_interrupt(unsigned long vector, struct pt_regs *regs) { unsigned long pld; unsigned int i; @@ -116,9 +116,9 @@ alcor_device_interrupt(unsigned long vector) i = ffz(~pld); pld &= pld - 1; /* clear least bit set */ if (i == 31) { - isa_device_interrupt(vector); + isa_device_interrupt(vector, regs); } else { - handle_irq(16 + i); + handle_irq(16 + i, regs); } } } diff --git a/trunk/arch/alpha/kernel/sys_cabriolet.c b/trunk/arch/alpha/kernel/sys_cabriolet.c index ace475c124f6..25a215067da8 100644 --- a/trunk/arch/alpha/kernel/sys_cabriolet.c +++ b/trunk/arch/alpha/kernel/sys_cabriolet.c @@ -82,7 +82,7 @@ static struct hw_interrupt_type cabriolet_irq_type = { }; static void -cabriolet_device_interrupt(unsigned long v) +cabriolet_device_interrupt(unsigned long v, struct pt_regs *r) { unsigned long pld; unsigned int i; @@ -98,15 +98,15 @@ cabriolet_device_interrupt(unsigned long v) i = ffz(~pld); pld &= pld - 1; /* clear least bit set */ if (i == 4) { - isa_device_interrupt(v); + isa_device_interrupt(v, r); } else { - handle_irq(16 + i); + handle_irq(16 + i, r); } } } static void __init -common_init_irq(void (*srm_dev_int)(unsigned long v)) +common_init_irq(void (*srm_dev_int)(unsigned long v, struct pt_regs *r)) { init_i8259a_irqs(); @@ -154,18 +154,18 @@ cabriolet_init_irq(void) too invasive though. */ static void -pc164_srm_device_interrupt(unsigned long v) +pc164_srm_device_interrupt(unsigned long v, struct pt_regs *r) { __min_ipl = getipl(); - srm_device_interrupt(v); + srm_device_interrupt(v, r); __min_ipl = 0; } static void -pc164_device_interrupt(unsigned long v) +pc164_device_interrupt(unsigned long v, struct pt_regs *r) { __min_ipl = getipl(); - cabriolet_device_interrupt(v); + cabriolet_device_interrupt(v, r); __min_ipl = 0; } diff --git a/trunk/arch/alpha/kernel/sys_dp264.c b/trunk/arch/alpha/kernel/sys_dp264.c index 85d2f933dd07..dd6103b867e7 100644 --- a/trunk/arch/alpha/kernel/sys_dp264.c +++ b/trunk/arch/alpha/kernel/sys_dp264.c @@ -217,7 +217,7 @@ static struct hw_interrupt_type clipper_irq_type = { }; static void -dp264_device_interrupt(unsigned long vector) +dp264_device_interrupt(unsigned long vector, struct pt_regs * regs) { #if 1 printk("dp264_device_interrupt: NOT IMPLEMENTED YET!! \n"); @@ -236,9 +236,9 @@ dp264_device_interrupt(unsigned long vector) i = ffz(~pld); pld &= pld - 1; /* clear least bit set */ if (i == 55) - isa_device_interrupt(vector); + isa_device_interrupt(vector, regs); else - handle_irq(16 + i); + handle_irq(16 + i, 16 + i, regs); #if 0 TSUNAMI_cchip->dir0.csr = 1UL << i; mb(); tmp = TSUNAMI_cchip->dir0.csr; @@ -248,7 +248,7 @@ dp264_device_interrupt(unsigned long vector) } static void -dp264_srm_device_interrupt(unsigned long vector) +dp264_srm_device_interrupt(unsigned long vector, struct pt_regs * regs) { int irq; @@ -268,11 +268,11 @@ dp264_srm_device_interrupt(unsigned long vector) if (irq >= 32) irq -= 16; - handle_irq(irq); + handle_irq(irq, regs); } static void -clipper_srm_device_interrupt(unsigned long vector) +clipper_srm_device_interrupt(unsigned long vector, struct pt_regs * regs) { int irq; @@ -290,7 +290,7 @@ clipper_srm_device_interrupt(unsigned long vector) * * Eg IRQ 24 is DRIR bit 8, etc, etc */ - handle_irq(irq); + handle_irq(irq, regs); } static void __init diff --git a/trunk/arch/alpha/kernel/sys_eb64p.c b/trunk/arch/alpha/kernel/sys_eb64p.c index 9c5a306dc0ee..ed108b66ec09 100644 --- a/trunk/arch/alpha/kernel/sys_eb64p.c +++ b/trunk/arch/alpha/kernel/sys_eb64p.c @@ -80,7 +80,7 @@ static struct hw_interrupt_type eb64p_irq_type = { }; static void -eb64p_device_interrupt(unsigned long vector) +eb64p_device_interrupt(unsigned long vector, struct pt_regs *regs) { unsigned long pld; unsigned int i; @@ -97,9 +97,9 @@ eb64p_device_interrupt(unsigned long vector) pld &= pld - 1; /* clear least bit set */ if (i == 5) { - isa_device_interrupt(vector); + isa_device_interrupt(vector, regs); } else { - handle_irq(16 + i); + handle_irq(16 + i, regs); } } } diff --git a/trunk/arch/alpha/kernel/sys_eiger.c b/trunk/arch/alpha/kernel/sys_eiger.c index 7ef3b6fb3700..64a785baf53a 100644 --- a/trunk/arch/alpha/kernel/sys_eiger.c +++ b/trunk/arch/alpha/kernel/sys_eiger.c @@ -91,7 +91,7 @@ static struct hw_interrupt_type eiger_irq_type = { }; static void -eiger_device_interrupt(unsigned long vector) +eiger_device_interrupt(unsigned long vector, struct pt_regs * regs) { unsigned intstatus; @@ -118,20 +118,20 @@ eiger_device_interrupt(unsigned long vector) * despatch an interrupt if it's set. */ - if (intstatus & 8) handle_irq(16+3); - if (intstatus & 4) handle_irq(16+2); - if (intstatus & 2) handle_irq(16+1); - if (intstatus & 1) handle_irq(16+0); + if (intstatus & 8) handle_irq(16+3, regs); + if (intstatus & 4) handle_irq(16+2, regs); + if (intstatus & 2) handle_irq(16+1, regs); + if (intstatus & 1) handle_irq(16+0, regs); } else { - isa_device_interrupt(vector); + isa_device_interrupt(vector, regs); } } static void -eiger_srm_device_interrupt(unsigned long vector) +eiger_srm_device_interrupt(unsigned long vector, struct pt_regs * regs) { int irq = (vector - 0x800) >> 4; - handle_irq(irq); + handle_irq(irq, regs); } static void __init diff --git a/trunk/arch/alpha/kernel/sys_jensen.c b/trunk/arch/alpha/kernel/sys_jensen.c index 2c3de97de46c..4ac2b328b8de 100644 --- a/trunk/arch/alpha/kernel/sys_jensen.c +++ b/trunk/arch/alpha/kernel/sys_jensen.c @@ -129,7 +129,7 @@ static struct hw_interrupt_type jensen_local_irq_type = { }; static void -jensen_device_interrupt(unsigned long vector) +jensen_device_interrupt(unsigned long vector, struct pt_regs * regs) { int irq; @@ -189,7 +189,7 @@ jensen_device_interrupt(unsigned long vector) if (cc - last_msg > ((JENSEN_CYCLES_PER_SEC) * 3) || irq != last_irq) { printk(KERN_CRIT " irq %d count %d cc %u @ %lx\n", - irq, count, cc-last_cc, get_irq_regs()->pc); + irq, count, cc-last_cc, regs->pc); count = 0; last_msg = cc; last_irq = irq; @@ -198,7 +198,7 @@ jensen_device_interrupt(unsigned long vector) } #endif - handle_irq(irq); + handle_irq(irq, regs); } static void __init @@ -244,7 +244,7 @@ jensen_init_arch(void) } static void -jensen_machine_check (u64 vector, u64 la) +jensen_machine_check (u64 vector, u64 la, struct pt_regs *regs) { printk(KERN_CRIT "Machine check\n"); } diff --git a/trunk/arch/alpha/kernel/sys_marvel.c b/trunk/arch/alpha/kernel/sys_marvel.c index e349f03b830e..36d215954376 100644 --- a/trunk/arch/alpha/kernel/sys_marvel.c +++ b/trunk/arch/alpha/kernel/sys_marvel.c @@ -38,7 +38,7 @@ * Interrupt handling. */ static void -io7_device_interrupt(unsigned long vector) +io7_device_interrupt(unsigned long vector, struct pt_regs * regs) { unsigned int pid; unsigned int irq; @@ -64,7 +64,7 @@ io7_device_interrupt(unsigned long vector) irq &= MARVEL_IRQ_VEC_IRQ_MASK; /* not too many bits */ irq |= pid << MARVEL_IRQ_VEC_PE_SHIFT; /* merge the pid */ - handle_irq(irq); + handle_irq(irq, regs); } static volatile unsigned long * diff --git a/trunk/arch/alpha/kernel/sys_miata.c b/trunk/arch/alpha/kernel/sys_miata.c index b8b817feb1ee..61ac56f8eeea 100644 --- a/trunk/arch/alpha/kernel/sys_miata.c +++ b/trunk/arch/alpha/kernel/sys_miata.c @@ -33,7 +33,7 @@ static void -miata_srm_device_interrupt(unsigned long vector) +miata_srm_device_interrupt(unsigned long vector, struct pt_regs * regs) { int irq; @@ -56,7 +56,7 @@ miata_srm_device_interrupt(unsigned long vector) if (irq >= 16) irq = irq + 8; - handle_irq(irq); + handle_irq(irq, regs); } static void __init diff --git a/trunk/arch/alpha/kernel/sys_mikasa.c b/trunk/arch/alpha/kernel/sys_mikasa.c index 8d3e9429c5ee..cc4c58111366 100644 --- a/trunk/arch/alpha/kernel/sys_mikasa.c +++ b/trunk/arch/alpha/kernel/sys_mikasa.c @@ -79,7 +79,7 @@ static struct hw_interrupt_type mikasa_irq_type = { }; static void -mikasa_device_interrupt(unsigned long vector) +mikasa_device_interrupt(unsigned long vector, struct pt_regs *regs) { unsigned long pld; unsigned int i; @@ -97,9 +97,9 @@ mikasa_device_interrupt(unsigned long vector) i = ffz(~pld); pld &= pld - 1; /* clear least bit set */ if (i < 16) { - isa_device_interrupt(vector); + isa_device_interrupt(vector, regs); } else { - handle_irq(i); + handle_irq(i, regs); } } } @@ -182,7 +182,8 @@ mikasa_map_irq(struct pci_dev *dev, u8 slot, u8 pin) #if defined(CONFIG_ALPHA_GENERIC) || !defined(CONFIG_ALPHA_PRIMO) static void -mikasa_apecs_machine_check(unsigned long vector, unsigned long la_ptr) +mikasa_apecs_machine_check(unsigned long vector, unsigned long la_ptr, + struct pt_regs * regs) { #define MCHK_NO_DEVSEL 0x205U #define MCHK_NO_TABT 0x204U @@ -201,7 +202,7 @@ mikasa_apecs_machine_check(unsigned long vector, unsigned long la_ptr) mb(); code = mchk_header->code; - process_mcheck_info(vector, la_ptr, "MIKASA APECS", + process_mcheck_info(vector, la_ptr, regs, "MIKASA APECS", (mcheck_expected(0) && (code == MCHK_NO_DEVSEL || code == MCHK_NO_TABT))); diff --git a/trunk/arch/alpha/kernel/sys_nautilus.c b/trunk/arch/alpha/kernel/sys_nautilus.c index 93744bab73fb..c0d696efec5b 100644 --- a/trunk/arch/alpha/kernel/sys_nautilus.c +++ b/trunk/arch/alpha/kernel/sys_nautilus.c @@ -124,7 +124,8 @@ naut_sys_machine_check(unsigned long vector, unsigned long la_ptr, in the system. They are analysed separately but all starts here. */ void -nautilus_machine_check(unsigned long vector, unsigned long la_ptr) +nautilus_machine_check(unsigned long vector, unsigned long la_ptr, + struct pt_regs *regs) { char *mchk_class; @@ -164,7 +165,7 @@ nautilus_machine_check(unsigned long vector, unsigned long la_ptr) else if (vector == SCB_Q_SYSMCHK) mchk_class = "Fatal"; else { - ev6_machine_check(vector, la_ptr); + ev6_machine_check(vector, la_ptr, regs); return; } @@ -172,7 +173,7 @@ nautilus_machine_check(unsigned long vector, unsigned long la_ptr) "[%s System Machine Check (NMI)]\n", vector, mchk_class); - naut_sys_machine_check(vector, la_ptr, get_irq_regs()); + naut_sys_machine_check(vector, la_ptr, regs); /* Tell the PALcode to clear the machine check */ draina(); diff --git a/trunk/arch/alpha/kernel/sys_noritake.c b/trunk/arch/alpha/kernel/sys_noritake.c index de6ba3432e8a..2d3cff7e8c5f 100644 --- a/trunk/arch/alpha/kernel/sys_noritake.c +++ b/trunk/arch/alpha/kernel/sys_noritake.c @@ -77,7 +77,7 @@ static struct hw_interrupt_type noritake_irq_type = { }; static void -noritake_device_interrupt(unsigned long vector) +noritake_device_interrupt(unsigned long vector, struct pt_regs *regs) { unsigned long pld; unsigned int i; @@ -96,15 +96,15 @@ noritake_device_interrupt(unsigned long vector) i = ffz(~pld); pld &= pld - 1; /* clear least bit set */ if (i < 16) { - isa_device_interrupt(vector); + isa_device_interrupt(vector, regs); } else { - handle_irq(i); + handle_irq(i, regs); } } } static void -noritake_srm_device_interrupt(unsigned long vector) +noritake_srm_device_interrupt(unsigned long vector, struct pt_regs * regs) { int irq; @@ -122,7 +122,7 @@ noritake_srm_device_interrupt(unsigned long vector) if (irq >= 16) irq = irq + 1; - handle_irq(irq); + handle_irq(irq, regs); } static void __init @@ -264,7 +264,8 @@ noritake_swizzle(struct pci_dev *dev, u8 *pinp) #if defined(CONFIG_ALPHA_GENERIC) || !defined(CONFIG_ALPHA_PRIMO) static void -noritake_apecs_machine_check(unsigned long vector, unsigned long la_ptr) +noritake_apecs_machine_check(unsigned long vector, unsigned long la_ptr, + struct pt_regs * regs) { #define MCHK_NO_DEVSEL 0x205U #define MCHK_NO_TABT 0x204U @@ -283,7 +284,7 @@ noritake_apecs_machine_check(unsigned long vector, unsigned long la_ptr) mb(); code = mchk_header->code; - process_mcheck_info(vector, la_ptr, "NORITAKE APECS", + process_mcheck_info(vector, la_ptr, regs, "NORITAKE APECS", (mcheck_expected(0) && (code == MCHK_NO_DEVSEL || code == MCHK_NO_TABT))); diff --git a/trunk/arch/alpha/kernel/sys_rawhide.c b/trunk/arch/alpha/kernel/sys_rawhide.c index 581d08c70b92..949607e3d6fb 100644 --- a/trunk/arch/alpha/kernel/sys_rawhide.c +++ b/trunk/arch/alpha/kernel/sys_rawhide.c @@ -134,7 +134,7 @@ static struct hw_interrupt_type rawhide_irq_type = { }; static void -rawhide_srm_device_interrupt(unsigned long vector) +rawhide_srm_device_interrupt(unsigned long vector, struct pt_regs * regs) { int irq; @@ -158,7 +158,7 @@ rawhide_srm_device_interrupt(unsigned long vector) /* Adjust by which hose it is from. */ irq -= ((irq + 16) >> 2) & 0x38; - handle_irq(irq); + handle_irq(irq, regs); } static void __init diff --git a/trunk/arch/alpha/kernel/sys_rx164.c b/trunk/arch/alpha/kernel/sys_rx164.c index ce1faa6f1df1..6ae506052635 100644 --- a/trunk/arch/alpha/kernel/sys_rx164.c +++ b/trunk/arch/alpha/kernel/sys_rx164.c @@ -83,7 +83,7 @@ static struct hw_interrupt_type rx164_irq_type = { }; static void -rx164_device_interrupt(unsigned long vector) +rx164_device_interrupt(unsigned long vector, struct pt_regs *regs) { unsigned long pld; volatile unsigned int *dirr; @@ -102,9 +102,9 @@ rx164_device_interrupt(unsigned long vector) i = ffz(~pld); pld &= pld - 1; /* clear least bit set */ if (i == 20) { - isa_no_iack_sc_device_interrupt(vector); + isa_no_iack_sc_device_interrupt(vector, regs); } else { - handle_irq(16+i); + handle_irq(16+i, regs); } } } diff --git a/trunk/arch/alpha/kernel/sys_sable.c b/trunk/arch/alpha/kernel/sys_sable.c index 906019cfa681..a7a14647b50e 100644 --- a/trunk/arch/alpha/kernel/sys_sable.c +++ b/trunk/arch/alpha/kernel/sys_sable.c @@ -512,7 +512,7 @@ static struct hw_interrupt_type sable_lynx_irq_type = { }; static void -sable_lynx_srm_device_interrupt(unsigned long vector) +sable_lynx_srm_device_interrupt(unsigned long vector, struct pt_regs * regs) { /* Note that the vector reported by the SRM PALcode corresponds to the interrupt mask bits, but we have to manage via the @@ -526,7 +526,7 @@ sable_lynx_srm_device_interrupt(unsigned long vector) printk("%s: vector 0x%lx bit 0x%x irq 0x%x\n", __FUNCTION__, vector, bit, irq); #endif - handle_irq(irq); + handle_irq(irq, regs); } static void __init diff --git a/trunk/arch/alpha/kernel/sys_takara.c b/trunk/arch/alpha/kernel/sys_takara.c index 9bd9a31450c6..2c75cd1fd81a 100644 --- a/trunk/arch/alpha/kernel/sys_takara.c +++ b/trunk/arch/alpha/kernel/sys_takara.c @@ -85,7 +85,7 @@ static struct hw_interrupt_type takara_irq_type = { }; static void -takara_device_interrupt(unsigned long vector) +takara_device_interrupt(unsigned long vector, struct pt_regs *regs) { unsigned intstatus; @@ -112,20 +112,20 @@ takara_device_interrupt(unsigned long vector) * despatch an interrupt if it's set. */ - if (intstatus & 8) handle_irq(16+3); - if (intstatus & 4) handle_irq(16+2); - if (intstatus & 2) handle_irq(16+1); - if (intstatus & 1) handle_irq(16+0); + if (intstatus & 8) handle_irq(16+3, regs); + if (intstatus & 4) handle_irq(16+2, regs); + if (intstatus & 2) handle_irq(16+1, regs); + if (intstatus & 1) handle_irq(16+0, regs); } else { - isa_device_interrupt (vector); + isa_device_interrupt (vector, regs); } } static void -takara_srm_device_interrupt(unsigned long vector) +takara_srm_device_interrupt(unsigned long vector, struct pt_regs * regs) { int irq = (vector - 0x800) >> 4; - handle_irq(irq); + handle_irq(irq, regs); } static void __init diff --git a/trunk/arch/alpha/kernel/sys_titan.c b/trunk/arch/alpha/kernel/sys_titan.c index 29ab7db81c30..302aab38d95f 100644 --- a/trunk/arch/alpha/kernel/sys_titan.c +++ b/trunk/arch/alpha/kernel/sys_titan.c @@ -167,18 +167,18 @@ titan_set_irq_affinity(unsigned int irq, cpumask_t affinity) } static void -titan_device_interrupt(unsigned long vector) +titan_device_interrupt(unsigned long vector, struct pt_regs * regs) { printk("titan_device_interrupt: NOT IMPLEMENTED YET!! \n"); } static void -titan_srm_device_interrupt(unsigned long vector) +titan_srm_device_interrupt(unsigned long vector, struct pt_regs * regs) { int irq; irq = (vector - 0x800) >> 4; - handle_irq(irq); + handle_irq(irq, regs); } @@ -204,7 +204,7 @@ static struct hw_interrupt_type titan_irq_type = { }; static irqreturn_t -titan_intr_nop(int irq, void *dev_id) +titan_intr_nop(int irq, void *dev_id, struct pt_regs *regs) { /* * This is a NOP interrupt handler for the purposes of @@ -243,7 +243,7 @@ titan_legacy_init_irq(void) } void -titan_dispatch_irqs(u64 mask) +titan_dispatch_irqs(u64 mask, struct pt_regs *regs) { unsigned long vector; @@ -263,7 +263,7 @@ titan_dispatch_irqs(u64 mask) vector = 0x900 + (vector << 4); /* convert to SRM vector */ /* dispatch it */ - alpha_mv.device_interrupt(vector); + alpha_mv.device_interrupt(vector, regs); } } diff --git a/trunk/arch/alpha/kernel/sys_wildfire.c b/trunk/arch/alpha/kernel/sys_wildfire.c index 42c3eede4d09..22c5798fe083 100644 --- a/trunk/arch/alpha/kernel/sys_wildfire.c +++ b/trunk/arch/alpha/kernel/sys_wildfire.c @@ -234,7 +234,7 @@ wildfire_init_irq(void) } static void -wildfire_device_interrupt(unsigned long vector) +wildfire_device_interrupt(unsigned long vector, struct pt_regs * regs) { int irq; @@ -246,7 +246,7 @@ wildfire_device_interrupt(unsigned long vector) * bits 5-0: irq in PCA */ - handle_irq(irq); + handle_irq(irq, regs); return; } diff --git a/trunk/arch/alpha/kernel/time.c b/trunk/arch/alpha/kernel/time.c index d7053eb4ffcf..581ddcc22fc5 100644 --- a/trunk/arch/alpha/kernel/time.c +++ b/trunk/arch/alpha/kernel/time.c @@ -57,7 +57,6 @@ static int set_rtc_mmss(unsigned long); DEFINE_SPINLOCK(rtc_lock); -EXPORT_SYMBOL(rtc_lock); #define TICK_SIZE (tick_nsec / 1000) @@ -105,7 +104,7 @@ unsigned long long sched_clock(void) * timer_interrupt() needs to keep up the real-time clock, * as well as call the "do_timer()" routine every clocktick */ -irqreturn_t timer_interrupt(int irq, void *dev) +irqreturn_t timer_interrupt(int irq, void *dev, struct pt_regs * regs) { unsigned long delta; __u32 now; @@ -113,7 +112,7 @@ irqreturn_t timer_interrupt(int irq, void *dev) #ifndef CONFIG_SMP /* Not SMP, do kernel PC profiling here. */ - profile_tick(CPU_PROFILING); + profile_tick(CPU_PROFILING, regs); #endif write_seqlock(&xtime_lock); @@ -133,7 +132,7 @@ irqreturn_t timer_interrupt(int irq, void *dev) while (nticks > 0) { do_timer(1); #ifndef CONFIG_SMP - update_process_times(user_mode(get_irq_regs())); + update_process_times(user_mode(regs)); #endif nticks--; } diff --git a/trunk/arch/alpha/kernel/vmlinux.lds.S b/trunk/arch/alpha/kernel/vmlinux.lds.S index 76bf071e376c..71470e9d93ba 100644 --- a/trunk/arch/alpha/kernel/vmlinux.lds.S +++ b/trunk/arch/alpha/kernel/vmlinux.lds.S @@ -48,7 +48,13 @@ SECTIONS . = ALIGN(8); __initcall_start = .; .initcall.init : { - INITCALLS + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) } __initcall_end = .; diff --git a/trunk/arch/alpha/mm/numa.c b/trunk/arch/alpha/mm/numa.c index e3e3806a6f25..b826f58c6e72 100644 --- a/trunk/arch/alpha/mm/numa.c +++ b/trunk/arch/alpha/mm/numa.c @@ -13,14 +13,12 @@ #include #include #include -#include #include #include pg_data_t node_data[MAX_NUMNODES]; bootmem_data_t node_bdata[MAX_NUMNODES]; -EXPORT_SYMBOL(node_data); #undef DEBUG_DISCONTIG #ifdef DEBUG_DISCONTIG diff --git a/trunk/arch/arm/Kconfig b/trunk/arch/arm/Kconfig index ce00c570459d..adb05de40e24 100644 --- a/trunk/arch/arm/Kconfig +++ b/trunk/arch/arm/Kconfig @@ -879,8 +879,6 @@ endif source "drivers/scsi/Kconfig" -source "drivers/ata/Kconfig" - source "drivers/md/Kconfig" source "drivers/message/fusion/Kconfig" diff --git a/trunk/arch/arm/Makefile b/trunk/arch/arm/Makefile index 6f4f8bf36071..2a0b2c8a1fe0 100644 --- a/trunk/arch/arm/Makefile +++ b/trunk/arch/arm/Makefile @@ -174,13 +174,11 @@ libs-y := arch/arm/lib/ $(libs-y) # Default target when executing plain make ifeq ($(CONFIG_XIP_KERNEL),y) -KBUILD_IMAGE := xipImage +all: xipImage else -KBUILD_IMAGE := zImage +all: zImage endif -all: $(KBUILD_IMAGE) - boot := arch/arm/boot # Update machine arch and proc symlinks if something which affects diff --git a/trunk/arch/arm/common/dmabounce.c b/trunk/arch/arm/common/dmabounce.c index 2e635b814c14..028bdc9228fb 100644 --- a/trunk/arch/arm/common/dmabounce.c +++ b/trunk/arch/arm/common/dmabounce.c @@ -662,8 +662,7 @@ EXPORT_SYMBOL(dma_map_single); EXPORT_SYMBOL(dma_unmap_single); EXPORT_SYMBOL(dma_map_sg); EXPORT_SYMBOL(dma_unmap_sg); -EXPORT_SYMBOL(dma_sync_single_for_cpu); -EXPORT_SYMBOL(dma_sync_single_for_device); +EXPORT_SYMBOL(dma_sync_single); EXPORT_SYMBOL(dma_sync_sg); EXPORT_SYMBOL(dmabounce_register_dev); EXPORT_SYMBOL(dmabounce_unregister_dev); diff --git a/trunk/arch/arm/common/locomo.c b/trunk/arch/arm/common/locomo.c index 80a72c75214f..181ef1ead5b8 100644 --- a/trunk/arch/arm/common/locomo.c +++ b/trunk/arch/arm/common/locomo.c @@ -163,7 +163,8 @@ static struct locomo_dev_info locomo_devices[] = { #define LOCOMO_IRQ_LT_START (IRQ_LOCOMO_LT) #define LOCOMO_IRQ_SPI_START (IRQ_LOCOMO_SPI_RFR) -static void locomo_handler(unsigned int irq, struct irqdesc *desc) +static void locomo_handler(unsigned int irq, struct irqdesc *desc, + struct pt_regs *regs) { int req, i; struct irqdesc *d; @@ -181,7 +182,7 @@ static void locomo_handler(unsigned int irq, struct irqdesc *desc) d = irq_desc + irq; for (i = 0; i <= 3; i++, d++, irq++) { if (req & (0x0100 << i)) { - desc_handle_irq(irq, d); + desc_handle_irq(irq, d, regs); } } @@ -217,14 +218,15 @@ static struct irq_chip locomo_chip = { .unmask = locomo_unmask_irq, }; -static void locomo_key_handler(unsigned int irq, struct irqdesc *desc) +static void locomo_key_handler(unsigned int irq, struct irqdesc *desc, + struct pt_regs *regs) { struct irqdesc *d; void __iomem *mapbase = get_irq_chipdata(irq); if (locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC) & 0x0001) { d = irq_desc + LOCOMO_IRQ_KEY_START; - desc_handle_irq(LOCOMO_IRQ_KEY_START, d); + desc_handle_irq(LOCOMO_IRQ_KEY_START, d, regs); } } @@ -262,7 +264,8 @@ static struct irq_chip locomo_key_chip = { .unmask = locomo_key_unmask_irq, }; -static void locomo_gpio_handler(unsigned int irq, struct irqdesc *desc) +static void locomo_gpio_handler(unsigned int irq, struct irqdesc *desc, + struct pt_regs *regs) { int req, i; struct irqdesc *d; @@ -277,7 +280,7 @@ static void locomo_gpio_handler(unsigned int irq, struct irqdesc *desc) d = irq_desc + LOCOMO_IRQ_GPIO_START; for (i = 0; i <= 15; i++, irq++, d++) { if (req & (0x0001 << i)) { - desc_handle_irq(irq, d); + desc_handle_irq(irq, d, regs); } } } @@ -325,14 +328,15 @@ static struct irq_chip locomo_gpio_chip = { .unmask = locomo_gpio_unmask_irq, }; -static void locomo_lt_handler(unsigned int irq, struct irqdesc *desc) +static void locomo_lt_handler(unsigned int irq, struct irqdesc *desc, + struct pt_regs *regs) { struct irqdesc *d; void __iomem *mapbase = get_irq_chipdata(irq); if (locomo_readl(mapbase + LOCOMO_LTINT) & 0x0001) { d = irq_desc + LOCOMO_IRQ_LT_START; - desc_handle_irq(LOCOMO_IRQ_LT_START, d); + desc_handle_irq(LOCOMO_IRQ_LT_START, d, regs); } } @@ -370,7 +374,8 @@ static struct irq_chip locomo_lt_chip = { .unmask = locomo_lt_unmask_irq, }; -static void locomo_spi_handler(unsigned int irq, struct irqdesc *desc) +static void locomo_spi_handler(unsigned int irq, struct irqdesc *desc, + struct pt_regs *regs) { int req, i; struct irqdesc *d; @@ -383,7 +388,7 @@ static void locomo_spi_handler(unsigned int irq, struct irqdesc *desc) for (i = 0; i <= 3; i++, irq++, d++) { if (req & (0x0001 << i)) { - desc_handle_irq(irq, d); + desc_handle_irq(irq, d, regs); } } } diff --git a/trunk/arch/arm/common/sa1111.c b/trunk/arch/arm/common/sa1111.c index d5f72010a6f3..30046ad41ced 100644 --- a/trunk/arch/arm/common/sa1111.c +++ b/trunk/arch/arm/common/sa1111.c @@ -147,7 +147,7 @@ void __init sa1111_adjust_zones(int node, unsigned long *size, unsigned long *ho * will call us again if there are more interrupts to process. */ static void -sa1111_irq_handler(unsigned int irq, struct irqdesc *desc) +sa1111_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) { unsigned int stat0, stat1, i; void __iomem *base = get_irq_data(irq); @@ -162,17 +162,17 @@ sa1111_irq_handler(unsigned int irq, struct irqdesc *desc) sa1111_writel(stat1, base + SA1111_INTSTATCLR1); if (stat0 == 0 && stat1 == 0) { - do_bad_IRQ(irq, desc); + do_bad_IRQ(irq, desc, regs); return; } for (i = IRQ_SA1111_START; stat0; i++, stat0 >>= 1) if (stat0 & 1) - handle_edge_irq(i, irq_desc + i); + handle_edge_irq(i, irq_desc + i, regs); for (i = IRQ_SA1111_START + 32; stat1; i++, stat1 >>= 1) if (stat1 & 1) - handle_edge_irq(i, irq_desc + i); + handle_edge_irq(i, irq_desc + i, regs); /* For level-based interrupts */ desc->chip->unmask(irq); diff --git a/trunk/arch/arm/common/sharpsl_pm.c b/trunk/arch/arm/common/sharpsl_pm.c index 605dedf96790..f412dedda684 100644 --- a/trunk/arch/arm/common/sharpsl_pm.c +++ b/trunk/arch/arm/common/sharpsl_pm.c @@ -258,7 +258,7 @@ static void sharpsl_ac_timer(unsigned long data) } -irqreturn_t sharpsl_ac_isr(int irq, void *dev_id) +irqreturn_t sharpsl_ac_isr(int irq, void *dev_id, struct pt_regs *fp) { /* Delay the event slightly to debounce */ /* Must be a smaller delay than the chrg_full_isr below */ @@ -293,7 +293,7 @@ static void sharpsl_chrg_full_timer(unsigned long data) /* Charging Finished Interrupt (Not present on Corgi) */ /* Can trigger at the same time as an AC staus change so delay until after that has been processed */ -irqreturn_t sharpsl_chrg_full_isr(int irq, void *dev_id) +irqreturn_t sharpsl_chrg_full_isr(int irq, void *dev_id, struct pt_regs *fp) { if (sharpsl_pm.flags & SHARPSL_SUSPENDED) return IRQ_HANDLED; @@ -304,7 +304,7 @@ irqreturn_t sharpsl_chrg_full_isr(int irq, void *dev_id) return IRQ_HANDLED; } -irqreturn_t sharpsl_fatal_isr(int irq, void *dev_id) +irqreturn_t sharpsl_fatal_isr(int irq, void *dev_id, struct pt_regs *fp) { int is_fatal = 0; diff --git a/trunk/arch/arm/common/time-acorn.c b/trunk/arch/arm/common/time-acorn.c index 34038eccbba9..3f60dd9aca80 100644 --- a/trunk/arch/arm/common/time-acorn.c +++ b/trunk/arch/arm/common/time-acorn.c @@ -67,10 +67,10 @@ void __init ioctime_init(void) } static irqreturn_t -ioc_timer_interrupt(int irq, void *dev_id) +ioc_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { write_seqlock(&xtime_lock); - timer_tick(); + timer_tick(regs); write_sequnlock(&xtime_lock); return IRQ_HANDLED; } diff --git a/trunk/arch/arm/configs/assabet_defconfig b/trunk/arch/arm/configs/assabet_defconfig index b1cd331aaecf..089c9d598409 100644 --- a/trunk/arch/arm/configs/assabet_defconfig +++ b/trunk/arch/arm/configs/assabet_defconfig @@ -184,7 +184,6 @@ CONFIG_BINFMT_ELF=y # Power management options # CONFIG_PM=y -# CONFIG_PM_LEGACY is not set # CONFIG_APM is not set # diff --git a/trunk/arch/arm/configs/ateb9200_defconfig b/trunk/arch/arm/configs/ateb9200_defconfig index 3de5c643848c..15e6b0bbbde8 100644 --- a/trunk/arch/arm/configs/ateb9200_defconfig +++ b/trunk/arch/arm/configs/ateb9200_defconfig @@ -217,7 +217,7 @@ CONFIG_BINFMT_ELF=y # Power management options # CONFIG_PM=y -# CONFIG_PM_LEGACY is not set +CONFIG_PM_LEGACY=y # CONFIG_PM_DEBUG is not set # CONFIG_APM is not set diff --git a/trunk/arch/arm/configs/realview-smp_defconfig b/trunk/arch/arm/configs/bast_defconfig similarity index 58% rename from trunk/arch/arm/configs/realview-smp_defconfig rename to trunk/arch/arm/configs/bast_defconfig index ffd905ff19f1..4a8564f386af 100644 --- a/trunk/arch/arm/configs/realview-smp_defconfig +++ b/trunk/arch/arm/configs/bast_defconfig @@ -1,168 +1,136 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.19-rc3 -# Wed Oct 25 14:12:00 2006 +# Linux kernel version: 2.6.12-rc1-bk2 +# Sun Mar 27 02:24:16 2005 # CONFIG_ARM=y -# CONFIG_GENERIC_TIME is not set CONFIG_MMU=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -CONFIG_HARDIRQS_SW_RESEND=y -CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_UID16=y CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_VECTORS_BASE=0xffff0000 -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_GENERIC_IOMAP=y # # Code maturity level options # CONFIG_EXPERIMENTAL=y -CONFIG_LOCK_KERNEL=y -CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y # # General setup # CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -# CONFIG_SWAP is not set +CONFIG_SWAP=y CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set +CONFIG_SYSCTL=y # CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y # CONFIG_IKCONFIG is not set -# CONFIG_CPUSETS is not set -# 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 is not set CONFIG_KALLSYMS=y -CONFIG_KALLSYMS_ALL=y +# CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SHMEM=y -CONFIG_SLAB=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_RT_MUTEXES=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set # # Loadable module support # CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODULE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set -# CONFIG_KMOD is not set -CONFIG_STOP_MACHINE=y - -# -# Block layer -# -CONFIG_BLOCK=y -# CONFIG_BLK_DEV_IO_TRACE is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_AS is not set -CONFIG_IOSCHED_DEADLINE=y -# CONFIG_IOSCHED_CFQ is not set -# CONFIG_DEFAULT_AS is not set -CONFIG_DEFAULT_DEADLINE=y -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="deadline" +CONFIG_KMOD=y # # System Type # -# CONFIG_ARCH_AAEC2000 is not set -# CONFIG_ARCH_INTEGRATOR is not set -CONFIG_ARCH_REALVIEW=y -# CONFIG_ARCH_VERSATILE is not set -# CONFIG_ARCH_AT91 is not set # CONFIG_ARCH_CLPS7500 is not set # CONFIG_ARCH_CLPS711X is not set # CONFIG_ARCH_CO285 is not set # CONFIG_ARCH_EBSA110 is not set -# CONFIG_ARCH_EP93XX is not set # CONFIG_ARCH_FOOTBRIDGE is not set -# CONFIG_ARCH_NETX is not set -# CONFIG_ARCH_H720X is not set -# CONFIG_ARCH_IMX is not set -# CONFIG_ARCH_IOP32X is not set -# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set # CONFIG_ARCH_IXP4XX is not set # CONFIG_ARCH_IXP2000 is not set -# CONFIG_ARCH_IXP23XX is not set # CONFIG_ARCH_L7200 is not set -# CONFIG_ARCH_PNX4008 is not set # CONFIG_ARCH_PXA is not set # CONFIG_ARCH_RPC is not set # CONFIG_ARCH_SA1100 is not set -# CONFIG_ARCH_S3C2410 is not set +CONFIG_ARCH_S3C2410=y # CONFIG_ARCH_SHARK is not set # CONFIG_ARCH_LH7A40X is not set # CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set + +# +# S3C24XX Implementations +# +CONFIG_ARCH_BAST=y +# CONFIG_ARCH_H1940 is not set +# CONFIG_MACH_N30 is not set +# CONFIG_ARCH_SMDK2410 is not set +# CONFIG_ARCH_S3C2440 is not set +CONFIG_MACH_VR1000=y +# CONFIG_MACH_RX3715 is not set +# CONFIG_MACH_OTOM is not set +# CONFIG_MACH_NEXCODER_2440 is not set +CONFIG_CPU_S3C2410=y + +# +# S3C2410 Boot +# +# CONFIG_S3C2410_BOOT_WATCHDOG is not set # -# RealView platform type +# S3C2410 Setup # -CONFIG_MACH_REALVIEW_EB=y -CONFIG_REALVIEW_MPCORE=y +CONFIG_S3C2410_DMA=y +# CONFIG_S3C2410_DMA_DEBUG is not set +# CONFIG_S3C2410_PM_DEBUG is not set +# CONFIG_S3C2410_PM_CHECK is not set +CONFIG_S3C2410_LOWLEVEL_UART_PORT=0 # # Processor Type # CONFIG_CPU_32=y -# CONFIG_CPU_ARM926T is not set -CONFIG_CPU_V6=y -CONFIG_CPU_32v6K=y -CONFIG_CPU_32v6=y -CONFIG_CPU_ABRT_EV6=y -CONFIG_CPU_CACHE_V6=y -CONFIG_CPU_CACHE_VIPT=y -CONFIG_CPU_COPY_V6=y -CONFIG_CPU_TLB_V6=y -CONFIG_CPU_CP15=y -CONFIG_CPU_CP15_MMU=y +CONFIG_CPU_ARM920T=y +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_EV4T=y +CONFIG_CPU_CACHE_V4WT=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y # # Processor Features # -CONFIG_ARM_THUMB=y +# CONFIG_ARM_THUMB is not set # CONFIG_CPU_ICACHE_DISABLE is not set # CONFIG_CPU_DCACHE_DISABLE is not set # CONFIG_CPU_DCACHE_WRITETHROUGH is not set -# CONFIG_CPU_BPREDICT_DISABLE is not set -CONFIG_HAS_TLS_REG=y -CONFIG_ARM_GIC=y -CONFIG_ICST307=y # # Bus support # -CONFIG_ARM_AMBA=y # # PCCARD (PCMCIA/CardBus) support @@ -172,24 +140,7 @@ CONFIG_ARM_AMBA=y # # Kernel Features # -CONFIG_SMP=y -CONFIG_NR_CPUS=4 -CONFIG_HOTPLUG_CPU=y -CONFIG_LOCAL_TIMERS=y # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set -CONFIG_HZ=100 -# CONFIG_AEABI is not set -# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set CONFIG_ALIGNMENT_TRAP=y # @@ -197,7 +148,7 @@ CONFIG_ALIGNMENT_TRAP=y # CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="root=/dev/nfs nfsroot=10.1.69.3:/work/nfsroot ip=dhcp console=ttyAMA0 mem=128M" +CONFIG_CMDLINE="root=/dev/hda1 ro init=/bin/bash console=ttySAC0" # CONFIG_XIP_KERNEL is not set # @@ -210,105 +161,20 @@ CONFIG_CMDLINE="root=/dev/nfs nfsroot=10.1.69.3:/work/nfsroot ip=dhcp console=tt CONFIG_FPE_NWFPE=y # CONFIG_FPE_NWFPE_XP is not set # CONFIG_FPE_FASTFPE is not set -CONFIG_VFP=y # # Userspace binary formats # CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_AOUT=y # CONFIG_BINFMT_MISC is not set # CONFIG_ARTHUR is not set # # Power management options # -# CONFIG_PM is not set -# CONFIG_APM is not set - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -# CONFIG_NETDEBUG is not set -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_UNIX=y -# CONFIG_NET_KEY is not set -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_IPV6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set -# CONFIG_NETWORK_SECMARK is not set -# CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_IEEE80211 is not set +CONFIG_PM=y +CONFIG_APM=y # # Device Drivers @@ -321,12 +187,6 @@ CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set # CONFIG_DEBUG_DRIVER is not set -# CONFIG_SYS_HYPERVISOR is not set - -# -# Connector - unified userspace <-> kernelspace linker -# -# CONFIG_CONNECTOR is not set # # Memory Technology Devices (MTD) @@ -335,7 +195,10 @@ CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set # CONFIG_MTD_CONCAT is not set CONFIG_MTD_PARTITIONS=y -# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set CONFIG_MTD_CMDLINE_PARTS=y # CONFIG_MTD_AFS_PARTS is not set @@ -347,42 +210,44 @@ CONFIG_MTD_BLOCK=y # CONFIG_FTL is not set # CONFIG_NFTL is not set # CONFIG_INFTL is not set -# CONFIG_RFD_FTL is not set -# CONFIG_SSFDC is not set # # RAM/ROM/Flash chip drivers # CONFIG_MTD_CFI=y -# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_JEDECPROBE=y CONFIG_MTD_GEN_PROBE=y # CONFIG_MTD_CFI_ADV_OPTIONS is not set CONFIG_MTD_MAP_BANK_WIDTH_1=y CONFIG_MTD_MAP_BANK_WIDTH_2=y CONFIG_MTD_MAP_BANK_WIDTH_4=y # CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +CONFIG_MTD_MAP_BANK_WIDTH_16=y # CONFIG_MTD_MAP_BANK_WIDTH_32 is not set CONFIG_MTD_CFI_I1=y CONFIG_MTD_CFI_I2=y # CONFIG_MTD_CFI_I4 is not set # CONFIG_MTD_CFI_I8 is not set CONFIG_MTD_CFI_INTELEXT=y -CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_AMDSTD is not set # CONFIG_MTD_CFI_STAA is not set CONFIG_MTD_CFI_UTIL=y # CONFIG_MTD_RAM is not set # CONFIG_MTD_ROM is not set # CONFIG_MTD_ABSENT is not set # CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_XIP is not set # # Mapping drivers for chip access # # CONFIG_MTD_COMPLEX_MAPPINGS is not set # CONFIG_MTD_PHYSMAP is not set -CONFIG_MTD_ARM_INTEGRATOR=y -# CONFIG_MTD_PLATRAM is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_EDB7312 is not set +# CONFIG_MTD_IMPA7 is not set +CONFIG_MTD_BAST=y +CONFIG_MTD_BAST_MAXSIZE=4 # # Self-contained MTD device drivers @@ -390,6 +255,7 @@ CONFIG_MTD_ARM_INTEGRATOR=y # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set # CONFIG_MTD_BLOCK2MTD is not set # @@ -402,17 +268,23 @@ CONFIG_MTD_ARM_INTEGRATOR=y # # NAND Flash Device Drivers # -# CONFIG_MTD_NAND is not set - -# -# OneNAND Flash Device Drivers -# -# CONFIG_MTD_ONENAND is not set +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +CONFIG_MTD_NAND_IDS=y +CONFIG_MTD_NAND_S3C2410=y +# CONFIG_MTD_NAND_S3C2410_DEBUG is not set +# CONFIG_MTD_NAND_S3C2410_HWECC is not set +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_NANDSIM is not set # # Parallel port support # -# CONFIG_PARPORT is not set +CONFIG_PARPORT=y +# CONFIG_PARPORT_PC is not set +# CONFIG_PARPORT_ARC is not set +# CONFIG_PARPORT_GSC is not set +CONFIG_PARPORT_1284=y # # Plug and Play support @@ -421,20 +293,59 @@ CONFIG_MTD_ARM_INTEGRATOR=y # # Block devices # +# CONFIG_BLK_DEV_FD is not set +# CONFIG_PARIDE is not set # CONFIG_BLK_DEV_COW_COMMON is not set -# CONFIG_BLK_DEV_LOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_RAM is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" # CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y # CONFIG_ATA_OVER_ETH is not set +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +CONFIG_BLK_DEV_IDECD=y +CONFIG_BLK_DEV_IDETAPE=m +CONFIG_BLK_DEV_IDEFLOPPY=m +# CONFIG_IDE_TASK_IOCTL is not set + +# +# IDE chipset support/bugfixes +# +CONFIG_IDE_GENERIC=y +# CONFIG_IDE_ARM is not set +CONFIG_BLK_DEV_IDE_BAST=y +# CONFIG_BLK_DEV_IDEDMA is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_BLK_DEV_HD is not set + # # SCSI device support # -# CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set -# CONFIG_SCSI_NETLINK is not set # # Multi-device support (RAID and LVM) @@ -444,7 +355,6 @@ CONFIG_BLK_DEV_INITRD=y # # Fusion MPT device support # -# CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support @@ -455,26 +365,81 @@ CONFIG_BLK_DEV_INITRD=y # # -# Network device support +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_PACKET is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_IP_TCPDIAG=y +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing # +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set CONFIG_NETDEVICES=y # CONFIG_DUMMY is not set # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set -# -# PHY device support -# -# CONFIG_PHYLIB is not set - # # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y -CONFIG_MII=y -CONFIG_SMC91X=y -# CONFIG_DM9000 is not set +# CONFIG_MII is not set +# CONFIG_SMC91X is not set # # Ethernet (1000 Mbit) @@ -497,12 +462,11 @@ CONFIG_SMC91X=y # Wan interfaces # # CONFIG_WAN is not set +# CONFIG_PLIP is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set # # ISDN subsystem @@ -513,7 +477,6 @@ CONFIG_SMC91X=y # Input device support # CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set # # Userland interfaces @@ -536,7 +499,6 @@ CONFIG_KEYBOARD_ATKBD=y # CONFIG_KEYBOARD_LKKBD is not set # CONFIG_KEYBOARD_XTKBD is not set # CONFIG_KEYBOARD_NEWTON is not set -# CONFIG_KEYBOARD_STOWAWAY is not set CONFIG_INPUT_MOUSE=y CONFIG_MOUSE_PS2=y # CONFIG_MOUSE_SERIAL is not set @@ -549,11 +511,12 @@ CONFIG_MOUSE_PS2=y # Hardware I/O ports # CONFIG_SERIO=y -# CONFIG_SERIO_SERPORT is not set -CONFIG_SERIO_AMBAKMI=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_PARKBD is not set CONFIG_SERIO_LIBPS2=y # CONFIG_SERIO_RAW is not set # CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y # # Character devices @@ -561,25 +524,49 @@ CONFIG_SERIO_LIBPS2=y CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y -# CONFIG_VT_HW_CONSOLE_BINDING is not set -# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_COMPUTONE is not set +# CONFIG_ROCKETPORT is not set +# CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_ISI is not set +# CONFIG_SYNCLINKMP is not set +# CONFIG_N_HDLC is not set +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +# CONFIG_SX is not set +# CONFIG_RIO is not set +# CONFIG_STALDRV is not set # # Serial drivers # -# CONFIG_SERIAL_8250 is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=8 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_MULTIPORT is not set +# CONFIG_SERIAL_8250_RSA is not set # # Non-8250 serial port support # -# CONFIG_SERIAL_AMBA_PL010 is not set -CONFIG_SERIAL_AMBA_PL011=y -CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +CONFIG_SERIAL_S3C2410=y +CONFIG_SERIAL_S3C2410_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=16 +CONFIG_LEGACY_PTY_COUNT=256 +CONFIG_PRINTER=y +# CONFIG_LP_CONSOLE is not set +CONFIG_PPDEV=y +# CONFIG_TIPAR is not set # # IPMI @@ -589,15 +576,24 @@ CONFIG_LEGACY_PTY_COUNT=16 # # Watchdog Cards # -# CONFIG_WATCHDOG is not set -# CONFIG_HW_RANDOM is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_S3C2410_WATCHDOG=y # CONFIG_NVRAM is not set +# CONFIG_RTC is not set +CONFIG_S3C2410_RTC=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set # # Ftape, the floppy tape device driver # +# CONFIG_DRM is not set # CONFIG_RAW_DRIVER is not set # @@ -608,43 +604,73 @@ CONFIG_LEGACY_PTY_COUNT=16 # # I2C support # -# CONFIG_I2C is not set - -# -# SPI support -# -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set - -# -# Dallas's 1-wire bus -# -# CONFIG_W1 is not set - -# -# Hardware Monitoring support -# -# CONFIG_HWMON is not set -# CONFIG_HWMON_VID is not set +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=m + +# +# I2C Algorithms +# +CONFIG_I2C_ALGOBIT=m +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ISA is not set +# CONFIG_I2C_PARPORT is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +CONFIG_I2C_S3C2410=y +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Hardware Sensors Chip support +# +CONFIG_I2C_SENSOR=m +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +CONFIG_SENSORS_LM75=m +# CONFIG_SENSORS_LM77 is not set +CONFIG_SENSORS_LM78=m +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +CONFIG_SENSORS_LM85=m +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set + +# +# Other I2C Chip support +# +CONFIG_SENSORS_EEPROM=m +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set # # Misc devices # -# CONFIG_SGI_IOC4 is not set -# CONFIG_TIFM_CORE is not set - -# -# LED devices -# -# CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# # # Multimedia devices @@ -659,17 +685,13 @@ CONFIG_LEGACY_PTY_COUNT=16 # # Graphics support # -# CONFIG_FIRMWARE_EDID is not set CONFIG_FB=y -CONFIG_FB_CFB_FILLRECT=y -CONFIG_FB_CFB_COPYAREA=y -CONFIG_FB_CFB_IMAGEBLIT=y -# CONFIG_FB_MACMODES is not set -# CONFIG_FB_BACKLIGHT is not set -# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_CFB_FILLRECT is not set +# CONFIG_FB_CFB_COPYAREA is not set +# CONFIG_FB_CFB_IMAGEBLIT is not set +# CONFIG_FB_SOFT_CURSOR is not set +CONFIG_FB_MODE_HELPERS=y # CONFIG_FB_TILEBLITTING is not set -CONFIG_FB_ARMCLCD=y -# CONFIG_FB_S1D13XXX is not set # CONFIG_FB_VIRTUAL is not set # @@ -677,75 +699,26 @@ CONFIG_FB_ARMCLCD=y # # CONFIG_VGA_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE=y -# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set -# CONFIG_FONTS is not set -CONFIG_FONT_8x8=y -CONFIG_FONT_8x16=y +# CONFIG_FRAMEBUFFER_CONSOLE is not set # # Logo configuration # -CONFIG_LOGO=y -# CONFIG_LOGO_LINUX_MONO is not set -# CONFIG_LOGO_LINUX_VGA16 is not set -CONFIG_LOGO_LINUX_CLUT224=y +# CONFIG_LOGO is not set # CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound # -CONFIG_SOUND=y - -# -# Advanced Linux Sound Architecture -# -CONFIG_SND=y -CONFIG_SND_TIMER=y -CONFIG_SND_PCM=y -# CONFIG_SND_SEQUENCER is not set -CONFIG_SND_OSSEMUL=y -CONFIG_SND_MIXER_OSS=y -CONFIG_SND_PCM_OSS=y -CONFIG_SND_PCM_OSS_PLUGINS=y -# CONFIG_SND_DYNAMIC_MINORS is not set -CONFIG_SND_SUPPORT_OLD_API=y -CONFIG_SND_VERBOSE_PROCFS=y -# CONFIG_SND_VERBOSE_PRINTK is not set -# CONFIG_SND_DEBUG is not set - -# -# Generic devices -# -CONFIG_SND_AC97_CODEC=m -CONFIG_SND_AC97_BUS=m -# CONFIG_SND_DUMMY is not set -# CONFIG_SND_MTPAV is not set -# CONFIG_SND_SERIAL_U16550 is not set -# CONFIG_SND_MPU401 is not set - -# -# ALSA ARM devices -# -CONFIG_SND_ARMAACI=m - -# -# Open Sound System -# -# CONFIG_SOUND_PRIME is not set +# CONFIG_SOUND is not set # # USB support # CONFIG_USB_ARCH_HAS_HCD=y # CONFIG_USB_ARCH_HAS_OHCI is not set -# CONFIG_USB_ARCH_HAS_EHCI is not set # CONFIG_USB is not set -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - # # USB Gadget Support # @@ -754,62 +727,33 @@ CONFIG_USB_ARCH_HAS_HCD=y # # MMC/SD Card support # -CONFIG_MMC=y -# CONFIG_MMC_DEBUG is not set -CONFIG_MMC_BLOCK=y -CONFIG_MMC_ARMMMCI=y -# CONFIG_MMC_TIFM_SD is not set - -# -# Real Time Clock -# -CONFIG_RTC_LIB=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_HCTOSYS=y -CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -# CONFIG_RTC_DEBUG is not set - -# -# RTC interfaces -# -CONFIG_RTC_INTF_SYSFS=y -CONFIG_RTC_INTF_PROC=y -CONFIG_RTC_INTF_DEV=y -CONFIG_RTC_INTF_DEV_UIE_EMUL=y - -# -# RTC drivers -# -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_DS1742 is not set -# CONFIG_RTC_DRV_M48T86 is not set -CONFIG_RTC_DRV_PL031=y -# CONFIG_RTC_DRV_TEST is not set -# CONFIG_RTC_DRV_V3020 is not set +# CONFIG_MMC is not set # # File systems # CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP is not set -# CONFIG_EXT3_FS is not set -# CONFIG_EXT4DEV_FS is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set + +# +# XFS support +# # CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set -# CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -CONFIG_INOTIFY=y -# CONFIG_INOTIFY_USER is not set +CONFIG_ROMFS_FS=y # CONFIG_QUOTA is not set CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set # # CD-ROM/DVD Filesystems @@ -821,7 +765,7 @@ CONFIG_DNOTIFY=y # DOS/FAT/NT Filesystems # CONFIG_FAT_FS=y -# CONFIG_MSDOS_FS is not set +CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y CONFIG_FAT_DEFAULT_CODEPAGE=437 CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" @@ -831,13 +775,12 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" # Pseudo filesystems # CONFIG_PROC_FS=y -CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +# CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y -# CONFIG_CONFIGFS_FS is not set # # Miscellaneous filesystems @@ -849,9 +792,18 @@ CONFIG_RAMFS=y # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set -# CONFIG_JFFS2_FS is not set -CONFIG_CRAMFS=y +CONFIG_JFFS_FS=y +CONFIG_JFFS_FS_VERBOSE=0 +# CONFIG_JFFS_PROC_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_NAND is not set +# CONFIG_JFFS2_FS_NOR_ECC is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_CRAMFS is not set # CONFIG_VXFS_FS is not set # CONFIG_HPFS_FS is not set # CONFIG_QNX4FS_FS is not set @@ -862,15 +814,12 @@ CONFIG_CRAMFS=y # Network File Systems # CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V3 is not set # CONFIG_NFS_V4 is not set # CONFIG_NFS_DIRECTIO is not set # CONFIG_NFSD is not set CONFIG_ROOT_NFS=y CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set @@ -879,20 +828,33 @@ CONFIG_SUNRPC=y # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set # # Partition Types # -# CONFIG_PARTITION_ADVANCED is not set +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set CONFIG_MSDOS_PARTITION=y +CONFIG_BSD_DISKLABEL=y +# CONFIG_MINIX_SUBPARTITION is not set +CONFIG_SOLARIS_X86_PARTITION=y +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set # # Native Language Support # CONFIG_NLS=y CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_437 is not set # CONFIG_NLS_CODEPAGE_737 is not set # CONFIG_NLS_CODEPAGE_775 is not set # CONFIG_NLS_CODEPAGE_850 is not set @@ -916,7 +878,7 @@ CONFIG_NLS_CODEPAGE_437=y # CONFIG_NLS_CODEPAGE_1250 is not set # CONFIG_NLS_CODEPAGE_1251 is not set # CONFIG_NLS_ASCII is not set -CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_1 is not set # CONFIG_NLS_ISO8859_2 is not set # CONFIG_NLS_ISO8859_3 is not set # CONFIG_NLS_ISO8859_4 is not set @@ -940,37 +902,25 @@ CONFIG_NLS_ISO8859_1=y # Kernel hacking # # CONFIG_PRINTK_TIME is not set -# CONFIG_ENABLE_MUST_CHECK is not set -CONFIG_MAGIC_SYSRQ=y -# CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_KERNEL=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_MAGIC_SYSRQ is not set +CONFIG_LOG_BUF_SHIFT=16 # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_RT_MUTEX_TESTER is not set -CONFIG_DEBUG_SPINLOCK=y -CONFIG_DEBUG_MUTEXES=y -CONFIG_DEBUG_RWSEMS=y +# CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set -# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set CONFIG_DEBUG_BUGVERBOSE=y -# CONFIG_DEBUG_INFO is not set +CONFIG_DEBUG_INFO=y # CONFIG_DEBUG_FS is not set -# CONFIG_DEBUG_VM is not set -# CONFIG_DEBUG_LIST is not set CONFIG_FRAME_POINTER=y -# CONFIG_UNWIND_INFO is not set -CONFIG_FORCED_INLINING=y -# CONFIG_HEADERS_CHECK is not set -# CONFIG_RCU_TORTURE_TEST is not set CONFIG_DEBUG_USER=y # CONFIG_DEBUG_WAITQ is not set -CONFIG_DEBUG_ERRORS=y +# CONFIG_DEBUG_ERRORS is not set CONFIG_DEBUG_LL=y # CONFIG_DEBUG_ICEDCC is not set +CONFIG_DEBUG_S3C2410_PORT=y +CONFIG_DEBUG_S3C2410_UART=0 # # Security options @@ -983,12 +933,15 @@ CONFIG_DEBUG_LL=y # # CONFIG_CRYPTO is not set +# +# Hardware crypto devices +# + # # Library routines # # CONFIG_CRC_CCITT is not set -# CONFIG_CRC16 is not set CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y -CONFIG_PLIST=y +CONFIG_ZLIB_DEFLATE=y diff --git a/trunk/arch/arm/configs/cerfcube_defconfig b/trunk/arch/arm/configs/cerfcube_defconfig index 09b7acd7f647..f81a60005cd3 100644 --- a/trunk/arch/arm/configs/cerfcube_defconfig +++ b/trunk/arch/arm/configs/cerfcube_defconfig @@ -194,7 +194,6 @@ CONFIG_BINFMT_ELF=y # Power management options # CONFIG_PM=y -# CONFIG_PM_LEGACY is not set # CONFIG_APM is not set # diff --git a/trunk/arch/arm/configs/collie_defconfig b/trunk/arch/arm/configs/collie_defconfig index a3758913c0bb..074c47a4fb2e 100644 --- a/trunk/arch/arm/configs/collie_defconfig +++ b/trunk/arch/arm/configs/collie_defconfig @@ -219,7 +219,7 @@ CONFIG_BINFMT_ELF=y # Power management options # CONFIG_PM=y -# CONFIG_PM_LEGACY is not set +CONFIG_PM_LEGACY=y # CONFIG_PM_DEBUG is not set CONFIG_APM=y diff --git a/trunk/arch/arm/configs/corgi_defconfig b/trunk/arch/arm/configs/corgi_defconfig index c41c04fa5020..3c3461e83398 100644 --- a/trunk/arch/arm/configs/corgi_defconfig +++ b/trunk/arch/arm/configs/corgi_defconfig @@ -208,7 +208,6 @@ CONFIG_BINFMT_MISC=m # Power management options # CONFIG_PM=y -# CONFIG_PM_LEGACY is not set CONFIG_APM=y # diff --git a/trunk/arch/arm/configs/h3600_defconfig b/trunk/arch/arm/configs/h3600_defconfig index 8f986e9f1c62..7a0da0b7facb 100644 --- a/trunk/arch/arm/configs/h3600_defconfig +++ b/trunk/arch/arm/configs/h3600_defconfig @@ -194,7 +194,6 @@ CONFIG_BINFMT_ELF=y # Power management options # CONFIG_PM=y -# CONFIG_PM_LEGACY is not set # CONFIG_APM is not set # diff --git a/trunk/arch/arm/configs/integrator_defconfig b/trunk/arch/arm/configs/integrator_defconfig index 692ab57ba1ca..d1ba7fdde818 100644 --- a/trunk/arch/arm/configs/integrator_defconfig +++ b/trunk/arch/arm/configs/integrator_defconfig @@ -190,7 +190,6 @@ CONFIG_BINFMT_ELF=y # Power management options # CONFIG_PM=y -# CONFIG_PM_LEGACY is not set # CONFIG_APM is not set # diff --git a/trunk/arch/arm/configs/ixp4xx_defconfig b/trunk/arch/arm/configs/ixp4xx_defconfig index fac7c3b240c0..4975b914f923 100644 --- a/trunk/arch/arm/configs/ixp4xx_defconfig +++ b/trunk/arch/arm/configs/ixp4xx_defconfig @@ -206,8 +206,10 @@ CONFIG_BINFMT_ELF=y # # Power management options # -# CONFIG_PM is not set -# CONFIG_APM is not set +CONFIG_PM=y +CONFIG_PM_LEGACY=y +# CONFIG_PM_DEBUG is not set +CONFIG_APM=y # # Networking diff --git a/trunk/arch/arm/configs/jornada720_defconfig b/trunk/arch/arm/configs/jornada720_defconfig index 80a6fd97eb32..ad1048db96fb 100644 --- a/trunk/arch/arm/configs/jornada720_defconfig +++ b/trunk/arch/arm/configs/jornada720_defconfig @@ -182,7 +182,6 @@ CONFIG_BINFMT_AOUT=m # Power management options # CONFIG_PM=y -# CONFIG_PM_LEGACY is not set # CONFIG_APM is not set # diff --git a/trunk/arch/arm/configs/lart_defconfig b/trunk/arch/arm/configs/lart_defconfig index a1cc34f25602..c3a932844160 100644 --- a/trunk/arch/arm/configs/lart_defconfig +++ b/trunk/arch/arm/configs/lart_defconfig @@ -180,7 +180,6 @@ CONFIG_BINFMT_AOUT=y # Power management options # CONFIG_PM=y -# CONFIG_PM_LEGACY is not set CONFIG_APM=m # diff --git a/trunk/arch/arm/configs/neponset_defconfig b/trunk/arch/arm/configs/neponset_defconfig index df8168e57b7c..3d35255c64ed 100644 --- a/trunk/arch/arm/configs/neponset_defconfig +++ b/trunk/arch/arm/configs/neponset_defconfig @@ -190,7 +190,6 @@ CONFIG_BINFMT_AOUT=y # Power management options # CONFIG_PM=y -# CONFIG_PM_LEGACY is not set CONFIG_APM=y # diff --git a/trunk/arch/arm/configs/omap_h2_1610_defconfig b/trunk/arch/arm/configs/omap_h2_1610_defconfig index b0efd4ca9935..05adb0b34e72 100644 --- a/trunk/arch/arm/configs/omap_h2_1610_defconfig +++ b/trunk/arch/arm/configs/omap_h2_1610_defconfig @@ -257,7 +257,7 @@ CONFIG_BINFMT_AOUT=y # Power management options # CONFIG_PM=y -# CONFIG_PM_LEGACY is not set +CONFIG_PM_LEGACY=y # CONFIG_PM_DEBUG is not set # CONFIG_APM is not set diff --git a/trunk/arch/arm/configs/s3c2410_defconfig b/trunk/arch/arm/configs/s3c2410_defconfig index c0152393e494..a83222641045 100644 --- a/trunk/arch/arm/configs/s3c2410_defconfig +++ b/trunk/arch/arm/configs/s3c2410_defconfig @@ -1,10 +1,9 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.19-rc4 -# Fri Nov 3 17:41:31 2006 +# Linux kernel version: 2.6.18 +# Wed Sep 20 20:27:31 2006 # CONFIG_ARM=y -# CONFIG_GENERIC_TIME is not set CONFIG_MMU=y CONFIG_GENERIC_HARDIRQS=y CONFIG_TRACE_IRQFLAGS_SUPPORT=y @@ -30,20 +29,17 @@ CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set # 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 is not set +CONFIG_SYSCTL=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set @@ -66,8 +62,7 @@ CONFIG_BASE_SMALL=0 # Loadable module support # CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODULE_UNLOAD is not set # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_KMOD=y @@ -75,7 +70,6 @@ CONFIG_KMOD=y # # Block layer # -CONFIG_BLOCK=y # CONFIG_BLK_DEV_IO_TRACE is not set # @@ -126,7 +120,6 @@ CONFIG_ARCH_S3C2410=y # # S3C24XX Implementations # -# CONFIG_MACH_AML_M5900 is not set CONFIG_MACH_ANUBIS=y CONFIG_MACH_OSIRIS=y CONFIG_ARCH_BAST=y @@ -185,8 +178,6 @@ CONFIG_CPU_CACHE_V4WT=y CONFIG_CPU_CACHE_VIVT=y CONFIG_CPU_COPY_V4WB=y CONFIG_CPU_TLB_V4WBI=y -CONFIG_CPU_CP15=y -CONFIG_CPU_CP15_MMU=y # # Processor Features @@ -258,9 +249,8 @@ CONFIG_BINFMT_AOUT=y # Power management options # CONFIG_PM=y -# CONFIG_PM_LEGACY is not set +CONFIG_PM_LEGACY=y # CONFIG_PM_DEBUG is not set -# CONFIG_PM_SYSFS_DEPRECATED is not set CONFIG_APM=y # @@ -276,7 +266,6 @@ CONFIG_NET=y CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set # CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set @@ -297,12 +286,10 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_INET_TUNNEL is not set CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=y CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" +CONFIG_TCP_CONG_BIC=y # CONFIG_IPV6 is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set @@ -390,7 +377,6 @@ CONFIG_MTD_BLOCK=y # CONFIG_NFTL is not set # CONFIG_INFTL is not set # CONFIG_RFD_FTL is not set -# CONFIG_SSFDC is not set # # RAM/ROM/Flash chip drivers @@ -432,8 +418,6 @@ CONFIG_MTD_BAST_MAXSIZE=4 # # Self-contained MTD device drivers # -# CONFIG_MTD_DATAFLASH is not set -# CONFIG_MTD_M25P80 is not set # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set @@ -528,7 +512,6 @@ CONFIG_BLK_DEV_IDE_BAST=y # # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set -# CONFIG_SCSI_NETLINK is not set # # Multi-device support (RAID and LVM) @@ -623,7 +606,6 @@ CONFIG_DM9000=y # Input device support # CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set # # Userland interfaces @@ -646,7 +628,6 @@ CONFIG_KEYBOARD_ATKBD=y # CONFIG_KEYBOARD_LKKBD is not set # CONFIG_KEYBOARD_XTKBD is not set # CONFIG_KEYBOARD_NEWTON is not set -# CONFIG_KEYBOARD_STOWAWAY is not set CONFIG_INPUT_MOUSE=y CONFIG_MOUSE_PS2=y # CONFIG_MOUSE_SERIAL is not set @@ -753,6 +734,7 @@ CONFIG_S3C2410_WATCHDOG=y # CONFIG_USBPCWATCHDOG is not set CONFIG_HW_RANDOM=y # CONFIG_NVRAM is not set +CONFIG_S3C2410_RTC=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set @@ -765,6 +747,7 @@ CONFIG_HW_RANDOM=y # TPM devices # # CONFIG_TCG_TPM is not set +# CONFIG_TELCLOCK is not set # # I2C support @@ -809,26 +792,12 @@ CONFIG_SENSORS_EEPROM=m # # SPI support # -CONFIG_SPI=y -# CONFIG_SPI_DEBUG is not set -CONFIG_SPI_MASTER=y - -# -# SPI Master Controller Drivers -# -CONFIG_SPI_BITBANG=m -# CONFIG_SPI_BUTTERFLY is not set -CONFIG_SPI_S3C24XX_GPIO=m -CONFIG_SPI_S3C24XX=m - -# -# SPI Protocol Masters -# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set # # Dallas's 1-wire bus # -# CONFIG_W1 is not set # # Hardware Monitoring support @@ -851,7 +820,6 @@ CONFIG_HWMON_VID=m # CONFIG_SENSORS_GL520SM is not set # CONFIG_SENSORS_IT87 is not set # CONFIG_SENSORS_LM63 is not set -# CONFIG_SENSORS_LM70 is not set CONFIG_SENSORS_LM75=m # CONFIG_SENSORS_LM77 is not set CONFIG_SENSORS_LM78=m @@ -866,7 +834,6 @@ CONFIG_SENSORS_LM85=m # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_SMSC47M192 is not set # CONFIG_SENSORS_SMSC47B397 is not set -# CONFIG_SENSORS_VT1211 is not set # CONFIG_SENSORS_W83781D is not set # CONFIG_SENSORS_W83791D is not set # CONFIG_SENSORS_W83792D is not set @@ -878,31 +845,25 @@ CONFIG_SENSORS_LM85=m # # Misc devices # -# CONFIG_TIFM_CORE is not set # # LED devices # -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=m +# CONFIG_NEW_LEDS is not set # # LED drivers # -CONFIG_LEDS_S3C24XX=m # # LED Triggers # -CONFIG_LEDS_TRIGGERS=y -CONFIG_LEDS_TRIGGER_TIMER=m -# CONFIG_LEDS_TRIGGER_IDE_DISK is not set -CONFIG_LEDS_TRIGGER_HEARTBEAT=m # # Multimedia devices # # CONFIG_VIDEO_DEV is not set +CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices @@ -915,7 +876,6 @@ CONFIG_LEDS_TRIGGER_HEARTBEAT=m # CONFIG_FIRMWARE_EDID=y CONFIG_FB=y -# CONFIG_FB_DDC is not set CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y @@ -991,6 +951,7 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y # # may also be needed; see USB_STORAGE Help for more information # +# CONFIG_USB_STORAGE is not set # CONFIG_USB_LIBUSUAL is not set # @@ -1046,7 +1007,6 @@ CONFIG_USB_MON=y # # CONFIG_USB_EMI62 is not set # CONFIG_USB_EMI26 is not set -# CONFIG_USB_ADUTUX is not set # CONFIG_USB_AUERSWALD is not set # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set @@ -1054,12 +1014,11 @@ CONFIG_USB_MON=y # CONFIG_USB_LED is not set # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set -# CONFIG_USB_PHIDGET is not set +# CONFIG_USB_PHIDGETKIT is not set +# CONFIG_USB_PHIDGETSERVO is not set # CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_FTDI_ELAN is not set # CONFIG_USB_APPLEDISPLAY is not set # CONFIG_USB_LD is not set -# CONFIG_USB_TRANCEVIBRATOR is not set # CONFIG_USB_TEST is not set # @@ -1080,37 +1039,7 @@ CONFIG_USB_MON=y # Real Time Clock # CONFIG_RTC_LIB=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_HCTOSYS=y -CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -# CONFIG_RTC_DEBUG is not set - -# -# RTC interfaces -# -CONFIG_RTC_INTF_SYSFS=y -CONFIG_RTC_INTF_PROC=y -CONFIG_RTC_INTF_DEV=y -# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set - -# -# RTC drivers -# -# CONFIG_RTC_DRV_X1205 is not set -# CONFIG_RTC_DRV_DS1307 is not set -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_ISL1208 is not set -# CONFIG_RTC_DRV_DS1672 is not set -# CONFIG_RTC_DRV_DS1742 is not set -# CONFIG_RTC_DRV_PCF8563 is not set -# CONFIG_RTC_DRV_PCF8583 is not set -# CONFIG_RTC_DRV_RS5C348 is not set -# CONFIG_RTC_DRV_RS5C372 is not set -CONFIG_RTC_DRV_S3C=y -# CONFIG_RTC_DRV_M48T86 is not set -# CONFIG_RTC_DRV_TEST is not set -# CONFIG_RTC_DRV_MAX6902 is not set -# CONFIG_RTC_DRV_V3020 is not set +# CONFIG_RTC_CLASS is not set # # File systems @@ -1122,7 +1051,6 @@ CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y # CONFIG_EXT3_FS_POSIX_ACL is not set # CONFIG_EXT3_FS_SECURITY is not set -# CONFIG_EXT4DEV_FS is not set CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set CONFIG_FS_MBCACHE=y @@ -1130,7 +1058,6 @@ CONFIG_FS_MBCACHE=y # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set # CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set CONFIG_ROMFS_FS=y @@ -1162,7 +1089,6 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" # Pseudo filesystems # CONFIG_PROC_FS=y -CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y # CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set @@ -1293,7 +1219,6 @@ CONFIG_NLS_DEFAULT="iso8859-1" # Kernel hacking # # CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_MUST_CHECK=y CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_KERNEL=y @@ -1313,10 +1238,9 @@ CONFIG_DEBUG_BUGVERBOSE=y CONFIG_DEBUG_INFO=y # CONFIG_DEBUG_FS is not set # CONFIG_DEBUG_VM is not set -# CONFIG_DEBUG_LIST is not set CONFIG_FRAME_POINTER=y +# CONFIG_UNWIND_INFO is not set CONFIG_FORCED_INLINING=y -# CONFIG_HEADERS_CHECK is not set # CONFIG_RCU_TORTURE_TEST is not set CONFIG_DEBUG_USER=y # CONFIG_DEBUG_WAITQ is not set @@ -1337,6 +1261,10 @@ CONFIG_DEBUG_S3C2410_UART=0 # # CONFIG_CRYPTO is not set +# +# Hardware crypto devices +# + # # Library routines # diff --git a/trunk/arch/arm/configs/simpad_defconfig b/trunk/arch/arm/configs/simpad_defconfig index 140056a3507f..2e5a616cc98d 100644 --- a/trunk/arch/arm/configs/simpad_defconfig +++ b/trunk/arch/arm/configs/simpad_defconfig @@ -180,7 +180,6 @@ CONFIG_BINFMT_MISC=m # Power management options # CONFIG_PM=y -# CONFIG_PM_LEGACY is not set CONFIG_APM=y # diff --git a/trunk/arch/arm/configs/smdk2410_defconfig b/trunk/arch/arm/configs/smdk2410_defconfig new file mode 100644 index 000000000000..4d123d33c7df --- /dev/null +++ b/trunk/arch/arm/configs/smdk2410_defconfig @@ -0,0 +1,735 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc1-bk2 +# Sun Mar 27 22:42:40 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +CONFIG_ARCH_S3C2410=y +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set + +# +# S3C24XX Implementations +# +# CONFIG_ARCH_BAST is not set +# CONFIG_ARCH_H1940 is not set +# CONFIG_MACH_N30 is not set +CONFIG_ARCH_SMDK2410=y +# CONFIG_ARCH_S3C2440 is not set +# CONFIG_MACH_VR1000 is not set +# CONFIG_MACH_RX3715 is not set +# CONFIG_MACH_OTOM is not set +# CONFIG_MACH_NEXCODER_2440 is not set +CONFIG_CPU_S3C2410=y + +# +# S3C2410 Boot +# + +# +# S3C2410 Setup +# +# CONFIG_S3C2410_DMA is not set +CONFIG_S3C2410_LOWLEVEL_UART_PORT=0 + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM920T=y +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_EV4T=y +CONFIG_CPU_CACHE_V4WT=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set + +# +# Bus support +# + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="root=1f04 mem=32M" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +# CONFIG_FPE_NWFPE is not set +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_AOUT=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +# CONFIG_MTD_PARTITIONS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_EDB7312 is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_INITRD is not set +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_PACKET is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_IP_TCPDIAG is not set +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +# CONFIG_SMC91X is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_S3C2410=y +CONFIG_SERIAL_S3C2410_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_S3C2410_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +CONFIG_FB=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_SOFT_CURSOR=y +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set +CONFIG_FB_VIRTUAL=y + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y + +# +# Logo configuration +# +# CONFIG_LOGO is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +CONFIG_ROMFS_FS=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +# CONFIG_TMPFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +# CONFIG_MSDOS_PARTITION is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_MAGIC_SYSRQ is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_FS is not set +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_WAITQ is not set +# CONFIG_DEBUG_ERRORS is not set +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_ICEDCC is not set +CONFIG_DEBUG_S3C2410_PORT=y +CONFIG_DEBUG_S3C2410_UART=0 + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC32=y +CONFIG_LIBCRC32C=y diff --git a/trunk/arch/arm/configs/spitz_defconfig b/trunk/arch/arm/configs/spitz_defconfig index bd03238968c1..d1ace3abfd8a 100644 --- a/trunk/arch/arm/configs/spitz_defconfig +++ b/trunk/arch/arm/configs/spitz_defconfig @@ -207,7 +207,6 @@ CONFIG_BINFMT_MISC=m # Power management options # CONFIG_PM=y -# CONFIG_PM_LEGACY is not set CONFIG_APM=y # diff --git a/trunk/arch/arm/configs/versatile_defconfig b/trunk/arch/arm/configs/versatile_defconfig index f7bf6ef27d19..96b7a7762426 100644 --- a/trunk/arch/arm/configs/versatile_defconfig +++ b/trunk/arch/arm/configs/versatile_defconfig @@ -200,7 +200,7 @@ CONFIG_BINFMT_ELF=y # Power management options # CONFIG_PM=y -# CONFIG_PM_LEGACY is not set +CONFIG_PM_LEGACY=y # CONFIG_PM_DEBUG is not set # CONFIG_APM is not set diff --git a/trunk/arch/arm/kernel/armksyms.c b/trunk/arch/arm/kernel/armksyms.c index 4779f474f911..da69e660574b 100644 --- a/trunk/arch/arm/kernel/armksyms.c +++ b/trunk/arch/arm/kernel/armksyms.c @@ -178,3 +178,9 @@ EXPORT_SYMBOL(_find_next_zero_bit_be); EXPORT_SYMBOL(_find_first_bit_be); EXPORT_SYMBOL(_find_next_bit_be); #endif + + /* syscalls */ +EXPORT_SYMBOL(sys_write); +EXPORT_SYMBOL(sys_lseek); +EXPORT_SYMBOL(sys_exit); +EXPORT_SYMBOL(sys_wait4); diff --git a/trunk/arch/arm/kernel/ecard.c b/trunk/arch/arm/kernel/ecard.c index b27513a0f11e..3e14b1348c0b 100644 --- a/trunk/arch/arm/kernel/ecard.c +++ b/trunk/arch/arm/kernel/ecard.c @@ -567,7 +567,7 @@ static void ecard_check_lockup(struct irqdesc *desc) } static void -ecard_irq_handler(unsigned int irq, struct irqdesc *desc) +ecard_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) { ecard_t *ec; int called = 0; @@ -586,7 +586,7 @@ ecard_irq_handler(unsigned int irq, struct irqdesc *desc) if (pending) { struct irqdesc *d = irq_desc + ec->irq; - desc_handle_irq(ec->irq, d); + desc_handle_irq(ec->irq, d, regs); called ++; } } @@ -609,7 +609,7 @@ static unsigned char first_set[] = }; static void -ecard_irqexp_handler(unsigned int irq, struct irqdesc *desc) +ecard_irqexp_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) { const unsigned int statusmask = 15; unsigned int status; @@ -633,7 +633,7 @@ ecard_irqexp_handler(unsigned int irq, struct irqdesc *desc) * Serial cards should go in 0/1, ethernet/scsi in 2/3 * otherwise you will lose serial data at high speeds! */ - desc_handle_irq(ec->irq, d); + desc_handle_irq(ec->irq, d, regs); } else { printk(KERN_WARNING "card%d: interrupt from unclaimed " "card???\n", slot); diff --git a/trunk/arch/arm/kernel/irq.c b/trunk/arch/arm/kernel/irq.c index 2c4ff1cbe334..2e1bf830fe11 100644 --- a/trunk/arch/arm/kernel/irq.c +++ b/trunk/arch/arm/kernel/irq.c @@ -111,7 +111,6 @@ static struct irq_desc bad_irq_desc = { */ asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs) { - struct pt_regs *old_regs = set_irq_regs(regs); struct irqdesc *desc = irq_desc + irq; /* @@ -123,13 +122,12 @@ asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs) irq_enter(); - desc_handle_irq(irq, desc); + desc_handle_irq(irq, desc, regs); /* AT91 specific workaround */ irq_finish(irq); irq_exit(); - set_irq_regs(old_regs); } void set_irq_flags(unsigned int irq, unsigned int iflags) diff --git a/trunk/arch/arm/kernel/setup.c b/trunk/arch/arm/kernel/setup.c index 29efc9f82057..6bbd93dd186a 100644 --- a/trunk/arch/arm/kernel/setup.c +++ b/trunk/arch/arm/kernel/setup.c @@ -357,9 +357,6 @@ static void __init setup_processor(void) #ifndef CONFIG_VFP elf_hwcap &= ~HWCAP_VFP; #endif -#ifndef CONFIG_IWMMXT - elf_hwcap &= ~HWCAP_IWMMXT; -#endif cpu_proc_init(); } @@ -857,7 +854,6 @@ static const char *hwcap_str[] = { "vfp", "edsp", "java", - "iwmmxt", NULL }; diff --git a/trunk/arch/arm/kernel/smp.c b/trunk/arch/arm/kernel/smp.c index 070bcb7a6306..421329f5e18e 100644 --- a/trunk/arch/arm/kernel/smp.c +++ b/trunk/arch/arm/kernel/smp.c @@ -7,7 +7,6 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ -#include #include #include #include @@ -20,7 +19,6 @@ #include #include #include -#include #include #include @@ -451,7 +449,6 @@ int smp_call_function(void (*func)(void *info), void *info, int retry, return smp_call_function_on_cpu(func, info, retry, wait, cpu_online_map); } -EXPORT_SYMBOL_GPL(smp_call_function); void show_ipi_list(struct seq_file *p) { @@ -477,26 +474,25 @@ void show_local_irqs(struct seq_file *p) seq_putc(p, '\n'); } -static void ipi_timer(void) +static void ipi_timer(struct pt_regs *regs) { + int user = user_mode(regs); + irq_enter(); - profile_tick(CPU_PROFILING); - update_process_times(user_mode(get_irq_regs())); + profile_tick(CPU_PROFILING, regs); + update_process_times(user); irq_exit(); } #ifdef CONFIG_LOCAL_TIMERS asmlinkage void do_local_timer(struct pt_regs *regs) { - struct pt_regs *old_regs = set_irq_regs(regs); int cpu = smp_processor_id(); if (local_timer_ack()) { irq_stat[cpu].local_timer_irqs++; - ipi_timer(); + ipi_timer(regs); } - - set_irq_regs(old_regs); } #endif @@ -555,7 +551,6 @@ asmlinkage void do_IPI(struct pt_regs *regs) { unsigned int cpu = smp_processor_id(); struct ipi_data *ipi = &per_cpu(ipi_data, cpu); - struct pt_regs *old_regs = set_irq_regs(regs); ipi->ipi_count++; @@ -579,7 +574,7 @@ asmlinkage void do_IPI(struct pt_regs *regs) switch (nextmsg) { case IPI_TIMER: - ipi_timer(); + ipi_timer(regs); break; case IPI_RESCHEDULE: @@ -604,8 +599,6 @@ asmlinkage void do_IPI(struct pt_regs *regs) } } while (msgs); } - - set_irq_regs(old_regs); } void smp_send_reschedule(int cpu) diff --git a/trunk/arch/arm/kernel/time.c b/trunk/arch/arm/kernel/time.c index 6ff5e3ff6cb5..b030320b17c7 100644 --- a/trunk/arch/arm/kernel/time.c +++ b/trunk/arch/arm/kernel/time.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include @@ -220,10 +219,10 @@ EXPORT_SYMBOL(leds_event); #ifdef CONFIG_LEDS_TIMER static inline void do_leds(void) { - static unsigned int count = HZ/2; + static unsigned int count = 50; if (--count == 0) { - count = HZ/2; + count = 50; leds_event(led_timer); } } @@ -325,14 +324,14 @@ EXPORT_SYMBOL(restore_time_delta); /* * Kernel system timer support. */ -void timer_tick(void) +void timer_tick(struct pt_regs *regs) { - profile_tick(CPU_PROFILING); + profile_tick(CPU_PROFILING, regs); do_leds(); do_set_rtc(); do_timer(1); #ifndef CONFIG_SMP - update_process_times(user_mode(get_irq_regs())); + update_process_times(user_mode(regs)); #endif } diff --git a/trunk/arch/arm/kernel/vmlinux.lds.S b/trunk/arch/arm/kernel/vmlinux.lds.S index a8fa75ea07a9..3ca574ee2772 100644 --- a/trunk/arch/arm/kernel/vmlinux.lds.S +++ b/trunk/arch/arm/kernel/vmlinux.lds.S @@ -45,7 +45,13 @@ SECTIONS *(.early_param.init) __early_end = .; __initcall_start = .; - INITCALLS + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) __initcall_end = .; __con_initcall_start = .; *(.con_initcall.init) diff --git a/trunk/arch/arm/mach-aaec2000/core.c b/trunk/arch/arm/mach-aaec2000/core.c index fe3d297d682d..baa997c857dc 100644 --- a/trunk/arch/arm/mach-aaec2000/core.c +++ b/trunk/arch/arm/mach-aaec2000/core.c @@ -127,12 +127,12 @@ static unsigned long aaec2000_gettimeoffset(void) /* We enter here with IRQs enabled */ static irqreturn_t -aaec2000_timer_interrupt(int irq, void *dev_id) +aaec2000_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { /* TODO: Check timer accuracy */ write_seqlock(&xtime_lock); - timer_tick(); + timer_tick(regs); TIMER1_CLEAR = 1; write_sequnlock(&xtime_lock); diff --git a/trunk/arch/arm/mach-at91rm9200/at91rm9200_time.c b/trunk/arch/arm/mach-at91rm9200/at91rm9200_time.c index 07c9cea8961d..a92a8622c78a 100644 --- a/trunk/arch/arm/mach-at91rm9200/at91rm9200_time.c +++ b/trunk/arch/arm/mach-at91rm9200/at91rm9200_time.c @@ -65,13 +65,13 @@ static unsigned long at91rm9200_gettimeoffset(void) /* * IRQ handler for the timer. */ -static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id) +static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { if (at91_sys_read(AT91_ST_SR) & AT91_ST_PITS) { /* This is a shared interrupt */ write_seqlock(&xtime_lock); while (((read_CRTR() - last_crtr) & AT91_ST_ALMV) >= LATCH) { - timer_tick(); + timer_tick(regs); last_crtr = (last_crtr + LATCH) & AT91_ST_ALMV; } diff --git a/trunk/arch/arm/mach-at91rm9200/gpio.c b/trunk/arch/arm/mach-at91rm9200/gpio.c index 7467d644f0a3..58c9bf5e9520 100644 --- a/trunk/arch/arm/mach-at91rm9200/gpio.c +++ b/trunk/arch/arm/mach-at91rm9200/gpio.c @@ -332,7 +332,7 @@ static struct irq_chip gpio_irqchip = { .set_wake = gpio_irq_set_wake, }; -static void gpio_irq_handler(unsigned irq, struct irqdesc *desc) +static void gpio_irq_handler(unsigned irq, struct irqdesc *desc, struct pt_regs *regs) { unsigned pin; struct irqdesc *gpio; @@ -363,7 +363,7 @@ static void gpio_irq_handler(unsigned irq, struct irqdesc *desc) gpio_irq_mask(pin); } else - desc_handle_irq(pin, gpio); + desc_handle_irq(pin, gpio, regs); } pin++; gpio++; diff --git a/trunk/arch/arm/mach-clps711x/time.c b/trunk/arch/arm/mach-clps711x/time.c index 428493dd4687..a071eac4a30a 100644 --- a/trunk/arch/arm/mach-clps711x/time.c +++ b/trunk/arch/arm/mach-clps711x/time.c @@ -48,10 +48,10 @@ static unsigned long clps711x_gettimeoffset(void) * IRQ handler for the timer */ static irqreturn_t -p720t_timer_interrupt(int irq, void *dev_id) +p720t_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { write_seqlock(&xtime_lock); - timer_tick(); + timer_tick(regs); write_sequnlock(&xtime_lock); return IRQ_HANDLED; } diff --git a/trunk/arch/arm/mach-clps7500/core.c b/trunk/arch/arm/mach-clps7500/core.c index fb10cf252588..92eaebdd5606 100644 --- a/trunk/arch/arm/mach-clps7500/core.c +++ b/trunk/arch/arm/mach-clps7500/core.c @@ -292,11 +292,11 @@ extern void ioctime_init(void); extern unsigned long ioc_timer_gettimeoffset(void); static irqreturn_t -clps7500_timer_interrupt(int irq, void *dev_id) +clps7500_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { write_seqlock(&xtime_lock); - timer_tick(); + timer_tick(regs); /* Why not using do_leds interface?? */ { diff --git a/trunk/arch/arm/mach-ebsa110/core.c b/trunk/arch/arm/mach-ebsa110/core.c index 90103ab373a6..70dd12ef3c40 100644 --- a/trunk/arch/arm/mach-ebsa110/core.c +++ b/trunk/arch/arm/mach-ebsa110/core.c @@ -174,7 +174,7 @@ static unsigned long ebsa110_gettimeoffset(void) } static irqreturn_t -ebsa110_timer_interrupt(int irq, void *dev_id) +ebsa110_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { u32 count; @@ -190,7 +190,7 @@ ebsa110_timer_interrupt(int irq, void *dev_id) __raw_writeb(count & 0xff, PIT_T1); __raw_writeb(count >> 8, PIT_T1); - timer_tick(); + timer_tick(regs); write_sequnlock(&xtime_lock); diff --git a/trunk/arch/arm/mach-ebsa110/io.c b/trunk/arch/arm/mach-ebsa110/io.c index db38afb2aa88..c648bfb676a1 100644 --- a/trunk/arch/arm/mach-ebsa110/io.c +++ b/trunk/arch/arm/mach-ebsa110/io.c @@ -28,7 +28,7 @@ #include #include -static void __iomem *__isamem_convert_addr(const volatile void __iomem *addr) +static void __iomem *__isamem_convert_addr(void __iomem *addr) { u32 ret, a = (u32 __force) addr; @@ -63,7 +63,7 @@ static void __iomem *__isamem_convert_addr(const volatile void __iomem *addr) /* * read[bwl] and write[bwl] */ -u8 __readb(const volatile void __iomem *addr) +u8 __readb(void __iomem *addr) { void __iomem *a = __isamem_convert_addr(addr); u32 ret; @@ -75,7 +75,7 @@ u8 __readb(const volatile void __iomem *addr) return ret; } -u16 __readw(const volatile void __iomem *addr) +u16 __readw(void __iomem *addr) { void __iomem *a = __isamem_convert_addr(addr); @@ -85,7 +85,7 @@ u16 __readw(const volatile void __iomem *addr) return __raw_readw(a); } -u32 __readl(const volatile void __iomem *addr) +u32 __readl(void __iomem *addr) { void __iomem *a = __isamem_convert_addr(addr); u32 ret; diff --git a/trunk/arch/arm/mach-ep93xx/core.c b/trunk/arch/arm/mach-ep93xx/core.c index e3fd1ab6adcc..a87a784b9201 100644 --- a/trunk/arch/arm/mach-ep93xx/core.c +++ b/trunk/arch/arm/mach-ep93xx/core.c @@ -97,7 +97,7 @@ static unsigned int last_jiffy_time; #define TIMER4_TICKS_PER_JIFFY ((CLOCK_TICK_RATE + (HZ/2)) / HZ) -static int ep93xx_timer_interrupt(int irq, void *dev_id) +static int ep93xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { write_seqlock(&xtime_lock); @@ -106,7 +106,7 @@ static int ep93xx_timer_interrupt(int irq, void *dev_id) (__raw_readl(EP93XX_TIMER4_VALUE_LOW) - last_jiffy_time) >= TIMER4_TICKS_PER_JIFFY) { last_jiffy_time += TIMER4_TICKS_PER_JIFFY; - timer_tick(); + timer_tick(regs); } write_sequnlock(&xtime_lock); @@ -245,7 +245,7 @@ EXPORT_SYMBOL(gpio_line_set); * EP93xx IRQ handling *************************************************************************/ static void ep93xx_gpio_ab_irq_handler(unsigned int irq, - struct irqdesc *desc) + struct irqdesc *desc, struct pt_regs *regs) { unsigned char status; int i; @@ -254,7 +254,7 @@ static void ep93xx_gpio_ab_irq_handler(unsigned int irq, for (i = 0; i < 8; i++) { if (status & (1 << i)) { desc = irq_desc + IRQ_EP93XX_GPIO(0) + i; - desc_handle_irq(IRQ_EP93XX_GPIO(0) + i, desc); + desc_handle_irq(IRQ_EP93XX_GPIO(0) + i, desc, regs); } } @@ -262,7 +262,7 @@ static void ep93xx_gpio_ab_irq_handler(unsigned int irq, for (i = 0; i < 8; i++) { if (status & (1 << i)) { desc = irq_desc + IRQ_EP93XX_GPIO(8) + i; - desc_handle_irq(IRQ_EP93XX_GPIO(8) + i, desc); + desc_handle_irq(IRQ_EP93XX_GPIO(8) + i, desc, regs); } } } diff --git a/trunk/arch/arm/mach-footbridge/dc21285-timer.c b/trunk/arch/arm/mach-footbridge/dc21285-timer.c index fa6be870c6c2..2af610811ca4 100644 --- a/trunk/arch/arm/mach-footbridge/dc21285-timer.c +++ b/trunk/arch/arm/mach-footbridge/dc21285-timer.c @@ -28,13 +28,13 @@ static unsigned long timer1_gettimeoffset (void) } static irqreturn_t -timer1_interrupt(int irq, void *dev_id) +timer1_interrupt(int irq, void *dev_id, struct pt_regs *regs) { write_seqlock(&xtime_lock); *CSR_TIMER1_CLR = 0; - timer_tick(); + timer_tick(regs); write_sequnlock(&xtime_lock); diff --git a/trunk/arch/arm/mach-footbridge/dc21285.c b/trunk/arch/arm/mach-footbridge/dc21285.c index 1463330ed8ee..a1ae49df5c3b 100644 --- a/trunk/arch/arm/mach-footbridge/dc21285.c +++ b/trunk/arch/arm/mach-footbridge/dc21285.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include @@ -155,7 +154,7 @@ static void dc21285_enable_error(unsigned long __data) /* * Warn on PCI errors. */ -static irqreturn_t dc21285_abort_irq(int irq, void *dev_id) +static irqreturn_t dc21285_abort_irq(int irq, void *dev_id, struct pt_regs *regs) { unsigned int cmd; unsigned int status; @@ -166,7 +165,7 @@ static irqreturn_t dc21285_abort_irq(int irq, void *dev_id) if (status & PCI_STATUS_REC_MASTER_ABORT) { printk(KERN_DEBUG "PCI: master abort, pc=0x%08lx\n", - instruction_pointer(get_irq_regs())); + instruction_pointer(regs)); cmd |= PCI_STATUS_REC_MASTER_ABORT << 16; } @@ -185,7 +184,7 @@ static irqreturn_t dc21285_abort_irq(int irq, void *dev_id) return IRQ_HANDLED; } -static irqreturn_t dc21285_serr_irq(int irq, void *dev_id) +static irqreturn_t dc21285_serr_irq(int irq, void *dev_id, struct pt_regs *regs) { struct timer_list *timer = dev_id; unsigned int cntl; @@ -207,7 +206,7 @@ static irqreturn_t dc21285_serr_irq(int irq, void *dev_id) return IRQ_HANDLED; } -static irqreturn_t dc21285_discard_irq(int irq, void *dev_id) +static irqreturn_t dc21285_discard_irq(int irq, void *dev_id, struct pt_regs *regs) { printk(KERN_DEBUG "PCI: discard timer expired\n"); *CSR_SA110_CNTL &= 0xffffde07; @@ -215,7 +214,7 @@ static irqreturn_t dc21285_discard_irq(int irq, void *dev_id) return IRQ_HANDLED; } -static irqreturn_t dc21285_dparity_irq(int irq, void *dev_id) +static irqreturn_t dc21285_dparity_irq(int irq, void *dev_id, struct pt_regs *regs) { unsigned int cmd; @@ -229,7 +228,7 @@ static irqreturn_t dc21285_dparity_irq(int irq, void *dev_id) return IRQ_HANDLED; } -static irqreturn_t dc21285_parity_irq(int irq, void *dev_id) +static irqreturn_t dc21285_parity_irq(int irq, void *dev_id, struct pt_regs *regs) { struct timer_list *timer = dev_id; unsigned int cmd; diff --git a/trunk/arch/arm/mach-footbridge/isa-irq.c b/trunk/arch/arm/mach-footbridge/isa-irq.c index 888dedd501b9..87448c2d6baa 100644 --- a/trunk/arch/arm/mach-footbridge/isa-irq.c +++ b/trunk/arch/arm/mach-footbridge/isa-irq.c @@ -85,17 +85,17 @@ static struct irqchip isa_hi_chip = { }; static void -isa_irq_handler(unsigned int irq, struct irqdesc *desc) +isa_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) { unsigned int isa_irq = *(unsigned char *)PCIIACK_BASE; if (isa_irq < _ISA_IRQ(0) || isa_irq >= _ISA_IRQ(16)) { - do_bad_IRQ(isa_irq, desc); + do_bad_IRQ(isa_irq, desc, regs); return; } desc = irq_desc + isa_irq; - desc_handle_irq(isa_irq, desc); + desc_handle_irq(isa_irq, desc, regs); } static struct irqaction irq_cascade = { diff --git a/trunk/arch/arm/mach-footbridge/isa-timer.c b/trunk/arch/arm/mach-footbridge/isa-timer.c index d884a3954fb4..c4810a40c8e1 100644 --- a/trunk/arch/arm/mach-footbridge/isa-timer.c +++ b/trunk/arch/arm/mach-footbridge/isa-timer.c @@ -62,10 +62,10 @@ static unsigned long isa_gettimeoffset(void) } static irqreturn_t -isa_timer_interrupt(int irq, void *dev_id) +isa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { write_seqlock(&xtime_lock); - timer_tick(); + timer_tick(regs); write_sequnlock(&xtime_lock); return IRQ_HANDLED; } diff --git a/trunk/arch/arm/mach-h720x/common.c b/trunk/arch/arm/mach-h720x/common.c index 4719229a1a78..c096b4569308 100644 --- a/trunk/arch/arm/mach-h720x/common.c +++ b/trunk/arch/arm/mach-h720x/common.c @@ -101,14 +101,14 @@ static void inline unmask_gpio_irq(u32 irq) static void h720x_gpio_handler(unsigned int mask, unsigned int irq, - struct irqdesc *desc) + struct irqdesc *desc, struct pt_regs *regs) { IRQDBG("%s irq: %d\n",__FUNCTION__,irq); desc = irq_desc + irq; while (mask) { if (mask & 1) { IRQDBG("handling irq %d\n", irq); - desc_handle_irq(irq, desc); + desc_handle_irq(irq, desc, regs); } irq++; desc++; @@ -117,58 +117,63 @@ h720x_gpio_handler(unsigned int mask, unsigned int irq, } static void -h720x_gpioa_demux_handler(unsigned int irq_unused, struct irqdesc *desc) +h720x_gpioa_demux_handler(unsigned int irq_unused, struct irqdesc *desc, + struct pt_regs *regs) { unsigned int mask, irq; mask = CPU_REG(GPIO_A_VIRT,GPIO_STAT); irq = IRQ_CHAINED_GPIOA(0); IRQDBG("%s mask: 0x%08x irq: %d\n",__FUNCTION__,mask,irq); - h720x_gpio_handler(mask, irq, desc); + h720x_gpio_handler(mask, irq, desc, regs); } static void -h720x_gpiob_demux_handler(unsigned int irq_unused, struct irqdesc *desc) +h720x_gpiob_demux_handler(unsigned int irq_unused, struct irqdesc *desc, + struct pt_regs *regs) { unsigned int mask, irq; mask = CPU_REG(GPIO_B_VIRT,GPIO_STAT); irq = IRQ_CHAINED_GPIOB(0); IRQDBG("%s mask: 0x%08x irq: %d\n",__FUNCTION__,mask,irq); - h720x_gpio_handler(mask, irq, desc); + h720x_gpio_handler(mask, irq, desc, regs); } static void -h720x_gpioc_demux_handler(unsigned int irq_unused, struct irqdesc *desc) +h720x_gpioc_demux_handler(unsigned int irq_unused, struct irqdesc *desc, + struct pt_regs *regs) { unsigned int mask, irq; mask = CPU_REG(GPIO_C_VIRT,GPIO_STAT); irq = IRQ_CHAINED_GPIOC(0); IRQDBG("%s mask: 0x%08x irq: %d\n",__FUNCTION__,mask,irq); - h720x_gpio_handler(mask, irq, desc); + h720x_gpio_handler(mask, irq, desc, regs); } static void -h720x_gpiod_demux_handler(unsigned int irq_unused, struct irqdesc *desc) +h720x_gpiod_demux_handler(unsigned int irq_unused, struct irqdesc *desc, + struct pt_regs *regs) { unsigned int mask, irq; mask = CPU_REG(GPIO_D_VIRT,GPIO_STAT); irq = IRQ_CHAINED_GPIOD(0); IRQDBG("%s mask: 0x%08x irq: %d\n",__FUNCTION__,mask,irq); - h720x_gpio_handler(mask, irq, desc); + h720x_gpio_handler(mask, irq, desc, regs); } #ifdef CONFIG_CPU_H7202 static void -h720x_gpioe_demux_handler(unsigned int irq_unused, struct irqdesc *desc) +h720x_gpioe_demux_handler(unsigned int irq_unused, struct irqdesc *desc, + struct pt_regs *regs) { unsigned int mask, irq; mask = CPU_REG(GPIO_E_VIRT,GPIO_STAT); irq = IRQ_CHAINED_GPIOE(0); IRQDBG("%s mask: 0x%08x irq: %d\n",__FUNCTION__,mask,irq); - h720x_gpio_handler(mask, irq, desc); + h720x_gpio_handler(mask, irq, desc, regs); } #endif diff --git a/trunk/arch/arm/mach-h720x/cpu-h7201.c b/trunk/arch/arm/mach-h720x/cpu-h7201.c index 13f76bdb3d9d..a9a8255a3a03 100644 --- a/trunk/arch/arm/mach-h720x/cpu-h7201.c +++ b/trunk/arch/arm/mach-h720x/cpu-h7201.c @@ -27,12 +27,12 @@ * Timer interrupt handler */ static irqreturn_t -h7201_timer_interrupt(int irq, void *dev_id) +h7201_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { write_seqlock(&xtime_lock); CPU_REG (TIMER_VIRT, TIMER_TOPSTAT); - timer_tick(); + timer_tick(regs); write_sequnlock(&xtime_lock); diff --git a/trunk/arch/arm/mach-h720x/cpu-h7202.c b/trunk/arch/arm/mach-h720x/cpu-h7202.c index 06fecaefd8dc..da678d163fd9 100644 --- a/trunk/arch/arm/mach-h720x/cpu-h7202.c +++ b/trunk/arch/arm/mach-h720x/cpu-h7202.c @@ -106,7 +106,8 @@ static struct platform_device *devices[] __initdata = { * we have to handle all timer interrupts in one place. */ static void -h7202_timerx_demux_handler(unsigned int irq_unused, struct irqdesc *desc) +h7202_timerx_demux_handler(unsigned int irq_unused, struct irqdesc *desc, + struct pt_regs *regs) { unsigned int mask, irq; @@ -114,7 +115,7 @@ h7202_timerx_demux_handler(unsigned int irq_unused, struct irqdesc *desc) if ( mask & TSTAT_T0INT ) { write_seqlock(&xtime_lock); - timer_tick(); + timer_tick(regs); write_sequnlock(&xtime_lock); if( mask == TSTAT_T0INT ) return; @@ -125,7 +126,7 @@ h7202_timerx_demux_handler(unsigned int irq_unused, struct irqdesc *desc) desc = irq_desc + irq; while (mask) { if (mask & 1) - desc_handle_irq(irq, desc); + desc_handle_irq(irq, desc, regs); irq++; desc++; mask >>= 1; @@ -136,9 +137,9 @@ h7202_timerx_demux_handler(unsigned int irq_unused, struct irqdesc *desc) * Timer interrupt handler */ static irqreturn_t -h7202_timer_interrupt(int irq, void *dev_id) +h7202_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - h7202_timerx_demux_handler(0, NULL); + h7202_timerx_demux_handler(0, NULL, regs); return IRQ_HANDLED; } diff --git a/trunk/arch/arm/mach-imx/dma.c b/trunk/arch/arm/mach-imx/dma.c index 6d50d85a618c..36578871ecc8 100644 --- a/trunk/arch/arm/mach-imx/dma.c +++ b/trunk/arch/arm/mach-imx/dma.c @@ -279,8 +279,8 @@ imx_dma_setup_sg(imx_dmach_t dma_ch, */ int imx_dma_setup_handlers(imx_dmach_t dma_ch, - void (*irq_handler) (int, void *), - void (*err_handler) (int, void *, int), + void (*irq_handler) (int, void *, struct pt_regs *), + void (*err_handler) (int, void *, struct pt_regs *, int), void *data) { struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch]; @@ -461,7 +461,7 @@ imx_dma_request_by_prio(imx_dmach_t * pdma_ch, const char *name, return -ENODEV; } -static irqreturn_t dma_err_handler(int irq, void *dev_id) +static irqreturn_t dma_err_handler(int irq, void *dev_id, struct pt_regs *regs) { int i, disr = DISR; struct imx_dma_channel *channel; @@ -500,7 +500,7 @@ static irqreturn_t dma_err_handler(int irq, void *dev_id) /*imx_dma_channels[i].sg = NULL;*/ if (channel->name && channel->err_handler) { - channel->err_handler(i, channel->data, errcode); + channel->err_handler(i, channel->data, regs, errcode); continue; } @@ -517,7 +517,7 @@ static irqreturn_t dma_err_handler(int irq, void *dev_id) return IRQ_HANDLED; } -static irqreturn_t dma_irq_handler(int irq, void *dev_id) +static irqreturn_t dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs) { int i, disr = DISR; @@ -536,7 +536,7 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id) } else { if (channel->irq_handler) channel->irq_handler(i, - channel->data); + channel->data, regs); } } else { /* diff --git a/trunk/arch/arm/mach-imx/irq.c b/trunk/arch/arm/mach-imx/irq.c index 368b13b058ab..2688bd82c2a2 100644 --- a/trunk/arch/arm/mach-imx/irq.c +++ b/trunk/arch/arm/mach-imx/irq.c @@ -146,13 +146,13 @@ imx_gpio_unmask_irq(unsigned int irq) static void imx_gpio_handler(unsigned int mask, unsigned int irq, - struct irqdesc *desc) + struct irqdesc *desc, struct pt_regs *regs) { desc = irq_desc + irq; while (mask) { if (mask & 1) { DEBUG_IRQ("handling irq %d\n", irq); - desc_handle_irq(irq, desc); + desc_handle_irq(irq, desc, regs); } irq++; desc++; @@ -161,43 +161,47 @@ imx_gpio_handler(unsigned int mask, unsigned int irq, } static void -imx_gpioa_demux_handler(unsigned int irq_unused, struct irqdesc *desc) +imx_gpioa_demux_handler(unsigned int irq_unused, struct irqdesc *desc, + struct pt_regs *regs) { unsigned int mask, irq; mask = ISR(0); irq = IRQ_GPIOA(0); - imx_gpio_handler(mask, irq, desc); + imx_gpio_handler(mask, irq, desc, regs); } static void -imx_gpiob_demux_handler(unsigned int irq_unused, struct irqdesc *desc) +imx_gpiob_demux_handler(unsigned int irq_unused, struct irqdesc *desc, + struct pt_regs *regs) { unsigned int mask, irq; mask = ISR(1); irq = IRQ_GPIOB(0); - imx_gpio_handler(mask, irq, desc); + imx_gpio_handler(mask, irq, desc, regs); } static void -imx_gpioc_demux_handler(unsigned int irq_unused, struct irqdesc *desc) +imx_gpioc_demux_handler(unsigned int irq_unused, struct irqdesc *desc, + struct pt_regs *regs) { unsigned int mask, irq; mask = ISR(2); irq = IRQ_GPIOC(0); - imx_gpio_handler(mask, irq, desc); + imx_gpio_handler(mask, irq, desc, regs); } static void -imx_gpiod_demux_handler(unsigned int irq_unused, struct irqdesc *desc) +imx_gpiod_demux_handler(unsigned int irq_unused, struct irqdesc *desc, + struct pt_regs *regs) { unsigned int mask, irq; mask = ISR(3); irq = IRQ_GPIOD(0); - imx_gpio_handler(mask, irq, desc); + imx_gpio_handler(mask, irq, desc, regs); } static struct irq_chip imx_internal_chip = { diff --git a/trunk/arch/arm/mach-imx/time.c b/trunk/arch/arm/mach-imx/time.c index 8ae4a2c5066f..6ed7523c65bb 100644 --- a/trunk/arch/arm/mach-imx/time.c +++ b/trunk/arch/arm/mach-imx/time.c @@ -56,7 +56,7 @@ static unsigned long imx_gettimeoffset(void) * IRQ handler for the timer */ static irqreturn_t -imx_timer_interrupt(int irq, void *dev_id) +imx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { write_seqlock(&xtime_lock); @@ -64,7 +64,7 @@ imx_timer_interrupt(int irq, void *dev_id) if (IMX_TSTAT(TIMER_BASE)) IMX_TSTAT(TIMER_BASE) = 0; - timer_tick(); + timer_tick(regs); write_sequnlock(&xtime_lock); return IRQ_HANDLED; diff --git a/trunk/arch/arm/mach-integrator/core.c b/trunk/arch/arm/mach-integrator/core.c index 8d880cb9ba39..42021fdfa0c6 100644 --- a/trunk/arch/arm/mach-integrator/core.c +++ b/trunk/arch/arm/mach-integrator/core.c @@ -248,7 +248,7 @@ unsigned long integrator_gettimeoffset(void) * IRQ handler for the timer */ static irqreturn_t -integrator_timer_interrupt(int irq, void *dev_id) +integrator_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { write_seqlock(&xtime_lock); @@ -262,7 +262,7 @@ integrator_timer_interrupt(int irq, void *dev_id) * primary CPU */ if (hard_smp_processor_id() == 0) { - timer_tick(); + timer_tick(regs); #ifdef CONFIG_SMP smp_send_timer(); #endif @@ -272,7 +272,7 @@ integrator_timer_interrupt(int irq, void *dev_id) /* * this is the ARM equivalent of the APIC timer interrupt */ - update_process_times(user_mode(get_irq_regs())); + update_process_times(user_mode(regs)); #endif /* CONFIG_SMP */ write_sequnlock(&xtime_lock); diff --git a/trunk/arch/arm/mach-integrator/integrator_cp.c b/trunk/arch/arm/mach-integrator/integrator_cp.c index 771b65bffe69..678b6ba2b463 100644 --- a/trunk/arch/arm/mach-integrator/integrator_cp.c +++ b/trunk/arch/arm/mach-integrator/integrator_cp.c @@ -202,12 +202,12 @@ static struct irq_chip sic_chip = { }; static void -sic_handle_irq(unsigned int irq, struct irqdesc *desc) +sic_handle_irq(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) { unsigned long status = sic_readl(INTCP_VA_SIC_BASE + IRQ_STATUS); if (status == 0) { - do_bad_IRQ(irq, desc); + do_bad_IRQ(irq, desc, regs); return; } @@ -218,7 +218,7 @@ sic_handle_irq(unsigned int irq, struct irqdesc *desc) irq += IRQ_SIC_START; desc = irq_desc + irq; - desc_handle_irq(irq, desc); + desc_handle_irq(irq, desc, regs); } while (status); } diff --git a/trunk/arch/arm/mach-integrator/pci_v3.c b/trunk/arch/arm/mach-integrator/pci_v3.c index fb8c6d97b22b..4418f6d7572d 100644 --- a/trunk/arch/arm/mach-integrator/pci_v3.c +++ b/trunk/arch/arm/mach-integrator/pci_v3.c @@ -440,10 +440,9 @@ v3_pci_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) return 1; } -static irqreturn_t v3_irq(int irq, void *devid) +static irqreturn_t v3_irq(int irq, void *devid, struct pt_regs *regs) { #ifdef CONFIG_DEBUG_LL - struct pt_regs *regs = get_irq_regs(); unsigned long pc = instruction_pointer(regs); unsigned long instr = *(unsigned long *)pc; char buf[128]; diff --git a/trunk/arch/arm/mach-integrator/time.c b/trunk/arch/arm/mach-integrator/time.c index 5278f589fcee..ee49cf790dab 100644 --- a/trunk/arch/arm/mach-integrator/time.c +++ b/trunk/arch/arm/mach-integrator/time.c @@ -96,7 +96,8 @@ static struct rtc_ops rtc_ops = { .set_alarm = integrator_rtc_set_alarm, }; -static irqreturn_t arm_rtc_interrupt(int irq, void *dev_id) +static irqreturn_t arm_rtc_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { writel(0, rtc_base + RTC_EOI); return IRQ_HANDLED; diff --git a/trunk/arch/arm/mach-iop32x/n2100.c b/trunk/arch/arm/mach-iop32x/n2100.c index 2499a7707e3c..a2c94a47b2b2 100644 --- a/trunk/arch/arm/mach-iop32x/n2100.c +++ b/trunk/arch/arm/mach-iop32x/n2100.c @@ -85,7 +85,7 @@ n2100_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) irq = IRQ_IOP32X_XINT0; } else if (PCI_SLOT(dev->devfn) == 2) { /* RTL8110SB #2 */ - irq = IRQ_IOP32X_XINT3; + irq = IRQ_IOP32X_XINT1; } else if (PCI_SLOT(dev->devfn) == 3) { /* Sil3512 */ irq = IRQ_IOP32X_XINT2; diff --git a/trunk/arch/arm/mach-ixp2000/core.c b/trunk/arch/arm/mach-ixp2000/core.c index 22c98e9dad28..7f91f689a041 100644 --- a/trunk/arch/arm/mach-ixp2000/core.c +++ b/trunk/arch/arm/mach-ixp2000/core.c @@ -204,7 +204,7 @@ unsigned long ixp2000_gettimeoffset (void) return offset / ticks_per_usec; } -static int ixp2000_timer_interrupt(int irq, void *dev_id) +static int ixp2000_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { write_seqlock(&xtime_lock); @@ -213,7 +213,7 @@ static int ixp2000_timer_interrupt(int irq, void *dev_id) while ((signed long)(next_jiffy_time - *missing_jiffy_timer_csr) >= ticks_per_jiffy) { - timer_tick(); + timer_tick(regs); next_jiffy_time -= ticks_per_jiffy; } @@ -308,7 +308,7 @@ EXPORT_SYMBOL(gpio_line_config); /************************************************************************* * IRQ handling IXP2000 *************************************************************************/ -static void ixp2000_GPIO_irq_handler(unsigned int irq, struct irqdesc *desc) +static void ixp2000_GPIO_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) { int i; unsigned long status = *IXP2000_GPIO_INST; @@ -316,7 +316,7 @@ static void ixp2000_GPIO_irq_handler(unsigned int irq, struct irqdesc *desc) for (i = 0; i <= 7; i++) { if (status & (1<= 0; i--) { if(status & (1 << i)) { desc = irq_desc + IRQ_IXP2000_DRAM0_MIN_ERR + i; - desc_handle_irq(IRQ_IXP2000_DRAM0_MIN_ERR + i, desc); + desc_handle_irq(IRQ_IXP2000_DRAM0_MIN_ERR + i, desc, regs); } } } diff --git a/trunk/arch/arm/mach-ixp2000/ixdp2400.c b/trunk/arch/arm/mach-ixp2000/ixdp2400.c index 0fdd03ab36e6..a6f14801872d 100644 --- a/trunk/arch/arm/mach-ixp2000/ixdp2400.c +++ b/trunk/arch/arm/mach-ixp2000/ixdp2400.c @@ -133,13 +133,11 @@ static void ixdp2400_pci_postinit(void) struct pci_dev *dev; if (ixdp2x00_master_npu()) { - dev = pci_get_bus_and_slot(1, IXDP2400_SLAVE_ENET_DEVFN); + dev = pci_find_slot(1, IXDP2400_SLAVE_ENET_DEVFN); pci_remove_bus_device(dev); - pci_dev_put(dev); } else { - dev = pci_get_bus_and_slot(1, IXDP2400_MASTER_ENET_DEVFN); + dev = pci_find_slot(1, IXDP2400_MASTER_ENET_DEVFN); pci_remove_bus_device(dev); - pci_dev_put(dev); ixdp2x00_slave_pci_postinit(); } diff --git a/trunk/arch/arm/mach-ixp2000/ixdp2800.c b/trunk/arch/arm/mach-ixp2000/ixdp2800.c index 70d247f09a7e..91d36d91dac0 100644 --- a/trunk/arch/arm/mach-ixp2000/ixdp2800.c +++ b/trunk/arch/arm/mach-ixp2000/ixdp2800.c @@ -261,16 +261,14 @@ int __init ixdp2800_pci_init(void) pci_common_init(&ixdp2800_pci); if (ixdp2x00_master_npu()) { - dev = pci_get_bus_and_slot(1, IXDP2800_SLAVE_ENET_DEVFN); + dev = pci_find_slot(1, IXDP2800_SLAVE_ENET_DEVFN); pci_remove_bus_device(dev); - pci_dev_put(dev); ixdp2800_master_enable_slave(); ixdp2800_master_wait_for_slave_bus_scan(); } else { - dev = pci_get_bus_and_slot(1, IXDP2800_MASTER_ENET_DEVFN); + dev = pci_find_slot(1, IXDP2800_MASTER_ENET_DEVFN); pci_remove_bus_device(dev); - pci_dev_put(dev); } } diff --git a/trunk/arch/arm/mach-ixp2000/ixdp2x00.c b/trunk/arch/arm/mach-ixp2000/ixdp2x00.c index aa2655092d2d..40eef8b36740 100644 --- a/trunk/arch/arm/mach-ixp2000/ixdp2x00.c +++ b/trunk/arch/arm/mach-ixp2000/ixdp2x00.c @@ -106,7 +106,7 @@ static void ixdp2x00_irq_unmask(unsigned int irq) ixp2000_release_slowport(&old_cfg); } -static void ixdp2x00_irq_handler(unsigned int irq, struct irqdesc *desc) +static void ixdp2x00_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) { volatile u32 ex_interrupt = 0; static struct slowport_cfg old_cfg; @@ -132,7 +132,7 @@ static void ixdp2x00_irq_handler(unsigned int irq, struct irqdesc *desc) struct irqdesc *cpld_desc; int cpld_irq = IXP2000_BOARD_IRQ(0) + i; cpld_desc = irq_desc + cpld_irq; - desc_handle_irq(cpld_irq, cpld_desc); + desc_handle_irq(cpld_irq, cpld_desc, regs); } } @@ -241,14 +241,11 @@ void ixdp2x00_slave_pci_postinit(void) /* * Remove PMC device is there is one */ - if((dev = pci_get_bus_and_slot(1, IXDP2X00_PMC_DEVFN))) { + if((dev = pci_find_slot(1, IXDP2X00_PMC_DEVFN))) pci_remove_bus_device(dev); - pci_dev_put(dev); - } - dev = pci_get_bus_and_slot(0, IXDP2X00_21555_DEVFN); + dev = pci_find_slot(0, IXDP2X00_21555_DEVFN); pci_remove_bus_device(dev); - pci_dev_put(dev); } /************************************************************************** diff --git a/trunk/arch/arm/mach-ixp2000/ixdp2x01.c b/trunk/arch/arm/mach-ixp2000/ixdp2x01.c index 9ccae9e63f70..7f42366f60d1 100644 --- a/trunk/arch/arm/mach-ixp2000/ixdp2x01.c +++ b/trunk/arch/arm/mach-ixp2000/ixdp2x01.c @@ -63,7 +63,7 @@ static void ixdp2x01_irq_unmask(unsigned int irq) static u32 valid_irq_mask; -static void ixdp2x01_irq_handler(unsigned int irq, struct irqdesc *desc) +static void ixdp2x01_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) { u32 ex_interrupt; int i; @@ -82,7 +82,7 @@ static void ixdp2x01_irq_handler(unsigned int irq, struct irqdesc *desc) struct irqdesc *cpld_desc; int cpld_irq = IXP2000_BOARD_IRQ(0) + i; cpld_desc = irq_desc + cpld_irq; - desc_handle_irq(cpld_irq, cpld_desc); + desc_handle_irq(cpld_irq, cpld_desc, regs); } } diff --git a/trunk/arch/arm/mach-ixp23xx/core.c b/trunk/arch/arm/mach-ixp23xx/core.c index a704a1820048..566a07821c77 100644 --- a/trunk/arch/arm/mach-ixp23xx/core.c +++ b/trunk/arch/arm/mach-ixp23xx/core.c @@ -251,7 +251,7 @@ static void ixp23xx_pci_irq_unmask(unsigned int irq) /* * TODO: Should this just be done at ASM level? */ -static void pci_handler(unsigned int irq, struct irqdesc *desc) +static void pci_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) { u32 pci_interrupt; unsigned int irqno; @@ -271,7 +271,7 @@ static void pci_handler(unsigned int irq, struct irqdesc *desc) } int_desc = irq_desc + irqno; - desc_handle_irq(irqno, int_desc); + desc_handle_irq(irqno, int_desc, regs); desc->chip->unmask(irq); } @@ -348,12 +348,12 @@ ixp23xx_gettimeoffset(void) } static irqreturn_t -ixp23xx_timer_interrupt(int irq, void *dev_id) +ixp23xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { /* Clear Pending Interrupt by writing '1' to it */ *IXP23XX_TIMER_STATUS = IXP23XX_TIMER1_INT_PEND; while ((signed long)(*IXP23XX_TIMER_CONT - next_jiffy_time) >= LATCH) { - timer_tick(); + timer_tick(regs); next_jiffy_time += LATCH; } diff --git a/trunk/arch/arm/mach-ixp23xx/ixdp2351.c b/trunk/arch/arm/mach-ixp23xx/ixdp2351.c index b6ab0e8bb5e8..37a32e6bcca2 100644 --- a/trunk/arch/arm/mach-ixp23xx/ixdp2351.c +++ b/trunk/arch/arm/mach-ixp23xx/ixdp2351.c @@ -60,7 +60,7 @@ static void ixdp2351_inta_unmask(unsigned int irq) *IXDP2351_CPLD_INTA_MASK_CLR_REG = IXDP2351_INTA_IRQ_MASK(irq); } -static void ixdp2351_inta_handler(unsigned int irq, struct irqdesc *desc) +static void ixdp2351_inta_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) { u16 ex_interrupt = *IXDP2351_CPLD_INTA_STAT_REG & IXDP2351_INTA_IRQ_VALID; @@ -74,7 +74,7 @@ static void ixdp2351_inta_handler(unsigned int irq, struct irqdesc *desc) int cpld_irq = IXP23XX_MACH_IRQ(IXDP2351_INTA_IRQ_BASE + i); cpld_desc = irq_desc + cpld_irq; - desc_handle_irq(cpld_irq, cpld_desc); + desc_handle_irq(cpld_irq, cpld_desc, regs); } } @@ -97,7 +97,7 @@ static void ixdp2351_intb_unmask(unsigned int irq) *IXDP2351_CPLD_INTB_MASK_CLR_REG = IXDP2351_INTB_IRQ_MASK(irq); } -static void ixdp2351_intb_handler(unsigned int irq, struct irqdesc *desc) +static void ixdp2351_intb_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) { u16 ex_interrupt = *IXDP2351_CPLD_INTB_STAT_REG & IXDP2351_INTB_IRQ_VALID; @@ -111,7 +111,7 @@ static void ixdp2351_intb_handler(unsigned int irq, struct irqdesc *desc) int cpld_irq = IXP23XX_MACH_IRQ(IXDP2351_INTB_IRQ_BASE + i); cpld_desc = irq_desc + cpld_irq; - desc_handle_irq(cpld_irq, cpld_desc); + desc_handle_irq(cpld_irq, cpld_desc, regs); } } diff --git a/trunk/arch/arm/mach-ixp4xx/Kconfig b/trunk/arch/arm/mach-ixp4xx/Kconfig index e316bd93313f..57f23b465392 100644 --- a/trunk/arch/arm/mach-ixp4xx/Kconfig +++ b/trunk/arch/arm/mach-ixp4xx/Kconfig @@ -133,7 +133,7 @@ config IXP4XX_INDIRECT_PCI into the kernel and we can use the standard read[bwl]/write[bwl] macros. This is the preferred method due to speed but it limits the system to just 64MB of PCI memory. This can be - problematic if using video cards and other memory-heavy devices. + problamatic if using video cards and other memory-heavy devices. 2) If > 64MB of memory space is required, the IXP4xx can be configured to use indirect registers to access PCI This allows diff --git a/trunk/arch/arm/mach-ixp4xx/common.c b/trunk/arch/arm/mach-ixp4xx/common.c index fbe288a8da65..35dd8b3824b0 100644 --- a/trunk/arch/arm/mach-ixp4xx/common.c +++ b/trunk/arch/arm/mach-ixp4xx/common.c @@ -86,8 +86,7 @@ enum ixp4xx_irq_type { IXP4XX_IRQ_LEVEL, IXP4XX_IRQ_EDGE }; -/* Each bit represents an IRQ: 1: edge-triggered, 0: level triggered */ -static unsigned long long ixp4xx_irq_edge = 0; +static void ixp4xx_config_irq(unsigned irq, enum ixp4xx_irq_type type); /* * IRQ -> GPIO mapping table @@ -136,11 +135,7 @@ static int ixp4xx_set_irq_type(unsigned int irq, unsigned int type) default: return -EINVAL; } - - if (irq_type == IXP4XX_IRQ_EDGE) - ixp4xx_irq_edge |= (1 << irq); - else - ixp4xx_irq_edge &= ~(1 << irq); + ixp4xx_config_irq(irq, irq_type); if (line >= 8) { /* pins 8-15 */ line -= 8; @@ -172,6 +167,14 @@ static void ixp4xx_irq_mask(unsigned int irq) *IXP4XX_ICMR &= ~(1 << irq); } +static void ixp4xx_irq_unmask(unsigned int irq) +{ + if (cpu_is_ixp46x() && irq >= 32) + *IXP4XX_ICMR2 |= (1 << (irq - 32)); + else + *IXP4XX_ICMR |= (1 << irq); +} + static void ixp4xx_irq_ack(unsigned int irq) { int line = (irq < 32) ? irq2gpio[irq] : -1; @@ -184,25 +187,41 @@ static void ixp4xx_irq_ack(unsigned int irq) * Level triggered interrupts on GPIO lines can only be cleared when the * interrupt condition disappears. */ -static void ixp4xx_irq_unmask(unsigned int irq) +static void ixp4xx_irq_level_unmask(unsigned int irq) { - if (!(ixp4xx_irq_edge & (1 << irq))) - ixp4xx_irq_ack(irq); - - if (cpu_is_ixp46x() && irq >= 32) - *IXP4XX_ICMR2 |= (1 << (irq - 32)); - else - *IXP4XX_ICMR |= (1 << irq); + ixp4xx_irq_ack(irq); + ixp4xx_irq_unmask(irq); } -static struct irqchip ixp4xx_irq_chip = { - .name = "IXP4xx", +static struct irqchip ixp4xx_irq_level_chip = { + .ack = ixp4xx_irq_mask, + .mask = ixp4xx_irq_mask, + .unmask = ixp4xx_irq_level_unmask, + .set_type = ixp4xx_set_irq_type, +}; + +static struct irqchip ixp4xx_irq_edge_chip = { .ack = ixp4xx_irq_ack, .mask = ixp4xx_irq_mask, .unmask = ixp4xx_irq_unmask, .set_type = ixp4xx_set_irq_type, }; +static void ixp4xx_config_irq(unsigned irq, enum ixp4xx_irq_type type) +{ + switch (type) { + case IXP4XX_IRQ_LEVEL: + set_irq_chip(irq, &ixp4xx_irq_level_chip); + set_irq_handler(irq, do_level_IRQ); + break; + case IXP4XX_IRQ_EDGE: + set_irq_chip(irq, &ixp4xx_irq_edge_chip); + set_irq_handler(irq, do_edge_IRQ); + break; + } + set_irq_flags(irq, IRQF_VALID); +} + void __init ixp4xx_init_irq(void) { int i = 0; @@ -222,11 +241,8 @@ void __init ixp4xx_init_irq(void) } /* Default to all level triggered */ - for(i = 0; i < NR_IRQS; i++) { - set_irq_chip(i, &ixp4xx_irq_chip); - set_irq_handler(i, do_level_IRQ); - set_irq_flags(i, IRQF_VALID); - } + for(i = 0; i < NR_IRQS; i++) + ixp4xx_config_irq(i, IXP4XX_IRQ_LEVEL); } @@ -240,7 +256,7 @@ static unsigned volatile last_jiffy_time; #define CLOCK_TICKS_PER_USEC ((CLOCK_TICK_RATE + USEC_PER_SEC/2) / USEC_PER_SEC) -static irqreturn_t ixp4xx_timer_interrupt(int irq, void *dev_id) +static irqreturn_t ixp4xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { write_seqlock(&xtime_lock); @@ -251,7 +267,7 @@ static irqreturn_t ixp4xx_timer_interrupt(int irq, void *dev_id) * Catch up with the real idea of time */ while ((signed long)(*IXP4XX_OSTS - last_jiffy_time) >= LATCH) { - timer_tick(); + timer_tick(regs); last_jiffy_time += LATCH; } diff --git a/trunk/arch/arm/mach-ixp4xx/nas100d-power.c b/trunk/arch/arm/mach-ixp4xx/nas100d-power.c index 29aa98d3a7fa..81ffcae1f56e 100644 --- a/trunk/arch/arm/mach-ixp4xx/nas100d-power.c +++ b/trunk/arch/arm/mach-ixp4xx/nas100d-power.c @@ -24,7 +24,7 @@ #include -static irqreturn_t nas100d_reset_handler(int irq, void *dev_id) +static irqreturn_t nas100d_reset_handler(int irq, void *dev_id, struct pt_regs *regs) { /* Signal init to do the ctrlaltdel action, this will bypass init if * it hasn't started and do a kernel_restart. diff --git a/trunk/arch/arm/mach-ixp4xx/nslu2-power.c b/trunk/arch/arm/mach-ixp4xx/nslu2-power.c index acd71e9c38a7..a29b3b2b61b6 100644 --- a/trunk/arch/arm/mach-ixp4xx/nslu2-power.c +++ b/trunk/arch/arm/mach-ixp4xx/nslu2-power.c @@ -25,7 +25,7 @@ #include -static irqreturn_t nslu2_power_handler(int irq, void *dev_id) +static irqreturn_t nslu2_power_handler(int irq, void *dev_id, struct pt_regs *regs) { /* Signal init to do the ctrlaltdel action, this will bypass init if * it hasn't started and do a kernel_restart. @@ -35,7 +35,7 @@ static irqreturn_t nslu2_power_handler(int irq, void *dev_id) return IRQ_HANDLED; } -static irqreturn_t nslu2_reset_handler(int irq, void *dev_id) +static irqreturn_t nslu2_reset_handler(int irq, void *dev_id, struct pt_regs *regs) { /* This is the paper-clip reset, it shuts the machine down directly. */ diff --git a/trunk/arch/arm/mach-lh7a40x/Kconfig b/trunk/arch/arm/mach-lh7a40x/Kconfig index 6f4c6a1798c1..558a34f53b1c 100644 --- a/trunk/arch/arm/mach-lh7a40x/Kconfig +++ b/trunk/arch/arm/mach-lh7a40x/Kconfig @@ -8,13 +8,13 @@ config MACH_KEV7A400 help Say Y here if you are using the Sharp KEV7A400 development board. This hardware is discontinued, so I'd be very - surprised if you wanted this option. + suprised if you wanted this option. config MACH_LPD7A400 bool "LPD7A400 Card Engine" select ARCH_LH7A400 # select IDE_POLL -# select HAS_TOUCHSCREEN_ADS7843_LH7 + select HAS_TOUCHSCREEN_ADS7843_LH7 help Say Y here if you are using Logic Product Development's LPD7A400 CardEngine. For the time being, the LPD7A400 and @@ -24,7 +24,7 @@ config MACH_LPD7A404 bool "LPD7A404 Card Engine" select ARCH_LH7A404 # select IDE_POLL -# select HAS_TOUCHSCREEN_ADC_LH7 + select HAS_TOUCHSCREEN_ADC_LH7 help Say Y here if you are using Logic Product Development's LPD7A404 CardEngine. For the time being, the LPD7A400 and diff --git a/trunk/arch/arm/mach-lh7a40x/arch-kev7a400.c b/trunk/arch/arm/mach-lh7a40x/arch-kev7a400.c index 15fbcc911fe7..4f2ab48800a5 100644 --- a/trunk/arch/arm/mach-lh7a40x/arch-kev7a400.c +++ b/trunk/arch/arm/mach-lh7a40x/arch-kev7a400.c @@ -71,13 +71,14 @@ static struct irq_chip kev7a400_cpld_chip = { }; -static void kev7a400_cpld_handler (unsigned int irq, struct irqdesc *desc) +static void kev7a400_cpld_handler (unsigned int irq, struct irqdesc *desc, + struct pt_regs *regs) { u32 mask = CPLD_LATCHED_INTS; irq = IRQ_KEV7A400_CPLD; for (; mask; mask >>= 1, ++irq) { if (mask & 1) - desc[irq].handle (irq, desc); + desc[irq].handle (irq, desc, regs); } } diff --git a/trunk/arch/arm/mach-lh7a40x/arch-lpd7a40x.c b/trunk/arch/arm/mach-lh7a40x/arch-lpd7a40x.c index 8441e0a156cb..a21b12f06c6b 100644 --- a/trunk/arch/arm/mach-lh7a40x/arch-lpd7a40x.c +++ b/trunk/arch/arm/mach-lh7a40x/arch-lpd7a40x.c @@ -207,7 +207,8 @@ static struct irq_chip lpd7a40x_cpld_chip = { .unmask = lh7a40x_unmask_cpld_irq, }; -static void lpd7a40x_cpld_handler (unsigned int irq, struct irqdesc *desc) +static void lpd7a40x_cpld_handler (unsigned int irq, struct irqdesc *desc, + struct pt_regs *regs) { unsigned int mask = CPLD_INTERRUPTS; diff --git a/trunk/arch/arm/mach-lh7a40x/common.h b/trunk/arch/arm/mach-lh7a40x/common.h index 0ca20c6c83b7..18e8bb4eb202 100644 --- a/trunk/arch/arm/mach-lh7a40x/common.h +++ b/trunk/arch/arm/mach-lh7a40x/common.h @@ -15,4 +15,4 @@ extern void lh7a404_init_irq (void); extern void lh7a40x_clcd_init (void); extern void lh7a40x_init_board_irq (void); -#define IRQ_DISPATCH(irq) desc_handle_irq((irq),(irq_desc + irq)) +#define IRQ_DISPATCH(irq) desc_handle_irq((irq),(irq_desc + irq), regs) diff --git a/trunk/arch/arm/mach-lh7a40x/irq-kev7a400.c b/trunk/arch/arm/mach-lh7a40x/irq-kev7a400.c index 646071334b8f..f9b3fe9174a5 100644 --- a/trunk/arch/arm/mach-lh7a40x/irq-kev7a400.c +++ b/trunk/arch/arm/mach-lh7a40x/irq-kev7a400.c @@ -51,13 +51,14 @@ irq_chip lh7a400_cpld_chip = { }; static void -lh7a400_cpld_handler (unsigned int irq, struct irqdesc *desc) +lh7a400_cpld_handler (unsigned int irq, struct irqdesc *desc, + struct pt_regs *regs) { u32 mask = CPLD_LATCHED_INTS; irq = IRQ_KEV_7A400_CPLD; for (; mask; mask >>= 1, ++irq) { if (mask & 1) - desc[irq].handle (irq, desc); + desc[irq].handle (irq, desc, regs); } } diff --git a/trunk/arch/arm/mach-lh7a40x/irq-lpd7a40x.c b/trunk/arch/arm/mach-lh7a40x/irq-lpd7a40x.c index b20376804bbb..d6055dde6468 100644 --- a/trunk/arch/arm/mach-lh7a40x/irq-lpd7a40x.c +++ b/trunk/arch/arm/mach-lh7a40x/irq-lpd7a40x.c @@ -57,7 +57,8 @@ static struct irq_chip lh7a40x_cpld_chip = { .unmask = lh7a40x_unmask_cpld_irq, }; -static void lh7a40x_cpld_handler (unsigned int irq, struct irqdesc *desc) +static void lh7a40x_cpld_handler (unsigned int irq, struct irqdesc *desc, + struct pt_regs *regs) { unsigned int mask = CPLD_INTERRUPTS; diff --git a/trunk/arch/arm/mach-lh7a40x/time.c b/trunk/arch/arm/mach-lh7a40x/time.c index bef3c4b68d3b..ad5652e01507 100644 --- a/trunk/arch/arm/mach-lh7a40x/time.c +++ b/trunk/arch/arm/mach-lh7a40x/time.c @@ -39,12 +39,12 @@ #endif static irqreturn_t -lh7a40x_timer_interrupt(int irq, void *dev_id) +lh7a40x_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { write_seqlock(&xtime_lock); TIMER_EOI = 0; - timer_tick(); + timer_tick(regs); write_sequnlock(&xtime_lock); diff --git a/trunk/arch/arm/mach-netx/generic.c b/trunk/arch/arm/mach-netx/generic.c index edbbbdc3b06b..af0b13534cfd 100644 --- a/trunk/arch/arm/mach-netx/generic.c +++ b/trunk/arch/arm/mach-netx/generic.c @@ -69,7 +69,8 @@ static struct platform_device *devices[] __initdata = { #endif static void -netx_hif_demux_handler(unsigned int irq_unused, struct irqdesc *desc) +netx_hif_demux_handler(unsigned int irq_unused, struct irqdesc *desc, + struct pt_regs *regs) { unsigned int irq = NETX_IRQ_HIF_CHAINED(0); unsigned int stat; @@ -82,7 +83,7 @@ netx_hif_demux_handler(unsigned int irq_unused, struct irqdesc *desc) while (stat) { if (stat & 1) { DEBUG_IRQ("handling irq %d\n", irq); - desc_handle_irq(irq, desc); + desc_handle_irq(irq, desc, regs); } irq++; desc++; diff --git a/trunk/arch/arm/mach-netx/time.c b/trunk/arch/arm/mach-netx/time.c index 0993336c0b55..6d72c81b7d9f 100644 --- a/trunk/arch/arm/mach-netx/time.c +++ b/trunk/arch/arm/mach-netx/time.c @@ -38,11 +38,11 @@ static unsigned long netx_gettimeoffset(void) * IRQ handler for the timer */ static irqreturn_t -netx_timer_interrupt(int irq, void *dev_id) +netx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { write_seqlock(&xtime_lock); - timer_tick(); + timer_tick(regs); write_sequnlock(&xtime_lock); /* acknowledge interrupt */ diff --git a/trunk/arch/arm/mach-omap1/board-osk.c b/trunk/arch/arm/mach-omap1/board-osk.c index 3a622801d7b0..6b05647a6c01 100644 --- a/trunk/arch/arm/mach-omap1/board-osk.c +++ b/trunk/arch/arm/mach-omap1/board-osk.c @@ -327,7 +327,7 @@ static struct spi_board_info __initdata mistral_boardinfo[] = { { #ifdef CONFIG_PM static irqreturn_t -osk_mistral_wake_interrupt(int irq, void *ignored) +osk_mistral_wake_interrupt(int irq, void *ignored, struct pt_regs *regs) { return IRQ_HANDLED; } diff --git a/trunk/arch/arm/mach-omap1/fpga.c b/trunk/arch/arm/mach-omap1/fpga.c index 8e40208b10bb..efe9bfc6e55f 100644 --- a/trunk/arch/arm/mach-omap1/fpga.c +++ b/trunk/arch/arm/mach-omap1/fpga.c @@ -84,7 +84,8 @@ static void fpga_mask_ack_irq(unsigned int irq) fpga_ack_irq(irq); } -void innovator_fpga_IRQ_demux(unsigned int irq, struct irqdesc *desc) +void innovator_fpga_IRQ_demux(unsigned int irq, struct irqdesc *desc, + struct pt_regs *regs) { struct irqdesc *d; u32 stat; @@ -100,7 +101,7 @@ void innovator_fpga_IRQ_demux(unsigned int irq, struct irqdesc *desc) fpga_irq++, stat >>= 1) { if (stat & 1) { d = irq_desc + fpga_irq; - desc_handle_irq(fpga_irq, d); + desc_handle_irq(fpga_irq, d, regs); } } } diff --git a/trunk/arch/arm/mach-omap1/pm.c b/trunk/arch/arm/mach-omap1/pm.c index 4834758d340c..cd76185bab74 100644 --- a/trunk/arch/arm/mach-omap1/pm.c +++ b/trunk/arch/arm/mach-omap1/pm.c @@ -682,7 +682,8 @@ static int omap_pm_finish(suspend_state_t state) } -static irqreturn_t omap_wakeup_interrupt(int irq, void *dev) +static irqreturn_t omap_wakeup_interrupt(int irq, void * dev, + struct pt_regs * regs) { return IRQ_HANDLED; } diff --git a/trunk/arch/arm/mach-omap1/serial.c b/trunk/arch/arm/mach-omap1/serial.c index 4cc98a578e4b..c4b790217a5b 100644 --- a/trunk/arch/arm/mach-omap1/serial.c +++ b/trunk/arch/arm/mach-omap1/serial.c @@ -204,7 +204,8 @@ void __init omap_serial_init(void) #ifdef CONFIG_OMAP_SERIAL_WAKE -static irqreturn_t omap_serial_wake_interrupt(int irq, void *dev_id) +static irqreturn_t omap_serial_wake_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { /* Need to do something with serial port right after wake-up? */ return IRQ_HANDLED; diff --git a/trunk/arch/arm/mach-omap1/time.c b/trunk/arch/arm/mach-omap1/time.c index 1b7e4a506c26..4d91b9f51084 100644 --- a/trunk/arch/arm/mach-omap1/time.c +++ b/trunk/arch/arm/mach-omap1/time.c @@ -160,7 +160,8 @@ static unsigned long omap_mpu_timer_gettimeoffset(void) * Latency during the interrupt is calculated using timer1. * Both timer0 and timer1 are counting at 6MHz (P2 6.5MHz). */ -static irqreturn_t omap_mpu_timer_interrupt(int irq, void *dev_id) +static irqreturn_t omap_mpu_timer_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { unsigned long now, latency; @@ -168,7 +169,7 @@ static irqreturn_t omap_mpu_timer_interrupt(int irq, void *dev_id) now = 0 - omap_mpu_timer_read(0); latency = MPU_TICKS_PER_SEC / HZ - omap_mpu_timer_read(1); omap_mpu_timer_last = now - latency; - timer_tick(); + timer_tick(regs); write_sequnlock(&xtime_lock); return IRQ_HANDLED; @@ -181,7 +182,8 @@ static struct irqaction omap_mpu_timer_irq = { }; static unsigned long omap_mpu_timer1_overflows; -static irqreturn_t omap_mpu_timer1_interrupt(int irq, void *dev_id) +static irqreturn_t omap_mpu_timer1_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { omap_mpu_timer1_overflows++; return IRQ_HANDLED; diff --git a/trunk/arch/arm/mach-omap2/board-apollon.c b/trunk/arch/arm/mach-omap2/board-apollon.c index 03d6905ba490..c37b0e6d1248 100644 --- a/trunk/arch/arm/mach-omap2/board-apollon.c +++ b/trunk/arch/arm/mach-omap2/board-apollon.c @@ -203,7 +203,7 @@ static void __init apollon_led_init(void) omap_set_gpio_dataout(LED2_GPIO15, 0); } -static irqreturn_t apollon_sw_interrupt(int irq, void *ignored) +static irqreturn_t apollon_sw_interrupt(int irq, void *ignored, struct pt_regs *regs) { static unsigned int led0, led1, led2; diff --git a/trunk/arch/arm/mach-omap2/timer-gp.c b/trunk/arch/arm/mach-omap2/timer-gp.c index 973189cd9766..fe5fd6d42dea 100644 --- a/trunk/arch/arm/mach-omap2/timer-gp.c +++ b/trunk/arch/arm/mach-omap2/timer-gp.c @@ -37,12 +37,13 @@ static inline void omap2_gp_timer_start(unsigned long load_val) omap_dm_timer_start(gptimer); } -static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id) +static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { write_seqlock(&xtime_lock); omap_dm_timer_write_status(gptimer, OMAP_TIMER_INT_OVERFLOW); - timer_tick(); + timer_tick(regs); write_sequnlock(&xtime_lock); diff --git a/trunk/arch/arm/mach-pnx4008/core.c b/trunk/arch/arm/mach-pnx4008/core.c index 429c796938be..3d73c1e93752 100644 --- a/trunk/arch/arm/mach-pnx4008/core.c +++ b/trunk/arch/arm/mach-pnx4008/core.c @@ -133,79 +133,10 @@ static struct platform_device serial_device = { }, }; -static struct platform_device nand_flash_device = { - .name = "pnx4008-flash", - .id = -1, - .dev = { - .coherent_dma_mask = 0xFFFFFFFF, - }, -}; - -/* The dmamask must be set for OHCI to work */ -static u64 ohci_dmamask = ~(u32) 0; - -static struct resource ohci_resources[] = { - { - .start = IO_ADDRESS(PNX4008_USB_CONFIG_BASE), - .end = IO_ADDRESS(PNX4008_USB_CONFIG_BASE + 0x100), - .flags = IORESOURCE_MEM, - }, { - .start = USB_HOST_INT, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device ohci_device = { - .name = "pnx4008-usb-ohci", - .id = -1, - .dev = { - .dma_mask = &ohci_dmamask, - .coherent_dma_mask = 0xffffffff, - }, - .num_resources = ARRAY_SIZE(ohci_resources), - .resource = ohci_resources, -}; - -static struct platform_device sdum_device = { - .name = "pnx4008-sdum", - .id = 0, - .dev = { - .coherent_dma_mask = 0xffffffff, - }, -}; - -static struct platform_device rgbfb_device = { - .name = "pnx4008-rgbfb", - .id = 0, - .dev = { - .coherent_dma_mask = 0xffffffff, - } -}; - -struct resource watchdog_resources[] = { - { - .start = PNX4008_WDOG_BASE, - .end = PNX4008_WDOG_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device watchdog_device = { - .name = "pnx4008-watchdog", - .id = -1, - .num_resources = ARRAY_SIZE(watchdog_resources), - .resource = watchdog_resources, -}; - static struct platform_device *devices[] __initdata = { &spipnx_1, &spipnx_2, &serial_device, - &ohci_device, - &nand_flash_device, - &sdum_device, - &rgbfb_device, - &watchdog_device, }; diff --git a/trunk/arch/arm/mach-pnx4008/dma.c b/trunk/arch/arm/mach-pnx4008/dma.c index d6a279e4b524..ec01574f88ac 100644 --- a/trunk/arch/arm/mach-pnx4008/dma.c +++ b/trunk/arch/arm/mach-pnx4008/dma.c @@ -32,7 +32,7 @@ static struct dma_channel { char *name; - void (*irq_handler) (int, int, void *); + void (*irq_handler) (int, int, void *, struct pt_regs *); void *data; struct pnx4008_dma_ll *ll; u32 ll_dma; @@ -150,7 +150,8 @@ static inline void pnx4008_dma_unlock(void) #define VALID_CHANNEL(c) (((c) >= 0) && ((c) < MAX_DMA_CHANNELS)) int pnx4008_request_channel(char *name, int ch, - void (*irq_handler) (int, int, void *), void *data) + void (*irq_handler) (int, int, void *, + struct pt_regs *), void *data) { int i, found = 0; @@ -1032,7 +1033,7 @@ int pnx4008_dma_ch_enabled(int ch) EXPORT_SYMBOL_GPL(pnx4008_dma_ch_enabled); -static irqreturn_t dma_irq_handler(int irq, void *dev_id) +static irqreturn_t dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs) { int i; unsigned long dint = __raw_readl(DMAC_INT_STAT); @@ -1052,7 +1053,8 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id) cause |= DMA_ERR_INT; if (tcint & i_bit) cause |= DMA_TC_INT; - channel->irq_handler(i, cause, channel->data); + channel->irq_handler(i, cause, channel->data, + regs); } else { /* * IRQ for an unregistered DMA channel diff --git a/trunk/arch/arm/mach-pnx4008/time.c b/trunk/arch/arm/mach-pnx4008/time.c index 8621c206ac84..b986065cd0f3 100644 --- a/trunk/arch/arm/mach-pnx4008/time.c +++ b/trunk/arch/arm/mach-pnx4008/time.c @@ -47,14 +47,15 @@ static unsigned long pnx4008_gettimeoffset(void) /*! * IRQ handler for the timer */ -static irqreturn_t pnx4008_timer_interrupt(int irq, void *dev_id) +static irqreturn_t pnx4008_timer_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { if (__raw_readl(HSTIM_INT) & MATCH0_INT) { write_seqlock(&xtime_lock); do { - timer_tick(); + timer_tick(regs); /* * this algorithm takes care of possible delay diff --git a/trunk/arch/arm/mach-pxa/corgi.c b/trunk/arch/arm/mach-pxa/corgi.c index a1a900d16665..337c01c4ac37 100644 --- a/trunk/arch/arm/mach-pxa/corgi.c +++ b/trunk/arch/arm/mach-pxa/corgi.c @@ -212,7 +212,7 @@ static struct platform_device corgits_device = { */ static struct pxamci_platform_data corgi_mci_platform_data; -static int corgi_mci_init(struct device *dev, irq_handler_t corgi_detect_int, void *data) +static int corgi_mci_init(struct device *dev, irqreturn_t (*corgi_detect_int)(int, void *, struct pt_regs *), void *data) { int err; diff --git a/trunk/arch/arm/mach-pxa/dma.c b/trunk/arch/arm/mach-pxa/dma.c index 4440babe7b97..7d8c85486c66 100644 --- a/trunk/arch/arm/mach-pxa/dma.c +++ b/trunk/arch/arm/mach-pxa/dma.c @@ -27,13 +27,13 @@ static struct dma_channel { char *name; - void (*irq_handler)(int, void *); + void (*irq_handler)(int, void *, struct pt_regs *); void *data; } dma_channels[PXA_DMA_CHANNELS]; int pxa_request_dma (char *name, pxa_dma_prio prio, - void (*irq_handler)(int, void *), + void (*irq_handler)(int, void *, struct pt_regs *), void *data) { unsigned long flags; @@ -87,7 +87,7 @@ void pxa_free_dma (int dma_ch) local_irq_restore(flags); } -static irqreturn_t dma_irq_handler(int irq, void *dev_id) +static irqreturn_t dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs) { int i, dint = DINT; @@ -95,7 +95,7 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id) if (dint & (1 << i)) { struct dma_channel *channel = &dma_channels[i]; if (channel->name && channel->irq_handler) { - channel->irq_handler(i, channel->data); + channel->irq_handler(i, channel->data, regs); } else { /* * IRQ for an unregistered DMA channel: diff --git a/trunk/arch/arm/mach-pxa/idp.c b/trunk/arch/arm/mach-pxa/idp.c index 64df44043a65..3e4b0ab71c66 100644 --- a/trunk/arch/arm/mach-pxa/idp.c +++ b/trunk/arch/arm/mach-pxa/idp.c @@ -125,7 +125,7 @@ static struct pxafb_mach_info sharp_lm8v31 = { .pxafb_lcd_power = &idp_lcd_power }; -static int idp_mci_init(struct device *dev, irq_handler_t idp_detect_int, void *data) +static int idp_mci_init(struct device *dev, irqreturn_t (*idp_detect_int)(int, void *, struct pt_regs *), void *data) { /* setup GPIO for PXA25x MMC controller */ pxa_gpio_mode(GPIO6_MMCCLK_MD); diff --git a/trunk/arch/arm/mach-pxa/irq.c b/trunk/arch/arm/mach-pxa/irq.c index ab1a16025d51..12141e2a50cc 100644 --- a/trunk/arch/arm/mach-pxa/irq.c +++ b/trunk/arch/arm/mach-pxa/irq.c @@ -143,7 +143,8 @@ static struct irq_chip pxa_low_gpio_chip = { * Demux handler for GPIO>=2 edge detect interrupts */ -static void pxa_gpio_demux_handler(unsigned int irq, struct irqdesc *desc) +static void pxa_gpio_demux_handler(unsigned int irq, struct irqdesc *desc, + struct pt_regs *regs) { unsigned int mask; int loop; @@ -159,7 +160,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irqdesc *desc) mask >>= 2; do { if (mask & 1) - desc_handle_irq(irq, desc); + desc_handle_irq(irq, desc, regs); irq++; desc++; mask >>= 1; @@ -174,7 +175,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irqdesc *desc) desc = irq_desc + irq; do { if (mask & 1) - desc_handle_irq(irq, desc); + desc_handle_irq(irq, desc, regs); irq++; desc++; mask >>= 1; @@ -189,7 +190,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irqdesc *desc) desc = irq_desc + irq; do { if (mask & 1) - desc_handle_irq(irq, desc); + desc_handle_irq(irq, desc, regs); irq++; desc++; mask >>= 1; @@ -205,7 +206,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irqdesc *desc) desc = irq_desc + irq; do { if (mask & 1) - desc_handle_irq(irq, desc); + desc_handle_irq(irq, desc, regs); irq++; desc++; mask >>= 1; diff --git a/trunk/arch/arm/mach-pxa/lpd270.c b/trunk/arch/arm/mach-pxa/lpd270.c index 5749f6b72e12..eff2a91b2565 100644 --- a/trunk/arch/arm/mach-pxa/lpd270.c +++ b/trunk/arch/arm/mach-pxa/lpd270.c @@ -75,7 +75,8 @@ static struct irq_chip lpd270_irq_chip = { .unmask = lpd270_unmask_irq, }; -static void lpd270_irq_handler(unsigned int irq, struct irqdesc *desc) +static void lpd270_irq_handler(unsigned int irq, struct irqdesc *desc, + struct pt_regs *regs) { unsigned long pending; @@ -85,7 +86,7 @@ static void lpd270_irq_handler(unsigned int irq, struct irqdesc *desc) if (likely(pending)) { irq = LPD270_IRQ(0) + __ffs(pending); desc = irq_desc + irq; - desc_handle_irq(irq, desc); + desc_handle_irq(irq, desc, regs); pending = __raw_readw(LPD270_INT_STATUS) & lpd270_irq_enabled; diff --git a/trunk/arch/arm/mach-pxa/lubbock.c b/trunk/arch/arm/mach-pxa/lubbock.c index 142c33c3dff5..157cf47cbe66 100644 --- a/trunk/arch/arm/mach-pxa/lubbock.c +++ b/trunk/arch/arm/mach-pxa/lubbock.c @@ -85,7 +85,8 @@ static struct irq_chip lubbock_irq_chip = { .unmask = lubbock_unmask_irq, }; -static void lubbock_irq_handler(unsigned int irq, struct irqdesc *desc) +static void lubbock_irq_handler(unsigned int irq, struct irqdesc *desc, + struct pt_regs *regs) { unsigned long pending = LUB_IRQ_SET_CLR & lubbock_irq_enabled; do { @@ -93,7 +94,7 @@ static void lubbock_irq_handler(unsigned int irq, struct irqdesc *desc) if (likely(pending)) { irq = LUBBOCK_IRQ(0) + __ffs(pending); desc = irq_desc + irq; - desc_handle_irq(irq, desc); + desc_handle_irq(irq, desc, regs); } pending = LUB_IRQ_SET_CLR & lubbock_irq_enabled; } while (pending); @@ -378,7 +379,7 @@ static struct pxafb_mach_info sharp_lm8v31 = { #define MMC_POLL_RATE msecs_to_jiffies(1000) static void lubbock_mmc_poll(unsigned long); -static irq_handler_t mmc_detect_int; +static irqreturn_t (*mmc_detect_int)(int, void *, struct pt_regs *); static struct timer_list mmc_timer = { .function = lubbock_mmc_poll, @@ -397,22 +398,22 @@ static void lubbock_mmc_poll(unsigned long data) if (LUB_IRQ_SET_CLR & (1 << 0)) mod_timer(&mmc_timer, jiffies + MMC_POLL_RATE); else { - (void) mmc_detect_int(LUBBOCK_SD_IRQ, (void *)data); + (void) mmc_detect_int(LUBBOCK_SD_IRQ, (void *)data, NULL); enable_irq(LUBBOCK_SD_IRQ); } } -static irqreturn_t lubbock_detect_int(int irq, void *data) +static irqreturn_t lubbock_detect_int(int irq, void *data, struct pt_regs *regs) { /* IRQ is level triggered; disable, and poll for removal */ disable_irq(irq); mod_timer(&mmc_timer, jiffies + MMC_POLL_RATE); - return mmc_detect_int(irq, data); + return mmc_detect_int(irq, data, regs); } static int lubbock_mci_init(struct device *dev, - irq_handler_t detect_int, + irqreturn_t (*detect_int)(int, void *, struct pt_regs *), void *data) { /* setup GPIO for PXA25x MMC controller */ diff --git a/trunk/arch/arm/mach-pxa/mainstone.c b/trunk/arch/arm/mach-pxa/mainstone.c index 49c34d94a9fe..7ba0447d6fa3 100644 --- a/trunk/arch/arm/mach-pxa/mainstone.c +++ b/trunk/arch/arm/mach-pxa/mainstone.c @@ -71,7 +71,8 @@ static struct irq_chip mainstone_irq_chip = { .unmask = mainstone_unmask_irq, }; -static void mainstone_irq_handler(unsigned int irq, struct irqdesc *desc) +static void mainstone_irq_handler(unsigned int irq, struct irqdesc *desc, + struct pt_regs *regs) { unsigned long pending = MST_INTSETCLR & mainstone_irq_enabled; do { @@ -79,7 +80,7 @@ static void mainstone_irq_handler(unsigned int irq, struct irqdesc *desc) if (likely(pending)) { irq = MAINSTONE_IRQ(0) + __ffs(pending); desc = irq_desc + irq; - desc_handle_irq(irq, desc); + desc_handle_irq(irq, desc, regs); } pending = MST_INTSETCLR & mainstone_irq_enabled; } while (pending); @@ -313,7 +314,7 @@ static struct pxafb_mach_info mainstone_pxafb_info = { .pxafb_backlight_power = mainstone_backlight_power, }; -static int mainstone_mci_init(struct device *dev, irq_handler_t mstone_detect_int, void *data) +static int mainstone_mci_init(struct device *dev, irqreturn_t (*mstone_detect_int)(int, void *, struct pt_regs *), void *data) { int err; diff --git a/trunk/arch/arm/mach-pxa/poodle.c b/trunk/arch/arm/mach-pxa/poodle.c index 34fb80b37023..5e8c098ca139 100644 --- a/trunk/arch/arm/mach-pxa/poodle.c +++ b/trunk/arch/arm/mach-pxa/poodle.c @@ -197,7 +197,7 @@ static struct platform_device poodle_ts_device = { */ static struct pxamci_platform_data poodle_mci_platform_data; -static int poodle_mci_init(struct device *dev, irq_handler_t poodle_detect_int, void *data) +static int poodle_mci_init(struct device *dev, irqreturn_t (*poodle_detect_int)(int, void *, struct pt_regs *), void *data) { int err; diff --git a/trunk/arch/arm/mach-pxa/spitz.c b/trunk/arch/arm/mach-pxa/spitz.c index 3cbac63bed3c..401cdb850fbc 100644 --- a/trunk/arch/arm/mach-pxa/spitz.c +++ b/trunk/arch/arm/mach-pxa/spitz.c @@ -291,7 +291,7 @@ static struct platform_device spitzts_device = { static struct pxamci_platform_data spitz_mci_platform_data; -static int spitz_mci_init(struct device *dev, irq_handler_t spitz_detect_int, void *data) +static int spitz_mci_init(struct device *dev, irqreturn_t (*spitz_detect_int)(int, void *, struct pt_regs *), void *data) { int err; diff --git a/trunk/arch/arm/mach-pxa/ssp.c b/trunk/arch/arm/mach-pxa/ssp.c index 6cc202755fb4..1fddfeaa630d 100644 --- a/trunk/arch/arm/mach-pxa/ssp.c +++ b/trunk/arch/arm/mach-pxa/ssp.c @@ -65,7 +65,7 @@ static const struct ssp_info_ ssp_info[PXA_SSP_PORTS] = { static DEFINE_MUTEX(mutex); static int use_count[PXA_SSP_PORTS] = {0, 0, 0}; -static irqreturn_t ssp_interrupt(int irq, void *dev_id) +static irqreturn_t ssp_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct ssp_dev *dev = (struct ssp_dev*) dev_id; unsigned int status = SSSR_P(dev->port); diff --git a/trunk/arch/arm/mach-pxa/time.c b/trunk/arch/arm/mach-pxa/time.c index 3ac268fa419b..5dbd191c57c4 100644 --- a/trunk/arch/arm/mach-pxa/time.c +++ b/trunk/arch/arm/mach-pxa/time.c @@ -75,7 +75,7 @@ static int match_posponed; #endif static irqreturn_t -pxa_timer_interrupt(int irq, void *dev_id) +pxa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { int next_match; @@ -105,7 +105,7 @@ pxa_timer_interrupt(int irq, void *dev_id) * exactly one tick period which should be a pretty rare event. */ do { - timer_tick(); + timer_tick(regs); OSSR = OSSR_M0; /* Clear match on timer 0 */ next_match = (OSMR0 += LATCH); } while( (signed long)(next_match - OSCR) <= 8 ); @@ -157,13 +157,13 @@ static void pxa_dyn_tick_reprogram(unsigned long ticks) } static irqreturn_t -pxa_dyn_tick_handler(int irq, void *dev_id) +pxa_dyn_tick_handler(int irq, void *dev_id, struct pt_regs *regs) { if (match_posponed) { match_posponed = 0; OSMR0 = initial_match; if ( (signed long)(initial_match - OSCR) <= 8 ) - return pxa_timer_interrupt(irq, dev_id); + return pxa_timer_interrupt(irq, dev_id, regs); } return IRQ_NONE; } diff --git a/trunk/arch/arm/mach-pxa/tosa.c b/trunk/arch/arm/mach-pxa/tosa.c index 7915a5a22865..249353616aba 100644 --- a/trunk/arch/arm/mach-pxa/tosa.c +++ b/trunk/arch/arm/mach-pxa/tosa.c @@ -174,7 +174,7 @@ static struct pxa2xx_udc_mach_info udc_info __initdata = { */ static struct pxamci_platform_data tosa_mci_platform_data; -static int tosa_mci_init(struct device *dev, irq_handler_t tosa_detect_int, void *data) +static int tosa_mci_init(struct device *dev, irqreturn_t (*tosa_detect_int)(int, void *, struct pt_regs *), void *data) { int err; diff --git a/trunk/arch/arm/mach-pxa/trizeps4.c b/trunk/arch/arm/mach-pxa/trizeps4.c index c1827d021ba8..910571e9a190 100644 --- a/trunk/arch/arm/mach-pxa/trizeps4.c +++ b/trunk/arch/arm/mach-pxa/trizeps4.c @@ -270,7 +270,7 @@ void board_pcmcia_power(int power) {;} #endif /* CONFIG_MACH_TRIZEPS4_CONXS */ EXPORT_SYMBOL(board_pcmcia_power); -static int trizeps4_mci_init(struct device *dev, irq_handler_t mci_detect_int, void *data) +static int trizeps4_mci_init(struct device *dev, irqreturn_t (*mci_detect_int)(int, void *, struct pt_regs *), void *data) { int err; /* setup GPIO for PXA27x MMC controller */ diff --git a/trunk/arch/arm/mach-realview/core.c b/trunk/arch/arm/mach-realview/core.c index 68c67053f479..da0286973823 100644 --- a/trunk/arch/arm/mach-realview/core.c +++ b/trunk/arch/arm/mach-realview/core.c @@ -515,18 +515,18 @@ static unsigned long realview_gettimeoffset(void) /* * IRQ handler for the timer */ -static irqreturn_t realview_timer_interrupt(int irq, void *dev_id) +static irqreturn_t realview_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { write_seqlock(&xtime_lock); // ...clear the interrupt writel(1, TIMER0_VA_BASE + TIMER_INTCLR); - timer_tick(); + timer_tick(regs); #if defined(CONFIG_SMP) && !defined(CONFIG_LOCAL_TIMERS) smp_send_timer(); - update_process_times(user_mode(get_irq_regs())); + update_process_times(user_mode(regs)); #endif write_sequnlock(&xtime_lock); diff --git a/trunk/arch/arm/mach-rpc/dma.c b/trunk/arch/arm/mach-rpc/dma.c index 596379a4cf82..ac511d41d4d7 100644 --- a/trunk/arch/arm/mach-rpc/dma.c +++ b/trunk/arch/arm/mach-rpc/dma.c @@ -83,7 +83,7 @@ static void iomd_get_next_sg(struct scatterlist *sg, dma_t *dma) sg->length |= flags; } -static irqreturn_t iomd_dma_handle(int irq, void *dev_id) +static irqreturn_t iomd_dma_handle(int irq, void *dev_id, struct pt_regs *regs) { dma_t *dma = (dma_t *)dev_id; unsigned long base = dma->dma_base; diff --git a/trunk/arch/arm/mach-s3c2410/Kconfig b/trunk/arch/arm/mach-s3c2410/Kconfig index 9aa26b99045d..63965c78de8c 100644 --- a/trunk/arch/arm/mach-s3c2410/Kconfig +++ b/trunk/arch/arm/mach-s3c2410/Kconfig @@ -91,7 +91,7 @@ config SMDK2440_CPU2442 config MACH_S3C2413 bool help - Internal node for S3C2413 version of SMDK2413, so that + Internal node for S3C2413 verison of SMDK2413, so that machine_is_s3c2413() will work when MACH_SMDK2413 is selected diff --git a/trunk/arch/arm/mach-s3c2410/bast-irq.c b/trunk/arch/arm/mach-s3c2410/bast-irq.c index 23d5beea5568..440e9aa0211a 100644 --- a/trunk/arch/arm/mach-s3c2410/bast-irq.c +++ b/trunk/arch/arm/mach-s3c2410/bast-irq.c @@ -112,7 +112,8 @@ static struct irqchip bast_pc104_chip = { static void bast_irq_pc104_demux(unsigned int irq, - struct irqdesc *desc) + struct irqdesc *desc, + struct pt_regs *regs) { unsigned int stat; unsigned int irqno; @@ -132,7 +133,7 @@ bast_irq_pc104_demux(unsigned int irq, if (stat & 1) { irqno = bast_pc104_irqs[i]; desc = irq_desc + irqno; - desc_handle_irq(irqno, desc); + desc_handle_irq(irqno, desc, regs); } } } diff --git a/trunk/arch/arm/mach-s3c2410/dma.c b/trunk/arch/arm/mach-s3c2410/dma.c index 3d211dc2f2f9..d264bbbd8bef 100644 --- a/trunk/arch/arm/mach-s3c2410/dma.c +++ b/trunk/arch/arm/mach-s3c2410/dma.c @@ -595,7 +595,7 @@ s3c2410_dma_lastxfer(struct s3c2410_dma_chan *chan) #define dmadbg2(x...) static irqreturn_t -s3c2410_dma_irq(int irq, void *devpw) +s3c2410_dma_irq(int irq, void *devpw, struct pt_regs *regs) { struct s3c2410_dma_chan *chan = (struct s3c2410_dma_chan *)devpw; struct s3c2410_dma_buf *buf; diff --git a/trunk/arch/arm/mach-s3c2410/gpio.c b/trunk/arch/arm/mach-s3c2410/gpio.c index ba346546150b..db6393c99860 100644 --- a/trunk/arch/arm/mach-s3c2410/gpio.c +++ b/trunk/arch/arm/mach-s3c2410/gpio.c @@ -3,7 +3,7 @@ * Copyright (c) 2004-2005 Simtec Electronics * Ben Dooks * - * S3C24XX GPIO support + * S3C2410 GPIO support * * 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 @@ -163,22 +163,3 @@ unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change) } EXPORT_SYMBOL(s3c2410_modify_misccr); - -int s3c2410_gpio_getirq(unsigned int pin) -{ - if (pin < S3C2410_GPF0 || pin > S3C2410_GPG15) - return -1; /* not valid interrupts */ - - if (pin < S3C2410_GPG0 && pin > S3C2410_GPF7) - return -1; /* not valid pin */ - - if (pin < S3C2410_GPF4) - return (pin - S3C2410_GPF0) + IRQ_EINT0; - - if (pin < S3C2410_GPG0) - return (pin - S3C2410_GPF4) + IRQ_EINT4; - - return (pin - S3C2410_GPG0) + IRQ_EINT8; -} - -EXPORT_SYMBOL(s3c2410_gpio_getirq); diff --git a/trunk/arch/arm/mach-s3c2410/irq.c b/trunk/arch/arm/mach-s3c2410/irq.c index 683b3491ba3c..3e9f3462c61b 100644 --- a/trunk/arch/arm/mach-s3c2410/irq.c +++ b/trunk/arch/arm/mach-s3c2410/irq.c @@ -480,7 +480,8 @@ static struct irqchip s3c_irq_adc = { /* irq demux for adc */ static void s3c_irq_demux_adc(unsigned int irq, - struct irqdesc *desc) + struct irqdesc *desc, + struct pt_regs *regs) { unsigned int subsrc, submsk; unsigned int offset = 9; @@ -499,16 +500,17 @@ static void s3c_irq_demux_adc(unsigned int irq, if (subsrc != 0) { if (subsrc & 1) { mydesc = irq_desc + IRQ_TC; - desc_handle_irq(IRQ_TC, mydesc); + desc_handle_irq(IRQ_TC, mydesc, regs); } if (subsrc & 2) { mydesc = irq_desc + IRQ_ADC; - desc_handle_irq(IRQ_ADC, mydesc); + desc_handle_irq(IRQ_ADC, mydesc, regs); } } } -static void s3c_irq_demux_uart(unsigned int start) +static void s3c_irq_demux_uart(unsigned int start, + struct pt_regs *regs) { unsigned int subsrc, submsk; unsigned int offset = start - IRQ_S3CUART_RX0; @@ -531,17 +533,17 @@ static void s3c_irq_demux_uart(unsigned int start) desc = irq_desc + start; if (subsrc & 1) - desc_handle_irq(start, desc); + desc_handle_irq(start, desc, regs); desc++; if (subsrc & 2) - desc_handle_irq(start+1, desc); + desc_handle_irq(start+1, desc, regs); desc++; if (subsrc & 4) - desc_handle_irq(start+2, desc); + desc_handle_irq(start+2, desc, regs); } } @@ -549,31 +551,35 @@ static void s3c_irq_demux_uart(unsigned int start) static void s3c_irq_demux_uart0(unsigned int irq, - struct irqdesc *desc) + struct irqdesc *desc, + struct pt_regs *regs) { irq = irq; - s3c_irq_demux_uart(IRQ_S3CUART_RX0); + s3c_irq_demux_uart(IRQ_S3CUART_RX0, regs); } static void s3c_irq_demux_uart1(unsigned int irq, - struct irqdesc *desc) + struct irqdesc *desc, + struct pt_regs *regs) { irq = irq; - s3c_irq_demux_uart(IRQ_S3CUART_RX1); + s3c_irq_demux_uart(IRQ_S3CUART_RX1, regs); } static void s3c_irq_demux_uart2(unsigned int irq, - struct irqdesc *desc) + struct irqdesc *desc, + struct pt_regs *regs) { irq = irq; - s3c_irq_demux_uart(IRQ_S3CUART_RX2); + s3c_irq_demux_uart(IRQ_S3CUART_RX2, regs); } static void s3c_irq_demux_extint8(unsigned int irq, - struct irqdesc *desc) + struct irqdesc *desc, + struct pt_regs *regs) { unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND); unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK); @@ -588,14 +594,15 @@ s3c_irq_demux_extint8(unsigned int irq, eintpnd &= ~(1< S3C2410_GPG15) + return -1; /* not valid interrupts */ + + if (pin < S3C2410_GPG0 && pin > S3C2410_GPF7) + return -1; /* not valid pin */ + + if (pin < S3C2410_GPF4) + return (pin - S3C2410_GPF0) + IRQ_EINT0; + + if (pin < S3C2410_GPG0) + return (pin - S3C2410_GPF4) + IRQ_EINT4; + + return (pin - S3C2410_GPG0) + IRQ_EINT8; +} + +EXPORT_SYMBOL(s3c2410_gpio_getirq); diff --git a/trunk/arch/arm/mach-s3c2410/s3c2440-irq.c b/trunk/arch/arm/mach-s3c2410/s3c2440-irq.c index 39db0752d53b..fc08febe2e54 100644 --- a/trunk/arch/arm/mach-s3c2410/s3c2440-irq.c +++ b/trunk/arch/arm/mach-s3c2410/s3c2440-irq.c @@ -42,7 +42,8 @@ /* WDT/AC97 */ static void s3c_irq_demux_wdtac97(unsigned int irq, - struct irqdesc *desc) + struct irqdesc *desc, + struct pt_regs *regs) { unsigned int subsrc, submsk; struct irqdesc *mydesc; @@ -60,11 +61,11 @@ static void s3c_irq_demux_wdtac97(unsigned int irq, if (subsrc != 0) { if (subsrc & 1) { mydesc = irq_desc + IRQ_S3C2440_WDT; - desc_handle_irq(IRQ_S3C2440_WDT, mydesc); + desc_handle_irq(IRQ_S3C2440_WDT, mydesc, regs); } if (subsrc & 2) { mydesc = irq_desc + IRQ_S3C2440_AC97; - desc_handle_irq(IRQ_S3C2440_AC97, mydesc); + desc_handle_irq(IRQ_S3C2440_AC97, mydesc, regs); } } } diff --git a/trunk/arch/arm/mach-s3c2410/s3c244x-irq.c b/trunk/arch/arm/mach-s3c2410/s3c244x-irq.c index 146f2109dd90..ec702f88b299 100644 --- a/trunk/arch/arm/mach-s3c2410/s3c244x-irq.c +++ b/trunk/arch/arm/mach-s3c2410/s3c244x-irq.c @@ -42,7 +42,8 @@ /* camera irq */ static void s3c_irq_demux_cam(unsigned int irq, - struct irqdesc *desc) + struct irqdesc *desc, + struct pt_regs *regs) { unsigned int subsrc, submsk; struct irqdesc *mydesc; @@ -60,11 +61,11 @@ static void s3c_irq_demux_cam(unsigned int irq, if (subsrc != 0) { if (subsrc & 1) { mydesc = irq_desc + IRQ_S3C2440_CAM_C; - desc_handle_irq(IRQ_S3C2440_CAM_C, mydesc); + desc_handle_irq(IRQ_S3C2440_CAM_C, mydesc, regs); } if (subsrc & 2) { mydesc = irq_desc + IRQ_S3C2440_CAM_P; - desc_handle_irq(IRQ_S3C2440_CAM_P, mydesc); + desc_handle_irq(IRQ_S3C2440_CAM_P, mydesc, regs); } } } diff --git a/trunk/arch/arm/mach-s3c2410/time.c b/trunk/arch/arm/mach-s3c2410/time.c index 9910bf0f2cea..00d1cfca9712 100644 --- a/trunk/arch/arm/mach-s3c2410/time.c +++ b/trunk/arch/arm/mach-s3c2410/time.c @@ -128,10 +128,10 @@ static unsigned long s3c2410_gettimeoffset (void) * IRQ handler for the timer */ static irqreturn_t -s3c2410_timer_interrupt(int irq, void *dev_id) +s3c2410_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { write_seqlock(&xtime_lock); - timer_tick(); + timer_tick(regs); write_sequnlock(&xtime_lock); return IRQ_HANDLED; } diff --git a/trunk/arch/arm/mach-s3c2410/usb-simtec.c b/trunk/arch/arm/mach-s3c2410/usb-simtec.c index 22b0e1cdd4bf..c635efa7cd31 100644 --- a/trunk/arch/arm/mach-s3c2410/usb-simtec.c +++ b/trunk/arch/arm/mach-s3c2410/usb-simtec.c @@ -58,7 +58,7 @@ usb_simtec_powercontrol(int port, int to) } static irqreturn_t -usb_simtec_ocirq(int irq, void *pw) +usb_simtec_ocirq(int irq, void *pw, struct pt_regs *regs) { struct s3c2410_hcd_info *info = (struct s3c2410_hcd_info *)pw; diff --git a/trunk/arch/arm/mach-sa1100/cpu-sa1110.c b/trunk/arch/arm/mach-sa1100/cpu-sa1110.c index 78f4c1346044..639597729932 100644 --- a/trunk/arch/arm/mach-sa1100/cpu-sa1110.c +++ b/trunk/arch/arm/mach-sa1100/cpu-sa1110.c @@ -82,14 +82,6 @@ static struct sdram_params sdram_tbl[] __initdata = { .twr = 9, .refresh = 64000, .cas_latency = 3, - }, { /* Samsung K4S281632B-1H */ - .name = "K4S281632B-1H", - .rows = 12, - .tck = 10, - .trp = 20, - .twr = 10, - .refresh = 64000, - .cas_latency = 3, }, { /* Samsung KM416S4030CT */ .name = "KM416S4030CT", .rows = 13, @@ -374,8 +366,6 @@ static int __init sa1110_clk_init(void) if (machine_is_h3100()) name = "KM416S4030CT"; - if (machine_is_jornada720()) - name = "K4S281632B-1H"; } sdram = sa1110_find_sdram(name); diff --git a/trunk/arch/arm/mach-sa1100/dma.c b/trunk/arch/arm/mach-sa1100/dma.c index 1fbe053e8b59..2ea2a657a034 100644 --- a/trunk/arch/arm/mach-sa1100/dma.c +++ b/trunk/arch/arm/mach-sa1100/dma.c @@ -42,7 +42,7 @@ static sa1100_dma_t dma_chan[SA1100_DMA_CHANNELS]; static spinlock_t dma_list_lock; -static irqreturn_t dma_irq_handler(int irq, void *dev_id) +static irqreturn_t dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs) { dma_regs_t *dma_regs = dev_id; sa1100_dma_t *dma = dma_chan + (((u_int)dma_regs >> 5) & 7); diff --git a/trunk/arch/arm/mach-sa1100/h3600.c b/trunk/arch/arm/mach-sa1100/h3600.c index fa6dc71bd6ad..7364478cec12 100644 --- a/trunk/arch/arm/mach-sa1100/h3600.c +++ b/trunk/arch/arm/mach-sa1100/h3600.c @@ -702,7 +702,7 @@ static u32 gpio_irq_mask[] = { GPIO2_SD_CON_SLT, }; -static void h3800_IRQ_demux(unsigned int irq, struct irqdesc *desc) +static void h3800_IRQ_demux(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) { int i; @@ -719,14 +719,14 @@ static void h3800_IRQ_demux(unsigned int irq, struct irqdesc *desc) if (0) printk("%s KPIO 0x%08X\n", __FUNCTION__, irq); for (j = 0; j < H3800_KPIO_IRQ_COUNT; j++) if (irq & kpio_irq_mask[j]) - do_edge_IRQ(H3800_KPIO_IRQ_COUNT + j, irq_desc + H3800_KPIO_IRQ_COUNT + j); + do_edge_IRQ(H3800_KPIO_IRQ_COUNT + j, irq_desc + H3800_KPIO_IRQ_COUNT + j, regs); /* GPIO2 */ irq = H3800_ASIC2_GPIINTFLAG; if (0) printk("%s GPIO 0x%08X\n", __FUNCTION__, irq); for (j = 0; j < H3800_GPIO_IRQ_COUNT; j++) if (irq & gpio_irq_mask[j]) - do_edge_IRQ(H3800_GPIO_IRQ_COUNT + j, irq_desc + H3800_GPIO_IRQ_COUNT + j); + do_edge_IRQ(H3800_GPIO_IRQ_COUNT + j, irq_desc + H3800_GPIO_IRQ_COUNT + j , regs); } if (i >= MAX_ASIC_ISR_LOOPS) diff --git a/trunk/arch/arm/mach-sa1100/irq.c b/trunk/arch/arm/mach-sa1100/irq.c index f4c6322ca33e..b55b90a2e8fe 100644 --- a/trunk/arch/arm/mach-sa1100/irq.c +++ b/trunk/arch/arm/mach-sa1100/irq.c @@ -110,7 +110,8 @@ static struct irq_chip sa1100_low_gpio_chip = { * and call the handler. */ static void -sa1100_high_gpio_handler(unsigned int irq, struct irqdesc *desc) +sa1100_high_gpio_handler(unsigned int irq, struct irqdesc *desc, + struct pt_regs *regs) { unsigned int mask; @@ -127,7 +128,7 @@ sa1100_high_gpio_handler(unsigned int irq, struct irqdesc *desc) mask >>= 11; do { if (mask & 1) - desc_handle_irq(irq, desc); + desc_handle_irq(irq, desc, regs); mask >>= 1; irq++; desc++; diff --git a/trunk/arch/arm/mach-sa1100/neponset.c b/trunk/arch/arm/mach-sa1100/neponset.c index 354d5e91da59..af6d2775cf82 100644 --- a/trunk/arch/arm/mach-sa1100/neponset.c +++ b/trunk/arch/arm/mach-sa1100/neponset.c @@ -29,7 +29,7 @@ * is rather unfortunate. */ static void -neponset_irq_handler(unsigned int irq, struct irqdesc *desc) +neponset_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) { unsigned int irr; @@ -69,12 +69,12 @@ neponset_irq_handler(unsigned int irq, struct irqdesc *desc) if (irr & IRR_ETHERNET) { d = irq_desc + IRQ_NEPONSET_SMC9196; - desc_handle_irq(IRQ_NEPONSET_SMC9196, d); + desc_handle_irq(IRQ_NEPONSET_SMC9196, d, regs); } if (irr & IRR_USAR) { d = irq_desc + IRQ_NEPONSET_USAR; - desc_handle_irq(IRQ_NEPONSET_USAR, d); + desc_handle_irq(IRQ_NEPONSET_USAR, d, regs); } desc->chip->unmask(irq); @@ -82,7 +82,7 @@ neponset_irq_handler(unsigned int irq, struct irqdesc *desc) if (irr & IRR_SA1111) { d = irq_desc + IRQ_NEPONSET_SA1111; - desc_handle_irq(IRQ_NEPONSET_SA1111, d); + desc_handle_irq(IRQ_NEPONSET_SA1111, d, regs); } } } diff --git a/trunk/arch/arm/mach-sa1100/ssp.c b/trunk/arch/arm/mach-sa1100/ssp.c index 59703c6fb29b..5eba5fbbb561 100644 --- a/trunk/arch/arm/mach-sa1100/ssp.c +++ b/trunk/arch/arm/mach-sa1100/ssp.c @@ -25,7 +25,7 @@ #define TIMEOUT 100000 -static irqreturn_t ssp_interrupt(int irq, void *dev_id) +static irqreturn_t ssp_interrupt(int irq, void *dev_id, struct pt_regs *regs) { unsigned int status = Ser4SSSR; diff --git a/trunk/arch/arm/mach-sa1100/time.c b/trunk/arch/arm/mach-sa1100/time.c index 4284bd6f7a1f..49ae716e16c2 100644 --- a/trunk/arch/arm/mach-sa1100/time.c +++ b/trunk/arch/arm/mach-sa1100/time.c @@ -77,7 +77,7 @@ static int match_posponed; #endif static irqreturn_t -sa1100_timer_interrupt(int irq, void *dev_id) +sa1100_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { unsigned int next_match; @@ -99,7 +99,7 @@ sa1100_timer_interrupt(int irq, void *dev_id) * handlers. */ do { - timer_tick(); + timer_tick(regs); OSSR = OSSR_M0; /* Clear match on timer 0 */ next_match = (OSMR0 += LATCH); } while ((signed long)(next_match - OSCR) <= 0); @@ -151,13 +151,13 @@ static void sa1100_dyn_tick_reprogram(unsigned long ticks) } static irqreturn_t -sa1100_dyn_tick_handler(int irq, void *dev_id) +sa1100_dyn_tick_handler(int irq, void *dev_id, struct pt_regs *regs) { if (match_posponed) { match_posponed = 0; OSMR0 = initial_match; if ((signed long)(initial_match - OSCR) <= 0) - return sa1100_timer_interrupt(irq, dev_id); + return sa1100_timer_interrupt(irq, dev_id, regs); } return IRQ_NONE; } diff --git a/trunk/arch/arm/mach-shark/core.c b/trunk/arch/arm/mach-shark/core.c index 0e480fae8ec5..1095df34fec0 100644 --- a/trunk/arch/arm/mach-shark/core.c +++ b/trunk/arch/arm/mach-shark/core.c @@ -80,10 +80,10 @@ static void __init shark_map_io(void) #define HZ_TIME ((1193180 + HZ/2) / HZ) static irqreturn_t -shark_timer_interrupt(int irq, void *dev_id) +shark_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { write_seqlock(&xtime_lock); - timer_tick(); + timer_tick(regs); write_sequnlock(&xtime_lock); return IRQ_HANDLED; } diff --git a/trunk/arch/arm/mach-shark/irq.c b/trunk/arch/arm/mach-shark/irq.c index 297ecf130650..b227052296cf 100644 --- a/trunk/arch/arm/mach-shark/irq.c +++ b/trunk/arch/arm/mach-shark/irq.c @@ -61,7 +61,7 @@ static void shark_enable_8259A_irq(unsigned int irq) static void shark_ack_8259A_irq(unsigned int irq){} -static irqreturn_t bogus_int(int irq, void *dev_id) +static irqreturn_t bogus_int(int irq, void *dev_id, struct pt_regs *regs) { printk("Got interrupt %i!\n",irq); return IRQ_NONE; diff --git a/trunk/arch/arm/mach-versatile/core.c b/trunk/arch/arm/mach-versatile/core.c index 3b8576111c16..f2bbef07b1e4 100644 --- a/trunk/arch/arm/mach-versatile/core.c +++ b/trunk/arch/arm/mach-versatile/core.c @@ -77,12 +77,12 @@ static struct irq_chip sic_chip = { }; static void -sic_handle_irq(unsigned int irq, struct irqdesc *desc) +sic_handle_irq(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) { unsigned long status = readl(VA_SIC_BASE + SIC_IRQ_STATUS); if (status == 0) { - do_bad_IRQ(irq, desc); + do_bad_IRQ(irq, desc, regs); return; } @@ -93,7 +93,7 @@ sic_handle_irq(unsigned int irq, struct irqdesc *desc) irq += IRQ_SIC_START; desc = irq_desc + irq; - desc_handle_irq(irq, desc); + desc_handle_irq(irq, desc, regs); } while (status); } @@ -188,12 +188,12 @@ static struct map_desc versatile_io_desc[] __initdata = { .length = SZ_4K, .type = MT_DEVICE }, { - .virtual = (unsigned long)VERSATILE_PCI_VIRT_BASE, + .virtual = VERSATILE_PCI_VIRT_BASE, .pfn = __phys_to_pfn(VERSATILE_PCI_BASE), .length = VERSATILE_PCI_BASE_SIZE, .type = MT_DEVICE }, { - .virtual = (unsigned long)VERSATILE_PCI_CFG_VIRT_BASE, + .virtual = VERSATILE_PCI_CFG_VIRT_BASE, .pfn = __phys_to_pfn(VERSATILE_PCI_CFG_BASE), .length = VERSATILE_PCI_CFG_BASE_SIZE, .type = MT_DEVICE @@ -851,14 +851,14 @@ static unsigned long versatile_gettimeoffset(void) /* * IRQ handler for the timer */ -static irqreturn_t versatile_timer_interrupt(int irq, void *dev_id) +static irqreturn_t versatile_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { write_seqlock(&xtime_lock); // ...clear the interrupt writel(1, TIMER0_VA_BASE + TIMER_INTCLR); - timer_tick(); + timer_tick(regs); write_sequnlock(&xtime_lock); diff --git a/trunk/arch/arm/mach-versatile/pci.c b/trunk/arch/arm/mach-versatile/pci.c index 5cd0b5d9e7eb..13bbd08ff841 100644 --- a/trunk/arch/arm/mach-versatile/pci.c +++ b/trunk/arch/arm/mach-versatile/pci.c @@ -40,15 +40,14 @@ * Cfg 42000000 - 42FFFFFF PCI config * */ -#define __IO_ADDRESS(n) ((void __iomem *)(unsigned long)IO_ADDRESS(n)) -#define SYS_PCICTL __IO_ADDRESS(VERSATILE_SYS_PCICTL) -#define PCI_IMAP0 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x0) -#define PCI_IMAP1 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x4) -#define PCI_IMAP2 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x8) -#define PCI_SMAP0 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x10) -#define PCI_SMAP1 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x14) -#define PCI_SMAP2 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x18) -#define PCI_SELFID __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0xc) +#define SYS_PCICTL IO_ADDRESS(VERSATILE_SYS_PCICTL) +#define PCI_IMAP0 IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x0) +#define PCI_IMAP1 IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x4) +#define PCI_IMAP2 IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x8) +#define PCI_SMAP0 IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x10) +#define PCI_SMAP1 IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x14) +#define PCI_SMAP2 IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x18) +#define PCI_SELFID IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0xc) #define DEVICE_ID_OFFSET 0x00 #define CSR_OFFSET 0x04 @@ -77,7 +76,7 @@ static int __init versatile_pci_slot_ignore(char *str) __setup("pci_slot_ignore=", versatile_pci_slot_ignore); -static void __iomem *__pci_addr(struct pci_bus *bus, +static unsigned long __pci_addr(struct pci_bus *bus, unsigned int devfn, int offset) { unsigned int busnr = bus->number; @@ -92,14 +91,14 @@ static void __iomem *__pci_addr(struct pci_bus *bus, if (devfn > 255) BUG(); - return VERSATILE_PCI_CFG_VIRT_BASE + ((busnr << 16) | + return (VERSATILE_PCI_CFG_VIRT_BASE | (busnr << 16) | (PCI_SLOT(devfn) << 11) | (PCI_FUNC(devfn) << 8) | offset); } static int versatile_read_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val) { - void __iomem *addr = __pci_addr(bus, devfn, where & ~3); + unsigned long addr = __pci_addr(bus, devfn, where); u32 v; int slot = PCI_SLOT(devfn); @@ -122,12 +121,13 @@ static int versatile_read_config(struct pci_bus *bus, unsigned int devfn, int wh break; case 2: - v = __raw_readl(addr); - if (where & 2) v >>= 16; + v = __raw_readl(addr & ~3); + if (addr & 2) v >>= 16; v &= 0xffff; break; default: + addr &= ~3; v = __raw_readl(addr); break; } @@ -140,7 +140,7 @@ static int versatile_read_config(struct pci_bus *bus, unsigned int devfn, int wh static int versatile_write_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val) { - void __iomem *addr = __pci_addr(bus, devfn, where); + unsigned long addr = __pci_addr(bus, devfn, where); int slot = PCI_SLOT(devfn); if (pci_slot_ignore & (1 << slot)) { @@ -279,7 +279,7 @@ int __init pci_versatile_setup(int nr, struct pci_sys_data *sys) printk("PCI core found (slot %d)\n",myslot); __raw_writel(myslot, PCI_SELFID); - local_pci_cfg_base = VERSATILE_PCI_CFG_VIRT_BASE + (myslot << 11); + local_pci_cfg_base = (void *) VERSATILE_PCI_CFG_VIRT_BASE + (myslot << 11); val = __raw_readl(local_pci_cfg_base + CSR_OFFSET); val |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE; diff --git a/trunk/arch/arm/mm/Kconfig b/trunk/arch/arm/mm/Kconfig index b09a19f87d68..c0bfb8212b77 100644 --- a/trunk/arch/arm/mm/Kconfig +++ b/trunk/arch/arm/mm/Kconfig @@ -197,7 +197,7 @@ config CPU_ARM940T select CPU_CP15_MPU help ARM940T is a member of the ARM9TDMI family of general- - purpose microprocessors with MPU and separate 4KB + purpose microprocessors with MPU and seperate 4KB instruction and 4KB data cases, each with a 4-word line length. diff --git a/trunk/arch/arm/mm/consistent.c b/trunk/arch/arm/mm/consistent.c index b797217e82be..50e6b6bfb2e2 100644 --- a/trunk/arch/arm/mm/consistent.c +++ b/trunk/arch/arm/mm/consistent.c @@ -476,9 +476,6 @@ core_initcall(consistent_init); /* * Make an area consistent for devices. - * Note: Drivers should NOT use this function directly, as it will break - * platforms with CONFIG_DMABOUNCE. - * Use the driver DMA support - see dma-mapping.h (dma_sync_*) */ void consistent_sync(void *vaddr, size_t size, int direction) { diff --git a/trunk/arch/arm/mm/init.c b/trunk/arch/arm/mm/init.c index b5814b4b6f35..22217fe2650b 100644 --- a/trunk/arch/arm/mm/init.c +++ b/trunk/arch/arm/mm/init.c @@ -32,51 +32,40 @@ extern unsigned long phys_initrd_start; extern unsigned long phys_initrd_size; /* - * This is used to pass memory configuration data from paging_init - * to mem_init, and by show_mem() to skip holes in the memory map. + * The sole use of this is to pass memory configuration + * data from paging_init to mem_init. */ -static struct meminfo meminfo = { 0, }; - -#define for_each_nodebank(iter,mi,no) \ - for (iter = 0; iter < mi->nr_banks; iter++) \ - if (mi->bank[iter].node == no) +static struct meminfo meminfo __initdata = { 0, }; void show_mem(void) { int free = 0, total = 0, reserved = 0; - int shared = 0, cached = 0, slab = 0, node, i; - struct meminfo * mi = &meminfo; + int shared = 0, cached = 0, slab = 0, node; printk("Mem-info:\n"); show_free_areas(); printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); for_each_online_node(node) { - for_each_nodebank (i,mi,node) { - unsigned int pfn1, pfn2; - struct page *page, *end; - - pfn1 = mi->bank[i].start >> PAGE_SHIFT; - pfn2 = (mi->bank[i].size + mi->bank[i].start) >> PAGE_SHIFT; - - page = NODE_MEM_MAP(node) + pfn1; - end = NODE_MEM_MAP(node) + pfn2; - - do { - total++; - if (PageReserved(page)) - reserved++; - else if (PageSwapCache(page)) - cached++; - else if (PageSlab(page)) - slab++; - else if (!page_count(page)) - free++; - else - shared += page_count(page) - 1; - page++; - } while (page < end); - } + struct page *page, *end; + + page = NODE_MEM_MAP(node); + end = page + NODE_DATA(node)->node_spanned_pages; + + do { + total++; + if (PageReserved(page)) + reserved++; + else if (PageSwapCache(page)) + cached++; + else if (PageSlab(page)) + slab++; + else if (!page_count(page)) + free++; + else + shared += page_count(page) - 1; + page++; + } while (page < end); } printk("%d pages of RAM\n", total); @@ -87,6 +76,10 @@ void show_mem(void) printk("%d pages swap cached\n", cached); } +#define for_each_nodebank(iter,mi,no) \ + for (iter = 0; iter < mi->nr_banks; iter++) \ + if (mi->bank[iter].node == no) + /* * FIXME: We really want to avoid allocating the bootmap bitmap * over the top of the initrd. Hopefully, this is located towards diff --git a/trunk/arch/arm/mm/ioremap.c b/trunk/arch/arm/mm/ioremap.c index 465440592791..591fc3187c7f 100644 --- a/trunk/arch/arm/mm/ioremap.c +++ b/trunk/arch/arm/mm/ioremap.c @@ -361,14 +361,14 @@ __ioremap(unsigned long phys_addr, size_t size, unsigned long flags) } EXPORT_SYMBOL(__ioremap); -void __iounmap(volatile void __iomem *addr) +void __iounmap(void __iomem *addr) { #ifndef CONFIG_SMP struct vm_struct **p, *tmp; #endif unsigned int section_mapping = 0; - addr = (volatile void __iomem *)(PAGE_MASK & (unsigned long)addr); + addr = (void __iomem *)(PAGE_MASK & (unsigned long)addr); #ifndef CONFIG_SMP /* @@ -395,6 +395,6 @@ void __iounmap(volatile void __iomem *addr) #endif if (!section_mapping) - vunmap((void __force *)addr); + vunmap(addr); } EXPORT_SYMBOL(__iounmap); diff --git a/trunk/arch/arm/mm/proc-xscale.S b/trunk/arch/arm/mm/proc-xscale.S index 2749c1f88d7d..e8b377d637f6 100644 --- a/trunk/arch/arm/mm/proc-xscale.S +++ b/trunk/arch/arm/mm/proc-xscale.S @@ -909,7 +909,7 @@ __pxa270_proc_info: b __xscale_setup .long cpu_arch_name .long cpu_elf_name - .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_IWMMXT + .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP .long cpu_pxa270_name .long xscale_processor_functions .long v4wbi_tlb_fns diff --git a/trunk/arch/arm/oprofile/op_counter.h b/trunk/arch/arm/oprofile/op_counter.h index ca942a63b52f..8c5351d751cf 100644 --- a/trunk/arch/arm/oprofile/op_counter.h +++ b/trunk/arch/arm/oprofile/op_counter.h @@ -10,6 +10,8 @@ #ifndef OP_COUNTER_H #define OP_COUNTER_H +#define OP_MAX_COUNTER 5 + /* Per performance monitor configuration as set via * oprofilefs. */ diff --git a/trunk/arch/arm/oprofile/op_model_xscale.c b/trunk/arch/arm/oprofile/op_model_xscale.c index 7c3289c2acd7..726ad2b3b435 100644 --- a/trunk/arch/arm/oprofile/op_model_xscale.c +++ b/trunk/arch/arm/oprofile/op_model_xscale.c @@ -20,8 +20,7 @@ #include #include #include -#include - +#include #include #include "op_counter.h" @@ -342,7 +341,7 @@ static void inline __xsc2_check_ctrs(void) __asm__ __volatile__ ("mcr p14, 0, %0, c5, c1, 0" : : "r" (flag)); } -static irqreturn_t xscale_pmu_interrupt(int irq, void *arg) +static irqreturn_t xscale_pmu_interrupt(int irq, void *arg, struct pt_regs *regs) { int i; u32 pmnc; @@ -357,7 +356,7 @@ static irqreturn_t xscale_pmu_interrupt(int irq, void *arg) continue; write_counter(i, -(u32)results[i].reset_counter); - oprofile_add_sample(get_irq_regs(), i); + oprofile_add_sample(regs, i); results[i].ovf--; } diff --git a/trunk/arch/arm/plat-iop/time.c b/trunk/arch/arm/plat-iop/time.c index f530abdaa7a1..06282dffbdc6 100644 --- a/trunk/arch/arm/plat-iop/time.c +++ b/trunk/arch/arm/plat-iop/time.c @@ -47,7 +47,7 @@ unsigned long iop3xx_gettimeoffset(void) } static irqreturn_t -iop3xx_timer_interrupt(int irq, void *dev_id) +iop3xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { write_seqlock(&xtime_lock); @@ -57,7 +57,7 @@ iop3xx_timer_interrupt(int irq, void *dev_id) while ((signed long)(next_jiffy_time - *IOP3XX_TU_TCR1) >= ticks_per_jiffy) { - timer_tick(); + timer_tick(regs); next_jiffy_time -= ticks_per_jiffy; } diff --git a/trunk/arch/arm/plat-omap/dma.c b/trunk/arch/arm/plat-omap/dma.c index bb045e5ddbd8..1bbb431843ce 100644 --- a/trunk/arch/arm/plat-omap/dma.c +++ b/trunk/arch/arm/plat-omap/dma.c @@ -899,7 +899,8 @@ static int omap1_dma_handle_ch(int ch) return 1; } -static irqreturn_t omap1_dma_irq_handler(int irq, void *dev_id) +static irqreturn_t omap1_dma_irq_handler(int irq, void *dev_id, + struct pt_regs *regs) { int ch = ((int) dev_id) - 1; int handled = 0; @@ -961,7 +962,8 @@ static int omap2_dma_handle_ch(int ch) } /* STATUS register count is from 1-32 while our is 0-31 */ -static irqreturn_t omap2_dma_irq_handler(int irq, void *dev_id) +static irqreturn_t omap2_dma_irq_handler(int irq, void *dev_id, + struct pt_regs *regs) { u32 val; int i; @@ -1218,7 +1220,8 @@ static void set_b1_regs(void) omap_writew(fi, OMAP1610_DMA_LCD_SRC_FI_B1_L); } -static irqreturn_t lcd_dma_irq_handler(int irq, void *dev_id) +static irqreturn_t lcd_dma_irq_handler(int irq, void *dev_id, + struct pt_regs *regs) { u16 w; diff --git a/trunk/arch/arm/plat-omap/gpio.c b/trunk/arch/arm/plat-omap/gpio.c index 8162eed8b500..f55f99ae58ae 100644 --- a/trunk/arch/arm/plat-omap/gpio.c +++ b/trunk/arch/arm/plat-omap/gpio.c @@ -783,7 +783,8 @@ void omap_free_gpio(int gpio) * line's interrupt handler has been run, we may miss some nested * interrupts. */ -static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc) +static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc, + struct pt_regs *regs) { void __iomem *isr_reg = NULL; u32 isr; @@ -881,7 +882,7 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc) continue; } - desc_handle_irq(gpio_irq, d); + desc_handle_irq(gpio_irq, d, regs); if (unlikely((d->status & IRQ_PENDING) && !d->depth)) { irq_mask = 1 << diff --git a/trunk/arch/arm/plat-omap/mcbsp.c b/trunk/arch/arm/plat-omap/mcbsp.c index ec50008a2df6..ade9a0fa6ef6 100644 --- a/trunk/arch/arm/plat-omap/mcbsp.c +++ b/trunk/arch/arm/plat-omap/mcbsp.c @@ -96,7 +96,7 @@ static void omap_mcbsp_dump_reg(u8 id) DBG("***********************\n"); } -static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id) +static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id, struct pt_regs *regs) { struct omap_mcbsp * mcbsp_tx = (struct omap_mcbsp *)(dev_id); @@ -106,7 +106,7 @@ static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id) return IRQ_HANDLED; } -static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id) +static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id, struct pt_regs *regs) { struct omap_mcbsp * mcbsp_rx = (struct omap_mcbsp *)(dev_id); diff --git a/trunk/arch/arm/plat-omap/timer32k.c b/trunk/arch/arm/plat-omap/timer32k.c index 265310601161..cf6df3378d37 100644 --- a/trunk/arch/arm/plat-omap/timer32k.c +++ b/trunk/arch/arm/plat-omap/timer32k.c @@ -194,7 +194,8 @@ unsigned long long sched_clock(void) * issues with dynamic tick. In the dynamic tick case, we need to lock * with irqsave. */ -static inline irqreturn_t _omap_32k_timer_interrupt(int irq, void *dev_id) +static inline irqreturn_t _omap_32k_timer_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { unsigned long now; @@ -204,7 +205,7 @@ static inline irqreturn_t _omap_32k_timer_interrupt(int irq, void *dev_id) while ((signed long)(now - omap_32k_last_tick) >= OMAP_32K_TICKS_PER_HZ) { omap_32k_last_tick += OMAP_32K_TICKS_PER_HZ; - timer_tick(); + timer_tick(regs); } /* Restart timer so we don't drift off due to modulo or dynamic tick. @@ -217,17 +218,19 @@ static inline irqreturn_t _omap_32k_timer_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -static irqreturn_t omap_32k_timer_handler(int irq, void *dev_id) +static irqreturn_t omap_32k_timer_handler(int irq, void *dev_id, + struct pt_regs *regs) { - return _omap_32k_timer_interrupt(irq, dev_id); + return _omap_32k_timer_interrupt(irq, dev_id, regs); } -static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id) +static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { unsigned long flags; write_seqlock_irqsave(&xtime_lock, flags); - _omap_32k_timer_interrupt(irq, dev_id); + _omap_32k_timer_interrupt(irq, dev_id, regs); write_sequnlock_irqrestore(&xtime_lock, flags); return IRQ_HANDLED; diff --git a/trunk/arch/arm/tools/mach-types b/trunk/arch/arm/tools/mach-types index 579c69ae9ff7..b02af1d740fa 100644 --- a/trunk/arch/arm/tools/mach-types +++ b/trunk/arch/arm/tools/mach-types @@ -4,7 +4,7 @@ # # Up to date versions of this file can be obtained from: # -# http://www.arm.linux.org.uk/developer/machines/download.php +# http://www.arm.linux.org.uk/developer/machines/?action=download # # Please do not send patches to this file; it is automatically generated! # To add an entry into this database, please see Documentation/arm/README, @@ -12,7 +12,7 @@ # # http://www.arm.linux.org.uk/developer/machines/?action=new # -# Last update: Mon Oct 16 21:13:36 2006 +# Last update: Sat Sep 23 13:20:43 2006 # # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number # @@ -1157,17 +1157,3 @@ adsturboxb MACH_ADSTURBOXB ADSTURBOXB 1143 oti4110 MACH_OTI4110 OTI4110 1144 hme_pxa MACH_HME_PXA HME_PXA 1145 deisterdca MACH_DEISTERDCA DEISTERDCA 1146 -ces_ssem2 MACH_CES_SSEM2 CES_SSEM2 1147 -ces_mtr MACH_CES_MTR CES_MTR 1148 -tds_avng_sbc MACH_TDS_AVNG_SBC TDS_AVNG_SBC 1149 -everest MACH_EVEREST EVEREST 1150 -pnx4010 MACH_PNX4010 PNX4010 1151 -oxnas MACH_OXNAS OXNAS 1152 -fiori MACH_FIORI FIORI 1153 -ml1200 MACH_ML1200 ML1200 1154 -cactus MACH_CACTUS CACTUS 1155 -nb2xxx MACH_NB2XXX NB2XXX 1156 -hw6900 MACH_HW6900 HW6900 1157 -cdcs_quoll MACH_CDCS_QUOLL CDCS_QUOLL 1158 -quicksilver MACH_QUICKSILVER QUICKSILVER 1159 -uplat926 MACH_UPLAT926 UPLAT926 1160 diff --git a/trunk/arch/arm/vfp/vfpdouble.c b/trunk/arch/arm/vfp/vfpdouble.c index e44b9ed0f81f..4fc05ee0a2ef 100644 --- a/trunk/arch/arm/vfp/vfpdouble.c +++ b/trunk/arch/arm/vfp/vfpdouble.c @@ -56,7 +56,7 @@ static void vfp_double_normalise_denormal(struct vfp_double *vd) { int bits = 31 - fls(vd->significand >> 32); if (bits == 31) - bits = 63 - fls(vd->significand); + bits = 62 - fls(vd->significand); vfp_double_dump("normalise_denormal: in", vd); diff --git a/trunk/arch/arm/vfp/vfpmodule.c b/trunk/arch/arm/vfp/vfpmodule.c index f08eafbddcc1..dedbb449632e 100644 --- a/trunk/arch/arm/vfp/vfpmodule.c +++ b/trunk/arch/arm/vfp/vfpmodule.c @@ -90,7 +90,7 @@ void vfp_raise_sigfpe(unsigned int sicode, struct pt_regs *regs) info.si_signo = SIGFPE; info.si_code = sicode; - info.si_addr = (void __user *)(instruction_pointer(regs) - 4); + info.si_addr = (void *)(instruction_pointer(regs) - 4); /* * This is the same as NWFPE, because it's not clear what @@ -148,7 +148,6 @@ static void vfp_raise_exceptions(u32 exceptions, u32 inst, u32 fpscr, struct pt_ /* * These are arranged in priority order, least to highest. */ - RAISE(FPSCR_DZC, FPSCR_DZE, FPE_FLTDIV); RAISE(FPSCR_IXC, FPSCR_IXE, FPE_FLTRES); RAISE(FPSCR_UFC, FPSCR_UFE, FPE_FLTUND); RAISE(FPSCR_OFC, FPSCR_OFE, FPE_FLTOVF); diff --git a/trunk/arch/arm26/kernel/armksyms.c b/trunk/arch/arm26/kernel/armksyms.c index 93293d04b303..07907b6ecb63 100644 --- a/trunk/arch/arm26/kernel/armksyms.c +++ b/trunk/arch/arm26/kernel/armksyms.c @@ -202,6 +202,14 @@ EXPORT_SYMBOL(_find_next_zero_bit_le); EXPORT_SYMBOL(elf_platform); EXPORT_SYMBOL(elf_hwcap); + /* syscalls */ +EXPORT_SYMBOL(sys_write); +EXPORT_SYMBOL(sys_read); +EXPORT_SYMBOL(sys_lseek); +EXPORT_SYMBOL(sys_open); +EXPORT_SYMBOL(sys_exit); +EXPORT_SYMBOL(sys_wait4); + #ifdef CONFIG_PREEMPT EXPORT_SYMBOL(kernel_flag); #endif diff --git a/trunk/arch/avr32/Makefile b/trunk/arch/avr32/Makefile index 7b842e98efed..cefc95a73980 100644 --- a/trunk/arch/avr32/Makefile +++ b/trunk/arch/avr32/Makefile @@ -7,7 +7,7 @@ # Default target when executing plain make .PHONY: all -all: uImage vmlinux.elf +all: uImage vmlinux.elf linux.lst KBUILD_DEFCONFIG := atstk1002_defconfig @@ -21,7 +21,9 @@ cpuflags-$(CONFIG_CPU_AP7000) += -mcpu=ap7000 CFLAGS += $(cpuflags-y) AFLAGS += $(cpuflags-y) -CHECKFLAGS += -D__avr32__ -D__BIG_ENDIAN +CHECKFLAGS += -D__avr32__ + +LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) head-$(CONFIG_LOADER_U_BOOT) += arch/avr32/boot/u-boot/head.o head-y += arch/avr32/kernel/head.o @@ -30,7 +32,7 @@ core-$(CONFIG_BOARD_ATSTK1000) += arch/avr32/boards/atstk1000/ core-$(CONFIG_LOADER_U_BOOT) += arch/avr32/boot/u-boot/ core-y += arch/avr32/kernel/ core-y += arch/avr32/mm/ -libs-y += arch/avr32/lib/ +libs-y += arch/avr32/lib/ #$(LIBGCC) archincdir-$(CONFIG_PLATFORM_AT32AP) := arch-at32ap @@ -46,8 +48,6 @@ endif archprepare: include/asm-avr32/.arch -CLEAN_FILES += include/asm-avr32/.arch include/asm-avr32/arch - BOOT_TARGETS := vmlinux.elf vmlinux.bin uImage uImage.srec .PHONY: $(BOOT_TARGETS) install @@ -71,19 +71,14 @@ vmlinux.elf vmlinux.bin uImage.srec uImage vmlinux.cso: vmlinux install: vmlinux $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) $@ -vmlinux.s: vmlinux +linux.s: vmlinux $(call if_changed,disasm) -vmlinux.lst: vmlinux +linux.lst: vmlinux $(call if_changed,listing) -CLEAN_FILES += vmlinux.s vmlinux.lst - -archclean: - $(Q)$(MAKE) $(clean)=$(boot) - define archhelp @echo '* vmlinux.elf - ELF image with load address 0' @echo ' vmlinux.cso - PathFinder CSO image' - @echo '* uImage - Create a bootable image for U-Boot' + @echo ' uImage - Create a bootable image for U-Boot' endef diff --git a/trunk/arch/avr32/boards/atstk1000/setup.c b/trunk/arch/avr32/boards/atstk1000/setup.c index 272c011802a7..191ab85de9a3 100644 --- a/trunk/arch/avr32/boards/atstk1000/setup.c +++ b/trunk/arch/avr32/boards/atstk1000/setup.c @@ -21,6 +21,15 @@ struct tag *bootloader_tags __initdata; struct lcdc_platform_data __initdata atstk1000_fb0_data; +asmlinkage void __init board_early_init(void) +{ + extern void sdram_init(void); + +#ifdef CONFIG_LOADER_STANDALONE + sdram_init(); +#endif +} + void __init board_setup_fbmem(unsigned long fbmem_start, unsigned long fbmem_size) { diff --git a/trunk/arch/avr32/boot/images/Makefile b/trunk/arch/avr32/boot/images/Makefile index 219720a47bf9..ccd74eeecec3 100644 --- a/trunk/arch/avr32/boot/images/Makefile +++ b/trunk/arch/avr32/boot/images/Makefile @@ -37,12 +37,14 @@ OBJCOPYFLAGS_vmlinux.elf := --change-section-lma .text-0x80000000 \ --change-section-lma .data-0x80000000 \ --change-section-lma .init-0x80000000 \ --change-section-lma .bss-0x80000000 \ + --change-section-lma .initrd-0x80000000 \ --change-section-lma __param-0x80000000 \ --change-section-lma __ksymtab-0x80000000 \ --change-section-lma __ksymtab_gpl-0x80000000 \ --change-section-lma __kcrctab-0x80000000 \ --change-section-lma __kcrctab_gpl-0x80000000 \ --change-section-lma __ksymtab_strings-0x80000000 \ + --change-section-lma .got-0x80000000 \ --set-start 0xa0000000 $(obj)/vmlinux.elf: vmlinux FORCE $(call if_changed,objcopy) @@ -57,4 +59,4 @@ install: $(BOOTIMAGE) sh $(srctree)/install-kernel.sh $< # Generated files to be removed upon make clean -clean-files := vmlinux.elf vmlinux.bin vmlinux.gz uImage uImage.srec +clean-files := vmlinux* uImage uImage.srec diff --git a/trunk/arch/avr32/configs/atstk1002_defconfig b/trunk/arch/avr32/configs/atstk1002_defconfig index ae92a14ef9a0..6c2c5e00dfc7 100644 --- a/trunk/arch/avr32/configs/atstk1002_defconfig +++ b/trunk/arch/avr32/configs/atstk1002_defconfig @@ -1,14 +1,13 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.19-rc2 -# Fri Oct 20 11:52:37 2006 +# Linux kernel version: 2.6.18-rc1 +# Tue Jul 11 12:41:36 2006 # CONFIG_AVR32=y CONFIG_GENERIC_HARDIRQS=y CONFIG_HARDIRQS_SW_RESEND=y CONFIG_GENERIC_IRQ_PROBE=y CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_GENERIC_TIME=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" @@ -26,23 +25,16 @@ CONFIG_INIT_ENV_ARG_LIMIT=32 CONFIG_LOCALVERSION="" # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SWAP=y -CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set -CONFIG_POSIX_MQUEUE=y -CONFIG_BSD_PROCESS_ACCT=y -CONFIG_BSD_PROCESS_ACCT_V3=y -CONFIG_TASKSTATS=y -CONFIG_TASK_DELAY_ACCT=y -# CONFIG_UTS_NS is not set -CONFIG_AUDIT=y +# CONFIG_SYSVIPC is not set +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set -CONFIG_RELAY=y +# CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" CONFIG_CC_OPTIMIZE_FOR_SIZE=y -# CONFIG_TASK_XACCT is not set -CONFIG_SYSCTL=y CONFIG_EMBEDDED=y -# CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set @@ -51,15 +43,14 @@ CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y # CONFIG_BASE_FULL is not set -CONFIG_FUTEX=y -CONFIG_EPOLL=y +# CONFIG_FUTEX is not set +# CONFIG_EPOLL is not set CONFIG_SHMEM=y -CONFIG_SLAB=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_RT_MUTEXES=y +# CONFIG_SLAB is not set +# CONFIG_VM_EVENT_COUNTERS is not set # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=1 -# CONFIG_SLOB is not set +CONFIG_SLOB=y # # Loadable module support @@ -74,7 +65,6 @@ CONFIG_MODULE_UNLOAD=y # # Block layer # -CONFIG_BLOCK=y # CONFIG_BLK_DEV_IO_TRACE is not set # @@ -176,12 +166,10 @@ CONFIG_IP_PNP_DHCP=y # CONFIG_INET_TUNNEL is not set # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" +CONFIG_TCP_CONG_BIC=y # CONFIG_IPV6 is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set @@ -211,6 +199,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_ATALK is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set @@ -223,6 +212,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # Network testing # # CONFIG_NET_PKTGEN is not set +# CONFIG_NET_TCPPROBE is not set # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set @@ -249,84 +239,7 @@ CONFIG_STANDALONE=y # # Memory Technology Devices (MTD) # -CONFIG_MTD=y -# CONFIG_MTD_DEBUG is not set -# CONFIG_MTD_CONCAT is not set -CONFIG_MTD_PARTITIONS=y -# CONFIG_MTD_REDBOOT_PARTS is not set -CONFIG_MTD_CMDLINE_PARTS=y - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLOCK=y -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set -# CONFIG_RFD_FTL is not set -# CONFIG_SSFDC is not set - -# -# RAM/ROM/Flash chip drivers -# -CONFIG_MTD_CFI=y -# CONFIG_MTD_JEDECPROBE is not set -CONFIG_MTD_GEN_PROBE=y -# CONFIG_MTD_CFI_ADV_OPTIONS is not set -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -CONFIG_MTD_MAP_BANK_WIDTH_4=y -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -# CONFIG_MTD_CFI_INTELEXT is not set -CONFIG_MTD_CFI_AMDSTD=y -# CONFIG_MTD_CFI_STAA is not set -CONFIG_MTD_CFI_UTIL=y -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_ROM is not set -# CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_OBSOLETE_CHIPS is not set - -# -# Mapping drivers for chip access -# -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_PHYSMAP_START=0x8000000 -CONFIG_MTD_PHYSMAP_LEN=0x0 -CONFIG_MTD_PHYSMAP_BANKWIDTH=2 -# CONFIG_MTD_PLATRAM is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLOCK2MTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOC2001PLUS is not set - -# -# NAND Flash Device Drivers -# -# CONFIG_MTD_NAND is not set - -# -# OneNAND Flash Device Drivers -# -# CONFIG_MTD_ONENAND is not set +# CONFIG_MTD is not set # # Parallel port support @@ -347,17 +260,10 @@ CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=m CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set -# -# Misc devices -# -# CONFIG_SGI_IOC4 is not set -# CONFIG_TIFM_CORE is not set - # # ATA/ATAPI/MFM/RLL support # @@ -368,12 +274,6 @@ CONFIG_BLK_DEV_INITRD=y # # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set -# CONFIG_SCSI_NETLINK is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# -# CONFIG_ATA is not set # # Multi-device support (RAID and LVM) @@ -405,11 +305,14 @@ CONFIG_TUN=m # # PHY device support # +# CONFIG_PHYLIB is not set # # Ethernet (10 or 100Mbit) # -# CONFIG_NET_ETHERNET is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_MACB=y # # Ethernet (1000 Mbit) @@ -438,11 +341,10 @@ CONFIG_PPP=m CONFIG_PPP_ASYNC=m # CONFIG_PPP_SYNC_TTY is not set CONFIG_PPP_DEFLATE=m -CONFIG_PPP_BSDCOMP=m +# CONFIG_PPP_BSDCOMP is not set # CONFIG_PPP_MPPE is not set # CONFIG_PPPOE is not set # CONFIG_SLIP is not set -CONFIG_SLHC=m # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set @@ -515,6 +417,7 @@ CONFIG_UNIX98_PTYS=y # TPM devices # # CONFIG_TCG_TPM is not set +# CONFIG_TELCLOCK is not set # # I2C support @@ -524,13 +427,23 @@ CONFIG_UNIX98_PTYS=y # # SPI support # -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +CONFIG_SPI_ATMEL=m +# CONFIG_SPI_BITBANG is not set + +# +# SPI Protocol Masters +# # # Dallas's 1-wire bus # -# CONFIG_W1 is not set # # Hardware Monitoring support @@ -538,10 +451,15 @@ CONFIG_UNIX98_PTYS=y # CONFIG_HWMON is not set # CONFIG_HWMON_VID is not set +# +# Misc devices +# + # # Multimedia devices # # CONFIG_VIDEO_DEV is not set +CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices @@ -552,8 +470,28 @@ CONFIG_UNIX98_PTYS=y # Graphics support # # CONFIG_FIRMWARE_EDID is not set -# CONFIG_FB is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +CONFIG_FB=m +CONFIG_FB_CFB_FILLRECT=m +CONFIG_FB_CFB_COPYAREA=m +CONFIG_FB_CFB_IMAGEBLIT=m +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set +CONFIG_FB_SIDSA=m +CONFIG_FB_SIDSA_DEFAULT_BPP=24 +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set + +# +# Logo configuration +# +# CONFIG_LOGO is not set +CONFIG_BACKLIGHT_LCD_SUPPORT=y +# CONFIG_BACKLIGHT_CLASS_DEVICE is not set +CONFIG_LCD_CLASS_DEVICE=m +CONFIG_LCD_DEVICE=y +CONFIG_LCD_LTV350QV=m # # Sound @@ -623,21 +561,18 @@ CONFIG_UNIX98_PTYS=y # # File systems # -CONFIG_EXT2_FS=m +CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set # CONFIG_EXT2_FS_XIP is not set # CONFIG_EXT3_FS is not set -# CONFIG_EXT4DEV_FS is not set # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set # CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set CONFIG_MINIX_FS=m -# CONFIG_ROMFS_FS is not set -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y +CONFIG_ROMFS_FS=m +# CONFIG_INOTIFY is not set # CONFIG_QUOTA is not set # CONFIG_DNOTIFY is not set # CONFIG_AUTOFS_FS is not set @@ -665,10 +600,8 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" # CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y -CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y CONFIG_CONFIGFS_FS=m @@ -683,16 +616,6 @@ CONFIG_CONFIGFS_FS=m # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set -CONFIG_JFFS2_FS=y -CONFIG_JFFS2_FS_DEBUG=0 -CONFIG_JFFS2_FS_WRITEBUFFER=y -# CONFIG_JFFS2_SUMMARY is not set -# CONFIG_JFFS2_FS_XATTR is not set -# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set -CONFIG_JFFS2_ZLIB=y -CONFIG_JFFS2_RTIME=y -# CONFIG_JFFS2_RUBIN is not set # CONFIG_CRAMFS is not set # CONFIG_VXFS_FS is not set # CONFIG_HPFS_FS is not set @@ -703,10 +626,26 @@ CONFIG_JFFS2_RTIME=y # # Network File Systems # -# CONFIG_NFS_FS is not set +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set # CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set +CONFIG_CIFS=m +# CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_XATTR is not set +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_EXPERIMENTAL is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set @@ -726,7 +665,7 @@ CONFIG_NLS_DEFAULT="iso8859-1" CONFIG_NLS_CODEPAGE_437=m # CONFIG_NLS_CODEPAGE_737 is not set # CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set +CONFIG_NLS_CODEPAGE_850=m # CONFIG_NLS_CODEPAGE_852 is not set # CONFIG_NLS_CODEPAGE_855 is not set # CONFIG_NLS_CODEPAGE_857 is not set @@ -766,17 +705,13 @@ CONFIG_NLS_UTF8=m # Kernel hacking # CONFIG_TRACE_IRQFLAGS_SUPPORT=y -# CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_MUST_CHECK=y +CONFIG_PRINTK_TIME=y CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_KERNEL=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set -# CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_MUTEXES is not set # CONFIG_DEBUG_RWSEMS is not set @@ -787,13 +722,11 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_INFO is not set CONFIG_DEBUG_FS=y # CONFIG_DEBUG_VM is not set -# CONFIG_DEBUG_LIST is not set CONFIG_FRAME_POINTER=y # CONFIG_UNWIND_INFO is not set CONFIG_FORCED_INLINING=y -# CONFIG_HEADERS_CHECK is not set # CONFIG_RCU_TORTURE_TEST is not set -# CONFIG_KPROBES is not set +CONFIG_KPROBES=y # # Security options @@ -806,14 +739,16 @@ CONFIG_FORCED_INLINING=y # # CONFIG_CRYPTO is not set +# +# Hardware crypto devices +# + # # Library routines # CONFIG_CRC_CCITT=m # CONFIG_CRC16 is not set -CONFIG_CRC32=y +CONFIG_CRC32=m # CONFIG_LIBCRC32C is not set -CONFIG_AUDIT_GENERIC=y -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y -CONFIG_PLIST=y +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m diff --git a/trunk/arch/avr32/kernel/avr32_ksyms.c b/trunk/arch/avr32/kernel/avr32_ksyms.c index 372e3f8b2417..04f767a272b7 100644 --- a/trunk/arch/avr32/kernel/avr32_ksyms.c +++ b/trunk/arch/avr32/kernel/avr32_ksyms.c @@ -7,7 +7,6 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ -#include #include #include @@ -54,11 +53,3 @@ EXPORT_SYMBOL(find_next_zero_bit); EXPORT_SYMBOL(find_first_bit); EXPORT_SYMBOL(find_next_bit); EXPORT_SYMBOL(generic_find_next_zero_le_bit); - -/* I/O primitives (lib/io-*.S) */ -EXPORT_SYMBOL(__raw_readsb); -EXPORT_SYMBOL(__raw_readsw); -EXPORT_SYMBOL(__raw_readsl); -EXPORT_SYMBOL(__raw_writesb); -EXPORT_SYMBOL(__raw_writesw); -EXPORT_SYMBOL(__raw_writesl); diff --git a/trunk/arch/avr32/kernel/head.S b/trunk/arch/avr32/kernel/head.S index 6163bd0acb95..773b7ad87be9 100644 --- a/trunk/arch/avr32/kernel/head.S +++ b/trunk/arch/avr32/kernel/head.S @@ -30,6 +30,9 @@ kernel_entry: mov r7, 0 #endif + /* Set up the PIO, SDRAM controller, early printk, etc. */ + rcall board_early_init + /* Start the show */ lddpc pc, kernel_start_addr diff --git a/trunk/arch/avr32/kernel/kprobes.c b/trunk/arch/avr32/kernel/kprobes.c index ca41fc1edbe1..6caf9e8d8080 100644 --- a/trunk/arch/avr32/kernel/kprobes.c +++ b/trunk/arch/avr32/kernel/kprobes.c @@ -109,7 +109,7 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) void *addr = (void *)regs->pc; int ret = 0; - pr_debug("kprobe_handler: kprobe_running=%p\n", + pr_debug("kprobe_handler: kprobe_running=%d\n", kprobe_running()); /* diff --git a/trunk/arch/avr32/kernel/module.c b/trunk/arch/avr32/kernel/module.c index b599eae64576..dfc32f2817b6 100644 --- a/trunk/arch/avr32/kernel/module.c +++ b/trunk/arch/avr32/kernel/module.c @@ -263,7 +263,7 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab, * value of PC. Just subtract the value of * GOT, and we're done. */ - pr_debug("GOTPC: PC=0x%x, got_offset=0x%lx, core=0x%p\n", + pr_debug("GOTPC: PC=0x%lx, got_offset=0x%lx, core=0x%p\n", relocation, module->arch.got_offset, module->module_core); relocation -= ((unsigned long)module->module_core @@ -282,7 +282,7 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab, && (relocation & 0xffff0000) != 0xffff0000) return reloc_overflow(module, "R_AVR32_GOT16S", relocation); - pr_debug("GOT reloc @ 0x%x -> %u\n", + pr_debug("GOT reloc @ 0x%lx -> %lu\n", rel->r_offset, relocation); value = *location; value = ((value & 0xffff0000) diff --git a/trunk/arch/avr32/kernel/ptrace.c b/trunk/arch/avr32/kernel/ptrace.c index f2e81cd79002..3c89e59029ab 100644 --- a/trunk/arch/avr32/kernel/ptrace.c +++ b/trunk/arch/avr32/kernel/ptrace.c @@ -157,7 +157,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) unsigned long tmp; int ret; - pr_debug("arch_ptrace(%ld, %d, %#lx, %#lx)\n", + pr_debug("arch_ptrace(%ld, %ld, %#lx, %#lx)\n", request, child->pid, addr, data); pr_debug("ptrace: Enabling monitor mode...\n"); diff --git a/trunk/arch/avr32/kernel/syscall-stubs.S b/trunk/arch/avr32/kernel/syscall-stubs.S index 890286a1e62b..7589a9b426cb 100644 --- a/trunk/arch/avr32/kernel/syscall-stubs.S +++ b/trunk/arch/avr32/kernel/syscall-stubs.S @@ -100,12 +100,3 @@ __sys_splice: rcall sys_splice sub sp, -4 popm pc - - .global __sys_epoll_pwait - .type __sys_epoll_pwait,@function -__sys_epoll_pwait: - pushm lr - st.w --sp, ARG6 - rcall sys_epoll_pwait - sub sp, -4 - popm pc diff --git a/trunk/arch/avr32/kernel/syscall_table.S b/trunk/arch/avr32/kernel/syscall_table.S index db8f8b55ffdf..63b206965d05 100644 --- a/trunk/arch/avr32/kernel/syscall_table.S +++ b/trunk/arch/avr32/kernel/syscall_table.S @@ -286,5 +286,4 @@ sys_call_table: .long sys_sync_file_range .long sys_tee .long sys_vmsplice - .long __sys_epoll_pwait /* 265 */ .long sys_ni_syscall /* r8 is saturated at nr_syscalls */ diff --git a/trunk/arch/avr32/kernel/time.c b/trunk/arch/avr32/kernel/time.c index 5a247ba71a72..3e56b9f4358a 100644 --- a/trunk/arch/avr32/kernel/time.c +++ b/trunk/arch/avr32/kernel/time.c @@ -124,15 +124,15 @@ unsigned long long sched_clock(void) * * In UP mode, it is invoked from the (global) timer_interrupt. */ -static void local_timer_interrupt(int irq, void *dev_id) +static void local_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { if (current->pid) - profile_tick(CPU_PROFILING); - update_process_times(user_mode(get_irq_regs())); + profile_tick(CPU_PROFILING, regs); + update_process_times(user_mode(regs)); } static irqreturn_t -timer_interrupt(int irq, void *dev_id) +timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { unsigned int count; @@ -157,7 +157,7 @@ timer_interrupt(int irq, void *dev_id) * * SMP is not supported yet. */ - local_timer_interrupt(irq, dev_id); + local_timer_interrupt(irq, dev_id, regs); return IRQ_HANDLED; } diff --git a/trunk/arch/avr32/kernel/vmlinux.lds.c b/trunk/arch/avr32/kernel/vmlinux.lds.c index 5c4424e362b5..cdd627c6b7dc 100644 --- a/trunk/arch/avr32/kernel/vmlinux.lds.c +++ b/trunk/arch/avr32/kernel/vmlinux.lds.c @@ -38,7 +38,13 @@ SECTIONS __setup_end = .; . = ALIGN(4); __initcall_start = .; - INITCALLS + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) __initcall_end = .; __con_initcall_start = .; *(.con_initcall.init) diff --git a/trunk/arch/avr32/lib/Makefile b/trunk/arch/avr32/lib/Makefile index 084d95bac5e7..09ac43e40522 100644 --- a/trunk/arch/avr32/lib/Makefile +++ b/trunk/arch/avr32/lib/Makefile @@ -7,5 +7,4 @@ lib-y += strncpy_from_user.o strnlen_user.o lib-y += delay.o memset.o memcpy.o findbit.o lib-y += csum_partial.o csum_partial_copy_generic.o lib-y += io-readsw.o io-readsl.o io-writesw.o io-writesl.o -lib-y += io-readsb.o io-writesb.o lib-y += __avr32_lsl64.o __avr32_lsr64.o __avr32_asr64.o diff --git a/trunk/arch/avr32/lib/findbit.S b/trunk/arch/avr32/lib/findbit.S index c6b91dee857c..2b4856f4bf7c 100644 --- a/trunk/arch/avr32/lib/findbit.S +++ b/trunk/arch/avr32/lib/findbit.S @@ -136,7 +136,6 @@ ENTRY(generic_find_next_zero_le_bit) /* offset is not word-aligned. Handle the first (32 - r10) bits */ ldswp.w r8, r12[0] sub r12, -4 - com r8 lsr r8, r8, r10 brne .L_found @@ -147,7 +146,7 @@ ENTRY(generic_find_next_zero_le_bit) /* Main loop. offset must be word-aligned */ 1: ldswp.w r8, r12[0] - com r8 + cp.w r8, 0 brne .L_found sub r12, -4 sub r9, 32 diff --git a/trunk/arch/avr32/lib/io-readsb.S b/trunk/arch/avr32/lib/io-readsb.S deleted file mode 100644 index 2be5da7ed26b..000000000000 --- a/trunk/arch/avr32/lib/io-readsb.S +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * 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. - */ - - .text -.Lnot_word_aligned: -1: ld.ub r8, r12[0] - sub r10, 1 - st.b r11++, r8 - reteq r12 - tst r11, r9 - brne 1b - - /* fall through */ - - .global __raw_readsb - .type __raw_readsb,@function -__raw_readsb: - cp.w r10, 0 - mov r9, 3 - reteq r12 - - tst r11, r9 - brne .Lnot_word_aligned - - sub r10, 4 - brlt 2f - -1: ldins.b r8:t, r12[0] - ldins.b r8:u, r12[0] - ldins.b r8:l, r12[0] - ldins.b r8:b, r12[0] - st.w r11++, r8 - sub r10, 4 - brge 1b - -2: sub r10, -4 - reteq r12 - -3: ld.uh r8, r12[0] - sub r10, 1 - st.b r11++, r8 - brne 3b - - retal r12 diff --git a/trunk/arch/avr32/lib/io-writesb.S b/trunk/arch/avr32/lib/io-writesb.S deleted file mode 100644 index b4ebaacccf68..000000000000 --- a/trunk/arch/avr32/lib/io-writesb.S +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * 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. - */ - - .text -.Lnot_word_aligned: -1: ld.ub r8, r11++ - sub r10, 1 - st.b r12[0], r8 - reteq r12 - tst r11, r9 - brne 1b - - /* fall through */ - - .global __raw_writesb - .type __raw_writesb,@function -__raw_writesb: - cp.w r10, 0 - mov r9, 3 - reteq r12 - - tst r11, r9 - brne .Lnot_word_aligned - - sub r10, 4 - brlt 2f - -1: ld.w r8, r11++ - bfextu r9, r8, 24, 8 - st.b r12[0], r9 - bfextu r9, r8, 16, 8 - st.b r12[0], r9 - bfextu r9, r8, 8, 8 - st.b r12[0], r9 - st.b r12[0], r8 - sub r10, 4 - brge 1b - -2: sub r10, -4 - reteq r12 - -3: ld.ub r8, r11++ - sub r10, 1 - st.b r12[0], r8 - brne 3b - - retal r12 diff --git a/trunk/arch/avr32/mach-at32ap/extint.c b/trunk/arch/avr32/mach-at32ap/extint.c index 4dff1f988900..7da9c5f7a0eb 100644 --- a/trunk/arch/avr32/mach-at32ap/extint.c +++ b/trunk/arch/avr32/mach-at32ap/extint.c @@ -102,7 +102,8 @@ struct irq_chip eim_chip = { .set_type = eim_set_irq_type, }; -static void demux_eim_irq(unsigned int irq, struct irq_desc *desc) +static void demux_eim_irq(unsigned int irq, struct irq_desc *desc, + struct pt_regs *regs) { struct at32_sm *sm = desc->handler_data; struct irq_desc *ext_desc; @@ -120,7 +121,7 @@ static void demux_eim_irq(unsigned int irq, struct irq_desc *desc) ext_irq = i + sm->eim_first_irq; ext_desc = irq_desc + ext_irq; - ext_desc->handle_irq(ext_irq, ext_desc); + ext_desc->handle_irq(ext_irq, ext_desc, regs); } spin_unlock(&sm->lock); diff --git a/trunk/arch/avr32/mach-at32ap/hsmc.h b/trunk/arch/avr32/mach-at32ap/hsmc.h index d1d48e26e393..5681276fafdb 100644 --- a/trunk/arch/avr32/mach-at32ap/hsmc.h +++ b/trunk/arch/avr32/mach-at32ap/hsmc.h @@ -120,8 +120,8 @@ /* Register access macros */ #define hsmc_readl(port,reg) \ - __raw_readl((port)->regs + HSMC_##reg) + readl((port)->regs + HSMC_##reg) #define hsmc_writel(port,reg,value) \ - __raw_writel((value), (port)->regs + HSMC_##reg) + writel((value), (port)->regs + HSMC_##reg) #endif /* __ASM_AVR32_HSMC_H__ */ diff --git a/trunk/arch/avr32/mach-at32ap/intc.c b/trunk/arch/avr32/mach-at32ap/intc.c index eb87a18ad7b2..74f8c9f2f03d 100644 --- a/trunk/arch/avr32/mach-at32ap/intc.c +++ b/trunk/arch/avr32/mach-at32ap/intc.c @@ -52,19 +52,16 @@ static struct intc intc0 = { asmlinkage void do_IRQ(int level, struct pt_regs *regs) { struct irq_desc *desc; - struct pt_regs *old_regs; unsigned int irq; unsigned long status_reg; local_irq_disable(); - old_regs = set_irq_regs(regs); - irq_enter(); irq = intc_readl(&intc0, INTCAUSE0 - 4 * level); desc = irq_desc + irq; - desc->handle_irq(irq, desc); + desc->handle_irq(irq, desc, regs); /* * Clear all interrupt level masks so that we may handle @@ -78,8 +75,6 @@ asmlinkage void do_IRQ(int level, struct pt_regs *regs) sysreg_write(SR, status_reg); irq_exit(); - - set_irq_regs(old_regs); } void __init init_IRQ(void) diff --git a/trunk/arch/avr32/mach-at32ap/intc.h b/trunk/arch/avr32/mach-at32ap/intc.h index 4d3664e43a8e..d289ca2fff13 100644 --- a/trunk/arch/avr32/mach-at32ap/intc.h +++ b/trunk/arch/avr32/mach-at32ap/intc.h @@ -321,9 +321,7 @@ #define INTC_MKBF(name, value) (((value) & ((1 << INTC_##name##_SIZE) - 1)) << INTC_##name##_OFFSET) #define INTC_GETBF(name, value) (((value) >> INTC_##name##_OFFSET) & ((1 << INTC_##name##_SIZE) - 1)) -#define intc_readl(port,reg) \ - __raw_readl((port)->regs + INTC_##reg) -#define intc_writel(port,reg,value) \ - __raw_writel((value), (port)->regs + INTC_##reg) +#define intc_readl(port,reg) readl((port)->regs + INTC_##reg) +#define intc_writel(port,reg,value) writel((value), (port)->regs + INTC_##reg) #endif /* __ASM_AVR32_PERIHP_INTC_H__ */ diff --git a/trunk/arch/avr32/mach-at32ap/pio.h b/trunk/arch/avr32/mach-at32ap/pio.h index 50fa3aca32c5..cfea12351599 100644 --- a/trunk/arch/avr32/mach-at32ap/pio.h +++ b/trunk/arch/avr32/mach-at32ap/pio.h @@ -170,10 +170,8 @@ #define PIO_BFINS(name,value,old) (((old) & ~(((1 << PIO_##name##_SIZE) - 1) << PIO_##name##_OFFSET)) | PIO_BF(name,value)) /* Register access macros */ -#define pio_readl(port,reg) \ - __raw_readl((port)->regs + PIO_##reg) -#define pio_writel(port,reg,value) \ - __raw_writel((value), (port)->regs + PIO_##reg) +#define pio_readl(port,reg) readl((port)->regs + PIO_##reg) +#define pio_writel(port,reg,value) writel((value), (port)->regs + PIO_##reg) void at32_init_pio(struct platform_device *pdev); diff --git a/trunk/arch/avr32/mach-at32ap/sm.h b/trunk/arch/avr32/mach-at32ap/sm.h index cad02b512bcb..27565822ae2a 100644 --- a/trunk/arch/avr32/mach-at32ap/sm.h +++ b/trunk/arch/avr32/mach-at32ap/sm.h @@ -234,9 +234,7 @@ #define SM_BFINS(name,value,old) (((old) & ~(((1 << SM_##name##_SIZE) - 1) << SM_##name##_OFFSET)) | SM_BF(name,value)) /* Register access macros */ -#define sm_readl(port,reg) \ - __raw_readl((port)->regs + SM_##reg) -#define sm_writel(port,reg,value) \ - __raw_writel((value), (port)->regs + SM_##reg) +#define sm_readl(port,reg) readl((port)->regs + SM_##reg) +#define sm_writel(port,reg,value) writel((value), (port)->regs + SM_##reg) #endif /* __ASM_AVR32_SM_H__ */ diff --git a/trunk/arch/avr32/mm/init.c b/trunk/arch/avr32/mm/init.c index 70da6894acc1..3e6c41039808 100644 --- a/trunk/arch/avr32/mm/init.c +++ b/trunk/arch/avr32/mm/init.c @@ -206,7 +206,7 @@ void __init setup_bootmem(void) if (mem_ramdisk) { #ifdef CONFIG_BLK_DEV_INITRD - initrd_start = (unsigned long)__va(mem_ramdisk->addr); + initrd_start = __va(mem_ramdisk->addr); initrd_end = initrd_start + mem_ramdisk->size; print_memory_map("RAMDISK images", mem_ramdisk); diff --git a/trunk/arch/avr32/mm/ioremap.c b/trunk/arch/avr32/mm/ioremap.c index 3437c82434ac..8cfec65e37f7 100644 --- a/trunk/arch/avr32/mm/ioremap.c +++ b/trunk/arch/avr32/mm/ioremap.c @@ -77,8 +77,6 @@ void __iounmap(void __iomem *addr) if ((unsigned long)addr >= P4SEG) return; - if (PXSEG(addr) == P2SEG) - return; p = remove_vm_area((void *)(PAGE_MASK & (unsigned long __force)addr)); if (unlikely(!p)) { diff --git a/trunk/arch/cris/arch-v10/Kconfig b/trunk/arch/cris/arch-v10/Kconfig index c7ea9efd0104..44eb1b9accb3 100644 --- a/trunk/arch/cris/arch-v10/Kconfig +++ b/trunk/arch/cris/arch-v10/Kconfig @@ -323,7 +323,7 @@ config ETRAX_DEF_R_WAITSTATES depends on ETRAX_ARCH_V10 default "95a6" help - Waitstates for SRAM, Flash and peripherals (not DRAM). 95f8 is a + Waitstates for SRAM, Flash and peripherials (not DRAM). 95f8 is a good choice for most Axis products... config ETRAX_DEF_R_BUS_CONFIG diff --git a/trunk/arch/cris/arch-v10/drivers/Kconfig b/trunk/arch/cris/arch-v10/drivers/Kconfig index e7e724bc0ba6..734d5f3a5304 100644 --- a/trunk/arch/cris/arch-v10/drivers/Kconfig +++ b/trunk/arch/cris/arch-v10/drivers/Kconfig @@ -839,7 +839,7 @@ config ETRAX_DS1302_TRICKLE_CHARGE default "0" help This controls the initial value of the trickle charge register. - 0 = disabled (use this if you are unsure or have a non rechargeable battery) + 0 = disabled (use this if you are unsure or have a non rechargable battery) Otherwise the following values can be OR:ed together to control the charge current: 1 = 2kohm, 2 = 4kohm, 3 = 4kohm diff --git a/trunk/arch/cris/arch-v10/drivers/eeprom.c b/trunk/arch/cris/arch-v10/drivers/eeprom.c index 284ebfda03f0..6e1f191a71e3 100644 --- a/trunk/arch/cris/arch-v10/drivers/eeprom.c +++ b/trunk/arch/cris/arch-v10/drivers/eeprom.c @@ -1,7 +1,7 @@ /*!***************************************************************************** *! -*! Implements an interface for i2c compatible eeproms to run under Linux. -*! Supports 2k, 8k(?) and 16k. Uses adaptive timing adjustments by +*! Implements an interface for i2c compatible eeproms to run under linux. +*! Supports 2k, 8k(?) and 16k. Uses adaptive timing adjustents by *! Johan.Adolfsson@axis.com *! *! Probing results: @@ -51,7 +51,7 @@ *! Revision 1.8 2001/06/15 13:24:29 jonashg *! * Added verification of pointers from userspace in read and write. *! * Made busy counter volatile. -*! * Added define for initial write delay. +*! * Added define for inital write delay. *! * Removed warnings by using loff_t instead of unsigned long. *! *! Revision 1.7 2001/06/14 15:26:54 jonashg diff --git a/trunk/arch/cris/arch-v10/drivers/i2c.c b/trunk/arch/cris/arch-v10/drivers/i2c.c index 092c724a645f..6114596c3b33 100644 --- a/trunk/arch/cris/arch-v10/drivers/i2c.c +++ b/trunk/arch/cris/arch-v10/drivers/i2c.c @@ -47,7 +47,7 @@ *! Update Port B register and shadow even when running with hardware support *! to avoid glitches when reading bits *! Never set direction to out in i2c_inbyte -*! Removed incorrect clock toggling at end of i2c_inbyte +*! Removed incorrect clock togling at end of i2c_inbyte *! *! Revision 1.8 2002/08/13 06:31:53 starvik *! Made SDA and SCL line configurable diff --git a/trunk/arch/cris/arch-v10/kernel/kgdb.c b/trunk/arch/cris/arch-v10/kernel/kgdb.c index 07628a13c6c4..34528da98817 100644 --- a/trunk/arch/cris/arch-v10/kernel/kgdb.c +++ b/trunk/arch/cris/arch-v10/kernel/kgdb.c @@ -33,7 +33,7 @@ *! *! Revision 1.2 2002/11/19 14:35:24 starvik *! Changes from linux 2.4 -*! Changed struct initializer syntax to the currently preferred notation +*! Changed struct initializer syntax to the currently prefered notation *! *! Revision 1.1 2001/12/17 13:59:27 bjornw *! Initial revision diff --git a/trunk/arch/cris/arch-v32/drivers/Kconfig b/trunk/arch/cris/arch-v32/drivers/Kconfig index f64624fc4504..a33097f95362 100644 --- a/trunk/arch/cris/arch-v32/drivers/Kconfig +++ b/trunk/arch/cris/arch-v32/drivers/Kconfig @@ -88,7 +88,7 @@ config ETRAX_SERIAL_PORT0_DMA7_IN help Enables the DMA7 input channel for ser0 (ttyS0). If you do not enable DMA, an interrupt for each character will be - used when receiving data. + used when receiveing data. Normally you want to use DMA, unless you use the DMA channel for something else. @@ -157,7 +157,7 @@ config ETRAX_SERIAL_PORT1_DMA5_IN help Enables the DMA5 input channel for ser1 (ttyS1). If you do not enable DMA, an interrupt for each character will be - used when receiving data. + used when receiveing data. Normally you want this on, unless you use the DMA channel for something else. @@ -228,7 +228,7 @@ config ETRAX_SERIAL_PORT2_DMA3_IN help Enables the DMA3 input channel for ser2 (ttyS2). If you do not enable DMA, an interrupt for each character will be - used when receiving data. + used when receiveing data. Normally you want to use DMA, unless you use the DMA channel for something else. @@ -297,7 +297,7 @@ config ETRAX_SERIAL_PORT3_DMA9_IN help Enables the DMA9 input channel for ser3 (ttyS3). If you do not enable DMA, an interrupt for each character will be - used when receiving data. + used when receiveing data. Normally you want to use DMA, unless you use the DMA channel for something else. diff --git a/trunk/arch/cris/arch-v32/drivers/cryptocop.c b/trunk/arch/cris/arch-v32/drivers/cryptocop.c index 2449637e6fc0..ba096ebb0b15 100644 --- a/trunk/arch/cris/arch-v32/drivers/cryptocop.c +++ b/trunk/arch/cris/arch-v32/drivers/cryptocop.c @@ -2051,6 +2051,7 @@ static void cryptocop_job_queue_close(void) spin_lock_irqsave(&cryptocop_process_lock, process_flags); /* Empty the job queue. */ + spin_lock_irqsave(&cryptocop_process_lock, process_flags); for (i = 0; i < cryptocop_prio_no_prios; i++){ if (!list_empty(&(cryptocop_job_queues[i].jobs))){ list_for_each_safe(node, tmp, &(cryptocop_job_queues[i].jobs)) { diff --git a/trunk/arch/frv/kernel/dma.c b/trunk/arch/frv/kernel/dma.c index 156184e17e57..f5de6cf7df4e 100644 --- a/trunk/arch/frv/kernel/dma.c +++ b/trunk/arch/frv/kernel/dma.c @@ -121,14 +121,15 @@ unsigned long frv_dma_inprogress; /* * DMA irq handler - determine channel involved, grab status and call real handler */ -static irqreturn_t dma_irq_handler(int irq, void *_channel) +static irqreturn_t dma_irq_handler(int irq, void *_channel, struct pt_regs *regs) { struct frv_dma_channel *channel = _channel; frv_clear_dma_inprogress(channel - frv_dma_channels); return channel->handler(channel - frv_dma_channels, __get_DMAC(channel->ioaddr, CSTR), - channel->data); + channel->data, + regs); } /* end dma_irq_handler() */ diff --git a/trunk/arch/frv/kernel/irq-mb93091.c b/trunk/arch/frv/kernel/irq-mb93091.c index ad753c1e9b8f..369bc0a7443d 100644 --- a/trunk/arch/frv/kernel/irq-mb93091.c +++ b/trunk/arch/frv/kernel/irq-mb93091.c @@ -80,7 +80,7 @@ static struct irq_chip frv_fpga_pic = { /* * FPGA PIC interrupt handler */ -static irqreturn_t fpga_interrupt(int irq, void *_mask) +static irqreturn_t fpga_interrupt(int irq, void *_mask, struct pt_regs *regs) { uint16_t imr, mask = (unsigned long) _mask; @@ -95,7 +95,7 @@ static irqreturn_t fpga_interrupt(int irq, void *_mask) irq = 31 - irq; mask &= ~(1 << irq); - generic_handle_irq(IRQ_BASE_FPGA + irq); + generic_handle_irq(IRQ_BASE_FPGA + irq, regs); } return IRQ_HANDLED; diff --git a/trunk/arch/frv/kernel/irq-mb93093.c b/trunk/arch/frv/kernel/irq-mb93093.c index e0983f6926ed..a43a22158956 100644 --- a/trunk/arch/frv/kernel/irq-mb93093.c +++ b/trunk/arch/frv/kernel/irq-mb93093.c @@ -79,7 +79,7 @@ static struct irq_chip frv_fpga_pic = { /* * FPGA PIC interrupt handler */ -static irqreturn_t fpga_interrupt(int irq, void *_mask) +static irqreturn_t fpga_interrupt(int irq, void *_mask, struct pt_regs *regs) { uint16_t imr, mask = (unsigned long) _mask; @@ -94,7 +94,7 @@ static irqreturn_t fpga_interrupt(int irq, void *_mask) irq = 31 - irq; mask &= ~(1 << irq); - generic_irq_handle(IRQ_BASE_FPGA + irq); + generic_irq_handle(IRQ_BASE_FPGA + irq, regs); } return IRQ_HANDLED; diff --git a/trunk/arch/frv/kernel/irq-mb93493.c b/trunk/arch/frv/kernel/irq-mb93493.c index c157eeff871d..39c0188a3498 100644 --- a/trunk/arch/frv/kernel/irq-mb93493.c +++ b/trunk/arch/frv/kernel/irq-mb93493.c @@ -90,7 +90,7 @@ static struct irq_chip frv_mb93493_pic = { /* * MB93493 PIC interrupt handler */ -static irqreturn_t mb93493_interrupt(int irq, void *_piqsr) +static irqreturn_t mb93493_interrupt(int irq, void *_piqsr, struct pt_regs *regs) { volatile void *piqsr = _piqsr; uint32_t iqsr; @@ -106,7 +106,7 @@ static irqreturn_t mb93493_interrupt(int irq, void *_piqsr) irq = 31 - irq; iqsr &= ~(1 << irq); - generic_handle_irq(IRQ_BASE_MB93493 + irq); + generic_handle_irq(IRQ_BASE_MB93493 + irq, regs); } return IRQ_HANDLED; diff --git a/trunk/arch/frv/kernel/irq.c b/trunk/arch/frv/kernel/irq.c index 87f360a4ea27..5ac041c7c0a4 100644 --- a/trunk/arch/frv/kernel/irq.c +++ b/trunk/arch/frv/kernel/irq.c @@ -143,7 +143,7 @@ static struct irq_chip frv_cpu_pic = { asmlinkage void do_IRQ(void) { irq_enter(); - generic_handle_irq(__get_IRL()); + generic_handle_irq(__get_IRL(), __frame); irq_exit(); } diff --git a/trunk/arch/frv/kernel/time.c b/trunk/arch/frv/kernel/time.c index ed588d73d7d8..44a9aebc4f5a 100644 --- a/trunk/arch/frv/kernel/time.c +++ b/trunk/arch/frv/kernel/time.c @@ -40,7 +40,7 @@ unsigned long __nongprelbss __dsu_clock_speed_HZ; unsigned long __nongprelbss __serial_clock_speed_HZ; unsigned long __delay_loops_MHz; -static irqreturn_t timer_interrupt(int irq, void *dummy); +static irqreturn_t timer_interrupt(int irq, void *dummy, struct pt_regs *regs); static struct irqaction timer_irq = { timer_interrupt, IRQF_DISABLED, CPU_MASK_NONE, "timer", NULL, NULL @@ -55,7 +55,7 @@ static inline int set_rtc_mmss(unsigned long nowtime) * timer_interrupt() needs to keep up the real-time clock, * as well as call the "do_timer()" routine every clocktick */ -static irqreturn_t timer_interrupt(int irq, void *dummy) +static irqreturn_t timer_interrupt(int irq, void *dummy, struct pt_regs * regs) { /* last time the cmos clock got updated */ static long last_rtc_update = 0; @@ -70,8 +70,8 @@ static irqreturn_t timer_interrupt(int irq, void *dummy) write_seqlock(&xtime_lock); do_timer(1); - update_process_times(user_mode(get_irq_regs())); - profile_tick(CPU_PROFILING); + update_process_times(user_mode(regs)); + profile_tick(CPU_PROFILING, regs); /* * If we have an externally synchronized Linux clock, then update diff --git a/trunk/arch/frv/kernel/vmlinux.lds.S b/trunk/arch/frv/kernel/vmlinux.lds.S index 9c1fb12367fa..f474534ba78a 100644 --- a/trunk/arch/frv/kernel/vmlinux.lds.S +++ b/trunk/arch/frv/kernel/vmlinux.lds.S @@ -44,7 +44,13 @@ SECTIONS __initcall_start = .; .initcall.init : { - INITCALLS + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) } __initcall_end = .; __con_initcall_start = .; diff --git a/trunk/arch/h8300/kernel/vmlinux.lds.S b/trunk/arch/h8300/kernel/vmlinux.lds.S index 756325dd480e..6406c388f88a 100644 --- a/trunk/arch/h8300/kernel/vmlinux.lds.S +++ b/trunk/arch/h8300/kernel/vmlinux.lds.S @@ -118,7 +118,13 @@ SECTIONS . = ALIGN(0x4) ; ___setup_end = .; ___initcall_start = .; - INITCALLS + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) ___initcall_end = .; ___con_initcall_start = .; *(.con_initcall.init) diff --git a/trunk/arch/i386/Kconfig.cpu b/trunk/arch/i386/Kconfig.cpu index fc4f2abccf06..21c9a4e71104 100644 --- a/trunk/arch/i386/Kconfig.cpu +++ b/trunk/arch/i386/Kconfig.cpu @@ -7,7 +7,6 @@ choice config M386 bool "386" - depends on !UML ---help--- This is the processor type of your CPU. This information is used for optimizing purposes. In order to compile a kernel that can run on @@ -302,7 +301,7 @@ config X86_USE_PPRO_CHECKSUM config X86_USE_3DNOW bool - depends on (MCYRIXIII || MK7 || MGEODE_LX) && !UML + depends on MCYRIXIII || MK7 || MGEODE_LX default y config X86_OOSTORE diff --git a/trunk/arch/i386/Makefile b/trunk/arch/i386/Makefile index 0677908dfa06..7cc0b189b82b 100644 --- a/trunk/arch/i386/Makefile +++ b/trunk/arch/i386/Makefile @@ -42,10 +42,6 @@ cflags-$(CONFIG_REGPARM) += -mregparm=3 # temporary until string.h is fixed cflags-y += -ffreestanding -# this works around some issues with generating unwind tables in older gccs -# newer gccs do it by default -cflags-y += -maccumulate-outgoing-args - # Disable unit-at-a-time mode on pre-gcc-4.0 compilers, it makes gcc use # a lot more stack due to the lack of sharing of stacklots: CFLAGS += $(shell if [ $(call cc-version) -lt 0400 ] ; then echo $(call cc-option,-fno-unit-at-a-time); fi ;) @@ -55,8 +51,8 @@ cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) # is .cfi_signal_frame supported too? -cflags-y += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,) -AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,) +cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) +AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) CFLAGS += $(cflags-y) diff --git a/trunk/arch/i386/defconfig b/trunk/arch/i386/defconfig index 97aacd6bd7d8..ee2d79bd8af7 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-rc2-git4 -# Sat Oct 21 03:38:56 2006 +# Linux kernel version: 2.6.18-git7 +# Wed Sep 27 21:53:10 2006 # CONFIG_X86_32=y CONFIG_GENERIC_TIME=y @@ -31,11 +31,9 @@ CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set CONFIG_POSIX_MQUEUE=y # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y @@ -43,10 +41,9 @@ CONFIG_IKCONFIG_PROC=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 is not set +CONFIG_SYSCTL=y CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y # CONFIG_KALLSYMS_EXTRA_PASS is not set @@ -79,7 +76,6 @@ 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 @@ -167,7 +163,6 @@ CONFIG_VM86=y # CONFIG_I8K is not set # CONFIG_X86_REBOOTFIXUPS is not set CONFIG_MICROCODE=y -CONFIG_MICROCODE_OLD_INTERFACE=y CONFIG_X86_MSR=y CONFIG_X86_CPUID=y @@ -182,7 +177,6 @@ CONFIG_HIGHMEM4G=y # CONFIG_HIGHMEM64G is not set CONFIG_PAGE_OFFSET=0xC0000000 CONFIG_HIGHMEM=y -CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y # CONFIG_DISCONTIGMEM_MANUAL is not set @@ -301,7 +295,6 @@ CONFIG_PCI_MMCONFIG=y CONFIG_PCI_MSI=y # CONFIG_PCI_MULTITHREAD_PROBE is not set # CONFIG_PCI_DEBUG is not set -# CONFIG_HT_IRQ is not set CONFIG_ISA_DMA_API=y # CONFIG_ISA is not set # CONFIG_MCA is not set @@ -361,7 +354,6 @@ CONFIG_IP_PNP_DHCP=y # CONFIG_INET_TUNNEL is not set CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y -# CONFIG_INET_XFRM_MODE_BEET is not set CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set @@ -378,10 +370,9 @@ CONFIG_IPV6=y # CONFIG_INET6_TUNNEL is not set CONFIG_INET6_XFRM_MODE_TRANSPORT=y CONFIG_INET6_XFRM_MODE_TUNNEL=y -# CONFIG_INET6_XFRM_MODE_BEET is not set # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set -CONFIG_IPV6_SIT=y # CONFIG_IPV6_TUNNEL is not set +# CONFIG_IPV6_SUBTREES is not set # CONFIG_IPV6_MULTIPLE_TABLES is not set # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set @@ -482,13 +473,6 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set -# -# Misc devices -# -# CONFIG_IBM_ASM is not set -# CONFIG_SGI_IOC4 is not set -# CONFIG_TIFM_CORE is not set - # # ATA/ATAPI/MFM/RLL support # @@ -535,7 +519,6 @@ CONFIG_BLK_DEV_AMD74XX=y # CONFIG_BLK_DEV_CS5535 is not set # CONFIG_BLK_DEV_HPT34X is not set # CONFIG_BLK_DEV_HPT366 is not set -# CONFIG_BLK_DEV_JMICRON is not set # CONFIG_BLK_DEV_SC1200 is not set CONFIG_BLK_DEV_PIIX=y # CONFIG_BLK_DEV_IT821X is not set @@ -632,7 +615,6 @@ CONFIG_AIC79XX_DEBUG_MASK=0 # CONFIG_SCSI_IPR is not set # CONFIG_SCSI_QLOGIC_1280 is not set # CONFIG_SCSI_QLA_FC is not set -# CONFIG_SCSI_QLA_ISCSI is not set # CONFIG_SCSI_LPFC is not set # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set @@ -676,6 +658,7 @@ CONFIG_SATA_INTEL_COMBINED=y # CONFIG_PATA_HPT3X3 is not set # CONFIG_PATA_IT821X is not set # CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_LEGACY is not set # CONFIG_PATA_TRIFLEX is not set # CONFIG_PATA_MPIIX is not set # CONFIG_PATA_OLDPIIX is not set @@ -684,6 +667,7 @@ CONFIG_SATA_INTEL_COMBINED=y # CONFIG_PATA_OPTI is not set # CONFIG_PATA_OPTIDMA is not set # CONFIG_PATA_PDC_OLD is not set +# CONFIG_PATA_QDI is not set # CONFIG_PATA_RADISYS is not set # CONFIG_PATA_RZ1000 is not set # CONFIG_PATA_SC1200 is not set @@ -700,7 +684,6 @@ CONFIG_SATA_INTEL_COMBINED=y CONFIG_MD=y # CONFIG_BLK_DEV_MD is not set CONFIG_BLK_DEV_DM=y -# CONFIG_DM_DEBUG is not set # CONFIG_DM_CRYPT is not set # CONFIG_DM_SNAPSHOT is not set # CONFIG_DM_MIRROR is not set @@ -891,7 +874,6 @@ CONFIG_NET_POLL_CONTROLLER=y # Input device support # CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set # # Userland interfaces @@ -914,7 +896,6 @@ CONFIG_KEYBOARD_ATKBD=y # CONFIG_KEYBOARD_LKKBD is not set # CONFIG_KEYBOARD_XTKBD is not set # CONFIG_KEYBOARD_NEWTON is not set -# CONFIG_KEYBOARD_STOWAWAY is not set CONFIG_INPUT_MOUSE=y CONFIG_MOUSE_PS2=y # CONFIG_MOUSE_SERIAL is not set @@ -1031,7 +1012,6 @@ CONFIG_HANGCHECK_TIMER=y # # Dallas's 1-wire bus # -# CONFIG_W1 is not set # # Hardware Monitoring support @@ -1039,10 +1019,16 @@ CONFIG_HANGCHECK_TIMER=y # CONFIG_HWMON is not set # CONFIG_HWMON_VID is not set +# +# Misc devices +# +# CONFIG_IBM_ASM is not set + # # Multimedia devices # # CONFIG_VIDEO_DEV is not set +CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices @@ -1148,7 +1134,6 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_STORAGE_SDDR55 is not set # CONFIG_USB_STORAGE_JUMPSHOT is not set # CONFIG_USB_STORAGE_ALAUDA is not set -# CONFIG_USB_STORAGE_KARMA is not set # CONFIG_USB_LIBUSUAL is not set # @@ -1202,7 +1187,6 @@ CONFIG_USB_MON=y # # CONFIG_USB_EMI62 is not set # CONFIG_USB_EMI26 is not set -# CONFIG_USB_ADUTUX is not set # CONFIG_USB_AUERSWALD is not set # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set @@ -1210,13 +1194,12 @@ CONFIG_USB_MON=y # CONFIG_USB_LED is not set # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set -# CONFIG_USB_PHIDGET is not set +# CONFIG_USB_PHIDGETKIT is not set +# CONFIG_USB_PHIDGETSERVO is not set # CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_FTDI_ELAN is not set # CONFIG_USB_APPLEDISPLAY is not set # CONFIG_USB_SISUSBVGA is not set # CONFIG_USB_LD is not set -# CONFIG_USB_TRANCEVIBRATOR is not set # CONFIG_USB_TEST is not set # @@ -1286,7 +1269,6 @@ CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y CONFIG_EXT3_FS_POSIX_ACL=y # CONFIG_EXT3_FS_SECURITY is not set -# CONFIG_EXT4DEV_FS is not set CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set CONFIG_FS_MBCACHE=y @@ -1299,7 +1281,6 @@ CONFIG_REISERFS_FS_POSIX_ACL=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set @@ -1310,7 +1291,6 @@ CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set CONFIG_AUTOFS4_FS=y # CONFIG_FUSE_FS is not set -CONFIG_GENERIC_ACL=y # # CD-ROM/DVD Filesystems @@ -1335,10 +1315,8 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" # CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y -CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y CONFIG_TMPFS=y -CONFIG_TMPFS_POSIX_ACL=y CONFIG_HUGETLBFS=y CONFIG_HUGETLB_PAGE=y CONFIG_RAMFS=y @@ -1474,14 +1452,11 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_INFO is not set # CONFIG_DEBUG_FS is not set # CONFIG_DEBUG_VM is not set -# CONFIG_DEBUG_LIST is not set # CONFIG_FRAME_POINTER is not set CONFIG_UNWIND_INFO=y CONFIG_STACK_UNWIND=y # CONFIG_FORCED_INLINING is not set -# CONFIG_HEADERS_CHECK is not set # CONFIG_RCU_TORTURE_TEST is not set -# CONFIG_LKDTM is not set CONFIG_EARLY_PRINTK=y CONFIG_DEBUG_STACKOVERFLOW=y # CONFIG_DEBUG_STACK_USAGE is not set diff --git a/trunk/arch/i386/kernel/acpi/boot.c b/trunk/arch/i386/kernel/acpi/boot.c index d12fb97a5337..92f79cdd9a48 100644 --- a/trunk/arch/i386/kernel/acpi/boot.c +++ b/trunk/arch/i386/kernel/acpi/boot.c @@ -70,7 +70,7 @@ static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id) { return #define PREFIX "ACPI: " -int acpi_noirq; /* skip ACPI IRQ initialization */ +int acpi_noirq __initdata; /* skip ACPI IRQ initialization */ int acpi_pci_disabled __initdata; /* skip ACPI PCI scan and IRQ initialization */ int acpi_ht __initdata = 1; /* enable HT */ @@ -82,7 +82,6 @@ EXPORT_SYMBOL(acpi_strict); acpi_interrupt_flags acpi_sci_flags __initdata; int acpi_sci_override_gsi __initdata; int acpi_skip_timer_override __initdata; -int acpi_use_timer_override __initdata; #ifdef CONFIG_X86_LOCAL_APIC static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE; @@ -333,7 +332,7 @@ acpi_parse_ioapic(acpi_table_entry_header * header, const unsigned long end) /* * Parse Interrupt Source Override for the ACPI SCI */ -static void acpi_sci_ioapic_setup(u32 bus_irq, u32 gsi, u16 polarity, u16 trigger) +static void acpi_sci_ioapic_setup(u32 gsi, u16 polarity, u16 trigger) { if (trigger == 0) /* compatible SCI trigger is level */ trigger = 3; @@ -353,13 +352,13 @@ static void acpi_sci_ioapic_setup(u32 bus_irq, u32 gsi, u16 polarity, u16 trigge * If GSI is < 16, this will update its flags, * else it will create a new mp_irqs[] entry. */ - mp_override_legacy_irq(bus_irq, polarity, trigger, gsi); + mp_override_legacy_irq(gsi, polarity, trigger, gsi); /* * stash over-ride to indicate we've been here * and for later update of acpi_fadt */ - acpi_sci_override_gsi = bus_irq; + acpi_sci_override_gsi = gsi; return; } @@ -377,7 +376,7 @@ acpi_parse_int_src_ovr(acpi_table_entry_header * header, acpi_table_print_madt_entry(header); if (intsrc->bus_irq == acpi_fadt.sci_int) { - acpi_sci_ioapic_setup(intsrc->bus_irq, intsrc->global_irq, + acpi_sci_ioapic_setup(intsrc->global_irq, intsrc->flags.polarity, intsrc->flags.trigger); return 0; @@ -880,7 +879,7 @@ static int __init acpi_parse_madt_ioapic_entries(void) * pretend we got one so we can set the SCI flags. */ if (!acpi_sci_override_gsi) - acpi_sci_ioapic_setup(acpi_fadt.sci_int, acpi_fadt.sci_int, 0, 0); + acpi_sci_ioapic_setup(acpi_fadt.sci_int, 0, 0); /* Fill in identity legacy mapings where no override */ mp_config_acpi_legacy_irqs(); @@ -1301,13 +1300,6 @@ static int __init parse_acpi_skip_timer_override(char *arg) return 0; } early_param("acpi_skip_timer_override", parse_acpi_skip_timer_override); - -static int __init parse_acpi_use_timer_override(char *arg) -{ - acpi_use_timer_override = 1; - return 0; -} -early_param("acpi_use_timer_override", parse_acpi_use_timer_override); #endif /* CONFIG_X86_IO_APIC */ static int __init setup_acpi_sci(char *s) diff --git a/trunk/arch/i386/kernel/acpi/cstate.c b/trunk/arch/i386/kernel/acpi/cstate.c index 20563e52c622..25db49ef1770 100644 --- a/trunk/arch/i386/kernel/acpi/cstate.c +++ b/trunk/arch/i386/kernel/acpi/cstate.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include @@ -42,124 +41,5 @@ void acpi_processor_power_init_bm_check(struct acpi_processor_flags *flags, flags->bm_check = 1; } } -EXPORT_SYMBOL(acpi_processor_power_init_bm_check); - -/* The code below handles cstate entry with monitor-mwait pair on Intel*/ - -struct cstate_entry_s { - struct { - unsigned int eax; - unsigned int ecx; - } states[ACPI_PROCESSOR_MAX_POWER]; -}; -static struct cstate_entry_s *cpu_cstate_entry; /* per CPU ptr */ - -static short mwait_supported[ACPI_PROCESSOR_MAX_POWER]; - -#define MWAIT_SUBSTATE_MASK (0xf) -#define MWAIT_SUBSTATE_SIZE (4) - -#define CPUID_MWAIT_LEAF (5) -#define CPUID5_ECX_EXTENSIONS_SUPPORTED (0x1) -#define CPUID5_ECX_INTERRUPT_BREAK (0x2) - -#define MWAIT_ECX_INTERRUPT_BREAK (0x1) - -#define NATIVE_CSTATE_BEYOND_HALT (2) - -int acpi_processor_ffh_cstate_probe(unsigned int cpu, - struct acpi_processor_cx *cx, struct acpi_power_register *reg) -{ - struct cstate_entry_s *percpu_entry; - struct cpuinfo_x86 *c = cpu_data + cpu; - - cpumask_t saved_mask; - int retval; - unsigned int eax, ebx, ecx, edx; - unsigned int edx_part; - unsigned int cstate_type; /* C-state type and not ACPI C-state type */ - unsigned int num_cstate_subtype; - - if (!cpu_cstate_entry || c->cpuid_level < CPUID_MWAIT_LEAF ) - return -1; - - if (reg->bit_offset != NATIVE_CSTATE_BEYOND_HALT) - return -1; - - percpu_entry = per_cpu_ptr(cpu_cstate_entry, cpu); - percpu_entry->states[cx->index].eax = 0; - percpu_entry->states[cx->index].ecx = 0; - - /* Make sure we are running on right CPU */ - saved_mask = current->cpus_allowed; - retval = set_cpus_allowed(current, cpumask_of_cpu(cpu)); - if (retval) - return -1; - - cpuid(CPUID_MWAIT_LEAF, &eax, &ebx, &ecx, &edx); - - /* Check whether this particular cx_type (in CST) is supported or not */ - cstate_type = (cx->address >> MWAIT_SUBSTATE_SIZE) + 1; - edx_part = edx >> (cstate_type * MWAIT_SUBSTATE_SIZE); - num_cstate_subtype = edx_part & MWAIT_SUBSTATE_MASK; - - retval = 0; - if (num_cstate_subtype < (cx->address & MWAIT_SUBSTATE_MASK)) { - retval = -1; - goto out; - } - /* mwait ecx extensions INTERRUPT_BREAK should be supported for C2/C3 */ - if (!(ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED) || - !(ecx & CPUID5_ECX_INTERRUPT_BREAK)) { - retval = -1; - goto out; - } - percpu_entry->states[cx->index].ecx = MWAIT_ECX_INTERRUPT_BREAK; - - /* Use the hint in CST */ - percpu_entry->states[cx->index].eax = cx->address; - - if (!mwait_supported[cstate_type]) { - mwait_supported[cstate_type] = 1; - printk(KERN_DEBUG "Monitor-Mwait will be used to enter C-%d " - "state\n", cx->type); - } - -out: - set_cpus_allowed(current, saved_mask); - return retval; -} -EXPORT_SYMBOL_GPL(acpi_processor_ffh_cstate_probe); - -void acpi_processor_ffh_cstate_enter(struct acpi_processor_cx *cx) -{ - unsigned int cpu = smp_processor_id(); - struct cstate_entry_s *percpu_entry; - - percpu_entry = per_cpu_ptr(cpu_cstate_entry, cpu); - mwait_idle_with_hints(percpu_entry->states[cx->index].eax, - percpu_entry->states[cx->index].ecx); -} -EXPORT_SYMBOL_GPL(acpi_processor_ffh_cstate_enter); - -static int __init ffh_cstate_init(void) -{ - struct cpuinfo_x86 *c = &boot_cpu_data; - if (c->x86_vendor != X86_VENDOR_INTEL) - return -1; - - cpu_cstate_entry = alloc_percpu(struct cstate_entry_s); - return 0; -} - -static void __exit ffh_cstate_exit(void) -{ - if (cpu_cstate_entry) { - free_percpu(cpu_cstate_entry); - cpu_cstate_entry = NULL; - } -} - -arch_initcall(ffh_cstate_init); -__exitcall(ffh_cstate_exit); +EXPORT_SYMBOL(acpi_processor_power_init_bm_check); diff --git a/trunk/arch/i386/kernel/acpi/earlyquirk.c b/trunk/arch/i386/kernel/acpi/earlyquirk.c index c9841692bb7c..fe799b11ac0a 100644 --- a/trunk/arch/i386/kernel/acpi/earlyquirk.c +++ b/trunk/arch/i386/kernel/acpi/earlyquirk.c @@ -27,17 +27,11 @@ static int __init check_bridge(int vendor, int device) #ifdef CONFIG_ACPI /* According to Nvidia all timer overrides are bogus unless HPET is enabled. */ - if (!acpi_use_timer_override && vendor == PCI_VENDOR_ID_NVIDIA) { + if (vendor == PCI_VENDOR_ID_NVIDIA) { nvidia_hpet_detected = 0; acpi_table_parse(ACPI_HPET, nvidia_hpet_check); if (nvidia_hpet_detected == 0) { acpi_skip_timer_override = 1; - printk(KERN_INFO "Nvidia board " - "detected. Ignoring ACPI " - "timer override.\n"); - printk(KERN_INFO "If you got timer trouble " - "try acpi_use_timer_override\n"); - } } #endif diff --git a/trunk/arch/i386/kernel/alternative.c b/trunk/arch/i386/kernel/alternative.c index 583c238e17fb..28ab80649764 100644 --- a/trunk/arch/i386/kernel/alternative.c +++ b/trunk/arch/i386/kernel/alternative.c @@ -344,7 +344,6 @@ void alternatives_smp_switch(int smp) void __init alternative_instructions(void) { - unsigned long flags; if (no_replacement) { printk(KERN_INFO "(SMP-)alternatives turned off\n"); free_init_pages("SMP alternatives", @@ -352,8 +351,6 @@ void __init alternative_instructions(void) (unsigned long)__smp_alt_end); return; } - - local_irq_save(flags); apply_alternatives(__alt_instructions, __alt_instructions_end); /* switch to patch-once-at-boottime-only mode and free the @@ -389,5 +386,4 @@ void __init alternative_instructions(void) alternatives_smp_switch(0); } #endif - local_irq_restore(flags); } diff --git a/trunk/arch/i386/kernel/apic.c b/trunk/arch/i386/kernel/apic.c index 2fd4b7d927c2..90faae5c5d30 100644 --- a/trunk/arch/i386/kernel/apic.c +++ b/trunk/arch/i386/kernel/apic.c @@ -1193,11 +1193,11 @@ EXPORT_SYMBOL(switch_ipi_to_APIC_timer); * value into /proc/profile. */ -inline void smp_local_timer_interrupt(void) +inline void smp_local_timer_interrupt(struct pt_regs * regs) { - profile_tick(CPU_PROFILING); + profile_tick(CPU_PROFILING, regs); #ifdef CONFIG_SMP - update_process_times(user_mode_vm(get_irq_regs())); + update_process_times(user_mode_vm(regs)); #endif /* @@ -1223,7 +1223,6 @@ inline void smp_local_timer_interrupt(void) fastcall void smp_apic_timer_interrupt(struct pt_regs *regs) { - struct pt_regs *old_regs = set_irq_regs(regs); int cpu = smp_processor_id(); /* @@ -1242,13 +1241,12 @@ fastcall void smp_apic_timer_interrupt(struct pt_regs *regs) * interrupt lock, which is the WrongThing (tm) to do. */ irq_enter(); - smp_local_timer_interrupt(); + smp_local_timer_interrupt(regs); irq_exit(); - set_irq_regs(old_regs); } #ifndef CONFIG_SMP -static void up_apic_timer_interrupt_call(void) +static void up_apic_timer_interrupt_call(struct pt_regs *regs) { int cpu = smp_processor_id(); @@ -1257,11 +1255,11 @@ static void up_apic_timer_interrupt_call(void) */ per_cpu(irq_stat, cpu).apic_timer_irqs++; - smp_local_timer_interrupt(); + smp_local_timer_interrupt(regs); } #endif -void smp_send_timer_broadcast_ipi(void) +void smp_send_timer_broadcast_ipi(struct pt_regs *regs) { cpumask_t mask; @@ -1274,7 +1272,7 @@ void smp_send_timer_broadcast_ipi(void) * We can directly call the apic timer interrupt handler * in UP case. Minus all irq related functions */ - up_apic_timer_interrupt_call(); + up_apic_timer_interrupt_call(regs); #endif } } diff --git a/trunk/arch/i386/kernel/apm.c b/trunk/arch/i386/kernel/apm.c index a60358fe9a49..b42f2d914af3 100644 --- a/trunk/arch/i386/kernel/apm.c +++ b/trunk/arch/i386/kernel/apm.c @@ -198,7 +198,7 @@ * (APM) BIOS Interface Specification, Revision 1.2, February 1996. * * [This document is available from Microsoft at: - * http://www.microsoft.com/whdc/archive/amp_12.mspx] + * http://www.microsoft.com/hwdev/busbios/amp_12.htm] */ #include @@ -540,30 +540,11 @@ static inline void apm_restore_cpus(cpumask_t mask) * Also, we KNOW that for the non error case of apm_bios_call, there * is no useful data returned in the low order 8 bits of eax. */ - -static inline unsigned long __apm_irq_save(void) -{ - unsigned long flags; - local_save_flags(flags); - if (apm_info.allow_ints) { - if (irqs_disabled_flags(flags)) - local_irq_enable(); - } else - local_irq_disable(); - - return flags; -} - -#define apm_irq_save(flags) \ - do { flags = __apm_irq_save(); } while (0) - -static inline void apm_irq_restore(unsigned long flags) -{ - if (irqs_disabled_flags(flags)) +#define APM_DO_CLI \ + if (apm_info.allow_ints) \ + local_irq_enable(); \ + else \ local_irq_disable(); - else if (irqs_disabled()) - local_irq_enable(); -} #ifdef APM_ZERO_SEGS # define APM_DECL_SEGS \ @@ -615,11 +596,12 @@ static u8 apm_bios_call(u32 func, u32 ebx_in, u32 ecx_in, save_desc_40 = gdt[0x40 / 8]; gdt[0x40 / 8] = bad_bios_desc; - apm_irq_save(flags); + local_save_flags(flags); + APM_DO_CLI; APM_DO_SAVE_SEGS; apm_bios_call_asm(func, ebx_in, ecx_in, eax, ebx, ecx, edx, esi); APM_DO_RESTORE_SEGS; - apm_irq_restore(flags); + local_irq_restore(flags); gdt[0x40 / 8] = save_desc_40; put_cpu(); apm_restore_cpus(cpus); @@ -658,11 +640,12 @@ static u8 apm_bios_call_simple(u32 func, u32 ebx_in, u32 ecx_in, u32 *eax) save_desc_40 = gdt[0x40 / 8]; gdt[0x40 / 8] = bad_bios_desc; - apm_irq_save(flags); + local_save_flags(flags); + APM_DO_CLI; APM_DO_SAVE_SEGS; error = apm_bios_call_simple_asm(func, ebx_in, ecx_in, eax); APM_DO_RESTORE_SEGS; - apm_irq_restore(flags); + local_irq_restore(flags); gdt[0x40 / 8] = save_desc_40; put_cpu(); apm_restore_cpus(cpus); diff --git a/trunk/arch/i386/kernel/cpu/mcheck/therm_throt.c b/trunk/arch/i386/kernel/cpu/mcheck/therm_throt.c index 2d8703b7ce65..4f43047de406 100644 --- a/trunk/arch/i386/kernel/cpu/mcheck/therm_throt.c +++ b/trunk/arch/i386/kernel/cpu/mcheck/therm_throt.c @@ -110,15 +110,17 @@ int therm_throt_process(int curr) #ifdef CONFIG_SYSFS /* Add/Remove thermal_throttle interface for CPU device */ -static __cpuinit int thermal_throttle_add_dev(struct sys_device *sys_dev) +static __cpuinit int thermal_throttle_add_dev(struct sys_device * sys_dev) { - return sysfs_create_group(&sys_dev->kobj, &thermal_throttle_attr_group); + sysfs_create_group(&sys_dev->kobj, &thermal_throttle_attr_group); + return 0; } #ifdef CONFIG_HOTPLUG_CPU -static __cpuinit void thermal_throttle_remove_dev(struct sys_device *sys_dev) +static __cpuinit int thermal_throttle_remove_dev(struct sys_device * sys_dev) { - return sysfs_remove_group(&sys_dev->kobj, &thermal_throttle_attr_group); + sysfs_remove_group(&sys_dev->kobj, &thermal_throttle_attr_group); + return 0; } /* Mutex protecting device creation against CPU hotplug */ @@ -131,14 +133,12 @@ static __cpuinit int thermal_throttle_cpu_callback(struct notifier_block *nfb, { unsigned int cpu = (unsigned long)hcpu; struct sys_device *sys_dev; - int err; sys_dev = get_cpu_sysdev(cpu); mutex_lock(&therm_cpu_lock); switch (action) { case CPU_ONLINE: - err = thermal_throttle_add_dev(sys_dev); - WARN_ON(err); + thermal_throttle_add_dev(sys_dev); break; case CPU_DEAD: thermal_throttle_remove_dev(sys_dev); @@ -157,7 +157,6 @@ static struct notifier_block thermal_throttle_cpu_notifier = static __init int thermal_throttle_init_device(void) { unsigned int cpu = 0; - int err; if (!atomic_read(&therm_throt_en)) return 0; @@ -168,10 +167,8 @@ static __init int thermal_throttle_init_device(void) mutex_lock(&therm_cpu_lock); #endif /* connect live CPUs to sysfs */ - for_each_online_cpu(cpu) { - err = thermal_throttle_add_dev(get_cpu_sysdev(cpu)); - WARN_ON(err); - } + for_each_online_cpu(cpu) + thermal_throttle_add_dev(get_cpu_sysdev(cpu)); #ifdef CONFIG_HOTPLUG_CPU mutex_unlock(&therm_cpu_lock); #endif diff --git a/trunk/arch/i386/kernel/cpuid.c b/trunk/arch/i386/kernel/cpuid.c index ab0c327e79dc..fde8bea85cee 100644 --- a/trunk/arch/i386/kernel/cpuid.c +++ b/trunk/arch/i386/kernel/cpuid.c @@ -156,14 +156,14 @@ static struct file_operations cpuid_fops = { .open = cpuid_open, }; -static int cpuid_device_create(int i) +static int cpuid_class_device_create(int i) { int err = 0; - struct device *dev; + struct class_device *class_err; - dev = device_create(cpuid_class, NULL, MKDEV(CPUID_MAJOR, i), "cpu%d",i); - if (IS_ERR(dev)) - err = PTR_ERR(dev); + class_err = class_device_create(cpuid_class, NULL, MKDEV(CPUID_MAJOR, i), NULL, "cpu%d",i); + if (IS_ERR(class_err)) + err = PTR_ERR(class_err); return err; } @@ -174,10 +174,10 @@ static int cpuid_class_cpu_callback(struct notifier_block *nfb, unsigned long ac switch (action) { case CPU_ONLINE: - cpuid_device_create(cpu); + cpuid_class_device_create(cpu); break; case CPU_DEAD: - device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, cpu)); + class_device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, cpu)); break; } return NOTIFY_OK; @@ -206,7 +206,7 @@ static int __init cpuid_init(void) goto out_chrdev; } for_each_online_cpu(i) { - err = cpuid_device_create(i); + err = cpuid_class_device_create(i); if (err != 0) goto out_class; } @@ -218,7 +218,7 @@ static int __init cpuid_init(void) out_class: i = 0; for_each_online_cpu(i) { - device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, i)); + class_device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, i)); } class_destroy(cpuid_class); out_chrdev: @@ -232,7 +232,7 @@ static void __exit cpuid_exit(void) int cpu = 0; for_each_online_cpu(cpu) - device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, cpu)); + class_device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, cpu)); class_destroy(cpuid_class); unregister_chrdev(CPUID_MAJOR, "cpu/cpuid"); unregister_hotcpu_notifier(&cpuid_class_cpu_notifier); diff --git a/trunk/arch/i386/kernel/head.S b/trunk/arch/i386/kernel/head.S index ca31f18d277c..be9d883c62ce 100644 --- a/trunk/arch/i386/kernel/head.S +++ b/trunk/arch/i386/kernel/head.S @@ -317,7 +317,7 @@ is386: movl $2,%ecx # set MP movl %eax,%gs lldt %ax cld # gcc2 wants the direction flag cleared at all times - pushl $0 # fake return address for unwinder + pushl %eax # fake return address #ifdef CONFIG_SMP movb ready, %cl movb $1, ready diff --git a/trunk/arch/i386/kernel/i8253.c b/trunk/arch/i386/kernel/i8253.c index 9a0060b92e32..477b24daff53 100644 --- a/trunk/arch/i386/kernel/i8253.c +++ b/trunk/arch/i386/kernel/i8253.c @@ -109,7 +109,7 @@ static struct clocksource clocksource_pit = { static int __init init_pit_clocksource(void) { - if (num_possible_cpus() > 1) /* PIT does not scale! */ + if (num_possible_cpus() > 4) /* PIT does not scale! */ return 0; clocksource_pit.mult = clocksource_hz2mult(CLOCK_TICK_RATE, 20); diff --git a/trunk/arch/i386/kernel/i8259.c b/trunk/arch/i386/kernel/i8259.c index 62996cd17084..d07ed31f11e3 100644 --- a/trunk/arch/i386/kernel/i8259.c +++ b/trunk/arch/i386/kernel/i8259.c @@ -113,8 +113,7 @@ void make_8259A_irq(unsigned int irq) { disable_irq_nosync(irq); io_apic_irqs &= ~(1<eip); + math_error((void __user *)regs->eip); return IRQ_HANDLED; } @@ -370,8 +369,8 @@ void __init init_ISA_irqs (void) /* * 16 old-style INTA-cycle interrupts: */ - set_irq_chip_and_handler_name(i, &i8259A_chip, - handle_level_irq, "XT"); + set_irq_chip_and_handler(i, &i8259A_chip, + handle_level_irq); } else { /* * 'high' PCI IRQs filled in on demand diff --git a/trunk/arch/i386/kernel/io_apic.c b/trunk/arch/i386/kernel/io_apic.c index 3b7a63e0ed1a..b7287fb499f3 100644 --- a/trunk/arch/i386/kernel/io_apic.c +++ b/trunk/arch/i386/kernel/io_apic.c @@ -91,46 +91,6 @@ static struct irq_pin_list { int apic, pin, next; } irq_2_pin[PIN_MAP_SIZE]; -struct io_apic { - unsigned int index; - unsigned int unused[3]; - unsigned int data; -}; - -static __attribute_const__ struct io_apic __iomem *io_apic_base(int idx) -{ - return (void __iomem *) __fix_to_virt(FIX_IO_APIC_BASE_0 + idx) - + (mp_ioapics[idx].mpc_apicaddr & ~PAGE_MASK); -} - -static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg) -{ - struct io_apic __iomem *io_apic = io_apic_base(apic); - writel(reg, &io_apic->index); - return readl(&io_apic->data); -} - -static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned int value) -{ - struct io_apic __iomem *io_apic = io_apic_base(apic); - writel(reg, &io_apic->index); - writel(value, &io_apic->data); -} - -/* - * Re-write a value: to be used for read-modify-write - * cycles where the read already set up the index register. - * - * Older SiS APIC requires we rewrite the index register - */ -static inline void io_apic_modify(unsigned int apic, unsigned int reg, unsigned int value) -{ - volatile struct io_apic *io_apic = io_apic_base(apic); - if (sis_apic_bug) - writel(reg, &io_apic->index); - writel(value, &io_apic->data); -} - union entry_union { struct { u32 w1, w2; }; struct IO_APIC_route_entry entry; @@ -147,33 +107,11 @@ static struct IO_APIC_route_entry ioapic_read_entry(int apic, int pin) return eu.entry; } -/* - * When we write a new IO APIC routing entry, we need to write the high - * word first! If the mask bit in the low word is clear, we will enable - * 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) { 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); - spin_unlock_irqrestore(&ioapic_lock, flags); -} - -/* - * When we mask an IO APIC routing entry, we need to write the low - * word first, in order to set the mask bit before we change the - * high bits! - */ -static void ioapic_mask_entry(int apic, int pin) -{ - unsigned long flags; - union entry_union eu = { .entry.mask = 1 }; - spin_lock_irqsave(&ioapic_lock, flags); io_apic_write(apic, 0x10 + 2*pin, eu.w1); io_apic_write(apic, 0x11 + 2*pin, eu.w2); @@ -296,7 +234,9 @@ static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin) /* * Disable it in the IO-APIC irq-routing table: */ - ioapic_mask_entry(apic, pin); + memset(&entry, 0, sizeof(entry)); + entry.mask = 1; + ioapic_write_entry(apic, pin, entry); } static void clear_IO_APIC (void) @@ -1244,8 +1184,8 @@ static int __assign_irq_vector(int irq) BUG_ON((unsigned)irq >= NR_IRQ_VECTORS); - if (irq_vector[irq] > 0) - return irq_vector[irq]; + if (IO_APIC_VECTOR(irq) > 0) + return IO_APIC_VECTOR(irq); current_vector += 8; if (current_vector == SYSCALL_VECTOR) @@ -1259,7 +1199,7 @@ static int __assign_irq_vector(int irq) } vector = current_vector; - irq_vector[irq] = vector; + IO_APIC_VECTOR(irq) = vector; return vector; } @@ -1285,13 +1225,11 @@ static void ioapic_register_intr(int irq, int vector, unsigned long trigger) { if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || trigger == IOAPIC_LEVEL) - set_irq_chip_and_handler_name(irq, &ioapic_chip, - handle_fasteoi_irq, "fasteoi"); - else { - irq_desc[irq].status |= IRQ_DELAYED_DISABLE; - set_irq_chip_and_handler_name(irq, &ioapic_chip, - handle_edge_irq, "edge"); - } + set_irq_chip_and_handler(irq, &ioapic_chip, + handle_fasteoi_irq); + else + set_irq_chip_and_handler(irq, &ioapic_chip, + handle_edge_irq); set_intr_gate(vector, interrupt[irq]); } @@ -2029,7 +1967,7 @@ static void ack_ioapic_quirk_irq(unsigned int irq) * operation to prevent an edge-triggered interrupt escaping meanwhile. * The idea is from Manfred Spraul. --macro */ - i = irq_vector[irq]; + i = IO_APIC_VECTOR(irq); v = apic_read(APIC_TMR + ((i & ~0x1f) >> 1)); @@ -2046,7 +1984,7 @@ static void ack_ioapic_quirk_irq(unsigned int irq) static int ioapic_retrigger_irq(unsigned int irq) { - send_IPI_self(irq_vector[irq]); + send_IPI_self(IO_APIC_VECTOR(irq)); return 1; } @@ -2082,7 +2020,7 @@ static inline void init_IO_APIC_traps(void) */ for (irq = 0; irq < NR_IRQS ; irq++) { int tmp = irq; - if (IO_APIC_IRQ(tmp) && !irq_vector[tmp]) { + if (IO_APIC_IRQ(tmp) && !IO_APIC_VECTOR(tmp)) { /* * Hmm.. We don't have an entry for this, * so default to an old-fashioned 8259 @@ -2297,8 +2235,7 @@ static inline void check_timer(void) printk(KERN_INFO "...trying to set up timer as Virtual Wire IRQ..."); disable_8259A_irq(0); - set_irq_chip_and_handler_name(0, &lapic_chip, handle_fasteoi_irq, - "fasteio"); + set_irq_chip_and_handler(0, &lapic_chip, handle_fasteoi_irq); apic_write_around(APIC_LVT0, APIC_DM_FIXED | vector); /* Fixed mode */ enable_8259A_irq(0); @@ -2604,8 +2541,7 @@ int arch_setup_msi_irq(unsigned int irq, struct pci_dev *dev) write_msi_msg(irq, &msg); - set_irq_chip_and_handler_name(irq, &msi_chip, handle_edge_irq, - "edge"); + set_irq_chip_and_handler(irq, &msi_chip, handle_edge_irq); return 0; } @@ -2626,16 +2562,18 @@ void arch_teardown_msi_irq(unsigned int irq) static void target_ht_irq(unsigned int irq, unsigned int dest) { - struct ht_irq_msg msg; - fetch_ht_irq_msg(irq, &msg); + u32 low, high; + low = read_ht_irq_low(irq); + high = read_ht_irq_high(irq); - msg.address_lo &= ~(HT_IRQ_LOW_DEST_ID_MASK); - msg.address_hi &= ~(HT_IRQ_HIGH_DEST_ID_MASK); + low &= ~(HT_IRQ_LOW_DEST_ID_MASK); + high &= ~(HT_IRQ_HIGH_DEST_ID_MASK); - msg.address_lo |= HT_IRQ_LOW_DEST_ID(dest); - msg.address_hi |= HT_IRQ_HIGH_DEST_ID(dest); + low |= HT_IRQ_LOW_DEST_ID(dest); + high |= HT_IRQ_HIGH_DEST_ID(dest); - write_ht_irq_msg(irq, &msg); + write_ht_irq_low(irq, low); + write_ht_irq_high(irq, high); } static void set_ht_irq_affinity(unsigned int irq, cpumask_t mask) @@ -2656,7 +2594,7 @@ static void set_ht_irq_affinity(unsigned int irq, cpumask_t mask) } #endif -static struct irq_chip ht_irq_chip = { +static struct hw_interrupt_type ht_irq_chip = { .name = "PCI-HT", .mask = mask_ht_irq, .unmask = unmask_ht_irq, @@ -2673,7 +2611,7 @@ int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev) vector = assign_irq_vector(irq); if (vector >= 0) { - struct ht_irq_msg msg; + u32 low, high; unsigned dest; cpumask_t tmp; @@ -2681,10 +2619,9 @@ int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev) cpu_set(vector >> 8, tmp); dest = cpu_mask_to_apicid(tmp); - msg.address_hi = HT_IRQ_HIGH_DEST_ID(dest); + high = HT_IRQ_HIGH_DEST_ID(dest); - msg.address_lo = - HT_IRQ_LOW_BASE | + low = HT_IRQ_LOW_BASE | HT_IRQ_LOW_DEST_ID(dest) | HT_IRQ_LOW_VECTOR(vector) | ((INT_DEST_MODE == 0) ? @@ -2696,10 +2633,10 @@ int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev) HT_IRQ_LOW_MT_ARBITRATED) | HT_IRQ_LOW_IRQ_MASKED; - write_ht_irq_msg(irq, &msg); + write_ht_irq_low(irq, low); + write_ht_irq_high(irq, high); - set_irq_chip_and_handler_name(irq, &ht_irq_chip, - handle_edge_irq, "edge"); + set_irq_chip_and_handler(irq, &ht_irq_chip, handle_edge_irq); } return vector; } diff --git a/trunk/arch/i386/kernel/irq.c b/trunk/arch/i386/kernel/irq.c index 3201d421090a..3dd2e180151b 100644 --- a/trunk/arch/i386/kernel/irq.c +++ b/trunk/arch/i386/kernel/irq.c @@ -53,7 +53,6 @@ static union irq_ctx *softirq_ctx[NR_CPUS] __read_mostly; */ fastcall unsigned int do_IRQ(struct pt_regs *regs) { - struct pt_regs *old_regs; /* high bit used in ret_from_ code */ int irq = ~regs->orig_eax; struct irq_desc *desc = irq_desc + irq; @@ -68,7 +67,6 @@ fastcall unsigned int do_IRQ(struct pt_regs *regs) BUG(); } - old_regs = set_irq_regs(regs); irq_enter(); #ifdef CONFIG_DEBUG_STACKOVERFLOW /* Debugging check for stack overflow: is there less than 1KB free? */ @@ -97,7 +95,7 @@ fastcall unsigned int do_IRQ(struct pt_regs *regs) * current stack (which is the irq stack already after all) */ if (curctx != irqctx) { - int arg1, arg2, ebx; + int arg1, arg2, arg3, ebx; /* build the stack frame on the IRQ stack */ isp = (u32*) ((char*)irqctx + sizeof(*irqctx)); @@ -116,17 +114,17 @@ fastcall unsigned int do_IRQ(struct pt_regs *regs) " xchgl %%ebx,%%esp \n" " call *%%edi \n" " movl %%ebx,%%esp \n" - : "=a" (arg1), "=d" (arg2), "=b" (ebx) - : "0" (irq), "1" (desc), "2" (isp), + : "=a" (arg1), "=d" (arg2), "=c" (arg3), "=b" (ebx) + : "0" (irq), "1" (desc), "2" (regs), "3" (isp), "D" (desc->handle_irq) : "memory", "cc" ); } else #endif - desc->handle_irq(irq, desc); + desc->handle_irq(irq, desc, regs); irq_exit(); - set_irq_regs(old_regs); + return 1; } @@ -258,7 +256,7 @@ int show_interrupts(struct seq_file *p, void *v) seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); #endif seq_printf(p, " %8s", irq_desc[i].chip->name); - seq_printf(p, "-%-8s", irq_desc[i].name); + seq_printf(p, "-%s", handle_irq_name(irq_desc[i].handle_irq)); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) diff --git a/trunk/arch/i386/kernel/kprobes.c b/trunk/arch/i386/kernel/kprobes.c index fc79e1e859c4..d98e44b16fe2 100644 --- a/trunk/arch/i386/kernel/kprobes.c +++ b/trunk/arch/i386/kernel/kprobes.c @@ -361,11 +361,8 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) asm volatile ( ".global kretprobe_trampoline\n" "kretprobe_trampoline: \n" " pushf\n" - /* skip cs, eip, orig_eax */ - " subl $12, %esp\n" - " pushl %gs\n" - " pushl %ds\n" - " pushl %es\n" + /* skip cs, eip, orig_eax, es, ds */ + " subl $20, %esp\n" " pushl %eax\n" " pushl %ebp\n" " pushl %edi\n" @@ -376,10 +373,10 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) " movl %esp, %eax\n" " call trampoline_handler\n" /* move eflags to cs */ - " movl 52(%esp), %edx\n" - " movl %edx, 48(%esp)\n" + " movl 48(%esp), %edx\n" + " movl %edx, 44(%esp)\n" /* save true return address on eflags */ - " movl %eax, 52(%esp)\n" + " movl %eax, 48(%esp)\n" " popl %ebx\n" " popl %ecx\n" " popl %edx\n" @@ -387,8 +384,8 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) " popl %edi\n" " popl %ebp\n" " popl %eax\n" - /* skip eip, orig_eax, es, ds, gs */ - " addl $20, %esp\n" + /* skip eip, orig_eax, es, ds */ + " addl $16, %esp\n" " popf\n" " ret\n"); } @@ -407,10 +404,6 @@ fastcall void *__kprobes trampoline_handler(struct pt_regs *regs) INIT_HLIST_HEAD(&empty_rp); spin_lock_irqsave(&kretprobe_lock, flags); head = kretprobe_inst_table_head(current); - /* fixup registers */ - regs->xcs = __KERNEL_CS; - regs->eip = trampoline_address; - regs->orig_eax = 0xffffffff; /* * It is possible to have multiple instances associated with a given @@ -432,7 +425,6 @@ fastcall void *__kprobes trampoline_handler(struct pt_regs *regs) if (ri->rp && ri->rp->handler){ __get_cpu_var(current_kprobe) = &ri->rp->kp; - get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE; ri->rp->handler(ri, regs); __get_cpu_var(current_kprobe) = NULL; } diff --git a/trunk/arch/i386/kernel/microcode.c b/trunk/arch/i386/kernel/microcode.c index 23f5984d0654..9b9479768d5e 100644 --- a/trunk/arch/i386/kernel/microcode.c +++ b/trunk/arch/i386/kernel/microcode.c @@ -577,7 +577,7 @@ static void microcode_init_cpu(int cpu) set_cpus_allowed(current, cpumask_of_cpu(cpu)); mutex_lock(µcode_mutex); collect_cpu_info(cpu); - if (uci->valid && system_state == SYSTEM_RUNNING) + if (uci->valid) cpu_request_microcode(cpu); mutex_unlock(µcode_mutex); set_cpus_allowed(current, old); @@ -656,18 +656,14 @@ static struct attribute_group mc_attr_group = { static int mc_sysdev_add(struct sys_device *sys_dev) { - int err, cpu = sys_dev->id; + int cpu = sys_dev->id; struct ucode_cpu_info *uci = ucode_cpu_info + cpu; if (!cpu_online(cpu)) return 0; - pr_debug("Microcode:CPU %d added\n", cpu); memset(uci, 0, sizeof(*uci)); - - err = sysfs_create_group(&sys_dev->kobj, &mc_attr_group); - if (err) - return err; + sysfs_create_group(&sys_dev->kobj, &mc_attr_group); microcode_init_cpu(cpu); return 0; diff --git a/trunk/arch/i386/kernel/msr.c b/trunk/arch/i386/kernel/msr.c index a773f776c9ea..d535cdbbfd25 100644 --- a/trunk/arch/i386/kernel/msr.c +++ b/trunk/arch/i386/kernel/msr.c @@ -239,14 +239,14 @@ static struct file_operations msr_fops = { .open = msr_open, }; -static int msr_device_create(int i) +static int msr_class_device_create(int i) { int err = 0; - struct device *dev; + struct class_device *class_err; - dev = device_create(msr_class, NULL, MKDEV(MSR_MAJOR, i), "msr%d",i); - if (IS_ERR(dev)) - err = PTR_ERR(dev); + class_err = class_device_create(msr_class, NULL, MKDEV(MSR_MAJOR, i), NULL, "msr%d",i); + if (IS_ERR(class_err)) + err = PTR_ERR(class_err); return err; } @@ -258,10 +258,10 @@ static int msr_class_cpu_callback(struct notifier_block *nfb, switch (action) { case CPU_ONLINE: - msr_device_create(cpu); + msr_class_device_create(cpu); break; case CPU_DEAD: - device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu)); + class_device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu)); break; } return NOTIFY_OK; @@ -290,7 +290,7 @@ static int __init msr_init(void) goto out_chrdev; } for_each_online_cpu(i) { - err = msr_device_create(i); + err = msr_class_device_create(i); if (err != 0) goto out_class; } @@ -302,7 +302,7 @@ static int __init msr_init(void) out_class: i = 0; for_each_online_cpu(i) - device_destroy(msr_class, MKDEV(MSR_MAJOR, i)); + class_device_destroy(msr_class, MKDEV(MSR_MAJOR, i)); class_destroy(msr_class); out_chrdev: unregister_chrdev(MSR_MAJOR, "cpu/msr"); @@ -314,7 +314,7 @@ static void __exit msr_exit(void) { int cpu = 0; for_each_online_cpu(cpu) - device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu)); + class_device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu)); class_destroy(msr_class); unregister_chrdev(MSR_MAJOR, "cpu/msr"); unregister_hotcpu_notifier(&msr_class_cpu_notifier); diff --git a/trunk/arch/i386/kernel/nmi.c b/trunk/arch/i386/kernel/nmi.c index eaafe233a5da..3e8e3adb0489 100644 --- a/trunk/arch/i386/kernel/nmi.c +++ b/trunk/arch/i386/kernel/nmi.c @@ -219,11 +219,11 @@ static int __init check_nmi_watchdog(void) int cpu; /* Enable NMI watchdog for newer systems. - Probably safe on most older systems too, but let's be careful. - IBM ThinkPads use INT10 inside SMM and that allows early NMI inside SMM - which hangs the system. Disable watchdog for all thinkpads */ - if (nmi_watchdog == NMI_DEFAULT && dmi_get_year(DMI_BIOS_DATE) >= 2004 && - !dmi_name_in_vendors("ThinkPad")) + Actually it should be safe for most systems before 2004 too except + for some IBM systems that corrupt registers when NMI happens + during SMM. Unfortunately we don't have more exact information + on these and use this coarse check. */ + if (nmi_watchdog == NMI_DEFAULT && dmi_get_year(DMI_BIOS_DATE) >= 2004) nmi_watchdog = NMI_LOCAL_APIC; if ((nmi_watchdog == NMI_NONE) || (nmi_watchdog == NMI_DEFAULT)) diff --git a/trunk/arch/i386/kernel/pci-dma.c b/trunk/arch/i386/kernel/pci-dma.c index 5c8c6ef1fc5e..25fe66853934 100644 --- a/trunk/arch/i386/kernel/pci-dma.c +++ b/trunk/arch/i386/kernel/pci-dma.c @@ -75,7 +75,7 @@ EXPORT_SYMBOL(dma_free_coherent); int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr, dma_addr_t device_addr, size_t size, int flags) { - void __iomem *mem_base = NULL; + void __iomem *mem_base; int pages = size >> PAGE_SHIFT; int bitmap_size = (pages + 31)/32; @@ -114,8 +114,6 @@ int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr, free1_out: kfree(dev->dma_mem->bitmap); out: - if (mem_base) - iounmap(mem_base); return 0; } EXPORT_SYMBOL(dma_declare_coherent_memory); diff --git a/trunk/arch/i386/kernel/process.c b/trunk/arch/i386/kernel/process.c index dd53c58f64f1..dad02a960e03 100644 --- a/trunk/arch/i386/kernel/process.c +++ b/trunk/arch/i386/kernel/process.c @@ -205,7 +205,7 @@ void cpu_idle(void) void cpu_idle_wait(void) { unsigned int cpu, this_cpu = get_cpu(); - cpumask_t map, tmp = current->cpus_allowed; + cpumask_t map; set_cpus_allowed(current, cpumask_of_cpu(this_cpu)); put_cpu(); @@ -227,8 +227,6 @@ void cpu_idle_wait(void) } cpus_and(map, map, cpu_online_map); } while (!cpus_empty(map)); - - set_cpus_allowed(current, tmp); } EXPORT_SYMBOL_GPL(cpu_idle_wait); @@ -238,28 +236,20 @@ EXPORT_SYMBOL_GPL(cpu_idle_wait); * We execute MONITOR against need_resched and enter optimized wait state * through MWAIT. Whenever someone changes need_resched, we would be woken * up from MWAIT (without an IPI). - * - * New with Core Duo processors, MWAIT can take some hints based on CPU - * capability. */ -void mwait_idle_with_hints(unsigned long eax, unsigned long ecx) +static void mwait_idle(void) { - if (!need_resched()) { + local_irq_enable(); + + while (!need_resched()) { __monitor((void *)¤t_thread_info()->flags, 0, 0); smp_mb(); - if (!need_resched()) - __mwait(eax, ecx); + if (need_resched()) + break; + __mwait(0, 0); } } -/* Default MONITOR/MWAIT with no hints, used for default C1 state */ -static void mwait_idle(void) -{ - local_irq_enable(); - while (!need_resched()) - mwait_idle_with_hints(0, 0); -} - void __devinit select_idle_routine(const struct cpuinfo_x86 *c) { if (cpu_has(c, X86_FEATURE_MWAIT)) { diff --git a/trunk/arch/i386/kernel/setup.c b/trunk/arch/i386/kernel/setup.c index 141041dde74d..000cf03751fe 100644 --- a/trunk/arch/i386/kernel/setup.c +++ b/trunk/arch/i386/kernel/setup.c @@ -846,7 +846,7 @@ efi_find_max_pfn(unsigned long start, unsigned long end, void *arg) static int __init efi_memory_present_wrapper(unsigned long start, unsigned long end, void *arg) { - memory_present(0, PFN_UP(start), PFN_DOWN(end)); + memory_present(0, start, end); return 0; } @@ -1083,15 +1083,16 @@ static unsigned long __init setup_memory(void) void __init zone_sizes_init(void) { - unsigned long max_zone_pfns[MAX_NR_ZONES]; - memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); - max_zone_pfns[ZONE_DMA] = - virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; - max_zone_pfns[ZONE_NORMAL] = max_low_pfn; #ifdef CONFIG_HIGHMEM - max_zone_pfns[ZONE_HIGHMEM] = highend_pfn; + unsigned long max_zone_pfns[MAX_NR_ZONES] = { + virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT, + max_low_pfn, + highend_pfn}; add_active_range(0, 0, highend_pfn); #else + unsigned long max_zone_pfns[MAX_NR_ZONES] = { + virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT, + max_low_pfn}; add_active_range(0, 0, max_low_pfn); #endif diff --git a/trunk/arch/i386/kernel/smp.c b/trunk/arch/i386/kernel/smp.c index 31e5c6573aae..1b080ab8a49f 100644 --- a/trunk/arch/i386/kernel/smp.c +++ b/trunk/arch/i386/kernel/smp.c @@ -321,7 +321,6 @@ 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(); @@ -352,7 +351,6 @@ 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, @@ -607,14 +605,11 @@ 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; @@ -637,7 +632,6 @@ fastcall void smp_call_function_interrupt(struct pt_regs *regs) mb(); atomic_inc(&call_data->finished); } - set_irq_regs(old_regs); } /* diff --git a/trunk/arch/i386/kernel/syscall_table.S b/trunk/arch/i386/kernel/syscall_table.S index 2697e9210e92..7e639f78b0b9 100644 --- a/trunk/arch/i386/kernel/syscall_table.S +++ b/trunk/arch/i386/kernel/syscall_table.S @@ -318,4 +318,3 @@ ENTRY(sys_call_table) .long sys_vmsplice .long sys_move_pages .long sys_getcpu - .long sys_epoll_pwait diff --git a/trunk/arch/i386/kernel/time.c b/trunk/arch/i386/kernel/time.c index 78af572fd17c..58a2d5582419 100644 --- a/trunk/arch/i386/kernel/time.c +++ b/trunk/arch/i386/kernel/time.c @@ -161,7 +161,7 @@ EXPORT_SYMBOL(profile_pc); * Time Stamp Counter value at the time of the timer interrupt, so that * we later on can estimate the time of day more exactly. */ -irqreturn_t timer_interrupt(int irq, void *dev_id) +irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { /* * Here we are in the timer irq handler. We just have irqs locally @@ -188,7 +188,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id) } #endif - do_timer_interrupt_hook(); + do_timer_interrupt_hook(regs); if (MCA_bus) { @@ -201,15 +201,15 @@ irqreturn_t timer_interrupt(int irq, void *dev_id) high bit of the PPI port B (0x61). Note that some PS/2s, notably the 55SX, work fine if this is removed. */ - u8 irq_v = inb_p( 0x61 ); /* read the current state */ - outb_p( irq_v|0x80, 0x61 ); /* reset the IRQ */ + irq = inb_p( 0x61 ); /* read the current state */ + outb_p( irq|0x80, 0x61 ); /* reset the IRQ */ } write_sequnlock(&xtime_lock); #ifdef CONFIG_X86_LOCAL_APIC if (using_apic_timer) - smp_send_timer_broadcast_ipi(); + smp_send_timer_broadcast_ipi(regs); #endif return IRQ_HANDLED; diff --git a/trunk/arch/i386/kernel/time_hpet.c b/trunk/arch/i386/kernel/time_hpet.c index 1a2a979cf6a3..6bf14a4e995e 100644 --- a/trunk/arch/i386/kernel/time_hpet.c +++ b/trunk/arch/i386/kernel/time_hpet.c @@ -441,7 +441,7 @@ int hpet_rtc_dropped_irq(void) return 1; } -irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id) +irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct rtc_time curr_time; unsigned long rtc_int_flag = 0; @@ -480,7 +480,7 @@ irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id) } if (call_rtc_interrupt) { rtc_int_flag |= (RTC_IRQF | (RTC_NUM_INTS << 8)); - rtc_interrupt(rtc_int_flag, dev_id); + rtc_interrupt(rtc_int_flag, dev_id, regs); } return IRQ_HANDLED; } diff --git a/trunk/arch/i386/kernel/traps.c b/trunk/arch/i386/kernel/traps.c index fe9c5e8e7e6f..00489b706d27 100644 --- a/trunk/arch/i386/kernel/traps.c +++ b/trunk/arch/i386/kernel/traps.c @@ -129,19 +129,15 @@ static inline unsigned long print_context_stack(struct thread_info *tinfo, #ifdef CONFIG_FRAME_POINTER while (valid_stack_ptr(tinfo, (void *)ebp)) { - unsigned long new_ebp; addr = *(unsigned long *)(ebp + 4); ops->address(data, addr); /* * break out of recursive entries (such as - * end_of_stack_stop_unwind_function). Also, - * we can never allow a frame pointer to - * move downwards! + * end_of_stack_stop_unwind_function): */ - new_ebp = *(unsigned long *)ebp; - if (new_ebp <= ebp) + if (ebp == *(unsigned long *)ebp) break; - ebp = new_ebp; + ebp = *(unsigned long *)ebp; } #else while (valid_stack_ptr(tinfo, stack)) { diff --git a/trunk/arch/i386/kernel/tsc.c b/trunk/arch/i386/kernel/tsc.c index fbc95828cd74..b8fa0a8b2e47 100644 --- a/trunk/arch/i386/kernel/tsc.c +++ b/trunk/arch/i386/kernel/tsc.c @@ -349,8 +349,8 @@ static int tsc_update_callback(void) int change = 0; /* check to see if we should switch to the safe clocksource: */ - if (clocksource_tsc.rating != 0 && check_tsc_unstable()) { - clocksource_tsc.rating = 0; + if (clocksource_tsc.rating != 50 && check_tsc_unstable()) { + clocksource_tsc.rating = 50; clocksource_reselect(); change = 1; } @@ -461,7 +461,7 @@ static int __init init_tsc_clocksource(void) clocksource_tsc.shift); /* lower the rating if we already know its unstable: */ if (check_tsc_unstable()) - clocksource_tsc.rating = 0; + clocksource_tsc.rating = 50; init_timer(&verify_tsc_freq_timer); verify_tsc_freq_timer.function = verify_tsc_freq; diff --git a/trunk/arch/i386/kernel/vm86.c b/trunk/arch/i386/kernel/vm86.c index cbcd61d6120b..8355d8d87d18 100644 --- a/trunk/arch/i386/kernel/vm86.c +++ b/trunk/arch/i386/kernel/vm86.c @@ -714,7 +714,7 @@ static int irqbits; | (1 << SIGUSR1) | (1 << SIGUSR2) | (1 << SIGIO) | (1 << SIGURG) \ | (1 << SIGUNUSED) ) -static irqreturn_t irq_handler(int intno, void *dev_id) +static irqreturn_t irq_handler(int intno, void *dev_id, struct pt_regs * regs) { int irq_bit; unsigned long flags; diff --git a/trunk/arch/i386/kernel/vmlinux.lds.S b/trunk/arch/i386/kernel/vmlinux.lds.S index c6f84a0322ba..1e7ac1c44ddc 100644 --- a/trunk/arch/i386/kernel/vmlinux.lds.S +++ b/trunk/arch/i386/kernel/vmlinux.lds.S @@ -51,7 +51,6 @@ SECTIONS __tracedata_end = .; /* writeable */ - . = ALIGN(4096); .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */ *(.data) CONSTRUCTORS @@ -127,7 +126,13 @@ SECTIONS __setup_end = .; __initcall_start = .; .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) { - INITCALLS + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) } __initcall_end = .; __con_initcall_start = .; diff --git a/trunk/arch/i386/lib/semaphore.S b/trunk/arch/i386/lib/semaphore.S index c01eb39c0b43..ef6ad9e1a609 100644 --- a/trunk/arch/i386/lib/semaphore.S +++ b/trunk/arch/i386/lib/semaphore.S @@ -152,8 +152,6 @@ ENTRY(__read_lock_failed) #endif -#ifdef CONFIG_RWSEM_XCHGADD_ALGORITHM - /* Fix up special calling conventions */ ENTRY(call_rwsem_down_read_failed) CFI_STARTPROC @@ -216,4 +214,3 @@ ENTRY(call_rwsem_downgrade_wake) CFI_ENDPROC END(call_rwsem_downgrade_wake) -#endif diff --git a/trunk/arch/i386/lib/usercopy.c b/trunk/arch/i386/lib/usercopy.c index d22cfc9d656c..08502fc6d0cb 100644 --- a/trunk/arch/i386/lib/usercopy.c +++ b/trunk/arch/i386/lib/usercopy.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include @@ -180,7 +179,7 @@ __clear_user(void __user *to, unsigned long n) EXPORT_SYMBOL(__clear_user); /** - * strnlen_user: - Get the size of a string in user space. + * strlen_user: - Get the size of a string in user space. * @s: The string to measure. * @n: The maximum valid length * @@ -742,7 +741,7 @@ unsigned long __copy_to_user_ll(void __user *to, const void *from, if (retval == -ENOMEM && is_init(current)) { up_read(¤t->mm->mmap_sem); - congestion_wait(WRITE, HZ/50); + blk_congestion_wait(WRITE, HZ/50); goto survive; } diff --git a/trunk/arch/i386/mach-visws/visws_apic.c b/trunk/arch/i386/mach-visws/visws_apic.c index 38c2b13124d9..5929f884d79b 100644 --- a/trunk/arch/i386/mach-visws/visws_apic.c +++ b/trunk/arch/i386/mach-visws/visws_apic.c @@ -122,7 +122,7 @@ static void end_cobalt_irq(unsigned int irq) spin_unlock_irqrestore(&cobalt_lock, flags); } -static struct irq_chip cobalt_irq_type = { +static struct hw_interrupt_type cobalt_irq_type = { .typename = "Cobalt-APIC", .startup = startup_cobalt_irq, .shutdown = disable_cobalt_irq, @@ -159,7 +159,7 @@ static void end_piix4_master_irq(unsigned int irq) spin_unlock_irqrestore(&cobalt_lock, flags); } -static struct irq_chip piix4_master_irq_type = { +static struct hw_interrupt_type piix4_master_irq_type = { .typename = "PIIX4-master", .startup = startup_piix4_master_irq, .ack = ack_cobalt_irq, @@ -167,8 +167,9 @@ static struct irq_chip piix4_master_irq_type = { }; -static struct irq_chip piix4_virtual_irq_type = { +static struct hw_interrupt_type piix4_virtual_irq_type = { .typename = "PIIX4-virtual", + .startup = startup_8259A_irq, .shutdown = disable_8259A_irq, .enable = enable_8259A_irq, .disable = disable_8259A_irq, @@ -190,7 +191,7 @@ static struct irq_chip piix4_virtual_irq_type = { * enable_irq gets the right irq. This 'master' irq is never directly * manipulated by any driver. */ -static irqreturn_t piix4_master_intr(int irq, void *dev_id) +static irqreturn_t piix4_master_intr(int irq, void *dev_id, struct pt_regs * regs) { int realirq; irq_desc_t *desc; @@ -243,7 +244,7 @@ static irqreturn_t piix4_master_intr(int irq, void *dev_id) kstat_cpu(smp_processor_id()).irqs[realirq]++; if (likely(desc->action != NULL)) - handle_IRQ_event(realirq, desc->action); + handle_IRQ_event(realirq, regs, desc->action); if (!(desc->status & IRQ_DISABLED)) enable_8259A_irq(realirq); diff --git a/trunk/arch/i386/mach-voyager/voyager_basic.c b/trunk/arch/i386/mach-voyager/voyager_basic.c index 8fe7e4593d5f..80b7f2fc4f46 100644 --- a/trunk/arch/i386/mach-voyager/voyager_basic.c +++ b/trunk/arch/i386/mach-voyager/voyager_basic.c @@ -44,7 +44,7 @@ struct voyager_SUS *voyager_SUS = NULL; #ifdef CONFIG_SMP static void -voyager_dump(int dummy1, struct tty_struct *dummy3) +voyager_dump(int dummy1, struct pt_regs *dummy2, struct tty_struct *dummy3) { /* get here via a sysrq */ voyager_smp_dump(); @@ -87,7 +87,7 @@ voyager_detect(struct voyager_bios_info *bios) } void -voyager_system_interrupt(int cpl, void *dev_id) +voyager_system_interrupt(int cpl, void *dev_id, struct pt_regs *regs) { printk("Voyager: detected system interrupt\n"); } @@ -166,7 +166,7 @@ voyager_memory_detect(int region, __u32 *start, __u32 *length) * off the timer tick to the SMP code, since the VIC doesn't have an * internal timer (The QIC does, but that's another story). */ void -voyager_timer_interrupt(void) +voyager_timer_interrupt(struct pt_regs *regs) { if((jiffies & 0x3ff) == 0) { @@ -202,7 +202,7 @@ voyager_timer_interrupt(void) } } #ifdef CONFIG_SMP - smp_vic_timer_interrupt(); + smp_vic_timer_interrupt(regs); #endif } diff --git a/trunk/arch/i386/mach-voyager/voyager_smp.c b/trunk/arch/i386/mach-voyager/voyager_smp.c index f3fea2ad50fe..856c73fcb7e7 100644 --- a/trunk/arch/i386/mach-voyager/voyager_smp.c +++ b/trunk/arch/i386/mach-voyager/voyager_smp.c @@ -85,8 +85,8 @@ static int ack_QIC_CPI(__u8 cpi); static void ack_special_QIC_CPI(__u8 cpi); static void ack_VIC_CPI(__u8 cpi); static void send_CPI_allbutself(__u8 cpi); -static void mask_vic_irq(unsigned int irq); -static void unmask_vic_irq(unsigned int irq); +static void enable_vic_irq(unsigned int irq); +static void disable_vic_irq(unsigned int irq); static unsigned int startup_vic_irq(unsigned int irq); static void enable_local_vic_irq(unsigned int irq); static void disable_local_vic_irq(unsigned int irq); @@ -126,10 +126,10 @@ send_QIC_CPI(__u32 cpuset, __u8 cpi) } static inline void -wrapper_smp_local_timer_interrupt(void) +wrapper_smp_local_timer_interrupt(struct pt_regs *regs) { irq_enter(); - smp_local_timer_interrupt(); + smp_local_timer_interrupt(regs); irq_exit(); } @@ -205,12 +205,15 @@ ack_CPI(__u8 cpi) /* The VIC IRQ descriptors -- these look almost identical to the * 8259 IRQs except that masks and things must be kept per processor */ -static struct irq_chip vic_chip = { - .name = "VIC", - .startup = startup_vic_irq, - .mask = mask_vic_irq, - .unmask = unmask_vic_irq, - .set_affinity = set_vic_irq_affinity, +static struct hw_interrupt_type vic_irq_type = { + .typename = "VIC-level", + .startup = startup_vic_irq, + .shutdown = disable_vic_irq, + .enable = enable_vic_irq, + .disable = disable_vic_irq, + .ack = before_handle_vic_irq, + .end = after_handle_vic_irq, + .set_affinity = set_vic_irq_affinity, }; /* used to count up as CPUs are brought on line (starts at 0) */ @@ -783,7 +786,7 @@ fastcall void smp_vic_sys_interrupt(struct pt_regs *regs) { ack_CPI(VIC_SYS_INT); - printk("Voyager SYSTEM INTERRUPT\n"); + printk("Voyager SYSTEM INTERRUPT\n"); } /* Handle a voyager CMN_INT; These interrupts occur either because of @@ -1132,19 +1135,15 @@ EXPORT_SYMBOL(smp_call_function); fastcall void smp_apic_timer_interrupt(struct pt_regs *regs) { - struct pt_regs *old_regs = set_irq_regs(regs); - wrapper_smp_local_timer_interrupt(); - set_irq_regs(old_regs); + wrapper_smp_local_timer_interrupt(regs); } /* All of the QUAD interrupt GATES */ fastcall void smp_qic_timer_interrupt(struct pt_regs *regs) { - struct pt_regs *old_regs = set_irq_regs(regs); ack_QIC_CPI(QIC_TIMER_CPI); - wrapper_smp_local_timer_interrupt(); - set_irq_regs(old_regs); + wrapper_smp_local_timer_interrupt(regs); } fastcall void @@ -1178,7 +1177,6 @@ smp_qic_call_function_interrupt(struct pt_regs *regs) fastcall void smp_vic_cpi_interrupt(struct pt_regs *regs) { - struct pt_regs *old_regs = set_irq_regs(regs); __u8 cpu = smp_processor_id(); if(is_cpu_quad()) @@ -1187,7 +1185,7 @@ smp_vic_cpi_interrupt(struct pt_regs *regs) ack_VIC_CPI(VIC_CPI_LEVEL0); if(test_and_clear_bit(VIC_TIMER_CPI, &vic_cpi_mailbox[cpu])) - wrapper_smp_local_timer_interrupt(); + wrapper_smp_local_timer_interrupt(regs); if(test_and_clear_bit(VIC_INVALIDATE_CPI, &vic_cpi_mailbox[cpu])) smp_invalidate_interrupt(); if(test_and_clear_bit(VIC_RESCHEDULE_CPI, &vic_cpi_mailbox[cpu])) @@ -1196,7 +1194,6 @@ smp_vic_cpi_interrupt(struct pt_regs *regs) smp_enable_irq_interrupt(); if(test_and_clear_bit(VIC_CALL_FUNCTION_CPI, &vic_cpi_mailbox[cpu])) smp_call_function_interrupt(); - set_irq_regs(old_regs); } static void @@ -1267,10 +1264,10 @@ smp_send_stop(void) /* this function is triggered in time.c when a clock tick fires * we need to re-broadcast the tick to all CPUs */ void -smp_vic_timer_interrupt(void) +smp_vic_timer_interrupt(struct pt_regs *regs) { send_CPI_allbutself(VIC_TIMER_CPI); - smp_local_timer_interrupt(); + smp_local_timer_interrupt(regs); } /* local (per CPU) timer interrupt. It does both profiling and @@ -1282,12 +1279,12 @@ smp_vic_timer_interrupt(void) * value into /proc/profile. */ void -smp_local_timer_interrupt(void) +smp_local_timer_interrupt(struct pt_regs * regs) { int cpu = smp_processor_id(); long weight; - profile_tick(CPU_PROFILING); + profile_tick(CPU_PROFILING, regs); if (--per_cpu(prof_counter, cpu) <= 0) { /* * The multiplier may have changed since the last time we got @@ -1305,7 +1302,7 @@ smp_local_timer_interrupt(void) per_cpu(prof_counter, cpu); } - update_process_times(user_mode_vm(get_irq_regs())); + update_process_times(user_mode_vm(regs)); } if( ((1<> PAGE_SHIFT; - max_zone_pfns[ZONE_NORMAL] = max_low_pfn; - max_zone_pfns[ZONE_HIGHMEM] = highend_pfn; + unsigned long max_zone_pfns[MAX_NR_ZONES] = { + virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT, + max_low_pfn, + highend_pfn + }; /* If SRAT has not registered memory, register it now */ if (find_max_pfn_with_active_regions() == 0) { diff --git a/trunk/arch/i386/pci/common.c b/trunk/arch/i386/pci/common.c index 53ca6e897984..68bce194e688 100644 --- a/trunk/arch/i386/pci/common.c +++ b/trunk/arch/i386/pci/common.c @@ -20,7 +20,6 @@ unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 | PCI_PROBE_MMCONF; -static int pci_bf_sort; int pci_routeirq; int pcibios_last_bus = -1; unsigned long pirq_table_addr; @@ -118,20 +117,6 @@ void __devinit pcibios_fixup_bus(struct pci_bus *b) pci_read_bridge_bases(b); } -/* - * Only use DMI information to set this if nothing was passed - * on the kernel command line (which was parsed earlier). - */ - -static int __devinit set_bf_sort(struct dmi_system_id *d) -{ - if (pci_bf_sort == pci_bf_sort_default) { - pci_bf_sort = pci_dmi_bf; - printk(KERN_INFO "PCI: %s detected, enabling pci=bfsort.\n", d->ident); - } - return 0; -} - /* * Enable renumbering of PCI bus# ranges to reach all PCI busses (Cardbus) */ @@ -145,11 +130,11 @@ static int __devinit assign_all_busses(struct dmi_system_id *d) } #endif -static struct dmi_system_id __devinitdata pciprobe_dmi_table[] = { -#ifdef __i386__ /* * Laptops which need pci=assign-busses to see Cardbus cards */ +static struct dmi_system_id __devinitdata pciprobe_dmi_table[] = { +#ifdef __i386__ { .callback = assign_all_busses, .ident = "Samsung X20 Laptop", @@ -159,38 +144,6 @@ static struct dmi_system_id __devinitdata pciprobe_dmi_table[] = { }, }, #endif /* __i386__ */ - { - .callback = set_bf_sort, - .ident = "Dell PowerEdge 1950", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell"), - DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1950"), - }, - }, - { - .callback = set_bf_sort, - .ident = "Dell PowerEdge 1955", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell"), - DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1955"), - }, - }, - { - .callback = set_bf_sort, - .ident = "Dell PowerEdge 2900", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell"), - DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2900"), - }, - }, - { - .callback = set_bf_sort, - .ident = "Dell PowerEdge 2950", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell"), - DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2950"), - }, - }, {} }; @@ -236,8 +189,6 @@ static int __init pcibios_init(void) pcibios_resource_survey(); - if (pci_bf_sort >= pci_force_bf) - pci_sort_breadthfirst(); #ifdef CONFIG_PCI_BIOS if ((pci_probe & PCI_BIOS_SORT) && !(pci_probe & PCI_NO_SORT)) pcibios_sort(); @@ -252,12 +203,6 @@ char * __devinit pcibios_setup(char *str) if (!strcmp(str, "off")) { pci_probe = 0; return NULL; - } else if (!strcmp(str, "bfsort")) { - pci_bf_sort = pci_force_bf; - return NULL; - } else if (!strcmp(str, "nobfsort")) { - pci_bf_sort = pci_force_nobf; - return NULL; } #ifdef CONFIG_PCI_BIOS else if (!strcmp(str, "bios")) { @@ -343,6 +288,7 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) void pcibios_disable_device (struct pci_dev *dev) { + pcibios_disable_resources(dev); if (pcibios_disable_irq) pcibios_disable_irq(dev); } diff --git a/trunk/arch/i386/pci/direct.c b/trunk/arch/i386/pci/direct.c index 431c9a51b157..5acf0b4743cf 100644 --- a/trunk/arch/i386/pci/direct.c +++ b/trunk/arch/i386/pci/direct.c @@ -256,8 +256,6 @@ static int __init pci_check_type2(void) void __init pci_direct_init(int type) { - if (type == 0) - return; printk(KERN_INFO "PCI: Using configuration type %d\n", type); if (type == 1) raw_pci_ops = &pci_direct_conf1; diff --git a/trunk/arch/i386/pci/fixup.c b/trunk/arch/i386/pci/fixup.c index cde1170b01a1..b60d7e8689ed 100644 --- a/trunk/arch/i386/pci/fixup.c +++ b/trunk/arch/i386/pci/fixup.c @@ -74,6 +74,52 @@ static void __devinit pci_fixup_ncr53c810(struct pci_dev *d) } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, pci_fixup_ncr53c810); +static void __devinit pci_fixup_ide_bases(struct pci_dev *d) +{ + int i; + + /* + * PCI IDE controllers use non-standard I/O port decoding, respect it. + */ + if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE) + return; + DBG("PCI: IDE base address fixup for %s\n", pci_name(d)); + for(i=0; i<4; i++) { + struct resource *r = &d->resource[i]; + if ((r->start & ~0x80) == 0x374) { + r->start |= 2; + r->end = r->start; + } + } +} +DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases); + +static void __devinit pci_fixup_ide_trash(struct pci_dev *d) +{ + int i; + + /* + * Runs the fixup only for the first IDE controller + * (Shai Fultheim - shai@ftcon.com) + */ + static int called = 0; + if (called) + return; + called = 1; + + /* + * There exist PCI IDE controllers which have utter garbage + * in first four base registers. Ignore that. + */ + DBG("PCI: IDE base address trash cleared for %s\n", pci_name(d)); + for(i=0; i<4; i++) + d->resource[i].start = d->resource[i].end = d->resource[i].flags = 0; +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5513, pci_fixup_ide_trash); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_10, pci_fixup_ide_trash); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_11, pci_fixup_ide_trash); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_9, pci_fixup_ide_trash); + static void __devinit pci_fixup_latency(struct pci_dev *d) { /* @@ -302,8 +348,8 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MCH_PC1, pcie_r * From information provided by "Jon Smirl" * * The standard boot ROM sequence for an x86 machine uses the BIOS - * to select an initial video card for boot display. This boot video - * card will have it's BIOS copied to C0000 in system RAM. + * to select an initial video card for boot display. This boot video + * card will have it's BIOS copied to C0000 in system RAM. * IORESOURCE_ROM_SHADOW is used to associate the boot video * card with this copy. On laptops this copy has to be used since * the main ROM may be compressed or combined with another image. @@ -325,17 +371,7 @@ static void __devinit pci_fixup_video(struct pci_dev *pdev) bus = pdev->bus; while (bus) { bridge = bus->self; - - /* - * From information provided by - * "David Miller" - * The bridge control register is valid for PCI header - * type BRIDGE, or CARDBUS. Host to PCI controllers use - * PCI header type NORMAL. - */ - if (bridge - &&((bridge->hdr_type == PCI_HEADER_TYPE_BRIDGE) - ||(bridge->hdr_type == PCI_HEADER_TYPE_CARDBUS))) { + if (bridge) { pci_read_config_word(bridge, PCI_BRIDGE_CONTROL, &config); if (!(config & PCI_BRIDGE_CTL_VGA)) diff --git a/trunk/arch/i386/pci/i386.c b/trunk/arch/i386/pci/i386.c index 43005f044424..10154a2cac68 100644 --- a/trunk/arch/i386/pci/i386.c +++ b/trunk/arch/i386/pci/i386.c @@ -104,24 +104,16 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list) /* Depth-First Search on bus tree */ list_for_each_entry(bus, bus_list, node) { if ((dev = bus->self)) { - for (idx = PCI_BRIDGE_RESOURCES; - idx < PCI_NUM_RESOURCES; idx++) { + for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) { r = &dev->resource[idx]; if (!r->flags) continue; pr = pci_find_parent_resource(dev, r); - if (!r->start || !pr || - request_resource(pr, r) < 0) { - printk(KERN_ERR "PCI: Cannot allocate " - "resource region %d " - "of bridge %s\n", - idx, pci_name(dev)); - /* - * Something is wrong with the region. - * Invalidate the resource to prevent - * child resource allocations in this - * range. - */ + if (!r->start || !pr || request_resource(pr, r) < 0) { + printk(KERN_ERR "PCI: Cannot allocate resource region %d of bridge %s\n", idx, pci_name(dev)); + /* Something is wrong with the region. + Invalidate the resource to prevent child + resource allocations in this range. */ r->flags = 0; } } @@ -139,7 +131,7 @@ static void __init pcibios_allocate_resources(int pass) for_each_pci_dev(dev) { pci_read_config_word(dev, PCI_COMMAND, &command); - for (idx = 0; idx < PCI_ROM_RESOURCE; idx++) { + for(idx = 0; idx < 6; idx++) { r = &dev->resource[idx]; if (r->parent) /* Already allocated */ continue; @@ -150,15 +142,11 @@ static void __init pcibios_allocate_resources(int pass) else disabled = !(command & PCI_COMMAND_MEMORY); if (pass == disabled) { - DBG("PCI: Resource %08lx-%08lx " - "(f=%lx, d=%d, p=%d)\n", + DBG("PCI: Resource %08lx-%08lx (f=%lx, d=%d, p=%d)\n", r->start, r->end, r->flags, disabled, pass); pr = pci_find_parent_resource(dev, r); if (!pr || request_resource(pr, r) < 0) { - printk(KERN_ERR "PCI: Cannot allocate " - "resource region %d " - "of device %s\n", - idx, pci_name(dev)); + printk(KERN_ERR "PCI: Cannot allocate resource region %d of device %s\n", idx, pci_name(dev)); /* We'll assign a new address later */ r->end -= r->start; r->start = 0; @@ -168,16 +156,12 @@ static void __init pcibios_allocate_resources(int pass) if (!pass) { r = &dev->resource[PCI_ROM_RESOURCE]; if (r->flags & IORESOURCE_ROM_ENABLE) { - /* Turn the ROM off, leave the resource region, - * but keep it unregistered. */ + /* Turn the ROM off, leave the resource region, but keep it unregistered. */ u32 reg; - DBG("PCI: Switching off ROM of %s\n", - pci_name(dev)); + DBG("PCI: Switching off ROM of %s\n", pci_name(dev)); r->flags &= ~IORESOURCE_ROM_ENABLE; - pci_read_config_dword(dev, - dev->rom_base_reg, ®); - pci_write_config_dword(dev, dev->rom_base_reg, - reg & ~PCI_ROM_ADDRESS_ENABLE); + pci_read_config_dword(dev, dev->rom_base_reg, ®); + pci_write_config_dword(dev, dev->rom_base_reg, reg & ~PCI_ROM_ADDRESS_ENABLE); } } } @@ -189,11 +173,9 @@ static int __init pcibios_assign_resources(void) struct resource *r, *pr; if (!(pci_probe & PCI_ASSIGN_ROMS)) { - /* - * Try to use BIOS settings for ROMs, otherwise let - * pci_assign_unassigned_resources() allocate the new - * addresses. - */ + /* Try to use BIOS settings for ROMs, otherwise let + pci_assign_unassigned_resources() allocate the new + addresses. */ for_each_pci_dev(dev) { r = &dev->resource[PCI_ROM_RESOURCE]; if (!r->flags || !r->start) @@ -233,9 +215,9 @@ int pcibios_enable_resources(struct pci_dev *dev, int mask) pci_read_config_word(dev, PCI_COMMAND, &cmd); old_cmd = cmd; - for (idx = 0; idx < PCI_NUM_RESOURCES; idx++) { + for(idx = 0; idx < PCI_NUM_RESOURCES; idx++) { /* Only set up the requested stuff */ - if (!(mask & (1 << idx))) + if (!(mask & (1<resource[idx]; @@ -245,9 +227,7 @@ int pcibios_enable_resources(struct pci_dev *dev, int mask) (!(r->flags & IORESOURCE_ROM_ENABLE))) continue; if (!r->start && r->end) { - printk(KERN_ERR "PCI: Device %s not available " - "because of resource collisions\n", - pci_name(dev)); + printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", pci_name(dev)); return -EINVAL; } if (r->flags & IORESOURCE_IO) @@ -256,13 +236,21 @@ int pcibios_enable_resources(struct pci_dev *dev, int mask) cmd |= PCI_COMMAND_MEMORY; } if (cmd != old_cmd) { - printk("PCI: Enabling device %s (%04x -> %04x)\n", - pci_name(dev), old_cmd, cmd); + printk("PCI: Enabling device %s (%04x -> %04x)\n", pci_name(dev), old_cmd, cmd); pci_write_config_word(dev, PCI_COMMAND, cmd); } return 0; } +void pcibios_disable_resources(struct pci_dev *dev) +{ + u16 cmd; + + pci_read_config_word(dev, PCI_COMMAND, &cmd); + cmd &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY); + pci_write_config_word(dev, PCI_COMMAND, cmd); +} + /* * If we set up a device for bus mastering, we need to check the latency * timer as certain crappy BIOSes forget to set it properly. @@ -279,8 +267,7 @@ void pcibios_set_master(struct pci_dev *dev) lat = pcibios_max_latency; else return; - printk(KERN_DEBUG "PCI: Setting latency timer of device %s to %d\n", - pci_name(dev), lat); + printk(KERN_DEBUG "PCI: Setting latency timer of device %s to %d\n", pci_name(dev), lat); pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); } diff --git a/trunk/arch/i386/pci/init.c b/trunk/arch/i386/pci/init.c index b21b6da8ab1d..d028e1b05c36 100644 --- a/trunk/arch/i386/pci/init.c +++ b/trunk/arch/i386/pci/init.c @@ -28,10 +28,6 @@ static __init int pci_access_init(void) #ifdef CONFIG_PCI_DIRECT pci_direct_init(type); #endif - if (!raw_pci_ops) - printk(KERN_ERR - "PCI: Fatal: No config space access function found\n"); - return 0; } arch_initcall(pci_access_init); diff --git a/trunk/arch/i386/pci/irq.c b/trunk/arch/i386/pci/irq.c index e65551cd8216..47f02af74be3 100644 --- a/trunk/arch/i386/pci/irq.c +++ b/trunk/arch/i386/pci/irq.c @@ -255,13 +255,13 @@ static int pirq_via_set(struct pci_dev *router, struct pci_dev *dev, int pirq, i */ static int pirq_via586_get(struct pci_dev *router, struct pci_dev *dev, int pirq) { - static const unsigned int pirqmap[5] = { 3, 2, 5, 1, 1 }; + static const unsigned int pirqmap[4] = { 3, 2, 5, 1 }; return read_config_nybble(router, 0x55, pirqmap[pirq-1]); } static int pirq_via586_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) { - static const unsigned int pirqmap[5] = { 3, 2, 5, 1, 1 }; + static const unsigned int pirqmap[4] = { 3, 2, 5, 1 }; write_config_nybble(router, 0x55, pirqmap[pirq-1], irq); return 1; } @@ -543,12 +543,6 @@ static __init int intel_router_probe(struct irq_router *r, struct pci_dev *route case PCI_DEVICE_ID_INTEL_ICH8_2: case PCI_DEVICE_ID_INTEL_ICH8_3: case PCI_DEVICE_ID_INTEL_ICH8_4: - case PCI_DEVICE_ID_INTEL_ICH9_0: - case PCI_DEVICE_ID_INTEL_ICH9_1: - case PCI_DEVICE_ID_INTEL_ICH9_2: - case PCI_DEVICE_ID_INTEL_ICH9_3: - case PCI_DEVICE_ID_INTEL_ICH9_4: - case PCI_DEVICE_ID_INTEL_ICH9_5: r->name = "PIIX/ICH"; r->get = pirq_piix_get; r->set = pirq_piix_set; @@ -1147,6 +1141,10 @@ static int pirq_enable_irq(struct pci_dev *dev) } dev = temp_dev; if (irq >= 0) { +#ifdef CONFIG_PCI_MSI + if (!platform_legacy_irq(irq)) + irq = IO_APIC_VECTOR(irq); +#endif printk(KERN_INFO "PCI->APIC IRQ transform: %s[%c] -> IRQ %d\n", pci_name(dev), 'A' + pin, irq); dev->irq = irq; diff --git a/trunk/arch/i386/pci/mmconfig.c b/trunk/arch/i386/pci/mmconfig.c index c6b6d9bbc453..d0c3da3aa2aa 100644 --- a/trunk/arch/i386/pci/mmconfig.c +++ b/trunk/arch/i386/pci/mmconfig.c @@ -154,6 +154,38 @@ static struct pci_raw_ops pci_mmcfg = { .write = pci_mmcfg_write, }; + +static __init void pci_mmcfg_insert_resources(void) +{ +#define PCI_MMCFG_RESOURCE_NAME_LEN 19 + int i; + struct resource *res; + char *names; + unsigned num_buses; + + res = kcalloc(PCI_MMCFG_RESOURCE_NAME_LEN + sizeof(*res), + pci_mmcfg_config_num, GFP_KERNEL); + + if (!res) { + printk(KERN_ERR "PCI: Unable to allocate MMCONFIG resources\n"); + return; + } + + names = (void *)&res[pci_mmcfg_config_num]; + for (i = 0; i < pci_mmcfg_config_num; i++, res++) { + num_buses = pci_mmcfg_config[i].end_bus_number - + pci_mmcfg_config[i].start_bus_number + 1; + res->name = names; + snprintf(names, PCI_MMCFG_RESOURCE_NAME_LEN, "PCI MMCONFIG %u", + pci_mmcfg_config[i].pci_segment_group_number); + res->start = pci_mmcfg_config[i].base_address; + res->end = res->start + (num_buses << 20) - 1; + res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; + insert_resource(&iomem_resource, res); + names += PCI_MMCFG_RESOURCE_NAME_LEN; + } +} + /* K8 systems have some devices (typically in the builtin northbridge) that are only accessible using type1 Normally this can be expressed in the MCFG by not listing them @@ -190,6 +222,8 @@ static __init void unreachable_devices(void) } } + + void __init pci_mmcfg_init(int type) { if ((pci_probe & PCI_PROBE_MMCONF) == 0) @@ -217,4 +251,5 @@ void __init pci_mmcfg_init(int type) pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; unreachable_devices(); + pci_mmcfg_insert_resources(); } diff --git a/trunk/arch/i386/pci/pci.h b/trunk/arch/i386/pci/pci.h index a0a25180b61a..1814f74569c6 100644 --- a/trunk/arch/i386/pci/pci.h +++ b/trunk/arch/i386/pci/pci.h @@ -30,19 +30,13 @@ extern unsigned int pci_probe; extern unsigned long pirq_table_addr; -enum pci_bf_sort_state { - pci_bf_sort_default, - pci_force_nobf, - pci_force_bf, - pci_dmi_bf, -}; - /* pci-i386.c */ extern unsigned int pcibios_max_latency; void pcibios_resource_survey(void); int pcibios_enable_resources(struct pci_dev *, int); +void pcibios_disable_resources(struct pci_dev *); /* pci-pc.c */ diff --git a/trunk/arch/ia64/Kconfig b/trunk/arch/ia64/Kconfig index 683b12c6f76c..70f7eb9fed35 100644 --- a/trunk/arch/ia64/Kconfig +++ b/trunk/arch/ia64/Kconfig @@ -341,7 +341,6 @@ config NUMA bool "NUMA support" depends on !IA64_HP_SIM && !FLATMEM default y if IA64_SGI_SN2 - select ACPI_NUMA if ACPI help Say Y to compile the kernel to support NUMA (Non-Uniform Memory Access). This option is for configuring high-end multiprocessor @@ -484,15 +483,6 @@ source "net/Kconfig" source "drivers/Kconfig" -config MSPEC - tristate "Memory special operations driver" - depends on IA64 - select IA64_UNCACHED_ALLOCATOR - help - If you have an ia64 and you want to enable memory special - operations support (formerly known as fetchop), say Y here, - otherwise say N. - source "fs/Kconfig" source "lib/Kconfig" diff --git a/trunk/arch/ia64/configs/sn2_defconfig b/trunk/arch/ia64/configs/sn2_defconfig index 64e951de4e57..0f14a82b856e 100644 --- a/trunk/arch/ia64/configs/sn2_defconfig +++ b/trunk/arch/ia64/configs/sn2_defconfig @@ -1,9 +1,8 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.19-rc1 -# Mon Oct 9 10:53:59 2006 +# Linux kernel version: 2.6.17-rc3 +# Thu Apr 27 11:48:23 2006 # -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # # Code maturity level options @@ -19,22 +18,16 @@ CONFIG_LOCALVERSION="" # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set CONFIG_POSIX_MQUEUE=y # CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_TASKSTATS=y -# CONFIG_TASK_DELAY_ACCT is not set -# CONFIG_UTS_NS is not set +CONFIG_SYSCTL=y # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set CONFIG_CPUSETS=y CONFIG_RELAY=y CONFIG_INITRAMFS_SOURCE="" CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_TASK_XACCT=y -CONFIG_SYSCTL=y # CONFIG_EMBEDDED is not set -# CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y # CONFIG_KALLSYMS_EXTRA_PASS is not set @@ -47,8 +40,6 @@ CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_SHMEM=y CONFIG_SLAB=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 # CONFIG_SLOB is not set @@ -67,7 +58,6 @@ CONFIG_STOP_MACHINE=y # # Block layer # -CONFIG_BLOCK=y # CONFIG_BLK_DEV_IO_TRACE is not set # @@ -99,7 +89,7 @@ CONFIG_EFI=y CONFIG_GENERIC_IOMAP=y CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y CONFIG_IA64_UNCACHED_ALLOCATOR=y -CONFIG_AUDIT_ARCH=y +CONFIG_DMA_IS_DMA32=y # CONFIG_IA64_GENERIC is not set # CONFIG_IA64_DIG is not set # CONFIG_IA64_HP_ZX1 is not set @@ -126,7 +116,6 @@ CONFIG_FORCE_MAX_ZONEORDER=17 CONFIG_SMP=y CONFIG_NR_CPUS=1024 # CONFIG_HOTPLUG_CPU is not set -CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_SCHED_SMT=y CONFIG_PREEMPT=y CONFIG_SELECT_MEMORY_MODEL=y @@ -139,7 +128,6 @@ CONFIG_NEED_MULTIPLE_NODES=y # CONFIG_SPARSEMEM_STATIC is not set CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_MIGRATION=y -CONFIG_RESOURCES_64BIT=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y CONFIG_ARCH_DISCONTIGMEM_ENABLE=y CONFIG_ARCH_FLATMEM_ENABLE=y @@ -147,24 +135,15 @@ CONFIG_ARCH_SPARSEMEM_ENABLE=y CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y CONFIG_NUMA=y CONFIG_NODES_SHIFT=10 -CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_VIRTUAL_MEM_MAP=y CONFIG_HOLES_IN_ZONE=y CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y -CONFIG_HAVE_ARCH_NODEDATA_EXTENSION=y CONFIG_IA32_SUPPORT=y CONFIG_COMPAT=y CONFIG_IA64_MCA_RECOVERY=y CONFIG_PERFMON=y CONFIG_IA64_PALINFO=y CONFIG_SGI_SN=y -# CONFIG_IA64_ESI is not set - -# -# SN Devices -# -CONFIG_SGI_IOC4=y -CONFIG_SGI_IOC3=y # # Firmware Drivers @@ -180,7 +159,6 @@ CONFIG_BINFMT_ELF=y CONFIG_PM=y # CONFIG_PM_LEGACY is not set # CONFIG_PM_DEBUG is not set -# CONFIG_PM_SYSFS_DEPRECATED is not set # # ACPI (Advanced Configuration and Power Interface) Support @@ -188,7 +166,6 @@ CONFIG_PM=y CONFIG_ACPI=y # CONFIG_ACPI_BUTTON is not set # CONFIG_ACPI_FAN is not set -# CONFIG_ACPI_DOCK is not set # CONFIG_ACPI_PROCESSOR is not set CONFIG_ACPI_NUMA=y CONFIG_ACPI_BLACKLIST_YEAR=0 @@ -208,12 +185,7 @@ CONFIG_ACPI_SYSTEM=y # CONFIG_PCI=y CONFIG_PCI_DOMAINS=y -CONFIG_PCIEPORTBUS=y -CONFIG_HOTPLUG_PCI_PCIE=y -# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set -CONFIG_PCIEAER=y # CONFIG_PCI_MSI is not set -# CONFIG_PCI_MULTITHREAD_PROBE is not set # CONFIG_PCI_DEBUG is not set # @@ -243,9 +215,6 @@ CONFIG_NET=y CONFIG_PACKET=y CONFIG_PACKET_MMAP=y CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set # CONFIG_NET_KEY is not set CONFIG_INET=y CONFIG_IP_MULTICAST=y @@ -262,31 +231,19 @@ CONFIG_SYN_COOKIES=y # CONFIG_INET_IPCOMP is not set # CONFIG_INET_XFRM_TUNNEL is not set # CONFIG_INET_TUNNEL is not set -CONFIG_INET_XFRM_MODE_TRANSPORT=y -CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=y CONFIG_INET_DIAG=m CONFIG_INET_TCP_DIAG=m # CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" +CONFIG_TCP_CONG_BIC=y CONFIG_IPV6=m # CONFIG_IPV6_PRIVACY is not set # CONFIG_IPV6_ROUTER_PREF is not set # CONFIG_INET6_AH is not set # CONFIG_INET6_ESP is not set # CONFIG_INET6_IPCOMP is not set -# CONFIG_IPV6_MIP6 is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set -CONFIG_INET6_XFRM_MODE_TRANSPORT=m -CONFIG_INET6_XFRM_MODE_TUNNEL=m -CONFIG_INET6_XFRM_MODE_BEET=m -# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set # CONFIG_IPV6_TUNNEL is not set -# CONFIG_IPV6_SUBTREES is not set -# CONFIG_IPV6_MULTIPLE_TABLES is not set -# CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set # @@ -312,6 +269,7 @@ CONFIG_INET6_XFRM_MODE_BEET=m # CONFIG_ATALK is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set @@ -340,7 +298,6 @@ CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y CONFIG_FW_LOADER=y # CONFIG_DEBUG_DRIVER is not set -# CONFIG_SYS_HYPERVISOR is not set # # Connector - unified userspace <-> kernelspace linker @@ -378,7 +335,6 @@ CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set CONFIG_ATA_OVER_ETH=m @@ -425,7 +381,6 @@ CONFIG_IDEDMA_PCI_AUTO=y # CONFIG_BLK_DEV_CS5530 is not set # CONFIG_BLK_DEV_HPT34X is not set # CONFIG_BLK_DEV_HPT366 is not set -# CONFIG_BLK_DEV_JMICRON is not set # CONFIG_BLK_DEV_SC1200 is not set # CONFIG_BLK_DEV_PIIX is not set # CONFIG_BLK_DEV_IT821X is not set @@ -449,7 +404,6 @@ CONFIG_IDEDMA_AUTO=y # # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y -CONFIG_SCSI_NETLINK=y CONFIG_SCSI_PROC_FS=y # @@ -471,14 +425,12 @@ CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_LOGGING is not set # -# SCSI Transports +# SCSI Transport Attributes # CONFIG_SCSI_SPI_ATTRS=y CONFIG_SCSI_FC_ATTRS=y CONFIG_SCSI_ISCSI_ATTRS=m CONFIG_SCSI_SAS_ATTRS=y -CONFIG_SCSI_SAS_LIBSAS=y -# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set # # SCSI low-level drivers @@ -491,81 +443,45 @@ CONFIG_ISCSI_TCP=m # CONFIG_SCSI_AIC7XXX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_AIC79XX is not set -# CONFIG_SCSI_AIC94XX is not set -# CONFIG_SCSI_ARCMSR is not set # CONFIG_MEGARAID_NEWGEN is not set # CONFIG_MEGARAID_LEGACY is not set # CONFIG_MEGARAID_SAS is not set -# CONFIG_SCSI_HPTIOP is not set +CONFIG_SCSI_SATA=y +# CONFIG_SCSI_SATA_AHCI is not set +# CONFIG_SCSI_SATA_SVW is not set +# CONFIG_SCSI_ATA_PIIX is not set +# CONFIG_SCSI_SATA_MV is not set +# CONFIG_SCSI_SATA_NV is not set +# CONFIG_SCSI_PDC_ADMA is not set +# CONFIG_SCSI_SATA_QSTOR is not set +# CONFIG_SCSI_SATA_PROMISE is not set +# CONFIG_SCSI_SATA_SX4 is not set +# CONFIG_SCSI_SATA_SIL is not set +# CONFIG_SCSI_SATA_SIL24 is not set +# CONFIG_SCSI_SATA_SIS is not set +# CONFIG_SCSI_SATA_ULI is not set +# CONFIG_SCSI_SATA_VIA is not set +CONFIG_SCSI_SATA_VITESSE=y # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set # CONFIG_SCSI_IPS is not set # CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_STEX is not set # CONFIG_SCSI_SYM53C8XX_2 is not set # CONFIG_SCSI_IPR is not set CONFIG_SCSI_QLOGIC_1280=y CONFIG_SCSI_QLA_FC=y -# CONFIG_SCSI_QLA_ISCSI is not set +CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE=y +# CONFIG_SCSI_QLA21XX is not set +CONFIG_SCSI_QLA22XX=y +CONFIG_SCSI_QLA2300=y +CONFIG_SCSI_QLA2322=y +# CONFIG_SCSI_QLA24XX is not set # CONFIG_SCSI_LPFC is not set # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_DEBUG is not set -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# -CONFIG_ATA=y -# CONFIG_SATA_AHCI is not set -# CONFIG_SATA_SVW is not set -# CONFIG_ATA_PIIX is not set -# CONFIG_SATA_MV is not set -# CONFIG_SATA_NV is not set -# CONFIG_PDC_ADMA is not set -# CONFIG_SATA_QSTOR is not set -# CONFIG_SATA_PROMISE is not set -# CONFIG_SATA_SX4 is not set -# CONFIG_SATA_SIL is not set -# CONFIG_SATA_SIL24 is not set -# CONFIG_SATA_SIS is not set -# CONFIG_SATA_ULI is not set -# CONFIG_SATA_VIA is not set -CONFIG_SATA_VITESSE=y -# CONFIG_PATA_ALI is not set -# CONFIG_PATA_AMD is not set -# CONFIG_PATA_ARTOP is not set -# CONFIG_PATA_ATIIXP is not set -# CONFIG_PATA_CMD64X is not set -# CONFIG_PATA_CS5520 is not set -# CONFIG_PATA_CS5530 is not set -# CONFIG_PATA_CYPRESS is not set -# CONFIG_PATA_EFAR is not set -# CONFIG_ATA_GENERIC is not set -# CONFIG_PATA_HPT366 is not set -# CONFIG_PATA_HPT37X is not set -# CONFIG_PATA_HPT3X2N is not set -# CONFIG_PATA_HPT3X3 is not set -# CONFIG_PATA_IT821X is not set -# CONFIG_PATA_JMICRON is not set -# CONFIG_PATA_TRIFLEX is not set -# CONFIG_PATA_MPIIX is not set -# CONFIG_PATA_OLDPIIX is not set -# CONFIG_PATA_NETCELL is not set -# CONFIG_PATA_NS87410 is not set -# CONFIG_PATA_OPTI is not set -# CONFIG_PATA_OPTIDMA is not set -# CONFIG_PATA_PDC_OLD is not set -# CONFIG_PATA_RADISYS is not set -# CONFIG_PATA_RZ1000 is not set -# CONFIG_PATA_SC1200 is not set -# CONFIG_PATA_SERVERWORKS is not set -# CONFIG_PATA_PDC2027X is not set -# CONFIG_PATA_SIL680 is not set -# CONFIG_PATA_SIS is not set -# CONFIG_PATA_VIA is not set -# CONFIG_PATA_WINBOND is not set - # # Multi-device support (RAID and LVM) # @@ -575,12 +491,12 @@ CONFIG_MD_LINEAR=y CONFIG_MD_RAID0=y CONFIG_MD_RAID1=y # CONFIG_MD_RAID10 is not set -CONFIG_MD_RAID456=y +CONFIG_MD_RAID5=y # CONFIG_MD_RAID5_RESHAPE is not set +# CONFIG_MD_RAID6 is not set CONFIG_MD_MULTIPATH=y # CONFIG_MD_FAULTY is not set CONFIG_BLK_DEV_DM=y -# CONFIG_DM_DEBUG is not set CONFIG_DM_CRYPT=m CONFIG_DM_SNAPSHOT=m CONFIG_DM_MIRROR=m @@ -647,7 +563,6 @@ CONFIG_NETDEVICES=y # CONFIG_SK98LIN is not set CONFIG_TIGON3=y # CONFIG_BNX2 is not set -# CONFIG_QLA3XXX is not set # # Ethernet (10000 Mbit) @@ -656,7 +571,6 @@ CONFIG_CHELSIO_T1=m # CONFIG_IXGB is not set CONFIG_S2IO=m # CONFIG_S2IO_NAPI is not set -# CONFIG_MYRI10GE is not set # # Token Ring devices @@ -698,7 +612,6 @@ CONFIG_NET_POLL_CONTROLLER=y # Input device support # CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set # # Userland interfaces @@ -733,7 +646,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y -# CONFIG_VT_HW_CONSOLE_BINDING is not set CONFIG_SERIAL_NONSTANDARD=y # CONFIG_COMPUTONE is not set # CONFIG_ROCKETPORT is not set @@ -747,12 +659,10 @@ CONFIG_SERIAL_NONSTANDARD=y # CONFIG_N_HDLC is not set # CONFIG_SPECIALIX is not set # CONFIG_SX is not set -# CONFIG_RIO is not set # CONFIG_STALDRV is not set CONFIG_SGI_SNSC=y CONFIG_SGI_TIOCX=y CONFIG_SGI_MBCS=m -CONFIG_MSPEC=y # # Serial drivers @@ -791,7 +701,6 @@ CONFIG_EFI_RTC=y # Ftape, the floppy tape device driver # CONFIG_AGP=y -# CONFIG_AGP_SIS is not set # CONFIG_AGP_VIA is not set CONFIG_AGP_SGI_TIOCA=y # CONFIG_DRM is not set @@ -821,6 +730,7 @@ CONFIG_MMTIMER=y # # Dallas's 1-wire bus # +# CONFIG_W1 is not set # # Hardware Monitoring support @@ -831,7 +741,6 @@ CONFIG_MMTIMER=y # # Misc devices # -# CONFIG_TIFM_CORE is not set # # Multimedia devices @@ -847,7 +756,6 @@ CONFIG_MMTIMER=y # # Graphics support # -CONFIG_FIRMWARE_EDID=y # CONFIG_FB is not set # @@ -856,7 +764,6 @@ CONFIG_FIRMWARE_EDID=y CONFIG_VGA_CONSOLE=y # CONFIG_VGACON_SOFT_SCROLLBACK is not set CONFIG_DUMMY_CONSOLE=y -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -887,7 +794,6 @@ CONFIG_USB=m CONFIG_USB_EHCI_HCD=m # CONFIG_USB_EHCI_SPLIT_ISO is not set # CONFIG_USB_EHCI_ROOT_HUB_TT is not set -# CONFIG_USB_EHCI_TT_NEWSCHED is not set # CONFIG_USB_ISP116X_HCD is not set CONFIG_USB_OHCI_HCD=m # CONFIG_USB_OHCI_BIG_ENDIAN is not set @@ -937,7 +843,6 @@ CONFIG_USB_HIDINPUT=y # CONFIG_USB_ATI_REMOTE2 is not set # CONFIG_USB_KEYSPAN_REMOTE is not set # CONFIG_USB_APPLETOUCH is not set -# CONFIG_USB_TRANCEVIBRATOR is not set # # USB Imaging devices @@ -969,18 +874,15 @@ CONFIG_USB_MON=y # # CONFIG_USB_EMI62 is not set # CONFIG_USB_EMI26 is not set -# CONFIG_USB_ADUTUX is not set # CONFIG_USB_AUERSWALD is not set # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set # CONFIG_USB_LED is not set -# CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set -# CONFIG_USB_PHIDGET is not set +# CONFIG_USB_PHIDGETKIT is not set +# CONFIG_USB_PHIDGETSERVO is not set # CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_FTDI_ELAN is not set -# CONFIG_USB_APPLEDISPLAY is not set # CONFIG_USB_SISUSBVGA is not set # CONFIG_USB_LD is not set @@ -1017,37 +919,27 @@ CONFIG_USB_MON=y CONFIG_INFINIBAND=m # CONFIG_INFINIBAND_USER_MAD is not set CONFIG_INFINIBAND_USER_ACCESS=m -CONFIG_INFINIBAND_ADDR_TRANS=y CONFIG_INFINIBAND_MTHCA=m CONFIG_INFINIBAND_MTHCA_DEBUG=y -# CONFIG_INFINIBAND_AMSO1100 is not set CONFIG_INFINIBAND_IPOIB=m CONFIG_INFINIBAND_IPOIB_DEBUG=y # CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set CONFIG_INFINIBAND_SRP=m -# CONFIG_INFINIBAND_ISER is not set - -# -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) -# - -# -# Real Time Clock -# -# CONFIG_RTC_CLASS is not set # -# DMA Engine support +# SN Devices # -# CONFIG_DMA_ENGINE is not set +CONFIG_SGI_IOC4=y +CONFIG_SGI_IOC3=y # -# DMA Clients +# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) # # -# DMA Devices +# Real Time Clock # +# CONFIG_RTC_CLASS is not set # # File systems @@ -1073,16 +965,15 @@ CONFIG_REISERFS_FS_SECURITY=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y CONFIG_XFS_FS=y +CONFIG_XFS_EXPORT=y CONFIG_XFS_QUOTA=y # CONFIG_XFS_SECURITY is not set CONFIG_XFS_POSIX_ACL=y CONFIG_XFS_RT=y -# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y CONFIG_QUOTA=y # CONFIG_QFMT_V1 is not set # CONFIG_QFMT_V2 is not set @@ -1116,10 +1007,8 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" # CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y -CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set CONFIG_HUGETLBFS=y CONFIG_HUGETLB_PAGE=y CONFIG_RAMFS=y @@ -1157,7 +1046,7 @@ CONFIG_NFSD_V4=y CONFIG_NFSD_TCP=y CONFIG_LOCKD=m CONFIG_LOCKD_V4=y -CONFIG_EXPORTFS=m +CONFIG_EXPORTFS=y CONFIG_NFS_COMMON=y CONFIG_SUNRPC=m CONFIG_SUNRPC_GSS=m @@ -1167,9 +1056,7 @@ CONFIG_SMB_FS=m # CONFIG_SMB_NLS_DEFAULT is not set CONFIG_CIFS=m # CONFIG_CIFS_STATS is not set -# CONFIG_CIFS_WEAK_PW_HASH is not set # CONFIG_CIFS_XATTR is not set -# CONFIG_CIFS_DEBUG2 is not set # CONFIG_CIFS_EXPERIMENTAL is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -1241,10 +1128,6 @@ CONFIG_NLS_ISO8859_1=y # CONFIG_NLS_KOI8_U is not set CONFIG_NLS_UTF8=y -# -# Distributed Lock Manager -# - # # Library routines # @@ -1255,11 +1138,9 @@ CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=m CONFIG_ZLIB_DEFLATE=m CONFIG_GENERIC_ALLOCATOR=y -CONFIG_PLIST=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y CONFIG_GENERIC_PENDING_IRQ=y -CONFIG_IRQ_PER_CPU=y # # Instrumentation Support @@ -1271,26 +1152,20 @@ CONFIG_IRQ_PER_CPU=y # Kernel hacking # # CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_MUST_CHECK=y CONFIG_MAGIC_SYSRQ=y -# CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_KERNEL=y CONFIG_LOG_BUF_SHIFT=20 CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_RT_MUTEX_TESTER is not set -# CONFIG_DEBUG_SPINLOCK is not set +CONFIG_DEBUG_PREEMPT=y # CONFIG_DEBUG_MUTEXES is not set -# CONFIG_DEBUG_RWSEMS is not set +# CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set -# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set CONFIG_DEBUG_INFO=y # CONFIG_DEBUG_FS is not set # CONFIG_DEBUG_VM is not set -# CONFIG_DEBUG_LIST is not set CONFIG_FORCED_INLINING=y # CONFIG_RCU_TORTURE_TEST is not set CONFIG_IA64_GRANULE_16MB=y @@ -1311,10 +1186,6 @@ CONFIG_SYSVIPC_COMPAT=y # Cryptographic options # CONFIG_CRYPTO=y -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_BLKCIPHER=m -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_MANAGER=m CONFIG_CRYPTO_HMAC=y # CONFIG_CRYPTO_NULL is not set # CONFIG_CRYPTO_MD4 is not set @@ -1324,8 +1195,6 @@ CONFIG_CRYPTO_SHA1=m # CONFIG_CRYPTO_SHA512 is not set # CONFIG_CRYPTO_WP512 is not set # CONFIG_CRYPTO_TGR192 is not set -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_CBC=m CONFIG_CRYPTO_DES=m # CONFIG_CRYPTO_BLOWFISH is not set # CONFIG_CRYPTO_TWOFISH is not set diff --git a/trunk/arch/ia64/hp/common/sba_iommu.c b/trunk/arch/ia64/hp/common/sba_iommu.c index 14691cda05c3..db8e1fcfa047 100644 --- a/trunk/arch/ia64/hp/common/sba_iommu.c +++ b/trunk/arch/ia64/hp/common/sba_iommu.c @@ -75,7 +75,7 @@ ** If a device prefetches beyond the end of a valid pdir entry, it will cause ** a hard failure, ie. MCA. Version 3.0 and later of the zx1 LBA should ** disconnect on 4k boundaries and prevent such issues. If the device is -** particularly aggressive, this option will keep the entire pdir valid such +** particularly agressive, this option will keep the entire pdir valid such ** that prefetching will hit a valid address. This could severely impact ** error containment, and is therefore off by default. The page that is ** used for spill-over is poisoned, so that should help debugging somewhat. @@ -258,10 +258,10 @@ static u64 prefetch_spill_page; /* ** DMA_CHUNK_SIZE is used by the SCSI mid-layer to break up -** (or rather not merge) DMAs into manageable chunks. +** (or rather not merge) DMA's into managable chunks. ** On parisc, this is more of the software/tuning constraint -** rather than the HW. I/O MMU allocation algorithms can be -** faster with smaller sizes (to some degree). +** rather than the HW. I/O MMU allocation alogorithms can be +** faster with smaller size is (to some degree). */ #define DMA_CHUNK_SIZE (BITS_PER_LONG*iovp_size) diff --git a/trunk/arch/ia64/hp/sim/Kconfig b/trunk/arch/ia64/hp/sim/Kconfig index f92306bbedb8..18ccb1266e18 100644 --- a/trunk/arch/ia64/hp/sim/Kconfig +++ b/trunk/arch/ia64/hp/sim/Kconfig @@ -13,8 +13,8 @@ config HP_SIMSERIAL_CONSOLE depends on HP_SIMSERIAL config HP_SIMSCSI - bool "Simulated SCSI disk" - depends on SCSI=y + tristate "Simulated SCSI disk" + depends on SCSI endmenu diff --git a/trunk/arch/ia64/hp/sim/hpsim_irq.c b/trunk/arch/ia64/hp/sim/hpsim_irq.c index c2f58ff364e7..8145547bb52d 100644 --- a/trunk/arch/ia64/hp/sim/hpsim_irq.c +++ b/trunk/arch/ia64/hp/sim/hpsim_irq.c @@ -27,7 +27,7 @@ hpsim_set_affinity_noop (unsigned int a, cpumask_t b) } static struct hw_interrupt_type irq_type_hp_sim = { - .name = "hpsim", + .typename = "hpsim", .startup = hpsim_irq_startup, .shutdown = hpsim_irq_noop, .enable = hpsim_irq_noop, diff --git a/trunk/arch/ia64/hp/sim/simeth.c b/trunk/arch/ia64/hp/sim/simeth.c index 424e9257c9a0..e1a1b11473e2 100644 --- a/trunk/arch/ia64/hp/sim/simeth.c +++ b/trunk/arch/ia64/hp/sim/simeth.c @@ -54,7 +54,7 @@ static int simeth_close(struct net_device *dev); static int simeth_tx(struct sk_buff *skb, struct net_device *dev); static int simeth_rx(struct net_device *dev); static struct net_device_stats *simeth_get_stats(struct net_device *dev); -static irqreturn_t simeth_interrupt(int irq, void *dev_id); +static irqreturn_t simeth_interrupt(int irq, void *dev_id, struct pt_regs * regs); static void set_multicast_list(struct net_device *dev); static int simeth_device_event(struct notifier_block *this,unsigned long event, void *ptr); @@ -87,7 +87,7 @@ static int simeth_debug; /* set to 1 to get debug information */ */ static struct notifier_block simeth_dev_notifier = { simeth_device_event, - NULL + 0 }; @@ -497,7 +497,7 @@ simeth_rx(struct net_device *dev) * Interrupt handler (Yes, we can do it too !!!) */ static irqreturn_t -simeth_interrupt(int irq, void *dev_id) +simeth_interrupt(int irq, void *dev_id, struct pt_regs * regs) { struct net_device *dev = dev_id; diff --git a/trunk/arch/ia64/hp/sim/simscsi.c b/trunk/arch/ia64/hp/sim/simscsi.c index bb87682bbb1b..8f0a16a79a67 100644 --- a/trunk/arch/ia64/hp/sim/simscsi.c +++ b/trunk/arch/ia64/hp/sim/simscsi.c @@ -103,7 +103,7 @@ simscsi_interrupt (unsigned long val) while ((sc = queue[rd].sc) != 0) { atomic_dec(&num_reqs); - queue[rd].sc = NULL; + queue[rd].sc = 0; if (DBG) printk("simscsi_interrupt: done with %ld\n", sc->serial_number); (*sc->scsi_done)(sc); diff --git a/trunk/arch/ia64/hp/sim/simserial.c b/trunk/arch/ia64/hp/sim/simserial.c index caab986af70c..246eb3d3757a 100644 --- a/trunk/arch/ia64/hp/sim/simserial.c +++ b/trunk/arch/ia64/hp/sim/simserial.c @@ -92,7 +92,7 @@ static struct serial_uart_config uart_config[] = { { "ST16650V2", 32, UART_CLEAR_FIFO | UART_USE_FIFO | UART_STARTECH }, { "TI16750", 64, UART_CLEAR_FIFO | UART_USE_FIFO}, - { NULL, 0} + { 0, 0} }; struct tty_driver *hp_simserial_driver; @@ -130,7 +130,7 @@ static void rs_start(struct tty_struct *tty) #endif } -static void receive_chars(struct tty_struct *tty) +static void receive_chars(struct tty_struct *tty, struct pt_regs *regs) { unsigned char ch; static unsigned char seen_esc = 0; @@ -152,7 +152,7 @@ static void receive_chars(struct tty_struct *tty) ch = ia64_ssc(0, 0, 0, 0, SSC_GETCHAR); while (!ch); - handle_sysrq(ch, NULL); + handle_sysrq(ch, regs, NULL); } #endif seen_esc = 0; @@ -170,7 +170,7 @@ static void receive_chars(struct tty_struct *tty) /* * This is the serial driver's interrupt routine for a single port */ -static irqreturn_t rs_interrupt_single(int irq, void *dev_id) +static irqreturn_t rs_interrupt_single(int irq, void *dev_id, struct pt_regs * regs) { struct async_struct * info; @@ -187,7 +187,7 @@ static irqreturn_t rs_interrupt_single(int irq, void *dev_id) * pretty simple in our case, because we only get interrupts * on inbound traffic */ - receive_chars(info->tty); + receive_chars(info->tty, regs); return IRQ_HANDLED; } @@ -555,7 +555,7 @@ static void shutdown(struct async_struct * info) if (info->xmit.buf) { free_page((unsigned long) info->xmit.buf); - info->xmit.buf = NULL; + info->xmit.buf = 0; } if (info->tty) set_bit(TTY_IO_ERROR, &info->tty->flags); @@ -628,7 +628,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp) if (tty->driver->flush_buffer) tty->driver->flush_buffer(tty); if (tty->ldisc.flush_buffer) tty->ldisc.flush_buffer(tty); info->event = 0; - info->tty = NULL; + info->tty = 0; if (info->blocked_open) { if (info->close_delay) schedule_timeout_interruptible(info->close_delay); @@ -668,7 +668,7 @@ static void rs_hangup(struct tty_struct *tty) info->event = 0; state->count = 0; info->flags &= ~ASYNC_NORMAL_ACTIVE; - info->tty = NULL; + info->tty = 0; wake_up_interruptible(&info->open_wait); } @@ -714,7 +714,7 @@ startup(struct async_struct *info) { unsigned long flags; int retval=0; - irq_handler_t handler; + irqreturn_t (*handler)(int, void *, struct pt_regs *); struct serial_state *state= info->state; unsigned long page; @@ -769,7 +769,7 @@ startup(struct async_struct *info) /* * Insert serial port into IRQ chain. */ - info->prev_port = NULL; + info->prev_port = 0; info->next_port = IRQ_ports[state->irq]; if (info->next_port) info->next_port->prev_port = info; diff --git a/trunk/arch/ia64/kernel/acpi.c b/trunk/arch/ia64/kernel/acpi.c index 73ef4a85b861..32c3abededc6 100644 --- a/trunk/arch/ia64/kernel/acpi.c +++ b/trunk/arch/ia64/kernel/acpi.c @@ -64,6 +64,9 @@ EXPORT_SYMBOL(pm_idle); void (*pm_power_off) (void); EXPORT_SYMBOL(pm_power_off); +unsigned char acpi_kbd_controller_present = 1; +unsigned char acpi_legacy_devices; + unsigned int acpi_cpei_override; unsigned int acpi_cpei_phys_cpuid; @@ -625,6 +628,12 @@ static int __init acpi_parse_fadt(unsigned long phys_addr, unsigned long size) fadt = (struct fadt_descriptor *)fadt_header; + if (!(fadt->iapc_boot_arch & BAF_8042_KEYBOARD_CONTROLLER)) + acpi_kbd_controller_present = 0; + + if (fadt->iapc_boot_arch & BAF_LEGACY_DEVICES) + acpi_legacy_devices = 1; + acpi_register_gsi(fadt->sci_int, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW); return 0; } diff --git a/trunk/arch/ia64/kernel/iosapic.c b/trunk/arch/ia64/kernel/iosapic.c index 60d64950e3c2..9bf15fefa7e4 100644 --- a/trunk/arch/ia64/kernel/iosapic.c +++ b/trunk/arch/ia64/kernel/iosapic.c @@ -426,7 +426,7 @@ iosapic_end_level_irq (unsigned int irq) #define iosapic_ack_level_irq nop struct hw_interrupt_type irq_type_iosapic_level = { - .name = "IO-SAPIC-level", + .typename = "IO-SAPIC-level", .startup = iosapic_startup_level_irq, .shutdown = iosapic_shutdown_level_irq, .enable = iosapic_enable_level_irq, @@ -473,7 +473,7 @@ iosapic_ack_edge_irq (unsigned int irq) #define iosapic_end_edge_irq nop struct hw_interrupt_type irq_type_iosapic_edge = { - .name = "IO-SAPIC-edge", + .typename = "IO-SAPIC-edge", .startup = iosapic_startup_edge_irq, .shutdown = iosapic_disable_edge_irq, .enable = iosapic_enable_edge_irq, @@ -664,7 +664,7 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery, printk(KERN_WARNING "%s: changing vector %d from %s to %s\n", __FUNCTION__, vector, - idesc->chip->name, irq_type->name); + idesc->chip->typename, irq_type->typename); idesc->chip = irq_type; } return 0; diff --git a/trunk/arch/ia64/kernel/irq.c b/trunk/arch/ia64/kernel/irq.c index 54d55e4d64f7..7852382de2fa 100644 --- a/trunk/arch/ia64/kernel/irq.c +++ b/trunk/arch/ia64/kernel/irq.c @@ -76,7 +76,7 @@ int show_interrupts(struct seq_file *p, void *v) seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); } #endif - seq_printf(p, " %14s", irq_desc[i].chip->name); + seq_printf(p, " %14s", irq_desc[i].chip->typename); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) @@ -194,11 +194,8 @@ void fixup_irqs(void) */ for (irq=0; irq < NR_IRQS; irq++) { if (vectors_in_migration[irq]) { - struct pt_regs *old_regs = set_irq_regs(NULL); - vectors_in_migration[irq]=0; - generic_handle_irq(irq); - set_irq_regs(old_regs); + __do_IRQ(irq, NULL); } } diff --git a/trunk/arch/ia64/kernel/irq_ia64.c b/trunk/arch/ia64/kernel/irq_ia64.c index ba3ba8bc50be..ab2d19c3661f 100644 --- a/trunk/arch/ia64/kernel/irq_ia64.c +++ b/trunk/arch/ia64/kernel/irq_ia64.c @@ -138,7 +138,6 @@ void destroy_irq(unsigned int irq) void ia64_handle_irq (ia64_vector vector, struct pt_regs *regs) { - struct pt_regs *old_regs = set_irq_regs(regs); unsigned long saved_tpr; #if IRQ_DEBUG @@ -180,13 +179,11 @@ ia64_handle_irq (ia64_vector vector, struct pt_regs *regs) saved_tpr = ia64_getreg(_IA64_REG_CR_TPR); ia64_srlz_d(); while (vector != IA64_SPURIOUS_INT_VECTOR) { - if (unlikely(IS_RESCHEDULE(vector))) - kstat_this_cpu.irqs[vector]++; - else { + if (!IS_RESCHEDULE(vector)) { ia64_setreg(_IA64_REG_CR_TPR, vector); ia64_srlz_d(); - generic_handle_irq(local_vector_to_irq(vector)); + __do_IRQ(local_vector_to_irq(vector), regs); /* * Disable interrupts and send EOI: @@ -203,7 +200,6 @@ ia64_handle_irq (ia64_vector vector, struct pt_regs *regs) * come through until ia64_eoi() has been done. */ irq_exit(); - set_irq_regs(old_regs); } #ifdef CONFIG_HOTPLUG_CPU @@ -227,11 +223,7 @@ void ia64_process_pending_intr(void) * Perform normal interrupt style processing */ while (vector != IA64_SPURIOUS_INT_VECTOR) { - if (unlikely(IS_RESCHEDULE(vector))) - kstat_this_cpu.irqs[vector]++; - else { - struct pt_regs *old_regs = set_irq_regs(NULL); - + if (!IS_RESCHEDULE(vector)) { ia64_setreg(_IA64_REG_CR_TPR, vector); ia64_srlz_d(); @@ -242,8 +234,7 @@ void ia64_process_pending_intr(void) * Probably could shared code. */ vectors_in_migration[local_vector_to_irq(vector)]=0; - generic_handle_irq(local_vector_to_irq(vector)); - set_irq_regs(old_regs); + __do_IRQ(local_vector_to_irq(vector), NULL); /* * Disable interrupts and send EOI @@ -260,24 +251,13 @@ void ia64_process_pending_intr(void) #ifdef CONFIG_SMP -extern irqreturn_t handle_IPI (int irq, void *dev_id); - -static irqreturn_t dummy_handler (int irq, void *dev_id) -{ - BUG(); -} +extern irqreturn_t handle_IPI (int irq, void *dev_id, struct pt_regs *regs); static struct irqaction ipi_irqaction = { .handler = handle_IPI, .flags = IRQF_DISABLED, .name = "IPI" }; - -static struct irqaction resched_irqaction = { - .handler = dummy_handler, - .flags = SA_INTERRUPT, - .name = "resched" -}; #endif void @@ -302,7 +282,6 @@ init_IRQ (void) register_percpu_irq(IA64_SPURIOUS_INT_VECTOR, NULL); #ifdef CONFIG_SMP register_percpu_irq(IA64_IPI_VECTOR, &ipi_irqaction); - register_percpu_irq(IA64_IPI_RESCHEDULE, &resched_irqaction); #endif #ifdef CONFIG_PERFMON pfm_init_percpu(); diff --git a/trunk/arch/ia64/kernel/irq_lsapic.c b/trunk/arch/ia64/kernel/irq_lsapic.c index c2f07beb1759..1ab58b09f3d7 100644 --- a/trunk/arch/ia64/kernel/irq_lsapic.c +++ b/trunk/arch/ia64/kernel/irq_lsapic.c @@ -34,7 +34,7 @@ static int lsapic_retrigger(unsigned int irq) } struct hw_interrupt_type irq_type_ia64_lsapic = { - .name = "LSAPIC", + .typename = "LSAPIC", .startup = lsapic_noop_startup, .shutdown = lsapic_noop, .enable = lsapic_noop, diff --git a/trunk/arch/ia64/kernel/machvec.c b/trunk/arch/ia64/kernel/machvec.c index 9620822270a6..d4a546aa5048 100644 --- a/trunk/arch/ia64/kernel/machvec.c +++ b/trunk/arch/ia64/kernel/machvec.c @@ -60,7 +60,7 @@ machvec_setup (char **arg) EXPORT_SYMBOL(machvec_setup); void -machvec_timer_interrupt (int irq, void *dev_id) +machvec_timer_interrupt (int irq, void *dev_id, struct pt_regs *regs) { } EXPORT_SYMBOL(machvec_timer_interrupt); diff --git a/trunk/arch/ia64/kernel/mca.c b/trunk/arch/ia64/kernel/mca.c index 7cfa63a98cb3..663230183254 100644 --- a/trunk/arch/ia64/kernel/mca.c +++ b/trunk/arch/ia64/kernel/mca.c @@ -499,7 +499,7 @@ int cpe_vector = -1; int ia64_cpe_irq = -1; static irqreturn_t -ia64_mca_cpe_int_handler (int cpe_irq, void *arg) +ia64_mca_cpe_int_handler (int cpe_irq, void *arg, struct pt_regs *ptregs) { static unsigned long cpe_history[CPE_HISTORY_LENGTH]; static int index; @@ -744,7 +744,7 @@ ia64_mca_wakeup_all(void) * Outputs : None */ static irqreturn_t -ia64_mca_rendez_int_handler(int rendez_irq, void *arg) +ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *regs) { unsigned long flags; int cpu = smp_processor_id(); @@ -753,8 +753,8 @@ ia64_mca_rendez_int_handler(int rendez_irq, void *arg) /* Mask all interrupts */ local_irq_save(flags); - if (notify_die(DIE_MCA_RENDZVOUS_ENTER, "MCA", get_irq_regs(), - (long)&nd, 0, 0) == NOTIFY_STOP) + if (notify_die(DIE_MCA_RENDZVOUS_ENTER, "MCA", regs, (long)&nd, 0, 0) + == NOTIFY_STOP) ia64_mca_spin(__FUNCTION__); ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_DONE; @@ -763,16 +763,16 @@ ia64_mca_rendez_int_handler(int rendez_irq, void *arg) */ ia64_sal_mc_rendez(); - if (notify_die(DIE_MCA_RENDZVOUS_PROCESS, "MCA", get_irq_regs(), - (long)&nd, 0, 0) == NOTIFY_STOP) + if (notify_die(DIE_MCA_RENDZVOUS_PROCESS, "MCA", regs, (long)&nd, 0, 0) + == NOTIFY_STOP) ia64_mca_spin(__FUNCTION__); /* Wait for the monarch cpu to exit. */ while (monarch_cpu != -1) cpu_relax(); /* spin until monarch leaves */ - if (notify_die(DIE_MCA_RENDZVOUS_LEAVE, "MCA", get_irq_regs(), - (long)&nd, 0, 0) == NOTIFY_STOP) + if (notify_die(DIE_MCA_RENDZVOUS_LEAVE, "MCA", regs, (long)&nd, 0, 0) + == NOTIFY_STOP) ia64_mca_spin(__FUNCTION__); /* Enable all interrupts */ @@ -791,11 +791,12 @@ ia64_mca_rendez_int_handler(int rendez_irq, void *arg) * * Inputs : wakeup_irq (Wakeup-interrupt bit) * arg (Interrupt handler specific argument) + * ptregs (Exception frame at the time of the interrupt) * Outputs : None * */ static irqreturn_t -ia64_mca_wakeup_int_handler(int wakeup_irq, void *arg) +ia64_mca_wakeup_int_handler(int wakeup_irq, void *arg, struct pt_regs *ptregs) { return IRQ_HANDLED; } @@ -1260,12 +1261,13 @@ static DECLARE_WORK(cmc_enable_work, ia64_mca_cmc_vector_enable_keventd, NULL); * Inputs * interrupt number * client data arg ptr + * saved registers ptr * * Outputs * None */ static irqreturn_t -ia64_mca_cmc_int_handler(int cmc_irq, void *arg) +ia64_mca_cmc_int_handler(int cmc_irq, void *arg, struct pt_regs *ptregs) { static unsigned long cmc_history[CMC_HISTORY_LENGTH]; static int index; @@ -1334,11 +1336,12 @@ ia64_mca_cmc_int_handler(int cmc_irq, void *arg) * Inputs * interrupt number * client data arg ptr + * saved registers ptr * Outputs * handled */ static irqreturn_t -ia64_mca_cmc_int_caller(int cmc_irq, void *arg) +ia64_mca_cmc_int_caller(int cmc_irq, void *arg, struct pt_regs *ptregs) { static int start_count = -1; unsigned int cpuid; @@ -1349,7 +1352,7 @@ ia64_mca_cmc_int_caller(int cmc_irq, void *arg) if (start_count == -1) start_count = IA64_LOG_COUNT(SAL_INFO_TYPE_CMC); - ia64_mca_cmc_int_handler(cmc_irq, arg); + ia64_mca_cmc_int_handler(cmc_irq, arg, ptregs); for (++cpuid ; cpuid < NR_CPUS && !cpu_online(cpuid) ; cpuid++); @@ -1400,13 +1403,14 @@ ia64_mca_cmc_poll (unsigned long dummy) * Inputs * interrupt number * client data arg ptr + * saved registers ptr * Outputs * handled */ #ifdef CONFIG_ACPI static irqreturn_t -ia64_mca_cpe_int_caller(int cpe_irq, void *arg) +ia64_mca_cpe_int_caller(int cpe_irq, void *arg, struct pt_regs *ptregs) { static int start_count = -1; static int poll_time = MIN_CPE_POLL_INTERVAL; @@ -1418,7 +1422,7 @@ ia64_mca_cpe_int_caller(int cpe_irq, void *arg) if (start_count == -1) start_count = IA64_LOG_COUNT(SAL_INFO_TYPE_CPE); - ia64_mca_cpe_int_handler(cpe_irq, arg); + ia64_mca_cpe_int_handler(cpe_irq, arg, ptregs); for (++cpuid ; cpuid < NR_CPUS && !cpu_online(cpuid) ; cpuid++); diff --git a/trunk/arch/ia64/kernel/mca_drv.c b/trunk/arch/ia64/kernel/mca_drv.c index afc1403799c9..a45009d2bc90 100644 --- a/trunk/arch/ia64/kernel/mca_drv.c +++ b/trunk/arch/ia64/kernel/mca_drv.c @@ -434,50 +434,6 @@ is_mca_global(peidx_table_t *peidx, pal_bus_check_info_t *pbci, return MCA_IS_GLOBAL; } -/** - * get_target_identifier - Get the valid Cache or Bus check target identifier. - * @peidx: pointer of index of processor error section - * - * Return value: - * target address on Success / 0 on Failue - */ -static u64 -get_target_identifier(peidx_table_t *peidx) -{ - u64 target_address = 0; - sal_log_mod_error_info_t *smei; - pal_cache_check_info_t *pcci; - int i, level = 9; - - /* - * Look through the cache checks for a valid target identifier - * If more than one valid target identifier, return the one - * with the lowest cache level. - */ - for (i = 0; i < peidx_cache_check_num(peidx); i++) { - smei = (sal_log_mod_error_info_t *)peidx_cache_check(peidx, i); - if (smei->valid.target_identifier && smei->target_identifier) { - pcci = (pal_cache_check_info_t *)&(smei->check_info); - if (!target_address || (pcci->level < level)) { - target_address = smei->target_identifier; - level = pcci->level; - continue; - } - } - } - if (target_address) - return target_address; - - /* - * Look at the bus check for a valid target identifier - */ - smei = peidx_bus_check(peidx, 0); - if (smei && smei->valid.target_identifier) - return smei->target_identifier; - - return 0; -} - /** * recover_from_read_error - Try to recover the errors which type are "read"s. * @slidx: pointer of index of SAL error record @@ -494,14 +450,13 @@ recover_from_read_error(slidx_table_t *slidx, peidx_table_t *peidx, pal_bus_check_info_t *pbci, struct ia64_sal_os_state *sos) { - u64 target_identifier; + sal_log_mod_error_info_t *smei; pal_min_state_area_t *pmsa; struct ia64_psr *psr1, *psr2; ia64_fptr_t *mca_hdlr_bh = (ia64_fptr_t*)mca_handler_bhhook; /* Is target address valid? */ - target_identifier = get_target_identifier(peidx); - if (!target_identifier) + if (!pbci->tv) return fatal_mca("target address not valid"); /* @@ -532,28 +487,32 @@ recover_from_read_error(slidx_table_t *slidx, pmsa = sos->pal_min_state; if (psr1->cpl != 0 || ((psr2->cpl != 0) && mca_recover_range(pmsa->pmsa_iip))) { - /* - * setup for resume to bottom half of MCA, - * "mca_handler_bhhook" - */ - /* pass to bhhook as argument (gr8, ...) */ - pmsa->pmsa_gr[8-1] = target_identifier; - pmsa->pmsa_gr[9-1] = pmsa->pmsa_iip; - pmsa->pmsa_gr[10-1] = pmsa->pmsa_ipsr; - /* set interrupted return address (but no use) */ - pmsa->pmsa_br0 = pmsa->pmsa_iip; - /* change resume address to bottom half */ - pmsa->pmsa_iip = mca_hdlr_bh->fp; - pmsa->pmsa_gr[1-1] = mca_hdlr_bh->gp; - /* set cpl with kernel mode */ - psr2 = (struct ia64_psr *)&pmsa->pmsa_ipsr; - psr2->cpl = 0; - psr2->ri = 0; - psr2->bn = 1; - psr2->i = 0; - - return mca_recovered("user memory corruption. " + smei = peidx_bus_check(peidx, 0); + if (smei->valid.target_identifier) { + /* + * setup for resume to bottom half of MCA, + * "mca_handler_bhhook" + */ + /* pass to bhhook as argument (gr8, ...) */ + pmsa->pmsa_gr[8-1] = smei->target_identifier; + pmsa->pmsa_gr[9-1] = pmsa->pmsa_iip; + pmsa->pmsa_gr[10-1] = pmsa->pmsa_ipsr; + /* set interrupted return address (but no use) */ + pmsa->pmsa_br0 = pmsa->pmsa_iip; + /* change resume address to bottom half */ + pmsa->pmsa_iip = mca_hdlr_bh->fp; + pmsa->pmsa_gr[1-1] = mca_hdlr_bh->gp; + /* set cpl with kernel mode */ + psr2 = (struct ia64_psr *)&pmsa->pmsa_ipsr; + psr2->cpl = 0; + psr2->ri = 0; + psr2->bn = 1; + psr2->i = 0; + + return mca_recovered("user memory corruption. " "kill affected process - recovered."); + } + } return fatal_mca("kernel context not recovered, iip 0x%lx\n", diff --git a/trunk/arch/ia64/kernel/pal.S b/trunk/arch/ia64/kernel/pal.S index 0b533441c3c9..ebaf1e685f5e 100644 --- a/trunk/arch/ia64/kernel/pal.S +++ b/trunk/arch/ia64/kernel/pal.S @@ -21,12 +21,11 @@ pal_entry_point: .text /* - * Set the PAL entry point address. This could be written in C code, but we - * do it here to keep it all in one module (besides, it's so trivial that it's + * Set the PAL entry point address. This could be written in C code, but we do it here + * to keep it all in one module (besides, it's so trivial that it's * not a big deal). * - * in0 Address of the PAL entry point (text address, NOT a function - * descriptor). + * in0 Address of the PAL entry point (text address, NOT a function descriptor). */ GLOBAL_ENTRY(ia64_pal_handler_init) alloc r3=ar.pfs,1,0,0,0 @@ -37,9 +36,9 @@ GLOBAL_ENTRY(ia64_pal_handler_init) END(ia64_pal_handler_init) /* - * Default PAL call handler. This needs to be coded in assembly because it - * uses the static calling convention, i.e., the RSE may not be used and - * calls are done via "br.cond" (not "br.call"). + * Default PAL call handler. This needs to be coded in assembly because it uses + * the static calling convention, i.e., the RSE may not be used and calls are + * done via "br.cond" (not "br.call"). */ GLOBAL_ENTRY(ia64_pal_default_handler) mov r8=-1 @@ -51,10 +50,12 @@ END(ia64_pal_default_handler) * * in0 Index of PAL service * in1 - in3 Remaining PAL arguments + * in4 1 ==> clear psr.ic, 0 ==> don't clear psr.ic + * */ GLOBAL_ENTRY(ia64_pal_call_static) - .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(4) - alloc loc1 = ar.pfs,4,5,0,0 + .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(5) + alloc loc1 = ar.pfs,5,5,0,0 movl loc2 = pal_entry_point 1: { mov r28 = in0 @@ -63,6 +64,7 @@ GLOBAL_ENTRY(ia64_pal_call_static) } ;; ld8 loc2 = [loc2] // loc2 <- entry point + tbit.nz p6,p7 = in4, 0 adds r8 = 1f-1b,r8 mov loc4=ar.rsc // save RSE configuration ;; @@ -72,11 +74,13 @@ GLOBAL_ENTRY(ia64_pal_call_static) .body mov r30 = in2 +(p6) rsm psr.i | psr.ic mov r31 = in3 mov b7 = loc2 - rsm psr.i +(p7) rsm psr.i ;; +(p6) srlz.i mov rp = r8 br.cond.sptk.many b7 1: mov psr.l = loc3 @@ -92,8 +96,8 @@ END(ia64_pal_call_static) * Make a PAL call using the stacked registers calling convention. * * Inputs: - * in0 Index of PAL service - * in2 - in3 Remaining PAL arguments + * in0 Index of PAL service + * in2 - in3 Remaning PAL arguments */ GLOBAL_ENTRY(ia64_pal_call_stacked) .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(4) @@ -127,18 +131,18 @@ END(ia64_pal_call_stacked) * Make a physical mode PAL call using the static registers calling convention. * * Inputs: - * in0 Index of PAL service - * in2 - in3 Remaining PAL arguments + * in0 Index of PAL service + * in2 - in3 Remaning PAL arguments * * PSR_LP, PSR_TB, PSR_ID, PSR_DA are never set by the kernel. * So we don't need to clear them. */ -#define PAL_PSR_BITS_TO_CLEAR \ - (IA64_PSR_I | IA64_PSR_IT | IA64_PSR_DT | IA64_PSR_DB | IA64_PSR_RT |\ - IA64_PSR_DD | IA64_PSR_SS | IA64_PSR_RI | IA64_PSR_ED | \ +#define PAL_PSR_BITS_TO_CLEAR \ + (IA64_PSR_I | IA64_PSR_IT | IA64_PSR_DT | IA64_PSR_DB | IA64_PSR_RT | \ + IA64_PSR_DD | IA64_PSR_SS | IA64_PSR_RI | IA64_PSR_ED | \ IA64_PSR_DFL | IA64_PSR_DFH) -#define PAL_PSR_BITS_TO_SET \ +#define PAL_PSR_BITS_TO_SET \ (IA64_PSR_BN) @@ -174,7 +178,7 @@ GLOBAL_ENTRY(ia64_pal_call_phys_static) ;; andcm r16=loc3,r16 // removes bits to clear from psr br.call.sptk.many rp=ia64_switch_mode_phys - mov rp = r8 // install return address (physical) +.ret1: mov rp = r8 // install return address (physical) mov loc5 = r19 mov loc6 = r20 br.cond.sptk.many b7 @@ -184,6 +188,7 @@ GLOBAL_ENTRY(ia64_pal_call_phys_static) mov r19=loc5 mov r20=loc6 br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode +.ret2: mov psr.l = loc3 // restore init PSR mov ar.pfs = loc1 @@ -198,8 +203,8 @@ END(ia64_pal_call_phys_static) * Make a PAL call using the stacked registers in physical mode. * * Inputs: - * in0 Index of PAL service - * in2 - in3 Remaining PAL arguments + * in0 Index of PAL service + * in2 - in3 Remaning PAL arguments */ GLOBAL_ENTRY(ia64_pal_call_phys_stacked) .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(5) @@ -207,7 +212,7 @@ GLOBAL_ENTRY(ia64_pal_call_phys_stacked) movl loc2 = pal_entry_point 1: { mov r28 = in0 // copy procedure index - mov loc0 = rp // save rp + mov loc0 = rp // save rp } .body ;; @@ -240,7 +245,7 @@ GLOBAL_ENTRY(ia64_pal_call_phys_stacked) mov r16=loc3 // r16= original psr mov r19=loc5 mov r20=loc6 - br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode + br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode mov psr.l = loc3 // restore init PSR mov ar.pfs = loc1 @@ -252,11 +257,10 @@ GLOBAL_ENTRY(ia64_pal_call_phys_stacked) END(ia64_pal_call_phys_stacked) /* - * Save scratch fp scratch regs which aren't saved in pt_regs already - * (fp10-fp15). + * Save scratch fp scratch regs which aren't saved in pt_regs already (fp10-fp15). * - * NOTE: We need to do this since firmware (SAL and PAL) may use any of the - * scratch regs fp-low partition. + * NOTE: We need to do this since firmware (SAL and PAL) may use any of the scratch + * regs fp-low partition. * * Inputs: * in0 Address of stack storage for fp regs diff --git a/trunk/arch/ia64/kernel/perfmon.c b/trunk/arch/ia64/kernel/perfmon.c index 3aaede0d6981..281004ff7b00 100644 --- a/trunk/arch/ia64/kernel/perfmon.c +++ b/trunk/arch/ia64/kernel/perfmon.c @@ -5558,13 +5558,12 @@ pfm_do_interrupt_handler(int irq, void *arg, struct pt_regs *regs) } static irqreturn_t -pfm_interrupt_handler(int irq, void *arg) +pfm_interrupt_handler(int irq, void *arg, struct pt_regs *regs) { unsigned long start_cycles, total_cycles; unsigned long min, max; int this_cpu; int ret; - struct pt_regs *regs = get_irq_regs(); this_cpu = get_cpu(); if (likely(!pfm_alt_intr_handler)) { diff --git a/trunk/arch/ia64/kernel/sal.c b/trunk/arch/ia64/kernel/sal.c index 20bad78b5073..642fdc7b969d 100644 --- a/trunk/arch/ia64/kernel/sal.c +++ b/trunk/arch/ia64/kernel/sal.c @@ -223,13 +223,12 @@ static void __init sal_desc_ap_wakeup(void *p) { } */ static int sal_cache_flush_drops_interrupts; -void __init +static void __init check_sal_cache_flush (void) { unsigned long flags; int cpu; - u64 vector, cache_type = 3; - struct ia64_sal_retval isrv; + u64 vector; cpu = get_cpu(); local_irq_save(flags); @@ -244,10 +243,7 @@ check_sal_cache_flush (void) while (!ia64_get_irr(IA64_TIMER_VECTOR)) cpu_relax(); - SAL_CALL(isrv, SAL_CACHE_FLUSH, cache_type, 0, 0, 0, 0, 0, 0); - - if (isrv.status) - printk(KERN_ERR "SAL_CAL_FLUSH failed with %ld\n", isrv.status); + ia64_sal_cache_flush(3); if (ia64_get_irr(IA64_TIMER_VECTOR)) { vector = ia64_get_ivr(); @@ -335,6 +331,7 @@ ia64_sal_init (struct ia64_sal_systab *systab) p += SAL_DESC_SIZE(*p); } + check_sal_cache_flush(); } int diff --git a/trunk/arch/ia64/kernel/setup.c b/trunk/arch/ia64/kernel/setup.c index d10404a41756..c4caa8003492 100644 --- a/trunk/arch/ia64/kernel/setup.c +++ b/trunk/arch/ia64/kernel/setup.c @@ -457,8 +457,6 @@ setup_arch (char **cmdline_p) cpu_init(); /* initialize the bootstrap CPU */ mmu_context_init(); /* initialize context_id bitmap */ - check_sal_cache_flush(); - #ifdef CONFIG_ACPI acpi_boot_init(); #endif diff --git a/trunk/arch/ia64/kernel/smp.c b/trunk/arch/ia64/kernel/smp.c index 6ab95ceaf9d4..657ac99a451c 100644 --- a/trunk/arch/ia64/kernel/smp.c +++ b/trunk/arch/ia64/kernel/smp.c @@ -108,7 +108,7 @@ cpu_die(void) } irqreturn_t -handle_IPI (int irq, void *dev_id) +handle_IPI (int irq, void *dev_id, struct pt_regs *regs) { int this_cpu = get_cpu(); unsigned long *pending_ipis = &__ia64_per_cpu_var(ipi_operation); @@ -328,14 +328,10 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic, int wait) { struct call_data_struct data; - int cpus; + int cpus = num_online_cpus()-1; - spin_lock(&call_lock); - cpus = num_online_cpus() - 1; - if (!cpus) { - spin_unlock(&call_lock); + if (!cpus) return 0; - } /* Can deadlock when called with interrupts disabled */ WARN_ON(irqs_disabled()); @@ -347,6 +343,8 @@ smp_call_function (void (*func) (void *info), void *info, int nonatomic, int wai if (wait) atomic_set(&data.finished, 0); + spin_lock(&call_lock); + call_data = &data; mb(); /* ensure store to call_data precedes setting of IPI_CALL_FUNC */ send_IPI_allbutself(IPI_CALL_FUNC); diff --git a/trunk/arch/ia64/kernel/time.c b/trunk/arch/ia64/kernel/time.c index 39e0cd3a0884..62e07f906e05 100644 --- a/trunk/arch/ia64/kernel/time.c +++ b/trunk/arch/ia64/kernel/time.c @@ -45,7 +45,7 @@ static struct time_interpolator itc_interpolator = { }; static irqreturn_t -timer_interrupt (int irq, void *dev_id) +timer_interrupt (int irq, void *dev_id, struct pt_regs *regs) { unsigned long new_itm; @@ -53,7 +53,7 @@ timer_interrupt (int irq, void *dev_id) return IRQ_HANDLED; } - platform_timer_interrupt(irq, dev_id); + platform_timer_interrupt(irq, dev_id, regs); new_itm = local_cpu_data->itm_next; @@ -61,10 +61,10 @@ timer_interrupt (int irq, void *dev_id) printk(KERN_ERR "Oops: timer tick before it's due (itc=%lx,itm=%lx)\n", ia64_get_itc(), new_itm); - profile_tick(CPU_PROFILING); + profile_tick(CPU_PROFILING, regs); while (1) { - update_process_times(user_mode(get_irq_regs())); + update_process_times(user_mode(regs)); new_itm += local_cpu_data->itm_delta; @@ -84,12 +84,6 @@ timer_interrupt (int irq, void *dev_id) if (time_after(new_itm, ia64_get_itc())) break; - - /* - * Allow IPIs to interrupt the timer loop. - */ - local_irq_enable(); - local_irq_disable(); } do { diff --git a/trunk/arch/ia64/kernel/vmlinux.lds.S b/trunk/arch/ia64/kernel/vmlinux.lds.S index d6083a0936f4..b3b2e389d6b2 100644 --- a/trunk/arch/ia64/kernel/vmlinux.lds.S +++ b/trunk/arch/ia64/kernel/vmlinux.lds.S @@ -128,7 +128,13 @@ SECTIONS .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) { __initcall_start = .; - INITCALLS + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) __initcall_end = .; } diff --git a/trunk/arch/ia64/mm/contig.c b/trunk/arch/ia64/mm/contig.c index 82deaa3a7c48..daf977ff2920 100644 --- a/trunk/arch/ia64/mm/contig.c +++ b/trunk/arch/ia64/mm/contig.c @@ -233,7 +233,6 @@ paging_init (void) efi_memmap_walk(count_pages, &num_physpages); max_dma = virt_to_phys((void *) MAX_DMA_ADDRESS) >> PAGE_SHIFT; - memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); max_zone_pfns[ZONE_DMA] = max_dma; max_zone_pfns[ZONE_NORMAL] = max_low_pfn; diff --git a/trunk/arch/ia64/mm/discontig.c b/trunk/arch/ia64/mm/discontig.c index 96722cb1b49d..d497b6b0f5b2 100644 --- a/trunk/arch/ia64/mm/discontig.c +++ b/trunk/arch/ia64/mm/discontig.c @@ -709,7 +709,6 @@ void __init paging_init(void) max_pfn = mem_data[node].max_pfn; } - memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); max_zone_pfns[ZONE_DMA] = max_dma; max_zone_pfns[ZONE_NORMAL] = max_pfn; free_area_init_nodes(max_zone_pfns); diff --git a/trunk/arch/ia64/mm/hugetlbpage.c b/trunk/arch/ia64/mm/hugetlbpage.c index f3a9585e98a8..eee5c1cfbe32 100644 --- a/trunk/arch/ia64/mm/hugetlbpage.c +++ b/trunk/arch/ia64/mm/hugetlbpage.c @@ -70,10 +70,8 @@ huge_pte_offset (struct mm_struct *mm, unsigned long addr) * Don't actually need to do any preparation, but need to make sure * the address is in the right region. */ -int prepare_hugepage_range(unsigned long addr, unsigned long len, pgoff_t pgoff) +int prepare_hugepage_range(unsigned long addr, unsigned long len) { - if (pgoff & (~HPAGE_MASK >> PAGE_SHIFT)) - return -EINVAL; if (len & ~HPAGE_MASK) return -EINVAL; if (addr & ~HPAGE_MASK) diff --git a/trunk/arch/ia64/pci/Makefile b/trunk/arch/ia64/pci/Makefile index fb14dc520d2d..e66889e6922a 100644 --- a/trunk/arch/ia64/pci/Makefile +++ b/trunk/arch/ia64/pci/Makefile @@ -1,4 +1,4 @@ # # Makefile for the ia64-specific parts of the pci bus # -obj-y := pci.o fixup.o +obj-y := pci.o diff --git a/trunk/arch/ia64/pci/fixup.c b/trunk/arch/ia64/pci/fixup.c deleted file mode 100644 index 245dc1fedc24..000000000000 --- a/trunk/arch/ia64/pci/fixup.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Exceptions for specific devices. Usually work-arounds for fatal design flaws. - * Derived from fixup.c of i386 tree. - */ - -#include -#include - -#include - -/* - * Fixup to mark boot BIOS video selected by BIOS before it changes - * - * From information provided by "Jon Smirl" - * - * The standard boot ROM sequence for an x86 machine uses the BIOS - * to select an initial video card for boot display. This boot video - * card will have it's BIOS copied to C0000 in system RAM. - * IORESOURCE_ROM_SHADOW is used to associate the boot video - * card with this copy. On laptops this copy has to be used since - * the main ROM may be compressed or combined with another image. - * See pci_map_rom() for use of this flag. IORESOURCE_ROM_SHADOW - * is marked here since the boot video device will be the only enabled - * video device at this point. - */ - -static void __devinit pci_fixup_video(struct pci_dev *pdev) -{ - struct pci_dev *bridge; - struct pci_bus *bus; - u16 config; - - if ((strcmp(platform_name, "dig") != 0) - && (strcmp(platform_name, "hpzx1") != 0)) - return; - /* Maybe, this machine supports legacy memory map. */ - - if ((pdev->class >> 8) != PCI_CLASS_DISPLAY_VGA) - return; - - /* Is VGA routed to us? */ - bus = pdev->bus; - while (bus) { - bridge = bus->self; - - /* - * From information provided by - * "David Miller" - * The bridge control register is valid for PCI header - * type BRIDGE, or CARDBUS. Host to PCI controllers use - * PCI header type NORMAL. - */ - if (bridge - &&((bridge->hdr_type == PCI_HEADER_TYPE_BRIDGE) - ||(bridge->hdr_type == PCI_HEADER_TYPE_CARDBUS))) { - pci_read_config_word(bridge, PCI_BRIDGE_CONTROL, - &config); - if (!(config & PCI_BRIDGE_CTL_VGA)) - return; - } - bus = bus->parent; - } - pci_read_config_word(pdev, PCI_COMMAND, &config); - if (config & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) { - pdev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_SHADOW; - printk(KERN_DEBUG "Boot video device is %s\n", pci_name(pdev)); - } -} -DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video); diff --git a/trunk/arch/ia64/pci/pci.c b/trunk/arch/ia64/pci/pci.c index f4edfbf27134..b30be7c48ba8 100644 --- a/trunk/arch/ia64/pci/pci.c +++ b/trunk/arch/ia64/pci/pci.c @@ -469,11 +469,10 @@ pcibios_fixup_resources(struct pci_dev *dev, int start, int limit) } } -void __devinit pcibios_fixup_device_resources(struct pci_dev *dev) +static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev) { pcibios_fixup_resources(dev, 0, PCI_BRIDGE_RESOURCES); } -EXPORT_SYMBOL_GPL(pcibios_fixup_device_resources); static void __devinit pcibios_fixup_bridge_resources(struct pci_dev *dev) { @@ -494,7 +493,6 @@ pcibios_fixup_bus (struct pci_bus *b) } list_for_each_entry(dev, &b->devices, bus_list) pcibios_fixup_device_resources(dev); - platform_pci_fixup_bus(b); return; } @@ -740,44 +738,75 @@ int ia64_pci_legacy_write(struct pci_bus *bus, u16 port, u32 val, u8 size) return ret; } -/* It's defined in drivers/pci/pci.c */ -extern u8 pci_cache_line_size; - /** - * set_pci_cacheline_size - determine cacheline size for PCI devices + * pci_cacheline_size - determine cacheline size for PCI devices + * @dev: void * * We want to use the line-size of the outer-most cache. We assume * that this line-size is the same for all CPUs. * * Code mostly taken from arch/ia64/kernel/palinfo.c:cache_info(). + * + * RETURNS: An appropriate -ERRNO error value on eror, or zero for success. */ -static void __init set_pci_cacheline_size(void) +static unsigned long +pci_cacheline_size (void) { u64 levels, unique_caches; s64 status; pal_cache_config_info_t cci; + static u8 cacheline_size; + + if (cacheline_size) + return cacheline_size; status = ia64_pal_cache_summary(&levels, &unique_caches); if (status != 0) { - printk(KERN_ERR "%s: ia64_pal_cache_summary() failed " - "(status=%ld)\n", __FUNCTION__, status); - return; + printk(KERN_ERR "%s: ia64_pal_cache_summary() failed (status=%ld)\n", + __FUNCTION__, status); + return SMP_CACHE_BYTES; } - status = ia64_pal_cache_config_info(levels - 1, - /* cache_type (data_or_unified)= */ 2, &cci); + status = ia64_pal_cache_config_info(levels - 1, /* cache_type (data_or_unified)= */ 2, + &cci); if (status != 0) { - printk(KERN_ERR "%s: ia64_pal_cache_config_info() failed " - "(status=%ld)\n", __FUNCTION__, status); - return; + printk(KERN_ERR "%s: ia64_pal_cache_config_info() failed (status=%ld)\n", + __FUNCTION__, status); + return SMP_CACHE_BYTES; } - pci_cache_line_size = (1 << cci.pcci_line_size) / 4; + cacheline_size = 1 << cci.pcci_line_size; + return cacheline_size; } -static int __init pcibios_init(void) -{ - set_pci_cacheline_size(); - return 0; +/** + * pcibios_prep_mwi - helper function for drivers/pci/pci.c:pci_set_mwi() + * @dev: the PCI device for which MWI is enabled + * + * For ia64, we can get the cacheline sizes from PAL. + * + * RETURNS: An appropriate -ERRNO error value on eror, or zero for success. + */ +int +pcibios_prep_mwi (struct pci_dev *dev) +{ + unsigned long desired_linesize, current_linesize; + int rc = 0; + u8 pci_linesize; + + desired_linesize = pci_cacheline_size(); + + pci_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &pci_linesize); + current_linesize = 4 * pci_linesize; + if (desired_linesize != current_linesize) { + printk(KERN_WARNING "PCI: slot %s has incorrect PCI cache line size of %lu bytes,", + pci_name(dev), current_linesize); + if (current_linesize > desired_linesize) { + printk(" expected %lu bytes instead\n", desired_linesize); + rc = -EINVAL; + } else { + printk(" correcting to %lu\n", desired_linesize); + pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, desired_linesize / 4); + } + } + return rc; } - -subsys_initcall(pcibios_init); diff --git a/trunk/arch/ia64/sn/kernel/Makefile b/trunk/arch/ia64/sn/kernel/Makefile index 0a59371d3475..2d78f34dd763 100644 --- a/trunk/arch/ia64/sn/kernel/Makefile +++ b/trunk/arch/ia64/sn/kernel/Makefile @@ -4,14 +4,13 @@ # License. See the file "COPYING" in the main directory of this archive # for more details. # -# Copyright (C) 1999,2001-2006 Silicon Graphics, Inc. All Rights Reserved. +# Copyright (C) 1999,2001-2005 Silicon Graphics, Inc. All Rights Reserved. # CPPFLAGS += -I$(srctree)/arch/ia64/sn/include obj-y += setup.o bte.o bte_error.o irq.o mca.o idle.o \ - huberror.o io_acpi_init.o io_common.o \ - io_init.o iomv.o klconflib.o pio_phys.o \ + huberror.o io_init.o iomv.o klconflib.o pio_phys.o \ sn2/ obj-$(CONFIG_IA64_GENERIC) += machvec.o obj-$(CONFIG_SGI_TIOCX) += tiocx.o diff --git a/trunk/arch/ia64/sn/kernel/bte.c b/trunk/arch/ia64/sn/kernel/bte.c index ff1c55601178..7f73ad4408aa 100644 --- a/trunk/arch/ia64/sn/kernel/bte.c +++ b/trunk/arch/ia64/sn/kernel/bte.c @@ -381,13 +381,14 @@ bte_result_t bte_unaligned_copy(u64 src, u64 dest, u64 len, u64 mode) * bcopy to the destination. */ + /* Add the leader from source */ + headBteLen = len + (src & L1_CACHE_MASK); + /* Add the trailing bytes from footer. */ + headBteLen += L1_CACHE_BYTES - (headBteLen & L1_CACHE_MASK); + headBteSource = src & ~L1_CACHE_MASK; headBcopySrcOffset = src & L1_CACHE_MASK; headBcopyDest = dest; headBcopyLen = len; - - headBteSource = src - headBcopySrcOffset; - /* Add the leading and trailing bytes from source */ - headBteLen = L1_CACHE_ALIGN(len + headBcopySrcOffset); } if (headBcopyLen > 0) { diff --git a/trunk/arch/ia64/sn/kernel/huberror.c b/trunk/arch/ia64/sn/kernel/huberror.c index abca6bd7962f..96fb81e6321f 100644 --- a/trunk/arch/ia64/sn/kernel/huberror.c +++ b/trunk/arch/ia64/sn/kernel/huberror.c @@ -22,7 +22,7 @@ void hubiio_crb_error_handler(struct hubdev_info *hubdev_info); extern void bte_crb_error_handler(cnodeid_t, int, int, ioerror_t *, int); -static irqreturn_t hub_eint_handler(int irq, void *arg) +static irqreturn_t hub_eint_handler(int irq, void *arg, struct pt_regs *ep) { struct hubdev_info *hubdev_info; struct ia64_sal_retval ret_stuff; @@ -178,7 +178,7 @@ void hubiio_crb_error_handler(struct hubdev_info *hubdev_info) */ void hub_error_init(struct hubdev_info *hubdev_info) { - if (request_irq(SGI_II_ERROR, hub_eint_handler, IRQF_SHARED, + if (request_irq(SGI_II_ERROR, (void *)hub_eint_handler, IRQF_SHARED, "SN_hub_error", (void *)hubdev_info)) printk("hub_error_init: Failed to request_irq for 0x%p\n", hubdev_info); diff --git a/trunk/arch/ia64/sn/kernel/io_acpi_init.c b/trunk/arch/ia64/sn/kernel/io_acpi_init.c deleted file mode 100644 index 99d7f278612a..000000000000 --- a/trunk/arch/ia64/sn/kernel/io_acpi_init.c +++ /dev/null @@ -1,231 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2006 Silicon Graphics, Inc. All rights reserved. - */ - -#include -#include -#include -#include -#include -#include "xtalk/hubdev.h" -#include - - -/* - * The code in this file will only be executed when running with - * a PROM that has ACPI IO support. (i.e., SN_ACPI_BASE_SUPPORT() == 1) - */ - - -/* - * This value must match the UUID the PROM uses - * (io/acpi/defblk.c) when building a vendor descriptor. - */ -struct acpi_vendor_uuid sn_uuid = { - .subtype = 0, - .data = { 0x2c, 0xc6, 0xa6, 0xfe, 0x9c, 0x44, 0xda, 0x11, - 0xa2, 0x7c, 0x08, 0x00, 0x69, 0x13, 0xea, 0x51 }, -}; - -/* - * Perform the early IO init in PROM. - */ -static s64 -sal_ioif_init(u64 *result) -{ - struct ia64_sal_retval isrv = {0,0,0,0}; - - SAL_CALL_NOLOCK(isrv, - SN_SAL_IOIF_INIT, 0, 0, 0, 0, 0, 0, 0); - *result = isrv.v0; - return isrv.status; -} - -/* - * sn_hubdev_add - The 'add' function of the acpi_sn_hubdev_driver. - * Called for every "SGIHUB" or "SGITIO" device defined - * in the ACPI namespace. - */ -static int __init -sn_hubdev_add(struct acpi_device *device) -{ - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; - u64 addr; - struct hubdev_info *hubdev; - struct hubdev_info *hubdev_ptr; - int i; - u64 nasid; - struct acpi_resource *resource; - int ret = 0; - acpi_status status; - struct acpi_resource_vendor_typed *vendor; - extern void sn_common_hubdev_init(struct hubdev_info *); - - status = acpi_get_vendor_resource(device->handle, METHOD_NAME__CRS, - &sn_uuid, &buffer); - if (ACPI_FAILURE(status)) { - printk(KERN_ERR - "sn_hubdev_add: acpi_get_vendor_resource() failed: %d\n", - status); - return 1; - } - - resource = buffer.pointer; - vendor = &resource->data.vendor_typed; - if ((vendor->byte_length - sizeof(struct acpi_vendor_uuid)) != - sizeof(struct hubdev_info *)) { - printk(KERN_ERR - "sn_hubdev_add: Invalid vendor data length: %d\n", - vendor->byte_length); - ret = 1; - goto exit; - } - - memcpy(&addr, vendor->byte_data, sizeof(struct hubdev_info *)); - hubdev_ptr = __va((struct hubdev_info *) addr); - - nasid = hubdev_ptr->hdi_nasid; - i = nasid_to_cnodeid(nasid); - hubdev = (struct hubdev_info *)(NODEPDA(i)->pdinfo); - *hubdev = *hubdev_ptr; - sn_common_hubdev_init(hubdev); - -exit: - kfree(buffer.pointer); - return ret; -} - -/* - * sn_get_bussoft_ptr() - The pcibus_bussoft pointer is found in - * the ACPI Vendor resource for this bus. - */ -static struct pcibus_bussoft * -sn_get_bussoft_ptr(struct pci_bus *bus) -{ - u64 addr; - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; - acpi_handle handle; - struct pcibus_bussoft *prom_bussoft_ptr; - struct acpi_resource *resource; - acpi_status status; - struct acpi_resource_vendor_typed *vendor; - - - handle = PCI_CONTROLLER(bus)->acpi_handle; - status = acpi_get_vendor_resource(handle, METHOD_NAME__CRS, - &sn_uuid, &buffer); - if (ACPI_FAILURE(status)) { - printk(KERN_ERR "get_acpi_pcibus_ptr: " - "get_acpi_bussoft_info() failed: %d\n", - status); - return NULL; - } - resource = buffer.pointer; - vendor = &resource->data.vendor_typed; - - if ((vendor->byte_length - sizeof(struct acpi_vendor_uuid)) != - sizeof(struct pcibus_bussoft *)) { - printk(KERN_ERR - "get_acpi_bussoft_ptr: Invalid vendor data " - "length %d\n", vendor->byte_length); - kfree(buffer.pointer); - return NULL; - } - memcpy(&addr, vendor->byte_data, sizeof(struct pcibus_bussoft *)); - prom_bussoft_ptr = __va((struct pcibus_bussoft *) addr); - kfree(buffer.pointer); - - return prom_bussoft_ptr; -} - -/* - * sn_acpi_bus_fixup - */ -void -sn_acpi_bus_fixup(struct pci_bus *bus) -{ - struct pci_dev *pci_dev = NULL; - struct pcibus_bussoft *prom_bussoft_ptr; - extern void sn_common_bus_fixup(struct pci_bus *, - struct pcibus_bussoft *); - - if (!bus->parent) { /* If root bus */ - prom_bussoft_ptr = sn_get_bussoft_ptr(bus); - if (prom_bussoft_ptr == NULL) { - printk(KERN_ERR - "sn_pci_fixup_bus: 0x%04x:0x%02x Unable to " - "obtain prom_bussoft_ptr\n", - pci_domain_nr(bus), bus->number); - return; - } - sn_common_bus_fixup(bus, prom_bussoft_ptr); - } - list_for_each_entry(pci_dev, &bus->devices, bus_list) { - sn_pci_fixup_slot(pci_dev); - } -} - -/* - * sn_acpi_slot_fixup - Perform any SN specific slot fixup. - * At present there does not appear to be - * any generic way to handle a ROM image - * that has been shadowed by the PROM, so - * we pass a pointer to it within the - * pcidev_info structure. - */ - -void -sn_acpi_slot_fixup(struct pci_dev *dev, struct pcidev_info *pcidev_info) -{ - void __iomem *addr; - size_t size; - - if (pcidev_info->pdi_pio_mapped_addr[PCI_ROM_RESOURCE]) { - /* - * A valid ROM image exists and has been shadowed by the - * PROM. Setup the pci_dev ROM resource to point to - * the shadowed copy. - */ - size = dev->resource[PCI_ROM_RESOURCE].end - - dev->resource[PCI_ROM_RESOURCE].start; - addr = - ioremap(pcidev_info->pdi_pio_mapped_addr[PCI_ROM_RESOURCE], - size); - dev->resource[PCI_ROM_RESOURCE].start = (unsigned long) addr; - dev->resource[PCI_ROM_RESOURCE].end = - (unsigned long) addr + size; - dev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_BIOS_COPY; - } -} - -static struct acpi_driver acpi_sn_hubdev_driver = { - .name = "SGI HUBDEV Driver", - .ids = "SGIHUB,SGITIO", - .ops = { - .add = sn_hubdev_add, - }, -}; - - -/* - * sn_io_acpi_init - PROM has ACPI support for IO, defining at a minimum the - * nodes and root buses in the DSDT. As a result, bus scanning - * will be initiated by the Linux ACPI code. - */ - -void __init -sn_io_acpi_init(void) -{ - u64 result; - s64 status; - - acpi_bus_register_driver(&acpi_sn_hubdev_driver); - status = sal_ioif_init(&result); - if (status || result) - panic("sal_ioif_init failed: [%lx] %s\n", - status, ia64_sal_strerror(status)); -} diff --git a/trunk/arch/ia64/sn/kernel/io_common.c b/trunk/arch/ia64/sn/kernel/io_common.c deleted file mode 100644 index d4dd8f4b6b8d..000000000000 --- a/trunk/arch/ia64/sn/kernel/io_common.c +++ /dev/null @@ -1,613 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2006 Silicon Graphics, Inc. All rights reserved. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "xtalk/hubdev.h" -#include "xtalk/xwidgetdev.h" -#include -#include -#include - -extern void sn_init_cpei_timer(void); -extern void register_sn_procfs(void); -extern void sn_acpi_bus_fixup(struct pci_bus *); -extern void sn_bus_fixup(struct pci_bus *); -extern void sn_acpi_slot_fixup(struct pci_dev *, struct pcidev_info *); -extern void sn_more_slot_fixup(struct pci_dev *, struct pcidev_info *); -extern void sn_legacy_pci_window_fixup(struct pci_controller *, u64, u64); -extern void sn_io_acpi_init(void); -extern void sn_io_init(void); - - -static struct list_head sn_sysdata_list; - -/* sysdata list struct */ -struct sysdata_el { - struct list_head entry; - void *sysdata; -}; - -int sn_ioif_inited; /* SN I/O infrastructure initialized? */ - -struct sn_pcibus_provider *sn_pci_provider[PCIIO_ASIC_MAX_TYPES]; /* indexed by asic type */ - -/* - * Hooks and struct for unsupported pci providers - */ - -static dma_addr_t -sn_default_pci_map(struct pci_dev *pdev, unsigned long paddr, size_t size, int type) -{ - return 0; -} - -static void -sn_default_pci_unmap(struct pci_dev *pdev, dma_addr_t addr, int direction) -{ - return; -} - -static void * -sn_default_pci_bus_fixup(struct pcibus_bussoft *soft, struct pci_controller *controller) -{ - return NULL; -} - -static struct sn_pcibus_provider sn_pci_default_provider = { - .dma_map = sn_default_pci_map, - .dma_map_consistent = sn_default_pci_map, - .dma_unmap = sn_default_pci_unmap, - .bus_fixup = sn_default_pci_bus_fixup, -}; - -/* - * Retrieve the DMA Flush List given nasid, widget, and device. - * This list is needed to implement the WAR - Flush DMA data on PIO Reads. - */ -static inline u64 -sal_get_device_dmaflush_list(u64 nasid, u64 widget_num, u64 device_num, - u64 address) -{ - struct ia64_sal_retval ret_stuff; - ret_stuff.status = 0; - ret_stuff.v0 = 0; - - SAL_CALL_NOLOCK(ret_stuff, - (u64) SN_SAL_IOIF_GET_DEVICE_DMAFLUSH_LIST, - (u64) nasid, (u64) widget_num, - (u64) device_num, (u64) address, 0, 0, 0); - return ret_stuff.status; -} - -/* - * Retrieve the pci device information given the bus and device|function number. - */ -static inline u64 -sal_get_pcidev_info(u64 segment, u64 bus_number, u64 devfn, u64 pci_dev, - u64 sn_irq_info) -{ - struct ia64_sal_retval ret_stuff; - ret_stuff.status = 0; - ret_stuff.v0 = 0; - - SAL_CALL_NOLOCK(ret_stuff, - (u64) SN_SAL_IOIF_GET_PCIDEV_INFO, - (u64) segment, (u64) bus_number, (u64) devfn, - (u64) pci_dev, - sn_irq_info, 0, 0); - return ret_stuff.v0; -} - -/* - * sn_pcidev_info_get() - Retrieve the pcidev_info struct for the specified - * device. - */ -inline struct pcidev_info * -sn_pcidev_info_get(struct pci_dev *dev) -{ - struct pcidev_info *pcidev; - - list_for_each_entry(pcidev, - &(SN_PLATFORM_DATA(dev)->pcidev_info), pdi_list) { - if (pcidev->pdi_linux_pcidev == dev) - return pcidev; - } - return NULL; -} - -/* Older PROM flush WAR - * - * 01/16/06 -- This war will be in place until a new official PROM is released. - * Additionally note that the struct sn_flush_device_war also has to be - * removed from arch/ia64/sn/include/xtalk/hubdev.h - */ -static u8 war_implemented = 0; - -static s64 sn_device_fixup_war(u64 nasid, u64 widget, int device, - struct sn_flush_device_common *common) -{ - struct sn_flush_device_war *war_list; - struct sn_flush_device_war *dev_entry; - struct ia64_sal_retval isrv = {0,0,0,0}; - - if (!war_implemented) { - printk(KERN_WARNING "PROM version < 4.50 -- implementing old " - "PROM flush WAR\n"); - war_implemented = 1; - } - - war_list = kzalloc(DEV_PER_WIDGET * sizeof(*war_list), GFP_KERNEL); - if (!war_list) - BUG(); - - SAL_CALL_NOLOCK(isrv, SN_SAL_IOIF_GET_WIDGET_DMAFLUSH_LIST, - nasid, widget, __pa(war_list), 0, 0, 0 ,0); - if (isrv.status) - panic("sn_device_fixup_war failed: %s\n", - ia64_sal_strerror(isrv.status)); - - dev_entry = war_list + device; - memcpy(common,dev_entry, sizeof(*common)); - kfree(war_list); - - return isrv.status; -} - -/* - * sn_common_hubdev_init() - This routine is called to initialize the HUB data - * structure for each node in the system. - */ -void __init -sn_common_hubdev_init(struct hubdev_info *hubdev) -{ - - struct sn_flush_device_kernel *sn_flush_device_kernel; - struct sn_flush_device_kernel *dev_entry; - s64 status; - int widget, device, size; - - /* Attach the error interrupt handlers */ - if (hubdev->hdi_nasid & 1) /* If TIO */ - ice_error_init(hubdev); - else - hub_error_init(hubdev); - - for (widget = 0; widget <= HUB_WIDGET_ID_MAX; widget++) - hubdev->hdi_xwidget_info[widget].xwi_hubinfo = hubdev; - - if (!hubdev->hdi_flush_nasid_list.widget_p) - return; - - size = (HUB_WIDGET_ID_MAX + 1) * - sizeof(struct sn_flush_device_kernel *); - hubdev->hdi_flush_nasid_list.widget_p = - kzalloc(size, GFP_KERNEL); - if (!hubdev->hdi_flush_nasid_list.widget_p) - BUG(); - - for (widget = 0; widget <= HUB_WIDGET_ID_MAX; widget++) { - size = DEV_PER_WIDGET * - sizeof(struct sn_flush_device_kernel); - sn_flush_device_kernel = kzalloc(size, GFP_KERNEL); - if (!sn_flush_device_kernel) - BUG(); - - dev_entry = sn_flush_device_kernel; - for (device = 0; device < DEV_PER_WIDGET; - device++, dev_entry++) { - size = sizeof(struct sn_flush_device_common); - dev_entry->common = kzalloc(size, GFP_KERNEL); - if (!dev_entry->common) - BUG(); - if (sn_prom_feature_available(PRF_DEVICE_FLUSH_LIST)) - status = sal_get_device_dmaflush_list( - hubdev->hdi_nasid, widget, device, - (u64)(dev_entry->common)); - else - status = sn_device_fixup_war(hubdev->hdi_nasid, - widget, device, - dev_entry->common); - if (status != SALRET_OK) - panic("SAL call failed: %s\n", - ia64_sal_strerror(status)); - - spin_lock_init(&dev_entry->sfdl_flush_lock); - } - - if (sn_flush_device_kernel) - hubdev->hdi_flush_nasid_list.widget_p[widget] = - sn_flush_device_kernel; - } -} - -void sn_pci_unfixup_slot(struct pci_dev *dev) -{ - struct pci_dev *host_pci_dev = SN_PCIDEV_INFO(dev)->host_pci_dev; - - sn_irq_unfixup(dev); - pci_dev_put(host_pci_dev); - pci_dev_put(dev); -} - -/* - * sn_pci_fixup_slot() - This routine sets up a slot's resources consistent - * with the Linux PCI abstraction layer. Resources - * acquired from our PCI provider include PIO maps - * to BAR space and interrupt objects. - */ -void sn_pci_fixup_slot(struct pci_dev *dev) -{ - int segment = pci_domain_nr(dev->bus); - int status = 0; - struct pcibus_bussoft *bs; - struct pci_bus *host_pci_bus; - struct pci_dev *host_pci_dev; - struct pcidev_info *pcidev_info; - struct sn_irq_info *sn_irq_info; - unsigned int bus_no, devfn; - - pci_dev_get(dev); /* for the sysdata pointer */ - pcidev_info = kzalloc(sizeof(struct pcidev_info), GFP_KERNEL); - if (!pcidev_info) - BUG(); /* Cannot afford to run out of memory */ - - sn_irq_info = kzalloc(sizeof(struct sn_irq_info), GFP_KERNEL); - if (!sn_irq_info) - BUG(); /* Cannot afford to run out of memory */ - - /* Call to retrieve pci device information needed by kernel. */ - status = sal_get_pcidev_info((u64) segment, (u64) dev->bus->number, - dev->devfn, - (u64) __pa(pcidev_info), - (u64) __pa(sn_irq_info)); - if (status) - BUG(); /* Cannot get platform pci device information */ - - /* Add pcidev_info to list in pci_controller.platform_data */ - list_add_tail(&pcidev_info->pdi_list, - &(SN_PLATFORM_DATA(dev->bus)->pcidev_info)); - - if (SN_ACPI_BASE_SUPPORT()) - sn_acpi_slot_fixup(dev, pcidev_info); - else - sn_more_slot_fixup(dev, pcidev_info); - /* - * Using the PROMs values for the PCI host bus, get the Linux - * PCI host_pci_dev struct and set up host bus linkages - */ - - bus_no = (pcidev_info->pdi_slot_host_handle >> 32) & 0xff; - devfn = pcidev_info->pdi_slot_host_handle & 0xffffffff; - host_pci_bus = pci_find_bus(segment, bus_no); - host_pci_dev = pci_get_slot(host_pci_bus, devfn); - - pcidev_info->host_pci_dev = host_pci_dev; - pcidev_info->pdi_linux_pcidev = dev; - pcidev_info->pdi_host_pcidev_info = SN_PCIDEV_INFO(host_pci_dev); - bs = SN_PCIBUS_BUSSOFT(dev->bus); - pcidev_info->pdi_pcibus_info = bs; - - if (bs && bs->bs_asic_type < PCIIO_ASIC_MAX_TYPES) { - SN_PCIDEV_BUSPROVIDER(dev) = sn_pci_provider[bs->bs_asic_type]; - } else { - SN_PCIDEV_BUSPROVIDER(dev) = &sn_pci_default_provider; - } - - /* Only set up IRQ stuff if this device has a host bus context */ - if (bs && sn_irq_info->irq_irq) { - pcidev_info->pdi_sn_irq_info = sn_irq_info; - dev->irq = pcidev_info->pdi_sn_irq_info->irq_irq; - sn_irq_fixup(dev, sn_irq_info); - } else { - pcidev_info->pdi_sn_irq_info = NULL; - kfree(sn_irq_info); - } -} - -/* - * sn_common_bus_fixup - Perform platform specific bus fixup. - * Execute the ASIC specific fixup routine - * for this bus. - */ -void -sn_common_bus_fixup(struct pci_bus *bus, - struct pcibus_bussoft *prom_bussoft_ptr) -{ - int cnode; - struct pci_controller *controller; - struct hubdev_info *hubdev_info; - int nasid; - void *provider_soft; - struct sn_pcibus_provider *provider; - struct sn_platform_data *sn_platform_data; - - controller = PCI_CONTROLLER(bus); - /* - * Per-provider fixup. Copies the bus soft structure from prom - * to local area and links SN_PCIBUS_BUSSOFT(). - */ - - if (prom_bussoft_ptr->bs_asic_type >= PCIIO_ASIC_MAX_TYPES) { - printk(KERN_WARNING "sn_common_bus_fixup: Unsupported asic type, %d", - prom_bussoft_ptr->bs_asic_type); - return; - } - - if (prom_bussoft_ptr->bs_asic_type == PCIIO_ASIC_TYPE_PPB) - return; /* no further fixup necessary */ - - provider = sn_pci_provider[prom_bussoft_ptr->bs_asic_type]; - if (provider == NULL) - panic("sn_common_bus_fixup: No provider registered for this asic type, %d", - prom_bussoft_ptr->bs_asic_type); - - if (provider->bus_fixup) - provider_soft = (*provider->bus_fixup) (prom_bussoft_ptr, - controller); - else - provider_soft = NULL; - - /* - * Generic bus fixup goes here. Don't reference prom_bussoft_ptr - * after this point. - */ - controller->platform_data = kzalloc(sizeof(struct sn_platform_data), - GFP_KERNEL); - if (controller->platform_data == NULL) - BUG(); - sn_platform_data = - (struct sn_platform_data *) controller->platform_data; - sn_platform_data->provider_soft = provider_soft; - INIT_LIST_HEAD(&((struct sn_platform_data *) - controller->platform_data)->pcidev_info); - nasid = NASID_GET(SN_PCIBUS_BUSSOFT(bus)->bs_base); - cnode = nasid_to_cnodeid(nasid); - hubdev_info = (struct hubdev_info *)(NODEPDA(cnode)->pdinfo); - SN_PCIBUS_BUSSOFT(bus)->bs_xwidget_info = - &(hubdev_info->hdi_xwidget_info[SN_PCIBUS_BUSSOFT(bus)->bs_xid]); - - /* - * If the node information we obtained during the fixup phase is - * invalid then set controller->node to -1 (undetermined) - */ - if (controller->node >= num_online_nodes()) { - struct pcibus_bussoft *b = SN_PCIBUS_BUSSOFT(bus); - - printk(KERN_WARNING "Device ASIC=%u XID=%u PBUSNUM=%u" - "L_IO=%lx L_MEM=%lx BASE=%lx\n", - b->bs_asic_type, b->bs_xid, b->bs_persist_busnum, - b->bs_legacy_io, b->bs_legacy_mem, b->bs_base); - printk(KERN_WARNING "on node %d but only %d nodes online." - "Association set to undetermined.\n", - controller->node, num_online_nodes()); - controller->node = -1; - } -} - -void sn_bus_store_sysdata(struct pci_dev *dev) -{ - struct sysdata_el *element; - - element = kzalloc(sizeof(struct sysdata_el), GFP_KERNEL); - if (!element) { - dev_dbg(dev, "%s: out of memory!\n", __FUNCTION__); - return; - } - element->sysdata = SN_PCIDEV_INFO(dev); - list_add(&element->entry, &sn_sysdata_list); -} - -void sn_bus_free_sysdata(void) -{ - struct sysdata_el *element; - struct list_head *list, *safe; - - list_for_each_safe(list, safe, &sn_sysdata_list) { - element = list_entry(list, struct sysdata_el, entry); - list_del(&element->entry); - list_del(&(((struct pcidev_info *) - (element->sysdata))->pdi_list)); - kfree(element->sysdata); - kfree(element); - } - return; -} - -/* - * hubdev_init_node() - Creates the HUB data structure and link them to it's - * own NODE specific data area. - */ -void hubdev_init_node(nodepda_t * npda, cnodeid_t node) -{ - struct hubdev_info *hubdev_info; - int size; - pg_data_t *pg; - - size = sizeof(struct hubdev_info); - - if (node >= num_online_nodes()) /* Headless/memless IO nodes */ - pg = NODE_DATA(0); - else - pg = NODE_DATA(node); - - hubdev_info = (struct hubdev_info *)alloc_bootmem_node(pg, size); - - npda->pdinfo = (void *)hubdev_info; -} - -geoid_t -cnodeid_get_geoid(cnodeid_t cnode) -{ - struct hubdev_info *hubdev; - - hubdev = (struct hubdev_info *)(NODEPDA(cnode)->pdinfo); - return hubdev->hdi_geoid; -} - -void sn_generate_path(struct pci_bus *pci_bus, char *address) -{ - nasid_t nasid; - cnodeid_t cnode; - geoid_t geoid; - moduleid_t moduleid; - u16 bricktype; - - nasid = NASID_GET(SN_PCIBUS_BUSSOFT(pci_bus)->bs_base); - cnode = nasid_to_cnodeid(nasid); - geoid = cnodeid_get_geoid(cnode); - moduleid = geo_module(geoid); - - sprintf(address, "module_%c%c%c%c%.2d", - '0'+RACK_GET_CLASS(MODULE_GET_RACK(moduleid)), - '0'+RACK_GET_GROUP(MODULE_GET_RACK(moduleid)), - '0'+RACK_GET_NUM(MODULE_GET_RACK(moduleid)), - MODULE_GET_BTCHAR(moduleid), MODULE_GET_BPOS(moduleid)); - - /* Tollhouse requires slot id to be displayed */ - bricktype = MODULE_GET_BTYPE(moduleid); - if ((bricktype == L1_BRICKTYPE_191010) || - (bricktype == L1_BRICKTYPE_1932)) - sprintf(address, "%s^%d", address, geo_slot(geoid)); -} - -/* - * sn_pci_fixup_bus() - Perform SN specific setup of software structs - * (pcibus_bussoft, pcidev_info) and hardware - * registers, for the specified bus and devices under it. - */ -void __devinit -sn_pci_fixup_bus(struct pci_bus *bus) -{ - - if (SN_ACPI_BASE_SUPPORT()) - sn_acpi_bus_fixup(bus); - else - sn_bus_fixup(bus); -} - -/* - * sn_io_early_init - Perform early IO (and some non-IO) initialization. - * In particular, setup the sn_pci_provider[] array. - * This needs to be done prior to any bus scanning - * (acpi_scan_init()) in the ACPI case, as the SN - * bus fixup code will reference the array. - */ -static int __init -sn_io_early_init(void) -{ - int i; - - if (!ia64_platform_is("sn2") || IS_RUNNING_ON_FAKE_PROM()) - return 0; - - /* - * prime sn_pci_provider[]. Individial provider init routines will - * override their respective default entries. - */ - - for (i = 0; i < PCIIO_ASIC_MAX_TYPES; i++) - sn_pci_provider[i] = &sn_pci_default_provider; - - pcibr_init_provider(); - tioca_init_provider(); - tioce_init_provider(); - - /* - * This is needed to avoid bounce limit checks in the blk layer - */ - ia64_max_iommu_merge_mask = ~PAGE_MASK; - - sn_irq_lh_init(); - INIT_LIST_HEAD(&sn_sysdata_list); - sn_init_cpei_timer(); - -#ifdef CONFIG_PROC_FS - register_sn_procfs(); -#endif - - printk(KERN_INFO "ACPI DSDT OEM Rev 0x%x\n", - acpi_gbl_DSDT->oem_revision); - if (SN_ACPI_BASE_SUPPORT()) - sn_io_acpi_init(); - else - sn_io_init(); - return 0; -} - -arch_initcall(sn_io_early_init); - -/* - * sn_io_late_init() - Perform any final platform specific IO initialization. - */ - -int __init -sn_io_late_init(void) -{ - struct pci_bus *bus; - struct pcibus_bussoft *bussoft; - cnodeid_t cnode; - nasid_t nasid; - cnodeid_t near_cnode; - - if (!ia64_platform_is("sn2") || IS_RUNNING_ON_FAKE_PROM()) - return 0; - - /* - * Setup closest node in pci_controller->node for - * PIC, TIOCP, TIOCE (TIOCA does it during bus fixup using - * info from the PROM). - */ - bus = NULL; - while ((bus = pci_find_next_bus(bus)) != NULL) { - bussoft = SN_PCIBUS_BUSSOFT(bus); - nasid = NASID_GET(bussoft->bs_base); - cnode = nasid_to_cnodeid(nasid); - if ((bussoft->bs_asic_type == PCIIO_ASIC_TYPE_TIOCP) || - (bussoft->bs_asic_type == PCIIO_ASIC_TYPE_TIOCE)) { - /* TIO PCI Bridge: find nearest node with CPUs */ - int e = sn_hwperf_get_nearest_node(cnode, NULL, - &near_cnode); - if (e < 0) { - near_cnode = (cnodeid_t)-1; /* use any node */ - printk(KERN_WARNING "pcibr_bus_fixup: failed " - "to find near node with CPUs to TIO " - "node %d, err=%d\n", cnode, e); - } - PCI_CONTROLLER(bus)->node = near_cnode; - } else if (bussoft->bs_asic_type == PCIIO_ASIC_TYPE_PIC) { - PCI_CONTROLLER(bus)->node = cnode; - } - } - - sn_ioif_inited = 1; /* SN I/O infrastructure now initialized */ - - return 0; -} - -fs_initcall(sn_io_late_init); - -EXPORT_SYMBOL(sn_pci_fixup_slot); -EXPORT_SYMBOL(sn_pci_unfixup_slot); -EXPORT_SYMBOL(sn_bus_store_sysdata); -EXPORT_SYMBOL(sn_bus_free_sysdata); -EXPORT_SYMBOL(sn_generate_path); - diff --git a/trunk/arch/ia64/sn/kernel/io_init.c b/trunk/arch/ia64/sn/kernel/io_init.c index 9ad843e0383b..dc09a6a28a37 100644 --- a/trunk/arch/ia64/sn/kernel/io_init.c +++ b/trunk/arch/ia64/sn/kernel/io_init.c @@ -3,28 +3,103 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1992 - 1997, 2000-2006 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 1992 - 1997, 2000-2005 Silicon Graphics, Inc. All rights reserved. */ +#include +#include #include #include +#include +#include #include +#include #include -#include +#include #include #include +#include #include +#include +#include #include "xtalk/hubdev.h" +#include "xtalk/xwidgetdev.h" -/* - * The code in this file will only be executed when running with - * a PROM that does _not_ have base ACPI IO support. - * (i.e., SN_ACPI_BASE_SUPPORT() == 0) - */ + +extern void sn_init_cpei_timer(void); +extern void register_sn_procfs(void); + +static struct list_head sn_sysdata_list; + +/* sysdata list struct */ +struct sysdata_el { + struct list_head entry; + void *sysdata; +}; + +struct slab_info { + struct hubdev_info hubdev; +}; + +struct brick { + moduleid_t id; /* Module ID of this module */ + struct slab_info slab_info[MAX_SLABS + 1]; +}; + +int sn_ioif_inited; /* SN I/O infrastructure initialized? */ + +struct sn_pcibus_provider *sn_pci_provider[PCIIO_ASIC_MAX_TYPES]; /* indexed by asic type */ static int max_segment_number; /* Default highest segment number */ static int max_pcibus_number = 255; /* Default highest pci bus number */ +/* + * Hooks and struct for unsupported pci providers + */ + +static dma_addr_t +sn_default_pci_map(struct pci_dev *pdev, unsigned long paddr, size_t size, int type) +{ + return 0; +} + +static void +sn_default_pci_unmap(struct pci_dev *pdev, dma_addr_t addr, int direction) +{ + return; +} + +static void * +sn_default_pci_bus_fixup(struct pcibus_bussoft *soft, struct pci_controller *controller) +{ + return NULL; +} + +static struct sn_pcibus_provider sn_pci_default_provider = { + .dma_map = sn_default_pci_map, + .dma_map_consistent = sn_default_pci_map, + .dma_unmap = sn_default_pci_unmap, + .bus_fixup = sn_default_pci_bus_fixup, +}; + +/* + * Retrieve the DMA Flush List given nasid, widget, and device. + * This list is needed to implement the WAR - Flush DMA data on PIO Reads. + */ +static inline u64 +sal_get_device_dmaflush_list(u64 nasid, u64 widget_num, u64 device_num, + u64 address) +{ + struct ia64_sal_retval ret_stuff; + ret_stuff.status = 0; + ret_stuff.v0 = 0; + + SAL_CALL_NOLOCK(ret_stuff, + (u64) SN_SAL_IOIF_GET_DEVICE_DMAFLUSH_LIST, + (u64) nasid, (u64) widget_num, + (u64) device_num, (u64) address, 0, 0, 0); + return ret_stuff.status; +} /* * Retrieve the hub device info structure for the given nasid. @@ -56,20 +131,93 @@ static inline u64 sal_get_pcibus_info(u64 segment, u64 busnum, u64 address) return ret_stuff.v0; } +/* + * Retrieve the pci device information given the bus and device|function number. + */ +static inline u64 +sal_get_pcidev_info(u64 segment, u64 bus_number, u64 devfn, u64 pci_dev, + u64 sn_irq_info) +{ + struct ia64_sal_retval ret_stuff; + ret_stuff.status = 0; + ret_stuff.v0 = 0; + + SAL_CALL_NOLOCK(ret_stuff, + (u64) SN_SAL_IOIF_GET_PCIDEV_INFO, + (u64) segment, (u64) bus_number, (u64) devfn, + (u64) pci_dev, + sn_irq_info, 0, 0); + return ret_stuff.v0; +} /* - * sn_fixup_ionodes() - This routine initializes the HUB data structure for - * each node in the system. This function is only - * executed when running with a non-ACPI capable PROM. + * sn_pcidev_info_get() - Retrieve the pcidev_info struct for the specified + * device. */ -static void __init sn_fixup_ionodes(void) +inline struct pcidev_info * +sn_pcidev_info_get(struct pci_dev *dev) { + struct pcidev_info *pcidev; + + list_for_each_entry(pcidev, + &(SN_PCI_CONTROLLER(dev)->pcidev_info), pdi_list) { + if (pcidev->pdi_linux_pcidev == dev) { + return pcidev; + } + } + return NULL; +} + +/* Older PROM flush WAR + * + * 01/16/06 -- This war will be in place until a new official PROM is released. + * Additionally note that the struct sn_flush_device_war also has to be + * removed from arch/ia64/sn/include/xtalk/hubdev.h + */ +static u8 war_implemented = 0; + +static s64 sn_device_fixup_war(u64 nasid, u64 widget, int device, + struct sn_flush_device_common *common) +{ + struct sn_flush_device_war *war_list; + struct sn_flush_device_war *dev_entry; + struct ia64_sal_retval isrv = {0,0,0,0}; + + if (!war_implemented) { + printk(KERN_WARNING "PROM version < 4.50 -- implementing old " + "PROM flush WAR\n"); + war_implemented = 1; + } + + war_list = kzalloc(DEV_PER_WIDGET * sizeof(*war_list), GFP_KERNEL); + if (!war_list) + BUG(); + + SAL_CALL_NOLOCK(isrv, SN_SAL_IOIF_GET_WIDGET_DMAFLUSH_LIST, + nasid, widget, __pa(war_list), 0, 0, 0 ,0); + if (isrv.status) + panic("sn_device_fixup_war failed: %s\n", + ia64_sal_strerror(isrv.status)); + + dev_entry = war_list + device; + memcpy(common,dev_entry, sizeof(*common)); + kfree(war_list); + return isrv.status; +} + +/* + * sn_fixup_ionodes() - This routine initializes the HUB data strcuture for + * each node in the system. + */ +static void __init sn_fixup_ionodes(void) +{ + struct sn_flush_device_kernel *sn_flush_device_kernel; + struct sn_flush_device_kernel *dev_entry; struct hubdev_info *hubdev; u64 status; u64 nasid; - int i; - extern void sn_common_hubdev_init(struct hubdev_info *); + int i, widget, device, size; /* * Get SGI Specific HUB chipset information. @@ -92,47 +240,70 @@ static void __init sn_fixup_ionodes(void) max_segment_number = hubdev->max_segment_number; max_pcibus_number = hubdev->max_pcibus_number; } - sn_common_hubdev_init(hubdev); - } -} -/* - * sn_pci_legacy_window_fixup - Create PCI controller windows for - * legacy IO and MEM space. This needs to - * be done here, as the PROM does not have - * ACPI support defining the root buses - * and their resources (_CRS), - */ -static void -sn_legacy_pci_window_fixup(struct pci_controller *controller, - u64 legacy_io, u64 legacy_mem) -{ - controller->window = kcalloc(2, sizeof(struct pci_window), - GFP_KERNEL); - if (controller->window == NULL) + /* Attach the error interrupt handlers */ + if (nasid & 1) + ice_error_init(hubdev); + else + hub_error_init(hubdev); + + for (widget = 0; widget <= HUB_WIDGET_ID_MAX; widget++) + hubdev->hdi_xwidget_info[widget].xwi_hubinfo = hubdev; + + if (!hubdev->hdi_flush_nasid_list.widget_p) + continue; + + size = (HUB_WIDGET_ID_MAX + 1) * + sizeof(struct sn_flush_device_kernel *); + hubdev->hdi_flush_nasid_list.widget_p = + kzalloc(size, GFP_KERNEL); + if (!hubdev->hdi_flush_nasid_list.widget_p) BUG(); - controller->window[0].offset = legacy_io; - controller->window[0].resource.name = "legacy_io"; - controller->window[0].resource.flags = IORESOURCE_IO; - controller->window[0].resource.start = legacy_io; - controller->window[0].resource.end = - controller->window[0].resource.start + 0xffff; - controller->window[0].resource.parent = &ioport_resource; - controller->window[1].offset = legacy_mem; - controller->window[1].resource.name = "legacy_mem"; - controller->window[1].resource.flags = IORESOURCE_MEM; - controller->window[1].resource.start = legacy_mem; - controller->window[1].resource.end = - controller->window[1].resource.start + (1024 * 1024) - 1; - controller->window[1].resource.parent = &iomem_resource; - controller->windows = 2; + + for (widget = 0; widget <= HUB_WIDGET_ID_MAX; widget++) { + size = DEV_PER_WIDGET * + sizeof(struct sn_flush_device_kernel); + sn_flush_device_kernel = kzalloc(size, GFP_KERNEL); + if (!sn_flush_device_kernel) + BUG(); + + dev_entry = sn_flush_device_kernel; + for (device = 0; device < DEV_PER_WIDGET; + device++,dev_entry++) { + size = sizeof(struct sn_flush_device_common); + dev_entry->common = kzalloc(size, GFP_KERNEL); + if (!dev_entry->common) + BUG(); + + if (sn_prom_feature_available( + PRF_DEVICE_FLUSH_LIST)) + status = sal_get_device_dmaflush_list( + nasid, widget, device, + (u64)(dev_entry->common)); + else + status = sn_device_fixup_war(nasid, + widget, device, + dev_entry->common); + if (status != SALRET_OK) + panic("SAL call failed: %s\n", + ia64_sal_strerror(status)); + + spin_lock_init(&dev_entry->sfdl_flush_lock); + } + + if (sn_flush_device_kernel) + hubdev->hdi_flush_nasid_list.widget_p[widget] = + sn_flush_device_kernel; + } + } } /* * sn_pci_window_fixup() - Create a pci_window for each device resource. - * It will setup pci_windows for use by - * pcibios_bus_to_resource(), pcibios_resource_to_bus(), - * etc. + * Until ACPI support is added, we need this code + * to setup pci_windows for use by + * pcibios_bus_to_resource(), + * pcibios_resource_to_bus(), etc. */ static void sn_pci_window_fixup(struct pci_dev *dev, unsigned int count, @@ -171,22 +342,60 @@ sn_pci_window_fixup(struct pci_dev *dev, unsigned int count, controller->window = new_window; } +void sn_pci_unfixup_slot(struct pci_dev *dev) +{ + struct pci_dev *host_pci_dev = SN_PCIDEV_INFO(dev)->host_pci_dev; + + sn_irq_unfixup(dev); + pci_dev_put(host_pci_dev); + pci_dev_put(dev); +} + /* - * sn_more_slot_fixup() - We are not running with an ACPI capable PROM, - * and need to convert the pci_dev->resource - * 'start' and 'end' addresses to mapped addresses, - * and setup the pci_controller->window array entries. + * sn_pci_fixup_slot() - This routine sets up a slot's resources + * consistent with the Linux PCI abstraction layer. Resources acquired + * from our PCI provider include PIO maps to BAR space and interrupt + * objects. */ -void -sn_more_slot_fixup(struct pci_dev *dev, struct pcidev_info *pcidev_info) +void sn_pci_fixup_slot(struct pci_dev *dev) { unsigned int count = 0; int idx; + int segment = pci_domain_nr(dev->bus); + int status = 0; + struct pcibus_bussoft *bs; + struct pci_bus *host_pci_bus; + struct pci_dev *host_pci_dev; + struct pcidev_info *pcidev_info; s64 pci_addrs[PCI_ROM_RESOURCE + 1]; - unsigned long addr, end, size, start; + struct sn_irq_info *sn_irq_info; + unsigned long size; + unsigned int bus_no, devfn; + + pci_dev_get(dev); /* for the sysdata pointer */ + pcidev_info = kzalloc(sizeof(struct pcidev_info), GFP_KERNEL); + if (!pcidev_info) + BUG(); /* Cannot afford to run out of memory */ + + sn_irq_info = kzalloc(sizeof(struct sn_irq_info), GFP_KERNEL); + if (!sn_irq_info) + BUG(); /* Cannot afford to run out of memory */ + + /* Call to retrieve pci device information needed by kernel. */ + status = sal_get_pcidev_info((u64) segment, (u64) dev->bus->number, + dev->devfn, + (u64) __pa(pcidev_info), + (u64) __pa(sn_irq_info)); + if (status) + BUG(); /* Cannot get platform pci device information */ + + /* Add pcidev_info to list in sn_pci_controller struct */ + list_add_tail(&pcidev_info->pdi_list, + &(SN_PCI_CONTROLLER(dev->bus)->pcidev_info)); /* Copy over PIO Mapped Addresses */ for (idx = 0; idx <= PCI_ROM_RESOURCE; idx++) { + unsigned long start, end, addr; if (!pcidev_info->pdi_pio_mapped_addr[idx]) { pci_addrs[idx] = -1; @@ -210,28 +419,60 @@ sn_more_slot_fixup(struct pci_dev *dev, struct pcidev_info *pcidev_info) dev->resource[idx].parent = &ioport_resource; else dev->resource[idx].parent = &iomem_resource; - /* If ROM, mark as shadowed in PROM */ - if (idx == PCI_ROM_RESOURCE) - dev->resource[idx].flags |= IORESOURCE_ROM_BIOS_COPY; } /* Create a pci_window in the pci_controller struct for * each device resource. */ if (count > 0) sn_pci_window_fixup(dev, count, pci_addrs); + + /* + * Using the PROMs values for the PCI host bus, get the Linux + * PCI host_pci_dev struct and set up host bus linkages + */ + + bus_no = (pcidev_info->pdi_slot_host_handle >> 32) & 0xff; + devfn = pcidev_info->pdi_slot_host_handle & 0xffffffff; + host_pci_bus = pci_find_bus(segment, bus_no); + host_pci_dev = pci_get_slot(host_pci_bus, devfn); + + pcidev_info->host_pci_dev = host_pci_dev; + pcidev_info->pdi_linux_pcidev = dev; + pcidev_info->pdi_host_pcidev_info = SN_PCIDEV_INFO(host_pci_dev); + bs = SN_PCIBUS_BUSSOFT(dev->bus); + pcidev_info->pdi_pcibus_info = bs; + + if (bs && bs->bs_asic_type < PCIIO_ASIC_MAX_TYPES) { + SN_PCIDEV_BUSPROVIDER(dev) = sn_pci_provider[bs->bs_asic_type]; + } else { + SN_PCIDEV_BUSPROVIDER(dev) = &sn_pci_default_provider; + } + + /* Only set up IRQ stuff if this device has a host bus context */ + if (bs && sn_irq_info->irq_irq) { + pcidev_info->pdi_sn_irq_info = sn_irq_info; + dev->irq = pcidev_info->pdi_sn_irq_info->irq_irq; + sn_irq_fixup(dev, sn_irq_info); + } else { + pcidev_info->pdi_sn_irq_info = NULL; + kfree(sn_irq_info); + } } /* * sn_pci_controller_fixup() - This routine sets up a bus's resources - * consistent with the Linux PCI abstraction layer. + * consistent with the Linux PCI abstraction layer. */ -static void -sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus) +void sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus) { - s64 status = 0; + int status; + int nasid, cnode; struct pci_controller *controller; + struct sn_pci_controller *sn_controller; struct pcibus_bussoft *prom_bussoft_ptr; - + struct hubdev_info *hubdev_info; + void *provider_soft; + struct sn_pcibus_provider *provider; status = sal_get_pcibus_info((u64) segment, (u64) busnum, (u64) ia64_tpa(&prom_bussoft_ptr)); @@ -239,77 +480,261 @@ sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus) return; /*bus # does not exist */ prom_bussoft_ptr = __va(prom_bussoft_ptr); - controller = kzalloc(sizeof(*controller), GFP_KERNEL); - if (!controller) + /* Allocate a sn_pci_controller, which has a pci_controller struct + * as the first member. + */ + sn_controller = kzalloc(sizeof(struct sn_pci_controller), GFP_KERNEL); + if (!sn_controller) BUG(); + INIT_LIST_HEAD(&sn_controller->pcidev_info); + controller = &sn_controller->pci_controller; controller->segment = segment; + if (bus == NULL) { + bus = pci_scan_bus(busnum, &pci_root_ops, controller); + if (bus == NULL) + goto error_return; /* error, or bus already scanned */ + bus->sysdata = NULL; + } + + if (bus->sysdata) + goto error_return; /* sysdata already alloc'd */ + /* - * Temporarily save the prom_bussoft_ptr for use by sn_bus_fixup(). - * (platform_data will be overwritten later in sn_common_bus_fixup()) + * Per-provider fixup. Copies the contents from prom to local + * area and links SN_PCIBUS_BUSSOFT(). */ - controller->platform_data = prom_bussoft_ptr; - bus = pci_scan_bus(busnum, &pci_root_ops, controller); - if (bus == NULL) - goto error_return; /* error, or bus already scanned */ + if (prom_bussoft_ptr->bs_asic_type >= PCIIO_ASIC_MAX_TYPES) + goto error_return; /* unsupported asic type */ + + if (prom_bussoft_ptr->bs_asic_type == PCIIO_ASIC_TYPE_PPB) + goto error_return; /* no further fixup necessary */ + + provider = sn_pci_provider[prom_bussoft_ptr->bs_asic_type]; + if (provider == NULL) + goto error_return; /* no provider registerd for this asic */ bus->sysdata = controller; + if (provider->bus_fixup) + provider_soft = (*provider->bus_fixup) (prom_bussoft_ptr, controller); + else + provider_soft = NULL; + + if (provider_soft == NULL) { + /* fixup failed or not applicable */ + bus->sysdata = NULL; + goto error_return; + } + + /* + * Setup pci_windows for legacy IO and MEM space. + * (Temporary until ACPI support is in place.) + */ + controller->window = kcalloc(2, sizeof(struct pci_window), GFP_KERNEL); + if (controller->window == NULL) + BUG(); + controller->window[0].offset = prom_bussoft_ptr->bs_legacy_io; + controller->window[0].resource.name = "legacy_io"; + controller->window[0].resource.flags = IORESOURCE_IO; + controller->window[0].resource.start = prom_bussoft_ptr->bs_legacy_io; + controller->window[0].resource.end = + controller->window[0].resource.start + 0xffff; + controller->window[0].resource.parent = &ioport_resource; + controller->window[1].offset = prom_bussoft_ptr->bs_legacy_mem; + controller->window[1].resource.name = "legacy_mem"; + controller->window[1].resource.flags = IORESOURCE_MEM; + controller->window[1].resource.start = prom_bussoft_ptr->bs_legacy_mem; + controller->window[1].resource.end = + controller->window[1].resource.start + (1024 * 1024) - 1; + controller->window[1].resource.parent = &iomem_resource; + controller->windows = 2; + + /* + * Generic bus fixup goes here. Don't reference prom_bussoft_ptr + * after this point. + */ + + PCI_CONTROLLER(bus)->platform_data = provider_soft; + nasid = NASID_GET(SN_PCIBUS_BUSSOFT(bus)->bs_base); + cnode = nasid_to_cnodeid(nasid); + hubdev_info = (struct hubdev_info *)(NODEPDA(cnode)->pdinfo); + SN_PCIBUS_BUSSOFT(bus)->bs_xwidget_info = + &(hubdev_info->hdi_xwidget_info[SN_PCIBUS_BUSSOFT(bus)->bs_xid]); + /* + * If the node information we obtained during the fixup phase is invalid + * then set controller->node to -1 (undetermined) + */ + if (controller->node >= num_online_nodes()) { + struct pcibus_bussoft *b = SN_PCIBUS_BUSSOFT(bus); + + printk(KERN_WARNING "Device ASIC=%u XID=%u PBUSNUM=%u" + "L_IO=%lx L_MEM=%lx BASE=%lx\n", + b->bs_asic_type, b->bs_xid, b->bs_persist_busnum, + b->bs_legacy_io, b->bs_legacy_mem, b->bs_base); + printk(KERN_WARNING "on node %d but only %d nodes online." + "Association set to undetermined.\n", + controller->node, num_online_nodes()); + controller->node = -1; + } return; error_return: - kfree(controller); + kfree(sn_controller); return; } -/* - * sn_bus_fixup - */ -void -sn_bus_fixup(struct pci_bus *bus) +void sn_bus_store_sysdata(struct pci_dev *dev) { - struct pci_dev *pci_dev = NULL; - struct pcibus_bussoft *prom_bussoft_ptr; - extern void sn_common_bus_fixup(struct pci_bus *, - struct pcibus_bussoft *); - - - if (!bus->parent) { /* If root bus */ - prom_bussoft_ptr = PCI_CONTROLLER(bus)->platform_data; - if (prom_bussoft_ptr == NULL) { - printk(KERN_ERR - "sn_bus_fixup: 0x%04x:0x%02x Unable to " - "obtain prom_bussoft_ptr\n", - pci_domain_nr(bus), bus->number); - return; - } - sn_common_bus_fixup(bus, prom_bussoft_ptr); - sn_legacy_pci_window_fixup(PCI_CONTROLLER(bus), - prom_bussoft_ptr->bs_legacy_io, - prom_bussoft_ptr->bs_legacy_mem); - } - list_for_each_entry(pci_dev, &bus->devices, bus_list) { - sn_pci_fixup_slot(pci_dev); - } + struct sysdata_el *element; + + element = kzalloc(sizeof(struct sysdata_el), GFP_KERNEL); + if (!element) { + dev_dbg(dev, "%s: out of memory!\n", __FUNCTION__); + return; + } + element->sysdata = SN_PCIDEV_INFO(dev); + list_add(&element->entry, &sn_sysdata_list); +} +void sn_bus_free_sysdata(void) +{ + struct sysdata_el *element; + struct list_head *list, *safe; + + list_for_each_safe(list, safe, &sn_sysdata_list) { + element = list_entry(list, struct sysdata_el, entry); + list_del(&element->entry); + list_del(&(((struct pcidev_info *) + (element->sysdata))->pdi_list)); + kfree(element->sysdata); + kfree(element); + } + return; } /* - * sn_io_init - PROM does not have ACPI support to define nodes or root buses, - * so we need to do things the hard way, including initiating the - * bus scanning ourselves. + * Ugly hack to get PCI setup until we have a proper ACPI namespace. */ -void __init sn_io_init(void) +#define PCI_BUSES_TO_SCAN 256 + +static int __init sn_pci_init(void) { int i, j; + struct pci_dev *pci_dev = NULL; + + if (!ia64_platform_is("sn2") || IS_RUNNING_ON_FAKE_PROM()) + return 0; + + /* + * prime sn_pci_provider[]. Individial provider init routines will + * override their respective default entries. + */ + + for (i = 0; i < PCIIO_ASIC_MAX_TYPES; i++) + sn_pci_provider[i] = &sn_pci_default_provider; + pcibr_init_provider(); + tioca_init_provider(); + tioce_init_provider(); + + /* + * This is needed to avoid bounce limit checks in the blk layer + */ + ia64_max_iommu_merge_mask = ~PAGE_MASK; sn_fixup_ionodes(); + sn_irq_lh_init(); + INIT_LIST_HEAD(&sn_sysdata_list); + sn_init_cpei_timer(); + +#ifdef CONFIG_PROC_FS + register_sn_procfs(); +#endif /* busses are not known yet ... */ for (i = 0; i <= max_segment_number; i++) for (j = 0; j <= max_pcibus_number; j++) sn_pci_controller_fixup(i, j, NULL); + + /* + * Generic Linux PCI Layer has created the pci_bus and pci_dev + * structures - time for us to add our SN PLatform specific + * information. + */ + + while ((pci_dev = + pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) != NULL) + sn_pci_fixup_slot(pci_dev); + + sn_ioif_inited = 1; /* sn I/O infrastructure now initialized */ + + return 0; +} + +/* + * hubdev_init_node() - Creates the HUB data structure and link them to it's + * own NODE specific data area. + */ +void hubdev_init_node(nodepda_t * npda, cnodeid_t node) +{ + struct hubdev_info *hubdev_info; + int size; + pg_data_t *pg; + + size = sizeof(struct hubdev_info); + + if (node >= num_online_nodes()) /* Headless/memless IO nodes */ + pg = NODE_DATA(0); + else + pg = NODE_DATA(node); + + hubdev_info = (struct hubdev_info *)alloc_bootmem_node(pg, size); + + npda->pdinfo = (void *)hubdev_info; } + +geoid_t +cnodeid_get_geoid(cnodeid_t cnode) +{ + struct hubdev_info *hubdev; + + hubdev = (struct hubdev_info *)(NODEPDA(cnode)->pdinfo); + return hubdev->hdi_geoid; +} + +void sn_generate_path(struct pci_bus *pci_bus, char *address) +{ + nasid_t nasid; + cnodeid_t cnode; + geoid_t geoid; + moduleid_t moduleid; + u16 bricktype; + + nasid = NASID_GET(SN_PCIBUS_BUSSOFT(pci_bus)->bs_base); + cnode = nasid_to_cnodeid(nasid); + geoid = cnodeid_get_geoid(cnode); + moduleid = geo_module(geoid); + + sprintf(address, "module_%c%c%c%c%.2d", + '0'+RACK_GET_CLASS(MODULE_GET_RACK(moduleid)), + '0'+RACK_GET_GROUP(MODULE_GET_RACK(moduleid)), + '0'+RACK_GET_NUM(MODULE_GET_RACK(moduleid)), + MODULE_GET_BTCHAR(moduleid), MODULE_GET_BPOS(moduleid)); + + /* Tollhouse requires slot id to be displayed */ + bricktype = MODULE_GET_BTYPE(moduleid); + if ((bricktype == L1_BRICKTYPE_191010) || + (bricktype == L1_BRICKTYPE_1932)) + sprintf(address, "%s^%d", address, geo_slot(geoid)); +} + +subsys_initcall(sn_pci_init); +EXPORT_SYMBOL(sn_pci_fixup_slot); +EXPORT_SYMBOL(sn_pci_unfixup_slot); +EXPORT_SYMBOL(sn_pci_controller_fixup); +EXPORT_SYMBOL(sn_bus_store_sysdata); +EXPORT_SYMBOL(sn_bus_free_sysdata); +EXPORT_SYMBOL(sn_generate_path); diff --git a/trunk/arch/ia64/sn/kernel/iomv.c b/trunk/arch/ia64/sn/kernel/iomv.c index 4aa4f301d56d..7ce3cdad627b 100644 --- a/trunk/arch/ia64/sn/kernel/iomv.c +++ b/trunk/arch/ia64/sn/kernel/iomv.c @@ -3,11 +3,10 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2000-2003, 2006 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 2000-2003 Silicon Graphics, Inc. All rights reserved. */ #include -#include #include #include #include @@ -16,7 +15,6 @@ #include #include #include -#include #define IS_LEGACY_VGA_IOPORT(p) \ (((p) >= 0x3b0 && (p) <= 0x3bb) || ((p) >= 0x3c0 && (p) <= 0x3df)) @@ -33,14 +31,11 @@ void *sn_io_addr(unsigned long port) { if (!IS_RUNNING_ON_SIMULATOR()) { if (IS_LEGACY_VGA_IOPORT(port)) - return (__ia64_mk_io_addr(port)); + port += vga_console_iobase; /* On sn2, legacy I/O ports don't point at anything */ if (port < (64 * 1024)) return NULL; - if (SN_ACPI_BASE_SUPPORT()) - return (__ia64_mk_io_addr(port)); - else - return ((void *)(port | __IA64_UNCACHED_OFFSET)); + return ((void *)(port | __IA64_UNCACHED_OFFSET)); } else { /* but the simulator uses them... */ unsigned long addr; diff --git a/trunk/arch/ia64/sn/kernel/irq.c b/trunk/arch/ia64/sn/kernel/irq.c index 0b49459a878a..7bb6ad188ba3 100644 --- a/trunk/arch/ia64/sn/kernel/irq.c +++ b/trunk/arch/ia64/sn/kernel/irq.c @@ -201,7 +201,7 @@ static void sn_set_affinity_irq(unsigned int irq, cpumask_t mask) } struct hw_interrupt_type irq_type_sn = { - .name = "SN hub", + .typename = "SN hub", .startup = sn_startup_irq, .shutdown = sn_shutdown_irq, .enable = sn_enable_irq, diff --git a/trunk/arch/ia64/sn/kernel/setup.c b/trunk/arch/ia64/sn/kernel/setup.c index 1d009f93244d..5f2dcba7fa8d 100644 --- a/trunk/arch/ia64/sn/kernel/setup.c +++ b/trunk/arch/ia64/sn/kernel/setup.c @@ -65,6 +65,7 @@ extern void sn_timer_init(void); extern unsigned long last_time_offset; extern void (*ia64_mark_idle) (int); extern void snidle(int); +extern unsigned char acpi_kbd_controller_present; extern unsigned long long (*ia64_printk_clock)(void); unsigned long sn_rtc_cycles_per_second; @@ -388,14 +389,6 @@ void __init sn_setup(char **cmdline_p) ia64_sn_plat_set_error_handling_features(); // obsolete ia64_sn_set_os_feature(OSF_MCA_SLV_TO_OS_INIT_SLV); ia64_sn_set_os_feature(OSF_FEAT_LOG_SBES); - /* - * Note: The calls to notify the PROM of ACPI and PCI Segment - * support must be done prior to acpi_load_tables(), as - * an ACPI capable PROM will rebuild the DSDT as result - * of the call. - */ - ia64_sn_set_os_feature(OSF_PCISEGMENT_ENABLE); - ia64_sn_set_os_feature(OSF_ACPI_ENABLE); #if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) @@ -421,16 +414,6 @@ void __init sn_setup(char **cmdline_p) if (! vga_console_membase) sn_scan_pcdp(); - /* - * Setup legacy IO space. - * vga_console_iobase maps to PCI IO Space address 0 on the - * bus containing the VGA console. - */ - if (vga_console_iobase) { - io_space[0].mmio_base = vga_console_iobase; - io_space[0].sparse = 0; - } - if (vga_console_membase) { /* usable vga ... make tty0 the preferred default console */ if (!strstr(*cmdline_p, "console=")) @@ -469,6 +452,17 @@ void __init sn_setup(char **cmdline_p) ia64_printk_clock = ia64_sn2_printk_clock; + /* + * Old PROMs do not provide an ACPI FADT. Disable legacy keyboard + * support here so we don't have to listen to failed keyboard probe + * messages. + */ + if (is_shub1() && version <= 0x0209 && acpi_kbd_controller_present) { + printk(KERN_INFO "Disabling legacy keyboard support as prom " + "is too old and doesn't provide FADT\n"); + acpi_kbd_controller_present = 0; + } + printk("SGI SAL version %x.%02x\n", version >> 8, version & 0x00FF); /* diff --git a/trunk/arch/ia64/sn/kernel/sn2/timer_interrupt.c b/trunk/arch/ia64/sn/kernel/sn2/timer_interrupt.c index 103d6ea8e94b..fa7f69945917 100644 --- a/trunk/arch/ia64/sn/kernel/sn2/timer_interrupt.c +++ b/trunk/arch/ia64/sn/kernel/sn2/timer_interrupt.c @@ -36,7 +36,7 @@ extern irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs); #define SN_LB_INT_WAR_INTERVAL 100 -void sn_timer_interrupt(int irq, void *dev_id) +void sn_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { /* LED blinking */ if (!pda->hb_count--) { diff --git a/trunk/arch/ia64/sn/kernel/tiocx.c b/trunk/arch/ia64/sn/kernel/tiocx.c index 493380b2c05f..feaf1a6e8101 100644 --- a/trunk/arch/ia64/sn/kernel/tiocx.c +++ b/trunk/arch/ia64/sn/kernel/tiocx.c @@ -552,7 +552,7 @@ static void __exit tiocx_exit(void) bus_unregister(&tiocx_bus_type); } -fs_initcall(tiocx_init); +subsys_initcall(tiocx_init); module_exit(tiocx_exit); /************************************************************************ diff --git a/trunk/arch/ia64/sn/kernel/xpc_main.c b/trunk/arch/ia64/sn/kernel/xpc_main.c index fa96dfc0e1aa..4d026f9dd98b 100644 --- a/trunk/arch/ia64/sn/kernel/xpc_main.c +++ b/trunk/arch/ia64/sn/kernel/xpc_main.c @@ -222,7 +222,7 @@ xpc_timeout_partition_disengage_request(unsigned long data) * Notify the heartbeat check thread that an IRQ has been received. */ static irqreturn_t -xpc_act_IRQ_handler(int irq, void *dev_id) +xpc_act_IRQ_handler(int irq, void *dev_id, struct pt_regs *regs) { atomic_inc(&xpc_act_IRQ_rcvd); wake_up_interruptible(&xpc_act_IRQ_wq); @@ -607,9 +607,12 @@ xpc_activate_partition(struct xpc_partition *part) * irq - Interrupt ReQuest number. NOT USED. * * dev_id - partid of IPI's potential sender. + * + * regs - processor's context before the processor entered + * interrupt code. NOT USED. */ irqreturn_t -xpc_notify_IRQ_handler(int irq, void *dev_id) +xpc_notify_IRQ_handler(int irq, void *dev_id, struct pt_regs *regs) { partid_t partid = (partid_t) (u64) dev_id; struct xpc_partition *part = &xpc_partitions[partid]; diff --git a/trunk/arch/ia64/sn/pci/pcibr/pcibr_ate.c b/trunk/arch/ia64/sn/pci/pcibr/pcibr_ate.c index 935029fc400d..5eb1e1e078b4 100644 --- a/trunk/arch/ia64/sn/pci/pcibr/pcibr_ate.c +++ b/trunk/arch/ia64/sn/pci/pcibr/pcibr_ate.c @@ -126,7 +126,7 @@ int pcibr_ate_alloc(struct pcibus_info *pcibus_info, int count) * Setup an Address Translation Entry as specified. Use either the Bridge * internal maps or the external map RAM, as appropriate. */ -static inline u64 __iomem *pcibr_ate_addr(struct pcibus_info *pcibus_info, +static inline u64 *pcibr_ate_addr(struct pcibus_info *pcibus_info, int ate_index) { if (ate_index < pcibus_info->pbi_int_ate_size) { diff --git a/trunk/arch/ia64/sn/pci/pcibr/pcibr_provider.c b/trunk/arch/ia64/sn/pci/pcibr/pcibr_provider.c index 6846dc9b432d..838c93c9a16a 100644 --- a/trunk/arch/ia64/sn/pci/pcibr/pcibr_provider.c +++ b/trunk/arch/ia64/sn/pci/pcibr/pcibr_provider.c @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2001-2004, 2006 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 2001-2004 Silicon Graphics, Inc. All rights reserved. */ #include @@ -95,7 +95,7 @@ u16 sn_ioboard_to_pci_bus(struct pci_bus *pci_bus) * bridge sends an error interrupt. */ static irqreturn_t -pcibr_error_intr_handler(int irq, void *arg) +pcibr_error_intr_handler(int irq, void *arg, struct pt_regs *regs) { struct pcibus_info *soft = (struct pcibus_info *)arg; @@ -109,6 +109,7 @@ void * pcibr_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *controller) { int nasid, cnode, j; + cnodeid_t near_cnode; struct hubdev_info *hubdev_info; struct pcibus_info *soft; struct sn_flush_device_kernel *sn_flush_device_kernel; @@ -137,7 +138,7 @@ pcibr_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont /* * register the bridge's error interrupt handler */ - if (request_irq(SGI_PCIASIC_ERROR, pcibr_error_intr_handler, + if (request_irq(SGI_PCIASIC_ERROR, (void *)pcibr_error_intr_handler, IRQF_SHARED, "PCIBR error", (void *)(soft))) { printk(KERN_WARNING "pcibr cannot allocate interrupt for error handler\n"); @@ -185,6 +186,20 @@ pcibr_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont return NULL; } + if (prom_bussoft->bs_asic_type == PCIIO_ASIC_TYPE_TIOCP) { + /* TIO PCI Bridge: find nearest node with CPUs */ + int e = sn_hwperf_get_nearest_node(cnode, NULL, &near_cnode); + + if (e < 0) { + near_cnode = (cnodeid_t)-1; /* use any node */ + printk(KERN_WARNING "pcibr_bus_fixup: failed to find " + "near node with CPUs to TIO node %d, err=%d\n", + cnode, e); + } + controller->node = near_cnode; + } + else + controller->node = cnode; return soft; } diff --git a/trunk/arch/ia64/sn/pci/tioca_provider.c b/trunk/arch/ia64/sn/pci/tioca_provider.c index 8a2cb4e691fd..c36b0f5affb3 100644 --- a/trunk/arch/ia64/sn/pci/tioca_provider.c +++ b/trunk/arch/ia64/sn/pci/tioca_provider.c @@ -550,12 +550,13 @@ tioca_dma_map(struct pci_dev *pdev, u64 paddr, size_t byte_count, int dma_flags) * tioca_error_intr_handler - SGI TIO CA error interrupt handler * @irq: unused * @arg: pointer to tioca_common struct for the given CA + * @pt: unused * * Handle a CA error interrupt. Simply a wrapper around a SAL call which * defers processing to the SGI prom. */ static irqreturn_t -tioca_error_intr_handler(int irq, void *arg) +tioca_error_intr_handler(int irq, void *arg, struct pt_regs *pt) { struct tioca_common *soft = arg; struct ia64_sal_retval ret_stuff; diff --git a/trunk/arch/ia64/sn/pci/tioce_provider.c b/trunk/arch/ia64/sn/pci/tioce_provider.c index 35f854fb6120..af7171adcd2c 100644 --- a/trunk/arch/ia64/sn/pci/tioce_provider.c +++ b/trunk/arch/ia64/sn/pci/tioce_provider.c @@ -15,6 +15,7 @@ #include #include #include +#include /* * 1/26/2006 @@ -52,7 +53,7 @@ */ static void inline -tioce_mmr_war_pre(struct tioce_kernel *kern, void __iomem *mmr_addr) +tioce_mmr_war_pre(struct tioce_kernel *kern, void *mmr_addr) { u64 mmr_base; u64 mmr_offset; @@ -61,7 +62,7 @@ tioce_mmr_war_pre(struct tioce_kernel *kern, void __iomem *mmr_addr) return; mmr_base = kern->ce_common->ce_pcibus.bs_base; - mmr_offset = (unsigned long)mmr_addr - mmr_base; + mmr_offset = (u64)mmr_addr - mmr_base; if (mmr_offset < 0x45000) { u64 mmr_war_offset; @@ -78,7 +79,7 @@ tioce_mmr_war_pre(struct tioce_kernel *kern, void __iomem *mmr_addr) } static void inline -tioce_mmr_war_post(struct tioce_kernel *kern, void __iomem *mmr_addr) +tioce_mmr_war_post(struct tioce_kernel *kern, void *mmr_addr) { u64 mmr_base; u64 mmr_offset; @@ -87,7 +88,7 @@ tioce_mmr_war_post(struct tioce_kernel *kern, void __iomem *mmr_addr) return; mmr_base = kern->ce_common->ce_pcibus.bs_base; - mmr_offset = (unsigned long)mmr_addr - mmr_base; + mmr_offset = (u64)mmr_addr - mmr_base; if (mmr_offset < 0x45000) { if (mmr_offset == 0x100) @@ -222,7 +223,7 @@ tioce_dma_d64(unsigned long ct_addr, int dma_flags) * @pci_dev. */ static inline void -pcidev_to_tioce(struct pci_dev *pdev, struct tioce __iomem **base, +pcidev_to_tioce(struct pci_dev *pdev, struct tioce **base, struct tioce_kernel **kernel, int *port) { struct pcidev_info *pcidev_info; @@ -234,7 +235,7 @@ pcidev_to_tioce(struct pci_dev *pdev, struct tioce __iomem **base, ce_kernel = (struct tioce_kernel *)ce_common->ce_kernel_private; if (base) - *base = (struct tioce __iomem *)ce_common->ce_pcibus.bs_base; + *base = (struct tioce *)ce_common->ce_pcibus.bs_base; if (kernel) *kernel = ce_kernel; @@ -274,13 +275,13 @@ tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port, u64 pagesize; int msi_capable, msi_wanted; u64 *ate_shadow; - u64 __iomem *ate_reg; + u64 *ate_reg; u64 addr; - struct tioce __iomem *ce_mmr; + struct tioce *ce_mmr; u64 bus_base; struct tioce_dmamap *map; - ce_mmr = (struct tioce __iomem *)ce_kern->ce_common->ce_pcibus.bs_base; + ce_mmr = (struct tioce *)ce_kern->ce_common->ce_pcibus.bs_base; switch (type) { case TIOCE_ATE_M32: @@ -385,7 +386,7 @@ tioce_dma_d32(struct pci_dev *pdev, u64 ct_addr, int dma_flags) { int dma_ok; int port; - struct tioce __iomem *ce_mmr; + struct tioce *ce_mmr; struct tioce_kernel *ce_kern; u64 ct_upper; u64 ct_lower; @@ -460,7 +461,7 @@ tioce_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, int dir) int i; int port; struct tioce_kernel *ce_kern; - struct tioce __iomem *ce_mmr; + struct tioce *ce_mmr; unsigned long flags; bus_addr = tioce_dma_barrier(bus_addr, 0); @@ -665,11 +666,12 @@ tioce_dma_consistent(struct pci_dev *pdev, u64 paddr, size_t byte_count, int dma * tioce_error_intr_handler - SGI TIO CE error interrupt handler * @irq: unused * @arg: pointer to tioce_common struct for the given CE + * @pt: unused * * Handle a CE error interrupt. Simply a wrapper around a SAL call which * defers processing to the SGI prom. */ static irqreturn_t -tioce_error_intr_handler(int irq, void *arg) +tioce_error_intr_handler(int irq, void *arg, struct pt_regs *pt) { struct tioce_common *soft = arg; struct ia64_sal_retval ret_stuff; @@ -699,9 +701,9 @@ static void tioce_reserve_m32(struct tioce_kernel *ce_kern, u64 base, u64 limit) { int ate_index, last_ate, ps; - struct tioce __iomem *ce_mmr; + struct tioce *ce_mmr; - ce_mmr = (struct tioce __iomem *)ce_kern->ce_common->ce_pcibus.bs_base; + ce_mmr = (struct tioce *)ce_kern->ce_common->ce_pcibus.bs_base; ps = ce_kern->ce_ate3240_pagesize; ate_index = ATE_PAGE(base, ps); last_ate = ate_index + ATE_NPAGES(base, limit-base+1, ps) - 1; @@ -735,7 +737,7 @@ tioce_kern_init(struct tioce_common *tioce_common) int dev; u32 tmp; unsigned int seg, bus; - struct tioce __iomem *tioce_mmr; + struct tioce *tioce_mmr; struct tioce_kernel *tioce_kern; tioce_kern = kzalloc(sizeof(struct tioce_kernel), GFP_KERNEL); @@ -766,7 +768,7 @@ tioce_kern_init(struct tioce_common *tioce_common) * the ate's. */ - tioce_mmr = (struct tioce __iomem *)tioce_common->ce_pcibus.bs_base; + tioce_mmr = (struct tioce *)tioce_common->ce_pcibus.bs_base; tioce_mmr_clri(tioce_kern, &tioce_mmr->ce_ure_page_map, CE_URE_PAGESIZE_MASK); tioce_mmr_seti(tioce_kern, &tioce_mmr->ce_ure_page_map, @@ -857,7 +859,7 @@ tioce_force_interrupt(struct sn_irq_info *sn_irq_info) struct pcidev_info *pcidev_info; struct tioce_common *ce_common; struct tioce_kernel *ce_kern; - struct tioce __iomem *ce_mmr; + struct tioce *ce_mmr; u64 force_int_val; if (!sn_irq_info->irq_bridge) @@ -871,7 +873,7 @@ tioce_force_interrupt(struct sn_irq_info *sn_irq_info) return; ce_common = (struct tioce_common *)pcidev_info->pdi_pcibus_info; - ce_mmr = (struct tioce __iomem *)ce_common->ce_pcibus.bs_base; + ce_mmr = (struct tioce *)ce_common->ce_pcibus.bs_base; ce_kern = (struct tioce_kernel *)ce_common->ce_kernel_private; /* @@ -952,7 +954,7 @@ tioce_target_interrupt(struct sn_irq_info *sn_irq_info) struct pcidev_info *pcidev_info; struct tioce_common *ce_common; struct tioce_kernel *ce_kern; - struct tioce __iomem *ce_mmr; + struct tioce *ce_mmr; int bit; u64 vector; @@ -961,7 +963,7 @@ tioce_target_interrupt(struct sn_irq_info *sn_irq_info) return; ce_common = (struct tioce_common *)pcidev_info->pdi_pcibus_info; - ce_mmr = (struct tioce __iomem *)ce_common->ce_pcibus.bs_base; + ce_mmr = (struct tioce *)ce_common->ce_pcibus.bs_base; ce_kern = (struct tioce_kernel *)ce_common->ce_kernel_private; bit = sn_irq_info->irq_int_bit; @@ -989,9 +991,11 @@ tioce_target_interrupt(struct sn_irq_info *sn_irq_info) static void * tioce_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *controller) { + int my_nasid; + cnodeid_t my_cnode, mem_cnode; struct tioce_common *tioce_common; struct tioce_kernel *tioce_kern; - struct tioce __iomem *tioce_mmr; + struct tioce *tioce_mmr; /* * Allocate kernel bus soft and copy from prom. @@ -1015,7 +1019,7 @@ tioce_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont * interrupt handler. */ - tioce_mmr = (struct tioce __iomem *)tioce_common->ce_pcibus.bs_base; + tioce_mmr = (struct tioce *)tioce_common->ce_pcibus.bs_base; tioce_mmr_seti(tioce_kern, &tioce_mmr->ce_adm_int_status_alias, ~0ULL); tioce_mmr_seti(tioce_kern, &tioce_mmr->ce_adm_error_summary_alias, ~0ULL); @@ -1032,6 +1036,21 @@ tioce_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont tioce_common->ce_pcibus.bs_persist_segment, tioce_common->ce_pcibus.bs_persist_busnum); + /* + * identify closest nasid for memory allocations + */ + + my_nasid = NASID_GET(tioce_common->ce_pcibus.bs_base); + my_cnode = nasid_to_cnodeid(my_nasid); + + if (sn_hwperf_get_nearest_node(my_cnode, &mem_cnode, NULL) < 0) { + printk(KERN_WARNING "tioce_bus_fixup: failed to find " + "closest node with MEM to TIO node %d\n", my_cnode); + mem_cnode = (cnodeid_t)-1; /* use any node */ + } + + controller->node = mem_cnode; + return tioce_common; } diff --git a/trunk/arch/m32r/kernel/irq.c b/trunk/arch/m32r/kernel/irq.c index f8d8650383e0..3841861df6a2 100644 --- a/trunk/arch/m32r/kernel/irq.c +++ b/trunk/arch/m32r/kernel/irq.c @@ -77,16 +77,13 @@ int show_interrupts(struct seq_file *p, void *v) */ asmlinkage unsigned int do_IRQ(int irq, struct pt_regs *regs) { - struct pt_regs *old_regs; - old_regs = set_irq_regs(regs); irq_enter(); #ifdef CONFIG_DEBUG_STACKOVERFLOW /* FIXME M32R */ #endif - __do_IRQ(irq); + __do_IRQ(irq, regs); irq_exit(); - set_irq_regs(old_regs); return 1; } diff --git a/trunk/arch/m32r/kernel/setup.c b/trunk/arch/m32r/kernel/setup.c index 0e7778be33cc..3f35ab3d2dc2 100644 --- a/trunk/arch/m32r/kernel/setup.c +++ b/trunk/arch/m32r/kernel/setup.c @@ -369,10 +369,10 @@ static void c_stop(struct seq_file *m, void *v) } struct seq_operations cpuinfo_op = { - .start = c_start, - .next = c_next, - .stop = c_stop, - .show = show_cpuinfo, + start: c_start, + next: c_next, + stop: c_stop, + show: show_cpuinfo, }; #endif /* CONFIG_PROC_FS */ diff --git a/trunk/arch/m32r/kernel/setup_mappi.c b/trunk/arch/m32r/kernel/setup_mappi.c index 6b2d77da0683..67dbbdc9d111 100644 --- a/trunk/arch/m32r/kernel/setup_mappi.c +++ b/trunk/arch/m32r/kernel/setup_mappi.c @@ -86,7 +86,7 @@ void __init init_IRQ(void) /* INT0 : LAN controller (RTL8019AS) */ irq_desc[M32R_IRQ_INT0].status = IRQ_DISABLED; irq_desc[M32R_IRQ_INT0].chip = &mappi_irq_type; - irq_desc[M32R_IRQ_INT0].action = NULL; + irq_desc[M32R_IRQ_INT0].action = 0; irq_desc[M32R_IRQ_INT0].depth = 1; icu_data[M32R_IRQ_INT0].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; disable_mappi_irq(M32R_IRQ_INT0); @@ -95,7 +95,7 @@ void __init init_IRQ(void) /* MFT2 : system timer */ irq_desc[M32R_IRQ_MFT2].status = IRQ_DISABLED; irq_desc[M32R_IRQ_MFT2].chip = &mappi_irq_type; - irq_desc[M32R_IRQ_MFT2].action = NULL; + irq_desc[M32R_IRQ_MFT2].action = 0; irq_desc[M32R_IRQ_MFT2].depth = 1; icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; disable_mappi_irq(M32R_IRQ_MFT2); @@ -104,7 +104,7 @@ void __init init_IRQ(void) /* SIO0_R : uart receive data */ irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED; irq_desc[M32R_IRQ_SIO0_R].chip = &mappi_irq_type; - irq_desc[M32R_IRQ_SIO0_R].action = NULL; + irq_desc[M32R_IRQ_SIO0_R].action = 0; irq_desc[M32R_IRQ_SIO0_R].depth = 1; icu_data[M32R_IRQ_SIO0_R].icucr = 0; disable_mappi_irq(M32R_IRQ_SIO0_R); @@ -112,7 +112,7 @@ void __init init_IRQ(void) /* SIO0_S : uart send data */ irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED; irq_desc[M32R_IRQ_SIO0_S].chip = &mappi_irq_type; - irq_desc[M32R_IRQ_SIO0_S].action = NULL; + irq_desc[M32R_IRQ_SIO0_S].action = 0; irq_desc[M32R_IRQ_SIO0_S].depth = 1; icu_data[M32R_IRQ_SIO0_S].icucr = 0; disable_mappi_irq(M32R_IRQ_SIO0_S); @@ -120,7 +120,7 @@ void __init init_IRQ(void) /* SIO1_R : uart receive data */ irq_desc[M32R_IRQ_SIO1_R].status = IRQ_DISABLED; irq_desc[M32R_IRQ_SIO1_R].chip = &mappi_irq_type; - irq_desc[M32R_IRQ_SIO1_R].action = NULL; + irq_desc[M32R_IRQ_SIO1_R].action = 0; irq_desc[M32R_IRQ_SIO1_R].depth = 1; icu_data[M32R_IRQ_SIO1_R].icucr = 0; disable_mappi_irq(M32R_IRQ_SIO1_R); @@ -128,7 +128,7 @@ void __init init_IRQ(void) /* SIO1_S : uart send data */ irq_desc[M32R_IRQ_SIO1_S].status = IRQ_DISABLED; irq_desc[M32R_IRQ_SIO1_S].chip = &mappi_irq_type; - irq_desc[M32R_IRQ_SIO1_S].action = NULL; + irq_desc[M32R_IRQ_SIO1_S].action = 0; irq_desc[M32R_IRQ_SIO1_S].depth = 1; icu_data[M32R_IRQ_SIO1_S].icucr = 0; disable_mappi_irq(M32R_IRQ_SIO1_S); @@ -138,7 +138,7 @@ void __init init_IRQ(void) /* INT1 : pccard0 interrupt */ irq_desc[M32R_IRQ_INT1].status = IRQ_DISABLED; irq_desc[M32R_IRQ_INT1].chip = &mappi_irq_type; - irq_desc[M32R_IRQ_INT1].action = NULL; + irq_desc[M32R_IRQ_INT1].action = 0; irq_desc[M32R_IRQ_INT1].depth = 1; icu_data[M32R_IRQ_INT1].icucr = M32R_ICUCR_IEN | M32R_ICUCR_ISMOD00; disable_mappi_irq(M32R_IRQ_INT1); @@ -146,7 +146,7 @@ void __init init_IRQ(void) /* INT2 : pccard1 interrupt */ irq_desc[M32R_IRQ_INT2].status = IRQ_DISABLED; irq_desc[M32R_IRQ_INT2].chip = &mappi_irq_type; - irq_desc[M32R_IRQ_INT2].action = NULL; + irq_desc[M32R_IRQ_INT2].action = 0; irq_desc[M32R_IRQ_INT2].depth = 1; icu_data[M32R_IRQ_INT2].icucr = M32R_ICUCR_IEN | M32R_ICUCR_ISMOD00; disable_mappi_irq(M32R_IRQ_INT2); diff --git a/trunk/arch/m32r/kernel/signal.c b/trunk/arch/m32r/kernel/signal.c index b60cea4aebaa..a9174efe80cb 100644 --- a/trunk/arch/m32r/kernel/signal.c +++ b/trunk/arch/m32r/kernel/signal.c @@ -33,7 +33,7 @@ int do_signal(struct pt_regs *, sigset_t *); asmlinkage int -sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, +sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, unsigned long r2, unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, struct pt_regs *regs) { @@ -78,8 +78,8 @@ sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, struct rt_sigframe { int sig; - struct siginfo __user *pinfo; - void __user *puc; + struct siginfo *pinfo; + void *puc; struct siginfo info; struct ucontext uc; // struct _fpstate fpstate; diff --git a/trunk/arch/m32r/kernel/smp.c b/trunk/arch/m32r/kernel/smp.c index 360129174b2b..8b1f6eb76870 100644 --- a/trunk/arch/m32r/kernel/smp.c +++ b/trunk/arch/m32r/kernel/smp.c @@ -101,7 +101,7 @@ void smp_call_function_interrupt(void); void smp_send_timer(void); void smp_ipi_timer_interrupt(struct pt_regs *); -void smp_local_timer_interrupt(void); +void smp_local_timer_interrupt(struct pt_regs *); void send_IPI_allbutself(int, int); static void send_IPI_mask(cpumask_t, int, int); @@ -231,7 +231,7 @@ void smp_flush_tlb_all(void) local_irq_save(flags); __flush_tlb_all(); local_irq_restore(flags); - smp_call_function(flush_tlb_all_ipi, NULL, 1, 1); + smp_call_function(flush_tlb_all_ipi, 0, 1, 1); preempt_enable(); } @@ -734,12 +734,9 @@ void smp_send_timer(void) *==========================================================================*/ void smp_ipi_timer_interrupt(struct pt_regs *regs) { - struct pt_regs *old_regs; - old_regs = set_irq_regs(regs); irq_enter(); - smp_local_timer_interrupt(); + smp_local_timer_interrupt(regs); irq_exit(); - set_irq_regs(old_regs); } /*==========================================================================* @@ -765,9 +762,9 @@ void smp_ipi_timer_interrupt(struct pt_regs *regs) * ---------- --- -------------------------------------------------------- * 2003-06-24 hy use per_cpu structure. *==========================================================================*/ -void smp_local_timer_interrupt(void) +void smp_local_timer_interrupt(struct pt_regs *regs) { - int user = user_mode(get_irq_regs()); + int user = user_mode(regs); int cpu_id = smp_processor_id(); /* @@ -777,7 +774,7 @@ void smp_local_timer_interrupt(void) * useful with a profiling multiplier != 1 */ - profile_tick(CPU_PROFILING); + profile_tick(CPU_PROFILING, regs); if (--per_cpu(prof_counter, cpu_id) <= 0) { /* diff --git a/trunk/arch/m32r/kernel/sys_m32r.c b/trunk/arch/m32r/kernel/sys_m32r.c index b4e7bcb43540..b567351f3c52 100644 --- a/trunk/arch/m32r/kernel/sys_m32r.c +++ b/trunk/arch/m32r/kernel/sys_m32r.c @@ -31,7 +31,7 @@ /* * sys_tas() - test-and-set */ -asmlinkage int sys_tas(int __user *addr) +asmlinkage int sys_tas(int *addr) { int oldval; @@ -90,7 +90,7 @@ sys_pipe(unsigned long r0, unsigned long r1, unsigned long r2, error = do_pipe(fd); if (!error) { - if (copy_to_user((void __user *)r0, fd, 2*sizeof(int))) + if (copy_to_user((void *)r0, (void *)fd, 2*sizeof(int))) error = -EFAULT; } return error; @@ -201,7 +201,7 @@ asmlinkage int sys_ipc(uint call, int first, int second, } } -asmlinkage int sys_uname(struct old_utsname __user * name) +asmlinkage int sys_uname(struct old_utsname * name) { int err; if (!name) diff --git a/trunk/arch/m32r/kernel/time.c b/trunk/arch/m32r/kernel/time.c index a09038282c78..d8af155db984 100644 --- a/trunk/arch/m32r/kernel/time.c +++ b/trunk/arch/m32r/kernel/time.c @@ -35,7 +35,7 @@ #ifdef CONFIG_SMP extern void send_IPI_allbutself(int, int); -extern void smp_local_timer_interrupt(void); +extern void smp_local_timer_interrupt(struct pt_regs *); #endif #define TICK_SIZE (tick_nsec / 1000) @@ -188,15 +188,15 @@ static long last_rtc_update = 0; * timer_interrupt() needs to keep up the real-time clock, * as well as call the "do_timer()" routine every clocktick */ -irqreturn_t timer_interrupt(int irq, void *dev_id) +irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { #ifndef CONFIG_SMP - profile_tick(CPU_PROFILING); + profile_tick(CPU_PROFILING, regs); #endif do_timer(1); #ifndef CONFIG_SMP - update_process_times(user_mode(get_irq_regs())); + update_process_times(user_mode(regs)); #endif /* * If we have an externally synchronized Linux clock, then update @@ -221,7 +221,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id) a hack, so don't look closely for now.. */ #ifdef CONFIG_SMP - smp_local_timer_interrupt(); + smp_local_timer_interrupt(regs); smp_send_timer(); #endif diff --git a/trunk/arch/m32r/kernel/traps.c b/trunk/arch/m32r/kernel/traps.c index 97e0b1c0830e..c1daf2c40c7c 100644 --- a/trunk/arch/m32r/kernel/traps.c +++ b/trunk/arch/m32r/kernel/traps.c @@ -268,7 +268,7 @@ static __inline__ void do_trap(int trapnr, int signr, const char * str, #define DO_ERROR(trapnr, signr, str, name) \ asmlinkage void do_##name(struct pt_regs * regs, long error_code) \ { \ - do_trap(trapnr, signr, NULL, regs, error_code, NULL); \ + do_trap(trapnr, signr, 0, regs, error_code, NULL); \ } #define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \ diff --git a/trunk/arch/m32r/kernel/vmlinux.lds.S b/trunk/arch/m32r/kernel/vmlinux.lds.S index 358b9cee2c65..13c7bb698e37 100644 --- a/trunk/arch/m32r/kernel/vmlinux.lds.S +++ b/trunk/arch/m32r/kernel/vmlinux.lds.S @@ -83,7 +83,13 @@ SECTIONS __setup_end = .; __initcall_start = .; .initcall.init : { - INITCALLS + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) } __initcall_end = .; __con_initcall_start = .; diff --git a/trunk/arch/m68k/Kconfig b/trunk/arch/m68k/Kconfig index 7bc14461a6ac..805b81fedf80 100644 --- a/trunk/arch/m68k/Kconfig +++ b/trunk/arch/m68k/Kconfig @@ -600,7 +600,7 @@ config MVME147_SCC config SERIAL167 bool "CD2401 support for MVME166/7 serial ports" - depends on MVME16x + depends on MVME16x && BROKEN help This is the driver for the serial ports on the Motorola MVME166, 167, and 172 boards. Everyone using one of these boards should say diff --git a/trunk/arch/m68k/amiga/amiints.c b/trunk/arch/m68k/amiga/amiints.c index 28d95cfe8ac0..96c79d840cff 100644 --- a/trunk/arch/m68k/amiga/amiints.c +++ b/trunk/arch/m68k/amiga/amiints.c @@ -47,10 +47,10 @@ static void amiga_enable_irq(unsigned int irq); static void amiga_disable_irq(unsigned int irq); -static irqreturn_t ami_int1(int irq, void *dev_id); -static irqreturn_t ami_int3(int irq, void *dev_id); -static irqreturn_t ami_int4(int irq, void *dev_id); -static irqreturn_t ami_int5(int irq, void *dev_id); +static irqreturn_t ami_int1(int irq, void *dev_id, struct pt_regs *fp); +static irqreturn_t ami_int3(int irq, void *dev_id, struct pt_regs *fp); +static irqreturn_t ami_int4(int irq, void *dev_id, struct pt_regs *fp); +static irqreturn_t ami_int5(int irq, void *dev_id, struct pt_regs *fp); static struct irq_controller amiga_irq_controller = { .name = "amiga", @@ -113,98 +113,98 @@ static void amiga_disable_irq(unsigned int irq) * The builtin Amiga hardware interrupt handlers. */ -static irqreturn_t ami_int1(int irq, void *dev_id) +static irqreturn_t ami_int1(int irq, void *dev_id, struct pt_regs *fp) { unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; /* if serial transmit buffer empty, interrupt */ if (ints & IF_TBE) { amiga_custom.intreq = IF_TBE; - m68k_handle_int(IRQ_AMIGA_TBE); + m68k_handle_int(IRQ_AMIGA_TBE, fp); } /* if floppy disk transfer complete, interrupt */ if (ints & IF_DSKBLK) { amiga_custom.intreq = IF_DSKBLK; - m68k_handle_int(IRQ_AMIGA_DSKBLK); + m68k_handle_int(IRQ_AMIGA_DSKBLK, fp); } /* if software interrupt set, interrupt */ if (ints & IF_SOFT) { amiga_custom.intreq = IF_SOFT; - m68k_handle_int(IRQ_AMIGA_SOFT); + m68k_handle_int(IRQ_AMIGA_SOFT, fp); } return IRQ_HANDLED; } -static irqreturn_t ami_int3(int irq, void *dev_id) +static irqreturn_t ami_int3(int irq, void *dev_id, struct pt_regs *fp) { unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; /* if a blitter interrupt */ if (ints & IF_BLIT) { amiga_custom.intreq = IF_BLIT; - m68k_handle_int(IRQ_AMIGA_BLIT); + m68k_handle_int(IRQ_AMIGA_BLIT, fp); } /* if a copper interrupt */ if (ints & IF_COPER) { amiga_custom.intreq = IF_COPER; - m68k_handle_int(IRQ_AMIGA_COPPER); + m68k_handle_int(IRQ_AMIGA_COPPER, fp); } /* if a vertical blank interrupt */ if (ints & IF_VERTB) { amiga_custom.intreq = IF_VERTB; - m68k_handle_int(IRQ_AMIGA_VERTB); + m68k_handle_int(IRQ_AMIGA_VERTB, fp); } return IRQ_HANDLED; } -static irqreturn_t ami_int4(int irq, void *dev_id) +static irqreturn_t ami_int4(int irq, void *dev_id, struct pt_regs *fp) { unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; /* if audio 0 interrupt */ if (ints & IF_AUD0) { amiga_custom.intreq = IF_AUD0; - m68k_handle_int(IRQ_AMIGA_AUD0); + m68k_handle_int(IRQ_AMIGA_AUD0, fp); } /* if audio 1 interrupt */ if (ints & IF_AUD1) { amiga_custom.intreq = IF_AUD1; - m68k_handle_int(IRQ_AMIGA_AUD1); + m68k_handle_int(IRQ_AMIGA_AUD1, fp); } /* if audio 2 interrupt */ if (ints & IF_AUD2) { amiga_custom.intreq = IF_AUD2; - m68k_handle_int(IRQ_AMIGA_AUD2); + m68k_handle_int(IRQ_AMIGA_AUD2, fp); } /* if audio 3 interrupt */ if (ints & IF_AUD3) { amiga_custom.intreq = IF_AUD3; - m68k_handle_int(IRQ_AMIGA_AUD3); + m68k_handle_int(IRQ_AMIGA_AUD3, fp); } return IRQ_HANDLED; } -static irqreturn_t ami_int5(int irq, void *dev_id) +static irqreturn_t ami_int5(int irq, void *dev_id, struct pt_regs *fp) { unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; /* if serial receive buffer full interrupt */ if (ints & IF_RBF) { /* acknowledge of IF_RBF must be done by the serial interrupt */ - m68k_handle_int(IRQ_AMIGA_RBF); + m68k_handle_int(IRQ_AMIGA_RBF, fp); } /* if a disk sync interrupt */ if (ints & IF_DSKSYN) { amiga_custom.intreq = IF_DSKSYN; - m68k_handle_int(IRQ_AMIGA_DSKSYN); + m68k_handle_int(IRQ_AMIGA_DSKSYN, fp); } return IRQ_HANDLED; } diff --git a/trunk/arch/m68k/amiga/cia.c b/trunk/arch/m68k/amiga/cia.c index 7a20058eb380..dbad30054721 100644 --- a/trunk/arch/m68k/amiga/cia.c +++ b/trunk/arch/m68k/amiga/cia.c @@ -82,7 +82,7 @@ unsigned char cia_able_irq(struct ciabase *base, unsigned char mask) return old; } -static irqreturn_t cia_handler(int irq, void *dev_id) +static irqreturn_t cia_handler(int irq, void *dev_id, struct pt_regs *fp) { struct ciabase *base = (struct ciabase *)dev_id; int mach_irq; @@ -93,7 +93,7 @@ static irqreturn_t cia_handler(int irq, void *dev_id) amiga_custom.intreq = base->int_mask; for (; ints; mach_irq++, ints >>= 1) { if (ints & 1) - m68k_handle_int(mach_irq); + m68k_handle_int(mach_irq, fp); } return IRQ_HANDLED; } diff --git a/trunk/arch/m68k/amiga/config.c b/trunk/arch/m68k/amiga/config.c index 3204f412cad8..092e50d2cb13 100644 --- a/trunk/arch/m68k/amiga/config.c +++ b/trunk/arch/m68k/amiga/config.c @@ -83,7 +83,7 @@ static char amiga_model_name[13] = "Amiga "; extern char m68k_debug_device[]; -static void amiga_sched_init(irq_handler_t handler); +static void amiga_sched_init(irqreturn_t (*handler)(int, void *, struct pt_regs *)); /* amiga specific irq functions */ extern void amiga_init_IRQ (void); static void amiga_get_model(char *model); @@ -487,7 +487,8 @@ void __init config_amiga(void) static unsigned short jiffy_ticks; -static void __init amiga_sched_init(irq_handler_t timer_routine) +static void __init amiga_sched_init(irqreturn_t (*timer_routine)(int, void *, + struct pt_regs *)) { static struct resource sched_res = { .name = "timer", .start = 0x00bfd400, .end = 0x00bfd5ff, diff --git a/trunk/arch/m68k/apollo/config.c b/trunk/arch/m68k/apollo/config.c index cb8e7609df4c..6f4581575fb4 100644 --- a/trunk/arch/m68k/apollo/config.c +++ b/trunk/arch/m68k/apollo/config.c @@ -25,7 +25,7 @@ u_long cpuctrl_physaddr; u_long timer_physaddr; u_long apollo_model; -extern void dn_sched_init(irq_handler_t handler); +extern void dn_sched_init(irqreturn_t (*handler)(int,void *,struct pt_regs *)); extern void dn_init_IRQ(void); extern unsigned long dn_gettimeoffset(void); extern int dn_dummy_hwclk(int, struct rtc_time *); @@ -38,7 +38,7 @@ extern irqreturn_t dn_process_int(int irq, struct pt_regs *fp); #ifdef CONFIG_HEARTBEAT static void dn_heartbeat(int on); #endif -static irqreturn_t dn_timer_int(int irq,void *); +static irqreturn_t dn_timer_int(int irq,void *, struct pt_regs *); static void dn_get_model(char *model); static const char *apollo_models[] = { [APOLLO_DN3000-APOLLO_DN3000] = "DN3000 (Otter)", @@ -174,13 +174,13 @@ void config_apollo(void) { } -irqreturn_t dn_timer_int(int irq, void *dev_id) +irqreturn_t dn_timer_int(int irq, void *dev_id, struct pt_regs *fp) { - irq_handler_t timer_handler = dev_id; + irqreturn_t (*timer_handler)(int, void *, struct pt_regs *) = dev_id; volatile unsigned char x; - timer_handler(irq, dev_id); + timer_handler(irq, dev_id, fp); x=*(volatile unsigned char *)(timer+3); x=*(volatile unsigned char *)(timer+5); @@ -188,8 +188,8 @@ irqreturn_t dn_timer_int(int irq, void *dev_id) return IRQ_HANDLED; } -void dn_sched_init(irq_handler_t timer_routine) -{ +void dn_sched_init(irqreturn_t (*timer_routine)(int, void *, struct pt_regs *)) { + /* program timer 1 */ *(volatile unsigned char *)(timer+3)=0x01; *(volatile unsigned char *)(timer+1)=0x40; diff --git a/trunk/arch/m68k/apollo/dma.c b/trunk/arch/m68k/apollo/dma.c new file mode 100644 index 000000000000..aed8be177ef1 --- /dev/null +++ b/trunk/arch/m68k/apollo/dma.c @@ -0,0 +1,50 @@ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +/* note only works for 16 Bit 1 page DMA's */ + +static unsigned short next_free_xlat_entry=0; + +unsigned short dma_map_page(unsigned long phys_addr,int count,int type) { + + unsigned long page_aligned_addr=phys_addr & (~((1<<12)-1)); + unsigned short start_map_addr=page_aligned_addr >> 10; + unsigned short free_xlat_entry, *xlat_map_entry; + int i; + + free_xlat_entry=next_free_xlat_entry; + for(i=0,xlat_map_entry=addr_xlat_map+(free_xlat_entry<<2);i<8;i++,xlat_map_entry++) { +#if 0 + printk("phys_addr: %x, page_aligned_addr: %x, start_map_addr: %x\n",phys_addr,page_aligned_addr,start_map_addr+i); +#endif + out_be16(xlat_map_entry, start_map_addr+i); + } + + next_free_xlat_entry+=2; + if(next_free_xlat_entry>125) + next_free_xlat_entry=0; + +#if 0 + printk("next_free_xlat_entry: %d\n",next_free_xlat_entry); +#endif + + return free_xlat_entry<<10; +} + +void dma_unmap_page(unsigned short dma_addr) { + + return ; + +} + diff --git a/trunk/arch/m68k/apollo/dn_ints.c b/trunk/arch/m68k/apollo/dn_ints.c index 4274af125998..9fe07803797b 100644 --- a/trunk/arch/m68k/apollo/dn_ints.c +++ b/trunk/arch/m68k/apollo/dn_ints.c @@ -6,7 +6,7 @@ void dn_process_int(unsigned int irq, struct pt_regs *fp) { - __m68k_handle_int(irq, fp); + m68k_handle_int(irq, fp); *(volatile unsigned char *)(pica)=0x20; *(volatile unsigned char *)(picb)=0x20; diff --git a/trunk/arch/m68k/atari/ataints.c b/trunk/arch/m68k/atari/ataints.c index 7f812641790c..ece13cbf9950 100644 --- a/trunk/arch/m68k/atari/ataints.c +++ b/trunk/arch/m68k/atari/ataints.c @@ -332,9 +332,6 @@ static void atari_shutdown_irq(unsigned int irq) atari_disable_irq(irq); atari_turnoff_irq(irq); m68k_irq_shutdown(irq); - - if (irq == IRQ_AUTO_4) - vectors[VEC_INT4] = falcon_hblhandler; } static struct irq_controller atari_irq_controller = { @@ -359,7 +356,7 @@ static struct irq_controller atari_irq_controller = { void __init atari_init_IRQ(void) { - m68k_setup_user_interrupt(VEC_USER, NUM_ATARI_SOURCES - IRQ_USER, NULL); + m68k_setup_user_interrupt(VEC_USER, 192, NULL); m68k_setup_irq_controller(&atari_irq_controller, 1, NUM_ATARI_SOURCES - 1); /* Initialize the MFP(s) */ @@ -406,10 +403,8 @@ void __init atari_init_IRQ(void) * gets overruns) */ - if (!MACH_IS_HADES) { + if (!MACH_IS_HADES) vectors[VEC_INT2] = falcon_hblhandler; - vectors[VEC_INT4] = falcon_hblhandler; - } } if (ATARIHW_PRESENT(PCM_8BIT) && ATARIHW_PRESENT(MICROWIRE)) { diff --git a/trunk/arch/m68k/atari/config.c b/trunk/arch/m68k/atari/config.c index ca5cd4344e3d..b2079252a954 100644 --- a/trunk/arch/m68k/atari/config.c +++ b/trunk/arch/m68k/atari/config.c @@ -62,7 +62,7 @@ static void atari_heartbeat( int on ); #endif /* atari specific timer functions (in time.c) */ -extern void atari_sched_init(irq_handler_t ); +extern void atari_sched_init(irqreturn_t (*)(int, void *, struct pt_regs *)); extern unsigned long atari_gettimeoffset (void); extern int atari_mste_hwclk (int, struct rtc_time *); extern int atari_tt_hwclk (int, struct rtc_time *); diff --git a/trunk/arch/m68k/atari/stdma.c b/trunk/arch/m68k/atari/stdma.c index d64b5804e980..288f5e6a124e 100644 --- a/trunk/arch/m68k/atari/stdma.c +++ b/trunk/arch/m68k/atari/stdma.c @@ -44,7 +44,7 @@ static int stdma_locked; /* the semaphore */ /* int func to be called */ -static irq_handler_t stdma_isr; +static irqreturn_t (*stdma_isr)(int, void *, struct pt_regs *); static void *stdma_isr_data; /* data passed to isr */ static DECLARE_WAIT_QUEUE_HEAD(stdma_wait); /* wait queue for ST-DMA */ @@ -53,7 +53,7 @@ static DECLARE_WAIT_QUEUE_HEAD(stdma_wait); /* wait queue for ST-DMA */ /***************************** Prototypes *****************************/ -static irqreturn_t stdma_int (int irq, void *dummy); +static irqreturn_t stdma_int (int irq, void *dummy, struct pt_regs *fp); /************************* End of Prototypes **************************/ @@ -75,7 +75,8 @@ static irqreturn_t stdma_int (int irq, void *dummy); * */ -void stdma_lock(irq_handler_t handler, void *data) +void stdma_lock(irqreturn_t (*handler)(int, void *, struct pt_regs *), + void *data) { unsigned long flags; @@ -187,9 +188,9 @@ void __init stdma_init(void) * */ -static irqreturn_t stdma_int(int irq, void *dummy) +static irqreturn_t stdma_int(int irq, void *dummy, struct pt_regs *fp) { if (stdma_isr) - (*stdma_isr)(irq, stdma_isr_data); + (*stdma_isr)(irq, stdma_isr_data, fp); return IRQ_HANDLED; } diff --git a/trunk/arch/m68k/atari/time.c b/trunk/arch/m68k/atari/time.c index e0d3c8bfb408..e79bbc94216d 100644 --- a/trunk/arch/m68k/atari/time.c +++ b/trunk/arch/m68k/atari/time.c @@ -16,12 +16,11 @@ #include #include #include -#include #include void __init -atari_sched_init(irq_handler_t timer_routine) +atari_sched_init(irqreturn_t (*timer_routine)(int, void *, struct pt_regs *)) { /* set Timer C data Register */ mfp.tim_dt_c = INT_TICKS; @@ -213,12 +212,8 @@ int atari_tt_hwclk( int op, struct rtc_time *t ) * additionally the RTC_SET bit is set to prevent an update cycle. */ - while( RTC_READ(RTC_FREQ_SELECT) & RTC_UIP ) { - if (in_atomic() || irqs_disabled()) - mdelay(1); - else - schedule_timeout_interruptible(HWCLK_POLL_INTERVAL); - } + while( RTC_READ(RTC_FREQ_SELECT) & RTC_UIP ) + schedule_timeout_interruptible(HWCLK_POLL_INTERVAL); local_irq_save(flags); RTC_WRITE( RTC_CONTROL, ctrl | RTC_SET ); diff --git a/trunk/arch/m68k/bvme6000/config.c b/trunk/arch/m68k/bvme6000/config.c index 896ae3d3d919..d1e916ae55a8 100644 --- a/trunk/arch/m68k/bvme6000/config.c +++ b/trunk/arch/m68k/bvme6000/config.c @@ -38,7 +38,7 @@ static void bvme6000_get_model(char *model); static int bvme6000_get_hardware_list(char *buffer); -extern void bvme6000_sched_init(irq_handler_t handler); +extern void bvme6000_sched_init(irqreturn_t (*handler)(int, void *, struct pt_regs *)); extern unsigned long bvme6000_gettimeoffset (void); extern int bvme6000_hwclk (int, struct rtc_time *); extern int bvme6000_set_clock_mmss (unsigned long); @@ -52,7 +52,7 @@ static unsigned char bin2bcd (unsigned char b); /* Save tick handler routine pointer, will point to do_timer() in * kernel/sched.c, called via bvme6000_process_int() */ -static irq_handler_t tick_handler; +static irqreturn_t (*tick_handler)(int, void *, struct pt_regs *); int bvme6000_parse_bootinfo(const struct bi_record *bi) @@ -154,7 +154,7 @@ void __init config_bvme6000(void) } -irqreturn_t bvme6000_abort_int (int irq, void *dev_id) +irqreturn_t bvme6000_abort_int (int irq, void *dev_id, struct pt_regs *fp) { unsigned long *new = (unsigned long *)vectors; unsigned long *old = (unsigned long *)0xf8000000; @@ -171,14 +171,14 @@ irqreturn_t bvme6000_abort_int (int irq, void *dev_id) } -static irqreturn_t bvme6000_timer_int (int irq, void *dev_id) +static irqreturn_t bvme6000_timer_int (int irq, void *dev_id, struct pt_regs *fp) { volatile RtcPtr_t rtc = (RtcPtr_t)BVME_RTC_BASE; unsigned char msr = rtc->msr & 0xc0; rtc->msr = msr | 0x20; /* Ack the interrupt */ - return tick_handler(irq, dev_id); + return tick_handler(irq, dev_id, fp); } /* @@ -190,7 +190,7 @@ static irqreturn_t bvme6000_timer_int (int irq, void *dev_id) * so divide by 8 to get the microsecond result. */ -void bvme6000_sched_init (irq_handler_t timer_routine) +void bvme6000_sched_init (irqreturn_t (*timer_routine)(int, void *, struct pt_regs *)) { volatile RtcPtr_t rtc = (RtcPtr_t)BVME_RTC_BASE; unsigned char msr = rtc->msr & 0xc0; diff --git a/trunk/arch/m68k/hp300/time.c b/trunk/arch/m68k/hp300/time.c index dd7c8a2583d3..7df05662b277 100644 --- a/trunk/arch/m68k/hp300/time.c +++ b/trunk/arch/m68k/hp300/time.c @@ -36,15 +36,15 @@ #define INTVAL ((10000 / 4) - 1) -static irqreturn_t hp300_tick(int irq, void *dev_id) +static irqreturn_t hp300_tick(int irq, void *dev_id, struct pt_regs *regs) { unsigned long tmp; - irq_handler_t vector = dev_id; + irqreturn_t (*vector)(int, void *, struct pt_regs *) = dev_id; in_8(CLOCKBASE + CLKSR); asm volatile ("movpw %1@(5),%0" : "=d" (tmp) : "a" (CLOCKBASE)); /* Turn off the network and SCSI leds */ blinken_leds(0, 0xe0); - return vector(irq, NULL); + return vector(irq, NULL, regs); } unsigned long hp300_gettimeoffset(void) @@ -63,7 +63,7 @@ unsigned long hp300_gettimeoffset(void) return (USECS_PER_JIFFY * ticks) / INTVAL; } -void __init hp300_sched_init(irq_handler_t vector) +void __init hp300_sched_init(irqreturn_t (*vector)(int, void *, struct pt_regs *)) { out_8(CLOCKBASE + CLKCR2, 0x1); /* select CR1 */ out_8(CLOCKBASE + CLKCR1, 0x1); /* reset */ diff --git a/trunk/arch/m68k/hp300/time.h b/trunk/arch/m68k/hp300/time.h index f5b3d098b0f5..8ef9987b49ab 100644 --- a/trunk/arch/m68k/hp300/time.h +++ b/trunk/arch/m68k/hp300/time.h @@ -1,4 +1,4 @@ -extern void hp300_sched_init(irq_handler_t vector); +extern void hp300_sched_init(irqreturn_t (*vector)(int, void *, struct pt_regs *)); extern unsigned long hp300_gettimeoffset (void); diff --git a/trunk/arch/m68k/kernel/Makefile b/trunk/arch/m68k/kernel/Makefile index 1c9ecaa473d5..dae609797dc0 100644 --- a/trunk/arch/m68k/kernel/Makefile +++ b/trunk/arch/m68k/kernel/Makefile @@ -9,11 +9,10 @@ else endif extra-y += vmlinux.lds -obj-y := entry.o process.o traps.o ints.o signal.o ptrace.o \ +obj-y := entry.o process.o traps.o ints.o dma.o signal.o ptrace.o \ sys_m68k.o time.o semaphore.o setup.o m68k_ksyms.o obj-$(CONFIG_PCI) += bios32.o obj-$(CONFIG_MODULES) += module.o -obj-y$(CONFIG_MMU_SUN3) += dma.o # no, it's not a typo EXTRA_AFLAGS := -traditional diff --git a/trunk/arch/m68k/kernel/dma.c b/trunk/arch/m68k/kernel/dma.c index 9d4e4b5b6bd8..fc449f8b2045 100644 --- a/trunk/arch/m68k/kernel/dma.c +++ b/trunk/arch/m68k/kernel/dma.c @@ -15,7 +15,7 @@ #include void *dma_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *handle, gfp_t flag) + dma_addr_t *handle, int flag) { struct page *page, **map; pgprot_t pgprot; @@ -51,7 +51,7 @@ void *dma_alloc_coherent(struct device *dev, size_t size, pgprot_val(pgprot) |= _PAGE_GLOBAL040 | _PAGE_NOCACHE_S; else pgprot_val(pgprot) |= _PAGE_NOCACHE030; - addr = vmap(map, size, VM_MAP, pgprot); + addr = vmap(map, size, flag, pgprot); kfree(map); return addr; diff --git a/trunk/arch/m68k/kernel/entry.S b/trunk/arch/m68k/kernel/entry.S index 222ce4244564..9083c8b7659f 100644 --- a/trunk/arch/m68k/kernel/entry.S +++ b/trunk/arch/m68k/kernel/entry.S @@ -205,7 +205,7 @@ ENTRY(auto_inthandler) movel %sp,%sp@- movel %d0,%sp@- | put vector # on stack auto_irqhandler_fixup = . + 2 - jsr __m68k_handle_int | process the IRQ + jsr m68k_handle_int | process the IRQ addql #8,%sp | pop parameters off stack ret_from_interrupt: @@ -239,7 +239,7 @@ user_irqvec_fixup = . + 2 movel %sp,%sp@- movel %d0,%sp@- | put vector # on stack user_irqhandler_fixup = . + 2 - jsr __m68k_handle_int | process the IRQ + jsr m68k_handle_int | process the IRQ addql #8,%sp | pop parameters off stack subqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) @@ -706,33 +706,4 @@ sys_call_table: .long sys_add_key .long sys_request_key /* 280 */ .long sys_keyctl - .long sys_ioprio_set - .long sys_ioprio_get - .long sys_inotify_init - .long sys_inotify_add_watch /* 285 */ - .long sys_inotify_rm_watch - .long sys_migrate_pages - .long sys_openat - .long sys_mkdirat - .long sys_mknodat /* 290 */ - .long sys_fchownat - .long sys_futimesat - .long sys_fstatat64 - .long sys_unlinkat - .long sys_renameat /* 295 */ - .long sys_linkat - .long sys_symlinkat - .long sys_readlinkat - .long sys_fchmodat - .long sys_faccessat /* 300 */ - .long sys_ni_syscall /* Reserved for pselect6 */ - .long sys_ni_syscall /* Reserved for ppoll */ - .long sys_unshare - .long sys_set_robust_list - .long sys_get_robust_list /* 305 */ - .long sys_splice - .long sys_sync_file_range - .long sys_tee - .long sys_vmsplice - .long sys_move_pages /* 310 */ diff --git a/trunk/arch/m68k/kernel/ints.c b/trunk/arch/m68k/kernel/ints.c index 84aceca6c05c..b33e37fb7b0e 100644 --- a/trunk/arch/m68k/kernel/ints.c +++ b/trunk/arch/m68k/kernel/ints.c @@ -39,7 +39,6 @@ #include #include #include -#include #ifdef CONFIG_Q40 #include @@ -105,7 +104,7 @@ void __init init_IRQ(void) * @handler: called from auto vector interrupts * * setup the handler to be called from auto vector interrupts instead of the - * standard __m68k_handle_int(), it will be called with irq numbers in the range + * standard m68k_handle_int(), it will be called with irq numbers in the range * from IRQ_AUTO_1 - IRQ_AUTO_7. */ void __init m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_regs *)) @@ -124,7 +123,7 @@ void __init m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_re * setup user vector interrupts, this includes activating the specified range * of interrupts, only then these interrupts can be requested (note: this is * different from auto vector interrupts). An optional handler can be installed - * to be called instead of the default __m68k_handle_int(), it will be called + * to be called instead of the default m68k_handle_int(), it will be called * with irq numbers starting from IRQ_USER. */ void __init m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt, @@ -132,7 +131,6 @@ void __init m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt, { int i; - BUG_ON(IRQ_USER + cnt >= NR_IRQS); m68k_first_user_vec = vec; for (i = 0; i < cnt; i++) irq_controller[IRQ_USER + i] = &user_irq_controller; @@ -217,7 +215,7 @@ int setup_irq(unsigned int irq, struct irq_node *node) } int request_irq(unsigned int irq, - irq_handler_t handler, + irqreturn_t (*handler) (int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id) { struct irq_node *node; @@ -381,25 +379,18 @@ unsigned int irq_canonicalize(unsigned int irq) EXPORT_SYMBOL(irq_canonicalize); -asmlinkage void m68k_handle_int(unsigned int irq) +asmlinkage void m68k_handle_int(unsigned int irq, struct pt_regs *regs) { struct irq_node *node; + kstat_cpu(0).irqs[irq]++; node = irq_list[irq]; do { - node->handler(irq, node->dev_id); + node->handler(irq, node->dev_id, regs); node = node->next; } while (node); } -asmlinkage void __m68k_handle_int(unsigned int irq, struct pt_regs *regs) -{ - struct pt_regs *old_regs; - old_regs = set_irq_regs(regs); - m68k_handle_int(irq); - set_irq_regs(old_regs); -} - asmlinkage void handle_badint(struct pt_regs *regs) { kstat_cpu(0).irqs[0]++; diff --git a/trunk/arch/m68k/kernel/m68k_ksyms.c b/trunk/arch/m68k/kernel/m68k_ksyms.c index 6fc69c74fe2e..aff26a52167c 100644 --- a/trunk/arch/m68k/kernel/m68k_ksyms.c +++ b/trunk/arch/m68k/kernel/m68k_ksyms.c @@ -1,10 +1,65 @@ #include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include #include +#include asmlinkage long long __ashldi3 (long long, int); asmlinkage long long __ashrdi3 (long long, int); asmlinkage long long __lshrdi3 (long long, int); asmlinkage long long __muldi3 (long long, long long); +extern char m68k_debug_device[]; + +/* platform dependent support */ + +EXPORT_SYMBOL(m68k_machtype); +EXPORT_SYMBOL(m68k_cputype); +EXPORT_SYMBOL(m68k_is040or060); +EXPORT_SYMBOL(m68k_realnum_memory); +EXPORT_SYMBOL(m68k_memory); +#ifndef CONFIG_SUN3 +EXPORT_SYMBOL(cache_push); +EXPORT_SYMBOL(cache_clear); +#ifndef CONFIG_SINGLE_MEMORY_CHUNK +EXPORT_SYMBOL(mm_vtop); +EXPORT_SYMBOL(mm_ptov); +EXPORT_SYMBOL(mm_end_of_chunk); +#else +EXPORT_SYMBOL(m68k_memoffset); +#endif /* !CONFIG_SINGLE_MEMORY_CHUNK */ +EXPORT_SYMBOL(__ioremap); +EXPORT_SYMBOL(iounmap); +EXPORT_SYMBOL(kernel_set_cachemode); +#endif /* !CONFIG_SUN3 */ +EXPORT_SYMBOL(m68k_debug_device); +EXPORT_SYMBOL(mach_hwclk); +EXPORT_SYMBOL(mach_get_ss); +EXPORT_SYMBOL(mach_get_rtc_pll); +EXPORT_SYMBOL(mach_set_rtc_pll); +#ifdef CONFIG_INPUT_M68K_BEEP_MODULE +EXPORT_SYMBOL(mach_beep); +#endif +EXPORT_SYMBOL(dump_fpu); +EXPORT_SYMBOL(dump_thread); +EXPORT_SYMBOL(strnlen); +EXPORT_SYMBOL(strrchr); +EXPORT_SYMBOL(strstr); +EXPORT_SYMBOL(kernel_thread); +#ifdef CONFIG_VME +EXPORT_SYMBOL(vme_brdtype); +#endif /* The following are special because they're not called explicitly (the C compiler generates them). Fortunately, diff --git a/trunk/arch/m68k/kernel/process.c b/trunk/arch/m68k/kernel/process.c index 99fc1226f7f8..45a46646c1b3 100644 --- a/trunk/arch/m68k/kernel/process.c +++ b/trunk/arch/m68k/kernel/process.c @@ -187,7 +187,6 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) set_fs (fs); return pid; } -EXPORT_SYMBOL(kernel_thread); void flush_thread(void) { @@ -222,13 +221,13 @@ asmlinkage int m68k_clone(struct pt_regs *regs) { unsigned long clone_flags; unsigned long newsp; - int __user *parent_tidptr, *child_tidptr; + int *parent_tidptr, *child_tidptr; /* syscall2 puts clone_flags in d1 and usp in d2 */ clone_flags = regs->d1; newsp = regs->d2; - parent_tidptr = (int __user *)regs->d3; - child_tidptr = (int __user *)regs->d4; + parent_tidptr = (int *)regs->d3; + child_tidptr = (int *)regs->d4; if (!newsp) newsp = rdusp(); return do_fork(clone_flags, newsp, regs, 0, @@ -312,7 +311,6 @@ int dump_fpu (struct pt_regs *regs, struct user_m68kfp_struct *fpu) : "memory"); return 1; } -EXPORT_SYMBOL(dump_fpu); /* * fill in the user structure for a core dump.. @@ -359,12 +357,11 @@ void dump_thread(struct pt_regs * regs, struct user * dump) /* dump floating point stuff */ dump->u_fpvalid = dump_fpu (regs, &dump->m68kfp); } -EXPORT_SYMBOL(dump_thread); /* * sys_execve() executes a new program. */ -asmlinkage int sys_execve(char __user *name, char __user * __user *argv, char __user * __user *envp) +asmlinkage int sys_execve(char *name, char **argv, char **envp) { int error; char * filename; diff --git a/trunk/arch/m68k/kernel/setup.c b/trunk/arch/m68k/kernel/setup.c index 9af3ee0e555d..f2d7ee0ee18c 100644 --- a/trunk/arch/m68k/kernel/setup.c +++ b/trunk/arch/m68k/kernel/setup.c @@ -42,39 +42,29 @@ unsigned long m68k_machtype; unsigned long m68k_cputype; -EXPORT_SYMBOL(m68k_machtype); -EXPORT_SYMBOL(m68k_cputype); unsigned long m68k_fputype; unsigned long m68k_mmutype; #ifdef CONFIG_VME unsigned long vme_brdtype; -EXPORT_SYMBOL(vme_brdtype); #endif int m68k_is040or060; -EXPORT_SYMBOL(m68k_is040or060); extern int end; extern unsigned long availmem; int m68k_num_memory; int m68k_realnum_memory; -EXPORT_SYMBOL(m68k_realnum_memory); -#ifdef CONFIG_SINGLE_MEMORY_CHUNK unsigned long m68k_memoffset; -EXPORT_SYMBOL(m68k_memoffset); -#endif struct mem_info m68k_memory[NUM_MEMINFO]; -EXPORT_SYMBOL(m68k_memory); static struct mem_info m68k_ramdisk; static char m68k_command_line[CL_SIZE]; char m68k_debug_device[6] = ""; -EXPORT_SYMBOL(m68k_debug_device); -void (*mach_sched_init) (irq_handler_t handler) __initdata = NULL; +void (*mach_sched_init) (irqreturn_t (*handler)(int, void *, struct pt_regs *)) __initdata = NULL; /* machine dependent irq functions */ void (*mach_init_IRQ) (void) __initdata = NULL; void (*mach_get_model) (char *model); @@ -82,14 +72,10 @@ int (*mach_get_hardware_list) (char *buffer); /* machine dependent timer functions */ unsigned long (*mach_gettimeoffset) (void); int (*mach_hwclk) (int, struct rtc_time*); -EXPORT_SYMBOL(mach_hwclk); int (*mach_set_clock_mmss) (unsigned long); unsigned int (*mach_get_ss)(void); int (*mach_get_rtc_pll)(struct rtc_pll_info *); int (*mach_set_rtc_pll)(struct rtc_pll_info *); -EXPORT_SYMBOL(mach_get_ss); -EXPORT_SYMBOL(mach_get_rtc_pll); -EXPORT_SYMBOL(mach_set_rtc_pll); void (*mach_reset)( void ); void (*mach_halt)( void ); void (*mach_power_off)( void ); @@ -103,7 +89,6 @@ void (*mach_l2_flush) (int); #endif #if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE) void (*mach_beep)(unsigned int, unsigned int); -EXPORT_SYMBOL(mach_beep); #endif #if defined(CONFIG_ISA) && defined(MULTI_ISA) int isa_type; diff --git a/trunk/arch/m68k/kernel/time.c b/trunk/arch/m68k/kernel/time.c index 2a599c3ed787..28b2fefa4513 100644 --- a/trunk/arch/m68k/kernel/time.c +++ b/trunk/arch/m68k/kernel/time.c @@ -21,7 +21,6 @@ #include #include -#include #include #include @@ -38,13 +37,13 @@ static inline int set_rtc_mmss(unsigned long nowtime) * timer_interrupt() needs to keep up the real-time clock, * as well as call the "do_timer()" routine every clocktick */ -static irqreturn_t timer_interrupt(int irq, void *dummy) +static irqreturn_t timer_interrupt(int irq, void *dummy, struct pt_regs * regs) { do_timer(1); #ifndef CONFIG_SMP - update_process_times(user_mode(get_irq_regs())); + update_process_times(user_mode(regs)); #endif - profile_tick(CPU_PROFILING); + profile_tick(CPU_PROFILING, regs); #ifdef CONFIG_HEARTBEAT /* use power LED as a heartbeat instead -- much more useful diff --git a/trunk/arch/m68k/kernel/traps.c b/trunk/arch/m68k/kernel/traps.c index 759fa244e6cd..4569406a2e1f 100644 --- a/trunk/arch/m68k/kernel/traps.c +++ b/trunk/arch/m68k/kernel/traps.c @@ -326,13 +326,13 @@ static inline int do_040writeback1(unsigned short wbs, unsigned long wba, switch (wbs & WBSIZ_040) { case BA_SIZE_BYTE: - res = put_user(wbd & 0xff, (char __user *)wba); + res = put_user(wbd & 0xff, (char *)wba); break; case BA_SIZE_WORD: - res = put_user(wbd & 0xffff, (short __user *)wba); + res = put_user(wbd & 0xffff, (short *)wba); break; case BA_SIZE_LONG: - res = put_user(wbd, (int __user *)wba); + res = put_user(wbd, (int *)wba); break; } diff --git a/trunk/arch/m68k/kernel/vmlinux-std.lds b/trunk/arch/m68k/kernel/vmlinux-std.lds index d2794452b195..69d1d3d30c78 100644 --- a/trunk/arch/m68k/kernel/vmlinux-std.lds +++ b/trunk/arch/m68k/kernel/vmlinux-std.lds @@ -54,7 +54,13 @@ SECTIONS __setup_end = .; __initcall_start = .; .initcall.init : { - INITCALLS + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) } __initcall_end = .; __con_initcall_start = .; diff --git a/trunk/arch/m68k/kernel/vmlinux-sun3.lds b/trunk/arch/m68k/kernel/vmlinux-sun3.lds index 2550b4ae2732..65cc39c24185 100644 --- a/trunk/arch/m68k/kernel/vmlinux-sun3.lds +++ b/trunk/arch/m68k/kernel/vmlinux-sun3.lds @@ -48,7 +48,13 @@ __init_begin = .; __setup_end = .; __initcall_start = .; .initcall.init : { - INITCALLS + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) } __initcall_end = .; __con_initcall_start = .; diff --git a/trunk/arch/m68k/lib/string.c b/trunk/arch/m68k/lib/string.c index 891e1347bc4e..b92b89e1ea0c 100644 --- a/trunk/arch/m68k/lib/string.c +++ b/trunk/arch/m68k/lib/string.c @@ -1,19 +1,6 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive - * for more details. - */ - -#define __IN_STRING_C +#include #include -#include - -char *strcpy(char *dest, const char *src) -{ - return __kernel_strcpy(dest, src); -} -EXPORT_SYMBOL(strcpy); void *memset(void *s, int c, size_t count) { diff --git a/trunk/arch/m68k/lib/uaccess.c b/trunk/arch/m68k/lib/uaccess.c index 865f9fb9e686..1bc188c0d983 100644 --- a/trunk/arch/m68k/lib/uaccess.c +++ b/trunk/arch/m68k/lib/uaccess.c @@ -84,7 +84,7 @@ unsigned long __generic_copy_to_user(void __user *to, const void *from, " .even\n" "20: lsl.l #2,%0\n" "50: add.l %5,%0\n" - " jra 8b\n" + " jra 7b\n" " .previous\n" "\n" " .section __ex_table,\"a\"\n" diff --git a/trunk/arch/m68k/mac/baboon.c b/trunk/arch/m68k/mac/baboon.c index a1c7ec706741..6eaa881793d1 100644 --- a/trunk/arch/m68k/mac/baboon.c +++ b/trunk/arch/m68k/mac/baboon.c @@ -25,7 +25,7 @@ int baboon_present,baboon_active; volatile struct baboon *baboon; -irqreturn_t baboon_irq(int, void *); +irqreturn_t baboon_irq(int, void *, struct pt_regs *); #if 0 extern int macide_ack_intr(struct ata_channel *); @@ -64,7 +64,7 @@ void __init baboon_register_interrupts(void) * Baboon interrupt handler. This works a lot like a VIA. */ -irqreturn_t baboon_irq(int irq, void *dev_id) +irqreturn_t baboon_irq(int irq, void *dev_id, struct pt_regs *regs) { int irq_bit,i; unsigned char events; @@ -81,7 +81,7 @@ irqreturn_t baboon_irq(int irq, void *dev_id) for (i = 0, irq_bit = 1 ; i < 3 ; i++, irq_bit <<= 1) { if (events & irq_bit/* & baboon_active*/) { baboon_active &= ~irq_bit; - m68k_handle_int(IRQ_BABOON_0 + i); + m68k_handle_int(IRQ_BABOON_0 + i, regs); baboon_active |= irq_bit; baboon->mb_ifr &= ~irq_bit; } diff --git a/trunk/arch/m68k/mac/config.c b/trunk/arch/m68k/mac/config.c index 562b38d00180..85dda1095b1f 100644 --- a/trunk/arch/m68k/mac/config.c +++ b/trunk/arch/m68k/mac/config.c @@ -72,7 +72,7 @@ extern int show_mac_interrupts(struct seq_file *, void *); extern void iop_preinit(void); extern void iop_init(void); extern void via_init(void); -extern void via_init_clock(irq_handler_t func); +extern void via_init_clock(irqreturn_t (*func)(int, void *, struct pt_regs *)); extern void via_flush_cache(void); extern void oss_init(void); extern void psc_init(void); @@ -88,7 +88,7 @@ extern void mac_debugging_long(int, long); static void mac_get_model(char *str); -static void mac_sched_init(irq_handler_t vector) +static void mac_sched_init(irqreturn_t (*vector)(int, void *, struct pt_regs *)) { via_init_clock(vector); } diff --git a/trunk/arch/m68k/mac/iop.c b/trunk/arch/m68k/mac/iop.c index 0cea21f58192..bc657b1057a7 100644 --- a/trunk/arch/m68k/mac/iop.c +++ b/trunk/arch/m68k/mac/iop.c @@ -132,7 +132,7 @@ static int iop_get_proc_info(char *, char **, off_t, int); struct listener { const char *devname; - void (*handler)(struct iop_msg *); + void (*handler)(struct iop_msg *, struct pt_regs *); }; /* @@ -152,7 +152,7 @@ static struct iop_msg iop_msg_pool[NUM_IOP_MSGS]; static struct iop_msg *iop_send_queue[NUM_IOPS][NUM_IOP_CHAN]; static struct listener iop_listeners[NUM_IOPS][NUM_IOP_CHAN]; -irqreturn_t iop_ism_irq(int, void *); +irqreturn_t iop_ism_irq(int, void *, struct pt_regs *); extern void oss_irq_enable(int); @@ -342,7 +342,7 @@ void __init iop_register_interrupts(void) */ int iop_listen(uint iop_num, uint chan, - void (*handler)(struct iop_msg *), + void (*handler)(struct iop_msg *, struct pt_regs *), const char *devname) { if ((iop_num >= NUM_IOPS) || !iop_base[iop_num]) return -EINVAL; @@ -407,7 +407,7 @@ static void iop_do_send(struct iop_msg *msg) * has gone into the IOP_MSG_COMPLETE state. */ -static void iop_handle_send(uint iop_num, uint chan) +static void iop_handle_send(uint iop_num, uint chan, struct pt_regs *regs) { volatile struct mac_iop *iop = iop_base[iop_num]; struct iop_msg *msg,*msg2; @@ -426,7 +426,7 @@ static void iop_handle_send(uint iop_num, uint chan) for (i = 0 ; i < IOP_MSG_LEN ; i++, offset++) { msg->reply[i] = iop_readb(iop, offset); } - if (msg->handler) (*msg->handler)(msg); + if (msg->handler) (*msg->handler)(msg, regs); msg2 = msg; msg = msg->next; iop_free_msg(msg2); @@ -440,7 +440,7 @@ static void iop_handle_send(uint iop_num, uint chan) * gone into the IOP_MSG_NEW state. */ -static void iop_handle_recv(uint iop_num, uint chan) +static void iop_handle_recv(uint iop_num, uint chan, struct pt_regs *regs) { volatile struct mac_iop *iop = iop_base[iop_num]; int i,offset; @@ -468,7 +468,7 @@ static void iop_handle_recv(uint iop_num, uint chan) /* the message ourselves to avoid possible stalls. */ if (msg->handler) { - (*msg->handler)(msg); + (*msg->handler)(msg, regs); } else { #ifdef DEBUG_IOP printk("iop_handle_recv: unclaimed message on iop %d channel %d\n", iop_num, chan); @@ -492,7 +492,7 @@ static void iop_handle_recv(uint iop_num, uint chan) int iop_send_message(uint iop_num, uint chan, void *privdata, uint msg_len, __u8 *msg_data, - void (*handler)(struct iop_msg *)) + void (*handler)(struct iop_msg *, struct pt_regs *)) { struct iop_msg *msg, *q; @@ -584,7 +584,7 @@ __u8 *iop_compare_code(uint iop_num, __u8 *code_start, * Handle an ISM IOP interrupt */ -irqreturn_t iop_ism_irq(int irq, void *dev_id) +irqreturn_t iop_ism_irq(int irq, void *dev_id, struct pt_regs *regs) { uint iop_num = (uint) dev_id; volatile struct mac_iop *iop = iop_base[iop_num]; @@ -608,7 +608,7 @@ irqreturn_t iop_ism_irq(int irq, void *dev_id) printk(" %02X", state); #endif if (state == IOP_MSG_COMPLETE) { - iop_handle_send(iop_num, i); + iop_handle_send(iop_num, i, regs); } } #ifdef DEBUG_IOP @@ -628,7 +628,7 @@ irqreturn_t iop_ism_irq(int irq, void *dev_id) printk(" %02X", state); #endif if (state == IOP_MSG_NEW) { - iop_handle_recv(iop_num, i); + iop_handle_recv(iop_num, i, regs); } } #ifdef DEBUG_IOP diff --git a/trunk/arch/m68k/mac/macints.c b/trunk/arch/m68k/mac/macints.c index f6fcd754d8f6..694b14bb0de1 100644 --- a/trunk/arch/m68k/mac/macints.c +++ b/trunk/arch/m68k/mac/macints.c @@ -133,7 +133,6 @@ #include #include #include -#include #define DEBUG_SPURIOUS #define SHUTUP_SONIC @@ -209,8 +208,8 @@ static void scc_irq_disable(unsigned int); * console_loglevel determines NMI handler function */ -irqreturn_t mac_nmi_handler(int, void *); -irqreturn_t mac_debug_handler(int, void *); +irqreturn_t mac_nmi_handler(int, void *, struct pt_regs *); +irqreturn_t mac_debug_handler(int, void *, struct pt_regs *); /* #define DEBUG_MACINTS */ @@ -394,7 +393,7 @@ int mac_irq_pending(unsigned int irq) static int num_debug[8]; -irqreturn_t mac_debug_handler(int irq, void *dev_id) +irqreturn_t mac_debug_handler(int irq, void *dev_id, struct pt_regs *regs) { if (num_debug[irq] < 10) { printk("DEBUG: Unexpected IRQ %d\n", irq); @@ -406,7 +405,7 @@ irqreturn_t mac_debug_handler(int irq, void *dev_id) static int in_nmi; static volatile int nmi_hold; -irqreturn_t mac_nmi_handler(int irq, void *dev_id) +irqreturn_t mac_nmi_handler(int irq, void *dev_id, struct pt_regs *fp) { int i; /* @@ -433,7 +432,6 @@ irqreturn_t mac_nmi_handler(int irq, void *dev_id) if (console_loglevel >= 8) { #if 0 - struct pt_regs *fp = get_irq_regs(); show_state(); printk("PC: %08lx\nSR: %04x SP: %p\n", fp->pc, fp->sr, fp); printk("d0: %08lx d1: %08lx d2: %08lx d3: %08lx\n", @@ -481,7 +479,7 @@ static void scc_irq_disable(unsigned int irq) * here is cleaner than hacking it into drivers/char/macserial.c. */ -void mac_scc_dispatch(int irq, void *dev_id) +void mac_scc_dispatch(int irq, void *dev_id, struct pt_regs *regs) { volatile unsigned char *scc = (unsigned char *) mac_bi_data.sccbase + 2; unsigned char reg; @@ -506,7 +504,7 @@ void mac_scc_dispatch(int irq, void *dev_id) /* pretty much kill the system. */ if (reg & 0x38) - m68k_handle_int(IRQ_SCCA); + m68k_handle_int(IRQ_SCCA, regs); if (reg & 0x07) - m68k_handle_int(IRQ_SCCB); + m68k_handle_int(IRQ_SCCB, regs); } diff --git a/trunk/arch/m68k/mac/oss.c b/trunk/arch/m68k/mac/oss.c index 63690819565a..63e04365191f 100644 --- a/trunk/arch/m68k/mac/oss.c +++ b/trunk/arch/m68k/mac/oss.c @@ -30,11 +30,11 @@ int oss_present; volatile struct mac_oss *oss; -irqreturn_t oss_irq(int, void *); -irqreturn_t oss_nubus_irq(int, void *); +irqreturn_t oss_irq(int, void *, struct pt_regs *); +irqreturn_t oss_nubus_irq(int, void *, struct pt_regs *); -extern irqreturn_t via1_irq(int, void *); -extern irqreturn_t mac_scc_dispatch(int, void *); +extern irqreturn_t via1_irq(int, void *, struct pt_regs *); +extern irqreturn_t mac_scc_dispatch(int, void *, struct pt_regs *); /* * Initialize the OSS @@ -92,7 +92,7 @@ void __init oss_nubus_init(void) * and SCSI; everything else is routed to its own autovector IRQ. */ -irqreturn_t oss_irq(int irq, void *dev_id) +irqreturn_t oss_irq(int irq, void *dev_id, struct pt_regs *regs) { int events; @@ -113,7 +113,7 @@ irqreturn_t oss_irq(int irq, void *dev_id) oss->irq_pending &= ~OSS_IP_SOUND; } else if (events & OSS_IP_SCSI) { oss->irq_level[OSS_SCSI] = OSS_IRQLEV_DISABLED; - m68k_handle_int(IRQ_MAC_SCSI); + m68k_handle_int(IRQ_MAC_SCSI, regs); oss->irq_pending &= ~OSS_IP_SCSI; oss->irq_level[OSS_SCSI] = OSS_IRQLEV_SCSI; } else { @@ -128,7 +128,7 @@ irqreturn_t oss_irq(int irq, void *dev_id) * Unlike the VIA/RBV this is on its own autovector interrupt level. */ -irqreturn_t oss_nubus_irq(int irq, void *dev_id) +irqreturn_t oss_nubus_irq(int irq, void *dev_id, struct pt_regs *regs) { int events, irq_bit, i; @@ -146,7 +146,7 @@ irqreturn_t oss_nubus_irq(int irq, void *dev_id) for (i = 0, irq_bit = 1 ; i < 6 ; i++, irq_bit <<= 1) { if (events & irq_bit) { oss->irq_level[i] = OSS_IRQLEV_DISABLED; - m68k_handle_int(NUBUS_SOURCE_BASE + i); + m68k_handle_int(NUBUS_SOURCE_BASE + i, regs); oss->irq_pending &= ~irq_bit; oss->irq_level[i] = OSS_IRQLEV_NUBUS; } diff --git a/trunk/arch/m68k/mac/psc.c b/trunk/arch/m68k/mac/psc.c index 15378a5878c9..e26218091755 100644 --- a/trunk/arch/m68k/mac/psc.c +++ b/trunk/arch/m68k/mac/psc.c @@ -30,7 +30,7 @@ int psc_present; volatile __u8 *psc; -irqreturn_t psc_irq(int, void *); +irqreturn_t psc_irq(int, void *, struct pt_regs *); /* * Debugging dump, used in various places to see what's going on. @@ -127,7 +127,7 @@ void __init psc_register_interrupts(void) * PSC interrupt handler. It's a lot like the VIA interrupt handler. */ -irqreturn_t psc_irq(int irq, void *dev_id) +irqreturn_t psc_irq(int irq, void *dev_id, struct pt_regs *regs) { int pIFR = pIFRbase + ((int) dev_id); int pIER = pIERbase + ((int) dev_id); @@ -149,7 +149,7 @@ irqreturn_t psc_irq(int irq, void *dev_id) for (i = 0, irq_bit = 1 ; i < 4 ; i++, irq_bit <<= 1) { if (events & irq_bit) { psc_write_byte(pIER, irq_bit); - m68k_handle_int(base_irq + i); + m68k_handle_int(base_irq + i, regs); psc_write_byte(pIFR, irq_bit); psc_write_byte(pIER, irq_bit | 0x80); } diff --git a/trunk/arch/m68k/mac/via.c b/trunk/arch/m68k/mac/via.c index e27735be2924..c4aa345d544e 100644 --- a/trunk/arch/m68k/mac/via.c +++ b/trunk/arch/m68k/mac/via.c @@ -63,14 +63,14 @@ static int gIER,gIFR,gBufA,gBufB; static int nubus_active; void via_debug_dump(void); -irqreturn_t via1_irq(int, void *); -irqreturn_t via2_irq(int, void *); -irqreturn_t via_nubus_irq(int, void *); +irqreturn_t via1_irq(int, void *, struct pt_regs *); +irqreturn_t via2_irq(int, void *, struct pt_regs *); +irqreturn_t via_nubus_irq(int, void *, struct pt_regs *); void via_irq_enable(int irq); void via_irq_disable(int irq); void via_irq_clear(int irq); -extern irqreturn_t mac_scc_dispatch(int, void *); +extern irqreturn_t mac_scc_dispatch(int, void *, struct pt_regs *); extern int oss_present; /* @@ -235,7 +235,7 @@ void __init via_init(void) * Start the 100 Hz clock */ -void __init via_init_clock(irq_handler_t func) +void __init via_init_clock(irqreturn_t (*func)(int, void *, struct pt_regs *)) { via1[vACR] |= 0x40; via1[vT1LL] = MAC_CLOCK_LOW; @@ -412,7 +412,7 @@ void __init via_nubus_init(void) * the machspec interrupt number after clearing the interrupt. */ -irqreturn_t via1_irq(int irq, void *dev_id) +irqreturn_t via1_irq(int irq, void *dev_id, struct pt_regs *regs) { int irq_bit, i; unsigned char events, mask; @@ -424,7 +424,7 @@ irqreturn_t via1_irq(int irq, void *dev_id) for (i = 0, irq_bit = 1 ; i < 7 ; i++, irq_bit <<= 1) if (events & irq_bit) { via1[vIER] = irq_bit; - m68k_handle_int(VIA1_SOURCE_BASE + i); + m68k_handle_int(VIA1_SOURCE_BASE + i, regs); via1[vIFR] = irq_bit; via1[vIER] = irq_bit | 0x80; } @@ -439,14 +439,14 @@ irqreturn_t via1_irq(int irq, void *dev_id) /* No, it won't be set. that's why we're doing this. */ via_irq_disable(IRQ_MAC_NUBUS); via_irq_clear(IRQ_MAC_NUBUS); - m68k_handle_int(IRQ_MAC_NUBUS); + m68k_handle_int(IRQ_MAC_NUBUS, regs); via_irq_enable(IRQ_MAC_NUBUS); } #endif return IRQ_HANDLED; } -irqreturn_t via2_irq(int irq, void *dev_id) +irqreturn_t via2_irq(int irq, void *dev_id, struct pt_regs *regs) { int irq_bit, i; unsigned char events, mask; @@ -459,7 +459,7 @@ irqreturn_t via2_irq(int irq, void *dev_id) if (events & irq_bit) { via2[gIER] = irq_bit; via2[gIFR] = irq_bit | rbv_clear; - m68k_handle_int(VIA2_SOURCE_BASE + i); + m68k_handle_int(VIA2_SOURCE_BASE + i, regs); via2[gIER] = irq_bit | 0x80; } return IRQ_HANDLED; @@ -470,7 +470,7 @@ irqreturn_t via2_irq(int irq, void *dev_id) * VIA2 dispatcher as a fast interrupt handler. */ -irqreturn_t via_nubus_irq(int irq, void *dev_id) +irqreturn_t via_nubus_irq(int irq, void *dev_id, struct pt_regs *regs) { int irq_bit, i; unsigned char events; @@ -481,7 +481,7 @@ irqreturn_t via_nubus_irq(int irq, void *dev_id) for (i = 0, irq_bit = 1 ; i < 7 ; i++, irq_bit <<= 1) { if (events & irq_bit) { via_irq_disable(NUBUS_SOURCE_BASE + i); - m68k_handle_int(NUBUS_SOURCE_BASE + i); + m68k_handle_int(NUBUS_SOURCE_BASE + i, regs); via_irq_enable(NUBUS_SOURCE_BASE + i); } } diff --git a/trunk/arch/m68k/mm/kmap.c b/trunk/arch/m68k/mm/kmap.c index b54ef1726c55..f46f049d29ff 100644 --- a/trunk/arch/m68k/mm/kmap.c +++ b/trunk/arch/m68k/mm/kmap.c @@ -7,7 +7,6 @@ * used by other architectures /Roman Zippel */ -#include #include #include #include @@ -220,7 +219,6 @@ void __iomem *__ioremap(unsigned long physaddr, unsigned long size, int cachefla return (void __iomem *)retaddr; } -EXPORT_SYMBOL(__ioremap); /* * Unmap a ioremap()ed region again @@ -236,7 +234,6 @@ void iounmap(void __iomem *addr) free_io_area((__force void *)addr); #endif } -EXPORT_SYMBOL(iounmap); /* * __iounmap unmaps nearly everything, so be careful @@ -363,4 +360,3 @@ void kernel_set_cachemode(void *addr, unsigned long size, int cmode) flush_tlb_all(); } -EXPORT_SYMBOL(kernel_set_cachemode); diff --git a/trunk/arch/m68k/mm/memory.c b/trunk/arch/m68k/mm/memory.c index 0f88812822b1..a0c095e17222 100644 --- a/trunk/arch/m68k/mm/memory.c +++ b/trunk/arch/m68k/mm/memory.c @@ -4,7 +4,6 @@ * Copyright (C) 1995 Hamish Macdonald */ -#include #include #include #include @@ -158,8 +157,9 @@ unsigned long mm_vtop(unsigned long vaddr) return -1; } -EXPORT_SYMBOL(mm_vtop); +#endif +#ifndef CONFIG_SINGLE_MEMORY_CHUNK unsigned long mm_ptov (unsigned long paddr) { int i = 0; @@ -185,7 +185,6 @@ unsigned long mm_ptov (unsigned long paddr) #endif return -1; } -EXPORT_SYMBOL(mm_ptov); #endif /* invalidate page in both caches */ @@ -299,7 +298,6 @@ void cache_clear (unsigned long paddr, int len) mach_l2_flush(0); #endif } -EXPORT_SYMBOL(cache_clear); /* probably can be unexported */ /* @@ -352,7 +350,6 @@ void cache_push (unsigned long paddr, int len) mach_l2_flush(1); #endif } -EXPORT_SYMBOL(cache_push); /* probably can be unexported */ #ifndef CONFIG_SINGLE_MEMORY_CHUNK int mm_end_of_chunk (unsigned long addr, int len) @@ -364,5 +361,4 @@ int mm_end_of_chunk (unsigned long addr, int len) return 1; return 0; } -EXPORT_SYMBOL(mm_end_of_chunk); #endif diff --git a/trunk/arch/m68k/mm/sun3kmap.c b/trunk/arch/m68k/mm/sun3kmap.c index 1af24cb5bfe1..7f0d86f3fe73 100644 --- a/trunk/arch/m68k/mm/sun3kmap.c +++ b/trunk/arch/m68k/mm/sun3kmap.c @@ -8,7 +8,6 @@ * for more details. */ -#include #include #include #include @@ -60,7 +59,7 @@ static inline void do_pmeg_mapin(unsigned long phys, unsigned long virt, } } -void __iomem *sun3_ioremap(unsigned long phys, unsigned long size, +void *sun3_ioremap(unsigned long phys, unsigned long size, unsigned long type) { struct vm_struct *area; @@ -102,24 +101,22 @@ void __iomem *sun3_ioremap(unsigned long phys, unsigned long size, virt += seg_pages * PAGE_SIZE; } - return (void __iomem *)ret; + return (void *)ret; } -void __iomem *__ioremap(unsigned long phys, unsigned long size, int cache) +void *__ioremap(unsigned long phys, unsigned long size, int cache) { return sun3_ioremap(phys, size, SUN3_PAGE_TYPE_IO); } -EXPORT_SYMBOL(__ioremap); -void iounmap(void __iomem *addr) +void iounmap(void *addr) { vfree((void *)(PAGE_MASK & (unsigned long)addr)); } -EXPORT_SYMBOL(iounmap); /* sun3_map_test(addr, val) -- Reads a byte from addr, storing to val, * trapping the potential read fault. Returns 0 if the access faulted, diff --git a/trunk/arch/m68k/mvme147/config.c b/trunk/arch/m68k/mvme147/config.c index 4a7df9c3f85a..0cd0e5bddcee 100644 --- a/trunk/arch/m68k/mvme147/config.c +++ b/trunk/arch/m68k/mvme147/config.c @@ -38,7 +38,7 @@ static void mvme147_get_model(char *model); static int mvme147_get_hardware_list(char *buffer); -extern void mvme147_sched_init(irq_handler_t handler); +extern void mvme147_sched_init(irqreturn_t (*handler)(int, void *, struct pt_regs *)); extern unsigned long mvme147_gettimeoffset (void); extern int mvme147_hwclk (int, struct rtc_time *); extern int mvme147_set_clock_mmss (unsigned long); @@ -51,7 +51,7 @@ static int bcd2int (unsigned char b); /* Save tick handler routine pointer, will point to do_timer() in * kernel/sched.c, called via mvme147_process_int() */ -irq_handler_t tick_handler; +irqreturn_t (*tick_handler)(int, void *, struct pt_regs *); int mvme147_parse_bootinfo(const struct bi_record *bi) @@ -114,15 +114,15 @@ void __init config_mvme147(void) /* Using pcc tick timer 1 */ -static irqreturn_t mvme147_timer_int (int irq, void *dev_id) +static irqreturn_t mvme147_timer_int (int irq, void *dev_id, struct pt_regs *fp) { m147_pcc->t1_int_cntrl = PCC_TIMER_INT_CLR; m147_pcc->t1_int_cntrl = PCC_INT_ENAB|PCC_LEVEL_TIMER1; - return tick_handler(irq, dev_id); + return tick_handler(irq, dev_id, fp); } -void mvme147_sched_init (irq_handler_t timer_routine) +void mvme147_sched_init (irqreturn_t (*timer_routine)(int, void *, struct pt_regs *)) { tick_handler = timer_routine; request_irq (PCC_IRQ_TIMER1, mvme147_timer_int, diff --git a/trunk/arch/m68k/mvme16x/config.c b/trunk/arch/m68k/mvme16x/config.c index c829ebb6b1af..ce2727ed1bc0 100644 --- a/trunk/arch/m68k/mvme16x/config.c +++ b/trunk/arch/m68k/mvme16x/config.c @@ -42,7 +42,7 @@ static MK48T08ptr_t volatile rtc = (MK48T08ptr_t)MVME_RTC_BASE; static void mvme16x_get_model(char *model); static int mvme16x_get_hardware_list(char *buffer); -extern void mvme16x_sched_init(irq_handler_t handler); +extern void mvme16x_sched_init(irqreturn_t (*handler)(int, void *, struct pt_regs *)); extern unsigned long mvme16x_gettimeoffset (void); extern int mvme16x_hwclk (int, struct rtc_time *); extern int mvme16x_set_clock_mmss (unsigned long); @@ -54,7 +54,7 @@ int bcd2int (unsigned char b); /* Save tick handler routine pointer, will point to do_timer() in * kernel/sched.c, called via mvme16x_process_int() */ -static irq_handler_t tick_handler; +static irqreturn_t (*tick_handler)(int, void *, struct pt_regs *); unsigned short mvme16x_config; @@ -190,7 +190,7 @@ void __init config_mvme16x(void) } } -static irqreturn_t mvme16x_abort_int (int irq, void *dev_id) +static irqreturn_t mvme16x_abort_int (int irq, void *dev_id, struct pt_regs *fp) { p_bdid p = &mvme_bdid; unsigned long *new = (unsigned long *)vectors; @@ -218,13 +218,13 @@ static irqreturn_t mvme16x_abort_int (int irq, void *dev_id) return IRQ_HANDLED; } -static irqreturn_t mvme16x_timer_int (int irq, void *dev_id) +static irqreturn_t mvme16x_timer_int (int irq, void *dev_id, struct pt_regs *fp) { *(volatile unsigned char *)0xfff4201b |= 8; - return tick_handler(irq, dev_id); + return tick_handler(irq, dev_id, fp); } -void mvme16x_sched_init (irq_handler_t timer_routine) +void mvme16x_sched_init (irqreturn_t (*timer_routine)(int, void *, struct pt_regs *)) { p_bdid p = &mvme_bdid; int irq; diff --git a/trunk/arch/m68k/q40/config.c b/trunk/arch/m68k/q40/config.c index 92f873cc7060..9a1827876408 100644 --- a/trunk/arch/m68k/q40/config.c +++ b/trunk/arch/m68k/q40/config.c @@ -39,7 +39,7 @@ extern irqreturn_t q40_process_int (int level, struct pt_regs *regs); extern void q40_init_IRQ (void); static void q40_get_model(char *model); static int q40_get_hardware_list(char *buffer); -extern void q40_sched_init(irq_handler_t handler); +extern void q40_sched_init(irqreturn_t (*handler)(int, void *, struct pt_regs *)); extern unsigned long q40_gettimeoffset (void); extern int q40_hwclk (int, struct rtc_time *); diff --git a/trunk/arch/m68k/q40/q40ints.c b/trunk/arch/m68k/q40/q40ints.c index 31cc07d8cec4..472f41c4158b 100644 --- a/trunk/arch/m68k/q40/q40ints.c +++ b/trunk/arch/m68k/q40/q40ints.c @@ -125,9 +125,9 @@ void q40_mksound(unsigned int hz, unsigned int ticks) sound_ticks = ticks << 1; } -static irq_handler_t q40_timer_routine; +static irqreturn_t (*q40_timer_routine)(int, void *, struct pt_regs *); -static irqreturn_t q40_timer_int (int irq, void * dev) +static irqreturn_t q40_timer_int (int irq, void * dev, struct pt_regs * regs) { ql_ticks = ql_ticks ? 0 : 1; if (sound_ticks) { @@ -138,11 +138,11 @@ static irqreturn_t q40_timer_int (int irq, void * dev) } if (!ql_ticks) - q40_timer_routine(irq, dev); + q40_timer_routine(irq, dev, regs); return IRQ_HANDLED; } -void q40_sched_init (irq_handler_t timer_routine) +void q40_sched_init (irqreturn_t (*timer_routine)(int, void *, struct pt_regs *)) { int timer_irq; @@ -218,11 +218,11 @@ static void q40_irq_handler(unsigned int irq, struct pt_regs *fp) switch (irq) { case 4: case 6: - __m68k_handle_int(Q40_IRQ_SAMPLE, fp); + m68k_handle_int(Q40_IRQ_SAMPLE, fp); return; } if (mir & Q40_IRQ_FRAME_MASK) { - __m68k_handle_int(Q40_IRQ_FRAME, fp); + m68k_handle_int(Q40_IRQ_FRAME, fp); master_outb(-1, FRAME_CLEAR_REG); } if ((mir & Q40_IRQ_SER_MASK) || (mir & Q40_IRQ_EXT_MASK)) { @@ -257,7 +257,7 @@ static void q40_irq_handler(unsigned int irq, struct pt_regs *fp) goto iirq; } q40_state[irq] |= IRQ_INPROGRESS; - __m68k_handle_int(irq, fp); + m68k_handle_int(irq, fp); q40_state[irq] &= ~IRQ_INPROGRESS; /* naively enable everything, if that fails than */ @@ -288,7 +288,7 @@ static void q40_irq_handler(unsigned int irq, struct pt_regs *fp) mir = master_inb(IIRQ_REG); /* should test whether keyboard irq is really enabled, doing it in defhand */ if (mir & Q40_IRQ_KEYB_MASK) - __m68k_handle_int(Q40_IRQ_KEYBOARD, fp); + m68k_handle_int(Q40_IRQ_KEYBOARD, fp); return; } diff --git a/trunk/arch/m68k/sun3/Makefile b/trunk/arch/m68k/sun3/Makefile index be1a8470d636..4d4f0695d985 100644 --- a/trunk/arch/m68k/sun3/Makefile +++ b/trunk/arch/m68k/sun3/Makefile @@ -2,6 +2,6 @@ # Makefile for Linux arch/m68k/sun3 source directory # -obj-y := sun3ints.o sun3dvma.o sbus.o idprom.o +obj-y := sun3_ksyms.o sun3ints.o sun3dvma.o sbus.o idprom.o obj-$(CONFIG_SUN3) += config.o mmu_emu.o leds.o dvma.o intersil.o diff --git a/trunk/arch/m68k/sun3/config.c b/trunk/arch/m68k/sun3/config.c index 4851b8437a87..d09d03b3d956 100644 --- a/trunk/arch/m68k/sun3/config.c +++ b/trunk/arch/m68k/sun3/config.c @@ -35,7 +35,7 @@ extern char _text, _end; char sun3_reserved_pmeg[SUN3_PMEGS_NUM]; extern unsigned long sun3_gettimeoffset(void); -extern void sun3_sched_init(irq_handler_t handler); +extern void sun3_sched_init(irqreturn_t (*handler)(int, void *, struct pt_regs *)); extern void sun3_get_model (char* model); extern void idprom_init (void); extern int sun3_hwclk(int set, struct rtc_time *t); @@ -162,7 +162,7 @@ void __init config_sun3(void) sun3_bootmem_alloc(memory_start, memory_end); } -void __init sun3_sched_init(irq_handler_t timer_routine) +void __init sun3_sched_init(irqreturn_t (*timer_routine)(int, void *, struct pt_regs *)) { sun3_disable_interrupts(); intersil_clock->cmd_reg=(INTERSIL_RUN|INTERSIL_INT_DISABLE|INTERSIL_24H_MODE); diff --git a/trunk/arch/m68k/sun3/idprom.c b/trunk/arch/m68k/sun3/idprom.c index dca6ab6a4ede..02c1fee6fe74 100644 --- a/trunk/arch/m68k/sun3/idprom.c +++ b/trunk/arch/m68k/sun3/idprom.c @@ -6,7 +6,6 @@ * Sun3/3x models added by David Monro (davidm@psrg.cs.usyd.edu.au) */ -#include #include #include #include @@ -17,8 +16,6 @@ #include /* Fun with Sun released architectures. */ struct idprom *idprom; -EXPORT_SYMBOL(idprom); - static struct idprom idprom_buffer; /* Here is the master table of Sun machines which use some implementation diff --git a/trunk/arch/m68k/sun3/sun3_ksyms.c b/trunk/arch/m68k/sun3/sun3_ksyms.c new file mode 100644 index 000000000000..43e5a9af8abd --- /dev/null +++ b/trunk/arch/m68k/sun3/sun3_ksyms.c @@ -0,0 +1,13 @@ +#include +#include +#include +#include + +/* + * Add things here when you find the need for it. + */ +EXPORT_SYMBOL(dvma_map_align); +EXPORT_SYMBOL(dvma_unmap); +EXPORT_SYMBOL(dvma_malloc_align); +EXPORT_SYMBOL(dvma_free); +EXPORT_SYMBOL(idprom); diff --git a/trunk/arch/m68k/sun3/sun3dvma.c b/trunk/arch/m68k/sun3/sun3dvma.c index 8709677fa025..a2bc2da7f8f0 100644 --- a/trunk/arch/m68k/sun3/sun3dvma.c +++ b/trunk/arch/m68k/sun3/sun3dvma.c @@ -6,7 +6,6 @@ * Contains common routines for sun3/sun3x DVMA management. */ -#include #include #include #include @@ -313,7 +312,6 @@ inline unsigned long dvma_map_align(unsigned long kaddr, int len, int align) BUG(); return 0; } -EXPORT_SYMBOL(dvma_map_align); void dvma_unmap(void *baddr) { @@ -329,7 +327,7 @@ void dvma_unmap(void *baddr) return; } -EXPORT_SYMBOL(dvma_unmap); + void *dvma_malloc_align(unsigned long len, unsigned long align) { @@ -369,7 +367,6 @@ void *dvma_malloc_align(unsigned long len, unsigned long align) return (void *)vaddr; } -EXPORT_SYMBOL(dvma_malloc_align); void dvma_free(void *vaddr) { @@ -377,4 +374,3 @@ void dvma_free(void *vaddr) return; } -EXPORT_SYMBOL(dvma_free); diff --git a/trunk/arch/m68k/sun3/sun3ints.c b/trunk/arch/m68k/sun3/sun3ints.c index baf74e8de8b5..dc4ea7e074a6 100644 --- a/trunk/arch/m68k/sun3/sun3ints.c +++ b/trunk/arch/m68k/sun3/sun3ints.c @@ -15,7 +15,6 @@ #include #include #include -#include #include extern void sun3_leds (unsigned char); @@ -49,7 +48,7 @@ void sun3_disable_irq(unsigned int irq) *sun3_intreg &= ~(1 << irq); } -static irqreturn_t sun3_int7(int irq, void *dev_id) +static irqreturn_t sun3_int7(int irq, void *dev_id, struct pt_regs *fp) { *sun3_intreg |= (1 << irq); if (!(kstat_cpu(0).irqs[irq] % 2000)) @@ -57,7 +56,7 @@ static irqreturn_t sun3_int7(int irq, void *dev_id) return IRQ_HANDLED; } -static irqreturn_t sun3_int5(int irq, void *dev_id) +static irqreturn_t sun3_int5(int irq, void *dev_id, struct pt_regs *fp) { #ifdef CONFIG_SUN3 intersil_clear(); @@ -68,14 +67,14 @@ static irqreturn_t sun3_int5(int irq, void *dev_id) #endif do_timer(1); #ifndef CONFIG_SMP - update_process_times(user_mode(get_irq_regs())); + update_process_times(user_mode(fp)); #endif if (!(kstat_cpu(0).irqs[irq] % 20)) sun3_leds(led_pattern[(kstat_cpu(0).irqs[irq] % 160) / 20]); return IRQ_HANDLED; } -static irqreturn_t sun3_vec255(int irq, void *dev_id) +static irqreturn_t sun3_vec255(int irq, void *dev_id, struct pt_regs *fp) { // intersil_clear(); return IRQ_HANDLED; @@ -85,7 +84,7 @@ static void sun3_inthandle(unsigned int irq, struct pt_regs *fp) { *sun3_intreg &= ~(1 << irq); - __m68k_handle_int(irq, fp); + m68k_handle_int(irq, fp); } static struct irq_controller sun3_irq_controller = { diff --git a/trunk/arch/m68k/sun3x/time.c b/trunk/arch/m68k/sun3x/time.c index f5eaafb00d21..6f4204fbecd7 100644 --- a/trunk/arch/m68k/sun3x/time.c +++ b/trunk/arch/m68k/sun3x/time.c @@ -90,7 +90,7 @@ static void sun3x_timer_tick(int irq, void *dev_id, struct pt_regs *regs) } #endif -void __init sun3x_sched_init(irq_handler_t vector) +void __init sun3x_sched_init(irqreturn_t (*vector)(int, void *, struct pt_regs *)) { sun3_disable_interrupts(); diff --git a/trunk/arch/m68k/sun3x/time.h b/trunk/arch/m68k/sun3x/time.h index 6909e1297534..e7e43b4ec4a1 100644 --- a/trunk/arch/m68k/sun3x/time.h +++ b/trunk/arch/m68k/sun3x/time.h @@ -3,7 +3,7 @@ extern int sun3x_hwclk(int set, struct rtc_time *t); unsigned long sun3x_gettimeoffset (void); -void sun3x_sched_init(irq_handler_t vector); +void sun3x_sched_init(irqreturn_t (*vector)(int, void *, struct pt_regs *)); struct mostek_dt { volatile unsigned char csr; diff --git a/trunk/arch/m68knommu/Kconfig b/trunk/arch/m68knommu/Kconfig index c1bc22c6d0d8..6d920d4bdc3d 100644 --- a/trunk/arch/m68knommu/Kconfig +++ b/trunk/arch/m68knommu/Kconfig @@ -565,7 +565,7 @@ config ROMVEC depends on ROM help This is almost always the same as the base of the ROM. Since on all - 68000 type variants the vectors are at the base of the boot device + 68000 type varients the vectors are at the base of the boot device on system startup. config ROMVECSIZE @@ -574,7 +574,7 @@ config ROMVECSIZE depends on ROM help Define the size of the vector region in ROM. For most 68000 - variants this would be 0x400 bytes in size. Set to 0 if you do + varients this would be 0x400 bytes in size. Set to 0 if you do not want a vector region at the start of the ROM. config ROMSTART diff --git a/trunk/arch/m68knommu/kernel/setup.c b/trunk/arch/m68knommu/kernel/setup.c index 7b21959eaeae..bde9811cf98c 100644 --- a/trunk/arch/m68knommu/kernel/setup.c +++ b/trunk/arch/m68knommu/kernel/setup.c @@ -62,7 +62,7 @@ int (*mach_kbdrate) (struct kbd_repeat *); void (*mach_kbd_leds) (unsigned int); /* machine dependent irq functions */ void (*mach_init_IRQ) (void); -irq_handler_t mach_default_handler; +irqreturn_t (*(*mach_default_handler)[]) (int, void *, struct pt_regs *); int (*mach_get_irq_list) (struct seq_file *, void *); void (*mach_process_int) (int irq, struct pt_regs *fp); void (*mach_trap_init) (void); diff --git a/trunk/arch/m68knommu/kernel/syscalltable.S b/trunk/arch/m68knommu/kernel/syscalltable.S index 4603f4f3c935..617e43ec95ae 100644 --- a/trunk/arch/m68knommu/kernel/syscalltable.S +++ b/trunk/arch/m68knommu/kernel/syscalltable.S @@ -296,39 +296,10 @@ ENTRY(sys_call_table) .long sys_mq_notify /* 275 */ .long sys_mq_getsetattr .long sys_waitid - .long sys_ni_syscall /* for sys_vserver */ - .long sys_add_key - .long sys_request_key /* 280 */ - .long sys_keyctl - .long sys_ioprio_set - .long sys_ioprio_get - .long sys_inotify_init - .long sys_inotify_add_watch /* 285 */ - .long sys_inotify_rm_watch - .long sys_migrate_pages - .long sys_openat - .long sys_mkdirat - .long sys_mknodat /* 290 */ - .long sys_fchownat - .long sys_futimesat - .long sys_fstatat64 - .long sys_unlinkat - .long sys_renameat /* 295 */ - .long sys_linkat - .long sys_symlinkat - .long sys_readlinkat - .long sys_fchmodat - .long sys_faccessat /* 300 */ - .long sys_ni_syscall /* Reserved for pselect6 */ - .long sys_ni_syscall /* Reserved for ppoll */ - .long sys_unshare - .long sys_set_robust_list - .long sys_get_robust_list /* 305 */ - .long sys_splice - .long sys_sync_file_range - .long sys_tee - .long sys_vmsplice - .long sys_move_pages /* 310 */ + .long sys_ni_syscall /* sys_setaltroot */ + .long sys_ni_syscall /* sys_add_key */ + .long sys_ni_syscall /* 280 */ /* sys_request_key */ + .long sys_ni_syscall /* sys_keyctl */ .rept NR_syscalls-(.-sys_call_table)/4 .long sys_ni_syscall diff --git a/trunk/arch/m68knommu/kernel/time.c b/trunk/arch/m68knommu/kernel/time.c index 9226264abf1a..c5667bdddd5e 100644 --- a/trunk/arch/m68knommu/kernel/time.c +++ b/trunk/arch/m68knommu/kernel/time.c @@ -54,7 +54,7 @@ static irqreturn_t timer_interrupt(int irq, void *dummy, struct pt_regs * regs) update_process_times(user_mode(regs)); #endif if (current->pid) - profile_tick(CPU_PROFILING); + profile_tick(CPU_PROFILING, regs); /* * If we have an externally synchronized Linux clock, then update diff --git a/trunk/arch/m68knommu/kernel/vmlinux.lds.S b/trunk/arch/m68knommu/kernel/vmlinux.lds.S index 58afa8be604e..ccd2ceb05cfb 100644 --- a/trunk/arch/m68knommu/kernel/vmlinux.lds.S +++ b/trunk/arch/m68knommu/kernel/vmlinux.lds.S @@ -140,7 +140,13 @@ SECTIONS { *(.init.setup) __setup_end = .; __initcall_start = .; - INITCALLS + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) __initcall_end = .; __con_initcall_start = .; *(.con_initcall.init) diff --git a/trunk/arch/m68knommu/platform/5307/ints.c b/trunk/arch/m68knommu/platform/5307/ints.c index a57239ec6c8c..b4b55093ae7e 100644 --- a/trunk/arch/m68knommu/platform/5307/ints.c +++ b/trunk/arch/m68knommu/platform/5307/ints.c @@ -33,7 +33,7 @@ /* * This table stores the address info for each vector handler. */ -struct irq_entry irq_list[SYS_IRQS]; +irq_handler_t irq_list[SYS_IRQS]; #define NUM_IRQ_NODES 16 static irq_node_t nodes[NUM_IRQ_NODES]; @@ -44,7 +44,7 @@ volatile unsigned int num_spurious; unsigned int local_bh_count[NR_CPUS]; unsigned int local_irq_count[NR_CPUS]; -static irqreturn_t default_irq_handler(int irq, void *ptr) +static irqreturn_t default_irq_handler(int irq, void *ptr, struct pt_regs *regs) { #if 1 printk(KERN_INFO "%s(%d): default irq handler vec=%d [0x%x]\n", @@ -70,7 +70,7 @@ void __init init_IRQ(void) for (i = 0; i < SYS_IRQS; i++) { if (mach_default_handler) - irq_list[i].handler = mach_default_handler; + irq_list[i].handler = (*mach_default_handler)[i]; else irq_list[i].handler = default_irq_handler; irq_list[i].flags = IRQ_FLG_STD; @@ -100,7 +100,7 @@ irq_node_t *new_irq_node(void) int request_irq( unsigned int irq, - irq_handler_t handler, + irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id) @@ -157,7 +157,7 @@ void free_irq(unsigned int irq, void *dev_id) } if (mach_default_handler) - irq_list[irq].handler = mach_default_handler; + irq_list[irq].handler = (*mach_default_handler)[irq]; else irq_list[irq].handler = default_irq_handler; irq_list[irq].flags = IRQ_FLG_STD; @@ -168,7 +168,8 @@ void free_irq(unsigned int irq, void *dev_id) EXPORT_SYMBOL(free_irq); -int sys_request_irq(unsigned int irq, irq_handler_t handler, +int sys_request_irq(unsigned int irq, + irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id) { if (irq > IRQ7) { @@ -210,7 +211,7 @@ void sys_free_irq(unsigned int irq, void *dev_id) printk(KERN_WARNING "%s: Removing probably wrong IRQ %d from %s\n", __FUNCTION__, irq, irq_list[irq].devname); - irq_list[irq].handler = mach_default_handler; + irq_list[irq].handler = (*mach_default_handler)[irq]; irq_list[irq].flags = 0; irq_list[irq].dev_id = NULL; irq_list[irq].devname = NULL; @@ -240,7 +241,7 @@ asmlinkage void process_int(unsigned long vec, struct pt_regs *fp) if (vec >= VEC_INT1 && vec <= VEC_INT7) { vec -= VEC_SPUR; kstat_cpu(0).irqs[vec]++; - irq_list[vec].handler(vec, irq_list[vec].dev_id); + irq_list[vec].handler(vec, irq_list[vec].dev_id, fp); } else { if (mach_process_int) mach_process_int(vec, fp); diff --git a/trunk/arch/mips/Kconfig b/trunk/arch/mips/Kconfig index 27f83e642968..8a49884bd5ec 100644 --- a/trunk/arch/mips/Kconfig +++ b/trunk/arch/mips/Kconfig @@ -266,8 +266,8 @@ config MIPS_MALTA select BOOT_ELF32 select HAVE_STD_PC_SERIAL_PORT select DMA_NONCOHERENT - select GENERIC_ISA_DMA select IRQ_CPU + select GENERIC_ISA_DMA select HW_HAS_PCI select I8259 select MIPS_BOARDS_GEN @@ -425,8 +425,9 @@ config MOMENCO_OCELOT_G select SWAP_IO_SPACE select SYS_HAS_CPU_RM7000 select SYS_SUPPORTS_32BIT_KERNEL - select SYS_SUPPORTS_64BIT_KERNEL if BROKEN + select SYS_SUPPORTS_64BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN + select ARCH_SPARSEMEM_ENABLE help The Ocelot is a MIPS-based Single Board Computer (SBC) made by Momentum Computer . @@ -534,7 +535,7 @@ config SGI_IP22 select HW_HAS_EISA select IP22_CPU_SCACHE select IRQ_CPU - select GENERIC_ISA_DMA_SUPPORT_BROKEN + select NO_ISA if ISA select SWAP_IO_SPACE select SYS_HAS_CPU_R4X00 select SYS_HAS_CPU_R5000 @@ -559,7 +560,6 @@ config SGI_IP27 select SYS_SUPPORTS_64BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN select SYS_SUPPORTS_NUMA - select SYS_SUPPORTS_SMP help This are the SGI Origin 200, Origin 2000 and Onyx 2 Graphics workstations. To compile a Linux kernel that runs on these, say Y @@ -766,23 +766,6 @@ config TOSHIBA_RBTX4938 endchoice -config KEXEC - bool "Kexec system call (EXPERIMENTAL)" - depends on EXPERIMENTAL - help - kexec is a system call that implements the ability to shutdown your - current kernel, and to start another kernel. It is like a reboot - but it is indepedent of the system firmware. And like a reboot - you can start any kernel with it, not just Linux. - - The name comes from the similiarity to the exec system call. - - It is an ongoing process to be certain the hardware in a machine - is properly shutdown, so do not be surprised if this code does not - initially work for you. It may help to enable device hotplugging - support. As of this writing the exact hardware interface is - strongly in flux, so no good recommendation can be made. - source "arch/mips/ddb5xxx/Kconfig" source "arch/mips/gt64120/ev64120/Kconfig" source "arch/mips/jazz/Kconfig" @@ -881,11 +864,8 @@ config MIPS_NILE4 config MIPS_DISABLE_OBSOLETE_IDE bool -config GENERIC_ISA_DMA_SUPPORT_BROKEN - bool - # -# Endianess selection. Sufficiently obscure so many users don't know what to +# Endianess selection. Suffiently obscure so many users don't know what to # answer,so we try hard to limit the available choices. Also the use of a # choice statement should be more obvious to the user. # @@ -894,7 +874,7 @@ choice help Some MIPS machines can be configured for either little or big endian byte order. These modes require different kernels and a different - Linux distribution. In general there is one preferred byteorder for a + Linux distribution. In general there is one prefered byteorder for a particular system but some systems are just as commonly used in the one or the other endianess. @@ -1030,6 +1010,11 @@ endchoice config ARC32 bool +config AU1X00_USB_DEVICE + bool + depends on MIPS_PB1500 || MIPS_PB1100 || MIPS_PB1000 + default n + config BOOT_ELF32 bool @@ -1480,8 +1465,10 @@ config MIPS_MT_DISABLED the option of an MT-enabled processor this option will be the only option in this menu. -config MIPS_MT_SMP - bool "Use 1 TC on each available VPE for SMP" +config MIPS_MT_SMTC + bool "SMTC: Use all TCs on all VPEs for SMP" + depends on CPU_MIPS32_R2 + #depends on CPU_MIPS64_R2 # once there is hardware ... depends on SYS_SUPPORTS_MULTITHREADING select CPU_MIPSR2_IRQ_VI select CPU_MIPSR2_SRS @@ -1489,13 +1476,11 @@ config MIPS_MT_SMP select SMP select SYS_SUPPORTS_SMP help - This is a kernel model which is also known a VSMP or lately - has been marketesed into SMVP. + This is a kernel model which is known a SMTC or lately has been + marketesed into SMVP. -config MIPS_MT_SMTC - bool "SMTC: Use all TCs on all VPEs for SMP" - depends on CPU_MIPS32_R2 - #depends on CPU_MIPS64_R2 # once there is hardware ... +config MIPS_MT_SMP + bool "Use 1 TC on each available VPE for SMP" depends on SYS_SUPPORTS_MULTITHREADING select CPU_MIPSR2_IRQ_VI select CPU_MIPSR2_SRS @@ -1503,8 +1488,8 @@ config MIPS_MT_SMTC select SMP select SYS_SUPPORTS_SMP help - This is a kernel model which is known a SMTC or lately has been - marketesed into SMVP. + This is a kernel model which is also known a VSMP or lately + has been marketesed into SMVP. config MIPS_VPE_LOADER bool "VPE loader support." @@ -1651,6 +1636,9 @@ config ARCH_DISCONTIGMEM_ENABLE or have huge holes in the physical address space for other reasons. See for more. +config ARCH_SPARSEMEM_ENABLE + bool + config ARCH_SPARSEMEM_ENABLE bool select SPARSEMEM_STATIC @@ -1707,7 +1695,6 @@ config NR_CPUS depends on SMP default "64" if SGI_IP27 default "2" - default "8" if MIPS_MT_SMTC help This allows you to specify the maximum number of CPUs which this kernel will support. The maximum supported value is 32 for 32-bit @@ -1855,11 +1842,13 @@ source "drivers/pci/Kconfig" config ISA bool +config NO_ISA + bool + config EISA bool "EISA support" depends on HW_HAS_EISA select ISA - select GENERIC_ISA_DMA ---help--- The Extended Industry Standard Architecture (EISA) bus was developed as an open alternative to the IBM MicroChannel bus. diff --git a/trunk/arch/mips/Makefile b/trunk/arch/mips/Makefile index 641aa30b3638..2124350ab94d 100644 --- a/trunk/arch/mips/Makefile +++ b/trunk/arch/mips/Makefile @@ -91,17 +91,8 @@ cflags-y += -ffreestanding # carefully avoid to add it redundantly because gcc 3.3/3.4 complains # when fed the toolchain default! # -# Certain gcc versions upto gcc 4.1.1 (probably 4.2-subversion as of -# 2006-10-10 don't properly change the the predefined symbols if -EB / -EL -# are used, so we kludge that here. A bug has been filed at -# http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29413. -# -undef-all += -UMIPSEB -U_MIPSEB -U__MIPSEB -U__MIPSEB__ -undef-all += -UMIPSEL -U_MIPSEL -U__MIPSEL -U__MIPSEL__ -predef-be += -DMIPSEB -D_MIPSEB -D__MIPSEB -D__MIPSEB__ -predef-le += -DMIPSEL -D_MIPSEL -D__MIPSEL -D__MIPSEL__ -cflags-$(CONFIG_CPU_BIG_ENDIAN) += $(shell $(CC) -dumpmachine |grep -q 'mips.*el-.*' && echo -EB $(undef-all) $(predef-be)) -cflags-$(CONFIG_CPU_LITTLE_ENDIAN) += $(shell $(CC) -dumpmachine |grep -q 'mips.*el-.*' || echo -EL $(undef-all) $(predef-le)) +cflags-$(CONFIG_CPU_BIG_ENDIAN) += $(shell $(CC) -dumpmachine |grep -q 'mips.*el-.*' && echo -EB -D__MIPSEB__) +cflags-$(CONFIG_CPU_LITTLE_ENDIAN) += $(shell $(CC) -dumpmachine |grep -q 'mips.*el-.*' || echo -EL -D__MIPSEL__) cflags-$(CONFIG_SB1XXX_CORELIS) += $(call cc-option,-mno-sched-prolog) \ -fno-omit-frame-pointer diff --git a/trunk/arch/mips/au1000/common/Makefile b/trunk/arch/mips/au1000/common/Makefile index 4c35525edb4f..bf682f50b859 100644 --- a/trunk/arch/mips/au1000/common/Makefile +++ b/trunk/arch/mips/au1000/common/Makefile @@ -10,5 +10,6 @@ obj-y += prom.o irq.o puts.o time.o reset.o \ au1xxx_irqmap.o clocks.o platform.o power.o setup.o \ sleeper.o cputable.o dma.o dbdma.o gpio.o +obj-$(CONFIG_AU1X00_USB_DEVICE) += usbdev.o obj-$(CONFIG_KGDB) += dbg_io.o obj-$(CONFIG_PCI) += pci.o diff --git a/trunk/arch/mips/au1000/common/dbdma.c b/trunk/arch/mips/au1000/common/dbdma.c index 626de44bd888..c4fae8ff4671 100644 --- a/trunk/arch/mips/au1000/common/dbdma.c +++ b/trunk/arch/mips/au1000/common/dbdma.c @@ -849,7 +849,7 @@ au1xxx_dbdma_chan_free(u32 chanid) EXPORT_SYMBOL(au1xxx_dbdma_chan_free); static irqreturn_t -dbdma_interrupt(int irq, void *dev_id) +dbdma_interrupt(int irq, void *dev_id, struct pt_regs *regs) { u32 intstat; u32 chan_index; diff --git a/trunk/arch/mips/au1000/common/dma.c b/trunk/arch/mips/au1000/common/dma.c index c78260d4e837..fb7c47c1585d 100644 --- a/trunk/arch/mips/au1000/common/dma.c +++ b/trunk/arch/mips/au1000/common/dma.c @@ -160,7 +160,7 @@ void dump_au1000_dma_channel(unsigned int dmanr) * Requests the DMA done IRQ if irqhandler != NULL. */ int request_au1000_dma(int dev_id, const char *dev_str, - irq_handler_t irqhandler, + irqreturn_t (*irqhandler)(int, void *, struct pt_regs *), unsigned long irqflags, void *irq_dev_id) { diff --git a/trunk/arch/mips/au1000/common/irq.c b/trunk/arch/mips/au1000/common/irq.c index 9cf7b6715836..316722ee8cf5 100644 --- a/trunk/arch/mips/au1000/common/irq.c +++ b/trunk/arch/mips/au1000/common/irq.c @@ -67,9 +67,10 @@ extern void set_debug_traps(void); extern irq_cpustat_t irq_stat [NR_CPUS]; -extern void mips_timer_interrupt(void); +extern void mips_timer_interrupt(struct pt_regs *regs); static void setup_local_irq(unsigned int irq, int type, int int_req); +static unsigned int startup_irq(unsigned int irq); static void end_irq(unsigned int irq_nr); static inline void mask_and_ack_level_irq(unsigned int irq_nr); static inline void mask_and_ack_rise_edge_irq(unsigned int irq_nr); @@ -80,9 +81,27 @@ inline void local_disable_irq(unsigned int irq_nr); void (*board_init_irq)(void); +#ifdef CONFIG_PM +extern irqreturn_t counter0_irq(int irq, void *dev_id, struct pt_regs *regs); +#endif + static DEFINE_SPINLOCK(irq_lock); +static unsigned int startup_irq(unsigned int irq_nr) +{ + local_enable_irq(irq_nr); + return 0; +} + + +static void shutdown_irq(unsigned int irq_nr) +{ + local_disable_irq(irq_nr); + return; +} + + inline void local_enable_irq(unsigned int irq_nr) { if (irq_nr > AU1000_LAST_INTC0_INT) { @@ -234,42 +253,46 @@ void restore_local_and_enable(int controller, unsigned long mask) static struct irq_chip rise_edge_irq_type = { .typename = "Au1000 Rise Edge", + .startup = startup_irq, + .shutdown = shutdown_irq, + .enable = local_enable_irq, + .disable = local_disable_irq, .ack = mask_and_ack_rise_edge_irq, - .mask = local_disable_irq, - .mask_ack = mask_and_ack_rise_edge_irq, - .unmask = local_enable_irq, .end = end_irq, }; static struct irq_chip fall_edge_irq_type = { .typename = "Au1000 Fall Edge", + .startup = startup_irq, + .shutdown = shutdown_irq, + .enable = local_enable_irq, + .disable = local_disable_irq, .ack = mask_and_ack_fall_edge_irq, - .mask = local_disable_irq, - .mask_ack = mask_and_ack_fall_edge_irq, - .unmask = local_enable_irq, .end = end_irq, }; static struct irq_chip either_edge_irq_type = { .typename = "Au1000 Rise or Fall Edge", + .startup = startup_irq, + .shutdown = shutdown_irq, + .enable = local_enable_irq, + .disable = local_disable_irq, .ack = mask_and_ack_either_edge_irq, - .mask = local_disable_irq, - .mask_ack = mask_and_ack_either_edge_irq, - .unmask = local_enable_irq, .end = end_irq, }; static struct irq_chip level_irq_type = { .typename = "Au1000 Level", + .startup = startup_irq, + .shutdown = shutdown_irq, + .enable = local_enable_irq, + .disable = local_disable_irq, .ack = mask_and_ack_level_irq, - .mask = local_disable_irq, - .mask_ack = mask_and_ack_level_irq, - .unmask = local_enable_irq, .end = end_irq, }; #ifdef CONFIG_PM -void startup_match20_interrupt(irq_handler_t handler) +void startup_match20_interrupt(irqreturn_t (*handler)(int, void *, struct pt_regs *)) { struct irq_desc *desc = &irq_desc[AU1000_TOY_MATCH2_INT]; @@ -309,31 +332,31 @@ static void setup_local_irq(unsigned int irq_nr, int type, int int_req) au_writel(1<<(irq_nr-32), IC1_CFG2CLR); au_writel(1<<(irq_nr-32), IC1_CFG1CLR); au_writel(1<<(irq_nr-32), IC1_CFG0SET); - set_irq_chip(irq_nr, &rise_edge_irq_type); + irq_desc[irq_nr].chip = &rise_edge_irq_type; break; case INTC_INT_FALL_EDGE: /* 0:1:0 */ au_writel(1<<(irq_nr-32), IC1_CFG2CLR); au_writel(1<<(irq_nr-32), IC1_CFG1SET); au_writel(1<<(irq_nr-32), IC1_CFG0CLR); - set_irq_chip(irq_nr, &fall_edge_irq_type); + irq_desc[irq_nr].chip = &fall_edge_irq_type; break; case INTC_INT_RISE_AND_FALL_EDGE: /* 0:1:1 */ au_writel(1<<(irq_nr-32), IC1_CFG2CLR); au_writel(1<<(irq_nr-32), IC1_CFG1SET); au_writel(1<<(irq_nr-32), IC1_CFG0SET); - set_irq_chip(irq_nr, &either_edge_irq_type); + irq_desc[irq_nr].chip = &either_edge_irq_type; break; case INTC_INT_HIGH_LEVEL: /* 1:0:1 */ au_writel(1<<(irq_nr-32), IC1_CFG2SET); au_writel(1<<(irq_nr-32), IC1_CFG1CLR); au_writel(1<<(irq_nr-32), IC1_CFG0SET); - set_irq_chip(irq_nr, &level_irq_type); + irq_desc[irq_nr].chip = &level_irq_type; break; case INTC_INT_LOW_LEVEL: /* 1:1:0 */ au_writel(1<<(irq_nr-32), IC1_CFG2SET); au_writel(1<<(irq_nr-32), IC1_CFG1SET); au_writel(1<<(irq_nr-32), IC1_CFG0CLR); - set_irq_chip(irq_nr, &level_irq_type); + irq_desc[irq_nr].chip = &level_irq_type; break; case INTC_INT_DISABLED: /* 0:0:0 */ au_writel(1<<(irq_nr-32), IC1_CFG0CLR); @@ -361,31 +384,31 @@ static void setup_local_irq(unsigned int irq_nr, int type, int int_req) au_writel(1< #include -extern char * prom_getcmdline(void); +extern char * __init prom_getcmdline(void); extern void __init board_setup(void); extern void au1000_restart(char *); extern void au1000_halt(void); diff --git a/trunk/arch/mips/au1000/common/time.c b/trunk/arch/mips/au1000/common/time.c index fa1c62f05515..0a067f3113a5 100644 --- a/trunk/arch/mips/au1000/common/time.c +++ b/trunk/arch/mips/au1000/common/time.c @@ -41,6 +41,7 @@ #include #include +#include #include #include #include @@ -53,12 +54,15 @@ static unsigned long r4k_cur; /* What counter should be at next timer irq */ int no_au1xxx_32khz; extern int allow_au1k_wait; /* default off for CP0 Counter */ +/* Cycle counter value at the previous timer interrupt.. */ +static unsigned int timerhi = 0, timerlo = 0; + #ifdef CONFIG_PM #if HZ < 100 || HZ > 1000 #error "unsupported HZ value! Must be in [100,1000]" #endif #define MATCH20_INC (328*100/HZ) /* magic number 328 is for HZ=100... */ -extern void startup_match20_interrupt(irq_handler_t handler); +extern void startup_match20_interrupt(irqreturn_t (*handler)(int, void *, struct pt_regs *)); static unsigned long last_pc0, last_match20; #endif @@ -75,10 +79,10 @@ static inline void ack_r4ktimer(unsigned long newval) * is provably more robust. */ unsigned long wtimer; - -void mips_timer_interrupt(void) +void mips_timer_interrupt(struct pt_regs *regs) { int irq = 63; + unsigned long count; irq_enter(); kstat_this_cpu.irqs[irq]++; @@ -87,10 +91,14 @@ void mips_timer_interrupt(void) goto null; do { + count = read_c0_count(); + timerhi += (count < timerlo); /* Wrap around */ + timerlo = count; + kstat_this_cpu.irqs[irq]++; do_timer(1); #ifndef CONFIG_SMP - update_process_times(user_mode(get_irq_regs())); + update_process_times(user_mode(regs)); #endif r4k_cur += r4k_offset; ack_r4ktimer(r4k_cur); @@ -107,7 +115,7 @@ void mips_timer_interrupt(void) } #ifdef CONFIG_PM -irqreturn_t counter0_irq(int irq, void *dev_id) +irqreturn_t counter0_irq(int irq, void *dev_id, struct pt_regs *regs) { unsigned long pc0; int time_elapsed; @@ -131,7 +139,7 @@ irqreturn_t counter0_irq(int irq, void *dev_id) while (time_elapsed > 0) { do_timer(1); #ifndef CONFIG_SMP - update_process_times(user_mode(get_irq_regs())); + update_process_times(user_mode(regs)); #endif time_elapsed -= MATCH20_INC; last_match20 += MATCH20_INC; @@ -150,7 +158,7 @@ irqreturn_t counter0_irq(int irq, void *dev_id) jiffie_drift -= 999; do_timer(1); /* increment jiffies by one */ #ifndef CONFIG_SMP - update_process_times(user_mode(get_irq_regs())); + update_process_times(user_mode(regs)); #endif } @@ -223,6 +231,7 @@ wakeup_counter0_set(int ticks) */ unsigned long cal_r4koff(void) { + unsigned long count; unsigned long cpu_speed; unsigned long flags; unsigned long counter; @@ -249,7 +258,7 @@ unsigned long cal_r4koff(void) #if defined(CONFIG_AU1000_USE32K) { - unsigned long start, end, count; + unsigned long start, end; start = au_readl(SYS_RTCREAD); start += 2; @@ -273,6 +282,7 @@ unsigned long cal_r4koff(void) #else cpu_speed = (au_readl(SYS_CPUPLL) & 0x0000003f) * AU1000_SRC_CLK; + count = cpu_speed / 2; #endif } else { @@ -281,15 +291,98 @@ unsigned long cal_r4koff(void) * NOTE: some old silicon doesn't allow reading the PLL. */ cpu_speed = (au_readl(SYS_CPUPLL) & 0x0000003f) * AU1000_SRC_CLK; + count = cpu_speed / 2; no_au1xxx_32khz = 1; } - mips_hpt_frequency = cpu_speed; + mips_hpt_frequency = count; // Equation: Baudrate = CPU / (SD * 2 * CLKDIV * 16) set_au1x00_uart_baud_base(cpu_speed / (2 * ((int)(au_readl(SYS_POWERCTRL)&0x03) + 2) * 16)); spin_unlock_irqrestore(&time_lock, flags); return (cpu_speed / HZ); } +/* This is for machines which generate the exact clock. */ +#define USECS_PER_JIFFY (1000000/HZ) +#define USECS_PER_JIFFY_FRAC (0x100000000LL*1000000/HZ&0xffffffff) + +static unsigned long +div64_32(unsigned long v1, unsigned long v2, unsigned long v3) +{ + unsigned long r0; + do_div64_32(r0, v1, v2, v3); + return r0; +} + +static unsigned long do_fast_cp0_gettimeoffset(void) +{ + u32 count; + unsigned long res, tmp; + unsigned long r0; + + /* Last jiffy when do_fast_gettimeoffset() was called. */ + static unsigned long last_jiffies=0; + unsigned long quotient; + + /* + * Cached "1/(clocks per usec)*2^32" value. + * It has to be recalculated once each jiffy. + */ + static unsigned long cached_quotient=0; + + tmp = jiffies; + + quotient = cached_quotient; + + if (tmp && last_jiffies != tmp) { + last_jiffies = tmp; + if (last_jiffies != 0) { + r0 = div64_32(timerhi, timerlo, tmp); + quotient = div64_32(USECS_PER_JIFFY, USECS_PER_JIFFY_FRAC, r0); + cached_quotient = quotient; + } + } + + /* Get last timer tick in absolute kernel time */ + count = read_c0_count(); + + /* .. relative to previous jiffy (32 bits is enough) */ + count -= timerlo; + + __asm__("multu\t%1,%2\n\t" + "mfhi\t%0" + : "=r" (res) + : "r" (count), "r" (quotient) + : "hi", "lo", GCC_REG_ACCUM); + + /* + * Due to possible jiffies inconsistencies, we need to check + * the result so that we'll get a timer that is monotonic. + */ + if (res >= USECS_PER_JIFFY) + res = USECS_PER_JIFFY-1; + + return res; +} + +#ifdef CONFIG_PM +static unsigned long do_fast_pm_gettimeoffset(void) +{ + unsigned long pc0; + unsigned long offset; + + pc0 = au_readl(SYS_TOYREAD); + au_sync(); + offset = pc0 - last_pc0; + if (offset > 2*MATCH20_INC) { + printk("huge offset %x, last_pc0 %x last_match20 %x pc0 %x\n", + (unsigned)offset, (unsigned)last_pc0, + (unsigned)last_match20, (unsigned)pc0); + } + offset = (unsigned long)((offset * 305) / 10); + return offset; +} +#endif + void __init plat_timer_setup(struct irqaction *irq) { unsigned int est_freq; @@ -327,6 +420,7 @@ void __init plat_timer_setup(struct irqaction *irq) unsigned int c0_status; printk("WARNING: no 32KHz clock found.\n"); + do_gettimeoffset = do_fast_cp0_gettimeoffset; /* Ensure we get CPO_COUNTER interrupts. */ @@ -351,11 +445,19 @@ void __init plat_timer_setup(struct irqaction *irq) while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20); startup_match20_interrupt(counter0_irq); + do_gettimeoffset = do_fast_pm_gettimeoffset; + /* We can use the real 'wait' instruction. */ allow_au1k_wait = 1; } +#else + /* We have to do this here instead of in timer_init because + * the generic code in arch/mips/kernel/time.c will write + * over our function pointer. + */ + do_gettimeoffset = do_fast_cp0_gettimeoffset; #endif } diff --git a/trunk/arch/mips/au1000/common/usbdev.c b/trunk/arch/mips/au1000/common/usbdev.c new file mode 100644 index 000000000000..63bcb3a95dc7 --- /dev/null +++ b/trunk/arch/mips/au1000/common/usbdev.c @@ -0,0 +1,1555 @@ +/* + * BRIEF MODULE DESCRIPTION + * Au1000 USB Device-Side (device layer) + * + * Copyright 2001-2002 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * stevel@mvista.com or source@mvista.com + * + * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define DEBUG +#include + +#include +#include +#include +#include +#include +#include +#include + +#ifdef DEBUG +#undef VDEBUG +#ifdef VDEBUG +#define vdbg(fmt, arg...) printk(KERN_DEBUG __FILE__ ": " fmt "\n" , ## arg) +#else +#define vdbg(fmt, arg...) do {} while (0) +#endif +#else +#define vdbg(fmt, arg...) do {} while (0) +#endif + +#define ALLOC_FLAGS (in_interrupt () ? GFP_ATOMIC : GFP_KERNEL) + +#define EP_FIFO_DEPTH 8 + +typedef enum { + SETUP_STAGE = 0, + DATA_STAGE, + STATUS_STAGE +} ep0_stage_t; + +typedef struct { + int read_fifo; + int write_fifo; + int ctrl_stat; + int read_fifo_status; + int write_fifo_status; +} endpoint_reg_t; + +typedef struct { + usbdev_pkt_t *head; + usbdev_pkt_t *tail; + int count; +} pkt_list_t; + +typedef struct { + int active; + struct usb_endpoint_descriptor *desc; + endpoint_reg_t *reg; + /* Only one of these are used, unless this is the control ep */ + pkt_list_t inlist; + pkt_list_t outlist; + unsigned int indma, outdma; /* DMA channel numbers for IN, OUT */ + /* following are extracted from endpoint descriptor for easy access */ + int max_pkt_size; + int type; + int direction; + /* WE assign endpoint addresses! */ + int address; + spinlock_t lock; +} endpoint_t; + + +static struct usb_dev { + endpoint_t ep[6]; + ep0_stage_t ep0_stage; + + struct usb_device_descriptor * dev_desc; + struct usb_interface_descriptor* if_desc; + struct usb_config_descriptor * conf_desc; + u8 * full_conf_desc; + struct usb_string_descriptor * str_desc[6]; + + /* callback to function layer */ + void (*func_cb)(usbdev_cb_type_t type, unsigned long arg, + void *cb_data); + void* cb_data; + + usbdev_state_t state; // device state + int suspended; // suspended flag + int address; // device address + int interface; + int num_ep; + u8 alternate_setting; + u8 configuration; // configuration value + int remote_wakeup_en; +} usbdev; + + +static endpoint_reg_t ep_reg[] = { + // FIFO's 0 and 1 are EP0 default control + {USBD_EP0RD, USBD_EP0WR, USBD_EP0CS, USBD_EP0RDSTAT, USBD_EP0WRSTAT }, + {0}, + // FIFO 2 is EP2, IN + { -1, USBD_EP2WR, USBD_EP2CS, -1, USBD_EP2WRSTAT }, + // FIFO 3 is EP3, IN + { -1, USBD_EP3WR, USBD_EP3CS, -1, USBD_EP3WRSTAT }, + // FIFO 4 is EP4, OUT + {USBD_EP4RD, -1, USBD_EP4CS, USBD_EP4RDSTAT, -1 }, + // FIFO 5 is EP5, OUT + {USBD_EP5RD, -1, USBD_EP5CS, USBD_EP5RDSTAT, -1 } +}; + +static struct { + unsigned int id; + const char *str; +} ep_dma_id[] = { + { DMA_ID_USBDEV_EP0_TX, "USBDev EP0 IN" }, + { DMA_ID_USBDEV_EP0_RX, "USBDev EP0 OUT" }, + { DMA_ID_USBDEV_EP2_TX, "USBDev EP2 IN" }, + { DMA_ID_USBDEV_EP3_TX, "USBDev EP3 IN" }, + { DMA_ID_USBDEV_EP4_RX, "USBDev EP4 OUT" }, + { DMA_ID_USBDEV_EP5_RX, "USBDev EP5 OUT" } +}; + +#define DIR_OUT 0 +#define DIR_IN (1<<3) + +#define CONTROL_EP USB_ENDPOINT_XFER_CONTROL +#define BULK_EP USB_ENDPOINT_XFER_BULK + +static inline endpoint_t * +epaddr_to_ep(struct usb_dev* dev, int ep_addr) +{ + if (ep_addr >= 0 && ep_addr < 2) + return &dev->ep[0]; + if (ep_addr < 6) + return &dev->ep[ep_addr]; + return NULL; +} + +static const char* std_req_name[] = { + "GET_STATUS", + "CLEAR_FEATURE", + "RESERVED", + "SET_FEATURE", + "RESERVED", + "SET_ADDRESS", + "GET_DESCRIPTOR", + "SET_DESCRIPTOR", + "GET_CONFIGURATION", + "SET_CONFIGURATION", + "GET_INTERFACE", + "SET_INTERFACE", + "SYNCH_FRAME" +}; + +static inline const char* +get_std_req_name(int req) +{ + return (req >= 0 && req <= 12) ? std_req_name[req] : "UNKNOWN"; +} + +#if 0 +static void +dump_setup(struct usb_ctrlrequest* s) +{ + dbg("%s: requesttype=%d", __FUNCTION__, s->requesttype); + dbg("%s: request=%d %s", __FUNCTION__, s->request, + get_std_req_name(s->request)); + dbg("%s: value=0x%04x", __FUNCTION__, s->wValue); + dbg("%s: index=%d", __FUNCTION__, s->index); + dbg("%s: length=%d", __FUNCTION__, s->length); +} +#endif + +static inline usbdev_pkt_t * +alloc_packet(endpoint_t * ep, int data_size, void* data) +{ + usbdev_pkt_t* pkt = kmalloc(sizeof(usbdev_pkt_t) + data_size, + ALLOC_FLAGS); + if (!pkt) + return NULL; + pkt->ep_addr = ep->address; + pkt->size = data_size; + pkt->status = 0; + pkt->next = NULL; + if (data) + memcpy(pkt->payload, data, data_size); + + return pkt; +} + + +/* + * Link a packet to the tail of the enpoint's packet list. + * EP spinlock must be held when calling. + */ +static void +link_tail(endpoint_t * ep, pkt_list_t * list, usbdev_pkt_t * pkt) +{ + if (!list->tail) { + list->head = list->tail = pkt; + list->count = 1; + } else { + list->tail->next = pkt; + list->tail = pkt; + list->count++; + } +} + +/* + * Unlink and return a packet from the head of the given packet + * list. It is the responsibility of the caller to free the packet. + * EP spinlock must be held when calling. + */ +static usbdev_pkt_t * +unlink_head(pkt_list_t * list) +{ + usbdev_pkt_t *pkt; + + pkt = list->head; + if (!pkt || !list->count) { + return NULL; + } + + list->head = pkt->next; + if (!list->head) { + list->head = list->tail = NULL; + list->count = 0; + } else + list->count--; + + return pkt; +} + +/* + * Create and attach a new packet to the tail of the enpoint's + * packet list. EP spinlock must be held when calling. + */ +static usbdev_pkt_t * +add_packet(endpoint_t * ep, pkt_list_t * list, int size) +{ + usbdev_pkt_t *pkt = alloc_packet(ep, size, NULL); + if (!pkt) + return NULL; + + link_tail(ep, list, pkt); + return pkt; +} + + +/* + * Unlink and free a packet from the head of the enpoint's + * packet list. EP spinlock must be held when calling. + */ +static inline void +free_packet(pkt_list_t * list) +{ + kfree(unlink_head(list)); +} + +/* EP spinlock must be held when calling. */ +static inline void +flush_pkt_list(pkt_list_t * list) +{ + while (list->count) + free_packet(list); +} + +/* EP spinlock must be held when calling */ +static inline void +flush_write_fifo(endpoint_t * ep) +{ + if (ep->reg->write_fifo_status >= 0) { + au_writel(USBDEV_FSTAT_FLUSH | USBDEV_FSTAT_UF | + USBDEV_FSTAT_OF, + ep->reg->write_fifo_status); + //udelay(100); + //au_writel(USBDEV_FSTAT_UF | USBDEV_FSTAT_OF, + // ep->reg->write_fifo_status); + } +} + +/* EP spinlock must be held when calling */ +static inline void +flush_read_fifo(endpoint_t * ep) +{ + if (ep->reg->read_fifo_status >= 0) { + au_writel(USBDEV_FSTAT_FLUSH | USBDEV_FSTAT_UF | + USBDEV_FSTAT_OF, + ep->reg->read_fifo_status); + //udelay(100); + //au_writel(USBDEV_FSTAT_UF | USBDEV_FSTAT_OF, + // ep->reg->read_fifo_status); + } +} + + +/* EP spinlock must be held when calling. */ +static void +endpoint_flush(endpoint_t * ep) +{ + // First, flush all packets + flush_pkt_list(&ep->inlist); + flush_pkt_list(&ep->outlist); + + // Now flush the endpoint's h/w FIFO(s) + flush_write_fifo(ep); + flush_read_fifo(ep); +} + +/* EP spinlock must be held when calling. */ +static void +endpoint_stall(endpoint_t * ep) +{ + u32 cs; + + warn("%s", __FUNCTION__); + + cs = au_readl(ep->reg->ctrl_stat) | USBDEV_CS_STALL; + au_writel(cs, ep->reg->ctrl_stat); +} + +/* EP spinlock must be held when calling. */ +static void +endpoint_unstall(endpoint_t * ep) +{ + u32 cs; + + warn("%s", __FUNCTION__); + + cs = au_readl(ep->reg->ctrl_stat) & ~USBDEV_CS_STALL; + au_writel(cs, ep->reg->ctrl_stat); +} + +static void +endpoint_reset_datatoggle(endpoint_t * ep) +{ + // FIXME: is this possible? +} + + +/* EP spinlock must be held when calling. */ +static int +endpoint_fifo_read(endpoint_t * ep) +{ + int read_count = 0; + u8 *bufptr; + usbdev_pkt_t *pkt = ep->outlist.tail; + + if (!pkt) + return -EINVAL; + + bufptr = &pkt->payload[pkt->size]; + while (au_readl(ep->reg->read_fifo_status) & USBDEV_FSTAT_FCNT_MASK) { + *bufptr++ = au_readl(ep->reg->read_fifo) & 0xff; + read_count++; + pkt->size++; + } + + return read_count; +} + +#if 0 +/* EP spinlock must be held when calling. */ +static int +endpoint_fifo_write(endpoint_t * ep, int index) +{ + int write_count = 0; + u8 *bufptr; + usbdev_pkt_t *pkt = ep->inlist.head; + + if (!pkt) + return -EINVAL; + + bufptr = &pkt->payload[index]; + while ((au_readl(ep->reg->write_fifo_status) & + USBDEV_FSTAT_FCNT_MASK) < EP_FIFO_DEPTH) { + if (bufptr < pkt->payload + pkt->size) { + au_writel(*bufptr++, ep->reg->write_fifo); + write_count++; + } else { + break; + } + } + + return write_count; +} +#endif + +/* + * This routine is called to restart transmission of a packet. + * The endpoint's TSIZE must be set to the new packet's size, + * and DMA to the write FIFO needs to be restarted. + * EP spinlock must be held when calling. + */ +static void +kickstart_send_packet(endpoint_t * ep) +{ + u32 cs; + usbdev_pkt_t *pkt = ep->inlist.head; + + vdbg("%s: ep%d, pkt=%p", __FUNCTION__, ep->address, pkt); + + if (!pkt) { + err("%s: head=NULL! list->count=%d", __FUNCTION__, + ep->inlist.count); + return; + } + + dma_cache_wback_inv((unsigned long)pkt->payload, pkt->size); + + /* + * make sure FIFO is empty + */ + flush_write_fifo(ep); + + cs = au_readl(ep->reg->ctrl_stat) & USBDEV_CS_STALL; + cs |= (pkt->size << USBDEV_CS_TSIZE_BIT); + au_writel(cs, ep->reg->ctrl_stat); + + if (get_dma_active_buffer(ep->indma) == 1) { + set_dma_count1(ep->indma, pkt->size); + set_dma_addr1(ep->indma, virt_to_phys(pkt->payload)); + enable_dma_buffer1(ep->indma); // reenable + } else { + set_dma_count0(ep->indma, pkt->size); + set_dma_addr0(ep->indma, virt_to_phys(pkt->payload)); + enable_dma_buffer0(ep->indma); // reenable + } + if (dma_halted(ep->indma)) + start_dma(ep->indma); +} + + +/* + * This routine is called when a packet in the inlist has been + * completed. Frees the completed packet and starts sending the + * next. EP spinlock must be held when calling. + */ +static usbdev_pkt_t * +send_packet_complete(endpoint_t * ep) +{ + usbdev_pkt_t *pkt = unlink_head(&ep->inlist); + + if (pkt) { + pkt->status = + (au_readl(ep->reg->ctrl_stat) & USBDEV_CS_NAK) ? + PKT_STATUS_NAK : PKT_STATUS_ACK; + + vdbg("%s: ep%d, %s pkt=%p, list count=%d", __FUNCTION__, + ep->address, (pkt->status & PKT_STATUS_NAK) ? + "NAK" : "ACK", pkt, ep->inlist.count); + } + + /* + * The write fifo should already be drained if things are + * working right, but flush it anyway just in case. + */ + flush_write_fifo(ep); + + // begin transmitting next packet in the inlist + if (ep->inlist.count) { + kickstart_send_packet(ep); + } + + return pkt; +} + +/* + * Add a new packet to the tail of the given ep's packet + * inlist. The transmit complete interrupt frees packets from + * the head of this list. EP spinlock must be held when calling. + */ +static int +send_packet(struct usb_dev* dev, usbdev_pkt_t *pkt, int async) +{ + pkt_list_t *list; + endpoint_t* ep; + + if (!pkt || !(ep = epaddr_to_ep(dev, pkt->ep_addr))) + return -EINVAL; + + if (!pkt->size) + return 0; + + list = &ep->inlist; + + if (!async && list->count) { + halt_dma(ep->indma); + flush_pkt_list(list); + } + + link_tail(ep, list, pkt); + + vdbg("%s: ep%d, pkt=%p, size=%d, list count=%d", __FUNCTION__, + ep->address, pkt, pkt->size, list->count); + + if (list->count == 1) { + /* + * if the packet count is one, it means the list was empty, + * and no more data will go out this ep until we kick-start + * it again. + */ + kickstart_send_packet(ep); + } + + return pkt->size; +} + +/* + * This routine is called to restart reception of a packet. + * EP spinlock must be held when calling. + */ +static void +kickstart_receive_packet(endpoint_t * ep) +{ + usbdev_pkt_t *pkt; + + // get and link a new packet for next reception + if (!(pkt = add_packet(ep, &ep->outlist, ep->max_pkt_size))) { + err("%s: could not alloc new packet", __FUNCTION__); + return; + } + + if (get_dma_active_buffer(ep->outdma) == 1) { + clear_dma_done1(ep->outdma); + set_dma_count1(ep->outdma, ep->max_pkt_size); + set_dma_count0(ep->outdma, 0); + set_dma_addr1(ep->outdma, virt_to_phys(pkt->payload)); + enable_dma_buffer1(ep->outdma); // reenable + } else { + clear_dma_done0(ep->outdma); + set_dma_count0(ep->outdma, ep->max_pkt_size); + set_dma_count1(ep->outdma, 0); + set_dma_addr0(ep->outdma, virt_to_phys(pkt->payload)); + enable_dma_buffer0(ep->outdma); // reenable + } + if (dma_halted(ep->outdma)) + start_dma(ep->outdma); +} + + +/* + * This routine is called when a packet in the outlist has been + * completed (received) and we need to prepare for a new packet + * to be received. Halts DMA and computes the packet size from the + * remaining DMA counter. Then prepares a new packet for reception + * and restarts DMA. FIXME: what if another packet comes in + * on top of the completed packet? Counter would be wrong. + * EP spinlock must be held when calling. + */ +static usbdev_pkt_t * +receive_packet_complete(endpoint_t * ep) +{ + usbdev_pkt_t *pkt = ep->outlist.tail; + u32 cs; + + halt_dma(ep->outdma); + + cs = au_readl(ep->reg->ctrl_stat); + + if (!pkt) + return NULL; + + pkt->size = ep->max_pkt_size - get_dma_residue(ep->outdma); + if (pkt->size) + dma_cache_inv((unsigned long)pkt->payload, pkt->size); + /* + * need to pull out any remaining bytes in the FIFO. + */ + endpoint_fifo_read(ep); + /* + * should be drained now, but flush anyway just in case. + */ + flush_read_fifo(ep); + + pkt->status = (cs & USBDEV_CS_NAK) ? PKT_STATUS_NAK : PKT_STATUS_ACK; + if (ep->address == 0 && (cs & USBDEV_CS_SU)) + pkt->status |= PKT_STATUS_SU; + + vdbg("%s: ep%d, %s pkt=%p, size=%d", __FUNCTION__, + ep->address, (pkt->status & PKT_STATUS_NAK) ? + "NAK" : "ACK", pkt, pkt->size); + + kickstart_receive_packet(ep); + + return pkt; +} + + +/* + **************************************************************************** + * Here starts the standard device request handlers. They are + * all called by do_setup() via a table of function pointers. + **************************************************************************** + */ + +static ep0_stage_t +do_get_status(struct usb_dev* dev, struct usb_ctrlrequest* setup) +{ + switch (setup->bRequestType) { + case 0x80: // Device + // FIXME: send device status + break; + case 0x81: // Interface + // FIXME: send interface status + break; + case 0x82: // End Point + // FIXME: send endpoint status + break; + default: + // Invalid Command + endpoint_stall(&dev->ep[0]); // Stall End Point 0 + break; + } + + return STATUS_STAGE; +} + +static ep0_stage_t +do_clear_feature(struct usb_dev* dev, struct usb_ctrlrequest* setup) +{ + switch (setup->bRequestType) { + case 0x00: // Device + if ((le16_to_cpu(setup->wValue) & 0xff) == 1) + dev->remote_wakeup_en = 0; + else + endpoint_stall(&dev->ep[0]); + break; + case 0x02: // End Point + if ((le16_to_cpu(setup->wValue) & 0xff) == 0) { + endpoint_t *ep = + epaddr_to_ep(dev, + le16_to_cpu(setup->wIndex) & 0xff); + + endpoint_unstall(ep); + endpoint_reset_datatoggle(ep); + } else + endpoint_stall(&dev->ep[0]); + break; + } + + return SETUP_STAGE; +} + +static ep0_stage_t +do_reserved(struct usb_dev* dev, struct usb_ctrlrequest* setup) +{ + // Invalid request, stall End Point 0 + endpoint_stall(&dev->ep[0]); + return SETUP_STAGE; +} + +static ep0_stage_t +do_set_feature(struct usb_dev* dev, struct usb_ctrlrequest* setup) +{ + switch (setup->bRequestType) { + case 0x00: // Device + if ((le16_to_cpu(setup->wValue) & 0xff) == 1) + dev->remote_wakeup_en = 1; + else + endpoint_stall(&dev->ep[0]); + break; + case 0x02: // End Point + if ((le16_to_cpu(setup->wValue) & 0xff) == 0) { + endpoint_t *ep = + epaddr_to_ep(dev, + le16_to_cpu(setup->wIndex) & 0xff); + + endpoint_stall(ep); + } else + endpoint_stall(&dev->ep[0]); + break; + } + + return SETUP_STAGE; +} + +static ep0_stage_t +do_set_address(struct usb_dev* dev, struct usb_ctrlrequest* setup) +{ + int new_state = dev->state; + int new_addr = le16_to_cpu(setup->wValue); + + dbg("%s: our address=%d", __FUNCTION__, new_addr); + + if (new_addr > 127) { + // usb spec doesn't tell us what to do, so just go to + // default state + new_state = DEFAULT; + dev->address = 0; + } else if (dev->address != new_addr) { + dev->address = new_addr; + new_state = ADDRESS; + } + + if (dev->state != new_state) { + dev->state = new_state; + /* inform function layer of usbdev state change */ + dev->func_cb(CB_NEW_STATE, dev->state, dev->cb_data); + } + + return SETUP_STAGE; +} + +static ep0_stage_t +do_get_descriptor(struct usb_dev* dev, struct usb_ctrlrequest* setup) +{ + int strnum, desc_len = le16_to_cpu(setup->wLength); + + switch (le16_to_cpu(setup->wValue) >> 8) { + case USB_DT_DEVICE: + // send device descriptor! + desc_len = desc_len > dev->dev_desc->bLength ? + dev->dev_desc->bLength : desc_len; + dbg("sending device desc, size=%d", desc_len); + send_packet(dev, alloc_packet(&dev->ep[0], desc_len, + dev->dev_desc), 0); + break; + case USB_DT_CONFIG: + // If the config descr index in low-byte of + // setup->wValue is valid, send config descr, + // otherwise stall ep0. + if ((le16_to_cpu(setup->wValue) & 0xff) == 0) { + // send config descriptor! + if (desc_len <= USB_DT_CONFIG_SIZE) { + dbg("sending partial config desc, size=%d", + desc_len); + send_packet(dev, + alloc_packet(&dev->ep[0], + desc_len, + dev->conf_desc), + 0); + } else { + int len = le16_to_cpu(dev->conf_desc->wTotalLength); + dbg("sending whole config desc," + " size=%d, our size=%d", desc_len, len); + desc_len = desc_len > len ? len : desc_len; + send_packet(dev, + alloc_packet(&dev->ep[0], + desc_len, + dev->full_conf_desc), + 0); + } + } else + endpoint_stall(&dev->ep[0]); + break; + case USB_DT_STRING: + // If the string descr index in low-byte of setup->wValue + // is valid, send string descr, otherwise stall ep0. + strnum = le16_to_cpu(setup->wValue) & 0xff; + if (strnum >= 0 && strnum < 6) { + struct usb_string_descriptor *desc = + dev->str_desc[strnum]; + desc_len = desc_len > desc->bLength ? + desc->bLength : desc_len; + dbg("sending string desc %d", strnum); + send_packet(dev, + alloc_packet(&dev->ep[0], desc_len, + desc), 0); + } else + endpoint_stall(&dev->ep[0]); + break; + default: + // Invalid request + err("invalid get desc=%d, stalled", + le16_to_cpu(setup->wValue) >> 8); + endpoint_stall(&dev->ep[0]); // Stall endpoint 0 + break; + } + + return STATUS_STAGE; +} + +static ep0_stage_t +do_set_descriptor(struct usb_dev* dev, struct usb_ctrlrequest* setup) +{ + // TODO: implement + // there will be an OUT data stage (the descriptor to set) + return DATA_STAGE; +} + +static ep0_stage_t +do_get_configuration(struct usb_dev* dev, struct usb_ctrlrequest* setup) +{ + // send dev->configuration + dbg("sending config"); + send_packet(dev, alloc_packet(&dev->ep[0], 1, &dev->configuration), + 0); + return STATUS_STAGE; +} + +static ep0_stage_t +do_set_configuration(struct usb_dev* dev, struct usb_ctrlrequest* setup) +{ + // set active config to low-byte of setup->wValue + dev->configuration = le16_to_cpu(setup->wValue) & 0xff; + dbg("set config, config=%d", dev->configuration); + if (!dev->configuration && dev->state > DEFAULT) { + dev->state = ADDRESS; + /* inform function layer of usbdev state change */ + dev->func_cb(CB_NEW_STATE, dev->state, dev->cb_data); + } else if (dev->configuration == 1) { + dev->state = CONFIGURED; + /* inform function layer of usbdev state change */ + dev->func_cb(CB_NEW_STATE, dev->state, dev->cb_data); + } else { + // FIXME: "respond with request error" - how? + } + + return SETUP_STAGE; +} + +static ep0_stage_t +do_get_interface(struct usb_dev* dev, struct usb_ctrlrequest* setup) +{ + // interface must be zero. + if ((le16_to_cpu(setup->wIndex) & 0xff) || dev->state == ADDRESS) { + // FIXME: respond with "request error". how? + } else if (dev->state == CONFIGURED) { + // send dev->alternate_setting + dbg("sending alt setting"); + send_packet(dev, alloc_packet(&dev->ep[0], 1, + &dev->alternate_setting), 0); + } + + return STATUS_STAGE; + +} + +static ep0_stage_t +do_set_interface(struct usb_dev* dev, struct usb_ctrlrequest* setup) +{ + if (dev->state == ADDRESS) { + // FIXME: respond with "request error". how? + } else if (dev->state == CONFIGURED) { + dev->interface = le16_to_cpu(setup->wIndex) & 0xff; + dev->alternate_setting = + le16_to_cpu(setup->wValue) & 0xff; + // interface and alternate_setting must be zero + if (dev->interface || dev->alternate_setting) { + // FIXME: respond with "request error". how? + } + } + + return SETUP_STAGE; +} + +static ep0_stage_t +do_synch_frame(struct usb_dev* dev, struct usb_ctrlrequest* setup) +{ + // TODO + return SETUP_STAGE; +} + +typedef ep0_stage_t (*req_method_t)(struct usb_dev* dev, + struct usb_ctrlrequest* setup); + + +/* Table of the standard device request handlers */ +static const req_method_t req_method[] = { + do_get_status, + do_clear_feature, + do_reserved, + do_set_feature, + do_reserved, + do_set_address, + do_get_descriptor, + do_set_descriptor, + do_get_configuration, + do_set_configuration, + do_get_interface, + do_set_interface, + do_synch_frame +}; + + +// SETUP packet request dispatcher +static void +do_setup (struct usb_dev* dev, struct usb_ctrlrequest* setup) +{ + req_method_t m; + + dbg("%s: req %d %s", __FUNCTION__, setup->bRequestType, + get_std_req_name(setup->bRequestType)); + + if ((setup->bRequestType & USB_TYPE_MASK) != USB_TYPE_STANDARD || + (setup->bRequestType & USB_RECIP_MASK) != USB_RECIP_DEVICE) { + err("%s: invalid requesttype 0x%02x", __FUNCTION__, + setup->bRequestType); + return; + } + + if ((setup->bRequestType & 0x80) == USB_DIR_OUT && setup->wLength) + dbg("%s: OUT phase! length=%d", __FUNCTION__, setup->wLength); + + if (setup->bRequestType < sizeof(req_method)/sizeof(req_method_t)) + m = req_method[setup->bRequestType]; + else + m = do_reserved; + + dev->ep0_stage = (*m)(dev, setup); +} + +/* + * A SETUP, DATA0, or DATA1 packet has been received + * on the default control endpoint's fifo. + */ +static void +process_ep0_receive (struct usb_dev* dev) +{ + endpoint_t *ep0 = &dev->ep[0]; + usbdev_pkt_t *pkt; + + spin_lock(&ep0->lock); + + // complete packet and prepare a new packet + pkt = receive_packet_complete(ep0); + if (!pkt) { + // FIXME: should put a warn/err here. + spin_unlock(&ep0->lock); + return; + } + + // unlink immediately from endpoint. + unlink_head(&ep0->outlist); + + // override current stage if h/w says it's a setup packet + if (pkt->status & PKT_STATUS_SU) + dev->ep0_stage = SETUP_STAGE; + + switch (dev->ep0_stage) { + case SETUP_STAGE: + vdbg("SU bit is %s in setup stage", + (pkt->status & PKT_STATUS_SU) ? "set" : "not set"); + + if (pkt->size == sizeof(struct usb_ctrlrequest)) { +#ifdef VDEBUG + if (pkt->status & PKT_STATUS_ACK) + vdbg("received SETUP"); + else + vdbg("received NAK SETUP"); +#endif + do_setup(dev, (struct usb_ctrlrequest*)pkt->payload); + } else + err("%s: wrong size SETUP received", __FUNCTION__); + break; + case DATA_STAGE: + /* + * this setup has an OUT data stage. Of the standard + * device requests, only set_descriptor has this stage, + * so this packet is that descriptor. TODO: drop it for + * now, set_descriptor not implemented. + * + * Need to place a byte in the write FIFO here, to prepare + * to send a zero-length DATA ack packet to the host in the + * STATUS stage. + */ + au_writel(0, ep0->reg->write_fifo); + dbg("received OUT stage DATAx on EP0, size=%d", pkt->size); + dev->ep0_stage = SETUP_STAGE; + break; + case STATUS_STAGE: + // this setup had an IN data stage, and host is ACK'ing + // the packet we sent during that stage. + if (pkt->size != 0) + warn("received non-zero ACK on EP0??"); +#ifdef VDEBUG + else + vdbg("received ACK on EP0"); +#endif + dev->ep0_stage = SETUP_STAGE; + break; + } + + spin_unlock(&ep0->lock); + // we're done processing the packet, free it + kfree(pkt); +} + + +/* + * A DATA0/1 packet has been received on one of the OUT endpoints (4 or 5) + */ +static void +process_ep_receive (struct usb_dev* dev, endpoint_t *ep) +{ + usbdev_pkt_t *pkt; + + spin_lock(&ep->lock); + pkt = receive_packet_complete(ep); + spin_unlock(&ep->lock); + + dev->func_cb(CB_PKT_COMPLETE, (unsigned long)pkt, dev->cb_data); +} + + + +/* This ISR handles the receive complete and suspend events */ +static void +req_sus_intr (int irq, void *dev_id, struct pt_regs *regs) +{ + struct usb_dev *dev = (struct usb_dev *) dev_id; + u32 status; + + status = au_readl(USBD_INTSTAT); + au_writel(status, USBD_INTSTAT); // ack'em + + if (status & (1<<0)) + process_ep0_receive(dev); + if (status & (1<<4)) + process_ep_receive(dev, &dev->ep[4]); + if (status & (1<<5)) + process_ep_receive(dev, &dev->ep[5]); +} + + +/* This ISR handles the DMA done events on EP0 */ +static void +dma_done_ep0_intr(int irq, void *dev_id, struct pt_regs *regs) +{ + struct usb_dev *dev = (struct usb_dev *) dev_id; + usbdev_pkt_t* pkt; + endpoint_t *ep0 = &dev->ep[0]; + u32 cs0, buff_done; + + spin_lock(&ep0->lock); + cs0 = au_readl(ep0->reg->ctrl_stat); + + // first check packet transmit done + if ((buff_done = get_dma_buffer_done(ep0->indma)) != 0) { + // transmitted a DATAx packet during DATA stage + // on control endpoint 0 + // clear DMA done bit + if (buff_done & DMA_D0) + clear_dma_done0(ep0->indma); + if (buff_done & DMA_D1) + clear_dma_done1(ep0->indma); + + pkt = send_packet_complete(ep0); + kfree(pkt); + } + + /* + * Now check packet receive done. Shouldn't get these, + * the receive packet complete intr should happen + * before the DMA done intr occurs. + */ + if ((buff_done = get_dma_buffer_done(ep0->outdma)) != 0) { + // clear DMA done bit + if (buff_done & DMA_D0) + clear_dma_done0(ep0->outdma); + if (buff_done & DMA_D1) + clear_dma_done1(ep0->outdma); + + //process_ep0_receive(dev); + } + + spin_unlock(&ep0->lock); +} + +/* This ISR handles the DMA done events on endpoints 2,3,4,5 */ +static void +dma_done_ep_intr(int irq, void *dev_id, struct pt_regs *regs) +{ + struct usb_dev *dev = (struct usb_dev *) dev_id; + int i; + + for (i = 2; i < 6; i++) { + u32 buff_done; + usbdev_pkt_t* pkt; + endpoint_t *ep = &dev->ep[i]; + + if (!ep->active) continue; + + spin_lock(&ep->lock); + + if (ep->direction == USB_DIR_IN) { + buff_done = get_dma_buffer_done(ep->indma); + if (buff_done != 0) { + // transmitted a DATAx pkt on the IN ep + // clear DMA done bit + if (buff_done & DMA_D0) + clear_dma_done0(ep->indma); + if (buff_done & DMA_D1) + clear_dma_done1(ep->indma); + + pkt = send_packet_complete(ep); + + spin_unlock(&ep->lock); + dev->func_cb(CB_PKT_COMPLETE, + (unsigned long)pkt, + dev->cb_data); + spin_lock(&ep->lock); + } + } else { + /* + * Check packet receive done (OUT ep). Shouldn't get + * these, the rx packet complete intr should happen + * before the DMA done intr occurs. + */ + buff_done = get_dma_buffer_done(ep->outdma); + if (buff_done != 0) { + // received a DATAx pkt on the OUT ep + // clear DMA done bit + if (buff_done & DMA_D0) + clear_dma_done0(ep->outdma); + if (buff_done & DMA_D1) + clear_dma_done1(ep->outdma); + + //process_ep_receive(dev, ep); + } + } + + spin_unlock(&ep->lock); + } +} + + +/*************************************************************************** + * Here begins the external interface functions + *************************************************************************** + */ + +/* + * allocate a new packet + */ +int +usbdev_alloc_packet(int ep_addr, int data_size, usbdev_pkt_t** pkt) +{ + endpoint_t * ep = epaddr_to_ep(&usbdev, ep_addr); + usbdev_pkt_t* lpkt = NULL; + + if (!ep || !ep->active || ep->address < 2) + return -ENODEV; + if (data_size > ep->max_pkt_size) + return -EINVAL; + + lpkt = *pkt = alloc_packet(ep, data_size, NULL); + if (!lpkt) + return -ENOMEM; + return 0; +} + + +/* + * packet send + */ +int +usbdev_send_packet(int ep_addr, usbdev_pkt_t * pkt) +{ + unsigned long flags; + int count; + endpoint_t * ep; + + if (!pkt || !(ep = epaddr_to_ep(&usbdev, pkt->ep_addr)) || + !ep->active || ep->address < 2) + return -ENODEV; + if (ep->direction != USB_DIR_IN) + return -EINVAL; + + spin_lock_irqsave(&ep->lock, flags); + count = send_packet(&usbdev, pkt, 1); + spin_unlock_irqrestore(&ep->lock, flags); + + return count; +} + +/* + * packet receive + */ +int +usbdev_receive_packet(int ep_addr, usbdev_pkt_t** pkt) +{ + unsigned long flags; + usbdev_pkt_t* lpkt = NULL; + endpoint_t *ep = epaddr_to_ep(&usbdev, ep_addr); + + if (!ep || !ep->active || ep->address < 2) + return -ENODEV; + if (ep->direction != USB_DIR_OUT) + return -EINVAL; + + spin_lock_irqsave(&ep->lock, flags); + if (ep->outlist.count > 1) + lpkt = unlink_head(&ep->outlist); + spin_unlock_irqrestore(&ep->lock, flags); + + if (!lpkt) { + /* no packet available */ + *pkt = NULL; + return -ENODATA; + } + + *pkt = lpkt; + + return lpkt->size; +} + + +/* + * return total queued byte count on the endpoint. + */ +int +usbdev_get_byte_count(int ep_addr) +{ + unsigned long flags; + pkt_list_t *list; + usbdev_pkt_t *scan; + int count = 0; + endpoint_t * ep = epaddr_to_ep(&usbdev, ep_addr); + + if (!ep || !ep->active || ep->address < 2) + return -ENODEV; + + if (ep->direction == USB_DIR_IN) { + list = &ep->inlist; + + spin_lock_irqsave(&ep->lock, flags); + for (scan = list->head; scan; scan = scan->next) + count += scan->size; + spin_unlock_irqrestore(&ep->lock, flags); + } else { + list = &ep->outlist; + + spin_lock_irqsave(&ep->lock, flags); + if (list->count > 1) { + for (scan = list->head; scan != list->tail; + scan = scan->next) + count += scan->size; + } + spin_unlock_irqrestore(&ep->lock, flags); + } + + return count; +} + + +void +usbdev_exit(void) +{ + endpoint_t *ep; + int i; + + au_writel(0, USBD_INTEN); // disable usb dev ints + au_writel(0, USBD_ENABLE); // disable usb dev + + free_irq(AU1000_USB_DEV_REQ_INT, &usbdev); + free_irq(AU1000_USB_DEV_SUS_INT, &usbdev); + + // free all control endpoint resources + ep = &usbdev.ep[0]; + free_au1000_dma(ep->indma); + free_au1000_dma(ep->outdma); + endpoint_flush(ep); + + // free ep resources + for (i = 2; i < 6; i++) { + ep = &usbdev.ep[i]; + if (!ep->active) continue; + + if (ep->direction == USB_DIR_IN) { + free_au1000_dma(ep->indma); + } else { + free_au1000_dma(ep->outdma); + } + endpoint_flush(ep); + } + + kfree(usbdev.full_conf_desc); +} + +int +usbdev_init(struct usb_device_descriptor* dev_desc, + struct usb_config_descriptor* config_desc, + struct usb_interface_descriptor* if_desc, + struct usb_endpoint_descriptor* ep_desc, + struct usb_string_descriptor* str_desc[], + void (*cb)(usbdev_cb_type_t, unsigned long, void *), + void* cb_data) +{ + endpoint_t *ep0; + int i, ret=0; + u8* fcd; + + if (dev_desc->bNumConfigurations > 1 || + config_desc->bNumInterfaces > 1 || + if_desc->bNumEndpoints > 4) { + err("Only one config, one i/f, and no more " + "than 4 ep's allowed"); + ret = -EINVAL; + goto out; + } + + if (!cb) { + err("Function-layer callback required"); + ret = -EINVAL; + goto out; + } + + if (dev_desc->bMaxPacketSize0 != USBDEV_EP0_MAX_PACKET_SIZE) { + warn("EP0 Max Packet size must be %d", + USBDEV_EP0_MAX_PACKET_SIZE); + dev_desc->bMaxPacketSize0 = USBDEV_EP0_MAX_PACKET_SIZE; + } + + memset(&usbdev, 0, sizeof(struct usb_dev)); + + usbdev.state = DEFAULT; + usbdev.dev_desc = dev_desc; + usbdev.if_desc = if_desc; + usbdev.conf_desc = config_desc; + for (i=0; i<6; i++) + usbdev.str_desc[i] = str_desc[i]; + usbdev.func_cb = cb; + usbdev.cb_data = cb_data; + + /* Initialize default control endpoint */ + ep0 = &usbdev.ep[0]; + ep0->active = 1; + ep0->type = CONTROL_EP; + ep0->max_pkt_size = USBDEV_EP0_MAX_PACKET_SIZE; + spin_lock_init(&ep0->lock); + ep0->desc = NULL; // ep0 has no descriptor + ep0->address = 0; + ep0->direction = 0; + ep0->reg = &ep_reg[0]; + + /* Initialize the other requested endpoints */ + for (i = 0; i < if_desc->bNumEndpoints; i++) { + struct usb_endpoint_descriptor* epd = &ep_desc[i]; + endpoint_t *ep; + + if ((epd->bEndpointAddress & 0x80) == USB_DIR_IN) { + ep = &usbdev.ep[2]; + ep->address = 2; + if (ep->active) { + ep = &usbdev.ep[3]; + ep->address = 3; + if (ep->active) { + err("too many IN ep's requested"); + ret = -ENODEV; + goto out; + } + } + } else { + ep = &usbdev.ep[4]; + ep->address = 4; + if (ep->active) { + ep = &usbdev.ep[5]; + ep->address = 5; + if (ep->active) { + err("too many OUT ep's requested"); + ret = -ENODEV; + goto out; + } + } + } + + ep->active = 1; + epd->bEndpointAddress &= ~0x0f; + epd->bEndpointAddress |= (u8)ep->address; + ep->direction = epd->bEndpointAddress & 0x80; + ep->type = epd->bmAttributes & 0x03; + ep->max_pkt_size = le16_to_cpu(epd->wMaxPacketSize); + spin_lock_init(&ep->lock); + ep->desc = epd; + ep->reg = &ep_reg[ep->address]; + } + + /* + * initialize the full config descriptor + */ + usbdev.full_conf_desc = fcd = kmalloc(le16_to_cpu(config_desc->wTotalLength), + ALLOC_FLAGS); + if (!fcd) { + err("failed to alloc full config descriptor"); + ret = -ENOMEM; + goto out; + } + + memcpy(fcd, config_desc, USB_DT_CONFIG_SIZE); + fcd += USB_DT_CONFIG_SIZE; + memcpy(fcd, if_desc, USB_DT_INTERFACE_SIZE); + fcd += USB_DT_INTERFACE_SIZE; + for (i = 0; i < if_desc->bNumEndpoints; i++) { + memcpy(fcd, &ep_desc[i], USB_DT_ENDPOINT_SIZE); + fcd += USB_DT_ENDPOINT_SIZE; + } + + /* Now we're ready to enable the controller */ + au_writel(0x0002, USBD_ENABLE); + udelay(100); + au_writel(0x0003, USBD_ENABLE); + udelay(100); + + /* build and send config table based on ep descriptors */ + for (i = 0; i < 6; i++) { + endpoint_t *ep; + if (i == 1) + continue; // skip dummy ep + ep = &usbdev.ep[i]; + if (ep->active) { + au_writel((ep->address << 4) | 0x04, USBD_CONFIG); + au_writel(((ep->max_pkt_size & 0x380) >> 7) | + (ep->direction >> 4) | (ep->type << 4), + USBD_CONFIG); + au_writel((ep->max_pkt_size & 0x7f) << 1, USBD_CONFIG); + au_writel(0x00, USBD_CONFIG); + au_writel(ep->address, USBD_CONFIG); + } else { + u8 dir = (i==2 || i==3) ? DIR_IN : DIR_OUT; + au_writel((i << 4) | 0x04, USBD_CONFIG); + au_writel(((16 & 0x380) >> 7) | dir | + (BULK_EP << 4), USBD_CONFIG); + au_writel((16 & 0x7f) << 1, USBD_CONFIG); + au_writel(0x00, USBD_CONFIG); + au_writel(i, USBD_CONFIG); + } + } + + /* + * Enable Receive FIFO Complete interrupts only. Transmit + * complete is being handled by the DMA done interrupts. + */ + au_writel(0x31, USBD_INTEN); + + /* + * Controller is now enabled, request DMA and IRQ + * resources. + */ + + /* request the USB device transfer complete interrupt */ + if (request_irq(AU1000_USB_DEV_REQ_INT, req_sus_intr, IRQF_DISABLED, + "USBdev req", &usbdev)) { + err("Can't get device request intr"); + ret = -ENXIO; + goto out; + } + /* request the USB device suspend interrupt */ + if (request_irq(AU1000_USB_DEV_SUS_INT, req_sus_intr, IRQF_DISABLED, + "USBdev sus", &usbdev)) { + err("Can't get device suspend intr"); + ret = -ENXIO; + goto out; + } + + /* Request EP0 DMA and IRQ */ + if ((ep0->indma = request_au1000_dma(ep_dma_id[0].id, + ep_dma_id[0].str, + dma_done_ep0_intr, + IRQF_DISABLED, + &usbdev)) < 0) { + err("Can't get %s DMA", ep_dma_id[0].str); + ret = -ENXIO; + goto out; + } + if ((ep0->outdma = request_au1000_dma(ep_dma_id[1].id, + ep_dma_id[1].str, + NULL, 0, NULL)) < 0) { + err("Can't get %s DMA", ep_dma_id[1].str); + ret = -ENXIO; + goto out; + } + + // Flush the ep0 buffers and FIFOs + endpoint_flush(ep0); + // start packet reception on ep0 + kickstart_receive_packet(ep0); + + /* Request DMA and IRQ for the other endpoints */ + for (i = 2; i < 6; i++) { + endpoint_t *ep = &usbdev.ep[i]; + if (!ep->active) + continue; + + // Flush the endpoint buffers and FIFOs + endpoint_flush(ep); + + if (ep->direction == USB_DIR_IN) { + ep->indma = + request_au1000_dma(ep_dma_id[ep->address].id, + ep_dma_id[ep->address].str, + dma_done_ep_intr, + IRQF_DISABLED, + &usbdev); + if (ep->indma < 0) { + err("Can't get %s DMA", + ep_dma_id[ep->address].str); + ret = -ENXIO; + goto out; + } + } else { + ep->outdma = + request_au1000_dma(ep_dma_id[ep->address].id, + ep_dma_id[ep->address].str, + NULL, 0, NULL); + if (ep->outdma < 0) { + err("Can't get %s DMA", + ep_dma_id[ep->address].str); + ret = -ENXIO; + goto out; + } + + // start packet reception on OUT endpoint + kickstart_receive_packet(ep); + } + } + + out: + if (ret) + usbdev_exit(); + return ret; +} + +EXPORT_SYMBOL(usbdev_init); +EXPORT_SYMBOL(usbdev_exit); +EXPORT_SYMBOL(usbdev_alloc_packet); +EXPORT_SYMBOL(usbdev_receive_packet); +EXPORT_SYMBOL(usbdev_send_packet); +EXPORT_SYMBOL(usbdev_get_byte_count); diff --git a/trunk/arch/mips/au1000/db1x00/board_setup.c b/trunk/arch/mips/au1000/db1x00/board_setup.c index 8b08edb977be..7a79293f8527 100644 --- a/trunk/arch/mips/au1000/db1x00/board_setup.c +++ b/trunk/arch/mips/au1000/db1x00/board_setup.c @@ -58,6 +58,11 @@ void __init board_setup(void) pin_func = 0; /* not valid for 1550 */ +#ifdef CONFIG_AU1X00_USB_DEVICE + // 2nd USB port is USB device + pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000); + au_writel(pin_func, SYS_PINFUNC); +#endif #if defined(CONFIG_IRDA) && (defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1100)) /* set IRFIRSEL instead of GPIO15 */ diff --git a/trunk/arch/mips/au1000/mtx-1/board_setup.c b/trunk/arch/mips/au1000/mtx-1/board_setup.c index 13f9bf5f91a6..e917e54fc683 100644 --- a/trunk/arch/mips/au1000/mtx-1/board_setup.c +++ b/trunk/arch/mips/au1000/mtx-1/board_setup.c @@ -51,11 +51,15 @@ void board_reset (void) void __init board_setup(void) { -#ifdef CONFIG_USB_OHCI +#if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE) +#ifdef CONFIG_AU1X00_USB_DEVICE + // 2nd USB port is USB device + au_writel(au_readl(SYS_PINFUNC) & (u32)(~0x8000), SYS_PINFUNC); +#endif // enable USB power switch au_writel( au_readl(GPIO2_DIR) | 0x10, GPIO2_DIR ); au_writel( 0x100000, GPIO2_OUTPUT ); -#endif // defined (CONFIG_USB_OHCI) +#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE) #ifdef CONFIG_PCI #if defined(__MIPSEB__) diff --git a/trunk/arch/mips/au1000/pb1000/board_setup.c b/trunk/arch/mips/au1000/pb1000/board_setup.c index 824cfafaff92..1cf18e16ab54 100644 --- a/trunk/arch/mips/au1000/pb1000/board_setup.c +++ b/trunk/arch/mips/au1000/pb1000/board_setup.c @@ -54,7 +54,7 @@ void __init board_setup(void) au_writel(0, SYS_PINSTATERD); udelay(100); -#ifdef CONFIG_USB_OHCI +#if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE) /* zero and disable FREQ2 */ sys_freqctrl = au_readl(SYS_FREQCTRL0); sys_freqctrl &= ~0xFFF00000; @@ -104,19 +104,23 @@ void __init board_setup(void) */ #ifdef CONFIG_USB_OHCI sys_clksrc |= ((4<<12) | (0<<11) | (0<<10)); +#endif +#ifdef CONFIG_AU1X00_USB_DEVICE + sys_clksrc |= ((4<<7) | (0<<6) | (0<<5)); #endif au_writel(sys_clksrc, SYS_CLKSRC); // configure pins GPIO[14:9] as GPIO pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8080); +#ifndef CONFIG_AU1X00_USB_DEVICE // 2nd USB port is USB host pin_func |= 0x8000; - +#endif au_writel(pin_func, SYS_PINFUNC); au_writel(0x2800, SYS_TRIOUTCLR); au_writel(0x0030, SYS_OUTPUTCLR); -#endif // defined (CONFIG_USB_OHCI) +#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE) // make gpio 15 an input (for interrupt line) pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x100); diff --git a/trunk/arch/mips/au1000/pb1100/board_setup.c b/trunk/arch/mips/au1000/pb1100/board_setup.c index 2d1533f116c0..db27b9331ff3 100644 --- a/trunk/arch/mips/au1000/pb1100/board_setup.c +++ b/trunk/arch/mips/au1000/pb1100/board_setup.c @@ -55,7 +55,7 @@ void __init board_setup(void) au_writel(0, SYS_PININPUTEN); udelay(100); -#ifdef CONFIG_USB_OHCI +#if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE) // configure pins GPIO[14:9] as GPIO pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x80); @@ -92,10 +92,12 @@ void __init board_setup(void) // get USB Functionality pin state (device vs host drive pins) pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000); +#ifndef CONFIG_AU1X00_USB_DEVICE // 2nd USB port is USB host pin_func |= 0x8000; +#endif au_writel(pin_func, SYS_PINFUNC); -#endif // defined (CONFIG_USB_OHCI) +#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE) /* Enable sys bus clock divider when IDLE state or no bus activity. */ au_writel(au_readl(SYS_POWERCTRL) | (0x3 << 5), SYS_POWERCTRL); diff --git a/trunk/arch/mips/au1000/pb1200/board_setup.c b/trunk/arch/mips/au1000/pb1200/board_setup.c index 043302b7fe58..8b953b9fc25c 100644 --- a/trunk/arch/mips/au1000/pb1200/board_setup.c +++ b/trunk/arch/mips/au1000/pb1200/board_setup.c @@ -55,7 +55,7 @@ #endif extern void _board_init_irq(void); -extern void (*board_init_irq)(void); +extern void (*board_init_irq)(void); void board_reset (void) { @@ -151,7 +151,11 @@ void __init board_setup(void) #endif /* Setup Pb1200 External Interrupt Controller */ - board_init_irq = _board_init_irq; + { + extern void (*board_init_irq)(void); + extern void _board_init_irq(void); + board_init_irq = _board_init_irq; + } } int diff --git a/trunk/arch/mips/au1000/pb1200/irqmap.c b/trunk/arch/mips/au1000/pb1200/irqmap.c index 91983ba407c4..f66779f0d4cd 100644 --- a/trunk/arch/mips/au1000/pb1200/irqmap.c +++ b/trunk/arch/mips/au1000/pb1200/irqmap.c @@ -65,7 +65,7 @@ int __initdata au1xxx_nr_irqs = ARRAY_SIZE(au1xxx_irq_map); */ static volatile int pb1200_cascade_en=0; -irqreturn_t pb1200_cascade_handler( int irq, void *dev_id) +irqreturn_t pb1200_cascade_handler( int irq, void *dev_id, struct pt_regs *regs) { unsigned short bisr = bcsr->int_status; int extirq_nr = 0; @@ -76,9 +76,8 @@ irqreturn_t pb1200_cascade_handler( int irq, void *dev_id) { extirq_nr = (PB1200_INT_BEGIN-1) + au_ffs(bisr); /* Ack and dispatch IRQ */ - do_IRQ(extirq_nr); + do_IRQ(extirq_nr,regs); } - return IRQ_RETVAL(1); } diff --git a/trunk/arch/mips/au1000/pb1500/board_setup.c b/trunk/arch/mips/au1000/pb1500/board_setup.c index 0ffdb4fd575b..1a9a293de6ab 100644 --- a/trunk/arch/mips/au1000/pb1500/board_setup.c +++ b/trunk/arch/mips/au1000/pb1500/board_setup.c @@ -56,7 +56,7 @@ void __init board_setup(void) au_writel(0, SYS_PINSTATERD); udelay(100); -#ifdef CONFIG_USB_OHCI +#if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE) /* GPIO201 is input for PCMCIA card detect */ /* GPIO203 is input for PCMCIA interrupt request */ @@ -87,15 +87,20 @@ void __init board_setup(void) */ #ifdef CONFIG_USB_OHCI sys_clksrc |= ((4<<12) | (0<<11) | (0<<10)); +#endif +#ifdef CONFIG_AU1X00_USB_DEVICE + sys_clksrc |= ((4<<7) | (0<<6) | (0<<5)); #endif au_writel(sys_clksrc, SYS_CLKSRC); pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000); +#ifndef CONFIG_AU1X00_USB_DEVICE // 2nd USB port is USB host pin_func |= 0x8000; +#endif au_writel(pin_func, SYS_PINFUNC); -#endif // defined (CONFIG_USB_OHCI) +#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE) diff --git a/trunk/arch/mips/basler/excite/excite_dbg_io.c b/trunk/arch/mips/basler/excite/excite_dbg_io.c index d289e3a868cf..c04505afa47f 100644 --- a/trunk/arch/mips/basler/excite/excite_dbg_io.c +++ b/trunk/arch/mips/basler/excite/excite_dbg_io.c @@ -112,7 +112,7 @@ int putDebugChar(int data) } /* KGDB interrupt handler */ -asmlinkage void excite_kgdb_inthdl(void) +asmlinkage void excite_kgdb_inthdl(struct pt_regs *regs) { if (unlikely( ((titan_readl(UAIIR) & 0x7) == 4) diff --git a/trunk/arch/mips/basler/excite/excite_iodev.c b/trunk/arch/mips/basler/excite/excite_iodev.c index 6af0b21ebc32..10bbb8cfb964 100644 --- a/trunk/arch/mips/basler/excite/excite_iodev.c +++ b/trunk/arch/mips/basler/excite/excite_iodev.c @@ -38,7 +38,7 @@ static int iodev_open(struct inode *, struct file *); static int iodev_release(struct inode *, struct file *); static ssize_t iodev_read(struct file *, char __user *, size_t s, loff_t *); static unsigned int iodev_poll(struct file *, struct poll_table_struct *); -static irqreturn_t iodev_irqhdl(int, void *); +static irqreturn_t iodev_irqhdl(int, void *, struct pt_regs *); @@ -108,12 +108,16 @@ static int __exit iodev_remove(struct device *dev) return misc_deregister(&miscdev); } + + static int iodev_open(struct inode *i, struct file *f) { return request_irq(iodev_irq, iodev_irqhdl, IRQF_DISABLED, iodev_name, &miscdev); } + + static int iodev_release(struct inode *i, struct file *f) { free_irq(iodev_irq, &miscdev); @@ -144,13 +148,17 @@ static unsigned int iodev_poll(struct file *f, struct poll_table_struct *p) return POLLOUT | POLLWRNORM; } -static irqreturn_t iodev_irqhdl(int irq, void *ctxt) + + + +static irqreturn_t iodev_irqhdl(int irq, void *ctxt, struct pt_regs *regs) { wake_up(&wq); - return IRQ_HANDLED; } + + static int __init iodev_init_module(void) { return driver_register(&iodev_driver); diff --git a/trunk/arch/mips/basler/excite/excite_irq.c b/trunk/arch/mips/basler/excite/excite_irq.c index 2e2061a286c5..511ad8730f54 100644 --- a/trunk/arch/mips/basler/excite/excite_irq.c +++ b/trunk/arch/mips/basler/excite/excite_irq.c @@ -56,7 +56,7 @@ void __init arch_init_irq(void) #endif } -asmlinkage void plat_irq_dispatch(void) +asmlinkage void plat_irq_dispatch(struct pt_regs *regs) { const u32 interrupts = read_c0_cause() >> 8, @@ -67,7 +67,7 @@ asmlinkage void plat_irq_dispatch(void) /* process timer interrupt */ if (pending & (1 << TIMER_IRQ)) { - do_IRQ(TIMER_IRQ); + do_IRQ(TIMER_IRQ, regs); return; } @@ -80,7 +80,7 @@ asmlinkage void plat_irq_dispatch(void) #else if (pending & (1 << USB_IRQ)) { #endif - do_IRQ(USB_IRQ); + do_IRQ(USB_IRQ, regs); return; } @@ -91,9 +91,9 @@ asmlinkage void plat_irq_dispatch(void) if ((pending & (1 << TITAN_IRQ)) && msgint) { ocd_writel(msgint, INTP0Clear0 + (TITAN_MSGINT / 0x20 * 0x10)); #if defined(CONFIG_KGDB) - excite_kgdb_inthdl(); + excite_kgdb_inthdl(regs); #endif - do_IRQ(TITAN_IRQ); + do_IRQ(TITAN_IRQ, regs); return; } @@ -102,7 +102,7 @@ asmlinkage void plat_irq_dispatch(void) msgintmask = ocd_readl(INTP0Mask0 + (FPGA0_MSGINT / 0x20 * 0x10)); msgint = msgintflags & msgintmask & (0x1 << (FPGA0_MSGINT % 0x20)); if ((pending & (1 << FPGA0_IRQ)) && msgint) { - do_IRQ(FPGA0_IRQ); + do_IRQ(FPGA0_IRQ, regs); return; } @@ -111,7 +111,7 @@ asmlinkage void plat_irq_dispatch(void) msgintmask = ocd_readl(INTP0Mask0 + (FPGA1_MSGINT / 0x20 * 0x10)); msgint = msgintflags & msgintmask & (0x1 << (FPGA1_MSGINT % 0x20)); if ((pending & (1 << FPGA1_IRQ)) && msgint) { - do_IRQ(FPGA1_IRQ); + do_IRQ(FPGA1_IRQ, regs); return; } @@ -120,10 +120,10 @@ asmlinkage void plat_irq_dispatch(void) msgintmask = ocd_readl(INTP0Mask0 + (PHY_MSGINT / 0x20 * 0x10)); msgint = msgintflags & msgintmask & (0x1 << (PHY_MSGINT % 0x20)); if ((pending & (1 << PHY_IRQ)) && msgint) { - do_IRQ(PHY_IRQ); + do_IRQ(PHY_IRQ, regs); return; } /* Process spurious interrupts */ - spurious_interrupt(); + spurious_interrupt(regs); } diff --git a/trunk/arch/mips/cobalt/irq.c b/trunk/arch/mips/cobalt/irq.c index 4c46f0e73783..0b75f4fb7195 100644 --- a/trunk/arch/mips/cobalt/irq.c +++ b/trunk/arch/mips/cobalt/irq.c @@ -16,6 +16,7 @@ #include #include #include +#include #include @@ -41,54 +42,70 @@ * 15 - IDE1 */ -static inline void galileo_irq(void) +static inline void galileo_irq(struct pt_regs *regs) { unsigned int mask, pending, devfn; - mask = GT_READ(GT_INTRMASK_OFS); - pending = GT_READ(GT_INTRCAUSE_OFS) & mask; - - if (pending & GT_INTR_T0EXP_MSK) { - GT_WRITE(GT_INTRCAUSE_OFS, ~GT_INTR_T0EXP_MSK); - do_IRQ(COBALT_GALILEO_IRQ); - } else if (pending & GT_INTR_RETRYCTR0_MSK) { - devfn = GT_READ(GT_PCI0_CFGADDR_OFS) >> 8; - GT_WRITE(GT_INTRCAUSE_OFS, ~GT_INTR_RETRYCTR0_MSK); - printk(KERN_WARNING - "Galileo: PCI retry count exceeded (%02x.%u)\n", - PCI_SLOT(devfn), PCI_FUNC(devfn)); + mask = GALILEO_INL(GT_INTRMASK_OFS); + pending = GALILEO_INL(GT_INTRCAUSE_OFS) & mask; + + if (pending & GALILEO_INTR_T0EXP) { + + GALILEO_OUTL(~GALILEO_INTR_T0EXP, GT_INTRCAUSE_OFS); + do_IRQ(COBALT_GALILEO_IRQ, regs); + + } else if (pending & GALILEO_INTR_RETRY_CTR) { + + devfn = GALILEO_INL(GT_PCI0_CFGADDR_OFS) >> 8; + GALILEO_OUTL(~GALILEO_INTR_RETRY_CTR, GT_INTRCAUSE_OFS); + printk(KERN_WARNING "Galileo: PCI retry count exceeded (%02x.%u)\n", + PCI_SLOT(devfn), PCI_FUNC(devfn)); + } else { - GT_WRITE(GT_INTRMASK_OFS, mask & ~pending); - printk(KERN_WARNING - "Galileo: masking unexpected interrupt %08x\n", pending); + + GALILEO_OUTL(mask & ~pending, GT_INTRMASK_OFS); + printk(KERN_WARNING "Galileo: masking unexpected interrupt %08x\n", pending); } } -static inline void via_pic_irq(void) +static inline void via_pic_irq(struct pt_regs *regs) { int irq; irq = i8259_irq(); if (irq >= 0) - do_IRQ(irq); + do_IRQ(irq, regs); } -asmlinkage void plat_irq_dispatch(void) +asmlinkage void plat_irq_dispatch(struct pt_regs *regs) { - unsigned pending = read_c0_status() & read_c0_cause(); - - if (pending & CAUSEF_IP2) /* COBALT_GALILEO_IRQ (18) */ - galileo_irq(); - else if (pending & CAUSEF_IP6) /* COBALT_VIA_IRQ (22) */ - via_pic_irq(); - else if (pending & CAUSEF_IP3) /* COBALT_ETH0_IRQ (19) */ - do_IRQ(COBALT_CPU_IRQ + 3); - else if (pending & CAUSEF_IP4) /* COBALT_ETH1_IRQ (20) */ - do_IRQ(COBALT_CPU_IRQ + 4); - else if (pending & CAUSEF_IP5) /* COBALT_SERIAL_IRQ (21) */ - do_IRQ(COBALT_CPU_IRQ + 5); - else if (pending & CAUSEF_IP7) /* IRQ 23 */ - do_IRQ(COBALT_CPU_IRQ + 7); + unsigned pending; + + pending = read_c0_status() & read_c0_cause(); + + if (pending & CAUSEF_IP2) /* COBALT_GALILEO_IRQ (18) */ + + galileo_irq(regs); + + else if (pending & CAUSEF_IP6) /* COBALT_VIA_IRQ (22) */ + + via_pic_irq(regs); + + else if (pending & CAUSEF_IP3) /* COBALT_ETH0_IRQ (19) */ + + do_IRQ(COBALT_CPU_IRQ + 3, regs); + + else if (pending & CAUSEF_IP4) /* COBALT_ETH1_IRQ (20) */ + + do_IRQ(COBALT_CPU_IRQ + 4, regs); + + else if (pending & CAUSEF_IP5) /* COBALT_SERIAL_IRQ (21) */ + + do_IRQ(COBALT_CPU_IRQ + 5, regs); + + else if (pending & CAUSEF_IP7) /* IRQ 23 */ + + do_IRQ(COBALT_CPU_IRQ + 7, regs); } static struct irqaction irq_via = { @@ -101,7 +118,7 @@ void __init arch_init_irq(void) * Mask all Galileo interrupts. The Galileo * handler is set in cobalt_timer_setup() */ - GT_WRITE(GT_INTRMASK_OFS, 0); + GALILEO_OUTL(0, GT_INTRMASK_OFS); init_i8259_irqs(); /* 0 ... 15 */ mips_cpu_irq_init(COBALT_CPU_IRQ); /* 16 ... 23 */ diff --git a/trunk/arch/mips/cobalt/setup.c b/trunk/arch/mips/cobalt/setup.c index e8f0f20b852d..0b347cffc768 100644 --- a/trunk/arch/mips/cobalt/setup.c +++ b/trunk/arch/mips/cobalt/setup.c @@ -50,24 +50,24 @@ const char *get_system_type(void) void __init plat_timer_setup(struct irqaction *irq) { - /* Load timer value for HZ (TCLK is 50MHz) */ - GT_WRITE(GT_TC0_OFS, 50*1000*1000 / HZ); + /* Load timer value for 1KHz (TCLK is 50MHz) */ + GALILEO_OUTL(50*1000*1000 / 1000, GT_TC0_OFS); /* Enable timer */ - GT_WRITE(GT_TC_CONTROL_OFS, GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK); + GALILEO_OUTL(GALILEO_ENTC0 | GALILEO_SELTC0, GT_TC_CONTROL_OFS); /* Register interrupt */ setup_irq(COBALT_GALILEO_IRQ, irq); /* Enable interrupt */ - GT_WRITE(GT_INTRMASK_OFS, GT_INTR_T0EXP_MSK | GT_READ(GT_INTRMASK_OFS)); + GALILEO_OUTL(GALILEO_INTR_T0EXP | GALILEO_INL(GT_INTRMASK_OFS), GT_INTRMASK_OFS); } extern struct pci_ops gt64111_pci_ops; static struct resource cobalt_mem_resource = { - .start = GT_DEF_PCI0_MEM0_BASE, - .end = GT_DEF_PCI0_MEM0_BASE + GT_DEF_PCI0_MEM0_SIZE - 1, + .start = GT64111_MEM_BASE, + .end = GT64111_MEM_END, .name = "PCI memory", .flags = IORESOURCE_MEM }; @@ -115,7 +115,7 @@ static struct pci_controller cobalt_pci_controller = { .mem_resource = &cobalt_mem_resource, .mem_offset = 0, .io_resource = &cobalt_io_resource, - .io_offset = 0 - GT_DEF_PCI0_IO_BASE, + .io_offset = 0 - GT64111_IO_BASE }; void __init plat_mem_setup(void) @@ -128,7 +128,7 @@ void __init plat_mem_setup(void) _machine_halt = cobalt_machine_halt; pm_power_off = cobalt_machine_power_off; - set_io_port_base(CKSEG1ADDR(GT_DEF_PCI0_IO_BASE)); + set_io_port_base(CKSEG1ADDR(GT64111_IO_BASE)); /* I/O port resource must include UART and LCD/buttons */ ioport_resource.end = 0x0fffffff; @@ -139,7 +139,7 @@ void __init plat_mem_setup(void) /* Read the cobalt id register out of the PCI config space */ PCI_CFG_SET(devfn, (VIA_COBALT_BRD_ID_REG & ~0x3)); - cobalt_board_id = GT_READ(GT_PCI0_CFGDATA_OFS); + cobalt_board_id = GALILEO_INL(GT_PCI0_CFGDATA_OFS); cobalt_board_id >>= ((VIA_COBALT_BRD_ID_REG & 3) * 8); cobalt_board_id = VIA_COBALT_BRD_REG_to_ID(cobalt_board_id); diff --git a/trunk/arch/mips/configs/bigsur_defconfig b/trunk/arch/mips/configs/bigsur_defconfig index ba3bf733d27d..c6a015940b41 100644 --- a/trunk/arch/mips/configs/bigsur_defconfig +++ b/trunk/arch/mips/configs/bigsur_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.19-rc1 -# Wed Oct 11 01:41:41 2006 +# Linux kernel version: 2.6.18-rc1 +# Thu Jul 6 10:02:58 2006 # CONFIG_MIPS=y @@ -25,6 +25,8 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set @@ -81,7 +83,6 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_TIME=y CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y CONFIG_DMA_COHERENT=y CONFIG_CPU_BIG_ENDIAN=y @@ -131,8 +132,8 @@ CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_SIBYTE_DMA_PAGEOPS is not set CONFIG_MIPS_MT_DISABLED=y -# CONFIG_MIPS_MT_SMP is not set # CONFIG_MIPS_MT_SMTC is not set +# CONFIG_MIPS_MT_SMP is not set # CONFIG_MIPS_VPE_LOADER is not set CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_SYNC=y @@ -184,11 +185,9 @@ CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set +CONFIG_SYSCTL=y # CONFIG_AUDIT is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y @@ -196,9 +195,7 @@ CONFIG_IKCONFIG_PROC=y # CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_SYSCTL=y CONFIG_EMBEDDED=y -# CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set @@ -207,12 +204,12 @@ CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y +CONFIG_RT_MUTEXES=y CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_SHMEM=y CONFIG_SLAB=y CONFIG_VM_EVENT_COUNTERS=y -CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 # CONFIG_SLOB is not set @@ -231,7 +228,6 @@ CONFIG_STOP_MACHINE=y # # Block layer # -CONFIG_BLOCK=y # CONFIG_BLK_DEV_IO_TRACE is not set # @@ -253,17 +249,18 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_DOMAINS=y -# CONFIG_PCI_MULTITHREAD_PROBE is not set CONFIG_PCI_DEBUG=y CONFIG_MMU=y # # PCCARD (PCMCIA/CardBus) support # +# CONFIG_PCCARD is not set # # PCI Hotplug Support # +# CONFIG_HOTPLUG_PCI is not set # # Executable file formats @@ -274,7 +271,7 @@ CONFIG_BINFMT_ELF=y CONFIG_MIPS32_COMPAT=y CONFIG_COMPAT=y CONFIG_MIPS32_O32=y -CONFIG_MIPS32_N32=y +# CONFIG_MIPS32_N32 is not set CONFIG_BINFMT_ELF32=y # @@ -291,7 +288,6 @@ CONFIG_PACKET_MMAP=y CONFIG_UNIX=y CONFIG_XFRM=y CONFIG_XFRM_USER=m -# CONFIG_XFRM_SUB_POLICY is not set CONFIG_NET_KEY=y CONFIG_INET=y # CONFIG_IP_MULTICAST is not set @@ -312,12 +308,10 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_INET_TUNNEL is not set CONFIG_INET_XFRM_MODE_TRANSPORT=m CONFIG_INET_XFRM_MODE_TUNNEL=m -CONFIG_INET_XFRM_MODE_BEET=y CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" +CONFIG_TCP_CONG_BIC=y # CONFIG_IPV6 is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set @@ -347,6 +341,7 @@ CONFIG_NETWORK_SECMARK=y # CONFIG_ATALK is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set @@ -373,6 +368,7 @@ CONFIG_NETWORK_SECMARK=y # CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set # CONFIG_DEBUG_DRIVER is not set # CONFIG_SYS_HYPERVISOR is not set @@ -408,7 +404,7 @@ CONFIG_BLK_DEV_LOOP=m CONFIG_BLK_DEV_NBD=m # CONFIG_BLK_DEV_SX8 is not set # CONFIG_BLK_DEV_RAM is not set -CONFIG_BLK_DEV_INITRD=y +# CONFIG_BLK_DEV_INITRD is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set @@ -416,7 +412,6 @@ CONFIG_BLK_DEV_INITRD=y # ATA/ATAPI/MFM/RLL support # CONFIG_IDE=y -CONFIG_IDE_MAX_HWIFS=4 CONFIG_BLK_DEV_IDE=y # @@ -434,40 +429,10 @@ CONFIG_BLK_DEV_IDEFLOPPY=y # IDE chipset support/bugfixes # CONFIG_IDE_GENERIC=y -CONFIG_BLK_DEV_IDEPCI=y -# CONFIG_IDEPCI_SHARE_IRQ is not set -# CONFIG_BLK_DEV_OFFBOARD is not set -CONFIG_BLK_DEV_GENERIC=y -# CONFIG_BLK_DEV_OPTI621 is not set -CONFIG_BLK_DEV_IDEDMA_PCI=y -# CONFIG_BLK_DEV_IDEDMA_FORCED is not set -# CONFIG_IDEDMA_PCI_AUTO is not set -# CONFIG_BLK_DEV_AEC62XX is not set -# CONFIG_BLK_DEV_ALI15X3 is not set -# CONFIG_BLK_DEV_AMD74XX is not set -CONFIG_BLK_DEV_CMD64X=y -# CONFIG_BLK_DEV_TRIFLEX is not set -# CONFIG_BLK_DEV_CY82C693 is not set -# CONFIG_BLK_DEV_CS5520 is not set -# CONFIG_BLK_DEV_CS5530 is not set -# CONFIG_BLK_DEV_HPT34X is not set -# CONFIG_BLK_DEV_HPT366 is not set -# CONFIG_BLK_DEV_JMICRON is not set -# CONFIG_BLK_DEV_SC1200 is not set -# CONFIG_BLK_DEV_PIIX is not set -# CONFIG_BLK_DEV_IT821X is not set -# CONFIG_BLK_DEV_NS87415 is not set -# CONFIG_BLK_DEV_PDC202XX_OLD is not set -# CONFIG_BLK_DEV_PDC202XX_NEW is not set -# CONFIG_BLK_DEV_SVWKS is not set -# CONFIG_BLK_DEV_SIIMAGE is not set -# CONFIG_BLK_DEV_SLC90E66 is not set -# CONFIG_BLK_DEV_TRM290 is not set -# CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_BLK_DEV_IDEPCI is not set # CONFIG_BLK_DEV_IDE_SWARM is not set # CONFIG_IDE_ARM is not set -CONFIG_BLK_DEV_IDEDMA=y -# CONFIG_IDEDMA_IVB is not set +# CONFIG_BLK_DEV_IDEDMA is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_BLK_DEV_HD is not set @@ -476,12 +441,6 @@ CONFIG_BLK_DEV_IDEDMA=y # # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set -# CONFIG_SCSI_NETLINK is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# -# CONFIG_ATA is not set # # Multi-device support (RAID and LVM) @@ -557,7 +516,6 @@ CONFIG_NET_SB1250_MAC=y # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_BNX2 is not set -# CONFIG_QLA3XXX is not set # # Ethernet (10000 Mbit) @@ -692,6 +650,7 @@ CONFIG_I2C_CHARDEV=y # CONFIG_I2C_ALGOBIT is not set # CONFIG_I2C_ALGOPCF is not set # CONFIG_I2C_ALGOPCA is not set +CONFIG_I2C_ALGO_SIBYTE=y # # I2C Hardware Bus support @@ -753,12 +712,12 @@ CONFIG_I2C_DEBUG_CHIP=y # # Misc devices # -# CONFIG_TIFM_CORE is not set # # Multimedia devices # # CONFIG_VIDEO_DEV is not set +CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices @@ -770,7 +729,6 @@ CONFIG_I2C_DEBUG_CHIP=y # # CONFIG_FIRMWARE_EDID is not set # CONFIG_FB is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -853,7 +811,6 @@ CONFIG_FS_MBCACHE=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set @@ -883,10 +840,8 @@ CONFIG_DNOTIFY=y # CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y -CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set @@ -896,7 +851,6 @@ CONFIG_RAMFS=y # # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set -# CONFIG_ECRYPT_FS is not set # CONFIG_HFS_FS is not set # CONFIG_HFSPLUS_FS is not set # CONFIG_BEFS_FS is not set @@ -927,6 +881,7 @@ CONFIG_SUNRPC=y # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set # CONFIG_CIFS is not set +# CONFIG_CIFS_DEBUG2 is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set @@ -943,10 +898,6 @@ CONFIG_MSDOS_PARTITION=y # # CONFIG_NLS is not set -# -# Distributed Lock Manager -# - # # Profiling support # @@ -956,8 +907,7 @@ CONFIG_MSDOS_PARTITION=y # Kernel hacking # CONFIG_TRACE_IRQFLAGS_SUPPORT=y -# CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_MUST_CHECK=y +CONFIG_PRINTK_TIME=y CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_KERNEL=y @@ -970,15 +920,12 @@ CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_DEBUG_SPINLOCK is not set CONFIG_DEBUG_MUTEXES=y # CONFIG_DEBUG_RWSEMS is not set -# CONFIG_DEBUG_LOCK_ALLOC is not set -# CONFIG_PROVE_LOCKING is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_INFO is not set # CONFIG_DEBUG_FS is not set # CONFIG_DEBUG_VM is not set -# CONFIG_DEBUG_LIST is not set CONFIG_FORCED_INLINING=y # CONFIG_RCU_TORTURE_TEST is not set CONFIG_CROSSCOMPILE=y @@ -999,10 +946,6 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y # Cryptographic options # CONFIG_CRYPTO=y -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_BLKCIPHER=m -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_MANAGER=m CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_NULL=y CONFIG_CRYPTO_MD4=y @@ -1012,12 +955,9 @@ CONFIG_CRYPTO_SHA256=y CONFIG_CRYPTO_SHA512=y CONFIG_CRYPTO_WP512=m CONFIG_CRYPTO_TGR192=m -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_CBC=m CONFIG_CRYPTO_DES=y CONFIG_CRYPTO_BLOWFISH=y CONFIG_CRYPTO_TWOFISH=y -CONFIG_CRYPTO_TWOFISH_COMMON=y CONFIG_CRYPTO_SERPENT=y CONFIG_CRYPTO_AES=m # CONFIG_CRYPTO_CAST5 is not set diff --git a/trunk/arch/mips/configs/jazz_defconfig b/trunk/arch/mips/configs/jazz_defconfig deleted file mode 100644 index 382083ebea0a..000000000000 --- a/trunk/arch/mips/configs/jazz_defconfig +++ /dev/null @@ -1,1404 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.19-rc1 -# Sun Oct 8 19:03:07 2006 -# -CONFIG_MIPS=y - -# -# Machine selection -# -# CONFIG_MIPS_MTX1 is not set -# CONFIG_MIPS_BOSPORUS is not set -# CONFIG_MIPS_PB1000 is not set -# CONFIG_MIPS_PB1100 is not set -# CONFIG_MIPS_PB1500 is not set -# CONFIG_MIPS_PB1550 is not set -# CONFIG_MIPS_PB1200 is not set -# CONFIG_MIPS_DB1000 is not set -# CONFIG_MIPS_DB1100 is not set -# CONFIG_MIPS_DB1500 is not set -# CONFIG_MIPS_DB1550 is not set -# CONFIG_MIPS_DB1200 is not set -# CONFIG_MIPS_MIRAGE is not set -# CONFIG_BASLER_EXCITE is not set -# CONFIG_MIPS_COBALT is not set -# CONFIG_MACH_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set -CONFIG_MACH_JAZZ=y -# CONFIG_LASAT is not set -# CONFIG_MIPS_ATLAS is not set -# CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set -# CONFIG_WR_PPMC is not set -# CONFIG_MIPS_SIM is not set -# CONFIG_MOMENCO_JAGUAR_ATX is not set -# CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_3 is not set -# CONFIG_MOMENCO_OCELOT_C is not set -# CONFIG_MOMENCO_OCELOT_G is not set -# CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_V2PCI is not set -# CONFIG_PNX8550_JBS is not set -# CONFIG_DDB5477 is not set -# CONFIG_MACH_VR41XX is not set -# CONFIG_PMC_YOSEMITE is not set -# CONFIG_QEMU is not set -# CONFIG_MARKEINS is not set -# CONFIG_SGI_IP22 is not set -# CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set -# CONFIG_SIBYTE_BIGSUR is not set -# CONFIG_SIBYTE_SWARM is not set -# CONFIG_SIBYTE_SENTOSA is not set -# CONFIG_SIBYTE_RHONE is not set -# CONFIG_SIBYTE_CARMEL is not set -# CONFIG_SIBYTE_PTSWARM is not set -# CONFIG_SIBYTE_LITTLESUR is not set -# CONFIG_SIBYTE_CRHINE is not set -# CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM200_PCI is not set -# CONFIG_TOSHIBA_JMR3927 is not set -# CONFIG_TOSHIBA_RBTX4927 is not set -# CONFIG_TOSHIBA_RBTX4938 is not set -# CONFIG_ACER_PICA_61 is not set -# CONFIG_MIPS_MAGNUM_4000 is not set -CONFIG_OLIVETTI_M700=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_TIME=y -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -CONFIG_ARC=y -CONFIG_ARCH_MAY_HAVE_PC_FDC=y -CONFIG_DMA_NONCOHERENT=y -CONFIG_DMA_NEED_PCI_MAP_STATE=y -CONFIG_GENERIC_ISA_DMA=y -CONFIG_I8259=y -# CONFIG_CPU_BIG_ENDIAN is not set -CONFIG_CPU_LITTLE_ENDIAN=y -CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y -CONFIG_ARC32=y -CONFIG_MIPS_L1_CACHE_SHIFT=5 -CONFIG_ARC_MEMORY=y -CONFIG_ARC_PROMLIB=y - -# -# CPU selection -# -# CONFIG_CPU_MIPS32_R1 is not set -# CONFIG_CPU_MIPS32_R2 is not set -# CONFIG_CPU_MIPS64_R1 is not set -# CONFIG_CPU_MIPS64_R2 is not set -# CONFIG_CPU_R3000 is not set -# CONFIG_CPU_TX39XX is not set -# CONFIG_CPU_VR41XX is not set -# CONFIG_CPU_R4300 is not set -CONFIG_CPU_R4X00=y -# CONFIG_CPU_TX49XX is not set -# CONFIG_CPU_R5000 is not set -# CONFIG_CPU_R5432 is not set -# CONFIG_CPU_R6000 is not set -# CONFIG_CPU_NEVADA is not set -# CONFIG_CPU_R8000 is not set -# CONFIG_CPU_R10000 is not set -# CONFIG_CPU_RM7000 is not set -# CONFIG_CPU_RM9000 is not set -# CONFIG_CPU_SB1 is not set -CONFIG_SYS_HAS_CPU_R4X00=y -CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y -CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y -CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y -CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y - -# -# Kernel type -# -CONFIG_32BIT=y -# CONFIG_64BIT is not set -CONFIG_PAGE_SIZE_4KB=y -# CONFIG_PAGE_SIZE_8KB is not set -# CONFIG_PAGE_SIZE_16KB is not set -# CONFIG_PAGE_SIZE_64KB is not set -CONFIG_MIPS_MT_DISABLED=y -# CONFIG_MIPS_MT_SMP is not set -# CONFIG_MIPS_MT_SMTC is not set -# CONFIG_MIPS_VPE_LOADER is not set -# CONFIG_64BIT_PHYS_ADDR is not set -CONFIG_CPU_HAS_LLSC=y -CONFIG_CPU_HAS_SYNC=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_ARCH_FLATMEM_ENABLE=y -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set -# CONFIG_HZ_48 is not set -CONFIG_HZ_100=y -# CONFIG_HZ_128 is not set -# CONFIG_HZ_250 is not set -# CONFIG_HZ_256 is not set -# CONFIG_HZ_1000 is not set -# CONFIG_HZ_1024 is not set -CONFIG_SYS_SUPPORTS_100HZ=y -CONFIG_HZ=100 -# CONFIG_PREEMPT_NONE is not set -CONFIG_PREEMPT_VOLUNTARY=y -# CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set -CONFIG_POSIX_MQUEUE=y -CONFIG_BSD_PROCESS_ACCT=y -# CONFIG_BSD_PROCESS_ACCT_V3 is not set -# CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set -# CONFIG_AUDIT is not set -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_RELAY=y -CONFIG_INITRAMFS_SOURCE="" -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_SYSCTL=y -CONFIG_EMBEDDED=y -# CONFIG_SYSCTL_SYSCALL is not set -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -CONFIG_SHMEM=y -CONFIG_SLAB=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set - -# -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set -CONFIG_MODVERSIONS=y -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y - -# -# Block layer -# -CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" - -# -# Bus options (PCI, PCMCIA, EISA, ISA, TC) -# -CONFIG_ISA=y -CONFIG_MMU=y -CONFIG_I8253=y - -# -# PCCARD (PCMCIA/CardBus) support -# -# CONFIG_PCCARD is not set - -# -# PCI Hotplug Support -# - -# -# Executable file formats -# -CONFIG_BINFMT_ELF=y -CONFIG_BINFMT_MISC=m -CONFIG_TRAD_SIGNALS=y - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -# CONFIG_NETDEBUG is not set -CONFIG_PACKET=m -CONFIG_PACKET_MMAP=y -CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -CONFIG_NET_KEY=m -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -# CONFIG_IP_PNP is not set -CONFIG_NET_IPIP=m -CONFIG_NET_IPGRE=m -CONFIG_NET_IPGRE_BROADCAST=y -CONFIG_IP_MROUTE=y -CONFIG_IP_PIMSM_V1=y -CONFIG_IP_PIMSM_V2=y -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -CONFIG_INET_TUNNEL=m -CONFIG_INET_XFRM_MODE_TRANSPORT=m -CONFIG_INET_XFRM_MODE_TUNNEL=m -CONFIG_INET_XFRM_MODE_BEET=y -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" - -# -# IP: Virtual Server Configuration -# -# CONFIG_IP_VS is not set -CONFIG_IPV6=m -CONFIG_IPV6_PRIVACY=y -CONFIG_IPV6_ROUTER_PREF=y -CONFIG_IPV6_ROUTE_INFO=y -CONFIG_INET6_AH=m -CONFIG_INET6_ESP=m -CONFIG_INET6_IPCOMP=m -# CONFIG_IPV6_MIP6 is not set -CONFIG_INET6_XFRM_TUNNEL=m -CONFIG_INET6_TUNNEL=m -CONFIG_INET6_XFRM_MODE_TRANSPORT=m -CONFIG_INET6_XFRM_MODE_TUNNEL=m -CONFIG_INET6_XFRM_MODE_BEET=m -# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set -CONFIG_IPV6_TUNNEL=m -# CONFIG_IPV6_SUBTREES is not set -# CONFIG_IPV6_MULTIPLE_TABLES is not set -CONFIG_NETWORK_SECMARK=y -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_DEBUG is not set -CONFIG_BRIDGE_NETFILTER=y - -# -# Core Netfilter Configuration -# -CONFIG_NETFILTER_NETLINK=m -CONFIG_NETFILTER_NETLINK_QUEUE=m -CONFIG_NETFILTER_NETLINK_LOG=m -CONFIG_NETFILTER_XTABLES=m -CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m -CONFIG_NETFILTER_XT_TARGET_CONNMARK=m -# CONFIG_NETFILTER_XT_TARGET_DSCP is not set -CONFIG_NETFILTER_XT_TARGET_MARK=m -CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m -CONFIG_NETFILTER_XT_TARGET_NOTRACK=m -CONFIG_NETFILTER_XT_TARGET_SECMARK=m -# CONFIG_NETFILTER_XT_TARGET_CONNSECMARK is not set -CONFIG_NETFILTER_XT_MATCH_COMMENT=m -CONFIG_NETFILTER_XT_MATCH_CONNMARK=m -CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m -CONFIG_NETFILTER_XT_MATCH_DCCP=m -# CONFIG_NETFILTER_XT_MATCH_DSCP is not set -CONFIG_NETFILTER_XT_MATCH_ESP=m -CONFIG_NETFILTER_XT_MATCH_HELPER=m -CONFIG_NETFILTER_XT_MATCH_LENGTH=m -CONFIG_NETFILTER_XT_MATCH_LIMIT=m -CONFIG_NETFILTER_XT_MATCH_MAC=m -CONFIG_NETFILTER_XT_MATCH_MARK=m -CONFIG_NETFILTER_XT_MATCH_POLICY=m -CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m -CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m -CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m -CONFIG_NETFILTER_XT_MATCH_QUOTA=m -CONFIG_NETFILTER_XT_MATCH_REALM=m -CONFIG_NETFILTER_XT_MATCH_SCTP=m -CONFIG_NETFILTER_XT_MATCH_STATE=m -CONFIG_NETFILTER_XT_MATCH_STATISTIC=m -CONFIG_NETFILTER_XT_MATCH_STRING=m -CONFIG_NETFILTER_XT_MATCH_TCPMSS=m - -# -# IP: Netfilter Configuration -# -CONFIG_IP_NF_CONNTRACK=m -# CONFIG_IP_NF_CT_ACCT is not set -CONFIG_IP_NF_CONNTRACK_MARK=y -CONFIG_IP_NF_CONNTRACK_SECMARK=y -CONFIG_IP_NF_CONNTRACK_EVENTS=y -CONFIG_IP_NF_CONNTRACK_NETLINK=m -CONFIG_IP_NF_CT_PROTO_SCTP=m -CONFIG_IP_NF_FTP=m -CONFIG_IP_NF_IRC=m -# CONFIG_IP_NF_NETBIOS_NS is not set -CONFIG_IP_NF_TFTP=m -CONFIG_IP_NF_AMANDA=m -CONFIG_IP_NF_PPTP=m -CONFIG_IP_NF_H323=m -CONFIG_IP_NF_SIP=m -CONFIG_IP_NF_QUEUE=m -CONFIG_IP_NF_IPTABLES=m -CONFIG_IP_NF_MATCH_IPRANGE=m -CONFIG_IP_NF_MATCH_TOS=m -CONFIG_IP_NF_MATCH_RECENT=m -CONFIG_IP_NF_MATCH_ECN=m -CONFIG_IP_NF_MATCH_AH=m -CONFIG_IP_NF_MATCH_TTL=m -CONFIG_IP_NF_MATCH_OWNER=m -CONFIG_IP_NF_MATCH_ADDRTYPE=m -CONFIG_IP_NF_MATCH_HASHLIMIT=m -CONFIG_IP_NF_FILTER=m -CONFIG_IP_NF_TARGET_REJECT=m -CONFIG_IP_NF_TARGET_LOG=m -CONFIG_IP_NF_TARGET_ULOG=m -CONFIG_IP_NF_TARGET_TCPMSS=m -CONFIG_IP_NF_NAT=m -CONFIG_IP_NF_NAT_NEEDED=y -CONFIG_IP_NF_TARGET_MASQUERADE=m -CONFIG_IP_NF_TARGET_REDIRECT=m -CONFIG_IP_NF_TARGET_NETMAP=m -CONFIG_IP_NF_TARGET_SAME=m -CONFIG_IP_NF_NAT_SNMP_BASIC=m -CONFIG_IP_NF_NAT_IRC=m -CONFIG_IP_NF_NAT_FTP=m -CONFIG_IP_NF_NAT_TFTP=m -CONFIG_IP_NF_NAT_AMANDA=m -CONFIG_IP_NF_NAT_PPTP=m -CONFIG_IP_NF_NAT_H323=m -CONFIG_IP_NF_NAT_SIP=m -CONFIG_IP_NF_MANGLE=m -CONFIG_IP_NF_TARGET_TOS=m -CONFIG_IP_NF_TARGET_ECN=m -CONFIG_IP_NF_TARGET_TTL=m -CONFIG_IP_NF_TARGET_CLUSTERIP=m -CONFIG_IP_NF_RAW=m -CONFIG_IP_NF_ARPTABLES=m -CONFIG_IP_NF_ARPFILTER=m -CONFIG_IP_NF_ARP_MANGLE=m - -# -# IPv6: Netfilter Configuration (EXPERIMENTAL) -# -CONFIG_IP6_NF_QUEUE=m -CONFIG_IP6_NF_IPTABLES=m -CONFIG_IP6_NF_MATCH_RT=m -CONFIG_IP6_NF_MATCH_OPTS=m -CONFIG_IP6_NF_MATCH_FRAG=m -CONFIG_IP6_NF_MATCH_HL=m -CONFIG_IP6_NF_MATCH_OWNER=m -CONFIG_IP6_NF_MATCH_IPV6HEADER=m -CONFIG_IP6_NF_MATCH_AH=m -CONFIG_IP6_NF_MATCH_EUI64=m -CONFIG_IP6_NF_FILTER=m -CONFIG_IP6_NF_TARGET_LOG=m -CONFIG_IP6_NF_TARGET_REJECT=m -CONFIG_IP6_NF_MANGLE=m -CONFIG_IP6_NF_TARGET_HL=m -CONFIG_IP6_NF_RAW=m - -# -# DECnet: Netfilter Configuration -# -CONFIG_DECNET_NF_GRABULATOR=m - -# -# Bridge: Netfilter Configuration -# -CONFIG_BRIDGE_NF_EBTABLES=m -CONFIG_BRIDGE_EBT_BROUTE=m -CONFIG_BRIDGE_EBT_T_FILTER=m -CONFIG_BRIDGE_EBT_T_NAT=m -CONFIG_BRIDGE_EBT_802_3=m -CONFIG_BRIDGE_EBT_AMONG=m -CONFIG_BRIDGE_EBT_ARP=m -CONFIG_BRIDGE_EBT_IP=m -CONFIG_BRIDGE_EBT_LIMIT=m -CONFIG_BRIDGE_EBT_MARK=m -CONFIG_BRIDGE_EBT_PKTTYPE=m -CONFIG_BRIDGE_EBT_STP=m -CONFIG_BRIDGE_EBT_VLAN=m -CONFIG_BRIDGE_EBT_ARPREPLY=m -CONFIG_BRIDGE_EBT_DNAT=m -CONFIG_BRIDGE_EBT_MARK_T=m -CONFIG_BRIDGE_EBT_REDIRECT=m -CONFIG_BRIDGE_EBT_SNAT=m -CONFIG_BRIDGE_EBT_LOG=m -CONFIG_BRIDGE_EBT_ULOG=m - -# -# DCCP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -CONFIG_BRIDGE=m -# CONFIG_VLAN_8021Q is not set -CONFIG_DECNET=m -# CONFIG_DECNET_ROUTER is not set -CONFIG_LLC=m -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -CONFIG_NET_SCHED=y -CONFIG_NET_SCH_CLK_JIFFIES=y -# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set -# CONFIG_NET_SCH_CLK_CPU is not set - -# -# Queueing/Scheduling -# -CONFIG_NET_SCH_CBQ=m -CONFIG_NET_SCH_HTB=m -CONFIG_NET_SCH_HFSC=m -CONFIG_NET_SCH_PRIO=m -CONFIG_NET_SCH_RED=m -CONFIG_NET_SCH_SFQ=m -CONFIG_NET_SCH_TEQL=m -CONFIG_NET_SCH_TBF=m -CONFIG_NET_SCH_GRED=m -CONFIG_NET_SCH_DSMARK=m -CONFIG_NET_SCH_NETEM=m -CONFIG_NET_SCH_INGRESS=m - -# -# Classification -# -CONFIG_NET_CLS=y -CONFIG_NET_CLS_BASIC=m -CONFIG_NET_CLS_TCINDEX=m -CONFIG_NET_CLS_ROUTE4=m -CONFIG_NET_CLS_ROUTE=y -CONFIG_NET_CLS_FW=m -CONFIG_NET_CLS_U32=m -# CONFIG_CLS_U32_PERF is not set -# CONFIG_CLS_U32_MARK is not set -CONFIG_NET_CLS_RSVP=m -CONFIG_NET_CLS_RSVP6=m -# CONFIG_NET_EMATCH is not set -# CONFIG_NET_CLS_ACT is not set -CONFIG_NET_CLS_POLICE=y -# CONFIG_NET_CLS_IND is not set -CONFIG_NET_ESTIMATOR=y - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -CONFIG_HAMRADIO=y - -# -# Packet Radio protocols -# -CONFIG_AX25=m -CONFIG_AX25_DAMA_SLAVE=y -CONFIG_NETROM=m -CONFIG_ROSE=m - -# -# AX.25 network device drivers -# -CONFIG_MKISS=m -CONFIG_6PACK=m -CONFIG_BPQETHER=m -# CONFIG_BAYCOM_SER_FDX is not set -# CONFIG_BAYCOM_SER_HDX is not set -# CONFIG_BAYCOM_PAR is not set -# CONFIG_BAYCOM_EPP is not set -# CONFIG_YAM is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -CONFIG_IEEE80211=m -# CONFIG_IEEE80211_DEBUG is not set -CONFIG_IEEE80211_CRYPT_WEP=m -CONFIG_IEEE80211_CRYPT_CCMP=m -CONFIG_IEEE80211_SOFTMAC=m -# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set -CONFIG_WIRELESS_EXT=y - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=y -# CONFIG_SYS_HYPERVISOR is not set - -# -# Connector - unified userspace <-> kernelspace linker -# -CONFIG_CONNECTOR=m - -# -# Memory Technology Devices (MTD) -# -# CONFIG_MTD is not set - -# -# Parallel port support -# -CONFIG_PARPORT=m -CONFIG_PARPORT_PC=m -# CONFIG_PARPORT_PC_FIFO is not set -# CONFIG_PARPORT_PC_SUPERIO is not set -# CONFIG_PARPORT_GSC is not set -# CONFIG_PARPORT_AX88796 is not set -CONFIG_PARPORT_1284=y - -# -# Plug and Play support -# -# CONFIG_PNP is not set - -# -# Block devices -# -CONFIG_BLK_DEV_FD=m -CONFIG_PARIDE=m -CONFIG_PARIDE_PARPORT=m - -# -# Parallel IDE high-level drivers -# -CONFIG_PARIDE_PD=m -CONFIG_PARIDE_PCD=m -CONFIG_PARIDE_PF=m -CONFIG_PARIDE_PT=m -CONFIG_PARIDE_PG=m - -# -# Parallel IDE protocol modules -# -CONFIG_PARIDE_ATEN=m -CONFIG_PARIDE_BPCK=m -CONFIG_PARIDE_BPCK6=m -CONFIG_PARIDE_COMM=m -CONFIG_PARIDE_DSTR=m -CONFIG_PARIDE_FIT2=m -CONFIG_PARIDE_FIT3=m -CONFIG_PARIDE_EPAT=m -# CONFIG_PARIDE_EPATC8 is not set -CONFIG_PARIDE_EPIA=m -CONFIG_PARIDE_FRIQ=m -CONFIG_PARIDE_FRPW=m -CONFIG_PARIDE_KBIC=m -CONFIG_PARIDE_KTTI=m -CONFIG_PARIDE_ON20=m -CONFIG_PARIDE_ON26=m -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=m -CONFIG_BLK_DEV_CRYPTOLOOP=m -CONFIG_BLK_DEV_NBD=m -CONFIG_BLK_DEV_RAM=m -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -# CONFIG_BLK_DEV_INITRD is not set -CONFIG_CDROM_PKTCDVD=m -CONFIG_CDROM_PKTCDVD_BUFFERS=8 -# CONFIG_CDROM_PKTCDVD_WCACHE is not set -CONFIG_ATA_OVER_ETH=m - -# -# ATA/ATAPI/MFM/RLL support -# -# CONFIG_IDE is not set - -# -# SCSI device support -# -CONFIG_RAID_ATTRS=m -CONFIG_SCSI=y -CONFIG_SCSI_NETLINK=y -CONFIG_SCSI_PROC_FS=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -CONFIG_CHR_DEV_ST=m -# CONFIG_CHR_DEV_OSST is not set -CONFIG_BLK_DEV_SR=m -CONFIG_BLK_DEV_SR_VENDOR=y -# CONFIG_CHR_DEV_SG is not set -# CONFIG_CHR_DEV_SCH is not set - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -# CONFIG_SCSI_MULTI_LUN is not set -CONFIG_SCSI_CONSTANTS=y -# CONFIG_SCSI_LOGGING is not set - -# -# SCSI Transports -# -CONFIG_SCSI_SPI_ATTRS=y -CONFIG_SCSI_FC_ATTRS=y -CONFIG_SCSI_ISCSI_ATTRS=m -CONFIG_SCSI_SAS_ATTRS=m -# CONFIG_SCSI_SAS_LIBSAS is not set - -# -# SCSI low-level drivers -# -CONFIG_ISCSI_TCP=m -# CONFIG_SCSI_AHA152X is not set -# CONFIG_SCSI_AIC7XXX_OLD is not set -# CONFIG_SCSI_IN2000 is not set -# CONFIG_SCSI_DTC3280 is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GENERIC_NCR5380 is not set -# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set -CONFIG_SCSI_PPA=m -CONFIG_SCSI_IMM=m -# CONFIG_SCSI_IZIP_EPP16 is not set -# CONFIG_SCSI_IZIP_SLOW_CTR is not set -# CONFIG_SCSI_NCR53C406A is not set -# CONFIG_SCSI_PAS16 is not set -# CONFIG_SCSI_PSI240I is not set -# CONFIG_SCSI_QLOGIC_FAS is not set -# CONFIG_SCSI_SYM53C416 is not set -# CONFIG_SCSI_T128 is not set -# CONFIG_SCSI_DEBUG is not set -CONFIG_JAZZ_ESP=y - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# -# CONFIG_ATA is not set - -# -# Old CD-ROM drivers (not SCSI, not IDE) -# -# CONFIG_CD_NO_IDESCSI is not set - -# -# Multi-device support (RAID and LVM) -# -CONFIG_MD=y -CONFIG_BLK_DEV_MD=m -CONFIG_MD_LINEAR=m -CONFIG_MD_RAID0=m -CONFIG_MD_RAID1=m -CONFIG_MD_RAID10=m -CONFIG_MD_RAID456=m -CONFIG_MD_RAID5_RESHAPE=y -CONFIG_MD_MULTIPATH=m -CONFIG_MD_FAULTY=m -CONFIG_BLK_DEV_DM=m -# CONFIG_DM_DEBUG is not set -# CONFIG_DM_CRYPT is not set -CONFIG_DM_SNAPSHOT=m -CONFIG_DM_MIRROR=m -CONFIG_DM_ZERO=m -CONFIG_DM_MULTIPATH=m -CONFIG_DM_MULTIPATH_EMC=m - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# - -# -# I2O device support -# - -# -# Network device support -# -CONFIG_NETDEVICES=y -CONFIG_DUMMY=m -CONFIG_BONDING=m -CONFIG_EQUALIZER=m -CONFIG_TUN=m - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set - -# -# PHY device support -# -CONFIG_PHYLIB=m - -# -# MII PHY device drivers -# -CONFIG_MARVELL_PHY=m -CONFIG_DAVICOM_PHY=m -CONFIG_QSEMI_PHY=m -CONFIG_LXT_PHY=m -CONFIG_CICADA_PHY=m -CONFIG_VITESSE_PHY=m -CONFIG_SMSC_PHY=m -# CONFIG_FIXED_PHY is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -CONFIG_MIPS_JAZZ_SONIC=y -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_NET_VENDOR_SMC is not set -# CONFIG_DM9000 is not set -# CONFIG_NET_VENDOR_RACAL is not set -# CONFIG_AT1700 is not set -# CONFIG_DEPCA is not set -# CONFIG_HP100 is not set -CONFIG_NET_ISA=y -# CONFIG_E2100 is not set -# CONFIG_EWRK3 is not set -# CONFIG_EEXPRESS is not set -# CONFIG_EEXPRESS_PRO is not set -# CONFIG_HPLAN_PLUS is not set -# CONFIG_HPLAN is not set -# CONFIG_LP486E is not set -# CONFIG_ETH16I is not set -CONFIG_NE2000=m -# CONFIG_SEEQ8005 is not set -CONFIG_NET_PCI=y -# CONFIG_AC3200 is not set -# CONFIG_APRICOT is not set -# CONFIG_CS89x0 is not set -# CONFIG_LAN_SAA9730 is not set -# CONFIG_NET_POCKET is not set - -# -# Ethernet (1000 Mbit) -# - -# -# Ethernet (10000 Mbit) -# - -# -# Token Ring devices -# -# CONFIG_TR is not set - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set -CONFIG_PLIP=m -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Telephony Support -# -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y -CONFIG_INPUT_FF_MEMLESS=m - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_PSAUX=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -CONFIG_INPUT_KEYBOARD=y -CONFIG_KEYBOARD_ATKBD=y -# CONFIG_KEYBOARD_SUNKBD is not set -# CONFIG_KEYBOARD_LKKBD is not set -# CONFIG_KEYBOARD_XTKBD is not set -# CONFIG_KEYBOARD_NEWTON is not set -# CONFIG_KEYBOARD_STOWAWAY is not set -CONFIG_INPUT_MOUSE=y -CONFIG_MOUSE_PS2=y -# CONFIG_MOUSE_SERIAL is not set -# CONFIG_MOUSE_INPORT is not set -# CONFIG_MOUSE_LOGIBM is not set -# CONFIG_MOUSE_PC110PAD is not set -# CONFIG_MOUSE_VSXXXAA is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -CONFIG_SERIO=y -CONFIG_SERIO_I8042=y -CONFIG_SERIO_SERPORT=y -CONFIG_SERIO_PARKBD=m -CONFIG_SERIO_LIBPS2=y -CONFIG_SERIO_RAW=m -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -CONFIG_VT_HW_CONSOLE_BINDING=y -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -CONFIG_SERIAL_8250=m -CONFIG_SERIAL_8250_NR_UARTS=4 -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 -CONFIG_SERIAL_8250_EXTENDED=y -# CONFIG_SERIAL_8250_MANY_PORTS is not set -CONFIG_SERIAL_8250_SHARE_IRQ=y -CONFIG_SERIAL_8250_DETECT_IRQ=y -CONFIG_SERIAL_8250_RSA=y - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_CORE=m -CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 -CONFIG_PRINTER=m -# CONFIG_LP_CONSOLE is not set -CONFIG_PPDEV=m -CONFIG_TIPAR=m - -# -# IPMI -# -# CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -# CONFIG_HW_RANDOM is not set -CONFIG_RTC=m -# CONFIG_GEN_RTC is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set - -# -# Ftape, the floppy tape device driver -# -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# -# CONFIG_TCG_TPM is not set -# CONFIG_TELCLOCK is not set - -# -# I2C support -# -# CONFIG_I2C is not set - -# -# SPI support -# -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set - -# -# Dallas's 1-wire bus -# -CONFIG_W1=m -CONFIG_W1_CON=y - -# -# 1-wire Bus Masters -# - -# -# 1-wire Slaves -# -# CONFIG_W1_SLAVE_THERM is not set -# CONFIG_W1_SLAVE_SMEM is not set -# CONFIG_W1_SLAVE_DS2433 is not set - -# -# Hardware Monitoring support -# -# CONFIG_HWMON is not set -# CONFIG_HWMON_VID is not set - -# -# Misc devices -# -# CONFIG_TIFM_CORE is not set - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set - -# -# Graphics support -# -# CONFIG_FIRMWARE_EDID is not set -# CONFIG_FB is not set - -# -# Console display driver support -# -CONFIG_VGA_CONSOLE=y -# CONFIG_VGACON_SOFT_SCROLLBACK is not set -# CONFIG_MDA_CONSOLE is not set -CONFIG_DUMMY_CONSOLE=y -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# USB support -# -# CONFIG_USB_ARCH_HAS_HCD is not set -# CONFIG_USB_ARCH_HAS_OHCI is not set -# CONFIG_USB_ARCH_HAS_EHCI is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# -# CONFIG_MMC is not set - -# -# LED devices -# -# CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# - -# -# InfiniBand support -# - -# -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) -# - -# -# Real Time Clock -# -# CONFIG_RTC_CLASS is not set - -# -# DMA Engine support -# -# CONFIG_DMA_ENGINE is not set - -# -# DMA Clients -# - -# -# DMA Devices -# - -# -# File systems -# -CONFIG_EXT2_FS=m -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -# CONFIG_EXT3_FS_POSIX_ACL is not set -# CONFIG_EXT3_FS_SECURITY is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FS_MBCACHE=y -CONFIG_REISERFS_FS=m -# CONFIG_REISERFS_CHECK is not set -# CONFIG_REISERFS_PROC_INFO is not set -CONFIG_REISERFS_FS_XATTR=y -CONFIG_REISERFS_FS_POSIX_ACL=y -CONFIG_REISERFS_FS_SECURITY=y -# CONFIG_JFS_FS is not set -CONFIG_FS_POSIX_ACL=y -CONFIG_XFS_FS=m -CONFIG_XFS_QUOTA=y -CONFIG_XFS_SECURITY=y -# CONFIG_XFS_POSIX_ACL is not set -# CONFIG_XFS_RT is not set -# CONFIG_GFS2_FS is not set -# CONFIG_OCFS2_FS is not set -CONFIG_MINIX_FS=m -CONFIG_ROMFS_FS=m -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y -# CONFIG_QUOTA is not set -CONFIG_QUOTACTL=y -CONFIG_DNOTIFY=y -CONFIG_AUTOFS_FS=m -CONFIG_AUTOFS4_FS=m -CONFIG_FUSE_FS=m - -# -# CD-ROM/DVD Filesystems -# -CONFIG_ISO9660_FS=m -CONFIG_JOLIET=y -CONFIG_ZISOFS=y -CONFIG_ZISOFS_FS=m -CONFIG_UDF_FS=m -CONFIG_UDF_NLS=y - -# -# DOS/FAT/NT Filesystems -# -CONFIG_FAT_FS=m -CONFIG_MSDOS_FS=m -CONFIG_VFAT_FS=m -CONFIG_FAT_DEFAULT_CODEPAGE=437 -CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -CONFIG_NTFS_FS=m -# CONFIG_NTFS_DEBUG is not set -# CONFIG_NTFS_RW is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_KCORE=y -CONFIG_PROC_SYSCTL=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y -# CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# -CONFIG_ADFS_FS=m -# CONFIG_ADFS_FS_RW is not set -CONFIG_AFFS_FS=m -# CONFIG_ECRYPT_FS is not set -CONFIG_HFS_FS=m -# CONFIG_HFSPLUS_FS is not set -CONFIG_BEFS_FS=m -# CONFIG_BEFS_DEBUG is not set -CONFIG_BFS_FS=m -CONFIG_EFS_FS=m -CONFIG_CRAMFS=m -CONFIG_VXFS_FS=m -CONFIG_HPFS_FS=m -CONFIG_QNX4FS_FS=m -CONFIG_SYSV_FS=m -CONFIG_UFS_FS=m -# CONFIG_UFS_FS_WRITE is not set -# CONFIG_UFS_DEBUG is not set - -# -# Network File Systems -# -CONFIG_NFS_FS=m -CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set -# CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set -CONFIG_NFSD=m -CONFIG_NFSD_V3=y -# CONFIG_NFSD_V3_ACL is not set -# CONFIG_NFSD_V4 is not set -CONFIG_NFSD_TCP=y -CONFIG_LOCKD=m -CONFIG_LOCKD_V4=y -CONFIG_EXPORTFS=m -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=m -CONFIG_SUNRPC_GSS=m -CONFIG_RPCSEC_GSS_KRB5=m -CONFIG_RPCSEC_GSS_SPKM3=m -CONFIG_SMB_FS=m -# CONFIG_SMB_NLS_DEFAULT is not set -CONFIG_CIFS=m -# CONFIG_CIFS_STATS is not set -# CONFIG_CIFS_WEAK_PW_HASH is not set -# CONFIG_CIFS_XATTR is not set -# CONFIG_CIFS_DEBUG2 is not set -# CONFIG_CIFS_EXPERIMENTAL is not set -CONFIG_NCP_FS=m -CONFIG_NCPFS_PACKET_SIGNING=y -CONFIG_NCPFS_IOCTL_LOCKING=y -CONFIG_NCPFS_STRONG=y -CONFIG_NCPFS_NFS_NS=y -CONFIG_NCPFS_OS2_NS=y -CONFIG_NCPFS_SMALLDOS=y -CONFIG_NCPFS_NLS=y -CONFIG_NCPFS_EXTRAS=y -CONFIG_CODA_FS=m -CONFIG_CODA_FS_OLD_API=y -CONFIG_AFS_FS=m -CONFIG_RXRPC=m -# CONFIG_9P_FS is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -# CONFIG_MAC_PARTITION is not set -CONFIG_MSDOS_PARTITION=y -# CONFIG_BSD_DISKLABEL is not set -# CONFIG_MINIX_SUBPARTITION is not set -# CONFIG_SOLARIS_X86_PARTITION is not set -# CONFIG_UNIXWARE_DISKLABEL is not set -# CONFIG_LDM_PARTITION is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_KARMA_PARTITION is not set -# CONFIG_EFI_PARTITION is not set - -# -# Native Language Support -# -CONFIG_NLS=m -CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=m -CONFIG_NLS_CODEPAGE_737=m -CONFIG_NLS_CODEPAGE_775=m -CONFIG_NLS_CODEPAGE_850=m -CONFIG_NLS_CODEPAGE_852=m -CONFIG_NLS_CODEPAGE_855=m -CONFIG_NLS_CODEPAGE_857=m -CONFIG_NLS_CODEPAGE_860=m -CONFIG_NLS_CODEPAGE_861=m -CONFIG_NLS_CODEPAGE_862=m -CONFIG_NLS_CODEPAGE_863=m -CONFIG_NLS_CODEPAGE_864=m -CONFIG_NLS_CODEPAGE_865=m -CONFIG_NLS_CODEPAGE_866=m -CONFIG_NLS_CODEPAGE_869=m -CONFIG_NLS_CODEPAGE_936=m -CONFIG_NLS_CODEPAGE_950=m -CONFIG_NLS_CODEPAGE_932=m -CONFIG_NLS_CODEPAGE_949=m -CONFIG_NLS_CODEPAGE_874=m -CONFIG_NLS_ISO8859_8=m -CONFIG_NLS_CODEPAGE_1250=m -CONFIG_NLS_CODEPAGE_1251=m -CONFIG_NLS_ASCII=m -CONFIG_NLS_ISO8859_1=m -CONFIG_NLS_ISO8859_2=m -CONFIG_NLS_ISO8859_3=m -CONFIG_NLS_ISO8859_4=m -CONFIG_NLS_ISO8859_5=m -CONFIG_NLS_ISO8859_6=m -CONFIG_NLS_ISO8859_7=m -CONFIG_NLS_ISO8859_9=m -CONFIG_NLS_ISO8859_13=m -CONFIG_NLS_ISO8859_14=m -CONFIG_NLS_ISO8859_15=m -CONFIG_NLS_KOI8_R=m -CONFIG_NLS_KOI8_U=m -CONFIG_NLS_UTF8=m - -# -# Distributed Lock Manager -# - -# -# Profiling support -# -# CONFIG_PROFILING is not set - -# -# Kernel hacking -# -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -# CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_MUST_CHECK=y -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_DEBUG_FS is not set -CONFIG_CROSSCOMPILE=y -CONFIG_CMDLINE="" - -# -# Security options -# -CONFIG_KEYS=y -CONFIG_KEYS_DEBUG_PROC_KEYS=y -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -CONFIG_CRYPTO=y -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_BLKCIPHER=m -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_MANAGER=m -CONFIG_CRYPTO_HMAC=y -CONFIG_CRYPTO_NULL=m -CONFIG_CRYPTO_MD4=m -CONFIG_CRYPTO_MD5=m -CONFIG_CRYPTO_SHA1=m -CONFIG_CRYPTO_SHA256=m -CONFIG_CRYPTO_SHA512=m -CONFIG_CRYPTO_WP512=m -CONFIG_CRYPTO_TGR192=m -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_CBC=m -CONFIG_CRYPTO_DES=m -CONFIG_CRYPTO_BLOWFISH=m -CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_TWOFISH_COMMON=m -CONFIG_CRYPTO_SERPENT=m -CONFIG_CRYPTO_AES=m -CONFIG_CRYPTO_CAST5=m -CONFIG_CRYPTO_CAST6=m -CONFIG_CRYPTO_TEA=m -CONFIG_CRYPTO_ARC4=m -CONFIG_CRYPTO_KHAZAD=m -CONFIG_CRYPTO_ANUBIS=m -CONFIG_CRYPTO_DEFLATE=m -CONFIG_CRYPTO_MICHAEL_MIC=m -CONFIG_CRYPTO_CRC32C=m -# CONFIG_CRYPTO_TEST is not set - -# -# Hardware crypto devices -# - -# -# Library routines -# -CONFIG_CRC_CCITT=m -CONFIG_CRC16=m -CONFIG_CRC32=y -CONFIG_LIBCRC32C=m -CONFIG_ZLIB_INFLATE=m -CONFIG_ZLIB_DEFLATE=m -CONFIG_TEXTSEARCH=y -CONFIG_TEXTSEARCH_KMP=m -CONFIG_TEXTSEARCH_BM=m -CONFIG_TEXTSEARCH_FSM=m -CONFIG_PLIST=y diff --git a/trunk/arch/mips/configs/malta_defconfig b/trunk/arch/mips/configs/malta_defconfig index 101e80347dce..aeefe2873e38 100644 --- a/trunk/arch/mips/configs/malta_defconfig +++ b/trunk/arch/mips/configs/malta_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.19-rc1 -# Fri Oct 6 17:34:55 2006 +# Linux kernel version: 2.6.18-rc1 +# Thu Jul 6 10:04:13 2006 # CONFIG_MIPS=y @@ -25,6 +25,8 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set @@ -65,7 +67,6 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_TIME=y CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y CONFIG_ARCH_MAY_HAVE_PC_FDC=y CONFIG_DMA_NONCOHERENT=y @@ -133,19 +134,19 @@ CONFIG_MIPS_CPU_SCACHE=y CONFIG_CPU_HAS_PREFETCH=y # CONFIG_MIPS_MT_DISABLED is not set # CONFIG_MIPS_MT_SMTC is not set -CONFIG_MIPS_MT_SMP=y -# CONFIG_MIPS_VPE_LOADER is not set +# CONFIG_MIPS_MT_SMP is not set +CONFIG_MIPS_VPE_LOADER=y CONFIG_MIPS_MT=y CONFIG_SYS_SUPPORTS_MULTITHREADING=y CONFIG_MIPS_MT_FPAFF=y +CONFIG_MIPS_VPE_LOADER_TOM=y +CONFIG_MIPS_VPE_APSP_API=y +CONFIG_MIPS_APSP_KSPD=y # CONFIG_64BIT_PHYS_ADDR is not set CONFIG_CPU_HAS_LLSC=y -CONFIG_CPU_MIPSR2_IRQ_VI=y -CONFIG_CPU_MIPSR2_SRS=y CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_IRQ_PER_CPU=y CONFIG_CPU_SUPPORTS_HIGHMEM=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_SELECT_MEMORY_MODEL=y @@ -157,9 +158,6 @@ CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set -CONFIG_SMP=y -CONFIG_SYS_SUPPORTS_SMP=y -CONFIG_NR_CPUS=2 # CONFIG_HZ_48 is not set CONFIG_HZ_100=y # CONFIG_HZ_128 is not set @@ -172,7 +170,6 @@ CONFIG_HZ=100 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_PREEMPT_BKL=y CONFIG_LOCKDEP_SUPPORT=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" @@ -181,7 +178,7 @@ CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # Code maturity level options # CONFIG_EXPERIMENTAL=y -CONFIG_LOCK_KERNEL=y +CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 # @@ -191,20 +188,15 @@ CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set +CONFIG_SYSCTL=y # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set -# CONFIG_CPUSETS is not set CONFIG_RELAY=y CONFIG_INITRAMFS_SOURCE="" # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_SYSCTL=y CONFIG_EMBEDDED=y -# CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set CONFIG_HOTPLUG=y @@ -212,12 +204,12 @@ CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y +CONFIG_RT_MUTEXES=y CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_SHMEM=y CONFIG_SLAB=y CONFIG_VM_EVENT_COUNTERS=y -CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 # CONFIG_SLOB is not set @@ -231,12 +223,10 @@ CONFIG_MODULE_UNLOAD=y CONFIG_MODVERSIONS=y CONFIG_MODULE_SRCVERSION_ALL=y CONFIG_KMOD=y -CONFIG_STOP_MACHINE=y # # Block layer # -CONFIG_BLOCK=y # CONFIG_LBD is not set # CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_LSF is not set @@ -259,7 +249,6 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # CONFIG_HW_HAS_PCI=y CONFIG_PCI=y -# CONFIG_PCI_MULTITHREAD_PROBE is not set CONFIG_MMU=y # @@ -293,7 +282,6 @@ CONFIG_PACKET_MMAP=y CONFIG_UNIX=y CONFIG_XFRM=y CONFIG_XFRM_USER=m -# CONFIG_XFRM_SUB_POLICY is not set CONFIG_NET_KEY=y CONFIG_INET=y CONFIG_IP_MULTICAST=y @@ -325,12 +313,10 @@ CONFIG_INET_XFRM_TUNNEL=m CONFIG_INET_TUNNEL=m CONFIG_INET_XFRM_MODE_TRANSPORT=m CONFIG_INET_XFRM_MODE_TUNNEL=m -CONFIG_INET_XFRM_MODE_BEET=y CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" +CONFIG_TCP_CONG_BIC=y # # IP: Virtual Server Configuration @@ -372,16 +358,11 @@ CONFIG_IPV6_ROUTE_INFO=y CONFIG_INET6_AH=m CONFIG_INET6_ESP=m CONFIG_INET6_IPCOMP=m -# CONFIG_IPV6_MIP6 is not set CONFIG_INET6_XFRM_TUNNEL=m CONFIG_INET6_TUNNEL=m CONFIG_INET6_XFRM_MODE_TRANSPORT=m CONFIG_INET6_XFRM_MODE_TUNNEL=m -CONFIG_INET6_XFRM_MODE_BEET=m -# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set CONFIG_IPV6_TUNNEL=m -# CONFIG_IPV6_SUBTREES is not set -# CONFIG_IPV6_MULTIPLE_TABLES is not set CONFIG_NETWORK_SECMARK=y CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set @@ -396,7 +377,6 @@ CONFIG_NETFILTER_NETLINK_LOG=m CONFIG_NETFILTER_XTABLES=m CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m CONFIG_NETFILTER_XT_TARGET_CONNMARK=m -# CONFIG_NETFILTER_XT_TARGET_DSCP is not set CONFIG_NETFILTER_XT_TARGET_MARK=m CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m CONFIG_NETFILTER_XT_TARGET_NOTRACK=m @@ -407,7 +387,6 @@ CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m CONFIG_NETFILTER_XT_MATCH_CONNMARK=m CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m CONFIG_NETFILTER_XT_MATCH_DCCP=m -# CONFIG_NETFILTER_XT_MATCH_DSCP is not set CONFIG_NETFILTER_XT_MATCH_ESP=m CONFIG_NETFILTER_XT_MATCH_HELPER=m CONFIG_NETFILTER_XT_MATCH_LENGTH=m @@ -450,6 +429,7 @@ CONFIG_IP_NF_MATCH_IPRANGE=m CONFIG_IP_NF_MATCH_TOS=m CONFIG_IP_NF_MATCH_RECENT=m CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_DSCP=m CONFIG_IP_NF_MATCH_AH=m CONFIG_IP_NF_MATCH_TTL=m CONFIG_IP_NF_MATCH_OWNER=m @@ -477,6 +457,7 @@ CONFIG_IP_NF_NAT_SIP=m CONFIG_IP_NF_MANGLE=m CONFIG_IP_NF_TARGET_TOS=m CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_DSCP=m CONFIG_IP_NF_TARGET_TTL=m CONFIG_IP_NF_TARGET_CLUSTERIP=m CONFIG_IP_NF_RAW=m @@ -555,12 +536,13 @@ CONFIG_LLC=m # CONFIG_LLC2 is not set # CONFIG_IPX is not set CONFIG_ATALK=m -CONFIG_DEV_APPLETALK=m +CONFIG_DEV_APPLETALK=y CONFIG_IPDDP=m CONFIG_IPDDP_ENCAP=y CONFIG_IPDDP_DECAP=y # CONFIG_X25 is not set # CONFIG_LAPB is not set +CONFIG_NET_DIVERT=y # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set @@ -622,7 +604,6 @@ CONFIG_IEEE80211_CRYPT_CCMP=m CONFIG_IEEE80211_SOFTMAC=m # CONFIG_IEEE80211_SOFTMAC_DEBUG is not set CONFIG_WIRELESS_EXT=y -CONFIG_FIB_RULES=y # # Device Drivers @@ -671,7 +652,6 @@ CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # CONFIG_BLK_DEV_INITRD is not set CONFIG_CDROM_PKTCDVD=m CONFIG_CDROM_PKTCDVD_BUFFERS=8 @@ -682,7 +662,6 @@ CONFIG_ATA_OVER_ETH=m # ATA/ATAPI/MFM/RLL support # CONFIG_IDE=y -CONFIG_IDE_MAX_HWIFS=4 CONFIG_BLK_DEV_IDE=y # @@ -720,7 +699,6 @@ CONFIG_IDEDMA_PCI_AUTO=y # CONFIG_BLK_DEV_CS5530 is not set # CONFIG_BLK_DEV_HPT34X is not set # CONFIG_BLK_DEV_HPT366 is not set -# CONFIG_BLK_DEV_JMICRON is not set # CONFIG_BLK_DEV_SC1200 is not set CONFIG_BLK_DEV_PIIX=y # CONFIG_BLK_DEV_IT821X is not set @@ -743,7 +721,6 @@ CONFIG_IDEDMA_AUTO=y # CONFIG_RAID_ATTRS=m CONFIG_SCSI=m -CONFIG_SCSI_NETLINK=y CONFIG_SCSI_PROC_FS=y # @@ -765,13 +742,12 @@ CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y # -# SCSI Transports +# SCSI Transport Attributes # CONFIG_SCSI_SPI_ATTRS=m CONFIG_SCSI_FC_ATTRS=m CONFIG_SCSI_ISCSI_ATTRS=m CONFIG_SCSI_SAS_ATTRS=m -# CONFIG_SCSI_SAS_LIBSAS is not set # # SCSI low-level drivers @@ -789,34 +765,27 @@ CONFIG_AIC7XXX_DEBUG_MASK=0 CONFIG_AIC7XXX_REG_PRETTY_PRINT=y # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_AIC79XX is not set -# CONFIG_SCSI_AIC94XX is not set # CONFIG_SCSI_DPT_I2O is not set -# CONFIG_SCSI_ARCMSR is not set # CONFIG_MEGARAID_NEWGEN is not set # CONFIG_MEGARAID_LEGACY is not set # CONFIG_MEGARAID_SAS is not set +# CONFIG_SCSI_SATA is not set # CONFIG_SCSI_HPTIOP is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set # CONFIG_SCSI_IPS is not set # CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_STEX is not set # CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set # CONFIG_SCSI_QLOGIC_1280 is not set # CONFIG_SCSI_QLA_FC is not set -# CONFIG_SCSI_QLA_ISCSI is not set # CONFIG_SCSI_LPFC is not set # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# -# CONFIG_ATA is not set - # # Multi-device support (RAID and LVM) # @@ -831,7 +800,6 @@ CONFIG_MD_RAID5_RESHAPE=y CONFIG_MD_MULTIPATH=m CONFIG_MD_FAULTY=m CONFIG_BLK_DEV_DM=m -# CONFIG_DM_DEBUG is not set CONFIG_DM_CRYPT=m CONFIG_DM_SNAPSHOT=m CONFIG_DM_MIRROR=m @@ -886,7 +854,6 @@ CONFIG_LXT_PHY=m CONFIG_CICADA_PHY=m CONFIG_VITESSE_PHY=m CONFIG_SMSC_PHY=m -# CONFIG_FIXED_PHY is not set # # Ethernet (10 or 100Mbit) @@ -906,7 +873,6 @@ CONFIG_MII=y # CONFIG_HP100 is not set CONFIG_NET_PCI=y CONFIG_PCNET32=y -# CONFIG_PCNET32_NAPI is not set # CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_B44 is not set @@ -943,7 +909,6 @@ CONFIG_PCNET32=y # CONFIG_VIA_VELOCITY is not set # CONFIG_TIGON3 is not set # CONFIG_BNX2 is not set -# CONFIG_QLA3XXX is not set # # Ethernet (10000 Mbit) @@ -991,7 +956,6 @@ CONFIG_PCNET32=y # Input device support # CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set # # Userland interfaces @@ -1106,12 +1070,12 @@ CONFIG_RTC=y # # Misc devices # -# CONFIG_TIFM_CORE is not set # # Multimedia devices # # CONFIG_VIDEO_DEV is not set +CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices @@ -1129,7 +1093,6 @@ CONFIG_RTC=y # # CONFIG_VGA_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -1228,7 +1191,6 @@ CONFIG_XFS_QUOTA=y CONFIG_XFS_SECURITY=y CONFIG_XFS_POSIX_ACL=y # CONFIG_XFS_RT is not set -# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set CONFIG_MINIX_FS=m CONFIG_ROMFS_FS=m @@ -1268,10 +1230,8 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" # CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y -CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set @@ -1319,6 +1279,7 @@ CONFIG_SUNRPC=y # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set # CONFIG_CIFS is not set +# CONFIG_CIFS_DEBUG2 is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set @@ -1374,11 +1335,6 @@ CONFIG_NLS_KOI8_R=m CONFIG_NLS_KOI8_U=m CONFIG_NLS_UTF8=m -# -# Distributed Lock Manager -# -# CONFIG_DLM is not set - # # Profiling support # @@ -1389,11 +1345,10 @@ CONFIG_NLS_UTF8=m # CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_MUST_CHECK=y # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set # CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=15 +CONFIG_LOG_BUF_SHIFT=14 # CONFIG_DEBUG_FS is not set CONFIG_CROSSCOMPILE=y CONFIG_CMDLINE="" @@ -1408,10 +1363,6 @@ CONFIG_CMDLINE="" # Cryptographic options # CONFIG_CRYPTO=y -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_BLKCIPHER=m -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_MANAGER=m CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_NULL=m CONFIG_CRYPTO_MD4=m @@ -1421,12 +1372,9 @@ CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m CONFIG_CRYPTO_WP512=m CONFIG_CRYPTO_TGR192=m -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_CBC=m CONFIG_CRYPTO_DES=m CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_TWOFISH_COMMON=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_AES=m CONFIG_CRYPTO_CAST5=m diff --git a/trunk/arch/mips/configs/pb1100_defconfig b/trunk/arch/mips/configs/pb1100_defconfig index 9e672f63a0aa..741f8258075c 100644 --- a/trunk/arch/mips/configs/pb1100_defconfig +++ b/trunk/arch/mips/configs/pb1100_defconfig @@ -76,6 +76,7 @@ CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y CONFIG_SOC_AU1100=y CONFIG_SOC_AU1X00=y CONFIG_SWAP_IO_SPACE=y +# CONFIG_AU1X00_USB_DEVICE is not set CONFIG_MIPS_L1_CACHE_SHIFT=5 # diff --git a/trunk/arch/mips/configs/pb1500_defconfig b/trunk/arch/mips/configs/pb1500_defconfig index d0c0f4af1bff..8576340714da 100644 --- a/trunk/arch/mips/configs/pb1500_defconfig +++ b/trunk/arch/mips/configs/pb1500_defconfig @@ -75,6 +75,7 @@ CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y CONFIG_SOC_AU1500=y CONFIG_SOC_AU1X00=y +# CONFIG_AU1X00_USB_DEVICE is not set CONFIG_MIPS_L1_CACHE_SHIFT=5 # diff --git a/trunk/arch/mips/configs/pnx8550-jbs_defconfig b/trunk/arch/mips/configs/pnx8550-jbs_defconfig index 280a8001eacf..26b0b9883496 100644 --- a/trunk/arch/mips/configs/pnx8550-jbs_defconfig +++ b/trunk/arch/mips/configs/pnx8550-jbs_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.19-rc2 -# Sat Oct 14 23:01:16 2006 +# Linux kernel version: 2.6.18-rc1 +# Thu Jul 6 10:04:18 2006 # CONFIG_MIPS=y @@ -25,6 +25,8 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set @@ -39,13 +41,13 @@ CONFIG_MIPS=y # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_V2PCI is not set -CONFIG_PNX8550_JBS=y +# CONFIG_PNX8550_JBS is not set # CONFIG_DDB5477 is not set # CONFIG_MACH_VR41XX is not set # CONFIG_PMC_YOSEMITE is not set # CONFIG_QEMU is not set # CONFIG_MARKEINS is not set -# CONFIG_SGI_IP22 is not set +CONFIG_SGI_IP22=y # CONFIG_SGI_IP27 is not set # CONFIG_SGI_IP32 is not set # CONFIG_SIBYTE_BIGSUR is not set @@ -65,21 +67,25 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_TIME=y CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_ARC=y CONFIG_DMA_NONCOHERENT=y CONFIG_DMA_NEED_PCI_MAP_STATE=y -# CONFIG_CPU_BIG_ENDIAN is not set -CONFIG_CPU_LITTLE_ENDIAN=y -CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y -CONFIG_PNX8550=y -CONFIG_SOC_PNX8550=y +CONFIG_CPU_BIG_ENDIAN=y +# CONFIG_CPU_LITTLE_ENDIAN is not set +CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y +CONFIG_IRQ_CPU=y +CONFIG_SWAP_IO_SPACE=y +CONFIG_ARC32=y +CONFIG_BOOT_ELF32=y CONFIG_MIPS_L1_CACHE_SHIFT=5 +# CONFIG_ARC_CONSOLE is not set +CONFIG_ARC_PROMLIB=y # # CPU selection # -CONFIG_CPU_MIPS32_R1=y +# CONFIG_CPU_MIPS32_R1 is not set # CONFIG_CPU_MIPS32_R2 is not set # CONFIG_CPU_MIPS64_R1 is not set # CONFIG_CPU_MIPS64_R2 is not set @@ -87,7 +93,7 @@ CONFIG_CPU_MIPS32_R1=y # CONFIG_CPU_TX39XX is not set # CONFIG_CPU_VR41XX is not set # CONFIG_CPU_R4300 is not set -# CONFIG_CPU_R4X00 is not set +CONFIG_CPU_R4X00=y # CONFIG_CPU_TX49XX is not set # CONFIG_CPU_R5000 is not set # CONFIG_CPU_R5432 is not set @@ -98,11 +104,12 @@ CONFIG_CPU_MIPS32_R1=y # CONFIG_CPU_RM7000 is not set # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set -CONFIG_SYS_HAS_CPU_MIPS32_R1=y -CONFIG_CPU_MIPS32=y -CONFIG_CPU_MIPSR1=y +CONFIG_SYS_HAS_CPU_R4X00=y +CONFIG_SYS_HAS_CPU_R5000=y CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y +CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y # # Kernel type @@ -113,17 +120,17 @@ CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set -CONFIG_CPU_HAS_PREFETCH=y +CONFIG_BOARD_SCACHE=y +CONFIG_IP22_CPU_SCACHE=y CONFIG_MIPS_MT_DISABLED=y -# CONFIG_MIPS_MT_SMP is not set # CONFIG_MIPS_MT_SMTC is not set +# CONFIG_MIPS_MT_SMP is not set # CONFIG_MIPS_VPE_LOADER is not set # CONFIG_64BIT_PHYS_ADDR is not set CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_CPU_SUPPORTS_HIGHMEM=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y @@ -137,12 +144,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_HZ_48 is not set # CONFIG_HZ_100 is not set # CONFIG_HZ_128 is not set -CONFIG_HZ_250=y +# CONFIG_HZ_250 is not set # CONFIG_HZ_256 is not set -# CONFIG_HZ_1000 is not set +CONFIG_HZ_1000=y # CONFIG_HZ_1024 is not set CONFIG_SYS_SUPPORTS_ARBIT_HZ=y -CONFIG_HZ=250 +CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set @@ -164,20 +171,16 @@ CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set +CONFIG_SYSCTL=y # CONFIG_AUDIT is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y # CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_SYSCTL=y CONFIG_EMBEDDED=y -# CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set @@ -186,12 +189,12 @@ CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y +CONFIG_RT_MUTEXES=y CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_SHMEM=y CONFIG_SLAB=y CONFIG_VM_EVENT_COUNTERS=y -CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 # CONFIG_SLOB is not set @@ -208,7 +211,6 @@ CONFIG_KMOD=y # # Block layer # -CONFIG_BLOCK=y # CONFIG_LBD is not set # CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_LSF is not set @@ -229,10 +231,8 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # -CONFIG_HW_HAS_PCI=y -CONFIG_PCI=y -# CONFIG_PCI_MULTITHREAD_PROBE is not set -# CONFIG_PCI_DEBUG is not set +CONFIG_HW_HAS_EISA=y +# CONFIG_EISA is not set CONFIG_MMU=y # @@ -243,7 +243,6 @@ CONFIG_MMU=y # # PCI Hotplug Support # -# CONFIG_HOTPLUG_PCI is not set # # Executable file formats @@ -266,7 +265,6 @@ CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set # CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set @@ -285,18 +283,16 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_INET_IPCOMP is not set # CONFIG_INET_XFRM_TUNNEL is not set # CONFIG_INET_TUNNEL is not set -CONFIG_INET_XFRM_MODE_TRANSPORT=y -CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" +CONFIG_TCP_CONG_BIC=y # CONFIG_IPV6 is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set -# CONFIG_NETWORK_SECMARK is not set +CONFIG_NETWORK_SECMARK=y # CONFIG_NETFILTER is not set # @@ -322,6 +318,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_ATALK is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set @@ -374,20 +371,13 @@ CONFIG_FW_LOADER=y # # Block devices # -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_CRYPTOLOOP is not set # CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_SX8 is not set -# CONFIG_BLK_DEV_UB is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=8192 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set @@ -396,7 +386,6 @@ CONFIG_BLK_DEV_INITRD=y # ATA/ATAPI/MFM/RLL support # CONFIG_IDE=y -CONFIG_IDE_MAX_HWIFS=4 CONFIG_BLK_DEV_IDE=y # @@ -415,39 +404,8 @@ CONFIG_BLK_DEV_IDESCSI=y # IDE chipset support/bugfixes # CONFIG_IDE_GENERIC=y -CONFIG_BLK_DEV_IDEPCI=y -CONFIG_IDEPCI_SHARE_IRQ=y -CONFIG_BLK_DEV_OFFBOARD=y -CONFIG_BLK_DEV_GENERIC=y -# CONFIG_BLK_DEV_OPTI621 is not set -CONFIG_BLK_DEV_IDEDMA_PCI=y -# CONFIG_BLK_DEV_IDEDMA_FORCED is not set -# CONFIG_IDEDMA_PCI_AUTO is not set -# CONFIG_BLK_DEV_AEC62XX is not set -# CONFIG_BLK_DEV_ALI15X3 is not set -# CONFIG_BLK_DEV_AMD74XX is not set -# CONFIG_BLK_DEV_CMD64X is not set -# CONFIG_BLK_DEV_TRIFLEX is not set -# CONFIG_BLK_DEV_CY82C693 is not set -# CONFIG_BLK_DEV_CS5520 is not set -# CONFIG_BLK_DEV_CS5530 is not set -# CONFIG_BLK_DEV_HPT34X is not set -CONFIG_BLK_DEV_HPT366=y -# CONFIG_BLK_DEV_JMICRON is not set -# CONFIG_BLK_DEV_SC1200 is not set -# CONFIG_BLK_DEV_PIIX is not set -# CONFIG_BLK_DEV_IT821X is not set -# CONFIG_BLK_DEV_NS87415 is not set -# CONFIG_BLK_DEV_PDC202XX_OLD is not set -# CONFIG_BLK_DEV_PDC202XX_NEW is not set -# CONFIG_BLK_DEV_SVWKS is not set -# CONFIG_BLK_DEV_SIIMAGE is not set -# CONFIG_BLK_DEV_SLC90E66 is not set -# CONFIG_BLK_DEV_TRM290 is not set -# CONFIG_BLK_DEV_VIA82CXXX is not set # CONFIG_IDE_ARM is not set -CONFIG_BLK_DEV_IDEDMA=y -# CONFIG_IDEDMA_IVB is not set +# CONFIG_BLK_DEV_IDEDMA is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_BLK_DEV_HD is not set @@ -456,7 +414,6 @@ CONFIG_BLK_DEV_IDEDMA=y # # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y -CONFIG_SCSI_NETLINK=y CONFIG_SCSI_PROC_FS=y # @@ -477,53 +434,21 @@ CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_LOGGING is not set # -# SCSI Transports +# SCSI Transport Attributes # # CONFIG_SCSI_SPI_ATTRS is not set CONFIG_SCSI_FC_ATTRS=y CONFIG_SCSI_ISCSI_ATTRS=m # CONFIG_SCSI_SAS_ATTRS is not set -# CONFIG_SCSI_SAS_LIBSAS is not set # # SCSI low-level drivers # CONFIG_ISCSI_TCP=m -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_SCSI_3W_9XXX is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AACRAID is not set -# CONFIG_SCSI_AIC7XXX is not set -# CONFIG_SCSI_AIC7XXX_OLD is not set -# CONFIG_SCSI_AIC79XX is not set -# CONFIG_SCSI_AIC94XX is not set -# CONFIG_SCSI_DPT_I2O is not set -# CONFIG_SCSI_ARCMSR is not set -# CONFIG_MEGARAID_NEWGEN is not set -# CONFIG_MEGARAID_LEGACY is not set -# CONFIG_MEGARAID_SAS is not set -# CONFIG_SCSI_HPTIOP is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_IPS is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_STEX is not set -# CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_QLOGIC_1280 is not set -# CONFIG_SCSI_QLA_FC is not set -# CONFIG_SCSI_QLA_ISCSI is not set -# CONFIG_SCSI_LPFC is not set -# CONFIG_SCSI_DC395x is not set -# CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_NSP32 is not set +# CONFIG_SGIWD93_SCSI is not set +# CONFIG_SCSI_SATA is not set # CONFIG_SCSI_DEBUG is not set -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# -# CONFIG_ATA is not set - # # Multi-device support (RAID and LVM) # @@ -533,19 +458,14 @@ CONFIG_ISCSI_TCP=m # Fusion MPT device support # # CONFIG_FUSION is not set -# CONFIG_FUSION_SPI is not set -# CONFIG_FUSION_FC is not set -# CONFIG_FUSION_SAS is not set # # IEEE 1394 (FireWire) support # -# CONFIG_IEEE1394 is not set # # I2O device support # -# CONFIG_I2O is not set # # Network device support @@ -556,11 +476,6 @@ CONFIG_NETDEVICES=y # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set -# -# ARCnet devices -# -# CONFIG_ARCNET is not set - # # PHY device support # @@ -571,73 +486,20 @@ CONFIG_NETDEVICES=y # CONFIG_NET_ETHERNET=y CONFIG_MII=y -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNGEM is not set -# CONFIG_CASSINI is not set -# CONFIG_NET_VENDOR_3COM is not set # CONFIG_DM9000 is not set - -# -# Tulip family network device support -# -# CONFIG_NET_TULIP is not set -# CONFIG_HP100 is not set -CONFIG_NET_PCI=y -# CONFIG_PCNET32 is not set -# CONFIG_AMD8111_ETH is not set -# CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_B44 is not set -# CONFIG_FORCEDETH is not set -# CONFIG_DGRS is not set -# CONFIG_EEPRO100 is not set -# CONFIG_E100 is not set -# CONFIG_FEALNX is not set -# CONFIG_NATSEMI is not set -# CONFIG_NE2K_PCI is not set -# CONFIG_8139CP is not set -CONFIG_8139TOO=y -# CONFIG_8139TOO_PIO is not set -CONFIG_8139TOO_TUNE_TWISTER=y -CONFIG_8139TOO_8129=y -# CONFIG_8139_OLD_RX_RESET is not set -# CONFIG_SIS900 is not set -# CONFIG_EPIC100 is not set -# CONFIG_SUNDANCE is not set -# CONFIG_TLAN is not set -# CONFIG_VIA_RHINE is not set -# CONFIG_LAN_SAA9730 is not set +# CONFIG_SGISEEQ is not set # # Ethernet (1000 Mbit) # -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_E1000 is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_R8169 is not set -# CONFIG_SIS190 is not set -# CONFIG_SKGE is not set -# CONFIG_SKY2 is not set -# CONFIG_SK98LIN is not set -# CONFIG_VIA_VELOCITY is not set -# CONFIG_TIGON3 is not set -# CONFIG_BNX2 is not set -# CONFIG_QLA3XXX is not set # # Ethernet (10000 Mbit) # -# CONFIG_CHELSIO_T1 is not set -# CONFIG_IXGB is not set -# CONFIG_S2IO is not set -# CONFIG_MYRI10GE is not set # # Token Ring devices # -# CONFIG_TR is not set # # Wireless LAN (non-hamradio) @@ -648,11 +510,8 @@ CONFIG_8139TOO_8129=y # Wan interfaces # # CONFIG_WAN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set -# CONFIG_NET_FC is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set @@ -672,7 +531,6 @@ CONFIG_8139TOO_8129=y # Input device support # CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set # # Userland interfaces @@ -698,7 +556,6 @@ CONFIG_INPUT=y CONFIG_SERIO=y # CONFIG_SERIO_I8042 is not set # CONFIG_SERIO_SERPORT is not set -# CONFIG_SERIO_PCIPS2 is not set CONFIG_SERIO_LIBPS2=y # CONFIG_SERIO_RAW is not set # CONFIG_GAMEPORT is not set @@ -709,7 +566,7 @@ CONFIG_SERIO_LIBPS2=y CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y -# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_VT_HW_CONSOLE_BINDING=y # CONFIG_SERIAL_NONSTANDARD is not set # @@ -720,8 +577,7 @@ CONFIG_HW_CONSOLE=y # # Non-8250 serial port support # -# CONFIG_SERIAL_IP3106 is not set -# CONFIG_SERIAL_JSM is not set +# CONFIG_SERIAL_IP22_ZILOG is not set CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -735,17 +591,16 @@ CONFIG_LEGACY_PTY_COUNT=256 # Watchdog Cards # # CONFIG_WATCHDOG is not set -CONFIG_HW_RANDOM=y +# CONFIG_HW_RANDOM is not set # CONFIG_RTC is not set +# CONFIG_SGI_DS1286 is not set # CONFIG_GEN_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set # # Ftape, the floppy tape device driver # -# CONFIG_DRM is not set # CONFIG_RAW_DRIVER is not set # @@ -776,37 +631,35 @@ CONFIG_HWMON=y # CONFIG_HWMON_VID is not set # CONFIG_SENSORS_ABITUGURU is not set # CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_VT1211 is not set # CONFIG_HWMON_DEBUG_CHIP is not set # # Misc devices # -# CONFIG_TIFM_CORE is not set # # Multimedia devices # # CONFIG_VIDEO_DEV is not set +CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices # # CONFIG_DVB is not set -# CONFIG_USB_DABUSB is not set # # Graphics support # -CONFIG_FIRMWARE_EDID=y +# CONFIG_FIRMWARE_EDID is not set # CONFIG_FB is not set # # Console display driver support # # CONFIG_VGA_CONSOLE is not set +# CONFIG_SGI_NEWPORT_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -816,130 +669,14 @@ CONFIG_DUMMY_CONSOLE=y # # USB support # -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB_ARCH_HAS_EHCI=y -CONFIG_USB=y -# CONFIG_USB_DEBUG is not set - -# -# Miscellaneous USB options -# -# CONFIG_USB_DEVICEFS is not set -# CONFIG_USB_BANDWIDTH is not set -# CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_OTG is not set - -# -# USB Host Controller Drivers -# -# CONFIG_USB_EHCI_HCD is not set -# CONFIG_USB_ISP116X_HCD is not set -CONFIG_USB_OHCI_HCD=y -# CONFIG_USB_OHCI_BIG_ENDIAN is not set -CONFIG_USB_OHCI_LITTLE_ENDIAN=y -# CONFIG_USB_UHCI_HCD is not set -# CONFIG_USB_SL811_HCD is not set - -# -# USB Device Class drivers -# -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set +# CONFIG_USB_ARCH_HAS_HCD is not set +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB_ARCH_HAS_EHCI is not set # # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' # -# -# may also be needed; see USB_STORAGE Help for more information -# -CONFIG_USB_STORAGE=y -# CONFIG_USB_STORAGE_DEBUG is not set -CONFIG_USB_STORAGE_DATAFAB=y -CONFIG_USB_STORAGE_FREECOM=y -CONFIG_USB_STORAGE_ISD200=y -CONFIG_USB_STORAGE_DPCM=y -CONFIG_USB_STORAGE_USBAT=y -CONFIG_USB_STORAGE_SDDR09=y -CONFIG_USB_STORAGE_SDDR55=y -CONFIG_USB_STORAGE_JUMPSHOT=y -# CONFIG_USB_STORAGE_ALAUDA is not set -# CONFIG_USB_STORAGE_KARMA is not set -# CONFIG_USB_LIBUSUAL is not set - -# -# USB Input Devices -# -# CONFIG_USB_HID is not set - -# -# USB HID Boot Protocol drivers -# -# CONFIG_USB_KBD is not set -# CONFIG_USB_MOUSE is not set -# CONFIG_USB_AIPTEK is not set -# CONFIG_USB_WACOM is not set -# CONFIG_USB_ACECAD is not set -# CONFIG_USB_KBTAB is not set -# CONFIG_USB_POWERMATE is not set -# CONFIG_USB_TOUCHSCREEN is not set -# CONFIG_USB_YEALINK is not set -# CONFIG_USB_XPAD is not set -# CONFIG_USB_ATI_REMOTE is not set -# CONFIG_USB_ATI_REMOTE2 is not set -# CONFIG_USB_KEYSPAN_REMOTE is not set -# CONFIG_USB_APPLETOUCH is not set -# CONFIG_USB_TRANCEVIBRATOR is not set - -# -# USB Imaging devices -# -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_MICROTEK is not set - -# -# USB Network Adapters -# -# CONFIG_USB_CATC is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RTL8150 is not set -# CONFIG_USB_USBNET is not set -CONFIG_USB_MON=y - -# -# USB port drivers -# - -# -# USB Serial Converter support -# -# CONFIG_USB_SERIAL is not set - -# -# USB Miscellaneous drivers -# -# CONFIG_USB_EMI62 is not set -# CONFIG_USB_EMI26 is not set -# CONFIG_USB_ADUTUX is not set -# CONFIG_USB_AUERSWALD is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_LEGOTOWER is not set -# CONFIG_USB_LCD is not set -# CONFIG_USB_LED is not set -# CONFIG_USB_CYPRESS_CY7C63 is not set -# CONFIG_USB_CYTHERM is not set -# CONFIG_USB_PHIDGET is not set -# CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_FTDI_ELAN is not set -# CONFIG_USB_APPLEDISPLAY is not set -# CONFIG_USB_LD is not set - -# -# USB DSL modem support -# - # # USB Gadget Support # @@ -966,7 +703,6 @@ CONFIG_USB_MON=y # # InfiniBand support # -# CONFIG_INFINIBAND is not set # # EDAC - error detection and reporting (RAS) (EXPERIMENTAL) @@ -997,12 +733,10 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set # CONFIG_EXT2_FS_XIP is not set # CONFIG_EXT3_FS is not set -# CONFIG_EXT4DEV_FS is not set # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set # CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set @@ -1035,10 +769,8 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" # CONFIG_PROC_FS=y # CONFIG_PROC_KCORE is not set -CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set @@ -1081,6 +813,7 @@ CONFIG_SUNRPC=y # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set # CONFIG_CIFS is not set +# CONFIG_CIFS_DEBUG2 is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set @@ -1091,6 +824,7 @@ CONFIG_SUNRPC=y # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y +CONFIG_SGI_PARTITION=y # # Native Language Support @@ -1146,7 +880,6 @@ CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_MUST_CHECK=y CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_KERNEL=y @@ -1160,17 +893,13 @@ CONFIG_DEBUG_SLAB=y # CONFIG_DEBUG_SPINLOCK is not set CONFIG_DEBUG_MUTEXES=y # CONFIG_DEBUG_RWSEMS is not set -# CONFIG_DEBUG_LOCK_ALLOC is not set -# CONFIG_PROVE_LOCKING is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_INFO is not set # CONFIG_DEBUG_FS is not set # CONFIG_DEBUG_VM is not set -# CONFIG_DEBUG_LIST is not set CONFIG_FORCED_INLINING=y -# CONFIG_HEADERS_CHECK is not set # CONFIG_RCU_TORTURE_TEST is not set CONFIG_CROSSCOMPILE=y CONFIG_CMDLINE="console=ttyS1,38400n8 kgdb=ttyS0 root=/dev/nfs ip=bootp" @@ -1189,9 +918,6 @@ CONFIG_CMDLINE="console=ttyS1,38400n8 kgdb=ttyS0 root=/dev/nfs ip=bootp" # Cryptographic options # CONFIG_CRYPTO=y -CONFIG_CRYPTO_ALGAPI=m -CONFIG_CRYPTO_BLKCIPHER=m -CONFIG_CRYPTO_MANAGER=m # CONFIG_CRYPTO_HMAC is not set # CONFIG_CRYPTO_NULL is not set # CONFIG_CRYPTO_MD4 is not set @@ -1201,8 +927,6 @@ CONFIG_CRYPTO_MD5=m # CONFIG_CRYPTO_SHA512 is not set # CONFIG_CRYPTO_WP512 is not set # CONFIG_CRYPTO_TGR192 is not set -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_CBC=m # CONFIG_CRYPTO_DES is not set # CONFIG_CRYPTO_BLOWFISH is not set # CONFIG_CRYPTO_TWOFISH is not set diff --git a/trunk/arch/mips/configs/pnx8550-v2pci_defconfig b/trunk/arch/mips/configs/pnx8550-v2pci_defconfig index 64b9fbf44a64..e93266b37dd9 100644 --- a/trunk/arch/mips/configs/pnx8550-v2pci_defconfig +++ b/trunk/arch/mips/configs/pnx8550-v2pci_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.19-rc2 -# Sat Oct 14 23:12:15 2006 +# Linux kernel version: 2.6.18-rc1 +# Thu Jul 6 10:04:18 2006 # CONFIG_MIPS=y @@ -25,6 +25,8 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set @@ -38,14 +40,14 @@ CONFIG_MIPS=y # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set -CONFIG_PNX8550_V2PCI=y +# CONFIG_PNX8550_V2PCI is not set # CONFIG_PNX8550_JBS is not set # CONFIG_DDB5477 is not set # CONFIG_MACH_VR41XX is not set # CONFIG_PMC_YOSEMITE is not set # CONFIG_QEMU is not set # CONFIG_MARKEINS is not set -# CONFIG_SGI_IP22 is not set +CONFIG_SGI_IP22=y # CONFIG_SGI_IP27 is not set # CONFIG_SGI_IP32 is not set # CONFIG_SIBYTE_BIGSUR is not set @@ -65,21 +67,25 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_TIME=y CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_ARC=y CONFIG_DMA_NONCOHERENT=y CONFIG_DMA_NEED_PCI_MAP_STATE=y -# CONFIG_CPU_BIG_ENDIAN is not set -CONFIG_CPU_LITTLE_ENDIAN=y -CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y -CONFIG_PNX8550=y -CONFIG_SOC_PNX8550=y +CONFIG_CPU_BIG_ENDIAN=y +# CONFIG_CPU_LITTLE_ENDIAN is not set +CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y +CONFIG_IRQ_CPU=y +CONFIG_SWAP_IO_SPACE=y +CONFIG_ARC32=y +CONFIG_BOOT_ELF32=y CONFIG_MIPS_L1_CACHE_SHIFT=5 +# CONFIG_ARC_CONSOLE is not set +CONFIG_ARC_PROMLIB=y # # CPU selection # -CONFIG_CPU_MIPS32_R1=y +# CONFIG_CPU_MIPS32_R1 is not set # CONFIG_CPU_MIPS32_R2 is not set # CONFIG_CPU_MIPS64_R1 is not set # CONFIG_CPU_MIPS64_R2 is not set @@ -87,7 +93,7 @@ CONFIG_CPU_MIPS32_R1=y # CONFIG_CPU_TX39XX is not set # CONFIG_CPU_VR41XX is not set # CONFIG_CPU_R4300 is not set -# CONFIG_CPU_R4X00 is not set +CONFIG_CPU_R4X00=y # CONFIG_CPU_TX49XX is not set # CONFIG_CPU_R5000 is not set # CONFIG_CPU_R5432 is not set @@ -98,11 +104,12 @@ CONFIG_CPU_MIPS32_R1=y # CONFIG_CPU_RM7000 is not set # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set -CONFIG_SYS_HAS_CPU_MIPS32_R1=y -CONFIG_CPU_MIPS32=y -CONFIG_CPU_MIPSR1=y +CONFIG_SYS_HAS_CPU_R4X00=y +CONFIG_SYS_HAS_CPU_R5000=y CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y +CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y # # Kernel type @@ -113,17 +120,17 @@ CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set -CONFIG_CPU_HAS_PREFETCH=y +CONFIG_BOARD_SCACHE=y +CONFIG_IP22_CPU_SCACHE=y CONFIG_MIPS_MT_DISABLED=y -# CONFIG_MIPS_MT_SMP is not set # CONFIG_MIPS_MT_SMTC is not set +# CONFIG_MIPS_MT_SMP is not set # CONFIG_MIPS_VPE_LOADER is not set # CONFIG_64BIT_PHYS_ADDR is not set CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_CPU_SUPPORTS_HIGHMEM=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y @@ -137,12 +144,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_HZ_48 is not set # CONFIG_HZ_100 is not set # CONFIG_HZ_128 is not set -CONFIG_HZ_250=y +# CONFIG_HZ_250 is not set # CONFIG_HZ_256 is not set -# CONFIG_HZ_1000 is not set +CONFIG_HZ_1000=y # CONFIG_HZ_1024 is not set CONFIG_SYS_SUPPORTS_ARBIT_HZ=y -CONFIG_HZ=250 +CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set @@ -164,20 +171,16 @@ CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set +CONFIG_SYSCTL=y # CONFIG_AUDIT is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y # CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_SYSCTL=y CONFIG_EMBEDDED=y -# CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set CONFIG_HOTPLUG=y @@ -185,12 +188,12 @@ CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y +CONFIG_RT_MUTEXES=y CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_SHMEM=y CONFIG_SLAB=y CONFIG_VM_EVENT_COUNTERS=y -CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 # CONFIG_SLOB is not set @@ -207,7 +210,6 @@ CONFIG_KMOD=y # # Block layer # -CONFIG_BLOCK=y # CONFIG_LBD is not set # CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_LSF is not set @@ -228,9 +230,8 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # -CONFIG_HW_HAS_PCI=y -CONFIG_PCI=y -# CONFIG_PCI_MULTITHREAD_PROBE is not set +CONFIG_HW_HAS_EISA=y +# CONFIG_EISA is not set CONFIG_MMU=y # @@ -241,7 +242,6 @@ CONFIG_MMU=y # # PCI Hotplug Support # -# CONFIG_HOTPLUG_PCI is not set # # Executable file formats @@ -264,7 +264,6 @@ CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set # CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set @@ -283,14 +282,12 @@ CONFIG_IP_PNP=y # CONFIG_INET_IPCOMP is not set # CONFIG_INET_XFRM_TUNNEL is not set # CONFIG_INET_TUNNEL is not set -CONFIG_INET_XFRM_MODE_TRANSPORT=y -CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" +CONFIG_TCP_CONG_BIC=y # # IP: Virtual Server Configuration @@ -303,18 +300,12 @@ CONFIG_IPV6_ROUTE_INFO=y # CONFIG_INET6_AH is not set # CONFIG_INET6_ESP is not set # CONFIG_INET6_IPCOMP is not set -# CONFIG_IPV6_MIP6 is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set CONFIG_INET6_XFRM_MODE_TRANSPORT=m CONFIG_INET6_XFRM_MODE_TUNNEL=m -CONFIG_INET6_XFRM_MODE_BEET=m -# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set -CONFIG_IPV6_SIT=m # CONFIG_IPV6_TUNNEL is not set -# CONFIG_IPV6_SUBTREES is not set -# CONFIG_IPV6_MULTIPLE_TABLES is not set -# CONFIG_NETWORK_SECMARK is not set +CONFIG_NETWORK_SECMARK=y CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set @@ -327,9 +318,9 @@ CONFIG_NETFILTER_XTABLES=m CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m CONFIG_NETFILTER_XT_TARGET_MARK=m CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_SECMARK=m CONFIG_NETFILTER_XT_MATCH_COMMENT=m CONFIG_NETFILTER_XT_MATCH_DCCP=m -# CONFIG_NETFILTER_XT_MATCH_DSCP is not set CONFIG_NETFILTER_XT_MATCH_ESP=m CONFIG_NETFILTER_XT_MATCH_LENGTH=m CONFIG_NETFILTER_XT_MATCH_LIMIT=m @@ -338,10 +329,10 @@ CONFIG_NETFILTER_XT_MATCH_MARK=m # CONFIG_NETFILTER_XT_MATCH_POLICY is not set CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m -# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set +CONFIG_NETFILTER_XT_MATCH_QUOTA=m CONFIG_NETFILTER_XT_MATCH_REALM=m CONFIG_NETFILTER_XT_MATCH_SCTP=m -# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m CONFIG_NETFILTER_XT_MATCH_STRING=m CONFIG_NETFILTER_XT_MATCH_TCPMSS=m @@ -382,6 +373,7 @@ CONFIG_NETFILTER_XT_MATCH_TCPMSS=m # CONFIG_ATALK is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set @@ -434,20 +426,13 @@ CONFIG_FW_LOADER=y # # Block devices # -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_CRYPTOLOOP is not set # CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_SX8 is not set -# CONFIG_BLK_DEV_UB is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=8192 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set @@ -456,7 +441,6 @@ CONFIG_BLK_DEV_INITRD=y # ATA/ATAPI/MFM/RLL support # CONFIG_IDE=y -CONFIG_IDE_MAX_HWIFS=4 CONFIG_BLK_DEV_IDE=y # @@ -475,41 +459,9 @@ CONFIG_IDEDISK_MULTI_MODE=y # IDE chipset support/bugfixes # CONFIG_IDE_GENERIC=y -CONFIG_BLK_DEV_IDEPCI=y -CONFIG_IDEPCI_SHARE_IRQ=y -# CONFIG_BLK_DEV_OFFBOARD is not set -# CONFIG_BLK_DEV_GENERIC is not set -# CONFIG_BLK_DEV_OPTI621 is not set -CONFIG_BLK_DEV_IDEDMA_PCI=y -# CONFIG_BLK_DEV_IDEDMA_FORCED is not set -CONFIG_IDEDMA_PCI_AUTO=y -# CONFIG_IDEDMA_ONLYDISK is not set -# CONFIG_BLK_DEV_AEC62XX is not set -# CONFIG_BLK_DEV_ALI15X3 is not set -# CONFIG_BLK_DEV_AMD74XX is not set -CONFIG_BLK_DEV_CMD64X=y -# CONFIG_BLK_DEV_TRIFLEX is not set -# CONFIG_BLK_DEV_CY82C693 is not set -# CONFIG_BLK_DEV_CS5520 is not set -# CONFIG_BLK_DEV_CS5530 is not set -# CONFIG_BLK_DEV_HPT34X is not set -# CONFIG_BLK_DEV_HPT366 is not set -# CONFIG_BLK_DEV_JMICRON is not set -# CONFIG_BLK_DEV_SC1200 is not set -# CONFIG_BLK_DEV_PIIX is not set -# CONFIG_BLK_DEV_IT821X is not set -# CONFIG_BLK_DEV_NS87415 is not set -# CONFIG_BLK_DEV_PDC202XX_OLD is not set -# CONFIG_BLK_DEV_PDC202XX_NEW is not set -# CONFIG_BLK_DEV_SVWKS is not set -# CONFIG_BLK_DEV_SIIMAGE is not set -# CONFIG_BLK_DEV_SLC90E66 is not set -# CONFIG_BLK_DEV_TRM290 is not set -# CONFIG_BLK_DEV_VIA82CXXX is not set # CONFIG_IDE_ARM is not set -CONFIG_BLK_DEV_IDEDMA=y -# CONFIG_IDEDMA_IVB is not set -CONFIG_IDEDMA_AUTO=y +# CONFIG_BLK_DEV_IDEDMA is not set +# CONFIG_IDEDMA_AUTO is not set # CONFIG_BLK_DEV_HD is not set # @@ -517,7 +469,6 @@ CONFIG_IDEDMA_AUTO=y # # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y -CONFIG_SCSI_NETLINK=y CONFIG_SCSI_PROC_FS=y # @@ -538,58 +489,21 @@ CONFIG_BLK_DEV_SD=y # CONFIG_SCSI_LOGGING is not set # -# SCSI Transports +# SCSI Transport Attributes # CONFIG_SCSI_SPI_ATTRS=m CONFIG_SCSI_FC_ATTRS=y CONFIG_SCSI_ISCSI_ATTRS=m # CONFIG_SCSI_SAS_ATTRS is not set -# CONFIG_SCSI_SAS_LIBSAS is not set # # SCSI low-level drivers # CONFIG_ISCSI_TCP=m -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_SCSI_3W_9XXX is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AACRAID is not set -CONFIG_SCSI_AIC7XXX=m -CONFIG_AIC7XXX_CMDS_PER_DEVICE=32 -CONFIG_AIC7XXX_RESET_DELAY_MS=15000 -# CONFIG_AIC7XXX_DEBUG_ENABLE is not set -CONFIG_AIC7XXX_DEBUG_MASK=0 -# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set -# CONFIG_SCSI_AIC7XXX_OLD is not set -# CONFIG_SCSI_AIC79XX is not set -# CONFIG_SCSI_AIC94XX is not set -# CONFIG_SCSI_DPT_I2O is not set -# CONFIG_SCSI_ARCMSR is not set -# CONFIG_MEGARAID_NEWGEN is not set -# CONFIG_MEGARAID_LEGACY is not set -# CONFIG_MEGARAID_SAS is not set -# CONFIG_SCSI_HPTIOP is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_IPS is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_STEX is not set -# CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_QLOGIC_1280 is not set -# CONFIG_SCSI_QLA_FC is not set -# CONFIG_SCSI_QLA_ISCSI is not set -# CONFIG_SCSI_LPFC is not set -# CONFIG_SCSI_DC395x is not set -# CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_NSP32 is not set +# CONFIG_SGIWD93_SCSI is not set +# CONFIG_SCSI_SATA is not set # CONFIG_SCSI_DEBUG is not set -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# -# CONFIG_ATA is not set - # # Multi-device support (RAID and LVM) # @@ -599,19 +513,14 @@ CONFIG_AIC7XXX_DEBUG_MASK=0 # Fusion MPT device support # # CONFIG_FUSION is not set -# CONFIG_FUSION_SPI is not set -# CONFIG_FUSION_FC is not set -# CONFIG_FUSION_SAS is not set # # IEEE 1394 (FireWire) support # -# CONFIG_IEEE1394 is not set # # I2O device support # -# CONFIG_I2O is not set # # Network device support @@ -622,11 +531,6 @@ CONFIG_NETDEVICES=y # CONFIG_EQUALIZER is not set CONFIG_TUN=m -# -# ARCnet devices -# -# CONFIG_ARCNET is not set - # # PHY device support # @@ -637,73 +541,20 @@ CONFIG_TUN=m # CONFIG_NET_ETHERNET=y CONFIG_MII=y -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNGEM is not set -# CONFIG_CASSINI is not set -# CONFIG_NET_VENDOR_3COM is not set # CONFIG_DM9000 is not set - -# -# Tulip family network device support -# -# CONFIG_NET_TULIP is not set -# CONFIG_HP100 is not set -CONFIG_NET_PCI=y -# CONFIG_PCNET32 is not set -# CONFIG_AMD8111_ETH is not set -# CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_B44 is not set -# CONFIG_FORCEDETH is not set -# CONFIG_DGRS is not set -# CONFIG_EEPRO100 is not set -# CONFIG_E100 is not set -# CONFIG_FEALNX is not set -CONFIG_NATSEMI=y -# CONFIG_NE2K_PCI is not set -# CONFIG_8139CP is not set -CONFIG_8139TOO=y -# CONFIG_8139TOO_PIO is not set -# CONFIG_8139TOO_TUNE_TWISTER is not set -# CONFIG_8139TOO_8129 is not set -# CONFIG_8139_OLD_RX_RESET is not set -# CONFIG_SIS900 is not set -# CONFIG_EPIC100 is not set -# CONFIG_SUNDANCE is not set -# CONFIG_TLAN is not set -# CONFIG_VIA_RHINE is not set -# CONFIG_LAN_SAA9730 is not set +# CONFIG_SGISEEQ is not set # # Ethernet (1000 Mbit) # -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_E1000 is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_R8169 is not set -# CONFIG_SIS190 is not set -# CONFIG_SKGE is not set -# CONFIG_SKY2 is not set -# CONFIG_SK98LIN is not set -# CONFIG_VIA_VELOCITY is not set -# CONFIG_TIGON3 is not set -# CONFIG_BNX2 is not set -# CONFIG_QLA3XXX is not set # # Ethernet (10000 Mbit) # -# CONFIG_CHELSIO_T1 is not set -# CONFIG_IXGB is not set -# CONFIG_S2IO is not set -# CONFIG_MYRI10GE is not set # # Token Ring devices # -# CONFIG_TR is not set # # Wireless LAN (non-hamradio) @@ -714,8 +565,6 @@ CONFIG_8139TOO=y # Wan interfaces # # CONFIG_WAN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set CONFIG_PPP=m # CONFIG_PPP_MULTILINK is not set # CONFIG_PPP_FILTER is not set @@ -726,8 +575,6 @@ CONFIG_PPP_DEFLATE=m CONFIG_PPP_MPPE=m # CONFIG_PPPOE is not set # CONFIG_SLIP is not set -CONFIG_SLHC=m -# CONFIG_NET_FC is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set @@ -747,7 +594,6 @@ CONFIG_SLHC=m # Input device support # CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set # # Userland interfaces @@ -770,7 +616,6 @@ CONFIG_KEYBOARD_ATKBD=y # CONFIG_KEYBOARD_LKKBD is not set # CONFIG_KEYBOARD_XTKBD is not set # CONFIG_KEYBOARD_NEWTON is not set -# CONFIG_KEYBOARD_STOWAWAY is not set CONFIG_INPUT_MOUSE=y CONFIG_MOUSE_PS2=y # CONFIG_MOUSE_SERIAL is not set @@ -785,7 +630,6 @@ CONFIG_MOUSE_PS2=y CONFIG_SERIO=y CONFIG_SERIO_I8042=y CONFIG_SERIO_SERPORT=y -# CONFIG_SERIO_PCIPS2 is not set CONFIG_SERIO_LIBPS2=y # CONFIG_SERIO_RAW is not set # CONFIG_GAMEPORT is not set @@ -796,7 +640,7 @@ CONFIG_SERIO_LIBPS2=y CONFIG_VT=y # CONFIG_VT_CONSOLE is not set CONFIG_HW_CONSOLE=y -# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_VT_HW_CONSOLE_BINDING=y CONFIG_SERIAL_NONSTANDARD=y # CONFIG_COMPUTONE is not set # CONFIG_ROCKETPORT is not set @@ -806,7 +650,6 @@ CONFIG_SERIAL_NONSTANDARD=y # CONFIG_MOXA_SMARTIO is not set # CONFIG_ISI is not set # CONFIG_SYNCLINKMP is not set -# CONFIG_SYNCLINK_GT is not set # CONFIG_N_HDLC is not set # CONFIG_RISCOM8 is not set # CONFIG_SPECIALIX is not set @@ -822,8 +665,7 @@ CONFIG_SERIAL_NONSTANDARD=y # # Non-8250 serial port support # -# CONFIG_SERIAL_IP3106 is not set -# CONFIG_SERIAL_JSM is not set +# CONFIG_SERIAL_IP22_ZILOG is not set CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -837,17 +679,16 @@ CONFIG_LEGACY_PTY_COUNT=256 # Watchdog Cards # # CONFIG_WATCHDOG is not set -CONFIG_HW_RANDOM=y +# CONFIG_HW_RANDOM is not set # CONFIG_RTC is not set +# CONFIG_SGI_DS1286 is not set # CONFIG_GEN_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set # # Ftape, the floppy tape device driver # -# CONFIG_DRM is not set # CONFIG_RAW_DRIVER is not set # @@ -868,30 +709,14 @@ CONFIG_I2C_CHARDEV=m CONFIG_I2C_ALGOBIT=m # CONFIG_I2C_ALGOPCF is not set # CONFIG_I2C_ALGOPCA is not set +# CONFIG_I2C_ALGO_SGI is not set # # I2C Hardware Bus support # -# CONFIG_I2C_ALI1535 is not set -# CONFIG_I2C_ALI1563 is not set -# CONFIG_I2C_ALI15X3 is not set -# CONFIG_I2C_AMD756 is not set -# CONFIG_I2C_AMD8111 is not set -# CONFIG_I2C_I801 is not set -# CONFIG_I2C_I810 is not set -# CONFIG_I2C_PIIX4 is not set -# CONFIG_I2C_NFORCE2 is not set # CONFIG_I2C_OCORES is not set # CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_PROSAVAGE is not set -# CONFIG_I2C_SAVAGE4 is not set -# CONFIG_I2C_SIS5595 is not set -# CONFIG_I2C_SIS630 is not set -# CONFIG_I2C_SIS96X is not set # CONFIG_I2C_STUB is not set -# CONFIG_I2C_VIA is not set -# CONFIG_I2C_VIAPRO is not set -# CONFIG_I2C_VOODOO3 is not set # CONFIG_I2C_PCA_ISA is not set # @@ -951,13 +776,9 @@ CONFIG_HWMON=y # CONFIG_SENSORS_LM92 is not set # CONFIG_SENSORS_MAX1619 is not set # CONFIG_SENSORS_PC87360 is not set -# CONFIG_SENSORS_SIS5595 is not set # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_SMSC47M192 is not set # CONFIG_SENSORS_SMSC47B397 is not set -# CONFIG_SENSORS_VIA686A is not set -# CONFIG_SENSORS_VT1211 is not set -# CONFIG_SENSORS_VT8231 is not set # CONFIG_SENSORS_W83781D is not set # CONFIG_SENSORS_W83791D is not set # CONFIG_SENSORS_W83792D is not set @@ -969,25 +790,23 @@ CONFIG_HWMON=y # # Misc devices # -# CONFIG_TIFM_CORE is not set # # Multimedia devices # # CONFIG_VIDEO_DEV is not set +CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices # # CONFIG_DVB is not set -# CONFIG_USB_DABUSB is not set # # Graphics support # -CONFIG_FIRMWARE_EDID=y +# CONFIG_FIRMWARE_EDID is not set CONFIG_FB=y -# CONFIG_FB_DDC is not set # CONFIG_FB_CFB_FILLRECT is not set # CONFIG_FB_CFB_COPYAREA is not set # CONFIG_FB_CFB_IMAGEBLIT is not set @@ -995,32 +814,14 @@ CONFIG_FB=y # CONFIG_FB_BACKLIGHT is not set # CONFIG_FB_MODE_HELPERS is not set # CONFIG_FB_TILEBLITTING is not set -# CONFIG_FB_CIRRUS is not set -# CONFIG_FB_PM2 is not set -# CONFIG_FB_CYBER2000 is not set -# CONFIG_FB_ASILIANT is not set -# CONFIG_FB_IMSTT is not set # CONFIG_FB_S1D13XXX is not set -# CONFIG_FB_NVIDIA is not set -# CONFIG_FB_RIVA is not set -# CONFIG_FB_MATROX is not set -# CONFIG_FB_RADEON is not set -# CONFIG_FB_ATY128 is not set -# CONFIG_FB_ATY is not set -# CONFIG_FB_SAVAGE is not set -# CONFIG_FB_SIS is not set -# CONFIG_FB_NEOMAGIC is not set -# CONFIG_FB_KYRO is not set -# CONFIG_FB_3DFX is not set -# CONFIG_FB_VOODOO1 is not set -# CONFIG_FB_SMIVGX is not set -# CONFIG_FB_TRIDENT is not set # CONFIG_FB_VIRTUAL is not set # # Console display driver support # # CONFIG_VGA_CONSOLE is not set +# CONFIG_SGI_NEWPORT_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y # CONFIG_FRAMEBUFFER_CONSOLE is not set @@ -1038,128 +839,14 @@ CONFIG_DUMMY_CONSOLE=y # # USB support # -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB_ARCH_HAS_EHCI=y -CONFIG_USB=y -# CONFIG_USB_DEBUG is not set - -# -# Miscellaneous USB options -# -CONFIG_USB_DEVICEFS=y -# CONFIG_USB_BANDWIDTH is not set -# CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_OTG is not set - -# -# USB Host Controller Drivers -# -# CONFIG_USB_EHCI_HCD is not set -# CONFIG_USB_ISP116X_HCD is not set -# CONFIG_USB_OHCI_HCD is not set -# CONFIG_USB_UHCI_HCD is not set -# CONFIG_USB_SL811_HCD is not set - -# -# USB Device Class drivers -# -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set +# CONFIG_USB_ARCH_HAS_HCD is not set +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB_ARCH_HAS_EHCI is not set # # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' # -# -# may also be needed; see USB_STORAGE Help for more information -# -CONFIG_USB_STORAGE=y -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_USBAT is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_SDDR55 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_STORAGE_ALAUDA is not set -# CONFIG_USB_STORAGE_ONETOUCH is not set -# CONFIG_USB_STORAGE_KARMA is not set -# CONFIG_USB_LIBUSUAL is not set - -# -# USB Input Devices -# -CONFIG_USB_HID=y -CONFIG_USB_HIDINPUT=y -# CONFIG_USB_HIDINPUT_POWERBOOK is not set -# CONFIG_HID_FF is not set -CONFIG_USB_HIDDEV=y -# CONFIG_USB_AIPTEK is not set -# CONFIG_USB_WACOM is not set -# CONFIG_USB_ACECAD is not set -# CONFIG_USB_KBTAB is not set -# CONFIG_USB_POWERMATE is not set -# CONFIG_USB_TOUCHSCREEN is not set -# CONFIG_USB_YEALINK is not set -# CONFIG_USB_XPAD is not set -# CONFIG_USB_ATI_REMOTE is not set -# CONFIG_USB_ATI_REMOTE2 is not set -# CONFIG_USB_KEYSPAN_REMOTE is not set -# CONFIG_USB_APPLETOUCH is not set -# CONFIG_USB_TRANCEVIBRATOR is not set - -# -# USB Imaging devices -# -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_MICROTEK is not set - -# -# USB Network Adapters -# -# CONFIG_USB_CATC is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RTL8150 is not set -# CONFIG_USB_USBNET is not set -CONFIG_USB_MON=y - -# -# USB port drivers -# - -# -# USB Serial Converter support -# -# CONFIG_USB_SERIAL is not set - -# -# USB Miscellaneous drivers -# -# CONFIG_USB_EMI62 is not set -# CONFIG_USB_EMI26 is not set -# CONFIG_USB_ADUTUX is not set -# CONFIG_USB_AUERSWALD is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_LEGOTOWER is not set -# CONFIG_USB_LCD is not set -# CONFIG_USB_LED is not set -# CONFIG_USB_CYPRESS_CY7C63 is not set -# CONFIG_USB_CYTHERM is not set -# CONFIG_USB_PHIDGET is not set -# CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_FTDI_ELAN is not set -# CONFIG_USB_APPLEDISPLAY is not set -# CONFIG_USB_LD is not set -# CONFIG_USB_TEST is not set - -# -# USB DSL modem support -# - # # USB Gadget Support # @@ -1186,7 +873,6 @@ CONFIG_USB_MON=y # # InfiniBand support # -# CONFIG_INFINIBAND is not set # # EDAC - error detection and reporting (RAS) (EXPERIMENTAL) @@ -1220,7 +906,6 @@ CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y # CONFIG_EXT3_FS_POSIX_ACL is not set # CONFIG_EXT3_FS_SECURITY is not set -# CONFIG_EXT4DEV_FS is not set CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set CONFIG_FS_MBCACHE=y @@ -1232,7 +917,6 @@ CONFIG_XFS_FS=m # CONFIG_XFS_SECURITY is not set # CONFIG_XFS_POSIX_ACL is not set # CONFIG_XFS_RT is not set -# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set @@ -1265,10 +949,8 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" # CONFIG_PROC_FS=y # CONFIG_PROC_KCORE is not set -CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set @@ -1312,6 +994,7 @@ CONFIG_SUNRPC=y CONFIG_SMB_FS=m # CONFIG_SMB_NLS_DEFAULT is not set # CONFIG_CIFS is not set +# CONFIG_CIFS_DEBUG2 is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set @@ -1322,6 +1005,7 @@ CONFIG_SMB_FS=m # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y +CONFIG_SGI_PARTITION=y # # Native Language Support @@ -1377,13 +1061,11 @@ CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_MUST_CHECK=y # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set # CONFIG_DEBUG_KERNEL is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_DEBUG_FS is not set -# CONFIG_HEADERS_CHECK is not set CONFIG_CROSSCOMPILE=y CONFIG_CMDLINE="" @@ -1397,9 +1079,6 @@ CONFIG_CMDLINE="" # Cryptographic options # CONFIG_CRYPTO=y -CONFIG_CRYPTO_ALGAPI=m -CONFIG_CRYPTO_BLKCIPHER=m -CONFIG_CRYPTO_MANAGER=m # CONFIG_CRYPTO_HMAC is not set # CONFIG_CRYPTO_NULL is not set # CONFIG_CRYPTO_MD4 is not set @@ -1409,8 +1088,6 @@ CONFIG_CRYPTO_SHA1=m # CONFIG_CRYPTO_SHA512 is not set # CONFIG_CRYPTO_WP512 is not set # CONFIG_CRYPTO_TGR192 is not set -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_CBC=m # CONFIG_CRYPTO_DES is not set # CONFIG_CRYPTO_BLOWFISH is not set # CONFIG_CRYPTO_TWOFISH is not set diff --git a/trunk/arch/mips/configs/tb0287_defconfig b/trunk/arch/mips/configs/tb0287_defconfig index f7e8194809a1..ad7271b3f266 100644 --- a/trunk/arch/mips/configs/tb0287_defconfig +++ b/trunk/arch/mips/configs/tb0287_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.19-rc2 -# Wed Oct 18 12:57:11 2006 +# Linux kernel version: 2.6.18-rc1 +# Thu Jul 6 10:04:21 2006 # CONFIG_MIPS=y @@ -25,6 +25,8 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set @@ -70,11 +72,11 @@ CONFIG_TANBAC_TB0287=y # CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set CONFIG_PCI_VR41XX=y +# CONFIG_VRC4173 is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_TIME=y CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y CONFIG_DMA_NONCOHERENT=y CONFIG_DMA_NEED_PCI_MAP_STATE=y @@ -121,8 +123,8 @@ CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_MIPS_MT_DISABLED=y -# CONFIG_MIPS_MT_SMP is not set # CONFIG_MIPS_MT_SMTC is not set +# CONFIG_MIPS_MT_SMP is not set # CONFIG_MIPS_VPE_LOADER is not set CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y @@ -167,19 +169,15 @@ CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set +CONFIG_SYSCTL=y # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set # CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_SYSCTL=y CONFIG_EMBEDDED=y -# CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set # CONFIG_HOTPLUG is not set @@ -187,12 +185,12 @@ CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y +CONFIG_RT_MUTEXES=y CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_SHMEM=y CONFIG_SLAB=y CONFIG_VM_EVENT_COUNTERS=y -CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 # CONFIG_SLOB is not set @@ -210,7 +208,6 @@ CONFIG_KMOD=y # # Block layer # -CONFIG_BLOCK=y # CONFIG_LBD is not set # CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_LSF is not set @@ -233,16 +230,17 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # CONFIG_HW_HAS_PCI=y CONFIG_PCI=y -# CONFIG_PCI_MULTITHREAD_PROBE is not set CONFIG_MMU=y # # PCCARD (PCMCIA/CardBus) support # +# CONFIG_PCCARD is not set # # PCI Hotplug Support # +# CONFIG_HOTPLUG_PCI is not set # # Executable file formats @@ -265,7 +263,6 @@ CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set # CONFIG_NET_KEY is not set CONFIG_INET=y CONFIG_IP_MULTICAST=y @@ -294,10 +291,13 @@ CONFIG_SYN_COOKIES=y CONFIG_INET_TUNNEL=m CONFIG_INET_XFRM_MODE_TRANSPORT=m CONFIG_INET_XFRM_MODE_TUNNEL=m -CONFIG_INET_XFRM_MODE_BEET=y CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y CONFIG_TCP_CONG_ADVANCED=y + +# +# TCP congestion control +# CONFIG_TCP_CONG_BIC=y CONFIG_TCP_CONG_CUBIC=m CONFIG_TCP_CONG_WESTWOOD=m @@ -308,13 +308,7 @@ CONFIG_TCP_CONG_HTCP=m # CONFIG_TCP_CONG_SCALABLE is not set # CONFIG_TCP_CONG_LP is not set # CONFIG_TCP_CONG_VENO is not set -CONFIG_DEFAULT_BIC=y -# CONFIG_DEFAULT_CUBIC is not set -# CONFIG_DEFAULT_HTCP is not set -# CONFIG_DEFAULT_VEGAS is not set -# CONFIG_DEFAULT_WESTWOOD is not set -# CONFIG_DEFAULT_RENO is not set -CONFIG_DEFAULT_TCP_CONG="bic" +# CONFIG_TCP_CONG_COMPOUND is not set # CONFIG_IPV6 is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set @@ -344,6 +338,7 @@ CONFIG_NETWORK_SECMARK=y # CONFIG_ATALK is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set @@ -360,7 +355,6 @@ CONFIG_NETWORK_SECMARK=y # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_IEEE80211 is not set -CONFIG_FIB_RULES=y # # Device Drivers @@ -371,6 +365,7 @@ CONFIG_FIB_RULES=y # CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set # CONFIG_SYS_HYPERVISOR is not set # @@ -408,7 +403,6 @@ CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # CONFIG_BLK_DEV_INITRD is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set @@ -416,14 +410,65 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # # ATA/ATAPI/MFM/RLL support # -# CONFIG_IDE is not set +CONFIG_IDE=y +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_IDE_TASK_IOCTL is not set + +# +# IDE chipset support/bugfixes +# +CONFIG_IDE_GENERIC=y +CONFIG_BLK_DEV_IDEPCI=y +# CONFIG_IDEPCI_SHARE_IRQ is not set +# CONFIG_BLK_DEV_OFFBOARD is not set +# CONFIG_BLK_DEV_GENERIC is not set +# CONFIG_BLK_DEV_OPTI621 is not set +CONFIG_BLK_DEV_IDEDMA_PCI=y +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set +# CONFIG_IDEDMA_PCI_AUTO is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD74XX is not set +# CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_TRIFLEX is not set +# CONFIG_BLK_DEV_CY82C693 is not set +# CONFIG_BLK_DEV_CS5520 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_HPT34X is not set +# CONFIG_BLK_DEV_HPT366 is not set +# CONFIG_BLK_DEV_SC1200 is not set +# CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_IT821X is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_SVWKS is not set +CONFIG_BLK_DEV_SIIMAGE=y +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_IDE_ARM is not set +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_IDEDMA_IVB is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_BLK_DEV_HD is not set # # SCSI device support # # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y -# CONFIG_SCSI_NETLINK is not set CONFIG_SCSI_PROC_FS=y # @@ -444,13 +489,12 @@ CONFIG_BLK_DEV_SD=y # CONFIG_SCSI_LOGGING is not set # -# SCSI Transports +# SCSI Transport Attributes # # CONFIG_SCSI_SPI_ATTRS is not set # CONFIG_SCSI_FC_ATTRS is not set # CONFIG_SCSI_ISCSI_ATTRS is not set # CONFIG_SCSI_SAS_ATTRS is not set -# CONFIG_SCSI_SAS_LIBSAS is not set # # SCSI low-level drivers @@ -463,83 +507,27 @@ CONFIG_BLK_DEV_SD=y # CONFIG_SCSI_AIC7XXX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_AIC79XX is not set -# CONFIG_SCSI_AIC94XX is not set # CONFIG_SCSI_DPT_I2O is not set -# CONFIG_SCSI_ARCMSR is not set # CONFIG_MEGARAID_NEWGEN is not set # CONFIG_MEGARAID_LEGACY is not set # CONFIG_MEGARAID_SAS is not set +# CONFIG_SCSI_SATA is not set # CONFIG_SCSI_HPTIOP is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set # CONFIG_SCSI_IPS is not set # CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_STEX is not set # CONFIG_SCSI_SYM53C8XX_2 is not set # CONFIG_SCSI_IPR is not set # CONFIG_SCSI_QLOGIC_1280 is not set # CONFIG_SCSI_QLA_FC is not set -# CONFIG_SCSI_QLA_ISCSI is not set # CONFIG_SCSI_LPFC is not set # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# -CONFIG_ATA=y -# CONFIG_SATA_AHCI is not set -# CONFIG_SATA_SVW is not set -# CONFIG_ATA_PIIX is not set -# CONFIG_SATA_MV is not set -# CONFIG_SATA_NV is not set -# CONFIG_PDC_ADMA is not set -# CONFIG_SATA_QSTOR is not set -# CONFIG_SATA_PROMISE is not set -# CONFIG_SATA_SX4 is not set -# CONFIG_SATA_SIL is not set -# CONFIG_SATA_SIL24 is not set -# CONFIG_SATA_SIS is not set -# CONFIG_SATA_ULI is not set -# CONFIG_SATA_VIA is not set -# CONFIG_SATA_VITESSE is not set -# CONFIG_PATA_ALI is not set -# CONFIG_PATA_AMD is not set -# CONFIG_PATA_ARTOP is not set -# CONFIG_PATA_ATIIXP is not set -# CONFIG_PATA_CMD64X is not set -# CONFIG_PATA_CS5520 is not set -# CONFIG_PATA_CS5530 is not set -# CONFIG_PATA_CYPRESS is not set -# CONFIG_PATA_EFAR is not set -# CONFIG_ATA_GENERIC is not set -# CONFIG_PATA_HPT366 is not set -# CONFIG_PATA_HPT37X is not set -# CONFIG_PATA_HPT3X2N is not set -# CONFIG_PATA_HPT3X3 is not set -# CONFIG_PATA_IT821X is not set -# CONFIG_PATA_JMICRON is not set -# CONFIG_PATA_TRIFLEX is not set -# CONFIG_PATA_MPIIX is not set -# CONFIG_PATA_OLDPIIX is not set -# CONFIG_PATA_NETCELL is not set -# CONFIG_PATA_NS87410 is not set -# CONFIG_PATA_OPTI is not set -# CONFIG_PATA_OPTIDMA is not set -# CONFIG_PATA_PDC_OLD is not set -# CONFIG_PATA_RADISYS is not set -# CONFIG_PATA_RZ1000 is not set -# CONFIG_PATA_SC1200 is not set -# CONFIG_PATA_SERVERWORKS is not set -# CONFIG_PATA_PDC2027X is not set -CONFIG_PATA_SIL680=y -# CONFIG_PATA_SIS is not set -# CONFIG_PATA_VIA is not set -# CONFIG_PATA_WINBOND is not set - # # Multi-device support (RAID and LVM) # @@ -644,7 +632,6 @@ CONFIG_R8169=y # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_BNX2 is not set -# CONFIG_QLA3XXX is not set # # Ethernet (10000 Mbit) @@ -692,7 +679,6 @@ CONFIG_R8169=y # Input device support # CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set # # Userland interfaces @@ -772,6 +758,7 @@ CONFIG_GPIO_VR41XX=y # TPM devices # # CONFIG_TCG_TPM is not set +# CONFIG_TELCLOCK is not set # # I2C support @@ -797,12 +784,12 @@ CONFIG_GPIO_VR41XX=y # # Misc devices # -# CONFIG_TIFM_CORE is not set # # Multimedia devices # # CONFIG_VIDEO_DEV is not set +CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices @@ -910,13 +897,13 @@ CONFIG_USB_STORAGE=m # CONFIG_USB_STORAGE_DEBUG is not set # CONFIG_USB_STORAGE_DATAFAB is not set # CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set # CONFIG_USB_STORAGE_DPCM is not set # CONFIG_USB_STORAGE_USBAT is not set # CONFIG_USB_STORAGE_SDDR09 is not set # CONFIG_USB_STORAGE_SDDR55 is not set # CONFIG_USB_STORAGE_JUMPSHOT is not set # CONFIG_USB_STORAGE_ALAUDA is not set -# CONFIG_USB_STORAGE_KARMA is not set # CONFIG_USB_LIBUSUAL is not set # @@ -945,7 +932,6 @@ CONFIG_USB_HIDINPUT=y # CONFIG_USB_ATI_REMOTE2 is not set # CONFIG_USB_KEYSPAN_REMOTE is not set # CONFIG_USB_APPLETOUCH is not set -# CONFIG_USB_TRANCEVIBRATOR is not set # # USB Imaging devices @@ -977,17 +963,16 @@ CONFIG_USB_MON=y # # CONFIG_USB_EMI62 is not set # CONFIG_USB_EMI26 is not set -# CONFIG_USB_ADUTUX is not set # CONFIG_USB_AUERSWALD is not set # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set # CONFIG_USB_LED is not set -# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CY7C63 is not set # CONFIG_USB_CYTHERM is not set -# CONFIG_USB_PHIDGET is not set +# CONFIG_USB_PHIDGETKIT is not set +# CONFIG_USB_PHIDGETSERVO is not set # CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_FTDI_ELAN is not set # CONFIG_USB_APPLEDISPLAY is not set # CONFIG_USB_SISUSBVGA is not set # CONFIG_USB_LD is not set @@ -1056,7 +1041,6 @@ CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y # CONFIG_EXT3_FS_POSIX_ACL is not set # CONFIG_EXT3_FS_SECURITY is not set -# CONFIG_EXT4DEV_FS is not set CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set CONFIG_FS_MBCACHE=y @@ -1068,7 +1052,6 @@ CONFIG_XFS_QUOTA=y # CONFIG_XFS_SECURITY is not set CONFIG_XFS_POSIX_ACL=y # CONFIG_XFS_RT is not set -# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set CONFIG_ROMFS_FS=m @@ -1099,10 +1082,8 @@ CONFIG_AUTOFS4_FS=y # CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y -CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set @@ -1142,6 +1123,7 @@ CONFIG_SUNRPC=y # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set # CONFIG_CIFS is not set +# CONFIG_CIFS_DEBUG2 is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set @@ -1168,13 +1150,11 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_MUST_CHECK=y # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set # CONFIG_DEBUG_KERNEL is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_DEBUG_FS is not set -# CONFIG_HEADERS_CHECK is not set CONFIG_CROSSCOMPILE=y CONFIG_CMDLINE="mem=64M console=ttyVR0,115200 ip=any root=/dev/nfs" @@ -1189,6 +1169,10 @@ CONFIG_CMDLINE="mem=64M console=ttyVR0,115200 ip=any root=/dev/nfs" # # CONFIG_CRYPTO is not set +# +# Hardware crypto devices +# + # # Library routines # diff --git a/trunk/arch/mips/ddb5xxx/ddb5477/irq.c b/trunk/arch/mips/ddb5xxx/ddb5477/irq.c index a8bd2e66705c..513fc6722d84 100644 --- a/trunk/arch/mips/ddb5xxx/ddb5477/irq.c +++ b/trunk/arch/mips/ddb5xxx/ddb5477/irq.c @@ -153,7 +153,8 @@ u8 i8259_interrupt_ack(void) * the first level int-handler will jump here if it is a vrc5477 irq */ #define NUM_5477_IRQS 32 -static void vrc5477_irq_dispatch(void) +static void +vrc5477_irq_dispatch(struct pt_regs *regs) { u32 intStatus; u32 bitmask; @@ -177,7 +178,7 @@ static void vrc5477_irq_dispatch(void) /* check for i8259 interrupts */ if (intStatus & (1 << VRC5477_I8259_CASCADE)) { int i8259_irq = i8259_interrupt_ack(); - do_IRQ(I8259_IRQ_BASE + i8259_irq); + do_IRQ(I8259_IRQ_BASE + i8259_irq, regs); return; } } @@ -185,7 +186,7 @@ static void vrc5477_irq_dispatch(void) for (i=0, bitmask=1; i<= NUM_5477_IRQS; bitmask <<=1, i++) { /* do we need to "and" with the int mask? */ if (intStatus & bitmask) { - do_IRQ(VRC5477_IRQ_BASE + i); + do_IRQ(VRC5477_IRQ_BASE + i, regs); return; } } @@ -193,18 +194,18 @@ static void vrc5477_irq_dispatch(void) #define VR5477INTS (STATUSF_IP2|STATUSF_IP3|STATUSF_IP4|STATUSF_IP5|STATUSF_IP6) -asmlinkage void plat_irq_dispatch(void) +asmlinkage void plat_irq_dispatch(struct pt_regs *regs) { unsigned int pending = read_c0_cause() & read_c0_status(); if (pending & STATUSF_IP7) - do_IRQ(CPU_IRQ_BASE + 7); + do_IRQ(CPU_IRQ_BASE + 7, regs); else if (pending & VR5477INTS) - vrc5477_irq_dispatch(); + vrc5477_irq_dispatch(regs); else if (pending & STATUSF_IP0) - do_IRQ(CPU_IRQ_BASE); + do_IRQ(CPU_IRQ_BASE, regs); else if (pending & STATUSF_IP1) - do_IRQ(CPU_IRQ_BASE + 1); + do_IRQ(CPU_IRQ_BASE + 1, regs); else - spurious_interrupt(); + spurious_interrupt(regs); } diff --git a/trunk/arch/mips/ddb5xxx/ddb5477/irq_5477.c b/trunk/arch/mips/ddb5xxx/ddb5477/irq_5477.c index 96249aa5df5d..ba52705a2738 100644 --- a/trunk/arch/mips/ddb5xxx/ddb5477/irq_5477.c +++ b/trunk/arch/mips/ddb5xxx/ddb5477/irq_5477.c @@ -53,6 +53,14 @@ vrc5477_irq_disable(unsigned int irq) ll_vrc5477_irq_disable(irq - vrc5477_irq_base); } +static unsigned int vrc5477_irq_startup(unsigned int irq) +{ + vrc5477_irq_enable(irq); + return 0; +} + +#define vrc5477_irq_shutdown vrc5477_irq_disable + static void vrc5477_irq_ack(unsigned int irq) { @@ -83,10 +91,11 @@ vrc5477_irq_end(unsigned int irq) struct irq_chip vrc5477_irq_controller = { .typename = "vrc5477_irq", + .startup = vrc5477_irq_startup, + .shutdown = vrc5477_irq_shutdown, + .enable = vrc5477_irq_enable, + .disable = vrc5477_irq_disable, .ack = vrc5477_irq_ack, - .mask = vrc5477_irq_disable, - .mask_ack = vrc5477_irq_ack, - .unmask = vrc5477_irq_enable, .end = vrc5477_irq_end }; @@ -94,8 +103,12 @@ void __init vrc5477_irq_init(u32 irq_base) { u32 i; - for (i= irq_base; i< irq_base+ NUM_5477_IRQ; i++) - set_irq_chip(i, &vrc5477_irq_controller); + for (i= irq_base; i< irq_base+ NUM_5477_IRQ; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = NULL; + irq_desc[i].depth = 1; + irq_desc[i].chip = &vrc5477_irq_controller; + } vrc5477_irq_base = irq_base; } diff --git a/trunk/arch/mips/dec/ecc-berr.c b/trunk/arch/mips/dec/ecc-berr.c index c8430c07355e..cc24c5ed0c05 100644 --- a/trunk/arch/mips/dec/ecc-berr.c +++ b/trunk/arch/mips/dec/ecc-berr.c @@ -18,12 +18,12 @@ #include #include #include +#include #include #include #include #include -#include #include #include #include @@ -200,10 +200,8 @@ int dec_ecc_be_handler(struct pt_regs *regs, int is_fixup) return dec_ecc_be_backend(regs, is_fixup, 0); } -irqreturn_t dec_ecc_be_interrupt(int irq, void *dev_id) +irqreturn_t dec_ecc_be_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct pt_regs *regs = get_irq_regs(); - int action = dec_ecc_be_backend(regs, 0, 1); if (action == MIPS_BE_DISCARD) @@ -230,10 +228,13 @@ irqreturn_t dec_ecc_be_interrupt(int irq, void *dev_id) static inline void dec_kn02_be_init(void) { volatile u32 *csr = (void *)CKSEG1ADDR(KN02_SLOT_BASE + KN02_CSR); + unsigned long flags; kn0x_erraddr = (void *)CKSEG1ADDR(KN02_SLOT_BASE + KN02_ERRADDR); kn0x_chksyn = (void *)CKSEG1ADDR(KN02_SLOT_BASE + KN02_CHKSYN); + spin_lock_irqsave(&kn02_lock, flags); + /* Preset write-only bits of the Control Register cache. */ cached_kn02_csr = *csr | KN02_CSR_LEDS; @@ -243,6 +244,8 @@ static inline void dec_kn02_be_init(void) cached_kn02_csr |= KN02_CSR_CORRECT; *csr = cached_kn02_csr; iob(); + + spin_unlock_irqrestore(&kn02_lock, flags); } static inline void dec_kn03_be_init(void) diff --git a/trunk/arch/mips/dec/int-handler.S b/trunk/arch/mips/dec/int-handler.S index b251ef864c33..455a65b91cb0 100644 --- a/trunk/arch/mips/dec/int-handler.S +++ b/trunk/arch/mips/dec/int-handler.S @@ -264,10 +264,10 @@ srlv t3,t1,t2 handle_it: - LONG_L s0, TI_REGS($28) - LONG_S sp, TI_REGS($28) - PTR_LA ra, ret_from_irq - j dec_irq_dispatch + jal do_IRQ + move a1,sp + + j ret_from_irq nop #ifdef CONFIG_32BIT @@ -277,8 +277,9 @@ fpu: #endif spurious: - PTR_LA ra, _ret_from_irq - j spurious_interrupt + jal spurious_interrupt + nop + j ret_from_irq nop END(plat_irq_dispatch) diff --git a/trunk/arch/mips/dec/ioasic-irq.c b/trunk/arch/mips/dec/ioasic-irq.c index 269b22b34313..41cd2a96148b 100644 --- a/trunk/arch/mips/dec/ioasic-irq.c +++ b/trunk/arch/mips/dec/ioasic-irq.c @@ -13,6 +13,7 @@ #include #include +#include #include #include @@ -20,6 +21,8 @@ #include +static DEFINE_SPINLOCK(ioasic_lock); + static int ioasic_irq_base; @@ -49,31 +52,65 @@ static inline void clear_ioasic_irq(unsigned int irq) ioasic_write(IO_REG_SIR, sir); } +static inline void enable_ioasic_irq(unsigned int irq) +{ + unsigned long flags; + + spin_lock_irqsave(&ioasic_lock, flags); + unmask_ioasic_irq(irq); + spin_unlock_irqrestore(&ioasic_lock, flags); +} + +static inline void disable_ioasic_irq(unsigned int irq) +{ + unsigned long flags; + + spin_lock_irqsave(&ioasic_lock, flags); + mask_ioasic_irq(irq); + spin_unlock_irqrestore(&ioasic_lock, flags); +} + + +static inline unsigned int startup_ioasic_irq(unsigned int irq) +{ + enable_ioasic_irq(irq); + return 0; +} + +#define shutdown_ioasic_irq disable_ioasic_irq + static inline void ack_ioasic_irq(unsigned int irq) { + spin_lock(&ioasic_lock); mask_ioasic_irq(irq); + spin_unlock(&ioasic_lock); fast_iob(); } static inline void end_ioasic_irq(unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) - unmask_ioasic_irq(irq); + enable_ioasic_irq(irq); } static struct irq_chip ioasic_irq_type = { .typename = "IO-ASIC", + .startup = startup_ioasic_irq, + .shutdown = shutdown_ioasic_irq, + .enable = enable_ioasic_irq, + .disable = disable_ioasic_irq, .ack = ack_ioasic_irq, - .mask = mask_ioasic_irq, - .mask_ack = ack_ioasic_irq, - .unmask = unmask_ioasic_irq, .end = end_ioasic_irq, }; -#define unmask_ioasic_dma_irq unmask_ioasic_irq +#define startup_ioasic_dma_irq startup_ioasic_irq + +#define shutdown_ioasic_dma_irq shutdown_ioasic_irq + +#define enable_ioasic_dma_irq enable_ioasic_irq -#define mask_ioasic_dma_irq mask_ioasic_irq +#define disable_ioasic_dma_irq disable_ioasic_irq #define ack_ioasic_dma_irq ack_ioasic_irq @@ -86,10 +123,11 @@ static inline void end_ioasic_dma_irq(unsigned int irq) static struct irq_chip ioasic_dma_irq_type = { .typename = "IO-ASIC-DMA", + .startup = startup_ioasic_dma_irq, + .shutdown = shutdown_ioasic_dma_irq, + .enable = enable_ioasic_dma_irq, + .disable = disable_ioasic_dma_irq, .ack = ack_ioasic_dma_irq, - .mask = mask_ioasic_dma_irq, - .mask_ack = ack_ioasic_dma_irq, - .unmask = unmask_ioasic_dma_irq, .end = end_ioasic_dma_irq, }; @@ -102,12 +140,18 @@ void __init init_ioasic_irqs(int base) ioasic_write(IO_REG_SIMR, 0); fast_iob(); - for (i = base; i < base + IO_INR_DMA; i++) - set_irq_chip_and_handler(i, &ioasic_irq_type, - handle_level_irq); - for (; i < base + IO_IRQ_LINES; i++) - set_irq_chip_and_handler(i, &ioasic_dma_irq_type, - handle_level_irq); + for (i = base; i < base + IO_INR_DMA; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 1; + irq_desc[i].chip = &ioasic_irq_type; + } + for (; i < base + IO_IRQ_LINES; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 1; + irq_desc[i].chip = &ioasic_dma_irq_type; + } ioasic_irq_base = base; } diff --git a/trunk/arch/mips/dec/kn01-berr.c b/trunk/arch/mips/dec/kn01-berr.c index f19b4617a0a6..b9271db9bc76 100644 --- a/trunk/arch/mips/dec/kn01-berr.c +++ b/trunk/arch/mips/dec/kn01-berr.c @@ -150,10 +150,10 @@ int dec_kn01_be_handler(struct pt_regs *regs, int is_fixup) return dec_kn01_be_backend(regs, is_fixup, 0); } -irqreturn_t dec_kn01_be_interrupt(int irq, void *dev_id) +irqreturn_t dec_kn01_be_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { volatile u16 *csr = (void *)CKSEG1ADDR(KN01_SLOT_BASE + KN01_CSR); - struct pt_regs *regs = get_irq_regs(); int action; if (!(*csr & KN01_CSR_MEMERR)) diff --git a/trunk/arch/mips/dec/kn02-irq.c b/trunk/arch/mips/dec/kn02-irq.c index 5a9be4c93584..04a367a60a57 100644 --- a/trunk/arch/mips/dec/kn02-irq.c +++ b/trunk/arch/mips/dec/kn02-irq.c @@ -14,6 +14,7 @@ #include #include +#include #include #include @@ -28,6 +29,7 @@ * There is no default value -- it has to be initialized. */ u32 cached_kn02_csr; +DEFINE_SPINLOCK(kn02_lock); static int kn02_irq_base; @@ -51,24 +53,54 @@ static inline void mask_kn02_irq(unsigned int irq) *csr = cached_kn02_csr; } +static inline void enable_kn02_irq(unsigned int irq) +{ + unsigned long flags; + + spin_lock_irqsave(&kn02_lock, flags); + unmask_kn02_irq(irq); + spin_unlock_irqrestore(&kn02_lock, flags); +} + +static inline void disable_kn02_irq(unsigned int irq) +{ + unsigned long flags; + + spin_lock_irqsave(&kn02_lock, flags); + mask_kn02_irq(irq); + spin_unlock_irqrestore(&kn02_lock, flags); +} + + +static unsigned int startup_kn02_irq(unsigned int irq) +{ + enable_kn02_irq(irq); + return 0; +} + +#define shutdown_kn02_irq disable_kn02_irq + static void ack_kn02_irq(unsigned int irq) { + spin_lock(&kn02_lock); mask_kn02_irq(irq); + spin_unlock(&kn02_lock); iob(); } static void end_kn02_irq(unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) - unmask_kn02_irq(irq); + enable_kn02_irq(irq); } static struct irq_chip kn02_irq_type = { .typename = "KN02-CSR", + .startup = startup_kn02_irq, + .shutdown = shutdown_kn02_irq, + .enable = enable_kn02_irq, + .disable = disable_kn02_irq, .ack = ack_kn02_irq, - .mask = mask_kn02_irq, - .mask_ack = ack_kn02_irq, - .unmask = unmask_kn02_irq, .end = end_kn02_irq, }; @@ -77,15 +109,22 @@ void __init init_kn02_irqs(int base) { volatile u32 *csr = (volatile u32 *)CKSEG1ADDR(KN02_SLOT_BASE + KN02_CSR); + unsigned long flags; int i; /* Mask interrupts. */ + spin_lock_irqsave(&kn02_lock, flags); cached_kn02_csr &= ~KN02_CSR_IOINTEN; *csr = cached_kn02_csr; iob(); - - for (i = base; i < base + KN02_IRQ_LINES; i++) - set_irq_chip_and_handler(i, &kn02_irq_type, handle_level_irq); + spin_unlock_irqrestore(&kn02_lock, flags); + + for (i = base; i < base + KN02_IRQ_LINES; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 1; + irq_desc[i].chip = &kn02_irq_type; + } kn02_irq_base = base; } diff --git a/trunk/arch/mips/dec/kn02xa-berr.c b/trunk/arch/mips/dec/kn02xa-berr.c index 7a053aadcd3a..6cd3f94f79fe 100644 --- a/trunk/arch/mips/dec/kn02xa-berr.c +++ b/trunk/arch/mips/dec/kn02xa-berr.c @@ -21,8 +21,6 @@ #include #include -#include -#include #include #include @@ -106,9 +104,9 @@ int dec_kn02xa_be_handler(struct pt_regs *regs, int is_fixup) return dec_kn02xa_be_backend(regs, is_fixup, 0); } -irqreturn_t dec_kn02xa_be_interrupt(int irq, void *dev_id) +irqreturn_t dec_kn02xa_be_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { - struct pt_regs *regs = get_irq_regs(); int action = dec_kn02xa_be_backend(regs, 0, 1); if (action == MIPS_BE_DISCARD) diff --git a/trunk/arch/mips/dec/reset.c b/trunk/arch/mips/dec/reset.c index 56397227adb0..f78c6da47921 100644 --- a/trunk/arch/mips/dec/reset.c +++ b/trunk/arch/mips/dec/reset.c @@ -8,6 +8,7 @@ #include #include +#include typedef void ATTRIB_NORET (* noret_func_t)(void); @@ -34,7 +35,7 @@ void ATTRIB_NORET dec_machine_power_off(void) back_to_prom(); } -irqreturn_t dec_intr_halt(int irq, void *dev_id) +irqreturn_t dec_intr_halt(int irq, void *dev_id, struct pt_regs *regs) { dec_machine_halt(); } diff --git a/trunk/arch/mips/dec/setup.c b/trunk/arch/mips/dec/setup.c index d34032ac492a..d43241c2f541 100644 --- a/trunk/arch/mips/dec/setup.c +++ b/trunk/arch/mips/dec/setup.c @@ -46,7 +46,7 @@ extern void dec_machine_restart(char *command); extern void dec_machine_halt(void); extern void dec_machine_power_off(void); -extern irqreturn_t dec_intr_halt(int irq, void *dev_id); +extern irqreturn_t dec_intr_halt(int irq, void *dev_id, struct pt_regs *regs); unsigned long dec_kn_slot_base, dec_kn_slot_size; @@ -761,9 +761,3 @@ void __init arch_init_irq(void) if (dec_interrupt[DEC_IRQ_HALT] >= 0) setup_irq(dec_interrupt[DEC_IRQ_HALT], &haltirq); } - -asmlinkage unsigned int dec_irq_dispatch(unsigned int irq) -{ - do_IRQ(irq); - return 0; -} diff --git a/trunk/arch/mips/dec/time.c b/trunk/arch/mips/dec/time.c index 8b7e0c17ac35..4cf0c06e2414 100644 --- a/trunk/arch/mips/dec/time.c +++ b/trunk/arch/mips/dec/time.c @@ -151,7 +151,7 @@ static void dec_timer_ack(void) CMOS_READ(RTC_REG_C); /* Ack the RTC interrupt. */ } -static cycle_t dec_ioasic_hpt_read(void) +static unsigned int dec_ioasic_hpt_read(void) { /* * The free-running counter is 32-bit which is good for about @@ -160,6 +160,11 @@ static cycle_t dec_ioasic_hpt_read(void) return ioasic_read(IO_REG_FCTR); } +static void dec_ioasic_hpt_init(unsigned int count) +{ + ioasic_write(IO_REG_FCTR, ioasic_read(IO_REG_FCTR) - count); +} + void __init dec_time_init(void) { @@ -169,9 +174,11 @@ void __init dec_time_init(void) mips_timer_state = dec_timer_state; mips_timer_ack = dec_timer_ack; - if (!cpu_has_counter && IOASIC) + if (!cpu_has_counter && IOASIC) { /* For pre-R4k systems we use the I/O ASIC's counter. */ - clocksource_mips.read = dec_ioasic_hpt_read; + mips_hpt_read = dec_ioasic_hpt_read; + mips_hpt_init = dec_ioasic_hpt_init; + } /* Set up the rate of periodic DS1287 interrupts. */ CMOS_WRITE(RTC_REF_CLCK_32KHZ | (16 - __ffs(HZ)), RTC_REG_A); diff --git a/trunk/arch/mips/emma2rh/common/irq.c b/trunk/arch/mips/emma2rh/common/irq.c index c191b3e9d9d9..3af57693c84c 100644 --- a/trunk/arch/mips/emma2rh/common/irq.c +++ b/trunk/arch/mips/emma2rh/common/irq.c @@ -39,7 +39,7 @@ /* * the first level int-handler will jump here if it is a emma2rh irq */ -void emma2rh_irq_dispatch(void) +asmlinkage void emma2rh_irq_dispatch(struct pt_regs *regs) { u32 intStatus; u32 bitmask; @@ -56,7 +56,7 @@ void emma2rh_irq_dispatch(void) & emma2rh_in32(EMMA2RH_BHIF_SW_INT_EN); for (i = 0, bitmask = 1; i < 32; i++, bitmask <<= 1) { if (swIntStatus & bitmask) { - do_IRQ(EMMA2RH_SW_IRQ_BASE + i); + do_IRQ(EMMA2RH_SW_IRQ_BASE + i, regs); return; } } @@ -65,7 +65,7 @@ void emma2rh_irq_dispatch(void) for (i = 0, bitmask = 1; i < 32; i++, bitmask <<= 1) { if (intStatus & bitmask) { - do_IRQ(EMMA2RH_IRQ_BASE + i); + do_IRQ(EMMA2RH_IRQ_BASE + i, regs); return; } } @@ -81,7 +81,7 @@ void emma2rh_irq_dispatch(void) & emma2rh_in32(EMMA2RH_GPIO_INT_MASK); for (i = 0, bitmask = 1; i < 32; i++, bitmask <<= 1) { if (gpioIntStatus & bitmask) { - do_IRQ(EMMA2RH_GPIO_IRQ_BASE + i); + do_IRQ(EMMA2RH_GPIO_IRQ_BASE + i, regs); return; } } @@ -90,7 +90,7 @@ void emma2rh_irq_dispatch(void) for (i = 32, bitmask = 1; i < 64; i++, bitmask <<= 1) { if (intStatus & bitmask) { - do_IRQ(EMMA2RH_IRQ_BASE + i); + do_IRQ(EMMA2RH_IRQ_BASE + i, regs); return; } } @@ -100,7 +100,7 @@ void emma2rh_irq_dispatch(void) for (i = 64, bitmask = 1; i < 96; i++, bitmask <<= 1) { if (intStatus & bitmask) { - do_IRQ(EMMA2RH_IRQ_BASE + i); + do_IRQ(EMMA2RH_IRQ_BASE + i, regs); return; } } diff --git a/trunk/arch/mips/emma2rh/common/irq_emma2rh.c b/trunk/arch/mips/emma2rh/common/irq_emma2rh.c index 59b98299c896..7c930860c921 100644 --- a/trunk/arch/mips/emma2rh/common/irq_emma2rh.c +++ b/trunk/arch/mips/emma2rh/common/irq_emma2rh.c @@ -56,6 +56,22 @@ static void emma2rh_irq_disable(unsigned int irq) ll_emma2rh_irq_disable(irq - emma2rh_irq_base); } +static unsigned int emma2rh_irq_startup(unsigned int irq) +{ + emma2rh_irq_enable(irq); + return 0; +} + +#define emma2rh_irq_shutdown emma2rh_irq_disable + +static void emma2rh_irq_ack(unsigned int irq) +{ + /* disable interrupt - some handler will re-enable the irq + * and if the interrupt is leveled, we will have infinite loop + */ + ll_emma2rh_irq_disable(irq - emma2rh_irq_base); +} + static void emma2rh_irq_end(unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) @@ -64,20 +80,25 @@ static void emma2rh_irq_end(unsigned int irq) struct irq_chip emma2rh_irq_controller = { .typename = "emma2rh_irq", - .ack = emma2rh_irq_disable, - .mask = emma2rh_irq_disable, - .mask_ack = emma2rh_irq_disable, - .unmask = emma2rh_irq_enable, + .startup = emma2rh_irq_startup, + .shutdown = emma2rh_irq_shutdown, + .enable = emma2rh_irq_enable, + .disable = emma2rh_irq_disable, + .ack = emma2rh_irq_ack, .end = emma2rh_irq_end, + .set_affinity = NULL /* no affinity stuff for UP */ }; void emma2rh_irq_init(u32 irq_base) { u32 i; - for (i = irq_base; i < irq_base + NUM_EMMA2RH_IRQ; i++) - set_irq_chip_and_handler(i, &emma2rh_irq_controller, - handle_level_irq); + for (i = irq_base; i < irq_base + NUM_EMMA2RH_IRQ; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = NULL; + irq_desc[i].depth = 1; + irq_desc[i].handler = &emma2rh_irq_controller; + } emma2rh_irq_base = irq_base; } diff --git a/trunk/arch/mips/emma2rh/markeins/irq.c b/trunk/arch/mips/emma2rh/markeins/irq.c index c93369cb4115..2a736be42c8c 100644 --- a/trunk/arch/mips/emma2rh/markeins/irq.c +++ b/trunk/arch/mips/emma2rh/markeins/irq.c @@ -57,7 +57,7 @@ extern void emma2rh_sw_irq_init(u32 base); extern void emma2rh_gpio_irq_init(u32 base); extern void emma2rh_irq_init(u32 base); -extern void emma2rh_irq_dispatch(void); +extern asmlinkage void emma2rh_irq_dispatch(struct pt_regs *regs); static struct irqaction irq_cascade = { .handler = no_action, @@ -114,20 +114,20 @@ void __init arch_init_irq(void) setup_irq(CPU_IRQ_BASE + CPU_EMMA2RH_CASCADE, &irq_cascade); } -asmlinkage void plat_irq_dispatch(void) +asmlinkage void plat_irq_dispatch(struct pt_regs *regs) { unsigned int pending = read_c0_status() & read_c0_cause(); if (pending & STATUSF_IP7) - do_IRQ(CPU_IRQ_BASE + 7); + do_IRQ(CPU_IRQ_BASE + 7, regs); else if (pending & STATUSF_IP2) - emma2rh_irq_dispatch(); + emma2rh_irq_dispatch(regs); else if (pending & STATUSF_IP1) - do_IRQ(CPU_IRQ_BASE + 1); + do_IRQ(CPU_IRQ_BASE + 1, regs); else if (pending & STATUSF_IP0) - do_IRQ(CPU_IRQ_BASE + 0); + do_IRQ(CPU_IRQ_BASE + 0, regs); else - spurious_interrupt(); + spurious_interrupt(regs); } diff --git a/trunk/arch/mips/emma2rh/markeins/irq_markeins.c b/trunk/arch/mips/emma2rh/markeins/irq_markeins.c index 3ac4e405ecdc..f23ae9fcffa0 100644 --- a/trunk/arch/mips/emma2rh/markeins/irq_markeins.c +++ b/trunk/arch/mips/emma2rh/markeins/irq_markeins.c @@ -48,6 +48,19 @@ static void emma2rh_sw_irq_disable(unsigned int irq) ll_emma2rh_sw_irq_disable(irq - emma2rh_sw_irq_base); } +static unsigned int emma2rh_sw_irq_startup(unsigned int irq) +{ + emma2rh_sw_irq_enable(irq); + return 0; +} + +#define emma2rh_sw_irq_shutdown emma2rh_sw_irq_disable + +static void emma2rh_sw_irq_ack(unsigned int irq) +{ + ll_emma2rh_sw_irq_disable(irq - emma2rh_sw_irq_base); +} + static void emma2rh_sw_irq_end(unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) @@ -56,20 +69,25 @@ static void emma2rh_sw_irq_end(unsigned int irq) struct irq_chip emma2rh_sw_irq_controller = { .typename = "emma2rh_sw_irq", - .ack = emma2rh_sw_irq_disable, - .mask = emma2rh_sw_irq_disable, - .mask_ack = emma2rh_sw_irq_disable, - .unmask = emma2rh_sw_irq_enable, + .startup = emma2rh_sw_irq_startup, + .shutdown = emma2rh_sw_irq_shutdown, + .enable = emma2rh_sw_irq_enable, + .disable = emma2rh_sw_irq_disable, + .ack = emma2rh_sw_irq_ack, .end = emma2rh_sw_irq_end, + .set_affinity = NULL, }; void emma2rh_sw_irq_init(u32 irq_base) { u32 i; - for (i = irq_base; i < irq_base + NUM_EMMA2RH_IRQ_SW; i++) - set_irq_chip_and_handler(i, &emma2rh_sw_irq_controller, - handle_level_irq); + for (i = irq_base; i < irq_base + NUM_EMMA2RH_IRQ_SW; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = NULL; + irq_desc[i].depth = 2; + irq_desc[i].handler = &emma2rh_sw_irq_controller; + } emma2rh_sw_irq_base = irq_base; } @@ -108,6 +126,14 @@ static void emma2rh_gpio_irq_disable(unsigned int irq) ll_emma2rh_gpio_irq_disable(irq - emma2rh_gpio_irq_base); } +static unsigned int emma2rh_gpio_irq_startup(unsigned int irq) +{ + emma2rh_gpio_irq_enable(irq); + return 0; +} + +#define emma2rh_gpio_irq_shutdown emma2rh_gpio_irq_disable + static void emma2rh_gpio_irq_ack(unsigned int irq) { irq -= emma2rh_gpio_irq_base; @@ -123,19 +149,25 @@ static void emma2rh_gpio_irq_end(unsigned int irq) struct irq_chip emma2rh_gpio_irq_controller = { .typename = "emma2rh_gpio_irq", + .startup = emma2rh_gpio_irq_startup, + .shutdown = emma2rh_gpio_irq_shutdown, + .enable = emma2rh_gpio_irq_enable, + .disable = emma2rh_gpio_irq_disable, .ack = emma2rh_gpio_irq_ack, - .mask = emma2rh_gpio_irq_disable, - .mask_ack = emma2rh_gpio_irq_ack, - .unmask = emma2rh_gpio_irq_enable, .end = emma2rh_gpio_irq_end, + .set_affinity = NULL, }; void emma2rh_gpio_irq_init(u32 irq_base) { u32 i; - for (i = irq_base; i < irq_base + NUM_EMMA2RH_IRQ_GPIO; i++) - set_irq_chip(i, &emma2rh_gpio_irq_controller); + for (i = irq_base; i < irq_base + NUM_EMMA2RH_IRQ_GPIO; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = NULL; + irq_desc[i].depth = 2; + irq_desc[i].handler = &emma2rh_gpio_irq_controller; + } emma2rh_gpio_irq_base = irq_base; } diff --git a/trunk/arch/mips/emma2rh/markeins/platform.c b/trunk/arch/mips/emma2rh/markeins/platform.c index 11567702b155..15cc61df3622 100644 --- a/trunk/arch/mips/emma2rh/markeins/platform.c +++ b/trunk/arch/mips/emma2rh/markeins/platform.c @@ -44,45 +44,18 @@ #define I2C_EMMA2RH "emma2rh-iic" /* must be in sync with IIC driver */ static struct resource i2c_emma_resources_0[] = { - { - .name = NULL, - .start = EMMA2RH_IRQ_PIIC0, - .end = EMMA2RH_IRQ_PIIC0, - .flags = IORESOURCE_IRQ - }, { - .name = NULL, - .start = EMMA2RH_PIIC0_BASE, - .end = EMMA2RH_PIIC0_BASE + 0x1000, - .flags = 0 - }, + { NULL, EMMA2RH_IRQ_PIIC0, EMMA2RH_IRQ_PIIC0, IORESOURCE_IRQ }, + { NULL, KSEG1ADDR(EMMA2RH_PIIC0_BASE), KSEG1ADDR(EMMA2RH_PIIC0_BASE + 0x1000), 0 }, }; struct resource i2c_emma_resources_1[] = { - { - .name = NULL, - .start = EMMA2RH_IRQ_PIIC1, - .end = EMMA2RH_IRQ_PIIC1, - .flags = IORESOURCE_IRQ - }, { - .name = NULL, - .start = EMMA2RH_PIIC1_BASE, - .end = EMMA2RH_PIIC1_BASE + 0x1000, - .flags = 0 - }, + { NULL, EMMA2RH_IRQ_PIIC1, EMMA2RH_IRQ_PIIC1, IORESOURCE_IRQ }, + { NULL, KSEG1ADDR(EMMA2RH_PIIC1_BASE), KSEG1ADDR(EMMA2RH_PIIC1_BASE + 0x1000), 0 }, }; struct resource i2c_emma_resources_2[] = { - { - .name = NULL, - .start = EMMA2RH_IRQ_PIIC2, - .end = EMMA2RH_IRQ_PIIC2, - .flags = IORESOURCE_IRQ - }, { - .name = NULL, - .start = EMMA2RH_PIIC2_BASE, - .end = EMMA2RH_PIIC2_BASE + 0x1000, - .flags = 0 - }, + { NULL, EMMA2RH_IRQ_PIIC2, EMMA2RH_IRQ_PIIC2, IORESOURCE_IRQ }, + { NULL, KSEG1ADDR(EMMA2RH_PIIC2_BASE), KSEG1ADDR(EMMA2RH_PIIC2_BASE + 0x1000), 0 }, }; struct platform_device i2c_emma_devices[] = { @@ -110,29 +83,32 @@ struct platform_device i2c_emma_devices[] = { #define EMMA2RH_SERIAL_FLAGS UPF_BOOT_AUTOCONF | UPF_SKIP_TEST static struct plat_serial8250_port platform_serial_ports[] = { - [0] = { - .membase= (void __iomem*)KSEG1ADDR(EMMA2RH_PFUR0_BASE + 3), - .irq = EMMA2RH_IRQ_PFUR0, - .uartclk = EMMA2RH_SERIAL_CLOCK, - .regshift = 4, - .iotype = UPIO_MEM, - .flags = EMMA2RH_SERIAL_FLAGS, - }, [1] = { - .membase = (void __iomem*)KSEG1ADDR(EMMA2RH_PFUR1_BASE + 3), - .irq = EMMA2RH_IRQ_PFUR1, - .uartclk = EMMA2RH_SERIAL_CLOCK, - .regshift = 4, - .iotype = UPIO_MEM, - .flags = EMMA2RH_SERIAL_FLAGS, - }, [2] = { - .membase = (void __iomem*)KSEG1ADDR(EMMA2RH_PFUR2_BASE + 3), - .irq = EMMA2RH_IRQ_PFUR2, - .uartclk = EMMA2RH_SERIAL_CLOCK, - .regshift = 4, - .iotype = UPIO_MEM, - .flags = EMMA2RH_SERIAL_FLAGS, - }, [3] = { - .flags = 0, + [0] = { + .membase = (void __iomem*)KSEG1ADDR(EMMA2RH_PFUR0_BASE + 3), + .irq = EMMA2RH_IRQ_PFUR0, + .uartclk = EMMA2RH_SERIAL_CLOCK, + .regshift = 4, + .iotype = UPIO_MEM, + .flags = EMMA2RH_SERIAL_FLAGS, + }, + [1] = { + .membase = (void __iomem*)KSEG1ADDR(EMMA2RH_PFUR1_BASE + 3), + .irq = EMMA2RH_IRQ_PFUR1, + .uartclk = EMMA2RH_SERIAL_CLOCK, + .regshift = 4, + .iotype = UPIO_MEM, + .flags = EMMA2RH_SERIAL_FLAGS, + }, + [2] = { + .membase = (void __iomem*)KSEG1ADDR(EMMA2RH_PFUR2_BASE + 3), + .irq = EMMA2RH_IRQ_PFUR2, + .uartclk = EMMA2RH_SERIAL_CLOCK, + .regshift = 4, + .iotype = UPIO_MEM, + .flags = EMMA2RH_SERIAL_FLAGS, + }, + [3] = { + .flags = 0, }, }; diff --git a/trunk/arch/mips/gt64120/common/time.c b/trunk/arch/mips/gt64120/common/time.c index c47eeb768192..7feca49350d1 100644 --- a/trunk/arch/mips/gt64120/common/time.c +++ b/trunk/arch/mips/gt64120/common/time.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include /* @@ -19,7 +19,7 @@ * differently than other MIPS interrupts. */ -static irqreturn_t gt64120_irq(int irq, void *dev_id) +static void gt64120_irq(int irq, void *dev_id, struct pt_regs *regs) { unsigned int irq_src, int_high_src, irq_src_mask, int_high_src_mask; int handled = 0; @@ -36,14 +36,12 @@ static irqreturn_t gt64120_irq(int irq, void *dev_id) irq_src &= ~0x00000800; do_timer(1); #ifndef CONFIG_SMP - update_process_times(user_mode(get_irq_regs())); + update_process_times(user_mode(regs)); #endif } GT_WRITE(GT_INTRCAUSE_OFS, 0); GT_WRITE(GT_HINTRCAUSE_OFS, 0); - - return IRQ_HANDLED; } /* @@ -64,14 +62,14 @@ static irqreturn_t gt64120_irq(int irq, void *dev_id) * as *irq (=irq0 in ../kernel/time.c). We will do our own timer interrupt * handling. */ -void __init plat_timer_setup(struct irqaction *irq) +void gt64120_time_init(void) { static struct irqaction timer; /* Disable timer first */ GT_WRITE(GT_TC_CONTROL_OFS, 0); /* Load timer value for 100 Hz */ - GT_WRITE(GT_TC3_OFS, Sys_clock / HZ); + GT_WRITE(GT_TC3_OFS, Sys_clock / 100); /* * Create the IRQ structure entry for the timer. Since we're too early diff --git a/trunk/arch/mips/gt64120/ev64120/irq.c b/trunk/arch/mips/gt64120/ev64120/irq.c index b3e5796c81d7..5d939ac58f3f 100644 --- a/trunk/arch/mips/gt64120/ev64120/irq.c +++ b/trunk/arch/mips/gt64120/ev64120/irq.c @@ -46,41 +46,58 @@ #include #include -asmlinkage void plat_irq_dispatch(void) +asmlinkage void plat_irq_dispatch(struct pt_regs *regs) { unsigned int pending = read_c0_status() & read_c0_cause(); if (pending & STATUSF_IP4) /* int2 hardware line (timer) */ - do_IRQ(4); + do_IRQ(4, regs); else if (pending & STATUSF_IP2) /* int0 hardware line */ - do_IRQ(GT_INTA); + do_IRQ(GT_INTA, regs); else if (pending & STATUSF_IP5) /* int3 hardware line */ - do_IRQ(GT_INTD); + do_IRQ(GT_INTD, regs); else if (pending & STATUSF_IP6) /* int4 hardware line */ - do_IRQ(6); + do_IRQ(6, regs); else if (pending & STATUSF_IP7) /* compare int */ - do_IRQ(7); + do_IRQ(7, regs); else - spurious_interrupt(); + spurious_interrupt(regs); } static void disable_ev64120_irq(unsigned int irq_nr) { + unsigned long flags; + + local_irq_save(flags); if (irq_nr >= 8) { // All PCI interrupts are on line 5 or 2 clear_c0_status(9 << 10); } else { clear_c0_status(1 << (irq_nr + 8)); } + local_irq_restore(flags); } static void enable_ev64120_irq(unsigned int irq_nr) { + unsigned long flags; + + local_irq_save(flags); if (irq_nr >= 8) // All PCI interrupts are on line 5 or 2 set_c0_status(9 << 10); else set_c0_status(1 << (irq_nr + 8)); + local_irq_restore(flags); +} + +static unsigned int startup_ev64120_irq(unsigned int irq) +{ + enable_ev64120_irq(irq); + return 0; /* Never anything pending */ } +#define shutdown_ev64120_irq disable_ev64120_irq +#define mask_and_ack_ev64120_irq disable_ev64120_irq + static void end_ev64120_irq(unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) @@ -89,11 +106,13 @@ static void end_ev64120_irq(unsigned int irq) static struct irq_chip ev64120_irq_type = { .typename = "EV64120", - .ack = disable_ev64120_irq, - .mask = disable_ev64120_irq, - .mask_ack = disable_ev64120_irq, - .unmask = enable_ev64120_irq, + .startup = startup_ev64120_irq, + .shutdown = shutdown_ev64120_irq, + .enable = enable_ev64120_irq, + .disable = disable_ev64120_irq, + .ack = mask_and_ack_ev64120_irq, .end = end_ev64120_irq, + .set_affinity = NULL }; void gt64120_irq_setup(void) @@ -103,6 +122,8 @@ void gt64120_irq_setup(void) */ clear_c0_status(ST0_IM); + local_irq_disable(); + /* * Enable timer. Other interrupts will be enabled as they are * registered. @@ -112,5 +133,16 @@ void gt64120_irq_setup(void) void __init arch_init_irq(void) { + int i; + + /* Let's initialize our IRQ descriptors */ + for (i = 0; i < NR_IRQS; i++) { + irq_desc[i].status = 0; + irq_desc[i].chip = &no_irq_chip; + irq_desc[i].action = NULL; + irq_desc[i].depth = 0; + spin_lock_init(&irq_desc[i].lock); + } + gt64120_irq_setup(); } diff --git a/trunk/arch/mips/gt64120/ev64120/setup.c b/trunk/arch/mips/gt64120/ev64120/setup.c index 99c8d42212e2..4236da31ecc6 100644 --- a/trunk/arch/mips/gt64120/ev64120/setup.c +++ b/trunk/arch/mips/gt64120/ev64120/setup.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -68,6 +69,7 @@ unsigned long __init prom_free_prom_memory(void) * Initializes basic routines and structures pointers, memory size (as * given by the bios and saves the command line. */ +extern void gt64120_time_init(void); void __init plat_mem_setup(void) { @@ -75,6 +77,7 @@ void __init plat_mem_setup(void) _machine_halt = galileo_machine_halt; pm_power_off = galileo_machine_power_off; + board_time_init = gt64120_time_init; set_io_port_base(KSEG1); } diff --git a/trunk/arch/mips/gt64120/momenco_ocelot/irq.c b/trunk/arch/mips/gt64120/momenco_ocelot/irq.c index d9294401ccb0..885f67f32ea3 100644 --- a/trunk/arch/mips/gt64120/momenco_ocelot/irq.c +++ b/trunk/arch/mips/gt64120/momenco_ocelot/irq.c @@ -48,22 +48,22 @@ #include #include -asmlinkage void plat_irq_dispatch(void) +asmlinkage void plat_irq_dispatch(struct pt_regs *regs) { unsigned int pending = read_c0_status() & read_c0_cause(); if (pending & STATUSF_IP2) /* int0 hardware line */ - do_IRQ(2); + do_IRQ(2, regs); else if (pending & STATUSF_IP3) /* int1 hardware line */ - do_IRQ(3); + do_IRQ(3, regs); else if (pending & STATUSF_IP4) /* int2 hardware line */ - do_IRQ(4); + do_IRQ(4, regs); else if (pending & STATUSF_IP5) /* int3 hardware line */ - do_IRQ(5); + do_IRQ(5, regs); else if (pending & STATUSF_IP6) /* int4 hardware line */ - do_IRQ(6); + do_IRQ(6, regs); else if (pending & STATUSF_IP7) /* cpu timer */ - do_IRQ(7); + do_IRQ(7, regs); else { /* * Now look at the extended interrupts @@ -71,13 +71,13 @@ asmlinkage void plat_irq_dispatch(void) pending = (read_c0_cause() & (read_c0_intcontrol() << 8)) >> 16; if (pending & STATUSF_IP8) /* int6 hardware line */ - do_IRQ(8); + do_IRQ(8, regs); else if (pending & STATUSF_IP9) /* int7 hardware line */ - do_IRQ(9); + do_IRQ(9, regs); else if (pending & STATUSF_IP10) /* int8 hardware line */ - do_IRQ(10); + do_IRQ(10, regs); else if (pending & STATUSF_IP11) /* int9 hardware line */ - do_IRQ(11); + do_IRQ(11, regs); } } diff --git a/trunk/arch/mips/gt64120/momenco_ocelot/setup.c b/trunk/arch/mips/gt64120/momenco_ocelot/setup.c index 94f94ebbda6c..9804642ecf89 100644 --- a/trunk/arch/mips/gt64120/momenco_ocelot/setup.c +++ b/trunk/arch/mips/gt64120/momenco_ocelot/setup.c @@ -56,6 +56,7 @@ #include #include #include +#include #include #include #include @@ -70,6 +71,7 @@ extern void momenco_ocelot_restart(char *command); extern void momenco_ocelot_halt(void); extern void momenco_ocelot_power_off(void); +extern void gt64120_time_init(void); extern void momenco_ocelot_irq_setup(void); static char reset_reason; @@ -155,6 +157,8 @@ void __init plat_mem_setup(void) void (*l3func)(unsigned long)=KSEG1ADDR(&setup_l3cache); unsigned int tmpword; + board_time_init = gt64120_time_init; + _machine_restart = momenco_ocelot_restart; _machine_halt = momenco_ocelot_halt; pm_power_off = momenco_ocelot_power_off; diff --git a/trunk/arch/mips/gt64120/wrppmc/irq.c b/trunk/arch/mips/gt64120/wrppmc/irq.c index eedfc24e1eae..8d75a43ce877 100644 --- a/trunk/arch/mips/gt64120/wrppmc/irq.c +++ b/trunk/arch/mips/gt64120/wrppmc/irq.c @@ -30,18 +30,18 @@ #include #include -asmlinkage void plat_irq_dispatch(void) +asmlinkage void plat_irq_dispatch(struct pt_regs *regs) { unsigned int pending = read_c0_status() & read_c0_cause(); if (pending & STATUSF_IP7) - do_IRQ(WRPPMC_MIPS_TIMER_IRQ); /* CPU Compare/Count internal timer */ + do_IRQ(WRPPMC_MIPS_TIMER_IRQ, regs); /* CPU Compare/Count internal timer */ else if (pending & STATUSF_IP6) - do_IRQ(WRPPMC_UART16550_IRQ); /* UART 16550 port */ + do_IRQ(WRPPMC_UART16550_IRQ, regs); /* UART 16550 port */ else if (pending & STATUSF_IP3) - do_IRQ(WRPPMC_PCI_INTA_IRQ); /* PCI INT_A */ + do_IRQ(WRPPMC_PCI_INTA_IRQ, regs); /* PCI INT_A */ else - spurious_interrupt(); + spurious_interrupt(regs); } /** diff --git a/trunk/arch/mips/jazz/irq.c b/trunk/arch/mips/jazz/irq.c index 5c4f50cdf157..eef05093deb4 100644 --- a/trunk/arch/mips/jazz/irq.c +++ b/trunk/arch/mips/jazz/irq.c @@ -28,6 +28,14 @@ static void enable_r4030_irq(unsigned int irq) spin_unlock_irqrestore(&r4030_lock, flags); } +static unsigned int startup_r4030_irq(unsigned int irq) +{ + enable_r4030_irq(irq); + return 0; /* never anything pending */ +} + +#define shutdown_r4030_irq disable_r4030_irq + void disable_r4030_irq(unsigned int irq) { unsigned int mask = ~(1 << (irq - JAZZ_PARALLEL_IRQ)); @@ -39,6 +47,8 @@ void disable_r4030_irq(unsigned int irq) spin_unlock_irqrestore(&r4030_lock, flags); } +#define mask_and_ack_r4030_irq disable_r4030_irq + static void end_r4030_irq(unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) @@ -47,10 +57,11 @@ static void end_r4030_irq(unsigned int irq) static struct irq_chip r4030_irq_type = { .typename = "R4030", - .ack = disable_r4030_irq, - .mask = disable_r4030_irq, - .mask_ack = disable_r4030_irq, - .unmask = enable_r4030_irq, + .startup = startup_r4030_irq, + .shutdown = shutdown_r4030_irq, + .enable = enable_r4030_irq, + .disable = disable_r4030_irq, + .ack = mask_and_ack_r4030_irq, .end = end_r4030_irq, }; @@ -58,8 +69,12 @@ void __init init_r4030_ints(void) { int i; - for (i = JAZZ_PARALLEL_IRQ; i <= JAZZ_TIMER_IRQ; i++) - set_irq_chip_and_handler(i, &r4030_irq_type, handle_level_irq); + for (i = JAZZ_PARALLEL_IRQ; i <= JAZZ_TIMER_IRQ; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 1; + irq_desc[i].chip = &r4030_irq_type; + } r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, 0); r4030_read_reg16(JAZZ_IO_IRQ_SOURCE); /* clear pending IRQs */ @@ -79,26 +94,26 @@ void __init arch_init_irq(void) change_c0_status(ST0_IM, IE_IRQ4 | IE_IRQ3 | IE_IRQ2 | IE_IRQ1); } -static void loc_call(unsigned int irq, unsigned int mask) +static void loc_call(unsigned int irq, struct pt_regs *regs, unsigned int mask) { r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, r4030_read_reg16(JAZZ_IO_IRQ_ENABLE) & mask); - do_IRQ(irq); + do_IRQ(irq, regs); r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, r4030_read_reg16(JAZZ_IO_IRQ_ENABLE) | mask); } -static void ll_local_dev(void) +static void ll_local_dev(struct pt_regs *regs) { switch (r4030_read_reg32(JAZZ_IO_IRQ_SOURCE)) { case 0: panic("Unimplemented loc_no_irq handler"); break; case 4: - loc_call(JAZZ_PARALLEL_IRQ, JAZZ_IE_PARALLEL); + loc_call(JAZZ_PARALLEL_IRQ, regs, JAZZ_IE_PARALLEL); break; case 8: - loc_call(JAZZ_PARALLEL_IRQ, JAZZ_IE_FLOPPY); + loc_call(JAZZ_PARALLEL_IRQ, regs, JAZZ_IE_FLOPPY); break; case 12: panic("Unimplemented loc_sound handler"); @@ -107,27 +122,27 @@ static void ll_local_dev(void) panic("Unimplemented loc_video handler"); break; case 20: - loc_call(JAZZ_ETHERNET_IRQ, JAZZ_IE_ETHERNET); + loc_call(JAZZ_ETHERNET_IRQ, regs, JAZZ_IE_ETHERNET); break; case 24: - loc_call(JAZZ_SCSI_IRQ, JAZZ_IE_SCSI); + loc_call(JAZZ_SCSI_IRQ, regs, JAZZ_IE_SCSI); break; case 28: - loc_call(JAZZ_KEYBOARD_IRQ, JAZZ_IE_KEYBOARD); + loc_call(JAZZ_KEYBOARD_IRQ, regs, JAZZ_IE_KEYBOARD); break; case 32: - loc_call(JAZZ_MOUSE_IRQ, JAZZ_IE_MOUSE); + loc_call(JAZZ_MOUSE_IRQ, regs, JAZZ_IE_MOUSE); break; case 36: - loc_call(JAZZ_SERIAL1_IRQ, JAZZ_IE_SERIAL1); + loc_call(JAZZ_SERIAL1_IRQ, regs, JAZZ_IE_SERIAL1); break; case 40: - loc_call(JAZZ_SERIAL2_IRQ, JAZZ_IE_SERIAL2); + loc_call(JAZZ_SERIAL2_IRQ, regs, JAZZ_IE_SERIAL2); break; } } -asmlinkage void plat_irq_dispatch(void) +asmlinkage void plat_irq_dispatch(struct pt_regs *regs) { unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; @@ -135,13 +150,13 @@ asmlinkage void plat_irq_dispatch(void) write_c0_compare(0); else if (pending & IE_IRQ4) { r4030_read_reg32(JAZZ_TIMER_REGISTER); - do_IRQ(JAZZ_TIMER_IRQ); + do_IRQ(JAZZ_TIMER_IRQ, regs); } else if (pending & IE_IRQ3) panic("Unimplemented ISA NMI handler"); else if (pending & IE_IRQ2) - do_IRQ(r4030_read_reg32(JAZZ_EISA_IRQ_ACK)); + do_IRQ(r4030_read_reg32(JAZZ_EISA_IRQ_ACK), regs); else if (pending & IE_IRQ1) { - ll_local_dev(); + ll_local_dev(regs); } else if (unlikely(pending & IE_IRQ0)) panic("Unimplemented local_dma handler"); else if (pending & IE_SW1) { diff --git a/trunk/arch/mips/jazz/setup.c b/trunk/arch/mips/jazz/setup.c index d848f1a07786..487a9ea1ef00 100644 --- a/trunk/arch/mips/jazz/setup.c +++ b/trunk/arch/mips/jazz/setup.c @@ -19,12 +19,12 @@ #include #include #include -#include #include #include #include #include +#include #include #include #include @@ -37,7 +37,7 @@ extern void jazz_machine_restart(char *command); extern void jazz_machine_halt(void); extern void jazz_machine_power_off(void); -void __init plat_timer_setup(struct irqaction *irq) +void __init plat_time_init(struct irqaction *irq) { /* set the clock to 100 Hz */ r4030_write_reg32(JAZZ_TIMER_INTERVAL, 9); @@ -45,27 +45,10 @@ void __init plat_timer_setup(struct irqaction *irq) } static struct resource jazz_io_resources[] = { - { - .start = 0x00, - .end = 0x1f, - .name = "dma1", - .flags = IORESOURCE_BUSY - }, { - .start = 0x40, - .end = 0x5f, - .name = "timer", - .end = IORESOURCE_BUSY - }, { - .start = 0x80, - .end = 0x8f, - .name = "dma page reg", - .flags = IORESOURCE_BUSY - }, { - .start = 0xc0, - .end = 0xdf, - .name = "dma2", - .flags = IORESOURCE_BUSY - } + { "dma1", 0x00, 0x1f, IORESOURCE_BUSY }, + { "timer", 0x40, 0x5f, IORESOURCE_BUSY }, + { "dma page reg", 0x80, 0x8f, IORESOURCE_BUSY }, + { "dma2", 0xc0, 0xdf, IORESOURCE_BUSY }, }; void __init plat_mem_setup(void) @@ -98,6 +81,8 @@ void __init plat_mem_setup(void) _machine_halt = jazz_machine_halt; pm_power_off = jazz_machine_power_off; +#warning "Somebody should check if screen_info is ok for Jazz." + screen_info = (struct screen_info) { 0, 0, /* orig-x, orig-y */ 0, /* unused */ diff --git a/trunk/arch/mips/jmr3927/rbhma3100/irq.c b/trunk/arch/mips/jmr3927/rbhma3100/irq.c index 3da49c5aaf49..722174481467 100644 --- a/trunk/arch/mips/jmr3927/rbhma3100/irq.c +++ b/trunk/arch/mips/jmr3927/rbhma3100/irq.c @@ -46,7 +46,6 @@ #include #include -#include #include #include #include @@ -90,6 +89,17 @@ static unsigned char irc_level[TX3927_NUM_IR] = { static void jmr3927_irq_disable(unsigned int irq_nr); static void jmr3927_irq_enable(unsigned int irq_nr); +static DEFINE_SPINLOCK(jmr3927_irq_lock); + +static unsigned int jmr3927_irq_startup(unsigned int irq) +{ + jmr3927_irq_enable(irq); + + return 0; +} + +#define jmr3927_irq_shutdown jmr3927_irq_disable + static void jmr3927_irq_ack(unsigned int irq) { if (irq == JMR3927_IRQ_IRC_TMR0) @@ -107,7 +117,9 @@ static void jmr3927_irq_end(unsigned int irq) static void jmr3927_irq_disable(unsigned int irq_nr) { struct tb_irq_space* sp; + unsigned long flags; + spin_lock_irqsave(&jmr3927_irq_lock, flags); for (sp = tb_irq_spaces; sp; sp = sp->next) { if (sp->start_irqno <= irq_nr && irq_nr < sp->start_irqno + sp->nr_irqs) { @@ -117,12 +129,15 @@ static void jmr3927_irq_disable(unsigned int irq_nr) break; } } + spin_unlock_irqrestore(&jmr3927_irq_lock, flags); } static void jmr3927_irq_enable(unsigned int irq_nr) { struct tb_irq_space* sp; + unsigned long flags; + spin_lock_irqsave(&jmr3927_irq_lock, flags); for (sp = tb_irq_spaces; sp; sp = sp->next) { if (sp->start_irqno <= irq_nr && irq_nr < sp->start_irqno + sp->nr_irqs) { @@ -132,6 +147,7 @@ static void jmr3927_irq_enable(unsigned int irq_nr) break; } } + spin_unlock_irqrestore(&jmr3927_irq_lock, flags); } /* @@ -223,83 +239,45 @@ struct tb_irq_space jmr3927_ioc_irqspace = { .space_id = 0, can_share : 1 }; - struct tb_irq_space jmr3927_irc_irqspace = { - .next = NULL, - .start_irqno = JMR3927_IRQ_IRC, - .nr_irqs = JMR3927_NR_IRQ_IRC, - .mask_func = mask_irq_irc, - .unmask_func = unmask_irq_irc, - .name = "on-chip", - .space_id = 0, - .can_share = 0 + .next = NULL, + .start_irqno = JMR3927_IRQ_IRC, + nr_irqs : JMR3927_NR_IRQ_IRC, + .mask_func = mask_irq_irc, + .unmask_func = unmask_irq_irc, + .name = "on-chip", + .space_id = 0, + can_share : 0 }; - -#ifdef CONFIG_TX_BRANCH_LIKELY_BUG_WORKAROUND -static int tx_branch_likely_bug_count = 0; -static int have_tx_branch_likely_bug = 0; - -static void tx_branch_likely_bug_fixup(void) +void jmr3927_spurious(struct pt_regs *regs) { - struct pt_regs *regs = get_irq_regs(); - - /* TX39/49-BUG: Under this condition, the insn in delay slot - of the branch likely insn is executed (not nullified) even - the branch condition is false. */ - if (!have_tx_branch_likely_bug) - return; - if ((regs->cp0_epc & 0xfff) == 0xffc && - KSEGX(regs->cp0_epc) != KSEG0 && - KSEGX(regs->cp0_epc) != KSEG1) { - unsigned int insn = *(unsigned int*)(regs->cp0_epc - 4); - /* beql,bnel,blezl,bgtzl */ - /* bltzl,bgezl,blezall,bgezall */ - /* bczfl, bcztl */ - if ((insn & 0xf0000000) == 0x50000000 || - (insn & 0xfc0e0000) == 0x04020000 || - (insn & 0xf3fe0000) == 0x41020000) { - regs->cp0_epc -= 4; - tx_branch_likely_bug_count++; - printk(KERN_INFO - "fix branch-likery bug in %s (insn %08x)\n", - current->comm, insn); - } - } -} -#endif - -static void jmr3927_spurious(void) -{ - struct pt_regs * regs = get_irq_regs(); - #ifdef CONFIG_TX_BRANCH_LIKELY_BUG_WORKAROUND - tx_branch_likely_bug_fixup(); + tx_branch_likely_bug_fixup(regs); #endif printk(KERN_WARNING "spurious interrupt (cause 0x%lx, pc 0x%lx, ra 0x%lx).\n", regs->cp0_cause, regs->cp0_epc, regs->regs[31]); } -asmlinkage void plat_irq_dispatch(void) +asmlinkage void plat_irq_dispatch(struct pt_regs *regs) { - struct pt_regs * regs = get_irq_regs(); int irq; #ifdef CONFIG_TX_BRANCH_LIKELY_BUG_WORKAROUND - tx_branch_likely_bug_fixup(); + tx_branch_likely_bug_fixup(regs); #endif if ((regs->cp0_cause & CAUSEF_IP7) == 0) { #if 0 - jmr3927_spurious(); + jmr3927_spurious(regs); #endif return; } irq = (regs->cp0_cause >> CAUSEB_IP2) & 0x0f; - do_IRQ(irq + JMR3927_IRQ_IRC); + do_IRQ(irq + JMR3927_IRQ_IRC, regs); } -static irqreturn_t jmr3927_ioc_interrupt(int irq, void *dev_id) +static irqreturn_t jmr3927_ioc_interrupt(int irq, void *dev_id, struct pt_regs *regs) { unsigned char istat = jmr3927_ioc_reg_in(JMR3927_IOC_INTS2_ADDR); int i; @@ -307,7 +285,7 @@ static irqreturn_t jmr3927_ioc_interrupt(int irq, void *dev_id) for (i = 0; i < JMR3927_NR_IRQ_IOC; i++) { if (istat & (1 << i)) { irq = JMR3927_IRQ_IOC + i; - do_IRQ(irq); + do_IRQ(irq, regs); } } return IRQ_HANDLED; @@ -317,7 +295,7 @@ static struct irqaction ioc_action = { jmr3927_ioc_interrupt, 0, CPU_MASK_NONE, "IOC", NULL, NULL, }; -static irqreturn_t jmr3927_isac_interrupt(int irq, void *dev_id) +static irqreturn_t jmr3927_isac_interrupt(int irq, void *dev_id, struct pt_regs *regs) { unsigned char istat = jmr3927_isac_reg_in(JMR3927_ISAC_INTS2_ADDR); int i; @@ -325,7 +303,7 @@ static irqreturn_t jmr3927_isac_interrupt(int irq, void *dev_id) for (i = 0; i < JMR3927_NR_IRQ_ISAC; i++) { if (istat & (1 << i)) { irq = JMR3927_IRQ_ISAC + i; - do_IRQ(irq); + do_IRQ(irq, regs); } } return IRQ_HANDLED; @@ -336,7 +314,7 @@ static struct irqaction isac_action = { }; -static irqreturn_t jmr3927_isaerr_interrupt(int irq, void *dev_id) +static irqreturn_t jmr3927_isaerr_interrupt(int irq, void * dev_id, struct pt_regs * regs) { printk(KERN_WARNING "ISA error interrupt (irq 0x%x).\n", irq); @@ -346,7 +324,7 @@ static struct irqaction isaerr_action = { jmr3927_isaerr_interrupt, 0, CPU_MASK_NONE, "ISA error", NULL, NULL, }; -static irqreturn_t jmr3927_pcierr_interrupt(int irq, void *dev_id) +static irqreturn_t jmr3927_pcierr_interrupt(int irq, void * dev_id, struct pt_regs * regs) { printk(KERN_WARNING "PCI error interrupt (irq 0x%x).\n", irq); printk(KERN_WARNING "pcistat:%02x, lbstat:%04lx\n", @@ -440,10 +418,11 @@ void __init arch_init_irq(void) static struct irq_chip jmr3927_irq_controller = { .typename = "jmr3927_irq", + .startup = jmr3927_irq_startup, + .shutdown = jmr3927_irq_shutdown, + .enable = jmr3927_irq_enable, + .disable = jmr3927_irq_disable, .ack = jmr3927_irq_ack, - .mask = jmr3927_irq_disable, - .mask_ack = jmr3927_irq_ack, - .unmask = jmr3927_irq_enable, .end = jmr3927_irq_end, }; @@ -451,8 +430,42 @@ void jmr3927_irq_init(u32 irq_base) { u32 i; - for (i= irq_base; i< irq_base + JMR3927_NR_IRQ_IRC + JMR3927_NR_IRQ_IOC; i++) - set_irq_chip(i, &jmr3927_irq_controller); + for (i= irq_base; i< irq_base + JMR3927_NR_IRQ_IRC + JMR3927_NR_IRQ_IOC; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = NULL; + irq_desc[i].depth = 1; + irq_desc[i].chip = &jmr3927_irq_controller; + } jmr3927_irq_base = irq_base; } + +#ifdef CONFIG_TX_BRANCH_LIKELY_BUG_WORKAROUND +static int tx_branch_likely_bug_count = 0; +static int have_tx_branch_likely_bug = 0; +void tx_branch_likely_bug_fixup(struct pt_regs *regs) +{ + /* TX39/49-BUG: Under this condition, the insn in delay slot + of the branch likely insn is executed (not nullified) even + the branch condition is false. */ + if (!have_tx_branch_likely_bug) + return; + if ((regs->cp0_epc & 0xfff) == 0xffc && + KSEGX(regs->cp0_epc) != KSEG0 && + KSEGX(regs->cp0_epc) != KSEG1) { + unsigned int insn = *(unsigned int*)(regs->cp0_epc - 4); + /* beql,bnel,blezl,bgtzl */ + /* bltzl,bgezl,blezall,bgezall */ + /* bczfl, bcztl */ + if ((insn & 0xf0000000) == 0x50000000 || + (insn & 0xfc0e0000) == 0x04020000 || + (insn & 0xf3fe0000) == 0x41020000) { + regs->cp0_epc -= 4; + tx_branch_likely_bug_count++; + printk(KERN_INFO + "fix branch-likery bug in %s (insn %08x)\n", + current->comm, insn); + } + } +} +#endif diff --git a/trunk/arch/mips/jmr3927/rbhma3100/setup.c b/trunk/arch/mips/jmr3927/rbhma3100/setup.c index 138f25efe38a..025434054ed0 100644 --- a/trunk/arch/mips/jmr3927/rbhma3100/setup.c +++ b/trunk/arch/mips/jmr3927/rbhma3100/setup.c @@ -170,20 +170,12 @@ static void jmr3927_machine_power_off(void) while (1); } -static cycle_t jmr3927_hpt_read(void) -{ - /* We assume this function is called xtime_lock held. */ - return jiffies * (JMR3927_TIMER_CLK / HZ) + jmr3927_tmrptr->trr; -} - #define USE_RTC_DS1742 #ifdef USE_RTC_DS1742 extern void rtc_ds1742_init(unsigned long base); #endif static void __init jmr3927_time_init(void) { - clocksource_mips.read = jmr3927_hpt_read; - mips_hpt_frequency = JMR3927_TIMER_CLK; #ifdef USE_RTC_DS1742 if (jmr3927_have_nvram()) { rtc_ds1742_init(JMR3927_IOC_NVRAMB_ADDR); @@ -191,8 +183,12 @@ static void __init jmr3927_time_init(void) #endif } +unsigned long jmr3927_do_gettimeoffset(void); + void __init plat_timer_setup(struct irqaction *irq) { + do_gettimeoffset = jmr3927_do_gettimeoffset; + jmr3927_tmrptr->cpra = JMR3927_TIMER_CLK / HZ; jmr3927_tmrptr->itmr = TXx927_TMTITMR_TIIE | TXx927_TMTITMR_TZCE; jmr3927_tmrptr->ccdr = JMR3927_TIMER_CCD; @@ -204,6 +200,34 @@ void __init plat_timer_setup(struct irqaction *irq) #define USECS_PER_JIFFY (1000000/HZ) +unsigned long jmr3927_do_gettimeoffset(void) +{ + unsigned long count; + unsigned long res = 0; + + /* MUST read TRR before TISR. */ + count = jmr3927_tmrptr->trr; + + if (jmr3927_tmrptr->tisr & TXx927_TMTISR_TIIS) { + /* timer interrupt is pending. use Max value. */ + res = USECS_PER_JIFFY - 1; + } else { + /* convert to usec */ + /* res = count / (JMR3927_TIMER_CLK / 1000000); */ + res = (count << 7) / ((JMR3927_TIMER_CLK << 7) / 1000000); + + /* + * Due to possible jiffies inconsistencies, we need to check + * the result so that we'll get a timer that is monotonic. + */ + if (res >= USECS_PER_JIFFY) + res = USECS_PER_JIFFY-1; + } + + return res; +} + + //#undef DO_WRITE_THROUGH #define DO_WRITE_THROUGH #define DO_ENABLE_CACHE diff --git a/trunk/arch/mips/kernel/Makefile b/trunk/arch/mips/kernel/Makefile index bbbb8d7cb89b..cd9cec9e39e9 100644 --- a/trunk/arch/mips/kernel/Makefile +++ b/trunk/arch/mips/kernel/Makefile @@ -6,7 +6,7 @@ extra-y := head.o init_task.o vmlinux.lds obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \ ptrace.o reset.o semaphore.o setup.o signal.o syscall.o \ - time.o topology.o traps.o unaligned.o + time.o traps.o unaligned.o binfmt_irix-objs := irixelf.o irixinv.o irixioctl.o irixsig.o \ irix5sys.o sysirix.o @@ -45,6 +45,7 @@ obj-$(CONFIG_MIPS_APSP_KSPD) += kspd.o obj-$(CONFIG_MIPS_VPE_LOADER) += vpe.o obj-$(CONFIG_MIPS_VPE_APSP_API) += rtlx.o +obj-$(CONFIG_NO_ISA) += dma-no-isa.o obj-$(CONFIG_I8259) += i8259.o obj-$(CONFIG_IRQ_CPU) += irq_cpu.o obj-$(CONFIG_IRQ_CPU_RM7K) += irq-rm7000.o @@ -66,8 +67,6 @@ obj-$(CONFIG_64BIT) += cpu-bugs64.o obj-$(CONFIG_I8253) += i8253.o -obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o - CFLAGS_cpu-bugs64.o = $(shell if $(CC) $(CFLAGS) -Wa,-mdaddi -c -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-DHAVE_AS_SET_DADDI"; fi) EXTRA_AFLAGS := $(CFLAGS) diff --git a/trunk/arch/mips/kernel/asm-offsets.c b/trunk/arch/mips/kernel/asm-offsets.c index ff88b06f89df..ec28077d5ee2 100644 --- a/trunk/arch/mips/kernel/asm-offsets.c +++ b/trunk/arch/mips/kernel/asm-offsets.c @@ -22,7 +22,7 @@ #define offset(string, ptr, member) \ __asm__("\n@@@" string "%0" : : "i" (_offset(ptr, member))) #define constant(string, member) \ - __asm__("\n@@@" string "%X0" : : "ri" (member)) + __asm__("\n@@@" string "%x0" : : "ri" (member)) #define size(string, size) \ __asm__("\n@@@" string "%0" : : "i" (sizeof(size))) #define linefeed text("") @@ -93,12 +93,11 @@ void output_thread_info_defines(void) offset("#define TI_TASK ", struct thread_info, task); offset("#define TI_EXEC_DOMAIN ", struct thread_info, exec_domain); offset("#define TI_FLAGS ", struct thread_info, flags); - offset("#define TI_TP_VALUE ", struct thread_info, tp_value); offset("#define TI_CPU ", struct thread_info, cpu); offset("#define TI_PRE_COUNT ", struct thread_info, preempt_count); offset("#define TI_ADDR_LIMIT ", struct thread_info, addr_limit); offset("#define TI_RESTART_BLOCK ", struct thread_info, restart_block); - offset("#define TI_REGS ", struct thread_info, regs); + offset("#define TI_TP_VALUE ", struct thread_info, tp_value); constant("#define _THREAD_SIZE_ORDER ", THREAD_SIZE_ORDER); constant("#define _THREAD_SIZE ", THREAD_SIZE); constant("#define _THREAD_MASK ", THREAD_MASK); diff --git a/trunk/arch/mips/kernel/cpu-probe.c b/trunk/arch/mips/kernel/cpu-probe.c index 442839e9578c..9fbf8430c849 100644 --- a/trunk/arch/mips/kernel/cpu-probe.c +++ b/trunk/arch/mips/kernel/cpu-probe.c @@ -110,8 +110,9 @@ static inline void check_wait(void) { struct cpuinfo_mips *c = ¤t_cpu_data; + printk("Checking for 'wait' instruction... "); if (nowait) { - printk("Wait instruction disabled.\n"); + printk (" disabled.\n"); return; } @@ -119,9 +120,11 @@ static inline void check_wait(void) case CPU_R3081: case CPU_R3081E: cpu_wait = r3081_wait; + printk(" available.\n"); break; case CPU_TX3927: cpu_wait = r39xx_wait; + printk(" available.\n"); break; case CPU_R4200: /* case CPU_R4300: */ @@ -132,6 +135,7 @@ static inline void check_wait(void) case CPU_R5000: case CPU_NEVADA: case CPU_RM7000: + case CPU_RM9000: case CPU_4KC: case CPU_4KEC: case CPU_4KSC: @@ -143,23 +147,25 @@ static inline void check_wait(void) case CPU_74K: case CPU_PR4450: cpu_wait = r4k_wait; + printk(" available.\n"); break; case CPU_TX49XX: cpu_wait = r4k_wait_irqoff; + printk(" available.\n"); break; case CPU_AU1000: case CPU_AU1100: case CPU_AU1500: case CPU_AU1550: case CPU_AU1200: - if (allow_au1k_wait) + if (allow_au1k_wait) { cpu_wait = au1k_wait; - break; - case CPU_RM9000: - if ((c->processor_id & 0x00ff) >= 0x40) - cpu_wait = r4k_wait; + printk(" available.\n"); + } else + printk(" unavailable.\n"); break; default: + printk(" unavailable.\n"); break; } } diff --git a/trunk/arch/mips/kernel/dma-no-isa.c b/trunk/arch/mips/kernel/dma-no-isa.c new file mode 100644 index 000000000000..6df8b07741e3 --- /dev/null +++ b/trunk/arch/mips/kernel/dma-no-isa.c @@ -0,0 +1,28 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2004 by Ralf Baechle + * + * Dummy ISA DMA functions for systems that don't have ISA but share drivers + * with ISA such as legacy free PCI. + */ +#include +#include +#include + +DEFINE_SPINLOCK(dma_spin_lock); + +int request_dma(unsigned int dmanr, const char * device_id) +{ + return -EINVAL; +} + +void free_dma(unsigned int dmanr) +{ +} + +EXPORT_SYMBOL(dma_spin_lock); +EXPORT_SYMBOL(request_dma); +EXPORT_SYMBOL(free_dma); diff --git a/trunk/arch/mips/kernel/entry.S b/trunk/arch/mips/kernel/entry.S index f10b6a19f8bf..766655f35250 100644 --- a/trunk/arch/mips/kernel/entry.S +++ b/trunk/arch/mips/kernel/entry.S @@ -20,7 +20,10 @@ #include #endif -#ifndef CONFIG_PREEMPT +#ifdef CONFIG_PREEMPT + .macro preempt_stop + .endm +#else .macro preempt_stop local_irq_disable .endm @@ -29,16 +32,9 @@ .text .align 5 -FEXPORT(ret_from_irq) - LONG_S s0, TI_REGS($28) -#ifdef CONFIG_PREEMPT -FEXPORT(ret_from_exception) -#else - b _ret_from_irq FEXPORT(ret_from_exception) preempt_stop -#endif -FEXPORT(_ret_from_irq) +FEXPORT(ret_from_irq) LONG_L t0, PT_STATUS(sp) # returning to kernel mode? andi t0, t0, KU_USER beqz t0, resume_kernel @@ -83,10 +79,8 @@ FEXPORT(syscall_exit) FEXPORT(restore_all) # restore full frame #ifdef CONFIG_MIPS_MT_SMTC /* Detect and execute deferred IPI "interrupts" */ - LONG_L s0, TI_REGS($28) - LONG_S sp, TI_REGS($28) + move a0,sp jal deferred_smtc_ipi - LONG_S s0, TI_REGS($28) /* Re-arm any temporarily masked interrupts not explicitly "acked" */ mfc0 v0, CP0_TCSTATUS ori v1, v0, TCSTATUS_IXMT diff --git a/trunk/arch/mips/kernel/genex.S b/trunk/arch/mips/kernel/genex.S index aacd4a005c5f..af6ef2fd8300 100644 --- a/trunk/arch/mips/kernel/genex.S +++ b/trunk/arch/mips/kernel/genex.S @@ -19,7 +19,6 @@ #include #include #include -#include #define PANIC_PIC(msg) \ .set push; \ @@ -132,9 +131,8 @@ NESTED(handle_int, PT_SIZE, sp) CLI TRACE_IRQS_OFF - LONG_L s0, TI_REGS($28) - LONG_S sp, TI_REGS($28) PTR_LA ra, ret_from_irq + move a0, sp j plat_irq_dispatch END(handle_int) @@ -221,9 +219,7 @@ NESTED(except_vec_vi_handler, 0, sp) #endif /* CONFIG_MIPS_MT_SMTC */ CLI TRACE_IRQS_OFF - - LONG_L s0, TI_REGS($28) - LONG_S sp, TI_REGS($28) + move a0, sp PTR_LA ra, ret_from_irq jr v0 END(except_vec_vi_handler) @@ -379,68 +375,6 @@ NESTED(nmi_handler, PT_SIZE, sp) BUILD_HANDLER dsp dsp sti silent /* #26 */ BUILD_HANDLER reserved reserved sti verbose /* others */ - .align 5 - LEAF(handle_ri_rdhwr_vivt) -#ifdef CONFIG_MIPS_MT_SMTC - PANIC_PIC("handle_ri_rdhwr_vivt called") -#else - .set push - .set noat - .set noreorder - /* check if TLB contains a entry for EPC */ - MFC0 k1, CP0_ENTRYHI - andi k1, 0xff /* ASID_MASK */ - MFC0 k0, CP0_EPC - PTR_SRL k0, PAGE_SHIFT + 1 - PTR_SLL k0, PAGE_SHIFT + 1 - or k1, k0 - MTC0 k1, CP0_ENTRYHI - mtc0_tlbw_hazard - tlbp - tlb_probe_hazard - mfc0 k1, CP0_INDEX - .set pop - bltz k1, handle_ri /* slow path */ - /* fall thru */ -#endif - END(handle_ri_rdhwr_vivt) - - LEAF(handle_ri_rdhwr) - .set push - .set noat - .set noreorder - /* 0x7c03e83b: rdhwr v1,$29 */ - MFC0 k1, CP0_EPC - lui k0, 0x7c03 - lw k1, (k1) - ori k0, 0xe83b - .set reorder - bne k0, k1, handle_ri /* if not ours */ - /* The insn is rdhwr. No need to check CAUSE.BD here. */ - get_saved_sp /* k1 := current_thread_info */ - .set noreorder - MFC0 k0, CP0_EPC -#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) - ori k1, _THREAD_MASK - xori k1, _THREAD_MASK - LONG_L v1, TI_TP_VALUE(k1) - LONG_ADDIU k0, 4 - jr k0 - rfe -#else - LONG_ADDIU k0, 4 /* stall on $k0 */ - MTC0 k0, CP0_EPC - /* I hope three instructions between MTC0 and ERET are enough... */ - ori k1, _THREAD_MASK - xori k1, _THREAD_MASK - LONG_L v1, TI_TP_VALUE(k1) - .set mips3 - eret - .set mips0 -#endif - .set pop - END(handle_ri_rdhwr) - #ifdef CONFIG_64BIT /* A temporary overflow handler used by check_daddi(). */ diff --git a/trunk/arch/mips/kernel/head.S b/trunk/arch/mips/kernel/head.S index a2e095adaa3f..8c6db0fc72f0 100644 --- a/trunk/arch/mips/kernel/head.S +++ b/trunk/arch/mips/kernel/head.S @@ -189,8 +189,7 @@ NESTED(kernel_entry, 16, sp) # kernel entry point MTC0 zero, CP0_CONTEXT # clear context register PTR_LA $28, init_thread_union - PTR_LI sp, _THREAD_SIZE - 32 - PTR_ADDU sp, $28 + PTR_ADDIU sp, $28, _THREAD_SIZE - 32 set_saved_sp sp, t0, t1 PTR_SUBU sp, 4 * SZREG # init stack pointer @@ -250,9 +249,6 @@ NESTED(smp_bootstrap, 16, sp) */ page swapper_pg_dir, _PGD_ORDER #ifdef CONFIG_64BIT -#if defined(CONFIG_MODULES) && !defined(CONFIG_BUILD_ELF64) - page module_pg_dir, _PGD_ORDER -#endif page invalid_pmd_table, _PMD_ORDER #endif page invalid_pte_table, _PTE_ORDER diff --git a/trunk/arch/mips/kernel/i8259.c b/trunk/arch/mips/kernel/i8259.c index 2526c0ca4d81..48e3418c217b 100644 --- a/trunk/arch/mips/kernel/i8259.c +++ b/trunk/arch/mips/kernel/i8259.c @@ -40,10 +40,21 @@ static void end_8259A_irq (unsigned int irq) enable_8259A_irq(irq); } +#define shutdown_8259A_irq disable_8259A_irq + void mask_and_ack_8259A(unsigned int); +static unsigned int startup_8259A_irq(unsigned int irq) +{ + enable_8259A_irq(irq); + + return 0; /* never anything pending */ +} + static struct irq_chip i8259A_irq_type = { .typename = "XT-PIC", + .startup = startup_8259A_irq, + .shutdown = shutdown_8259A_irq, .enable = enable_8259A_irq, .disable = disable_8259A_irq, .ack = mask_and_ack_8259A, @@ -109,7 +120,7 @@ int i8259A_irq_pending(unsigned int irq) void make_8259A_irq(unsigned int irq) { disable_irq_nosync(irq); - set_irq_chip(irq, &i8259A_irq_type); + irq_desc[irq].chip = &i8259A_irq_type; enable_irq(irq); } @@ -312,8 +323,12 @@ void __init init_i8259_irqs (void) init_8259A(0); - for (i = 0; i < 16; i++) - set_irq_chip(i, &i8259A_irq_type); + for (i = 0; i < 16; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = NULL; + irq_desc[i].depth = 1; + irq_desc[i].chip = &i8259A_irq_type; + } setup_irq(2, &irq2); } diff --git a/trunk/arch/mips/kernel/irq-msc01.c b/trunk/arch/mips/kernel/irq-msc01.c index bcaad6696082..63dfeb41796b 100644 --- a/trunk/arch/mips/kernel/irq-msc01.c +++ b/trunk/arch/mips/kernel/irq-msc01.c @@ -1,17 +1,16 @@ /* + * Copyright (c) 2004 MIPS Inc + * Author: chris@mips.com + * * 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. - * - * Copyright (c) 2004 MIPS Inc - * Author: chris@mips.com - * - * Copyright (C) 2004, 06 Ralf Baechle */ #include #include #include +#include #include #include #include @@ -44,6 +43,31 @@ static inline void unmask_msc_irq(unsigned int irq) MSCIC_WRITE(MSC01_IC_ENAH, 1<<(irq - irq_base - 32)); } +/* + * Enables the IRQ on SOC-it + */ +static void enable_msc_irq(unsigned int irq) +{ + unmask_msc_irq(irq); +} + +/* + * Initialize the IRQ on SOC-it + */ +static unsigned int startup_msc_irq(unsigned int irq) +{ + unmask_msc_irq(irq); + return 0; +} + +/* + * Disables the IRQ on SOC-it + */ +static void disable_msc_irq(unsigned int irq) +{ + mask_msc_irq(irq); +} + /* * Masks and ACKs an IRQ */ @@ -91,14 +115,14 @@ static void end_msc_irq(unsigned int irq) /* * Interrupt handler for interrupts coming from SOC-it. */ -void ll_msc_irq(void) +void ll_msc_irq(struct pt_regs *regs) { unsigned int irq; /* read the interrupt vector register */ MSCIC_READ(MSC01_IC_VEC, irq); if (irq < 64) - do_IRQ(irq + irq_base); + do_IRQ(irq + irq_base, regs); else { /* Ignore spurious interrupt */ } @@ -111,23 +135,25 @@ msc_bind_eic_interrupt (unsigned int irq, unsigned int set) (irq<im_type) { case MSC01_IRQ_EDGE: - set_irq_chip(base+n, &msc_edgeirq_type); + irq_desc[base+n].chip = &msc_edgeirq_type; if (cpu_has_veic) MSCIC_WRITE(MSC01_IC_SUP+n*8, MSC01_IC_SUP_EDGE_BIT); else MSCIC_WRITE(MSC01_IC_SUP+n*8, MSC01_IC_SUP_EDGE_BIT | imp->im_lvl); break; case MSC01_IRQ_LEVEL: - set_irq_chip(base+n, &msc_levelirq_type); + irq_desc[base+n].chip = &msc_levelirq_type; if (cpu_has_veic) MSCIC_WRITE(MSC01_IC_SUP+n*8, 0); else diff --git a/trunk/arch/mips/kernel/irq-mv6434x.c b/trunk/arch/mips/kernel/irq-mv6434x.c index 6cfb31cafde2..b117e64da64d 100644 --- a/trunk/arch/mips/kernel/irq-mv6434x.c +++ b/trunk/arch/mips/kernel/irq-mv6434x.c @@ -1,7 +1,7 @@ /* * Copyright 2002 Momentum Computer * Author: mdharm@momenco.com - * Copyright (C) 2004, 06 Ralf Baechle + * Copyright (C) 2004 Ralf Baechle * * 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 @@ -15,6 +15,7 @@ #include #include +#include #include #include #include @@ -66,6 +67,39 @@ static inline void unmask_mv64340_irq(unsigned int irq) } } +/* + * Enables the IRQ on Marvell Chip + */ +static void enable_mv64340_irq(unsigned int irq) +{ + unmask_mv64340_irq(irq); +} + +/* + * Initialize the IRQ on Marvell Chip + */ +static unsigned int startup_mv64340_irq(unsigned int irq) +{ + unmask_mv64340_irq(irq); + return 0; +} + +/* + * Disables the IRQ on Marvell Chip + */ +static void disable_mv64340_irq(unsigned int irq) +{ + mask_mv64340_irq(irq); +} + +/* + * Masks and ACKs an IRQ + */ +static void mask_and_ack_mv64340_irq(unsigned int irq) +{ + mask_mv64340_irq(irq); +} + /* * End IRQ processing */ @@ -79,7 +113,7 @@ static void end_mv64340_irq(unsigned int irq) * Interrupt handler for interrupts coming from the Marvell chip. * It could be built in ethernet ports etc... */ -void ll_mv64340_irq(void) +void ll_mv64340_irq(struct pt_regs *regs) { unsigned int irq_src_low, irq_src_high; unsigned int irq_mask_low, irq_mask_high; @@ -95,17 +129,20 @@ void ll_mv64340_irq(void) irq_src_high &= irq_mask_high; if (irq_src_low) - do_IRQ(ls1bit32(irq_src_low) + irq_base); + do_IRQ(ls1bit32(irq_src_low) + irq_base, regs); else - do_IRQ(ls1bit32(irq_src_high) + irq_base + 32); + do_IRQ(ls1bit32(irq_src_high) + irq_base + 32, regs); } +#define shutdown_mv64340_irq disable_mv64340_irq + struct irq_chip mv64340_irq_type = { .typename = "MV-64340", - .ack = mask_mv64340_irq, - .mask = mask_mv64340_irq, - .mask_ack = mask_mv64340_irq, - .unmask = unmask_mv64340_irq, + .startup = startup_mv64340_irq, + .shutdown = shutdown_mv64340_irq, + .enable = enable_mv64340_irq, + .disable = disable_mv64340_irq, + .ack = mask_and_ack_mv64340_irq, .end = end_mv64340_irq, }; @@ -113,9 +150,13 @@ void __init mv64340_irq_init(unsigned int base) { int i; - for (i = base; i < base + 64; i++) - set_irq_chip_and_handler(i, &mv64340_irq_type, - handle_level_irq); + /* Reset irq handlers pointers to NULL */ + for (i = base; i < base + 64; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 2; + irq_desc[i].chip = &mv64340_irq_type; + } irq_base = base; } diff --git a/trunk/arch/mips/kernel/irq-rm7000.c b/trunk/arch/mips/kernel/irq-rm7000.c index ddcc2a5f8a06..6b54c7109e2e 100644 --- a/trunk/arch/mips/kernel/irq-rm7000.c +++ b/trunk/arch/mips/kernel/irq-rm7000.c @@ -29,6 +29,42 @@ static inline void mask_rm7k_irq(unsigned int irq) clear_c0_intcontrol(0x100 << (irq - irq_base)); } +static inline void rm7k_cpu_irq_enable(unsigned int irq) +{ + unsigned long flags; + + local_irq_save(flags); + unmask_rm7k_irq(irq); + local_irq_restore(flags); +} + +static void rm7k_cpu_irq_disable(unsigned int irq) +{ + unsigned long flags; + + local_irq_save(flags); + mask_rm7k_irq(irq); + local_irq_restore(flags); +} + +static unsigned int rm7k_cpu_irq_startup(unsigned int irq) +{ + rm7k_cpu_irq_enable(irq); + + return 0; +} + +#define rm7k_cpu_irq_shutdown rm7k_cpu_irq_disable + +/* + * While we ack the interrupt interrupts are disabled and thus we don't need + * to deal with concurrency issues. Same for rm7k_cpu_irq_end. + */ +static void rm7k_cpu_irq_ack(unsigned int irq) +{ + mask_rm7k_irq(irq); +} + static void rm7k_cpu_irq_end(unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) @@ -37,10 +73,11 @@ static void rm7k_cpu_irq_end(unsigned int irq) static struct irq_chip rm7k_irq_controller = { .typename = "RM7000", - .ack = mask_rm7k_irq, - .mask = mask_rm7k_irq, - .mask_ack = mask_rm7k_irq, - .unmask = unmask_rm7k_irq, + .startup = rm7k_cpu_irq_startup, + .shutdown = rm7k_cpu_irq_shutdown, + .enable = rm7k_cpu_irq_enable, + .disable = rm7k_cpu_irq_disable, + .ack = rm7k_cpu_irq_ack, .end = rm7k_cpu_irq_end, }; @@ -50,9 +87,12 @@ void __init rm7k_cpu_irq_init(int base) clear_c0_intcontrol(0x00000f00); /* Mask all */ - for (i = base; i < base + 4; i++) - set_irq_chip_and_handler(i, &rm7k_irq_controller, - handle_level_irq); + for (i = base; i < base + 4; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = NULL; + irq_desc[i].depth = 1; + irq_desc[i].chip = &rm7k_irq_controller; + } irq_base = base; } diff --git a/trunk/arch/mips/kernel/irq-rm9000.c b/trunk/arch/mips/kernel/irq-rm9000.c index ba6440c88abd..62f011ba97a2 100644 --- a/trunk/arch/mips/kernel/irq-rm9000.c +++ b/trunk/arch/mips/kernel/irq-rm9000.c @@ -48,6 +48,15 @@ static void rm9k_cpu_irq_disable(unsigned int irq) local_irq_restore(flags); } +static unsigned int rm9k_cpu_irq_startup(unsigned int irq) +{ + rm9k_cpu_irq_enable(irq); + + return 0; +} + +#define rm9k_cpu_irq_shutdown rm9k_cpu_irq_disable + /* * Performance counter interrupts are global on all processors. */ @@ -80,6 +89,16 @@ static void rm9k_perfcounter_irq_shutdown(unsigned int irq) on_each_cpu(local_rm9k_perfcounter_irq_shutdown, (void *) irq, 0, 1); } + +/* + * While we ack the interrupt interrupts are disabled and thus we don't need + * to deal with concurrency issues. Same for rm9k_cpu_irq_end. + */ +static void rm9k_cpu_irq_ack(unsigned int irq) +{ + mask_rm9k_irq(irq); +} + static void rm9k_cpu_irq_end(unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) @@ -88,10 +107,11 @@ static void rm9k_cpu_irq_end(unsigned int irq) static struct irq_chip rm9k_irq_controller = { .typename = "RM9000", - .ack = mask_rm9k_irq, - .mask = mask_rm9k_irq, - .mask_ack = mask_rm9k_irq, - .unmask = unmask_rm9k_irq, + .startup = rm9k_cpu_irq_startup, + .shutdown = rm9k_cpu_irq_shutdown, + .enable = rm9k_cpu_irq_enable, + .disable = rm9k_cpu_irq_disable, + .ack = rm9k_cpu_irq_ack, .end = rm9k_cpu_irq_end, }; @@ -99,10 +119,9 @@ static struct irq_chip rm9k_perfcounter_irq = { .typename = "RM9000", .startup = rm9k_perfcounter_irq_startup, .shutdown = rm9k_perfcounter_irq_shutdown, - .ack = mask_rm9k_irq, - .mask = mask_rm9k_irq, - .mask_ack = mask_rm9k_irq, - .unmask = unmask_rm9k_irq, + .enable = rm9k_cpu_irq_enable, + .disable = rm9k_cpu_irq_disable, + .ack = rm9k_cpu_irq_ack, .end = rm9k_cpu_irq_end, }; @@ -116,13 +135,15 @@ void __init rm9k_cpu_irq_init(int base) clear_c0_intcontrol(0x0000f000); /* Mask all */ - for (i = base; i < base + 4; i++) - set_irq_chip_and_handler(i, &rm9k_irq_controller, - handle_level_irq); + for (i = base; i < base + 4; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = NULL; + irq_desc[i].depth = 1; + irq_desc[i].chip = &rm9k_irq_controller; + } rm9000_perfcount_irq = base + 1; - set_irq_chip_and_handler(rm9000_perfcount_irq, &rm9k_perfcounter_irq, - handle_level_irq); + irq_desc[rm9000_perfcount_irq].chip = &rm9k_perfcounter_irq; irq_base = base; } diff --git a/trunk/arch/mips/kernel/irq.c b/trunk/arch/mips/kernel/irq.c index b339798b3172..d955aaefbb8e 100644 --- a/trunk/arch/mips/kernel/irq.c +++ b/trunk/arch/mips/kernel/irq.c @@ -26,48 +26,6 @@ #include #include -static unsigned long irq_map[NR_IRQS / BITS_PER_LONG]; - -int __devinit allocate_irqno(void) -{ - int irq; - -again: - irq = find_first_zero_bit(irq_map, NR_IRQS); - - if (irq >= NR_IRQS) - return -ENOSPC; - - if (test_and_set_bit(irq, irq_map)) - goto again; - - return irq; -} - -EXPORT_SYMBOL_GPL(allocate_irqno); - -/* - * Allocate the 16 legacy interrupts for i8259 devices. This happens early - * in the kernel initialization so treating allocation failure as BUG() is - * ok. - */ -void __init alloc_legacy_irqno(void) -{ - int i; - - for (i = 0; i <= 16; i++) - BUG_ON(test_and_set_bit(i, irq_map)); -} - -void __devinit free_irqno(unsigned int irq) -{ - smp_mb__before_clear_bit(); - clear_bit(irq, irq_map); - smp_mb__after_clear_bit(); -} - -EXPORT_SYMBOL_GPL(free_irqno); - /* * 'what should we do if we get a hw irq event on an illegal vector'. * each architecture has to answer this themselves. @@ -88,6 +46,25 @@ atomic_t irq_err_count; unsigned long irq_hwmask[NR_IRQS]; #endif /* CONFIG_MIPS_MT_SMTC */ +#undef do_IRQ + +/* + * do_IRQ handles all normal device IRQ's (the special + * SMP cross-CPU interrupts have their own specific + * handlers). + */ +asmlinkage unsigned int do_IRQ(unsigned int irq, struct pt_regs *regs) +{ + irq_enter(); + + __DO_IRQ_SMTC_HOOK(); + __do_IRQ(irq, regs); + + irq_exit(); + + return 1; +} + /* * Generic, controller-independent functions: */ @@ -133,7 +110,7 @@ int show_interrupts(struct seq_file *p, void *v) return 0; } -asmlinkage void spurious_interrupt(void) +asmlinkage void spurious_interrupt(struct pt_regs *regs) { atomic_inc(&irq_err_count); } @@ -153,6 +130,19 @@ __setup("nokgdb", nokgdb); void __init init_IRQ(void) { + int i; + + for (i = 0; i < NR_IRQS; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = NULL; + irq_desc[i].depth = 1; + irq_desc[i].chip = &no_irq_chip; + spin_lock_init(&irq_desc[i].lock); +#ifdef CONFIG_MIPS_MT_SMTC + irq_hwmask[i] = 0; +#endif /* CONFIG_MIPS_MT_SMTC */ + } + arch_init_irq(); #ifdef CONFIG_KGDB diff --git a/trunk/arch/mips/kernel/irq_cpu.c b/trunk/arch/mips/kernel/irq_cpu.c index be5ac23d3812..9bb21c7f2149 100644 --- a/trunk/arch/mips/kernel/irq_cpu.c +++ b/trunk/arch/mips/kernel/irq_cpu.c @@ -50,6 +50,44 @@ static inline void mask_mips_irq(unsigned int irq) irq_disable_hazard(); } +static inline void mips_cpu_irq_enable(unsigned int irq) +{ + unsigned long flags; + + local_irq_save(flags); + unmask_mips_irq(irq); + back_to_back_c0_hazard(); + local_irq_restore(flags); +} + +static void mips_cpu_irq_disable(unsigned int irq) +{ + unsigned long flags; + + local_irq_save(flags); + mask_mips_irq(irq); + back_to_back_c0_hazard(); + local_irq_restore(flags); +} + +static unsigned int mips_cpu_irq_startup(unsigned int irq) +{ + mips_cpu_irq_enable(irq); + + return 0; +} + +#define mips_cpu_irq_shutdown mips_cpu_irq_disable + +/* + * While we ack the interrupt interrupts are disabled and thus we don't need + * to deal with concurrency issues. Same for mips_cpu_irq_end. + */ +static void mips_cpu_irq_ack(unsigned int irq) +{ + mask_mips_irq(irq); +} + static void mips_cpu_irq_end(unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) @@ -58,11 +96,11 @@ static void mips_cpu_irq_end(unsigned int irq) static struct irq_chip mips_cpu_irq_controller = { .typename = "MIPS", - .ack = mask_mips_irq, - .mask = mask_mips_irq, - .mask_ack = mask_mips_irq, - .unmask = unmask_mips_irq, - .eoi = unmask_mips_irq, + .startup = mips_cpu_irq_startup, + .shutdown = mips_cpu_irq_shutdown, + .enable = mips_cpu_irq_enable, + .disable = mips_cpu_irq_disable, + .ack = mips_cpu_irq_ack, .end = mips_cpu_irq_end, }; @@ -72,6 +110,8 @@ static struct irq_chip mips_cpu_irq_controller = { #define unmask_mips_mt_irq unmask_mips_irq #define mask_mips_mt_irq mask_mips_irq +#define mips_mt_cpu_irq_enable mips_cpu_irq_enable +#define mips_mt_cpu_irq_disable mips_cpu_irq_disable static unsigned int mips_mt_cpu_irq_startup(unsigned int irq) { @@ -79,11 +119,13 @@ static unsigned int mips_mt_cpu_irq_startup(unsigned int irq) clear_c0_cause(0x100 << (irq - mips_cpu_irq_base)); evpe(vpflags); - unmask_mips_mt_irq(irq); + mips_mt_cpu_irq_enable(irq); return 0; } +#define mips_mt_cpu_irq_shutdown mips_mt_cpu_irq_disable + /* * While we ack the interrupt interrupts are disabled and thus we don't need * to deal with concurrency issues. Same for mips_cpu_irq_end. @@ -101,11 +143,10 @@ static void mips_mt_cpu_irq_ack(unsigned int irq) static struct irq_chip mips_mt_cpu_irq_controller = { .typename = "MIPS", .startup = mips_mt_cpu_irq_startup, + .shutdown = mips_mt_cpu_irq_shutdown, + .enable = mips_mt_cpu_irq_enable, + .disable = mips_mt_cpu_irq_disable, .ack = mips_mt_cpu_irq_ack, - .mask = mask_mips_mt_irq, - .mask_ack = mips_mt_cpu_irq_ack, - .unmask = unmask_mips_mt_irq, - .eoi = unmask_mips_mt_irq, .end = mips_mt_cpu_irq_end, }; @@ -122,12 +163,19 @@ void __init mips_cpu_irq_init(int irq_base) * leave them uninitialized for other processors. */ if (cpu_has_mipsmt) - for (i = irq_base; i < irq_base + 2; i++) - set_irq_chip(i, &mips_mt_cpu_irq_controller); - - for (i = irq_base + 2; i < irq_base + 8; i++) - set_irq_chip_and_handler(i, &mips_cpu_irq_controller, - handle_level_irq); + for (i = irq_base; i < irq_base + 2; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = NULL; + irq_desc[i].depth = 1; + irq_desc[i].chip = &mips_mt_cpu_irq_controller; + } + + for (i = irq_base + 2; i < irq_base + 8; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = NULL; + irq_desc[i].depth = 1; + irq_desc[i].chip = &mips_cpu_irq_controller; + } mips_cpu_irq_base = irq_base; } diff --git a/trunk/arch/mips/kernel/linux32.c b/trunk/arch/mips/kernel/linux32.c index 7a3ebbeba1f3..53f4171fc188 100644 --- a/trunk/arch/mips/kernel/linux32.c +++ b/trunk/arch/mips/kernel/linux32.c @@ -1055,9 +1055,7 @@ asmlinkage long sys32_newuname(struct new_utsname __user * name) asmlinkage int sys32_personality(unsigned long personality) { int ret; - personality &= 0xffffffff; - if (personality(current->personality) == PER_LINUX32 && - personality == PER_LINUX) + if (current->personality == PER_LINUX32 && personality == PER_LINUX) personality = PER_LINUX32; ret = sys_personality(personality); if (ret == PER_LINUX32) diff --git a/trunk/arch/mips/kernel/machine_kexec.c b/trunk/arch/mips/kernel/machine_kexec.c deleted file mode 100644 index e0ad754c7edd..000000000000 --- a/trunk/arch/mips/kernel/machine_kexec.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * machine_kexec.c for kexec - * Created by on Thu Oct 12 15:15:06 2006 - * - * This source code is licensed under the GNU General Public License, - * Version 2. See the file COPYING for more details. - */ - -#include -#include -#include - -#include -#include - -const extern unsigned char relocate_new_kernel[]; -const extern unsigned int relocate_new_kernel_size; - -extern unsigned long kexec_start_address; -extern unsigned long kexec_indirection_page; - -int -machine_kexec_prepare(struct kimage *kimage) -{ - return 0; -} - -void -machine_kexec_cleanup(struct kimage *kimage) -{ -} - -void -machine_shutdown(void) -{ -} - -void -machine_crash_shutdown(struct pt_regs *regs) -{ -} - -void -machine_kexec(struct kimage *image) -{ - unsigned long reboot_code_buffer; - unsigned long entry; - unsigned long *ptr; - - reboot_code_buffer = - (unsigned long)page_address(image->control_code_page); - - kexec_start_address = image->start; - kexec_indirection_page = phys_to_virt(image->head & PAGE_MASK); - - memcpy((void*)reboot_code_buffer, relocate_new_kernel, - relocate_new_kernel_size); - - /* - * The generic kexec code builds a page list with physical - * addresses. they are directly accessible through KSEG0 (or - * CKSEG0 or XPHYS if on 64bit system), hence the - * pys_to_virt() call. - */ - for (ptr = &image->head; (entry = *ptr) && !(entry &IND_DONE); - ptr = (entry & IND_INDIRECTION) ? - phys_to_virt(entry & PAGE_MASK) : ptr + 1) { - if (*ptr & IND_SOURCE || *ptr & IND_INDIRECTION || - *ptr & IND_DESTINATION) - *ptr = phys_to_virt(*ptr); - } - - /* - * we do not want to be bothered. - */ - local_irq_disable(); - - flush_icache_range(reboot_code_buffer, - reboot_code_buffer + KEXEC_CONTROL_CODE_SIZE); - - printk("Will call new kernel at %08x\n", image->start); - printk("Bye ...\n"); - flush_cache_all(); - ((void (*)(void))reboot_code_buffer)(); -} diff --git a/trunk/arch/mips/kernel/module.c b/trunk/arch/mips/kernel/module.c index cb0801437b66..d7bf0215bc1d 100644 --- a/trunk/arch/mips/kernel/module.c +++ b/trunk/arch/mips/kernel/module.c @@ -29,7 +29,6 @@ #include #include #include -#include /* MODULE_START */ struct mips_hi16 { struct mips_hi16 *next; @@ -44,23 +43,9 @@ static DEFINE_SPINLOCK(dbe_lock); void *module_alloc(unsigned long size) { -#ifdef MODULE_START - struct vm_struct *area; - - size = PAGE_ALIGN(size); - if (!size) - return NULL; - - area = __get_vm_area(size, VM_ALLOC, MODULE_START, MODULE_END); - if (!area) - return NULL; - - return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL); -#else if (size == 0) return NULL; return vmalloc(size); -#endif } /* Free memory returned from module_alloc */ diff --git a/trunk/arch/mips/kernel/proc.c b/trunk/arch/mips/kernel/proc.c index 4ed37ba19731..d8beef107902 100644 --- a/trunk/arch/mips/kernel/proc.c +++ b/trunk/arch/mips/kernel/proc.c @@ -89,9 +89,9 @@ static const char *cpu_name[] = { static int show_cpuinfo(struct seq_file *m, void *v) { + unsigned int version = current_cpu_data.processor_id; + unsigned int fp_vers = current_cpu_data.fpu_id; unsigned long n = (unsigned long) v - 1; - unsigned int version = cpu_data[n].processor_id; - unsigned int fp_vers = cpu_data[n].fpu_id; char fmt [64]; #ifdef CONFIG_SMP @@ -107,9 +107,9 @@ static int show_cpuinfo(struct seq_file *m, void *v) seq_printf(m, "processor\t\t: %ld\n", n); sprintf(fmt, "cpu model\t\t: %%s V%%d.%%d%s\n", - cpu_data[n].options & MIPS_CPU_FPU ? " FPU V%d.%d" : ""); - seq_printf(m, fmt, cpu_name[cpu_data[n].cputype <= CPU_LAST ? - cpu_data[n].cputype : CPU_UNKNOWN], + cpu_has_fpu ? " FPU V%d.%d" : ""); + seq_printf(m, fmt, cpu_name[current_cpu_data.cputype <= CPU_LAST ? + current_cpu_data.cputype : CPU_UNKNOWN], (version >> 4) & 0x0f, version & 0x0f, (fp_vers >> 4) & 0x0f, fp_vers & 0x0f); seq_printf(m, "BogoMIPS\t\t: %lu.%02lu\n", @@ -118,7 +118,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) seq_printf(m, "wait instruction\t: %s\n", cpu_wait ? "yes" : "no"); seq_printf(m, "microsecond timers\t: %s\n", cpu_has_counter ? "yes" : "no"); - seq_printf(m, "tlb_entries\t\t: %d\n", cpu_data[n].tlbsize); + seq_printf(m, "tlb_entries\t\t: %d\n", current_cpu_data.tlbsize); seq_printf(m, "extra interrupt vector\t: %s\n", cpu_has_divec ? "yes" : "no"); seq_printf(m, "hardware watchpoint\t: %s\n", diff --git a/trunk/arch/mips/kernel/process.c b/trunk/arch/mips/kernel/process.c index ec8209f3a0c6..045d987bc683 100644 --- a/trunk/arch/mips/kernel/process.c +++ b/trunk/arch/mips/kernel/process.c @@ -115,7 +115,7 @@ void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp) status |= KU_USER; regs->cp0_status = status; clear_used_math(); - clear_fpu_owner(); + lose_fpu(); if (cpu_has_dsp) __init_dsp(); regs->cp0_epc = pc; @@ -358,8 +358,10 @@ static int __init frame_info_init(void) unsigned long size = 0; #ifdef CONFIG_KALLSYMS unsigned long ofs; + char *modname; + char namebuf[KSYM_NAME_LEN + 1]; - kallsyms_lookup_size_offset((unsigned long)schedule, &size, &ofs); + kallsyms_lookup((unsigned long)schedule, &size, &ofs, &modname, namebuf); #endif schedule_mfi.func = schedule; schedule_mfi.func_size = size; @@ -401,6 +403,8 @@ unsigned long unwind_stack(struct task_struct *task, unsigned long *sp, { unsigned long stack_page; struct mips_frame_info info; + char *modname; + char namebuf[KSYM_NAME_LEN + 1]; unsigned long size, ofs; int leaf; extern void ret_from_irq(void); @@ -429,7 +433,7 @@ unsigned long unwind_stack(struct task_struct *task, unsigned long *sp, } return 0; } - if (!kallsyms_lookup_size_offset(pc, &size, &ofs)) + if (!kallsyms_lookup(pc, &size, &ofs, &modname, namebuf)) return 0; /* * Return ra if an exception occured at the first instruction diff --git a/trunk/arch/mips/kernel/ptrace.c b/trunk/arch/mips/kernel/ptrace.c index 258d74fd0b63..362d1728e531 100644 --- a/trunk/arch/mips/kernel/ptrace.c +++ b/trunk/arch/mips/kernel/ptrace.c @@ -106,7 +106,6 @@ int ptrace_setregs (struct task_struct *child, __s64 __user *data) int ptrace_getfpregs (struct task_struct *child, __u32 __user *data) { int i; - unsigned int tmp; if (!access_ok(VERIFY_WRITE, data, 33 * 8)) return -EIO; @@ -122,10 +121,10 @@ int ptrace_getfpregs (struct task_struct *child, __u32 __user *data) __put_user (child->thread.fpu.fcr31, data + 64); - preempt_disable(); if (cpu_has_fpu) { - unsigned int flags; + unsigned int flags, tmp; + preempt_disable(); if (cpu_has_mipsmt) { unsigned int vpflags = dvpe(); flags = read_c0_status(); @@ -139,11 +138,11 @@ int ptrace_getfpregs (struct task_struct *child, __u32 __user *data) __asm__ __volatile__("cfc1\t%0,$0" : "=r" (tmp)); write_c0_status(flags); } + preempt_enable(); + __put_user (tmp, data + 65); } else { - tmp = 0; + __put_user ((__u32) 0, data + 65); } - preempt_enable(); - __put_user (tmp, data + 65); return 0; } @@ -246,17 +245,16 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) unsigned int mtflags; #endif /* CONFIG_MIPS_MT_SMTC */ - preempt_disable(); - if (!cpu_has_fpu) { - preempt_enable(); + if (!cpu_has_fpu) break; - } #ifdef CONFIG_MIPS_MT_SMTC /* Read-modify-write of Status must be atomic */ local_irq_save(irqflags); mtflags = dmt(); #endif /* CONFIG_MIPS_MT_SMTC */ + + preempt_disable(); if (cpu_has_mipsmt) { unsigned int vpflags = dvpe(); flags = read_c0_status(); diff --git a/trunk/arch/mips/kernel/ptrace32.c b/trunk/arch/mips/kernel/ptrace32.c index d9a39c169450..f40ecd8be05f 100644 --- a/trunk/arch/mips/kernel/ptrace32.c +++ b/trunk/arch/mips/kernel/ptrace32.c @@ -175,9 +175,7 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data) unsigned int mtflags; #endif /* CONFIG_MIPS_MT_SMTC */ - preempt_disable(); if (!cpu_has_fpu) { - preempt_enable(); tmp = 0; break; } @@ -188,6 +186,7 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data) mtflags = dmt(); #endif /* CONFIG_MIPS_MT_SMTC */ + preempt_disable(); if (cpu_has_mipsmt) { unsigned int vpflags = dvpe(); flags = read_c0_status(); diff --git a/trunk/arch/mips/kernel/r4k_switch.S b/trunk/arch/mips/kernel/r4k_switch.S index cc566cf12246..d5c8b82fed72 100644 --- a/trunk/arch/mips/kernel/r4k_switch.S +++ b/trunk/arch/mips/kernel/r4k_switch.S @@ -85,12 +85,7 @@ move $28, a2 cpu_restore_nonscratch a1 -#if (_THREAD_SIZE - 32) < 0x10000 PTR_ADDIU t0, $28, _THREAD_SIZE - 32 -#else - PTR_LI t0, _THREAD_SIZE - 32 - PTR_ADDU t0, $28 -#endif set_saved_sp t0, t1, t2 #ifdef CONFIG_MIPS_MT_SMTC /* Read-modify-writes of Status must be atomic on a VPE */ diff --git a/trunk/arch/mips/kernel/relocate_kernel.S b/trunk/arch/mips/kernel/relocate_kernel.S deleted file mode 100644 index a3f0d00c1334..000000000000 --- a/trunk/arch/mips/kernel/relocate_kernel.S +++ /dev/null @@ -1,80 +0,0 @@ -/* - * relocate_kernel.S for kexec - * Created by on Thu Oct 12 17:49:57 2006 - * - * This source code is licensed under the GNU General Public License, - * Version 2. See the file COPYING for more details. - */ - -#include -#include -#include -#include -#include -#include -#include - - .globl relocate_new_kernel -relocate_new_kernel: - - PTR_L s0, kexec_indirection_page - PTR_L s1, kexec_start_address - -process_entry: - PTR_L s2, (s0) - PTR_ADD s0, s0, SZREG - - /* destination page */ - and s3, s2, 0x1 - beq s3, zero, 1f - and s4, s2, ~0x1 /* store destination addr in s4 */ - move a0, s4 - b process_entry - -1: - /* indirection page, update s0 */ - and s3, s2, 0x2 - beq s3, zero, 1f - and s0, s2, ~0x2 - b process_entry - -1: - /* done page */ - and s3, s2, 0x4 - beq s3, zero, 1f - b done -1: - /* source page */ - and s3, s2, 0x8 - beq s3, zero, process_entry - and s2, s2, ~0x8 - li s6, (1 << PAGE_SHIFT) / SZREG - -copy_word: - /* copy page word by word */ - REG_L s5, (s2) - REG_S s5, (s4) - INT_ADD s4, s4, SZREG - INT_ADD s2, s2, SZREG - INT_SUB s6, s6, 1 - beq s6, zero, process_entry - b copy_word - b process_entry - -done: - /* jump to kexec_start_address */ - j s1 - - .globl kexec_start_address -kexec_start_address: - .long 0x0 - - .globl kexec_indirection_page -kexec_indirection_page: - .long 0x0 - -relocate_new_kernel_end: - - .globl relocate_new_kernel_size -relocate_new_kernel_size: - .long relocate_new_kernel_end - relocate_new_kernel diff --git a/trunk/arch/mips/kernel/rtlx.c b/trunk/arch/mips/kernel/rtlx.c index 8c8c8324f775..cdab1b2cd134 100644 --- a/trunk/arch/mips/kernel/rtlx.c +++ b/trunk/arch/mips/kernel/rtlx.c @@ -61,16 +61,16 @@ static int sp_stopping = 0; extern void *vpe_get_shared(int index); -static void rtlx_dispatch(void) +static void rtlx_dispatch(struct pt_regs *regs) { - do_IRQ(MIPSCPU_INT_BASE + MIPS_CPU_RTLX_IRQ); + do_IRQ(MIPSCPU_INT_BASE + MIPS_CPU_RTLX_IRQ, regs); } /* Interrupt handler may be called before rtlx_init has otherwise had a chance to run. */ -static irqreturn_t rtlx_interrupt(int irq, void *dev_id) +static irqreturn_t rtlx_interrupt(int irq, void *dev_id, struct pt_regs *regs) { int i; diff --git a/trunk/arch/mips/kernel/scall32-o32.S b/trunk/arch/mips/kernel/scall32-o32.S index 7c0b3936ba44..61362e6fa9ec 100644 --- a/trunk/arch/mips/kernel/scall32-o32.S +++ b/trunk/arch/mips/kernel/scall32-o32.S @@ -652,10 +652,7 @@ einval: li v0, -EINVAL sys sys_vmsplice 4 sys sys_move_pages 6 sys sys_set_robust_list 2 - sys sys_get_robust_list 3 /* 4310 */ - sys sys_kexec_load 4 - sys sys_getcpu 3 - sys sys_epoll_pwait 6 + sys sys_get_robust_list 3 .endm /* We pre-compute the number of _instruction_ bytes needed to diff --git a/trunk/arch/mips/kernel/scall64-64.S b/trunk/arch/mips/kernel/scall64-64.S index e569b846e9a3..6c7b5ed0ea6e 100644 --- a/trunk/arch/mips/kernel/scall64-64.S +++ b/trunk/arch/mips/kernel/scall64-64.S @@ -468,6 +468,3 @@ sys_call_table: PTR sys_move_pages PTR sys_set_robust_list PTR sys_get_robust_list - PTR sys_kexec_load /* 5270 */ - PTR sys_getcpu - PTR sys_epoll_pwait diff --git a/trunk/arch/mips/kernel/scall64-n32.S b/trunk/arch/mips/kernel/scall64-n32.S index 5b18f265d75b..6d9f18727ac5 100644 --- a/trunk/arch/mips/kernel/scall64-n32.S +++ b/trunk/arch/mips/kernel/scall64-n32.S @@ -280,7 +280,7 @@ EXPORT(sysn32_call_table) PTR sys_sync PTR sys_acct PTR sys32_settimeofday - PTR compat_sys_mount /* 6160 */ + PTR sys_mount /* 6160 */ PTR sys_umount PTR sys_swapon PTR sys_swapoff @@ -394,6 +394,3 @@ EXPORT(sysn32_call_table) PTR sys_move_pages PTR compat_sys_set_robust_list PTR compat_sys_get_robust_list - PTR compat_sys_kexec_load - PTR sys_getcpu - PTR sys_epoll_pwait diff --git a/trunk/arch/mips/kernel/scall64-o32.S b/trunk/arch/mips/kernel/scall64-o32.S index e91379c1be1d..2e6d0673163e 100644 --- a/trunk/arch/mips/kernel/scall64-o32.S +++ b/trunk/arch/mips/kernel/scall64-o32.S @@ -226,7 +226,7 @@ sys_call_table: PTR sys_ni_syscall /* was sys_stat */ PTR sys_lseek PTR sys_getpid /* 4020 */ - PTR compat_sys_mount + PTR sys_mount PTR sys_oldumount PTR sys_setuid PTR sys_getuid @@ -516,7 +516,4 @@ sys_call_table: PTR compat_sys_move_pages PTR compat_sys_set_robust_list PTR compat_sys_get_robust_list /* 4310 */ - PTR compat_sys_kexec_load - PTR sys_getcpu - PTR sys_epoll_pwait .size sys_call_table,.-sys_call_table diff --git a/trunk/arch/mips/kernel/setup.c b/trunk/arch/mips/kernel/setup.c index 89440a0d8528..fdbb508661c5 100644 --- a/trunk/arch/mips/kernel/setup.c +++ b/trunk/arch/mips/kernel/setup.c @@ -145,12 +145,13 @@ static int __init rd_start_early(char *p) unsigned long start = memparse(p, &p); #ifdef CONFIG_64BIT - /* Guess if the sign extension was forgotten by bootloader */ - if (start < XKPHYS) - start = (int)start; + /* HACK: Guess if the sign extension was forgotten */ + if (start > 0x0000000080000000 && start < 0x00000000ffffffff) + start |= 0xffffffff00000000UL; #endif initrd_start = start; initrd_end += start; + return 0; } early_param("rd_start", rd_start_early); @@ -158,64 +159,41 @@ early_param("rd_start", rd_start_early); static int __init rd_size_early(char *p) { initrd_end += memparse(p, &p); + return 0; } early_param("rd_size", rd_size_early); -/* it returns the next free pfn after initrd */ static unsigned long __init init_initrd(void) { - unsigned long end; + unsigned long tmp, end, size; u32 *initrd_header; + ROOT_DEV = Root_RAM0; + /* * Board specific code or command line parser should have * already set up initrd_start and initrd_end. In these cases * perfom sanity checks and use them if all looks good. */ - if (initrd_start && initrd_end > initrd_start) - goto sanitize; - - /* - * See if initrd has been added to the kernel image by - * arch/mips/boot/addinitrd.c. In that case a header is - * prepended to initrd and is made up by 8 bytes. The fisrt - * word is a magic number and the second one is the size of - * initrd. Initrd start must be page aligned in any cases. - */ - initrd_header = __va(PAGE_ALIGN(__pa_symbol(&_end) + 8)) - 8; - if (initrd_header[0] != 0x494E5244) - goto disable; - initrd_start = (unsigned long)(initrd_header + 2); - initrd_end = initrd_start + initrd_header[1]; - -sanitize: - if (initrd_start & ~PAGE_MASK) { - printk(KERN_ERR "initrd start must be page aligned\n"); - goto disable; + size = initrd_end - initrd_start; + if (initrd_end == 0 || size == 0) { + initrd_start = 0; + initrd_end = 0; + } else + return initrd_end; + + end = (unsigned long)&_end; + tmp = PAGE_ALIGN(end) - sizeof(u32) * 2; + if (tmp < end) + tmp += PAGE_SIZE; + + initrd_header = (u32 *)tmp; + if (initrd_header[0] == 0x494E5244) { + initrd_start = (unsigned long)&initrd_header[2]; + initrd_end = initrd_start + initrd_header[1]; } - if (initrd_start < PAGE_OFFSET) { - printk(KERN_ERR "initrd start < PAGE_OFFSET\n"); - goto disable; - } - - /* - * Sanitize initrd addresses. For example firmware - * can't guess if they need to pass them through - * 64-bits values if the kernel has been built in pure - * 32-bit. We need also to switch from KSEG0 to XKPHYS - * addresses now, so the code can now safely use __pa(). - */ - end = __pa(initrd_end); - initrd_end = (unsigned long)__va(end); - initrd_start = (unsigned long)__va(__pa(initrd_start)); - - ROOT_DEV = Root_RAM0; - return PFN_UP(end); -disable: - initrd_start = 0; - initrd_end = 0; - return 0; + return initrd_end; } static void __init finalize_initrd(void) @@ -226,12 +204,12 @@ static void __init finalize_initrd(void) printk(KERN_INFO "Initrd not found or empty"); goto disable; } - if (__pa(initrd_end) > PFN_PHYS(max_low_pfn)) { + if (CPHYSADDR(initrd_end) > PFN_PHYS(max_low_pfn)) { printk("Initrd extends beyond end of memory"); goto disable; } - reserve_bootmem(__pa(initrd_start), size); + reserve_bootmem(CPHYSADDR(initrd_start), size); initrd_below_start_ok = 1; printk(KERN_INFO "Initial ramdisk at: 0x%lx (%lu bytes)\n", @@ -245,11 +223,7 @@ static void __init finalize_initrd(void) #else /* !CONFIG_BLK_DEV_INITRD */ -static unsigned long __init init_initrd(void) -{ - return 0; -} - +#define init_initrd() 0 #define finalize_initrd() do {} while (0) #endif @@ -281,7 +255,8 @@ static void __init bootmem_init(void) * not selected. Once that done we can determine the low bound * of usable memory. */ - reserved_end = max(init_initrd(), PFN_UP(__pa_symbol(&_end))); + reserved_end = init_initrd(); + reserved_end = PFN_UP(CPHYSADDR(max(reserved_end, (unsigned long)&_end))); /* * Find the highest page frame number we have available. @@ -453,10 +428,10 @@ static void __init resource_init(void) if (UNCAC_BASE != IO_BASE) return; - code_resource.start = __pa_symbol(&_text); - code_resource.end = __pa_symbol(&_etext) - 1; - data_resource.start = __pa_symbol(&_etext); - data_resource.end = __pa_symbol(&_edata) - 1; + code_resource.start = virt_to_phys(&_text); + code_resource.end = virt_to_phys(&_etext) - 1; + data_resource.start = virt_to_phys(&_etext); + data_resource.end = virt_to_phys(&_edata) - 1; /* * Request address space for all standard RAM. diff --git a/trunk/arch/mips/kernel/signal_n32.c b/trunk/arch/mips/kernel/signal_n32.c index a67c18555ed3..477c5334ec1b 100644 --- a/trunk/arch/mips/kernel/signal_n32.c +++ b/trunk/arch/mips/kernel/signal_n32.c @@ -17,6 +17,7 @@ */ #include #include +#include #include #include #include diff --git a/trunk/arch/mips/kernel/smp-mt.c b/trunk/arch/mips/kernel/smp-mt.c index 1ee689c0e0c9..766253c44f3f 100644 --- a/trunk/arch/mips/kernel/smp-mt.c +++ b/trunk/arch/mips/kernel/smp-mt.c @@ -106,22 +106,22 @@ void __init sanitize_tlb_entries(void) clear_c0_mvpcontrol(MVPCONTROL_VPC); } -static void ipi_resched_dispatch(void) +static void ipi_resched_dispatch (struct pt_regs *regs) { - do_IRQ(MIPSCPU_INT_BASE + MIPS_CPU_IPI_RESCHED_IRQ); + do_IRQ(MIPSCPU_INT_BASE + MIPS_CPU_IPI_RESCHED_IRQ, regs); } -static void ipi_call_dispatch(void) +static void ipi_call_dispatch (struct pt_regs *regs) { - do_IRQ(MIPSCPU_INT_BASE + MIPS_CPU_IPI_CALL_IRQ); + do_IRQ(MIPSCPU_INT_BASE + MIPS_CPU_IPI_CALL_IRQ, regs); } -static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id) +irqreturn_t ipi_resched_interrupt(int irq, void *dev_id, struct pt_regs *regs) { return IRQ_HANDLED; } -static irqreturn_t ipi_call_interrupt(int irq, void *dev_id) +irqreturn_t ipi_call_interrupt(int irq, void *dev_id, struct pt_regs *regs) { smp_call_function_interrupt(); @@ -140,90 +140,15 @@ static struct irqaction irq_call = { .name = "IPI_call" }; -static void __init smp_copy_vpe_config(void) -{ - write_vpe_c0_status( - (read_c0_status() & ~(ST0_IM | ST0_IE | ST0_KSU)) | ST0_CU0); - - /* set config to be the same as vpe0, particularly kseg0 coherency alg */ - write_vpe_c0_config( read_c0_config()); - - /* make sure there are no software interrupts pending */ - write_vpe_c0_cause(0); - - /* Propagate Config7 */ - write_vpe_c0_config7(read_c0_config7()); - - write_vpe_c0_count(read_c0_count()); -} - -static unsigned int __init smp_vpe_init(unsigned int tc, unsigned int mvpconf0, - unsigned int ncpu) -{ - if (tc > ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT)) - return ncpu; - - /* Deactivate all but VPE 0 */ - if (tc != 0) { - unsigned long tmp = read_vpe_c0_vpeconf0(); - - tmp &= ~VPECONF0_VPA; - - /* master VPE */ - tmp |= VPECONF0_MVP; - write_vpe_c0_vpeconf0(tmp); - - /* Record this as available CPU */ - cpu_set(tc, phys_cpu_present_map); - __cpu_number_map[tc] = ++ncpu; - __cpu_logical_map[ncpu] = tc; - } - - /* Disable multi-threading with TC's */ - write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() & ~VPECONTROL_TE); - - if (tc != 0) - smp_copy_vpe_config(); - - return ncpu; -} - -static void __init smp_tc_init(unsigned int tc, unsigned int mvpconf0) -{ - unsigned long tmp; - - if (!tc) - return; - - /* bind a TC to each VPE, May as well put all excess TC's - on the last VPE */ - if (tc >= (((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT)+1)) - write_tc_c0_tcbind(read_tc_c0_tcbind() | ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT)); - else { - write_tc_c0_tcbind(read_tc_c0_tcbind() | tc); - - /* and set XTC */ - write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | (tc << VPECONF0_XTC_SHIFT)); - } - - tmp = read_tc_c0_tcstatus(); - - /* mark not allocated and not dynamically allocatable */ - tmp &= ~(TCSTATUS_A | TCSTATUS_DA); - tmp |= TCSTATUS_IXMT; /* interrupt exempt */ - write_tc_c0_tcstatus(tmp); - - write_tc_c0_tchalt(TCHALT_H); -} - /* * Common setup before any secondaries are started * Make sure all CPU's are in a sensible state before we boot any of the * secondarys */ -void __init plat_smp_setup(void) +void plat_smp_setup(void) { - unsigned int mvpconf0, ntc, tc, ncpu = 0; + unsigned long val; + int i, num; #ifdef CONFIG_MIPS_MT_FPAFF /* If we have an FPU, enroll ourselves in the FPU-full mask */ @@ -242,16 +167,75 @@ void __init plat_smp_setup(void) /* Put MVPE's into 'configuration state' */ set_c0_mvpcontrol(MVPCONTROL_VPC); - mvpconf0 = read_c0_mvpconf0(); - ntc = (mvpconf0 & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT; + val = read_c0_mvpconf0(); /* we'll always have more TC's than VPE's, so loop setting everything to a sensible state */ - for (tc = 0; tc <= ntc; tc++) { - settc(tc); + for (i = 0, num = 0; i <= ((val & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT); i++) { + settc(i); + + /* VPE's */ + if (i <= ((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT)) { + + /* deactivate all but vpe0 */ + if (i != 0) { + unsigned long tmp = read_vpe_c0_vpeconf0(); + + tmp &= ~VPECONF0_VPA; + + /* master VPE */ + tmp |= VPECONF0_MVP; + write_vpe_c0_vpeconf0(tmp); + + /* Record this as available CPU */ + cpu_set(i, phys_cpu_present_map); + __cpu_number_map[i] = ++num; + __cpu_logical_map[num] = i; + } + + /* disable multi-threading with TC's */ + write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() & ~VPECONTROL_TE); + + if (i != 0) { + write_vpe_c0_status((read_c0_status() & ~(ST0_IM | ST0_IE | ST0_KSU)) | ST0_CU0); - smp_tc_init(tc, mvpconf0); - ncpu = smp_vpe_init(tc, mvpconf0, ncpu); + /* set config to be the same as vpe0, particularly kseg0 coherency alg */ + write_vpe_c0_config( read_c0_config()); + + /* make sure there are no software interrupts pending */ + write_vpe_c0_cause(0); + + /* Propagate Config7 */ + write_vpe_c0_config7(read_c0_config7()); + } + + } + + /* TC's */ + + if (i != 0) { + unsigned long tmp; + + /* bind a TC to each VPE, May as well put all excess TC's + on the last VPE */ + if ( i >= (((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT)+1) ) + write_tc_c0_tcbind(read_tc_c0_tcbind() | ((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) ); + else { + write_tc_c0_tcbind( read_tc_c0_tcbind() | i); + + /* and set XTC */ + write_vpe_c0_vpeconf0( read_vpe_c0_vpeconf0() | (i << VPECONF0_XTC_SHIFT)); + } + + tmp = read_tc_c0_tcstatus(); + + /* mark not allocated and not dynamically allocatable */ + tmp &= ~(TCSTATUS_A | TCSTATUS_DA); + tmp |= TCSTATUS_IXMT; /* interrupt exempt */ + write_tc_c0_tcstatus(tmp); + + write_tc_c0_tchalt(TCHALT_H); + } } /* Release config state */ @@ -259,15 +243,15 @@ void __init plat_smp_setup(void) /* We'll wait until starting the secondaries before starting MVPE */ - printk(KERN_INFO "Detected %i available secondary CPU(s)\n", ncpu); + printk(KERN_INFO "Detected %i available secondary CPU(s)\n", num); } void __init plat_prepare_cpus(unsigned int max_cpus) { /* set up ipi interrupts */ if (cpu_has_vint) { - set_vi_handler(MIPS_CPU_IPI_RESCHED_IRQ, ipi_resched_dispatch); - set_vi_handler(MIPS_CPU_IPI_CALL_IRQ, ipi_call_dispatch); + set_vi_handler (MIPS_CPU_IPI_RESCHED_IRQ, ipi_resched_dispatch); + set_vi_handler (MIPS_CPU_IPI_CALL_IRQ, ipi_call_dispatch); } cpu_ipi_resched_irq = MIPSCPU_INT_BASE + MIPS_CPU_IPI_RESCHED_IRQ; @@ -278,9 +262,7 @@ void __init plat_prepare_cpus(unsigned int max_cpus) /* need to mark IPI's as IRQ_PER_CPU */ irq_desc[cpu_ipi_resched_irq].status |= IRQ_PER_CPU; - set_irq_handler(cpu_ipi_resched_irq, handle_percpu_irq); irq_desc[cpu_ipi_call_irq].status |= IRQ_PER_CPU; - set_irq_handler(cpu_ipi_call_irq, handle_percpu_irq); } /* diff --git a/trunk/arch/mips/kernel/smp.c b/trunk/arch/mips/kernel/smp.c index 49db516789e0..221895802dca 100644 --- a/trunk/arch/mips/kernel/smp.c +++ b/trunk/arch/mips/kernel/smp.c @@ -310,7 +310,7 @@ static void flush_tlb_all_ipi(void *info) void flush_tlb_all(void) { - on_each_cpu(flush_tlb_all_ipi, NULL, 1, 1); + on_each_cpu(flush_tlb_all_ipi, 0, 1, 1); } static void flush_tlb_mm_ipi(void *mm) @@ -463,5 +463,24 @@ void flush_tlb_one(unsigned long vaddr) smp_on_each_tlb(flush_tlb_one_ipi, (void *) vaddr); } +static DEFINE_PER_CPU(struct cpu, cpu_devices); + +static int __init topology_init(void) +{ + int cpu; + int ret; + + for_each_present_cpu(cpu) { + ret = register_cpu(&per_cpu(cpu_devices, cpu), cpu); + if (ret) + printk(KERN_WARNING "topology_init: register_cpu %d " + "failed (%d)\n", cpu, ret); + } + + return 0; +} + +subsys_initcall(topology_init); + EXPORT_SYMBOL(flush_tlb_page); EXPORT_SYMBOL(flush_tlb_one); diff --git a/trunk/arch/mips/kernel/smtc-asm.S b/trunk/arch/mips/kernel/smtc-asm.S index 921207c4a83c..76cb31d57482 100644 --- a/trunk/arch/mips/kernel/smtc-asm.S +++ b/trunk/arch/mips/kernel/smtc-asm.S @@ -97,14 +97,15 @@ FEXPORT(__smtc_ipi_vector) SAVE_ALL CLI TRACE_IRQS_OFF + move a0,sp /* Function to be invoked passed stack pad slot 5 */ lw t0,PT_PADSLOT5(sp) /* Argument from sender passed in stack pad slot 4 */ - lw a0,PT_PADSLOT4(sp) - LONG_L s0, TI_REGS($28) - LONG_S sp, TI_REGS($28) - PTR_LA ra, ret_from_irq - jr t0 + lw a1,PT_PADSLOT4(sp) + jalr t0 + nop + j ret_from_irq + nop /* * Called from idle loop to provoke processing of queued IPIs @@ -121,10 +122,7 @@ LEAF(self_ipi) subu t1,sp,PT_SIZE sw ra,PT_EPC(t1) sw a0,PT_PADSLOT4(t1) - LONG_L s0, TI_REGS($28) - LONG_S sp, TI_REGS($28) la t2,ipi_decode - LONG_S s0, TI_REGS($28) sw t2,PT_PADSLOT5(t1) /* Save pre-disable value of TCStatus */ sw t0,PT_TCSTATUS(t1) diff --git a/trunk/arch/mips/kernel/smtc.c b/trunk/arch/mips/kernel/smtc.c index 802febed7df5..604bcc5cb7c8 100644 --- a/trunk/arch/mips/kernel/smtc.c +++ b/trunk/arch/mips/kernel/smtc.c @@ -82,7 +82,7 @@ struct smtc_ipi_q freeIPIq; /* Forward declarations */ -void ipi_decode(struct smtc_ipi *); +void ipi_decode(struct pt_regs *, struct smtc_ipi *); void post_direct_ipi(int cpu, struct smtc_ipi *pipi); void setup_cross_vpe_interrupts(void); void init_smtc_stats(void); @@ -476,7 +476,6 @@ void mipsmt_prepare_cpus(void) write_vpe_c0_compare(0); /* Propagate Config7 */ write_vpe_c0_config7(read_c0_config7()); - write_vpe_c0_count(read_c0_count()); } /* enable multi-threading within VPE */ write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() | VPECONTROL_TE); @@ -821,19 +820,19 @@ void post_direct_ipi(int cpu, struct smtc_ipi *pipi) write_tc_c0_tcrestart(__smtc_ipi_vector); } -static void ipi_resched_interrupt(void) +void ipi_resched_interrupt(struct pt_regs *regs) { /* Return from interrupt should be enough to cause scheduler check */ } -static void ipi_call_interrupt(void) +void ipi_call_interrupt(struct pt_regs *regs) { /* Invoke generic function invocation code in smp.c */ smp_call_function_interrupt(); } -void ipi_decode(struct smtc_ipi *pipi) +void ipi_decode(struct pt_regs *regs, struct smtc_ipi *pipi) { void *arg_copy = pipi->arg; int type_copy = pipi->type; @@ -847,15 +846,15 @@ void ipi_decode(struct smtc_ipi *pipi) #ifdef SMTC_IDLE_HOOK_DEBUG clock_hang_reported[dest_copy] = 0; #endif /* SMTC_IDLE_HOOK_DEBUG */ - local_timer_interrupt(0, NULL); + local_timer_interrupt(0, NULL, regs); break; case LINUX_SMP_IPI: switch ((int)arg_copy) { case SMP_RESCHEDULE_YOURSELF: - ipi_resched_interrupt(); + ipi_resched_interrupt(regs); break; case SMP_CALL_FUNCTION: - ipi_call_interrupt(); + ipi_call_interrupt(regs); break; default: printk("Impossible SMTC IPI Argument 0x%x\n", @@ -869,7 +868,7 @@ void ipi_decode(struct smtc_ipi *pipi) } } -void deferred_smtc_ipi(void) +void deferred_smtc_ipi(struct pt_regs *regs) { struct smtc_ipi *pipi; unsigned long flags; @@ -884,7 +883,7 @@ void deferred_smtc_ipi(void) while((pipi = smtc_ipi_dq(&IPIQ[q])) != NULL) { /* ipi_decode() should be called with interrupts off */ local_irq_save(flags); - ipi_decode(pipi); + ipi_decode(regs, pipi); local_irq_restore(flags); } } @@ -918,7 +917,7 @@ void smtc_timer_broadcast(int vpe) static int cpu_ipi_irq = MIPSCPU_INT_BASE + MIPS_CPU_IPI_IRQ; -static irqreturn_t ipi_interrupt(int irq, void *dev_idm) +static irqreturn_t ipi_interrupt(int irq, void *dev_idm, struct pt_regs *regs) { int my_vpe = cpu_data[smp_processor_id()].vpe_id; int my_tc = cpu_data[smp_processor_id()].tc_id; @@ -979,7 +978,7 @@ static irqreturn_t ipi_interrupt(int irq, void *dev_idm) * with interrupts off */ local_irq_save(flags); - ipi_decode(pipi); + ipi_decode(regs, pipi); local_irq_restore(flags); } } @@ -988,9 +987,9 @@ static irqreturn_t ipi_interrupt(int irq, void *dev_idm) return IRQ_HANDLED; } -static void ipi_irq_dispatch(void) +static void ipi_irq_dispatch(struct pt_regs *regs) { - do_IRQ(cpu_ipi_irq); + do_IRQ(cpu_ipi_irq, regs); } static struct irqaction irq_ipi; @@ -1009,7 +1008,6 @@ void setup_cross_vpe_interrupts(void) setup_irq_smtc(cpu_ipi_irq, &irq_ipi, (0x100 << MIPS_CPU_IPI_IRQ)); irq_desc[cpu_ipi_irq].status |= IRQ_PER_CPU; - set_irq_handler(cpu_ipi_irq, handle_percpu_irq); } /* diff --git a/trunk/arch/mips/kernel/stacktrace.c b/trunk/arch/mips/kernel/stacktrace.c index a586aba337a7..4aabe526a68e 100644 --- a/trunk/arch/mips/kernel/stacktrace.c +++ b/trunk/arch/mips/kernel/stacktrace.c @@ -57,7 +57,7 @@ static void save_context_stack(struct stack_trace *trace, pc = unwind_stack(task, &sp, pc, &ra); } while (pc); #else - save_raw_context_stack(trace, sp); + save_raw_context_stack(sp); #endif } diff --git a/trunk/arch/mips/kernel/time.c b/trunk/arch/mips/kernel/time.c index 11aab6d6bfe5..a8340802f2d7 100644 --- a/trunk/arch/mips/kernel/time.c +++ b/trunk/arch/mips/kernel/time.c @@ -67,9 +67,15 @@ int (*rtc_mips_set_time)(unsigned long) = null_rtc_set_time; int (*rtc_mips_set_mmss)(unsigned long); +/* usecs per counter cycle, shifted to left by 32 bits */ +static unsigned int sll32_usecs_per_cycle; + /* how many counter cycles in a jiffy */ static unsigned long cycles_per_jiffy __read_mostly; +/* Cycle counter value at the previous timer interrupt.. */ +static unsigned int timerhi, timerlo; + /* expirelo is the count value for next CPU timer interrupt */ static unsigned int expirelo; @@ -82,11 +88,17 @@ static void null_timer_ack(void) { /* nothing */ } /* * Null high precision timer functions for systems lacking one. */ -static cycle_t null_hpt_read(void) +static unsigned int null_hpt_read(void) { return 0; } +static void null_hpt_init(unsigned int count) +{ + /* nothing */ +} + + /* * Timer ack for an R4k-compatible timer of a known frequency. */ @@ -111,20 +123,191 @@ static void c0_timer_ack(void) /* * High precision timer functions for a R4k-compatible timer. */ -static cycle_t c0_hpt_read(void) +static unsigned int c0_hpt_read(void) { return read_c0_count(); } +/* For use solely as a high precision timer. */ +static void c0_hpt_init(unsigned int count) +{ + write_c0_count(read_c0_count() - count); +} + /* For use both as a high precision timer and an interrupt source. */ -static void __init c0_hpt_timer_init(void) +static void c0_hpt_timer_init(unsigned int count) { - expirelo = read_c0_count() + cycles_per_jiffy; + count = read_c0_count() - count; + expirelo = (count / cycles_per_jiffy + 1) * cycles_per_jiffy; + write_c0_count(expirelo - cycles_per_jiffy); write_c0_compare(expirelo); + write_c0_count(count); } int (*mips_timer_state)(void); void (*mips_timer_ack)(void); +unsigned int (*mips_hpt_read)(void); +void (*mips_hpt_init)(unsigned int); + +/* + * Gettimeoffset routines. These routines returns the time duration + * since last timer interrupt in usecs. + * + * If the exact CPU counter frequency is known, use fixed_rate_gettimeoffset. + * Otherwise use calibrate_gettimeoffset() + * + * If the CPU does not have the counter register, you can either supply + * your own gettimeoffset() routine, or use null_gettimeoffset(), which + * gives the same resolution as HZ. + */ + +static unsigned long null_gettimeoffset(void) +{ + return 0; +} + + +/* The function pointer to one of the gettimeoffset funcs. */ +unsigned long (*do_gettimeoffset)(void) = null_gettimeoffset; + + +static unsigned long fixed_rate_gettimeoffset(void) +{ + u32 count; + unsigned long res; + + /* Get last timer tick in absolute kernel time */ + count = mips_hpt_read(); + + /* .. relative to previous jiffy (32 bits is enough) */ + count -= timerlo; + + __asm__("multu %1,%2" + : "=h" (res) + : "r" (count), "r" (sll32_usecs_per_cycle) + : "lo", GCC_REG_ACCUM); + + /* + * Due to possible jiffies inconsistencies, we need to check + * the result so that we'll get a timer that is monotonic. + */ + if (res >= USECS_PER_JIFFY) + res = USECS_PER_JIFFY - 1; + + return res; +} + + +/* + * Cached "1/(clocks per usec) * 2^32" value. + * It has to be recalculated once each jiffy. + */ +static unsigned long cached_quotient; + +/* Last jiffy when calibrate_divXX_gettimeoffset() was called. */ +static unsigned long last_jiffies; + +/* + * This is moved from dec/time.c:do_ioasic_gettimeoffset() by Maciej. + */ +static unsigned long calibrate_div32_gettimeoffset(void) +{ + u32 count; + unsigned long res, tmp; + unsigned long quotient; + + tmp = jiffies; + + quotient = cached_quotient; + + if (last_jiffies != tmp) { + last_jiffies = tmp; + if (last_jiffies != 0) { + unsigned long r0; + do_div64_32(r0, timerhi, timerlo, tmp); + do_div64_32(quotient, USECS_PER_JIFFY, + USECS_PER_JIFFY_FRAC, r0); + cached_quotient = quotient; + } + } + + /* Get last timer tick in absolute kernel time */ + count = mips_hpt_read(); + + /* .. relative to previous jiffy (32 bits is enough) */ + count -= timerlo; + + __asm__("multu %1,%2" + : "=h" (res) + : "r" (count), "r" (quotient) + : "lo", GCC_REG_ACCUM); + + /* + * Due to possible jiffies inconsistencies, we need to check + * the result so that we'll get a timer that is monotonic. + */ + if (res >= USECS_PER_JIFFY) + res = USECS_PER_JIFFY - 1; + + return res; +} + +static unsigned long calibrate_div64_gettimeoffset(void) +{ + u32 count; + unsigned long res, tmp; + unsigned long quotient; + + tmp = jiffies; + + quotient = cached_quotient; + + if (last_jiffies != tmp) { + last_jiffies = tmp; + if (last_jiffies) { + unsigned long r0; + __asm__(".set push\n\t" + ".set mips3\n\t" + "lwu %0,%3\n\t" + "dsll32 %1,%2,0\n\t" + "or %1,%1,%0\n\t" + "ddivu $0,%1,%4\n\t" + "mflo %1\n\t" + "dsll32 %0,%5,0\n\t" + "or %0,%0,%6\n\t" + "ddivu $0,%0,%1\n\t" + "mflo %0\n\t" + ".set pop" + : "=&r" (quotient), "=&r" (r0) + : "r" (timerhi), "m" (timerlo), + "r" (tmp), "r" (USECS_PER_JIFFY), + "r" (USECS_PER_JIFFY_FRAC) + : "hi", "lo", GCC_REG_ACCUM); + cached_quotient = quotient; + } + } + + /* Get last timer tick in absolute kernel time */ + count = mips_hpt_read(); + + /* .. relative to previous jiffy (32 bits is enough) */ + count -= timerlo; + + __asm__("multu %1,%2" + : "=h" (res) + : "r" (count), "r" (quotient) + : "lo", GCC_REG_ACCUM); + + /* + * Due to possible jiffies inconsistencies, we need to check + * the result so that we'll get a timer that is monotonic. + */ + if (res >= USECS_PER_JIFFY) + res = USECS_PER_JIFFY - 1; + + return res; +} + /* last time when xtime and rtc are sync'ed up */ static long last_rtc_update; @@ -139,22 +322,31 @@ static long last_rtc_update; * a broadcasted inter-processor interrupt which itself is triggered * by the global timer interrupt. */ -void local_timer_interrupt(int irq, void *dev_id) +void local_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - profile_tick(CPU_PROFILING); - update_process_times(user_mode(get_irq_regs())); + if (current->pid) + profile_tick(CPU_PROFILING, regs); + update_process_times(user_mode(regs)); } /* * High-level timer interrupt service routines. This function * is set as irqaction->handler and is invoked through do_IRQ. */ -irqreturn_t timer_interrupt(int irq, void *dev_id) +irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { + unsigned long j; + unsigned int count; + write_seqlock(&xtime_lock); + count = mips_hpt_read(); mips_timer_ack(); + /* Update timerhi/timerlo for intra-jiffy calibration. */ + timerhi += count < timerlo; /* Wrap around */ + timerlo = count; + /* * call the generic timer interrupt handling */ @@ -177,6 +369,47 @@ irqreturn_t timer_interrupt(int irq, void *dev_id) } } + /* + * If jiffies has overflown in this timer_interrupt, we must + * update the timer[hi]/[lo] to make fast gettimeoffset funcs + * quotient calc still valid. -arca + * + * The first timer interrupt comes late as interrupts are + * enabled long after timers are initialized. Therefore the + * high precision timer is fast, leading to wrong gettimeoffset() + * calculations. We deal with it by setting it based on the + * number of its ticks between the second and the third interrupt. + * That is still somewhat imprecise, but it's a good estimate. + * --macro + */ + j = jiffies; + if (j < 4) { + static unsigned int prev_count; + static int hpt_initialized; + + switch (j) { + case 0: + timerhi = timerlo = 0; + mips_hpt_init(count); + break; + case 2: + prev_count = count; + break; + case 3: + if (!hpt_initialized) { + unsigned int c3 = 3 * (count - prev_count); + + timerhi = 0; + timerlo = c3; + mips_hpt_init(count - c3); + hpt_initialized = 1; + } + break; + default: + break; + } + } + write_sequnlock(&xtime_lock); /* @@ -186,22 +419,22 @@ irqreturn_t timer_interrupt(int irq, void *dev_id) * In SMP mode, local_timer_interrupt() is invoked by appropriate * low-level local timer interrupt handler. */ - local_timer_interrupt(irq, dev_id); + local_timer_interrupt(irq, dev_id, regs); return IRQ_HANDLED; } -int null_perf_irq(void) +int null_perf_irq(struct pt_regs *regs) { return 0; } -int (*perf_irq)(void) = null_perf_irq; +int (*perf_irq)(struct pt_regs *regs) = null_perf_irq; EXPORT_SYMBOL(null_perf_irq); EXPORT_SYMBOL(perf_irq); -asmlinkage void ll_timer_interrupt(int irq) +asmlinkage void ll_timer_interrupt(int irq, struct pt_regs *regs) { int r2 = cpu_has_mips_r2; @@ -215,25 +448,25 @@ asmlinkage void ll_timer_interrupt(int irq) * performance counter interrupt handler anyway. */ if (!r2 || (read_c0_cause() & (1 << 26))) - if (perf_irq()) + if (perf_irq(regs)) goto out; /* we keep interrupt disabled all the time */ if (!r2 || (read_c0_cause() & (1 << 30))) - timer_interrupt(irq, NULL); + timer_interrupt(irq, NULL, regs); out: irq_exit(); } -asmlinkage void ll_local_timer_interrupt(int irq) +asmlinkage void ll_local_timer_interrupt(int irq, struct pt_regs *regs) { irq_enter(); if (smp_processor_id() != 0) kstat_this_cpu.irqs[irq]++; /* we keep interrupt disabled all the time */ - local_timer_interrupt(irq, NULL); + local_timer_interrupt(irq, NULL, regs); irq_exit(); } @@ -244,11 +477,12 @@ asmlinkage void ll_local_timer_interrupt(int irq) * 1) board_time_init() - * a) (optional) set up RTC routines, * b) (optional) calibrate and set the mips_hpt_frequency - * (only needed if you intended to use cpu counter as timer interrupt - * source) + * (only needed if you intended to use fixed_rate_gettimeoffset + * or use cpu counter as timer interrupt source) * 2) setup xtime based on rtc_mips_get_time(). - * 3) calculate a couple of cached variables for later usage - * 4) plat_timer_setup() - + * 3) choose a appropriate gettimeoffset routine. + * 4) calculate a couple of cached variables for later usage + * 5) plat_timer_setup() - * a) (optional) over-write any choices made above by time_init(). * b) machine specific code should setup the timer irqaction. * c) enable the timer interrupt @@ -266,7 +500,8 @@ static struct irqaction timer_irqaction = { static unsigned int __init calibrate_hpt(void) { - cycle_t frequency, hpt_start, hpt_end, hpt_count, hz; + u64 frequency; + u32 hpt_start, hpt_end, hpt_count, hz; const int loops = HZ / 10; int log_2_loops = 0; @@ -292,49 +527,20 @@ static unsigned int __init calibrate_hpt(void) * during the calculated number of periods between timer * interrupts. */ - hpt_start = clocksource_mips.read(); + hpt_start = mips_hpt_read(); do { while (mips_timer_state()); while (!mips_timer_state()); } while (--i); - hpt_end = clocksource_mips.read(); + hpt_end = mips_hpt_read(); - hpt_count = (hpt_end - hpt_start) & clocksource_mips.mask; + hpt_count = hpt_end - hpt_start; hz = HZ; - frequency = hpt_count * hz; + frequency = (u64)hpt_count * (u64)hz; return frequency >> log_2_loops; } -struct clocksource clocksource_mips = { - .name = "MIPS", - .mask = 0xffffffff, - .is_continuous = 1, -}; - -static void __init init_mips_clocksource(void) -{ - u64 temp; - u32 shift; - - if (!mips_hpt_frequency || clocksource_mips.read == null_hpt_read) - return; - - /* Calclate a somewhat reasonable rating value */ - clocksource_mips.rating = 200 + mips_hpt_frequency / 10000000; - /* Find a shift value */ - for (shift = 32; shift > 0; shift--) { - temp = (u64) NSEC_PER_SEC << shift; - do_div(temp, mips_hpt_frequency); - if ((temp >> 32) == 0) - break; - } - clocksource_mips.shift = shift; - clocksource_mips.mult = (u32)temp; - - clocksource_register(&clocksource_mips); -} - void __init time_init(void) { if (board_time_init) @@ -350,36 +556,59 @@ void __init time_init(void) -xtime.tv_sec, -xtime.tv_nsec); /* Choose appropriate high precision timer routines. */ - if (!cpu_has_counter && !clocksource_mips.read) + if (!cpu_has_counter && !mips_hpt_read) { /* No high precision timer -- sorry. */ - clocksource_mips.read = null_hpt_read; - else if (!mips_hpt_frequency && !mips_timer_state) { + mips_hpt_read = null_hpt_read; + mips_hpt_init = null_hpt_init; + } else if (!mips_hpt_frequency && !mips_timer_state) { /* A high precision timer of unknown frequency. */ - if (!clocksource_mips.read) + if (!mips_hpt_read) { /* No external high precision timer -- use R4k. */ - clocksource_mips.read = c0_hpt_read; + mips_hpt_read = c0_hpt_read; + mips_hpt_init = c0_hpt_init; + } + + if (cpu_has_mips32r1 || cpu_has_mips32r2 || + (current_cpu_data.isa_level == MIPS_CPU_ISA_I) || + (current_cpu_data.isa_level == MIPS_CPU_ISA_II)) + /* + * We need to calibrate the counter but we don't have + * 64-bit division. + */ + do_gettimeoffset = calibrate_div32_gettimeoffset; + else + /* + * We need to calibrate the counter but we *do* have + * 64-bit division. + */ + do_gettimeoffset = calibrate_div64_gettimeoffset; } else { /* We know counter frequency. Or we can get it. */ - if (!clocksource_mips.read) { + if (!mips_hpt_read) { /* No external high precision timer -- use R4k. */ - clocksource_mips.read = c0_hpt_read; + mips_hpt_read = c0_hpt_read; - if (!mips_timer_state) { + if (mips_timer_state) + mips_hpt_init = c0_hpt_init; + else { /* No external timer interrupt -- use R4k. */ + mips_hpt_init = c0_hpt_timer_init; mips_timer_ack = c0_timer_ack; - /* Calculate cache parameters. */ - cycles_per_jiffy = - (mips_hpt_frequency + HZ / 2) / HZ; - /* - * This sets up the high precision - * timer for the first interrupt. - */ - c0_hpt_timer_init(); } } if (!mips_hpt_frequency) mips_hpt_frequency = calibrate_hpt(); + do_gettimeoffset = fixed_rate_gettimeoffset; + + /* Calculate cache parameters. */ + cycles_per_jiffy = (mips_hpt_frequency + HZ / 2) / HZ; + + /* sll32_usecs_per_cycle = 10^6 * 2^32 / mips_counter_freq */ + do_div64_32(sll32_usecs_per_cycle, + 1000000, mips_hpt_frequency / 2, + mips_hpt_frequency); + /* Report the high precision timer rate for a reference. */ printk("Using %u.%03u MHz high precision timer.\n", ((mips_hpt_frequency + 500) / 1000) / 1000, @@ -390,6 +619,9 @@ void __init time_init(void) /* No timer interrupt ack (e.g. i8254). */ mips_timer_ack = null_timer_ack; + /* This sets up the high precision timer for the first interrupt. */ + mips_hpt_init(mips_hpt_read()); + /* * Call board specific timer interrupt setup. * @@ -402,8 +634,6 @@ void __init time_init(void) * is not invoked accidentally. */ plat_timer_setup(&timer_irqaction); - - init_mips_clocksource(); } #define FEBRUARY 2 diff --git a/trunk/arch/mips/kernel/topology.c b/trunk/arch/mips/kernel/topology.c deleted file mode 100644 index 660e44ed44d7..000000000000 --- a/trunk/arch/mips/kernel/topology.c +++ /dev/null @@ -1,29 +0,0 @@ -#include -#include -#include -#include -#include -#include - -static DEFINE_PER_CPU(struct cpu, cpu_devices); - -static int __init topology_init(void) -{ - int i, ret; - -#ifdef CONFIG_NUMA - for_each_online_node(i) - register_one_node(i); -#endif /* CONFIG_NUMA */ - - for_each_present_cpu(i) { - ret = register_cpu(&per_cpu(cpu_devices, i), i); - if (ret) - printk(KERN_WARNING "topology_init: register_cpu %d " - "failed (%d)\n", i, ret); - } - - return 0; -} - -subsys_initcall(topology_init); diff --git a/trunk/arch/mips/kernel/traps.c b/trunk/arch/mips/kernel/traps.c index 2a932cada244..b7292a56d4cd 100644 --- a/trunk/arch/mips/kernel/traps.c +++ b/trunk/arch/mips/kernel/traps.c @@ -54,8 +54,6 @@ extern asmlinkage void handle_dbe(void); extern asmlinkage void handle_sys(void); extern asmlinkage void handle_bp(void); extern asmlinkage void handle_ri(void); -extern asmlinkage void handle_ri_rdhwr_vivt(void); -extern asmlinkage void handle_ri_rdhwr(void); extern asmlinkage void handle_cpu(void); extern asmlinkage void handle_ov(void); extern asmlinkage void handle_tr(void); @@ -68,7 +66,7 @@ extern asmlinkage void handle_mcheck(void); extern asmlinkage void handle_reserved(void); extern int fpu_emulator_cop1Handler(struct pt_regs *xcp, - struct mips_fpu_struct *ctx, int has_fpu); + struct mips_fpu_struct *ctx); void (*board_be_init)(void); int (*board_be_handler)(struct pt_regs *regs, int is_fixup); @@ -399,6 +397,19 @@ asmlinkage void do_be(struct pt_regs *regs) force_sig(SIGBUS, current); } +static inline int get_insn_opcode(struct pt_regs *regs, unsigned int *opcode) +{ + unsigned int __user *epc; + + epc = (unsigned int __user *) regs->cp0_epc + + ((regs->cp0_cause & CAUSEF_BD) != 0); + if (!get_user(*opcode, epc)) + return 0; + + force_sig(SIGSEGV, current); + return 1; +} + /* * ll/sc emulation */ @@ -533,8 +544,8 @@ static inline int simulate_llsc(struct pt_regs *regs) { unsigned int opcode; - if (get_user(opcode, (unsigned int __user *) exception_epc(regs))) - goto out_sigsegv; + if (unlikely(get_insn_opcode(regs, &opcode))) + return -EFAULT; if ((opcode & OPCODE) == LL) { simulate_ll(regs, opcode); @@ -546,10 +557,6 @@ static inline int simulate_llsc(struct pt_regs *regs) } return -EFAULT; /* Strange things going on ... */ - -out_sigsegv: - force_sig(SIGSEGV, current); - return -EFAULT; } /* @@ -562,8 +569,8 @@ static inline int simulate_rdhwr(struct pt_regs *regs) struct thread_info *ti = task_thread_info(current); unsigned int opcode; - if (get_user(opcode, (unsigned int __user *) exception_epc(regs))) - goto out_sigsegv; + if (unlikely(get_insn_opcode(regs, &opcode))) + return -EFAULT; if (unlikely(compute_return_epc(regs))) return -EFAULT; @@ -582,10 +589,6 @@ static inline int simulate_rdhwr(struct pt_regs *regs) /* Not ours. */ return -EFAULT; - -out_sigsegv: - force_sig(SIGSEGV, current); - return -EFAULT; } asmlinkage void do_ov(struct pt_regs *regs) @@ -638,7 +641,7 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31) preempt_enable(); /* Run the emulator */ - sig = fpu_emulator_cop1Handler (regs, ¤t->thread.fpu, 1); + sig = fpu_emulator_cop1Handler (regs, ¤t->thread.fpu); preempt_disable(); @@ -669,8 +672,10 @@ asmlinkage void do_bp(struct pt_regs *regs) unsigned int opcode, bcode; siginfo_t info; - if (get_user(opcode, (unsigned int __user *) exception_epc(regs))) - goto out_sigsegv; + die_if_kernel("Break instruction in kernel code", regs); + + if (get_insn_opcode(regs, &opcode)) + return; /* * There is the ancient bug in the MIPS assemblers that the break @@ -691,7 +696,6 @@ asmlinkage void do_bp(struct pt_regs *regs) switch (bcode) { case BRK_OVERFLOW << 10: case BRK_DIVZERO << 10: - die_if_kernel("Break instruction in kernel code", regs); if (bcode == (BRK_DIVZERO << 10)) info.si_code = FPE_INTDIV; else @@ -701,16 +705,9 @@ asmlinkage void do_bp(struct pt_regs *regs) info.si_addr = (void __user *) regs->cp0_epc; force_sig_info(SIGFPE, &info, current); break; - case BRK_BUG: - die("Kernel bug detected", regs); - break; default: - die_if_kernel("Break instruction in kernel code", regs); force_sig(SIGTRAP, current); } - -out_sigsegv: - force_sig(SIGSEGV, current); } asmlinkage void do_tr(struct pt_regs *regs) @@ -718,8 +715,10 @@ asmlinkage void do_tr(struct pt_regs *regs) unsigned int opcode, tcode = 0; siginfo_t info; - if (get_user(opcode, (unsigned int __user *) exception_epc(regs))) - goto out_sigsegv; + die_if_kernel("Trap instruction in kernel code", regs); + + if (get_insn_opcode(regs, &opcode)) + return; /* Immediate versions don't provide a code. */ if (!(opcode & OPCODE)) @@ -734,7 +733,6 @@ asmlinkage void do_tr(struct pt_regs *regs) switch (tcode) { case BRK_OVERFLOW: case BRK_DIVZERO: - die_if_kernel("Trap instruction in kernel code", regs); if (tcode == BRK_DIVZERO) info.si_code = FPE_INTDIV; else @@ -744,16 +742,9 @@ asmlinkage void do_tr(struct pt_regs *regs) info.si_addr = (void __user *) regs->cp0_epc; force_sig_info(SIGFPE, &info, current); break; - case BRK_BUG: - die("Kernel bug detected", regs); - break; default: - die_if_kernel("Trap instruction in kernel code", regs); force_sig(SIGTRAP, current); } - -out_sigsegv: - force_sig(SIGSEGV, current); } asmlinkage void do_ri(struct pt_regs *regs) @@ -800,13 +791,11 @@ asmlinkage void do_cpu(struct pt_regs *regs) set_used_math(); } - if (cpu_has_fpu) { - preempt_enable(); - } else { - int sig; - preempt_enable(); - sig = fpu_emulator_cop1Handler(regs, - ¤t->thread.fpu, 0); + preempt_enable(); + + if (!cpu_has_fpu) { + int sig = fpu_emulator_cop1Handler(regs, + ¤t->thread.fpu); if (sig) force_sig(sig, current); #ifdef CONFIG_MIPS_MT_FPAFF @@ -1120,7 +1109,7 @@ static struct shadow_registers { static void mips_srs_init(void) { shadow_registers.sr_supported = ((read_c0_srsctl() >> 26) & 0x0f) + 1; - printk(KERN_INFO "%ld MIPSR2 register sets available\n", + printk(KERN_INFO "%d MIPSR2 register sets available\n", shadow_registers.sr_supported); shadow_registers.sr_allocated = 1; /* Set 0 used by kernel */ } @@ -1432,15 +1421,6 @@ void __init set_uncached_handler (unsigned long offset, void *addr, unsigned lon memcpy((void *)(uncached_ebase + offset), addr, size); } -static int __initdata rdhwr_noopt; -static int __init set_rdhwr_noopt(char *str) -{ - rdhwr_noopt = 1; - return 1; -} - -__setup("rdhwr_noopt", set_rdhwr_noopt); - void __init trap_init(void) { extern char except_vec3_generic, except_vec3_r4000; @@ -1520,9 +1500,7 @@ void __init trap_init(void) set_except_vector(8, handle_sys); set_except_vector(9, handle_bp); - set_except_vector(10, rdhwr_noopt ? handle_ri : - (cpu_has_vtag_icache ? - handle_ri_rdhwr_vivt : handle_ri_rdhwr)); + set_except_vector(10, handle_ri); set_except_vector(11, handle_cpu); set_except_vector(12, handle_ov); set_except_vector(13, handle_tr); diff --git a/trunk/arch/mips/kernel/vmlinux.lds.S b/trunk/arch/mips/kernel/vmlinux.lds.S index 79f0317d84ac..0bb9cd889456 100644 --- a/trunk/arch/mips/kernel/vmlinux.lds.S +++ b/trunk/arch/mips/kernel/vmlinux.lds.S @@ -50,16 +50,6 @@ SECTIONS /* writeable */ .data : { /* Data */ . = . + DATAOFFSET; /* for CONFIG_MAPPED_KERNEL */ - /* - * This ALIGN is needed as a workaround for a bug a gcc bug upto 4.1 which - * limits the maximum alignment to at most 32kB and results in the following - * warning: - * - * CC arch/mips/kernel/init_task.o - * arch/mips/kernel/init_task.c:30: warning: alignment of ‘init_thread_union’ - * is greater than maximum object file alignment. Using 32768 - */ - . = ALIGN(_PAGE_SIZE); *(.data.init_task) *(.data) @@ -101,7 +91,13 @@ SECTIONS __initcall_start = .; .initcall.init : { - INITCALLS + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) } __initcall_end = .; diff --git a/trunk/arch/mips/lasat/interrupt.c b/trunk/arch/mips/lasat/interrupt.c index 4a84a7beac53..456be8fc961a 100644 --- a/trunk/arch/mips/lasat/interrupt.c +++ b/trunk/arch/mips/lasat/interrupt.c @@ -36,14 +36,33 @@ static volatile int lasat_int_mask_shift; void disable_lasat_irq(unsigned int irq_nr) { + unsigned long flags; + + local_irq_save(flags); *lasat_int_mask &= ~(1 << irq_nr) << lasat_int_mask_shift; + local_irq_restore(flags); } void enable_lasat_irq(unsigned int irq_nr) { + unsigned long flags; + + local_irq_save(flags); *lasat_int_mask |= (1 << irq_nr) << lasat_int_mask_shift; + local_irq_restore(flags); } +static unsigned int startup_lasat_irq(unsigned int irq) +{ + enable_lasat_irq(irq); + + return 0; /* never anything pending */ +} + +#define shutdown_lasat_irq disable_lasat_irq + +#define mask_and_ack_lasat_irq disable_lasat_irq + static void end_lasat_irq(unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) @@ -52,10 +71,11 @@ static void end_lasat_irq(unsigned int irq) static struct irq_chip lasat_irq_type = { .typename = "Lasat", - .ack = disable_lasat_irq, - .mask = disable_lasat_irq, - .mask_ack = disable_lasat_irq, - .unmask = enable_lasat_irq, + .startup = startup_lasat_irq, + .shutdown = shutdown_lasat_irq, + .enable = enable_lasat_irq, + .disable = disable_lasat_irq, + .ack = mask_and_ack_lasat_irq, .end = end_lasat_irq, }; @@ -88,14 +108,14 @@ static unsigned long get_int_status_200(void) return int_status; } -asmlinkage void plat_irq_dispatch(void) +asmlinkage void plat_irq_dispatch(struct pt_regs *regs) { unsigned long int_status; unsigned int cause = read_c0_cause(); int irq; if (cause & CAUSEF_IP7) { /* R4000 count / compare IRQ */ - ll_timer_interrupt(7); + ll_timer_interrupt(7, regs); return; } @@ -105,7 +125,7 @@ asmlinkage void plat_irq_dispatch(void) if (int_status) { irq = ls1bit32(int_status); - do_IRQ(irq); + do_IRQ(irq, regs); } } @@ -132,6 +152,10 @@ void __init arch_init_irq(void) panic("arch_init_irq: mips_machtype incorrect"); } - for (i = 0; i <= LASATINT_END; i++) - set_irq_chip_and_handler(i, &lasat_irq_type, handle_level_irq); + for (i = 0; i <= LASATINT_END; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 1; + irq_desc[i].chip = &lasat_irq_type; + } } diff --git a/trunk/arch/mips/lib-64/dump_tlb.c b/trunk/arch/mips/lib-64/dump_tlb.c index 594df1a05ecc..be8261be679b 100644 --- a/trunk/arch/mips/lib-64/dump_tlb.c +++ b/trunk/arch/mips/lib-64/dump_tlb.c @@ -149,7 +149,7 @@ void dump_list_process(struct task_struct *t, void *address) printk("Addr == %08lx\n", addr); printk("tasks->mm.pgd == %08lx\n", (unsigned long) t->mm->pgd); - page_dir = pgd_offset(t->mm, 0UL); + page_dir = pgd_offset(t->mm, 0); printk("page_dir == %016lx\n", (unsigned long) page_dir); pgd = pgd_offset(t->mm, addr); @@ -184,13 +184,13 @@ void dump_list_current(void *address) dump_list_process(current, address); } -unsigned long vtop(void *address) +unsigned int vtop(void *address) { pgd_t *pgd; pud_t *pud; pmd_t *pmd; pte_t *pte; - unsigned long addr, paddr; + unsigned int addr, paddr; addr = (unsigned long) address; pgd = pgd_offset(current->mm, addr); diff --git a/trunk/arch/mips/math-emu/cp1emu.c b/trunk/arch/mips/math-emu/cp1emu.c index 80531b35cd61..3f0d5d26d506 100644 --- a/trunk/arch/mips/math-emu/cp1emu.c +++ b/trunk/arch/mips/math-emu/cp1emu.c @@ -38,6 +38,8 @@ #include #include +#include +#include #include #include #include @@ -1231,8 +1233,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, return 0; } -int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx, - int has_fpu) +int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx) { unsigned long oldepc, prevepc; mips_instruction insn; @@ -1262,7 +1263,7 @@ int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx, ieee754_csr.rm = mips_rm[ieee754_csr.rm]; } - if (has_fpu) + if (cpu_has_fpu) break; if (sig) break; diff --git a/trunk/arch/mips/mips-boards/atlas/atlas_int.c b/trunk/arch/mips/mips-boards/atlas/atlas_int.c index 43dba6ce6603..a020a3cb4f4b 100644 --- a/trunk/arch/mips/mips-boards/atlas/atlas_int.c +++ b/trunk/arch/mips/mips-boards/atlas/atlas_int.c @@ -62,6 +62,16 @@ void enable_atlas_irq(unsigned int irq_nr) iob(); } +static unsigned int startup_atlas_irq(unsigned int irq) +{ + enable_atlas_irq(irq); + return 0; /* never anything pending */ +} + +#define shutdown_atlas_irq disable_atlas_irq + +#define mask_and_ack_atlas_irq disable_atlas_irq + static void end_atlas_irq(unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) @@ -70,11 +80,11 @@ static void end_atlas_irq(unsigned int irq) static struct irq_chip atlas_irq_type = { .typename = "Atlas", - .ack = disable_atlas_irq, - .mask = disable_atlas_irq, - .mask_ack = disable_atlas_irq, - .unmask = enable_atlas_irq, - .eoi = enable_atlas_irq, + .startup = startup_atlas_irq, + .shutdown = shutdown_atlas_irq, + .enable = enable_atlas_irq, + .disable = disable_atlas_irq, + .ack = mask_and_ack_atlas_irq, .end = end_atlas_irq, }; @@ -91,7 +101,7 @@ static inline int ls1bit32(unsigned int x) return b; } -static inline void atlas_hw0_irqdispatch(void) +static inline void atlas_hw0_irqdispatch(struct pt_regs *regs) { unsigned long int_status; int irq; @@ -106,7 +116,7 @@ static inline void atlas_hw0_irqdispatch(void) DEBUG_INT("atlas_hw0_irqdispatch: irq=%d\n", irq); - do_IRQ(irq); + do_IRQ(irq, regs); } static inline int clz(unsigned long x) @@ -178,7 +188,7 @@ static inline unsigned int irq_ffs(unsigned int pending) * then we just return, if multiple IRQs are pending then we will just take * another exception, big deal. */ -asmlinkage void plat_irq_dispatch(void) +asmlinkage void plat_irq_dispatch(struct pt_regs *regs) { unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; int irq; @@ -186,11 +196,11 @@ asmlinkage void plat_irq_dispatch(void) irq = irq_ffs(pending); if (irq == MIPSCPU_INT_ATLAS) - atlas_hw0_irqdispatch(); + atlas_hw0_irqdispatch(regs); else if (irq >= 0) - do_IRQ(MIPSCPU_INT_BASE + irq); + do_IRQ(MIPSCPU_INT_BASE + irq, regs); else - spurious_interrupt(); + spurious_interrupt(regs); } static inline void init_atlas_irqs (int base) @@ -207,8 +217,13 @@ static inline void init_atlas_irqs (int base) */ atlas_hw0_icregs->intrsten = 0xffffffff; - for (i = ATLAS_INT_BASE; i <= ATLAS_INT_END; i++) - set_irq_chip_and_handler(i, &atlas_irq_type, handle_level_irq); + for (i = ATLAS_INT_BASE; i <= ATLAS_INT_END; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 1; + irq_desc[i].chip = &atlas_irq_type; + spin_lock_init(&irq_desc[i].lock); + } } static struct irqaction atlasirq = { diff --git a/trunk/arch/mips/mips-boards/generic/memory.c b/trunk/arch/mips/mips-boards/generic/memory.c index eeed944e0f83..be80c5dd4a0c 100644 --- a/trunk/arch/mips/mips-boards/generic/memory.c +++ b/trunk/arch/mips/mips-boards/generic/memory.c @@ -176,7 +176,7 @@ unsigned long __init prom_free_prom_memory(void) if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA) continue; - addr = PAGE_ALIGN(boot_mem_map.map[i].addr); + addr = boot_mem_map.map[i].addr; while (addr < boot_mem_map.map[i].addr + boot_mem_map.map[i].size) { ClearPageReserved(virt_to_page(__va(addr))); diff --git a/trunk/arch/mips/mips-boards/generic/pci.c b/trunk/arch/mips/mips-boards/generic/pci.c index 3192a14698c8..9337f6c8873a 100644 --- a/trunk/arch/mips/mips-boards/generic/pci.c +++ b/trunk/arch/mips/mips-boards/generic/pci.c @@ -90,7 +90,7 @@ static struct pci_controller msc_controller = { void __init mips_pcibios_init(void) { struct pci_controller *controller; - resource_size_t start, end, map, start1, end1, map1, map2, map3, mask; + unsigned long start, end, map, start1, end1, map1, map2, map3, mask; switch (mips_revision_corid) { case MIPS_REVISION_CORID_QED_RM5261: diff --git a/trunk/arch/mips/mips-boards/generic/time.c b/trunk/arch/mips/mips-boards/generic/time.c index e4604c73f02e..8d15861fce61 100644 --- a/trunk/arch/mips/mips-boards/generic/time.c +++ b/trunk/arch/mips/mips-boards/generic/time.c @@ -30,6 +30,7 @@ #include #include +#include #include #include #include @@ -81,19 +82,19 @@ static inline void scroll_display_message(void) } } -static void mips_timer_dispatch(void) +static void mips_timer_dispatch (struct pt_regs *regs) { - do_IRQ(mips_cpu_timer_irq); + do_IRQ (mips_cpu_timer_irq, regs); } /* * Redeclare until I get around mopping the timer code insanity on MIPS. */ -extern int null_perf_irq(void); +extern int null_perf_irq(struct pt_regs *regs); -extern int (*perf_irq)(void); +extern int (*perf_irq)(struct pt_regs *regs); -irqreturn_t mips_timer_interrupt(int irq, void *dev_id) +irqreturn_t mips_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { int cpu = smp_processor_id(); @@ -118,7 +119,7 @@ irqreturn_t mips_timer_interrupt(int irq, void *dev_id) * perf counter overflow, or both. */ if (read_c0_cause() & (1 << 26)) - perf_irq(); + perf_irq(regs); if (read_c0_cause() & (1 << 30)) { /* If timer interrupt, make it de-assert */ @@ -138,13 +139,13 @@ irqreturn_t mips_timer_interrupt(int irq, void *dev_id) * the tick on VPE 0 to run the full timer_interrupt(). */ if (cpu_data[cpu].vpe_id == 0) { - timer_interrupt(irq, NULL); + timer_interrupt(irq, NULL, regs); smtc_timer_broadcast(cpu_data[cpu].vpe_id); scroll_display_message(); } else { write_c0_compare(read_c0_count() + (mips_hpt_frequency/HZ)); - local_timer_interrupt(irq, dev_id); + local_timer_interrupt(irq, dev_id, regs); smtc_timer_broadcast(cpu_data[cpu].vpe_id); } } @@ -158,12 +159,12 @@ irqreturn_t mips_timer_interrupt(int irq, void *dev_id) * timer int. */ if (!r2 || (read_c0_cause() & (1 << 26))) - if (perf_irq()) + if (perf_irq(regs)) goto out; /* we keep interrupt disabled all the time */ if (!r2 || (read_c0_cause() & (1 << 30))) - timer_interrupt(irq, NULL); + timer_interrupt(irq, NULL, regs); scroll_display_message(); } else { @@ -179,7 +180,7 @@ irqreturn_t mips_timer_interrupt(int irq, void *dev_id) /* * Other CPUs should do profiling and process accounting */ - local_timer_interrupt(irq, dev_id); + local_timer_interrupt(irq, dev_id, regs); } out: #endif /* CONFIG_MIPS_MT_SMTC */ @@ -187,7 +188,7 @@ irqreturn_t mips_timer_interrupt(int irq, void *dev_id) } /* - * Estimate CPU frequency. Sets mips_hpt_frequency as a side-effect + * Estimate CPU frequency. Sets mips_counter_frequency as a side-effect */ static unsigned int __init estimate_cpu_frequency(void) { @@ -208,8 +209,7 @@ static unsigned int __init estimate_cpu_frequency(void) count = 6000000; #endif #if defined(CONFIG_MIPS_ATLAS) || defined(CONFIG_MIPS_MALTA) - unsigned long flags; - unsigned int start; + unsigned int flags; local_irq_save(flags); @@ -218,13 +218,13 @@ static unsigned int __init estimate_cpu_frequency(void) while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); /* Start r4k counter. */ - start = read_c0_count(); + write_c0_count(0); /* Read counter exactly on falling edge of update flag */ while (CMOS_READ(RTC_REG_A) & RTC_UIP); while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); - count = read_c0_count() - start; + count = read_c0_count(); /* restore interrupts */ local_irq_restore(flags); @@ -288,7 +288,6 @@ void __init plat_timer_setup(struct irqaction *irq) The effect is that the int remains disabled on the second cpu. Mark the interrupt with IRQ_PER_CPU to avoid any confusion */ irq_desc[mips_cpu_timer_irq].status |= IRQ_PER_CPU; - set_irq_handler(mips_cpu_timer_irq, handle_percpu_irq); #endif /* to generate the first timer interrupt */ diff --git a/trunk/arch/mips/mips-boards/malta/malta_int.c b/trunk/arch/mips/mips-boards/malta/malta_int.c index 90ad5bf3e2f1..7cc0ba4f553a 100644 --- a/trunk/arch/mips/mips-boards/malta/malta_int.c +++ b/trunk/arch/mips/mips-boards/malta/malta_int.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include @@ -115,7 +114,7 @@ static inline int get_int(void) return irq; } -static void malta_hw0_irqdispatch(void) +static void malta_hw0_irqdispatch(struct pt_regs *regs) { int irq; @@ -124,21 +123,17 @@ static void malta_hw0_irqdispatch(void) return; /* interrupt has already been cleared */ } - do_IRQ(MALTA_INT_BASE + irq); + do_IRQ(MALTA_INT_BASE+irq, regs); } -static void corehi_irqdispatch(void) +void corehi_irqdispatch(struct pt_regs *regs) { - unsigned int intedge, intsteer, pcicmd, pcibadaddr; - unsigned int pcimstat, intisr, inten, intpol; unsigned int intrcause,datalo,datahi; - struct pt_regs *regs = get_irq_regs(); + unsigned int pcimstat, intisr, inten, intpol, intedge, intsteer, pcicmd, pcibadaddr; printk("CoreHI interrupt, shouldn't happen, so we die here!!!\n"); - printk("epc : %08lx\nStatus: %08lx\n" - "Cause : %08lx\nbadVaddr : %08lx\n", - regs->cp0_epc, regs->cp0_status, - regs->cp0_cause, regs->cp0_badvaddr); + printk("epc : %08lx\nStatus: %08lx\nCause : %08lx\nbadVaddr : %08lx\n" +, regs->cp0_epc, regs->cp0_status, regs->cp0_cause, regs->cp0_badvaddr); /* Read all the registers and then print them as there is a problem with interspersed printk's upsetting the Bonito controller. @@ -151,7 +146,7 @@ static void corehi_irqdispatch(void) case MIPS_REVISION_CORID_CORE_FPGA3: case MIPS_REVISION_CORID_CORE_24K: case MIPS_REVISION_CORID_CORE_EMUL_MSC: - ll_msc_irq(); + ll_msc_irq(regs); break; case MIPS_REVISION_CORID_QED_RM5261: case MIPS_REVISION_CORID_CORE_LV: @@ -213,23 +208,23 @@ static inline unsigned int irq_ffs(unsigned int pending) unsigned int a0 = 7; unsigned int t0; - t0 = pending & 0xf000; + t0 = s0 & 0xf000; t0 = t0 < 1; t0 = t0 << 2; a0 = a0 - t0; - pending = pending << t0; + s0 = s0 << t0; - t0 = pending & 0xc000; + t0 = s0 & 0xc000; t0 = t0 < 1; t0 = t0 << 1; a0 = a0 - t0; - pending = pending << t0; + s0 = s0 << t0; - t0 = pending & 0x8000; + t0 = s0 & 0x8000; t0 = t0 < 1; //t0 = t0 << 2; a0 = a0 - t0; - //pending = pending << t0; + //s0 = s0 << t0; return a0; #endif @@ -260,7 +255,7 @@ static inline unsigned int irq_ffs(unsigned int pending) * another exception, big deal. */ -asmlinkage void plat_irq_dispatch(void) +asmlinkage void plat_irq_dispatch(struct pt_regs *regs) { unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; int irq; @@ -268,11 +263,11 @@ asmlinkage void plat_irq_dispatch(void) irq = irq_ffs(pending); if (irq == MIPSCPU_INT_I8259A) - malta_hw0_irqdispatch(); + malta_hw0_irqdispatch(regs); else if (irq > 0) - do_IRQ(MIPSCPU_INT_BASE + irq); + do_IRQ(MIPSCPU_INT_BASE + irq, regs); else - spurious_interrupt(); + spurious_interrupt(regs); } static struct irqaction i8259irq = { diff --git a/trunk/arch/mips/mips-boards/malta/malta_setup.c b/trunk/arch/mips/mips-boards/malta/malta_setup.c index 282f3e52eea3..ab460f805bef 100644 --- a/trunk/arch/mips/mips-boards/malta/malta_setup.c +++ b/trunk/arch/mips/mips-boards/malta/malta_setup.c @@ -159,7 +159,7 @@ void __init plat_mem_setup(void) BONITO_PCIMEMBASECFG |= (BONITO_PCIMEMBASECFG_MEMBASE0_CACHED | BONITO_PCIMEMBASECFG_MEMBASE1_CACHED); - printk("Enabled Bonito IOBC coherency\n"); + printk("Disabled Bonito IOBC coherency\n"); } } else diff --git a/trunk/arch/mips/mips-boards/sead/sead_int.c b/trunk/arch/mips/mips-boards/sead/sead_int.c index f445fcddfdfd..9168d934c661 100644 --- a/trunk/arch/mips/mips-boards/sead/sead_int.c +++ b/trunk/arch/mips/mips-boards/sead/sead_int.c @@ -98,7 +98,7 @@ static inline unsigned int irq_ffs(unsigned int pending) * then we just return, if multiple IRQs are pending then we will just take * another exception, big deal. */ -asmlinkage void plat_irq_dispatch(void) +asmlinkage void plat_irq_dispatch(struct pt_regs *regs) { unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; int irq; @@ -106,7 +106,7 @@ asmlinkage void plat_irq_dispatch(void) irq = irq_ffs(pending); if (irq >= 0) - do_IRQ(MIPSCPU_INT_BASE + irq); + do_IRQ(MIPSCPU_INT_BASE + irq, regs); else spurious_interrupt(regs); } diff --git a/trunk/arch/mips/mips-boards/sim/sim_int.c b/trunk/arch/mips/mips-boards/sim/sim_int.c index 2ce449dce6f2..2c15c8efec4e 100644 --- a/trunk/arch/mips/mips-boards/sim/sim_int.c +++ b/trunk/arch/mips/mips-boards/sim/sim_int.c @@ -71,7 +71,12 @@ static inline unsigned int irq_ffs(unsigned int pending) #endif } -asmlinkage void plat_irq_dispatch(void) +static inline void sim_hw0_irqdispatch(struct pt_regs *regs) +{ + do_IRQ(2, regs); +} + +asmlinkage void plat_irq_dispatch(struct pt_regs *regs) { unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; int irq; @@ -79,9 +84,9 @@ asmlinkage void plat_irq_dispatch(void) irq = irq_ffs(pending); if (irq > 0) - do_IRQ(MIPSCPU_INT_BASE + irq); + do_IRQ(MIPSCPU_INT_BASE + irq, regs); else - spurious_interrupt(); + spurious_interrupt(regs); } void __init arch_init_irq(void) diff --git a/trunk/arch/mips/mips-boards/sim/sim_time.c b/trunk/arch/mips/mips-boards/sim/sim_time.c index 30711d016fed..230929ecd57f 100644 --- a/trunk/arch/mips/mips-boards/sim/sim_time.c +++ b/trunk/arch/mips/mips-boards/sim/sim_time.c @@ -3,29 +3,37 @@ #include #include #include + +#include +#include +#include +#include +#include +#include + #include #include #include - #include #include #include +#include #include #include #include -#include #include #include -#include #include #include #include +#include +#include unsigned long cpu_khz; -irqreturn_t sim_timer_interrupt(int irq, void *dev_id) +irqreturn_t sim_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { #ifdef CONFIG_SMP int cpu = smp_processor_id(); @@ -36,7 +44,7 @@ irqreturn_t sim_timer_interrupt(int irq, void *dev_id) */ #ifndef CONFIG_MIPS_MT_SMTC if (cpu == 0) { - timer_interrupt(irq, dev_id); + timer_interrupt(irq, dev_id, regs); } else { /* Everyone else needs to reset the timer int here as @@ -76,7 +84,7 @@ irqreturn_t sim_timer_interrupt(int irq, void *dev_id) irq_enable_hazard(); evpe(vpflags); - if(cpu_data[cpu].vpe_id == 0) timer_interrupt(irq, dev_id); + if(cpu_data[cpu].vpe_id == 0) timer_interrupt(irq, dev_id, regs); else write_c0_compare (read_c0_count() + ( mips_hpt_frequency/HZ)); smtc_timer_broadcast(cpu_data[cpu].vpe_id); @@ -85,17 +93,17 @@ irqreturn_t sim_timer_interrupt(int irq, void *dev_id) /* * every CPU should do profiling and process accounting */ - local_timer_interrupt (irq, dev_id); + local_timer_interrupt (irq, dev_id, regs); return IRQ_HANDLED; #else - return timer_interrupt (irq, dev_id); + return timer_interrupt (irq, dev_id, regs); #endif } /* - * Estimate CPU frequency. Sets mips_hpt_frequency as a side-effect + * Estimate CPU frequency. Sets mips_counter_frequency as a side-effect */ static unsigned int __init estimate_cpu_frequency(void) { @@ -169,9 +177,9 @@ void __init sim_time_init(void) static int mips_cpu_timer_irq; -static void mips_timer_dispatch(void) +static void mips_timer_dispatch (struct pt_regs *regs) { - do_IRQ(mips_cpu_timer_irq); + do_IRQ (mips_cpu_timer_irq, regs); } @@ -196,8 +204,7 @@ void __init plat_timer_setup(struct irqaction *irq) on seperate cpu's the first one tries to handle the second interrupt. The effect is that the int remains disabled on the second cpu. Mark the interrupt with IRQ_PER_CPU to avoid any confusion */ - irq_desc[mips_cpu_timer_irq].flags |= IRQ_PER_CPU; - set_irq_handler(mips_cpu_timer_irq, handle_percpu_irq); + irq_desc[mips_cpu_timer_irq].status |= IRQ_PER_CPU; #endif /* to generate the first timer interrupt */ diff --git a/trunk/arch/mips/mm/c-r4k.c b/trunk/arch/mips/mm/c-r4k.c index df04a315d830..cc895dad71d2 100644 --- a/trunk/arch/mips/mm/c-r4k.c +++ b/trunk/arch/mips/mm/c-r4k.c @@ -323,6 +323,7 @@ static void __init r4k_blast_scache_setup(void) static inline void local_r4k_flush_cache_all(void * args) { r4k_blast_dcache(); + r4k_blast_icache(); } static void r4k_flush_cache_all(void) @@ -358,19 +359,21 @@ static void r4k___flush_cache_all(void) static inline void local_r4k_flush_cache_range(void * args) { struct vm_area_struct *vma = args; + int exec; if (!(cpu_context(smp_processor_id(), vma->vm_mm))) return; - r4k_blast_dcache(); + exec = vma->vm_flags & VM_EXEC; + if (cpu_has_dc_aliases || exec) + r4k_blast_dcache(); + if (exec) + r4k_blast_icache(); } static void r4k_flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) { - if (!cpu_has_dc_aliases) - return; - r4k_on_each_cpu(local_r4k_flush_cache_range, vma, 1, 1); } @@ -381,21 +384,18 @@ static inline void local_r4k_flush_cache_mm(void * args) if (!cpu_context(smp_processor_id(), mm)) return; + r4k_blast_dcache(); + r4k_blast_icache(); + /* * Kludge alert. For obscure reasons R4000SC and R4400SC go nuts if we * only flush the primary caches but R10000 and R12000 behave sane ... - * R4000SC and R4400SC indexed S-cache ops also invalidate primary - * caches, so we can bail out early. */ if (current_cpu_data.cputype == CPU_R4000SC || current_cpu_data.cputype == CPU_R4000MC || current_cpu_data.cputype == CPU_R4400SC || - current_cpu_data.cputype == CPU_R4400MC) { + current_cpu_data.cputype == CPU_R4400MC) r4k_blast_scache(); - return; - } - - r4k_blast_dcache(); } static void r4k_flush_cache_mm(struct mm_struct *mm) diff --git a/trunk/arch/mips/mm/c-sb1.c b/trunk/arch/mips/mm/c-sb1.c index 3a8afd47feaa..5537558f19f7 100644 --- a/trunk/arch/mips/mm/c-sb1.c +++ b/trunk/arch/mips/mm/c-sb1.c @@ -19,7 +19,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include -#include #include #include @@ -50,15 +49,6 @@ static unsigned short dcache_sets; static unsigned int icache_range_cutoff; static unsigned int dcache_range_cutoff; -static inline void sb1_on_each_cpu(void (*func) (void *info), void *info, - int retry, int wait) -{ - preempt_disable(); - smp_call_function(func, info, retry, wait); - func(info); - preempt_enable(); -} - /* * The dcache is fully coherent to the system, with one * big caveat: the instruction stream. In other words, @@ -236,32 +226,13 @@ static void sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr, args.vma = vma; args.addr = addr; args.pfn = pfn; - sb1_on_each_cpu(sb1_flush_cache_page_ipi, (void *) &args, 1, 1); + on_each_cpu(sb1_flush_cache_page_ipi, (void *) &args, 1, 1); } #else void sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn) __attribute__((alias("local_sb1_flush_cache_page"))); #endif -#ifdef CONFIG_SMP -static void sb1_flush_cache_data_page_ipi(void *info) -{ - unsigned long start = (unsigned long)info; - - __sb1_writeback_inv_dcache_range(start, start + PAGE_SIZE); -} - -static void sb1_flush_cache_data_page(unsigned long addr) -{ - if (in_atomic()) - __sb1_writeback_inv_dcache_range(addr, addr + PAGE_SIZE); - else - on_each_cpu(sb1_flush_cache_data_page_ipi, (void *) addr, 1, 1); -} -#else -void sb1_flush_cache_data_page(unsigned long) - __attribute__((alias("local_sb1_flush_cache_data_page"))); -#endif /* * Invalidate all caches on this CPU @@ -278,7 +249,7 @@ void sb1___flush_cache_all_ipi(void *ignored) static void sb1___flush_cache_all(void) { - sb1_on_each_cpu(sb1___flush_cache_all_ipi, 0, 1, 1); + on_each_cpu(sb1___flush_cache_all_ipi, 0, 1, 1); } #else void sb1___flush_cache_all(void) @@ -328,7 +299,7 @@ void sb1_flush_icache_range(unsigned long start, unsigned long end) args.start = start; args.end = end; - sb1_on_each_cpu(sb1_flush_icache_range_ipi, &args, 1, 1); + on_each_cpu(sb1_flush_icache_range_ipi, &args, 1, 1); } #else void sb1_flush_icache_range(unsigned long start, unsigned long end) @@ -355,7 +326,7 @@ static void sb1_flush_cache_sigtramp_ipi(void *info) static void sb1_flush_cache_sigtramp(unsigned long addr) { - sb1_on_each_cpu(sb1_flush_cache_sigtramp_ipi, (void *) addr, 1, 1); + on_each_cpu(sb1_flush_cache_sigtramp_ipi, (void *) addr, 1, 1); } #else void sb1_flush_cache_sigtramp(unsigned long addr) @@ -473,6 +444,7 @@ static __init void probe_cache_sizes(void) void sb1_cache_init(void) { extern char except_vec2_sb1; + extern char handle_vec2_sb1; /* Special cache error handler for SB1 */ set_uncached_handler (0x100, &except_vec2_sb1, 0x80); @@ -501,7 +473,7 @@ void sb1_cache_init(void) flush_cache_sigtramp = sb1_flush_cache_sigtramp; local_flush_data_cache_page = (void *) sb1_nop; - flush_data_cache_page = sb1_flush_cache_data_page; + flush_data_cache_page = (void *) sb1_nop; /* Full flush */ __flush_cache_all = sb1___flush_cache_all; @@ -525,5 +497,5 @@ void sb1_cache_init(void) : : "memory"); - local_sb1___flush_cache_all(); + flush_cache_all(); } diff --git a/trunk/arch/mips/mm/fault.c b/trunk/arch/mips/mm/fault.c index 6f90e7ef66ac..8423d8590779 100644 --- a/trunk/arch/mips/mm/fault.c +++ b/trunk/arch/mips/mm/fault.c @@ -60,10 +60,6 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write, */ if (unlikely(address >= VMALLOC_START && address <= VMALLOC_END)) goto vmalloc_fault; -#ifdef MODULE_START - if (unlikely(address >= MODULE_START && address < MODULE_END)) - goto vmalloc_fault; -#endif /* * If we're in an interrupt or have no user diff --git a/trunk/arch/mips/mm/init.c b/trunk/arch/mips/mm/init.c index 9e29ba9205f0..88b72c9a8495 100644 --- a/trunk/arch/mips/mm/init.c +++ b/trunk/arch/mips/mm/init.c @@ -30,34 +30,11 @@ #include #include #include -#include #include #include #include #include #include -#include - -/* Atomicity and interruptability */ -#ifdef CONFIG_MIPS_MT_SMTC - -#include - -#define ENTER_CRITICAL(flags) \ - { \ - unsigned int mvpflags; \ - local_irq_save(flags);\ - mvpflags = dvpe() -#define EXIT_CRITICAL(flags) \ - evpe(mvpflags); \ - local_irq_restore(flags); \ - } -#else - -#define ENTER_CRITICAL(flags) local_irq_save(flags) -#define EXIT_CRITICAL(flags) local_irq_restore(flags) - -#endif /* CONFIG_MIPS_MT_SMTC */ DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); @@ -90,9 +67,9 @@ unsigned long setup_zero_pages(void) if (!empty_zero_page) panic("Oh boy, that early out of memory?"); - page = virt_to_page((void *)empty_zero_page); + page = virt_to_page(empty_zero_page); split_page(page, order); - while (page < virt_to_page((void *)(empty_zero_page + (PAGE_SIZE << order)))) { + while (page < virt_to_page(empty_zero_page + (PAGE_SIZE << order))) { SetPageReserved(page); page++; } @@ -103,142 +80,13 @@ unsigned long setup_zero_pages(void) return 1UL << order; } -/* - * These are almost like kmap_atomic / kunmap_atmic except they take an - * additional address argument as the hint. - */ - -#define kmap_get_fixmap_pte(vaddr) \ - pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), (vaddr)) - -#ifdef CONFIG_MIPS_MT_SMTC -static pte_t *kmap_coherent_pte; -static void __init kmap_coherent_init(void) -{ - unsigned long vaddr; - - /* cache the first coherent kmap pte */ - vaddr = __fix_to_virt(FIX_CMAP_BEGIN); - kmap_coherent_pte = kmap_get_fixmap_pte(vaddr); -} -#else -static inline void kmap_coherent_init(void) {} -#endif - -static inline void *kmap_coherent(struct page *page, unsigned long addr) -{ - enum fixed_addresses idx; - unsigned long vaddr, flags, entrylo; - unsigned long old_ctx; - pte_t pte; - int tlbidx; - - inc_preempt_count(); - idx = (addr >> PAGE_SHIFT) & (FIX_N_COLOURS - 1); -#ifdef CONFIG_MIPS_MT_SMTC - idx += FIX_N_COLOURS * smp_processor_id(); -#endif - vaddr = __fix_to_virt(FIX_CMAP_END - idx); - pte = mk_pte(page, PAGE_KERNEL); -#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32_R1) - entrylo = pte.pte_high; -#else - entrylo = pte_val(pte) >> 6; -#endif - - ENTER_CRITICAL(flags); - old_ctx = read_c0_entryhi(); - write_c0_entryhi(vaddr & (PAGE_MASK << 1)); - write_c0_entrylo0(entrylo); - write_c0_entrylo1(entrylo); -#ifdef CONFIG_MIPS_MT_SMTC - set_pte(kmap_coherent_pte - (FIX_CMAP_END - idx), pte); - /* preload TLB instead of local_flush_tlb_one() */ - mtc0_tlbw_hazard(); - tlb_probe(); - tlb_probe_hazard(); - tlbidx = read_c0_index(); - mtc0_tlbw_hazard(); - if (tlbidx < 0) - tlb_write_random(); - else - tlb_write_indexed(); -#else - tlbidx = read_c0_wired(); - write_c0_wired(tlbidx + 1); - write_c0_index(tlbidx); - mtc0_tlbw_hazard(); - tlb_write_indexed(); -#endif - tlbw_use_hazard(); - write_c0_entryhi(old_ctx); - EXIT_CRITICAL(flags); - - return (void*) vaddr; -} - -#define UNIQUE_ENTRYHI(idx) (CKSEG0 + ((idx) << (PAGE_SHIFT + 1))) - -static inline void kunmap_coherent(struct page *page) -{ -#ifndef CONFIG_MIPS_MT_SMTC - unsigned int wired; - unsigned long flags, old_ctx; - - ENTER_CRITICAL(flags); - old_ctx = read_c0_entryhi(); - wired = read_c0_wired() - 1; - write_c0_wired(wired); - write_c0_index(wired); - write_c0_entryhi(UNIQUE_ENTRYHI(wired)); - write_c0_entrylo0(0); - write_c0_entrylo1(0); - mtc0_tlbw_hazard(); - tlb_write_indexed(); - tlbw_use_hazard(); - write_c0_entryhi(old_ctx); - EXIT_CRITICAL(flags); -#endif - dec_preempt_count(); - preempt_check_resched(); -} - -void copy_to_user_page(struct vm_area_struct *vma, - struct page *page, unsigned long vaddr, void *dst, const void *src, - unsigned long len) -{ - if (cpu_has_dc_aliases) { - void *vto = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK); - memcpy(vto, src, len); - kunmap_coherent(page); - } else - memcpy(dst, src, len); - if ((vma->vm_flags & VM_EXEC) && !cpu_has_ic_fills_f_dc) - flush_cache_page(vma, vaddr, page_to_pfn(page)); -} - -EXPORT_SYMBOL(copy_to_user_page); - -void copy_from_user_page(struct vm_area_struct *vma, - struct page *page, unsigned long vaddr, void *dst, const void *src, - unsigned long len) -{ - if (cpu_has_dc_aliases) { - void *vfrom = - kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK); - memcpy(dst, vfrom, len); - kunmap_coherent(page); - } else - memcpy(dst, src, len); -} - -EXPORT_SYMBOL(copy_from_user_page); - - #ifdef CONFIG_HIGHMEM pte_t *kmap_pte; pgprot_t kmap_prot; +#define kmap_get_fixmap_pte(vaddr) \ + pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), (vaddr)) + static void __init kmap_init(void) { unsigned long kmap_vstart; @@ -249,12 +97,11 @@ static void __init kmap_init(void) kmap_prot = PAGE_KERNEL; } -#endif /* CONFIG_HIGHMEM */ +#ifdef CONFIG_32BIT void __init fixrange_init(unsigned long start, unsigned long end, pgd_t *pgd_base) { -#if defined(CONFIG_HIGHMEM) || defined(CONFIG_MIPS_MT_SMTC) pgd_t *pgd; pud_t *pud; pmd_t *pmd; @@ -275,7 +122,7 @@ void __init fixrange_init(unsigned long start, unsigned long end, for (; (k < PTRS_PER_PMD) && (vaddr != end); pmd++, k++) { if (pmd_none(*pmd)) { pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); - set_pmd(pmd, __pmd((unsigned long)pte)); + set_pmd(pmd, __pmd(pte)); if (pte != pte_offset_kernel(pmd, 0)) BUG(); } @@ -285,8 +132,9 @@ void __init fixrange_init(unsigned long start, unsigned long end, } j = 0; } -#endif } +#endif /* CONFIG_32BIT */ +#endif /* CONFIG_HIGHMEM */ #ifndef CONFIG_NEED_MULTIPLE_NODES extern void pagetable_init(void); @@ -327,7 +175,6 @@ void __init paging_init(void) #ifdef CONFIG_HIGHMEM kmap_init(); #endif - kmap_coherent_init(); max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; low = max_low_pfn; @@ -443,18 +290,15 @@ void __init mem_init(void) } #endif /* !CONFIG_NEED_MULTIPLE_NODES */ -static void free_init_pages(char *what, unsigned long begin, unsigned long end) +void free_init_pages(char *what, unsigned long begin, unsigned long end) { - unsigned long pfn; - - for (pfn = PFN_UP(begin); pfn < PFN_DOWN(end); pfn++) { - struct page *page = pfn_to_page(pfn); - void *addr = phys_to_virt(PFN_PHYS(pfn)); + unsigned long addr; - ClearPageReserved(page); - init_page_count(page); - memset(addr, POISON_FREE_INITMEM, PAGE_SIZE); - __free_page(page); + for (addr = begin; addr < end; addr += PAGE_SIZE) { + ClearPageReserved(virt_to_page(addr)); + init_page_count(virt_to_page(addr)); + memset((void *)addr, 0xcc, PAGE_SIZE); + free_page(addr); totalram_pages++; } printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10); @@ -463,9 +307,12 @@ static void free_init_pages(char *what, unsigned long begin, unsigned long end) #ifdef CONFIG_BLK_DEV_INITRD void free_initrd_mem(unsigned long start, unsigned long end) { - free_init_pages("initrd memory", - virt_to_phys((void *)start), - virt_to_phys((void *)end)); +#ifdef CONFIG_64BIT + /* Switch from KSEG0 to XKPHYS addresses */ + start = (unsigned long)phys_to_virt(CPHYSADDR(start)); + end = (unsigned long)phys_to_virt(CPHYSADDR(end)); +#endif + free_init_pages("initrd memory", start, end); } #endif @@ -473,13 +320,17 @@ extern unsigned long prom_free_prom_memory(void); void free_initmem(void) { - unsigned long freed; + unsigned long start, end, freed; freed = prom_free_prom_memory(); if (freed) printk(KERN_INFO "Freeing firmware memory: %ldk freed\n",freed); - free_init_pages("unused kernel memory", - __pa_symbol(&__init_begin), - __pa_symbol(&__init_end)); + start = (unsigned long)(&__init_begin); + end = (unsigned long)(&__init_end); +#ifdef CONFIG_64BIT + start = PAGE_OFFSET | CPHYSADDR(start); + end = PAGE_OFFSET | CPHYSADDR(end); +#endif + free_init_pages("unused kernel memory", start, end); } diff --git a/trunk/arch/mips/mm/ioremap.c b/trunk/arch/mips/mm/ioremap.c index cea7d0ea36e4..3101d1db5592 100644 --- a/trunk/arch/mips/mm/ioremap.c +++ b/trunk/arch/mips/mm/ioremap.c @@ -176,7 +176,7 @@ void __iomem * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags) #define IS_KSEG1(addr) (((unsigned long)(addr) & ~0x1fffffffUL) == CKSEG1) -void __iounmap(const volatile void __iomem *addr) +void __iounmap(volatile void __iomem *addr) { struct vm_struct *p; diff --git a/trunk/arch/mips/mm/pg-r4k.c b/trunk/arch/mips/mm/pg-r4k.c index d41fc5885e87..b7c749232ffe 100644 --- a/trunk/arch/mips/mm/pg-r4k.c +++ b/trunk/arch/mips/mm/pg-r4k.c @@ -270,20 +270,6 @@ static inline void build_addiu_a2_a0(unsigned long offset) emit_instruction(mi); } -static inline void build_addiu_a2(unsigned long offset) -{ - union mips_instruction mi; - - BUG_ON(offset > 0x7fff); - - mi.i_format.opcode = cpu_has_64bit_gp_regs ? daddiu_op : addiu_op; - mi.i_format.rs = 6; /* $a2 */ - mi.i_format.rt = 6; /* $a2 */ - mi.i_format.simmediate = offset; - - emit_instruction(mi); -} - static inline void build_addiu_a1(unsigned long offset) { union mips_instruction mi; @@ -347,7 +333,6 @@ static inline void build_jr_ra(void) void __init build_clear_page(void) { unsigned int loop_start; - unsigned long off; epc = (unsigned int *) &clear_page_array; instruction_pending = 0; @@ -384,12 +369,7 @@ void __init build_clear_page(void) } } - off = PAGE_SIZE - (cpu_has_prefetch ? pref_offset_clear : 0); - if (off > 0x7fff) { - build_addiu_a2_a0(off >> 1); - build_addiu_a2(off >> 1); - } else - build_addiu_a2_a0(off); + build_addiu_a2_a0(PAGE_SIZE - (cpu_has_prefetch ? pref_offset_clear : 0)); if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x()) build_insn_word(0x3c01a000); /* lui $at, 0xa000 */ @@ -440,18 +420,12 @@ dest = label(); void __init build_copy_page(void) { unsigned int loop_start; - unsigned long off; epc = (unsigned int *) ©_page_array; store_offset = load_offset = 0; instruction_pending = 0; - off = PAGE_SIZE - (cpu_has_prefetch ? pref_offset_copy : 0); - if (off > 0x7fff) { - build_addiu_a2_a0(off >> 1); - build_addiu_a2(off >> 1); - } else - build_addiu_a2_a0(off); + build_addiu_a2_a0(PAGE_SIZE - (cpu_has_prefetch ? pref_offset_copy : 0)); if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x()) build_insn_word(0x3c01a000); /* lui $at, 0xa000 */ diff --git a/trunk/arch/mips/mm/pgtable-32.c b/trunk/arch/mips/mm/pgtable-32.c index 4a61e624b0ec..4bdaa05f485b 100644 --- a/trunk/arch/mips/mm/pgtable-32.c +++ b/trunk/arch/mips/mm/pgtable-32.c @@ -31,10 +31,9 @@ void pgd_init(unsigned long page) void __init pagetable_init(void) { - unsigned long vaddr; - pgd_t *pgd_base; #ifdef CONFIG_HIGHMEM - pgd_t *pgd; + unsigned long vaddr; + pgd_t *pgd, *pgd_base; pud_t *pud; pmd_t *pmd; pte_t *pte; @@ -45,6 +44,7 @@ void __init pagetable_init(void) pgd_init((unsigned long)swapper_pg_dir + sizeof(pgd_t) * USER_PTRS_PER_PGD); +#ifdef CONFIG_HIGHMEM pgd_base = swapper_pg_dir; /* @@ -53,7 +53,6 @@ void __init pagetable_init(void) vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK; fixrange_init(vaddr, 0, pgd_base); -#ifdef CONFIG_HIGHMEM /* * Permanent kmaps: */ diff --git a/trunk/arch/mips/mm/pgtable-64.c b/trunk/arch/mips/mm/pgtable-64.c index c46eb651bf09..44b5e97fff65 100644 --- a/trunk/arch/mips/mm/pgtable-64.c +++ b/trunk/arch/mips/mm/pgtable-64.c @@ -8,7 +8,6 @@ */ #include #include -#include #include void pgd_init(unsigned long page) @@ -53,20 +52,7 @@ void pmd_init(unsigned long addr, unsigned long pagetable) void __init pagetable_init(void) { - unsigned long vaddr; - pgd_t *pgd_base; - /* Initialize the entire pgd. */ pgd_init((unsigned long)swapper_pg_dir); -#ifdef MODULE_START - pgd_init((unsigned long)module_pg_dir); -#endif pmd_init((unsigned long)invalid_pmd_table, (unsigned long)invalid_pte_table); - - pgd_base = swapper_pg_dir; - /* - * Fixed mappings: - */ - vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK; - fixrange_init(vaddr, 0, pgd_base); } diff --git a/trunk/arch/mips/mm/tlbex.c b/trunk/arch/mips/mm/tlbex.c index 492c518e7ba5..6f8b25cfa6f0 100644 --- a/trunk/arch/mips/mm/tlbex.c +++ b/trunk/arch/mips/mm/tlbex.c @@ -102,7 +102,7 @@ enum opcode { insn_addu, insn_addiu, insn_and, insn_andi, insn_beq, insn_beql, insn_bgez, insn_bgezl, insn_bltz, insn_bltzl, insn_bne, insn_daddu, insn_daddiu, insn_dmfc0, insn_dmtc0, - insn_dsll, insn_dsll32, insn_dsra, insn_dsrl, insn_dsrl32, + insn_dsll, insn_dsll32, insn_dsra, insn_dsrl, insn_dsubu, insn_eret, insn_j, insn_jal, insn_jr, insn_ld, insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0, insn_mtc0, insn_ori, insn_rfe, insn_sc, insn_scd, insn_sd, insn_sll, @@ -145,7 +145,6 @@ static __initdata struct insn insn_table[] = { { insn_dsll32, M(spec_op,0,0,0,0,dsll32_op), RT | RD | RE }, { insn_dsra, M(spec_op,0,0,0,0,dsra_op), RT | RD | RE }, { insn_dsrl, M(spec_op,0,0,0,0,dsrl_op), RT | RD | RE }, - { insn_dsrl32, M(spec_op,0,0,0,0,dsrl32_op), RT | RD | RE }, { insn_dsubu, M(spec_op,0,0,0,0,dsubu_op), RS | RT | RD }, { insn_eret, M(cop0_op,cop_op,0,0,0,eret_op), 0 }, { insn_j, M(j_op,0,0,0,0,0), JIMM }, @@ -386,7 +385,6 @@ I_u2u1u3(_dsll); I_u2u1u3(_dsll32); I_u2u1u3(_dsra); I_u2u1u3(_dsrl); -I_u2u1u3(_dsrl32); I_u3u1u2(_dsubu); I_0(_eret); I_u1(_j); @@ -423,9 +421,6 @@ enum label_id { label_invalid, label_second_part, label_leave, -#ifdef MODULE_START - label_module_alloc, -#endif label_vmalloc, label_vmalloc_done, label_tlbw_hazard, @@ -458,9 +453,6 @@ static __init void build_label(struct label **lab, u32 *addr, L_LA(_second_part) L_LA(_leave) -#ifdef MODULE_START -L_LA(_module_alloc) -#endif L_LA(_vmalloc) L_LA(_vmalloc_done) L_LA(_tlbw_hazard) @@ -692,13 +684,6 @@ static void __init il_bgezl(u32 **p, struct reloc **r, unsigned int reg, i_bgezl(p, reg, 0); } -static void __init __attribute__((unused)) -il_bgez(u32 **p, struct reloc **r, unsigned int reg, enum label_id l) -{ - r_mips_pc16(r, *p, l); - i_bgez(p, reg, 0); -} - /* The only general purpose registers allowed in TLB handlers. */ #define K0 26 #define K1 27 @@ -983,11 +968,7 @@ build_get_pmde64(u32 **p, struct label **l, struct reloc **r, * The vmalloc handling is not in the hotpath. */ i_dmfc0(p, tmp, C0_BADVADDR); -#ifdef MODULE_START - il_bltz(p, r, tmp, label_module_alloc); -#else il_bltz(p, r, tmp, label_vmalloc); -#endif /* No i_nop needed here, since the next insn doesn't touch TMP. */ #ifdef CONFIG_SMP @@ -1015,12 +996,7 @@ build_get_pmde64(u32 **p, struct label **l, struct reloc **r, #endif l_vmalloc_done(l, *p); - - if (PGDIR_SHIFT - 3 < 32) /* get pgd offset in bytes */ - i_dsrl(p, tmp, tmp, PGDIR_SHIFT-3); - else - i_dsrl32(p, tmp, tmp, PGDIR_SHIFT - 3 - 32); - + i_dsrl(p, tmp, tmp, PGDIR_SHIFT-3); /* get pgd offset in bytes */ i_andi(p, tmp, tmp, (PTRS_PER_PGD - 1)<<3); i_daddu(p, ptr, ptr, tmp); /* add in pgd offset */ i_dmfc0(p, tmp, C0_BADVADDR); /* get faulting address */ @@ -1040,46 +1016,8 @@ build_get_pgd_vmalloc64(u32 **p, struct label **l, struct reloc **r, { long swpd = (long)swapper_pg_dir; -#ifdef MODULE_START - long modd = (long)module_pg_dir; - - l_module_alloc(l, *p); - /* - * Assumption: - * VMALLOC_START >= 0xc000000000000000UL - * MODULE_START >= 0xe000000000000000UL - */ - i_SLL(p, ptr, bvaddr, 2); - il_bgez(p, r, ptr, label_vmalloc); - - if (in_compat_space_p(MODULE_START) && !rel_lo(MODULE_START)) { - i_lui(p, ptr, rel_hi(MODULE_START)); /* delay slot */ - } else { - /* unlikely configuration */ - i_nop(p); /* delay slot */ - i_LA(p, ptr, MODULE_START); - } - i_dsubu(p, bvaddr, bvaddr, ptr); - - if (in_compat_space_p(modd) && !rel_lo(modd)) { - il_b(p, r, label_vmalloc_done); - i_lui(p, ptr, rel_hi(modd)); - } else { - i_LA_mostly(p, ptr, modd); - il_b(p, r, label_vmalloc_done); - i_daddiu(p, ptr, ptr, rel_lo(modd)); - } - - l_vmalloc(l, *p); - if (in_compat_space_p(MODULE_START) && !rel_lo(MODULE_START) && - MODULE_START << 32 == VMALLOC_START) - i_dsll32(p, ptr, ptr, 0); /* typical case */ - else - i_LA(p, ptr, VMALLOC_START); -#else l_vmalloc(l, *p); i_LA(p, ptr, VMALLOC_START); -#endif i_dsubu(p, bvaddr, bvaddr, ptr); if (in_compat_space_p(swpd) && !rel_lo(swpd)) { @@ -1135,7 +1073,7 @@ build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr) static __init void build_adjust_context(u32 **p, unsigned int ctx) { - unsigned int shift = 4 - (PTE_T_LOG2 + 1) + PAGE_SHIFT - 12; + unsigned int shift = 4 - (PTE_T_LOG2 + 1); unsigned int mask = (PTRS_PER_PTE / 2 - 1) << (PTE_T_LOG2 + 1); switch (current_cpu_data.cputype) { diff --git a/trunk/arch/mips/momentum/jaguar_atx/irq.c b/trunk/arch/mips/momentum/jaguar_atx/irq.c index 2efb25aa1aed..f9067469a656 100644 --- a/trunk/arch/mips/momentum/jaguar_atx/irq.c +++ b/trunk/arch/mips/momentum/jaguar_atx/irq.c @@ -40,33 +40,33 @@ #include #include -asmlinkage void plat_irq_dispatch(void) +asmlinkage void plat_irq_dispatch(struct pt_regs *regs) { unsigned int pending = read_c0_cause() & read_c0_status(); if (pending & STATUSF_IP0) - do_IRQ(0); + do_IRQ(0, regs); else if (pending & STATUSF_IP1) - do_IRQ(1); + do_IRQ(1, regs); else if (pending & STATUSF_IP2) - do_IRQ(2); + do_IRQ(2, regs); else if (pending & STATUSF_IP3) - do_IRQ(3); + do_IRQ(3, regs); else if (pending & STATUSF_IP4) - do_IRQ(4); + do_IRQ(4, regs); else if (pending & STATUSF_IP5) - do_IRQ(5); + do_IRQ(5, regs); else if (pending & STATUSF_IP6) - do_IRQ(6); + do_IRQ(6, regs); else if (pending & STATUSF_IP7) - ll_timer_interrupt(7); + ll_timer_interrupt(7, regs); else { /* * Now look at the extended interrupts */ pending = (read_c0_cause() & (read_c0_intcontrol() << 8)) >> 16; if (pending & STATUSF_IP8) - ll_mv64340_irq(); + ll_mv64340_irq(regs); } } diff --git a/trunk/arch/mips/momentum/jaguar_atx/setup.c b/trunk/arch/mips/momentum/jaguar_atx/setup.c index 5a510142b978..e6fe2992227d 100644 --- a/trunk/arch/mips/momentum/jaguar_atx/setup.c +++ b/trunk/arch/mips/momentum/jaguar_atx/setup.c @@ -62,6 +62,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/mips/momentum/ocelot_3/Makefile b/trunk/arch/mips/momentum/ocelot_3/Makefile index d5a090a85a15..8bcea64dd27b 100644 --- a/trunk/arch/mips/momentum/ocelot_3/Makefile +++ b/trunk/arch/mips/momentum/ocelot_3/Makefile @@ -5,4 +5,4 @@ # removes any old dependencies. DON'T put your own dependencies here # unless it's something special (ie not a .c file). # -obj-y += irq.o platform.o prom.o reset.o setup.o +obj-y += irq.o prom.o reset.o setup.o diff --git a/trunk/arch/mips/momentum/ocelot_3/irq.c b/trunk/arch/mips/momentum/ocelot_3/irq.c index cea0e5deb80e..793782a9c195 100644 --- a/trunk/arch/mips/momentum/ocelot_3/irq.c +++ b/trunk/arch/mips/momentum/ocelot_3/irq.c @@ -75,26 +75,26 @@ void __init arch_init_irq(void) } -asmlinkage void plat_irq_dispatch(void) +asmlinkage void plat_irq_dispatch(struct pt_regs *regs) { unsigned int pending = read_c0_cause() & read_c0_status(); if (pending & STATUSF_IP0) - do_IRQ(0); + do_IRQ(0, regs); else if (pending & STATUSF_IP1) - do_IRQ(1); + do_IRQ(1, regs); else if (pending & STATUSF_IP2) - do_IRQ(2); + do_IRQ(2, regs); else if (pending & STATUSF_IP3) - do_IRQ(3); + do_IRQ(3, regs); else if (pending & STATUSF_IP4) - do_IRQ(4); + do_IRQ(4, regs); else if (pending & STATUSF_IP5) - do_IRQ(5); + do_IRQ(5, regs); else if (pending & STATUSF_IP6) - do_IRQ(6); + do_IRQ(6, regs); else if (pending & STATUSF_IP7) - do_IRQ(7); + do_IRQ(7, regs); else { /* * Now look at the extended interrupts @@ -102,8 +102,8 @@ asmlinkage void plat_irq_dispatch(void) pending = (read_c0_cause() & (read_c0_intcontrol() << 8)) >> 16; if (pending & STATUSF_IP8) - ll_mv64340_irq(); + ll_mv64340_irq(regs); else - spurious_interrupt(); + spurious_interrupt(regs); } } diff --git a/trunk/arch/mips/momentum/ocelot_3/ocelot_3_fpga.h b/trunk/arch/mips/momentum/ocelot_3/ocelot_3_fpga.h index 5710a9029f1c..227e429fe720 100644 --- a/trunk/arch/mips/momentum/ocelot_3/ocelot_3_fpga.h +++ b/trunk/arch/mips/momentum/ocelot_3/ocelot_3_fpga.h @@ -51,9 +51,7 @@ extern unsigned long ocelot_fpga_base; -#define __FPGA_REG_TO_ADDR(reg) \ - ((void *) ocelot_fpga_base + OCELOT_3_REG_##reg) -#define OCELOT_FPGA_WRITE(x, reg) writeb(x, __FPGA_REG_TO_ADDR(reg)) -#define OCELOT_FPGA_READ(reg) readb(__FPGA_REG_TO_ADDR(reg)) +#define OCELOT_FPGA_WRITE(x, y) writeb(x, ocelot_fpga_base + OCELOT_3_REG_##y) +#define OCELOT_FPGA_READ(x) readb(ocelot_fpga_base + OCELOT_3_REG_##x) #endif diff --git a/trunk/arch/mips/momentum/ocelot_3/platform.c b/trunk/arch/mips/momentum/ocelot_3/platform.c deleted file mode 100644 index eefe5841fbb2..000000000000 --- a/trunk/arch/mips/momentum/ocelot_3/platform.c +++ /dev/null @@ -1,235 +0,0 @@ -#include -#include -#include -#include -#include - -#include "ocelot_3_fpga.h" - -#if defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE) - -static struct resource mv643xx_eth_shared_resources[] = { - [0] = { - .name = "ethernet shared base", - .start = 0xf1000000 + MV643XX_ETH_SHARED_REGS, - .end = 0xf1000000 + MV643XX_ETH_SHARED_REGS + - MV643XX_ETH_SHARED_REGS_SIZE - 1, - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device mv643xx_eth_shared_device = { - .name = MV643XX_ETH_SHARED_NAME, - .id = 0, - .num_resources = ARRAY_SIZE(mv643xx_eth_shared_resources), - .resource = mv643xx_eth_shared_resources, -}; - -#define MV_SRAM_BASE 0xfe000000UL -#define MV_SRAM_SIZE (256 * 1024) - -#define MV_SRAM_RXRING_SIZE (MV_SRAM_SIZE / 4) -#define MV_SRAM_TXRING_SIZE (MV_SRAM_SIZE / 4) - -#define MV_SRAM_BASE_ETH0 MV_SRAM_BASE -#define MV_SRAM_BASE_ETH1 (MV_SRAM_BASE + (MV_SRAM_SIZE / 2)) - -#define MV64x60_IRQ_ETH_0 48 -#define MV64x60_IRQ_ETH_1 49 -#define MV64x60_IRQ_ETH_2 50 - -#ifdef CONFIG_MV643XX_ETH_0 - -static struct resource mv64x60_eth0_resources[] = { - [0] = { - .name = "eth0 irq", - .start = MV64x60_IRQ_ETH_0, - .end = MV64x60_IRQ_ETH_0, - .flags = IORESOURCE_IRQ, - }, -}; - -static char eth0_mac_addr[ETH_ALEN]; - -static struct mv643xx_eth_platform_data eth0_pd = { - .mac_addr = eth0_mac_addr, - - .tx_sram_addr = MV_SRAM_BASE_ETH0, - .tx_sram_size = MV_SRAM_TXRING_SIZE, - .tx_queue_size = MV_SRAM_TXRING_SIZE / 16, - - .rx_sram_addr = MV_SRAM_BASE_ETH0 + MV_SRAM_TXRING_SIZE, - .rx_sram_size = MV_SRAM_RXRING_SIZE, - .rx_queue_size = MV_SRAM_RXRING_SIZE / 16, -}; - -static struct platform_device eth0_device = { - .name = MV643XX_ETH_NAME, - .id = 0, - .num_resources = ARRAY_SIZE(mv64x60_eth0_resources), - .resource = mv64x60_eth0_resources, - .dev = { - .platform_data = ð0_pd, - }, -}; -#endif /* CONFIG_MV643XX_ETH_0 */ - -#ifdef CONFIG_MV643XX_ETH_1 - -static struct resource mv64x60_eth1_resources[] = { - [0] = { - .name = "eth1 irq", - .start = MV64x60_IRQ_ETH_1, - .end = MV64x60_IRQ_ETH_1, - .flags = IORESOURCE_IRQ, - }, -}; - -static char eth1_mac_addr[ETH_ALEN]; - -static struct mv643xx_eth_platform_data eth1_pd = { - .mac_addr = eth1_mac_addr, - - .tx_sram_addr = MV_SRAM_BASE_ETH1, - .tx_sram_size = MV_SRAM_TXRING_SIZE, - .tx_queue_size = MV_SRAM_TXRING_SIZE / 16, - - .rx_sram_addr = MV_SRAM_BASE_ETH1 + MV_SRAM_TXRING_SIZE, - .rx_sram_size = MV_SRAM_RXRING_SIZE, - .rx_queue_size = MV_SRAM_RXRING_SIZE / 16, -}; - -static struct platform_device eth1_device = { - .name = MV643XX_ETH_NAME, - .id = 1, - .num_resources = ARRAY_SIZE(mv64x60_eth1_resources), - .resource = mv64x60_eth1_resources, - .dev = { - .platform_data = ð1_pd, - }, -}; -#endif /* CONFIG_MV643XX_ETH_1 */ - -#ifdef CONFIG_MV643XX_ETH_2 - -static struct resource mv64x60_eth2_resources[] = { - [0] = { - .name = "eth2 irq", - .start = MV64x60_IRQ_ETH_2, - .end = MV64x60_IRQ_ETH_2, - .flags = IORESOURCE_IRQ, - }, -}; - -static char eth2_mac_addr[ETH_ALEN]; - -static struct mv643xx_eth_platform_data eth2_pd = { - .mac_addr = eth2_mac_addr, -}; - -static struct platform_device eth2_device = { - .name = MV643XX_ETH_NAME, - .id = 1, - .num_resources = ARRAY_SIZE(mv64x60_eth2_resources), - .resource = mv64x60_eth2_resources, - .dev = { - .platform_data = ð2_pd, - }, -}; -#endif /* CONFIG_MV643XX_ETH_2 */ - -static struct platform_device *mv643xx_eth_pd_devs[] __initdata = { - &mv643xx_eth_shared_device, -#ifdef CONFIG_MV643XX_ETH_0 - ð0_device, -#endif -#ifdef CONFIG_MV643XX_ETH_1 - ð1_device, -#endif -#ifdef CONFIG_MV643XX_ETH_2 - ð2_device, -#endif -}; - -static u8 __init exchange_bit(u8 val, u8 cs) -{ - /* place the data */ - OCELOT_FPGA_WRITE((val << 2) | cs, EEPROM_MODE); - udelay(1); - - /* turn the clock on */ - OCELOT_FPGA_WRITE((val << 2) | cs | 0x2, EEPROM_MODE); - udelay(1); - - /* turn the clock off and read-strobe */ - OCELOT_FPGA_WRITE((val << 2) | cs | 0x10, EEPROM_MODE); - - /* return the data */ - return (OCELOT_FPGA_READ(EEPROM_MODE) >> 3) & 0x1; -} - -static void __init get_mac(char dest[6]) -{ - u8 read_opcode[12] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - int i,j; - - for (i = 0; i < 12; i++) - exchange_bit(read_opcode[i], 1); - - for (j = 0; j < 6; j++) { - dest[j] = 0; - for (i = 0; i < 8; i++) { - dest[j] <<= 1; - dest[j] |= exchange_bit(0, 1); - } - } - - /* turn off CS */ - exchange_bit(0,0); -} - -/* - * Copy and increment ethernet MAC address by a small value. - * - * This is useful for systems where the only one MAC address is stored in - * non-volatile memory for multiple ports. - */ -static inline void eth_mac_add(unsigned char *dst, unsigned char *src, - unsigned int add) -{ - int i; - - BUG_ON(add >= 256); - - for (i = ETH_ALEN; i >= 0; i--) { - dst[i] = src[i] + add; - add = dst[i] < src[i]; /* compute carry */ - } - - WARN_ON(add); -} - -static int __init mv643xx_eth_add_pds(void) -{ - unsigned char mac[ETH_ALEN]; - int ret; - - get_mac(mac); -#ifdef CONFIG_MV643XX_ETH_0 - eth_mac_add(eth1_mac_addr, mac, 0); -#endif -#ifdef CONFIG_MV643XX_ETH_1 - eth_mac_add(eth1_mac_addr, mac, 1); -#endif -#ifdef CONFIG_MV643XX_ETH_2 - eth_mac_add(eth2_mac_addr, mac, 2); -#endif - ret = platform_add_devices(mv643xx_eth_pd_devs, - ARRAY_SIZE(mv643xx_eth_pd_devs)); - - return ret; -} - -device_initcall(mv643xx_eth_add_pds); - -#endif /* defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE) */ diff --git a/trunk/arch/mips/momentum/ocelot_3/prom.c b/trunk/arch/mips/momentum/ocelot_3/prom.c index 6ce9b7fdb824..296d945bc248 100644 --- a/trunk/arch/mips/momentum/ocelot_3/prom.c +++ b/trunk/arch/mips/momentum/ocelot_3/prom.c @@ -34,11 +34,64 @@ struct callvectors* debug_vectors; extern unsigned long marvell_base; extern unsigned long cpu_clock; +#ifdef CONFIG_MV643XX_ETH +extern unsigned char prom_mac_addr_base[6]; +#endif + const char *get_system_type(void) { return "Momentum Ocelot-3"; } +#ifdef CONFIG_MV643XX_ETH +void burn_clocks(void) +{ + int i; + + /* this loop should burn at least 1us -- this should be plenty */ + for (i = 0; i < 0x10000; i++) + ; +} + +u8 exchange_bit(u8 val, u8 cs) +{ + /* place the data */ + OCELOT_FPGA_WRITE((val << 2) | cs, EEPROM_MODE); + burn_clocks(); + + /* turn the clock on */ + OCELOT_FPGA_WRITE((val << 2) | cs | 0x2, EEPROM_MODE); + burn_clocks(); + + /* turn the clock off and read-strobe */ + OCELOT_FPGA_WRITE((val << 2) | cs | 0x10, EEPROM_MODE); + + /* return the data */ + return ((OCELOT_FPGA_READ(EEPROM_MODE) >> 3) & 0x1); +} + +void get_mac(char dest[6]) +{ + u8 read_opcode[12] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + int i,j; + + for (i = 0; i < 12; i++) + exchange_bit(read_opcode[i], 1); + + for (j = 0; j < 6; j++) { + dest[j] = 0; + for (i = 0; i < 8; i++) { + dest[j] <<= 1; + dest[j] |= exchange_bit(0, 1); + } + } + + /* turn off CS */ + exchange_bit(0,0); +} +#endif + + #ifdef CONFIG_64BIT unsigned long signext(unsigned long addr) @@ -175,6 +228,11 @@ void __init prom_init(void) mips_machgroup = MACH_GROUP_MOMENCO; mips_machtype = MACH_MOMENCO_OCELOT_3; +#ifdef CONFIG_MV643XX_ETH + /* get the base MAC address for on-board ethernet ports */ + get_mac(prom_mac_addr_base); +#endif + #ifndef CONFIG_64BIT debug_vectors->printf("Booting Linux kernel...\n"); #endif diff --git a/trunk/arch/mips/momentum/ocelot_3/setup.c b/trunk/arch/mips/momentum/ocelot_3/setup.c index ff0829f81116..435d0787329e 100644 --- a/trunk/arch/mips/momentum/ocelot_3/setup.c +++ b/trunk/arch/mips/momentum/ocelot_3/setup.c @@ -4,7 +4,7 @@ * BRIEF MODULE DESCRIPTION * Momentum Computer Ocelot-3 board dependent boot routines * - * Copyright (C) 1996, 1997, 01, 05 - 06 Ralf Baechle + * Copyright (C) 1996, 1997, 01, 05 Ralf Baechle * Copyright (C) 2000 RidgeRun, Inc. * Copyright (C) 2001 Red Hat, Inc. * Copyright (C) 2002 Momentum Computer @@ -67,6 +67,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/mips/momentum/ocelot_c/Makefile b/trunk/arch/mips/momentum/ocelot_c/Makefile index d69161aa1675..94802b4db472 100644 --- a/trunk/arch/mips/momentum/ocelot_c/Makefile +++ b/trunk/arch/mips/momentum/ocelot_c/Makefile @@ -2,7 +2,7 @@ # Makefile for Momentum Computer's Ocelot-C and -CS boards. # -obj-y += cpci-irq.o irq.o platform.o prom.o reset.o \ +obj-y += cpci-irq.o irq.o prom.o reset.o \ setup.o uart-irq.o obj-$(CONFIG_KGDB) += dbg_io.o diff --git a/trunk/arch/mips/momentum/ocelot_c/cpci-irq.c b/trunk/arch/mips/momentum/ocelot_c/cpci-irq.c index e5a4a0a8a7f0..a5dc230520df 100644 --- a/trunk/arch/mips/momentum/ocelot_c/cpci-irq.c +++ b/trunk/arch/mips/momentum/ocelot_c/cpci-irq.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -65,6 +66,39 @@ static inline void unmask_cpci_irq(unsigned int irq) value = OCELOT_FPGA_READ(INTMASK); } +/* + * Enables the IRQ in the FPGA + */ +static void enable_cpci_irq(unsigned int irq) +{ + unmask_cpci_irq(irq); +} + +/* + * Initialize the IRQ in the FPGA + */ +static unsigned int startup_cpci_irq(unsigned int irq) +{ + unmask_cpci_irq(irq); + return 0; +} + +/* + * Disables the IRQ in the FPGA + */ +static void disable_cpci_irq(unsigned int irq) +{ + mask_cpci_irq(irq); +} + +/* + * Masks and ACKs an IRQ + */ +static void mask_and_ack_cpci_irq(unsigned int irq) +{ + mask_cpci_irq(irq); +} + /* * End IRQ processing */ @@ -78,7 +112,7 @@ static void end_cpci_irq(unsigned int irq) * Interrupt handler for interrupts coming from the FPGA chip. * It could be built in ethernet ports etc... */ -void ll_cpci_irq(void) +void ll_cpci_irq(struct pt_regs *regs) { unsigned int irq_src, irq_mask; @@ -89,15 +123,18 @@ void ll_cpci_irq(void) /* mask for just the interrupts we want */ irq_src &= ~irq_mask; - do_IRQ(ls1bit8(irq_src) + CPCI_IRQ_BASE); + do_IRQ(ls1bit8(irq_src) + CPCI_IRQ_BASE, regs); } +#define shutdown_cpci_irq disable_cpci_irq + struct irq_chip cpci_irq_type = { .typename = "CPCI/FPGA", - .ack = mask_cpci_irq, - .mask = mask_cpci_irq, - .mask_ack = mask_cpci_irq, - .unmask = unmask_cpci_irq, + .startup = startup_cpci_irq, + .shutdown = shutdown_cpci_irq, + .enable = enable_cpci_irq, + .disable = disable_cpci_irq, + .ack = mask_and_ack_cpci_irq, .end = end_cpci_irq, }; @@ -105,6 +142,11 @@ void cpci_irq_init(void) { int i; - for (i = CPCI_IRQ_BASE; i < (CPCI_IRQ_BASE + 8); i++) - set_irq_chip_and_handler(i, &cpci_irq_type, handle_level_irq); + /* Reset irq handlers pointers to NULL */ + for (i = CPCI_IRQ_BASE; i < (CPCI_IRQ_BASE + 8); i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 2; + irq_desc[i].chip = &cpci_irq_type; + } } diff --git a/trunk/arch/mips/momentum/ocelot_c/irq.c b/trunk/arch/mips/momentum/ocelot_c/irq.c index ea65223a6d2c..9d44ae1e156b 100644 --- a/trunk/arch/mips/momentum/ocelot_c/irq.c +++ b/trunk/arch/mips/momentum/ocelot_c/irq.c @@ -59,31 +59,31 @@ static struct irqaction cascade_mv64340 = { no_action, IRQF_DISABLED, CPU_MASK_NONE, "cascade via MV64340", NULL, NULL }; -extern void ll_uart_irq(void); -extern void ll_cpci_irq(void); +extern void ll_uart_irq(struct pt_regs *regs); +extern void ll_cpci_irq(struct pt_regs *regs); -asmlinkage void plat_irq_dispatch(void) +asmlinkage void plat_irq_dispatch(struct pt_regs *regs) { unsigned int pending = read_c0_cause() & read_c0_status(); if (pending & STATUSF_IP0) - do_IRQ(0); + do_IRQ(0, regs); else if (pending & STATUSF_IP1) - do_IRQ(1); + do_IRQ(1, regs); else if (pending & STATUSF_IP2) - do_IRQ(2); + do_IRQ(2, regs); else if (pending & STATUSF_IP3) - ll_uart_irq(); + ll_uart_irq(regs); else if (pending & STATUSF_IP4) - do_IRQ(4); + do_IRQ(4, regs); else if (pending & STATUSF_IP5) - ll_cpci_irq(); + ll_cpci_irq(regs); else if (pending & STATUSF_IP6) - ll_mv64340_irq(); + ll_mv64340_irq(regs); else if (pending & STATUSF_IP7) - do_IRQ(7); + do_IRQ(7, regs); else - spurious_interrupt(); + spurious_interrupt(regs); } void __init arch_init_irq(void) diff --git a/trunk/arch/mips/momentum/ocelot_c/ocelot_c_fpga.h b/trunk/arch/mips/momentum/ocelot_c/ocelot_c_fpga.h index f0f5581dcb50..7228cd19e5ea 100644 --- a/trunk/arch/mips/momentum/ocelot_c/ocelot_c_fpga.h +++ b/trunk/arch/mips/momentum/ocelot_c/ocelot_c_fpga.h @@ -53,9 +53,7 @@ #define OCELOT_C_REG_INTSET 0xe #define OCELOT_C_REG_INTCLR 0xf -#define __FPGA_REG_TO_ADDR(reg) \ - ((void *) OCELOT_C_CS0_ADDR + OCELOT_C_REG_##reg) -#define OCELOT_FPGA_WRITE(x, reg) writeb(x, __FPGA_REG_TO_ADDR(reg)) -#define OCELOT_FPGA_READ(reg) readb(__FPGA_REG_TO_ADDR(reg)) +#define OCELOT_FPGA_WRITE(x, y) writeb(x, OCELOT_C_CS0_ADDR + OCELOT_C_REG_##y) +#define OCELOT_FPGA_READ(x) readb(OCELOT_C_CS0_ADDR + OCELOT_C_REG_##x) #endif diff --git a/trunk/arch/mips/momentum/ocelot_c/platform.c b/trunk/arch/mips/momentum/ocelot_c/platform.c deleted file mode 100644 index 6c495b2f1560..000000000000 --- a/trunk/arch/mips/momentum/ocelot_c/platform.c +++ /dev/null @@ -1,201 +0,0 @@ -#include -#include -#include -#include -#include - -#include "ocelot_c_fpga.h" - -#if defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE) - -static struct resource mv643xx_eth_shared_resources[] = { - [0] = { - .name = "ethernet shared base", - .start = 0xf1000000 + MV643XX_ETH_SHARED_REGS, - .end = 0xf1000000 + MV643XX_ETH_SHARED_REGS + - MV643XX_ETH_SHARED_REGS_SIZE - 1, - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device mv643xx_eth_shared_device = { - .name = MV643XX_ETH_SHARED_NAME, - .id = 0, - .num_resources = ARRAY_SIZE(mv643xx_eth_shared_resources), - .resource = mv643xx_eth_shared_resources, -}; - -#define MV_SRAM_BASE 0xfe000000UL -#define MV_SRAM_SIZE (256 * 1024) - -#define MV_SRAM_RXRING_SIZE (MV_SRAM_SIZE / 4) -#define MV_SRAM_TXRING_SIZE (MV_SRAM_SIZE / 4) - -#define MV_SRAM_BASE_ETH0 MV_SRAM_BASE -#define MV_SRAM_BASE_ETH1 (MV_SRAM_BASE + (MV_SRAM_SIZE / 2)) - -#define MV64x60_IRQ_ETH_0 48 -#define MV64x60_IRQ_ETH_1 49 - -#ifdef CONFIG_MV643XX_ETH_0 - -static struct resource mv64x60_eth0_resources[] = { - [0] = { - .name = "eth0 irq", - .start = MV64x60_IRQ_ETH_0, - .end = MV64x60_IRQ_ETH_0, - .flags = IORESOURCE_IRQ, - }, -}; - -static char eth0_mac_addr[ETH_ALEN]; - -static struct mv643xx_eth_platform_data eth0_pd = { - .mac_addr = eth0_mac_addr, - - .tx_sram_addr = MV_SRAM_BASE_ETH0, - .tx_sram_size = MV_SRAM_TXRING_SIZE, - .tx_queue_size = MV_SRAM_TXRING_SIZE / 16, - - .rx_sram_addr = MV_SRAM_BASE_ETH0 + MV_SRAM_TXRING_SIZE, - .rx_sram_size = MV_SRAM_RXRING_SIZE, - .rx_queue_size = MV_SRAM_RXRING_SIZE / 16, -}; - -static struct platform_device eth0_device = { - .name = MV643XX_ETH_NAME, - .id = 0, - .num_resources = ARRAY_SIZE(mv64x60_eth0_resources), - .resource = mv64x60_eth0_resources, - .dev = { - .platform_data = ð0_pd, - }, -}; -#endif /* CONFIG_MV643XX_ETH_0 */ - -#ifdef CONFIG_MV643XX_ETH_1 - -static struct resource mv64x60_eth1_resources[] = { - [0] = { - .name = "eth1 irq", - .start = MV64x60_IRQ_ETH_1, - .end = MV64x60_IRQ_ETH_1, - .flags = IORESOURCE_IRQ, - }, -}; - -static char eth1_mac_addr[ETH_ALEN]; - -static struct mv643xx_eth_platform_data eth1_pd = { - .mac_addr = eth1_mac_addr, - - .tx_sram_addr = MV_SRAM_BASE_ETH1, - .tx_sram_size = MV_SRAM_TXRING_SIZE, - .tx_queue_size = MV_SRAM_TXRING_SIZE / 16, - - .rx_sram_addr = MV_SRAM_BASE_ETH1 + MV_SRAM_TXRING_SIZE, - .rx_sram_size = MV_SRAM_RXRING_SIZE, - .rx_queue_size = MV_SRAM_RXRING_SIZE / 16, -}; - -static struct platform_device eth1_device = { - .name = MV643XX_ETH_NAME, - .id = 1, - .num_resources = ARRAY_SIZE(mv64x60_eth1_resources), - .resource = mv64x60_eth1_resources, - .dev = { - .platform_data = ð1_pd, - }, -}; -#endif /* CONFIG_MV643XX_ETH_1 */ - -static struct platform_device *mv643xx_eth_pd_devs[] __initdata = { - &mv643xx_eth_shared_device, -#ifdef CONFIG_MV643XX_ETH_0 - ð0_device, -#endif -#ifdef CONFIG_MV643XX_ETH_1 - ð1_device, -#endif - /* The third port is not wired up on the Ocelot C */ -}; - -static u8 __init exchange_bit(u8 val, u8 cs) -{ - /* place the data */ - OCELOT_FPGA_WRITE((val << 2) | cs, EEPROM_MODE); - udelay(1); - - /* turn the clock on */ - OCELOT_FPGA_WRITE((val << 2) | cs | 0x2, EEPROM_MODE); - udelay(1); - - /* turn the clock off and read-strobe */ - OCELOT_FPGA_WRITE((val << 2) | cs | 0x10, EEPROM_MODE); - - /* return the data */ - return (OCELOT_FPGA_READ(EEPROM_MODE) >> 3) & 0x1; -} - -static void __init get_mac(char dest[6]) -{ - u8 read_opcode[12] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - int i,j; - - for (i = 0; i < 12; i++) - exchange_bit(read_opcode[i], 1); - - for (j = 0; j < 6; j++) { - dest[j] = 0; - for (i = 0; i < 8; i++) { - dest[j] <<= 1; - dest[j] |= exchange_bit(0, 1); - } - } - - /* turn off CS */ - exchange_bit(0,0); -} - -/* - * Copy and increment ethernet MAC address by a small value. - * - * This is useful for systems where the only one MAC address is stored in - * non-volatile memory for multiple ports. - */ -static inline void eth_mac_add(unsigned char *dst, unsigned char *src, - unsigned int add) -{ - int i; - - BUG_ON(add >= 256); - - for (i = ETH_ALEN; i >= 0; i--) { - dst[i] = src[i] + add; - add = dst[i] < src[i]; /* compute carry */ - } - - WARN_ON(add); -} - -static int __init mv643xx_eth_add_pds(void) -{ - unsigned char mac[ETH_ALEN]; - int ret; - - get_mac(mac); -#ifdef CONFIG_MV643XX_ETH_0 - eth_mac_add(eth1_mac_addr, mac, 0); -#endif -#ifdef CONFIG_MV643XX_ETH_1 - eth_mac_add(eth1_mac_addr, mac, 1); -#endif - ret = platform_add_devices(mv643xx_eth_pd_devs, - ARRAY_SIZE(mv643xx_eth_pd_devs)); - - return ret; -} - -device_initcall(mv643xx_eth_add_pds); - -#endif /* defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE) */ diff --git a/trunk/arch/mips/momentum/ocelot_c/prom.c b/trunk/arch/mips/momentum/ocelot_c/prom.c index d0b77e101d74..4c50a147f429 100644 --- a/trunk/arch/mips/momentum/ocelot_c/prom.c +++ b/trunk/arch/mips/momentum/ocelot_c/prom.c @@ -29,7 +29,11 @@ struct callvectors* debug_vectors; extern unsigned long marvell_base; -extern unsigned int cpu_clock; +extern unsigned long cpu_clock; + +#ifdef CONFIG_MV643XX_ETH +extern unsigned char prom_mac_addr_base[6]; +#endif const char *get_system_type(void) { @@ -40,6 +44,55 @@ const char *get_system_type(void) #endif } +#ifdef CONFIG_MV643XX_ETH +static void burn_clocks(void) +{ + int i; + + /* this loop should burn at least 1us -- this should be plenty */ + for (i = 0; i < 0x10000; i++) + ; +} + +static u8 exchange_bit(u8 val, u8 cs) +{ + /* place the data */ + OCELOT_FPGA_WRITE((val << 2) | cs, EEPROM_MODE); + burn_clocks(); + + /* turn the clock on */ + OCELOT_FPGA_WRITE((val << 2) | cs | 0x2, EEPROM_MODE); + burn_clocks(); + + /* turn the clock off and read-strobe */ + OCELOT_FPGA_WRITE((val << 2) | cs | 0x10, EEPROM_MODE); + + /* return the data */ + return ((OCELOT_FPGA_READ(EEPROM_MODE) >> 3) & 0x1); +} + +void get_mac(char dest[6]) +{ + u8 read_opcode[12] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + int i,j; + + for (i = 0; i < 12; i++) + exchange_bit(read_opcode[i], 1); + + for (j = 0; j < 6; j++) { + dest[j] = 0; + for (i = 0; i < 8; i++) { + dest[j] <<= 1; + dest[j] |= exchange_bit(0, 1); + } + } + + /* turn off CS */ + exchange_bit(0,0); +} +#endif + + #ifdef CONFIG_64BIT unsigned long signext(unsigned long addr) @@ -173,6 +226,11 @@ void __init prom_init(void) mips_machgroup = MACH_GROUP_MOMENCO; mips_machtype = MACH_MOMENCO_OCELOT_C; +#ifdef CONFIG_MV643XX_ETH + /* get the base MAC address for on-board ethernet ports */ + get_mac(prom_mac_addr_base); +#endif + #ifndef CONFIG_64BIT debug_vectors->printf("Booting Linux kernel...\n"); #endif diff --git a/trunk/arch/mips/momentum/ocelot_c/setup.c b/trunk/arch/mips/momentum/ocelot_c/setup.c index 0b6b2338cfb4..36f570ecc6fb 100644 --- a/trunk/arch/mips/momentum/ocelot_c/setup.c +++ b/trunk/arch/mips/momentum/ocelot_c/setup.c @@ -62,6 +62,7 @@ #include #include #include +#include #include #include #include @@ -69,7 +70,8 @@ #include "ocelot_c_fpga.h" unsigned long marvell_base; -unsigned int cpu_clock; +extern unsigned long mv64340_sram_base; +unsigned long cpu_clock; /* These functions are used for rebooting or halting the machine*/ extern void momenco_ocelot_restart(char *command); @@ -118,6 +120,7 @@ void PMON_v2_setup(void) add_wired_entry(ENTRYLO(0xfe000000), ENTRYLO(0xff000000), 0xfffffffffe000000, PM_16M); marvell_base = 0xfffffffff4000000; + mv64340_sram_base = 0xfffffffffe000000; #else /* marvell and extra space */ add_wired_entry(ENTRYLO(0xf4000000), ENTRYLO(0xf4010000), 0xf4000000, PM_64K); @@ -127,6 +130,7 @@ void PMON_v2_setup(void) add_wired_entry(ENTRYLO(0xfe000000), ENTRYLO(0xff000000), 0xfe000000, PM_16M); marvell_base = 0xf4000000; + mv64340_sram_base = 0xfe000000; #endif } @@ -343,20 +347,22 @@ void __init plat_mem_setup(void) } } -/* - * This needs to be one of the first initcalls, because no I/O port access - * can work before this - */ +#ifndef CONFIG_64BIT +/* This needs to be one of the first initcalls, because no I/O port access + can work before this */ static int io_base_ioremap(void) { - void __iomem * io_remap_range = ioremap(0xc0000000UL, 0x10000); + /* we're mapping PCI accesses from 0xc0000000 to 0xf0000000 */ + void *io_remap_range = ioremap(0xc0000000, 0x30000000); - if (!io_remap_range) + if (!io_remap_range) { panic("Could not ioremap I/O port range"); - - set_io_port_base((unsigned long) io_remap_range); + } + printk("io_remap_range set at 0x%08x\n", (uint32_t)io_remap_range); + set_io_port_base(io_remap_range - 0xc0000000); return 0; } module_init(io_base_ioremap); +#endif diff --git a/trunk/arch/mips/momentum/ocelot_c/uart-irq.c b/trunk/arch/mips/momentum/ocelot_c/uart-irq.c index 0029f0008dea..9f33d8f1d826 100644 --- a/trunk/arch/mips/momentum/ocelot_c/uart-irq.c +++ b/trunk/arch/mips/momentum/ocelot_c/uart-irq.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -59,6 +60,39 @@ static inline void unmask_uart_irq(unsigned int irq) value = OCELOT_FPGA_READ(UART_INTMASK); } +/* + * Enables the IRQ in the FPGA + */ +static void enable_uart_irq(unsigned int irq) +{ + unmask_uart_irq(irq); +} + +/* + * Initialize the IRQ in the FPGA + */ +static unsigned int startup_uart_irq(unsigned int irq) +{ + unmask_uart_irq(irq); + return 0; +} + +/* + * Disables the IRQ in the FPGA + */ +static void disable_uart_irq(unsigned int irq) +{ + mask_uart_irq(irq); +} + +/* + * Masks and ACKs an IRQ + */ +static void mask_and_ack_uart_irq(unsigned int irq) +{ + mask_uart_irq(irq); +} + /* * End IRQ processing */ @@ -71,7 +105,7 @@ static void end_uart_irq(unsigned int irq) /* * Interrupt handler for interrupts coming from the FPGA chip. */ -void ll_uart_irq(void) +void ll_uart_irq(struct pt_regs *regs) { unsigned int irq_src, irq_mask; @@ -82,20 +116,31 @@ void ll_uart_irq(void) /* mask for just the interrupts we want */ irq_src &= ~irq_mask; - do_IRQ(ls1bit8(irq_src) + 74); + do_IRQ(ls1bit8(irq_src) + 74, regs); } +#define shutdown_uart_irq disable_uart_irq + struct irq_chip uart_irq_type = { .typename = "UART/FPGA", - .ack = mask_uart_irq, - .mask = mask_uart_irq, - .mask_ack = mask_uart_irq, - .unmask = unmask_uart_irq, + .startup = startup_uart_irq, + .shutdown = shutdown_uart_irq, + .enable = enable_uart_irq, + .disable = disable_uart_irq, + .ack = mask_and_ack_uart_irq, .end = end_uart_irq, }; void uart_irq_init(void) { - set_irq_chip_and_handler(80, &uart_irq_type, handle_level_irq); - set_irq_chip_and_handler(81, &uart_irq_type, handle_level_irq); + /* Reset irq handlers pointers to NULL */ + irq_desc[80].status = IRQ_DISABLED; + irq_desc[80].action = 0; + irq_desc[80].depth = 2; + irq_desc[80].chip = &uart_irq_type; + + irq_desc[81].status = IRQ_DISABLED; + irq_desc[81].action = 0; + irq_desc[81].depth = 2; + irq_desc[81].chip = &uart_irq_type; } diff --git a/trunk/arch/mips/momentum/ocelot_g/gt-irq.c b/trunk/arch/mips/momentum/ocelot_g/gt-irq.c index e5576bd50fa9..6cd87cf0195a 100644 --- a/trunk/arch/mips/momentum/ocelot_g/gt-irq.c +++ b/trunk/arch/mips/momentum/ocelot_g/gt-irq.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -27,7 +28,7 @@ unsigned long bus_clock; * be handled and ack'ed differently than other MIPS interrupts. */ -#if 0 +#if CURRENTLY_UNUSED struct tq_struct irq_handlers[MAX_CAUSE_REGS][MAX_CAUSE_REG_WIDTH]; void hook_irq_handler(int int_cause, int bit_num, void *isr_ptr); @@ -95,7 +96,7 @@ int disable_galileo_irq(int int_cause, int bit_num) return 0; return 1; } -#endif /* 0 */ +#endif /* UNUSED */ /* * Interrupt handler for interrupts coming from the Galileo chip via P0_INT#. @@ -107,7 +108,7 @@ int disable_galileo_irq(int int_cause, int bit_num) * we keep this particular structure in the function. */ -static irqreturn_t gt64240_p0int_irq(int irq, void *dev) +static irqreturn_t gt64240_p0int_irq(int irq, void *dev, struct pt_regs *regs) { uint32_t irq_src, irq_src_mask; int handled; @@ -134,7 +135,7 @@ static irqreturn_t gt64240_p0int_irq(int irq, void *dev) /* handle the timer call */ do_timer(1); #ifndef CONFIG_SMP - update_process_times(user_mode(get_irq_regs())); + update_process_times(user_mode(regs)); #endif } @@ -196,7 +197,7 @@ void gt64240_time_init(void) void gt64240_irq_init(void) { -#if 0 +#if CURRENTLY_UNUSED int i, j; /* Reset irq handlers pointers to NULL */ @@ -208,5 +209,5 @@ void gt64240_irq_init(void) irq_handlers[i][j].data = NULL; } } -#endif /* 0 */ +#endif } diff --git a/trunk/arch/mips/momentum/ocelot_g/irq.c b/trunk/arch/mips/momentum/ocelot_g/irq.c index da46524e87cb..7a4a419804f1 100644 --- a/trunk/arch/mips/momentum/ocelot_g/irq.c +++ b/trunk/arch/mips/momentum/ocelot_g/irq.c @@ -48,22 +48,22 @@ #include #include -asmlinkage void plat_irq_dispatch(void) +asmlinkage void plat_irq_dispatch(struct pt_regs *regs) { unsigned int pending = read_c0_cause() & read_c0_status(); if (pending & STATUSF_IP2) - do_IRQ(2); + do_IRQ(2, regs); else if (pending & STATUSF_IP3) - do_IRQ(3); + do_IRQ(3, regs); else if (pending & STATUSF_IP4) - do_IRQ(4); + do_IRQ(4, regs); else if (pending & STATUSF_IP5) - do_IRQ(5); + do_IRQ(5, regs); else if (pending & STATUSF_IP6) - do_IRQ(6); + do_IRQ(6, regs); else if (pending & STATUSF_IP7) - do_IRQ(7); + do_IRQ(7, regs); else { /* * Now look at the extended interrupts @@ -71,15 +71,15 @@ asmlinkage void plat_irq_dispatch(void) pending = (read_c0_cause() & (read_c0_intcontrol() << 8)) >> 16; if (pending & STATUSF_IP8) - do_IRQ(8); + do_IRQ(8, regs); else if (pending & STATUSF_IP9) - do_IRQ(9); + do_IRQ(9, regs); else if (pending & STATUSF_IP10) - do_IRQ(10); + do_IRQ(10, regs); else if (pending & STATUSF_IP11) - do_IRQ(11); + do_IRQ(11, regs); else - spurious_interrupt(); + spurious_interrupt(regs); } } diff --git a/trunk/arch/mips/momentum/ocelot_g/ocelot_pld.h b/trunk/arch/mips/momentum/ocelot_g/ocelot_pld.h index 95e0534026d0..fcb8275e219d 100644 --- a/trunk/arch/mips/momentum/ocelot_g/ocelot_pld.h +++ b/trunk/arch/mips/momentum/ocelot_g/ocelot_pld.h @@ -23,8 +23,8 @@ #define OCELOT_REG_INTSET (12) #define OCELOT_REG_INTCLR (13) -#define __PLD_REG_TO_ADDR(reg) ((void *) OCELOT_CS0_ADDR + OCELOT_REG_##reg) -#define OCELOT_PLD_WRITE(x, reg) writeb(x, __PLD_REG_TO_ADDR(reg)) -#define OCELOT_PLD_READ(reg) readb(__PLD_REG_TO_ADDR(reg)) +#define OCELOT_PLD_WRITE(x, y) writeb(x, OCELOT_CS0_ADDR + OCELOT_REG_##y) +#define OCELOT_PLD_READ(x) readb(OCELOT_CS0_ADDR + OCELOT_REG_##x) + #endif /* __MOMENCO_OCELOT_PLD_H__ */ diff --git a/trunk/arch/mips/momentum/ocelot_g/setup.c b/trunk/arch/mips/momentum/ocelot_g/setup.c index d288f7b01842..c580b1de33bc 100644 --- a/trunk/arch/mips/momentum/ocelot_g/setup.c +++ b/trunk/arch/mips/momentum/ocelot_g/setup.c @@ -57,8 +57,8 @@ #include #include #include -#include #include +#include #include #include @@ -161,10 +161,6 @@ static void __init setup_l3cache(unsigned long size) printk("Done\n"); } -void __init plat_timer_setup(struct irqaction *irq) -{ -} - void __init plat_mem_setup(void) { void (*l3func)(unsigned long) = (void *) KSEG1ADDR(setup_l3cache); diff --git a/trunk/arch/mips/oprofile/Makefile b/trunk/arch/mips/oprofile/Makefile index bf3be6fcf7ff..0a50aad5bbe4 100644 --- a/trunk/arch/mips/oprofile/Makefile +++ b/trunk/arch/mips/oprofile/Makefile @@ -12,6 +12,5 @@ oprofile-y := $(DRIVER_OBJS) common.o oprofile-$(CONFIG_CPU_MIPS32) += op_model_mipsxx.o oprofile-$(CONFIG_CPU_MIPS64) += op_model_mipsxx.o -oprofile-$(CONFIG_CPU_R10000) += op_model_mipsxx.o oprofile-$(CONFIG_CPU_SB1) += op_model_mipsxx.o oprofile-$(CONFIG_CPU_RM9000) += op_model_rm9000.o diff --git a/trunk/arch/mips/oprofile/common.c b/trunk/arch/mips/oprofile/common.c index 4e0a90b3916b..65eb55400d77 100644 --- a/trunk/arch/mips/oprofile/common.c +++ b/trunk/arch/mips/oprofile/common.c @@ -83,9 +83,6 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) case CPU_74K: case CPU_SB1: case CPU_SB1A: - case CPU_R10000: - case CPU_R12000: - case CPU_R14000: lmodel = &op_model_mipsxx_ops; break; diff --git a/trunk/arch/mips/oprofile/op_impl.h b/trunk/arch/mips/oprofile/op_impl.h index fa6b4aae7523..5cfce7d87a4d 100644 --- a/trunk/arch/mips/oprofile/op_impl.h +++ b/trunk/arch/mips/oprofile/op_impl.h @@ -10,8 +10,10 @@ #ifndef OP_IMPL_H #define OP_IMPL_H 1 -extern int null_perf_irq(void); -extern int (*perf_irq)(void); +struct pt_regs; + +extern int null_perf_irq(struct pt_regs *regs); +extern int (*perf_irq)(struct pt_regs *regs); /* Per-counter configuration as set via oprofilefs. */ struct op_counter_config { diff --git a/trunk/arch/mips/oprofile/op_model_mipsxx.c b/trunk/arch/mips/oprofile/op_model_mipsxx.c index 455d76ad06d8..a175d673540f 100644 --- a/trunk/arch/mips/oprofile/op_model_mipsxx.c +++ b/trunk/arch/mips/oprofile/op_model_mipsxx.c @@ -3,13 +3,12 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2004, 05, 06 by Ralf Baechle + * Copyright (C) 2004, 2005 by Ralf Baechle * Copyright (C) 2005 by MIPS Technologies, Inc. */ #include #include #include -#include #include "op_impl.h" @@ -18,7 +17,7 @@ #define M_PERFCTL_SUPERVISOR (1UL << 2) #define M_PERFCTL_USER (1UL << 3) #define M_PERFCTL_INTERRUPT_ENABLE (1UL << 4) -#define M_PERFCTL_EVENT(event) (((event) & 0x3f) << 5) +#define M_PERFCTL_EVENT(event) ((event) << 5) #define M_PERFCTL_VPEID(vpe) ((vpe) << 16) #define M_PERFCTL_MT_EN(filter) ((filter) << 20) #define M_TC_EN_ALL M_PERFCTL_MT_EN(0) @@ -31,18 +30,16 @@ #define M_COUNTER_OVERFLOW (1UL << 31) #ifdef CONFIG_MIPS_MT_SMP -#define WHAT (M_TC_EN_VPE | M_PERFCTL_VPEID(smp_processor_id())) -#define vpe_id() smp_processor_id() +#define WHAT (M_TC_EN_VPE | M_PERFCTL_VPEID(smp_processor_id())) #else -#define WHAT 0 -#define vpe_id() smp_processor_id() +#define WHAT 0 #endif #define __define_perf_accessors(r, n, np) \ \ static inline unsigned int r_c0_ ## r ## n(void) \ { \ - unsigned int cpu = vpe_id(); \ + unsigned int cpu = smp_processor_id(); \ \ switch (cpu) { \ case 0: \ @@ -57,7 +54,7 @@ static inline unsigned int r_c0_ ## r ## n(void) \ \ static inline void w_c0_ ## r ## n(unsigned int value) \ { \ - unsigned int cpu = vpe_id(); \ + unsigned int cpu = smp_processor_id(); \ \ switch (cpu) { \ case 0: \ @@ -173,7 +170,7 @@ static void mipsxx_cpu_stop(void *args) } } -static int mipsxx_perfcount_handler(void) +static int mipsxx_perfcount_handler(struct pt_regs *regs) { unsigned int counters = op_model_mipsxx_ops.num_counters; unsigned int control; @@ -187,7 +184,7 @@ static int mipsxx_perfcount_handler(void) counter = r_c0_perfcntr ## n(); \ if ((control & M_PERFCTL_INTERRUPT_ENABLE) && \ (counter & M_COUNTER_OVERFLOW)) { \ - oprofile_add_sample(get_irq_regs(), n); \ + oprofile_add_sample(regs, n); \ w_c0_perfcntr ## n(reg.counter[n]); \ handled = 1; \ } @@ -218,23 +215,13 @@ static inline int __n_counters(void) static inline int n_counters(void) { - int counters; - - switch (current_cpu_data.cputype) { - case CPU_R10000: - counters = 2; - - case CPU_R12000: - case CPU_R14000: - counters = 4; - - default: - counters = __n_counters(); - } + int counters = __n_counters(); -#ifdef CONFIG_MIPS_MT_SMP - counters >> 1; +#ifndef CONFIG_SMP + if (current_cpu_data.cputype == CPU_34K) + return counters >> 1; #endif + return counters; } @@ -294,18 +281,6 @@ static int __init mipsxx_init(void) op_model_mipsxx_ops.cpu_type = "mips/5K"; break; - case CPU_R10000: - if ((current_cpu_data.processor_id & 0xff) == 0x20) - op_model_mipsxx_ops.cpu_type = "mips/r10000-v2.x"; - else - op_model_mipsxx_ops.cpu_type = "mips/r10000"; - break; - - case CPU_R12000: - case CPU_R14000: - op_model_mipsxx_ops.cpu_type = "mips/r12000"; - break; - case CPU_SB1: case CPU_SB1A: op_model_mipsxx_ops.cpu_type = "mips/sb1"; diff --git a/trunk/arch/mips/oprofile/op_model_rm9000.c b/trunk/arch/mips/oprofile/op_model_rm9000.c index 7dc9bf6f1321..b7063fefa65b 100644 --- a/trunk/arch/mips/oprofile/op_model_rm9000.c +++ b/trunk/arch/mips/oprofile/op_model_rm9000.c @@ -80,7 +80,8 @@ static void rm9000_cpu_stop(void *args) write_c0_perfcontrol(0); } -static irqreturn_t rm9000_perfcount_handler(int irq, void * dev_id) +static irqreturn_t rm9000_perfcount_handler(int irq, void * dev_id, + struct pt_regs *regs) { unsigned int control = read_c0_perfcontrol(); uint32_t counter1, counter2; diff --git a/trunk/arch/mips/pci/Makefile b/trunk/arch/mips/pci/Makefile index 70cb55b89df6..3cf0dd4ba548 100644 --- a/trunk/arch/mips/pci/Makefile +++ b/trunk/arch/mips/pci/Makefile @@ -26,7 +26,7 @@ obj-$(CONFIG_DDB5477) += fixup-ddb5477.o pci-ddb5477.o ops-ddb5477.o obj-$(CONFIG_LASAT) += pci-lasat.o obj-$(CONFIG_MIPS_ATLAS) += fixup-atlas.o obj-$(CONFIG_MIPS_COBALT) += fixup-cobalt.o -obj-$(CONFIG_MIPS_EV64120) += pci-ev64120.o +obj-$(CONFIG_MIPS_EV64120) += fixup-ev64120.o obj-$(CONFIG_SOC_AU1500) += fixup-au1000.o ops-au1000.o obj-$(CONFIG_SOC_AU1550) += fixup-au1000.o ops-au1000.o obj-$(CONFIG_SOC_PNX8550) += fixup-pnx8550.o ops-pnx8550.o diff --git a/trunk/arch/mips/pci/fixup-cobalt.c b/trunk/arch/mips/pci/fixup-cobalt.c index 7d5f6bbf7a9d..75a01e764898 100644 --- a/trunk/arch/mips/pci/fixup-cobalt.c +++ b/trunk/arch/mips/pci/fixup-cobalt.c @@ -94,21 +94,22 @@ static void qube_raq_galileo_fixup(struct pci_dev *dev) #if 0 if (galileo_id >= 0x10) { /* New Galileo, assumes PCI stop line to VIA is connected. */ - GT_WRITE(GT_PCI0_TOR_OFS, 0x4020); + GALILEO_OUTL(0x4020, GT_PCI0_TOR_OFS); } else if (galileo_id == 0x1 || galileo_id == 0x2) #endif { signed int timeo; /* XXX WE MUST DO THIS ELSE GALILEO LOCKS UP! -DaveM */ - timeo = GT_READ(GT_PCI0_TOR_OFS); + timeo = GALILEO_INL(GT_PCI0_TOR_OFS); /* Old Galileo, assumes PCI STOP line to VIA is disconnected. */ - GT_WRITE(GT_PCI0_TOR_OFS, + GALILEO_OUTL( (0xff << 16) | /* retry count */ (0xff << 8) | /* timeout 1 */ - 0xff); /* timeout 0 */ + 0xff, /* timeout 0 */ + GT_PCI0_TOR_OFS); /* enable PCI retry exceeded interrupt */ - GT_WRITE(GT_INTRMASK_OFS, GT_INTR_RETRYCTR0_MSK | GT_READ(GT_INTRMASK_OFS)); + GALILEO_OUTL(GALILEO_INTR_RETRY_CTR | GALILEO_INL(GT_INTRMASK_OFS), GT_INTRMASK_OFS); } } diff --git a/trunk/arch/mips/pci/fixup-ev64120.c b/trunk/arch/mips/pci/fixup-ev64120.c new file mode 100644 index 000000000000..8dbb90d63f0a --- /dev/null +++ b/trunk/arch/mips/pci/fixup-ev64120.c @@ -0,0 +1,34 @@ +#include +#include + +int pci_range_ck(unsigned char bus, unsigned char dev) +{ + if (((bus == 0) || (bus == 1)) && (dev >= 6) && (dev <= 8)) + return 0; + + return -1; +} + +/* + * After detecting all agents over the PCI , this function is called + * in order to give an interrupt number for each PCI device starting + * from IRQ 20. It does also enables master for each device. + */ +void __devinit pcibios_fixup_bus(struct pci_bus *bus) +{ + unsigned int irq = 20; + struct pci_bus *current_bus = bus; + struct pci_dev *dev; + struct list_head *devices_link; + + list_for_each(devices_link, &(current_bus->devices)) { + dev = pci_dev_b(devices_link); + if (dev != NULL) { + dev->irq = irq++; + + /* Assign an interrupt number for the device */ + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); + pcibios_set_master(dev); + } + } +} diff --git a/trunk/arch/mips/pci/ops-gt64111.c b/trunk/arch/mips/pci/ops-gt64111.c index ecd3991bd0e4..13de45940b19 100644 --- a/trunk/arch/mips/pci/ops-gt64111.c +++ b/trunk/arch/mips/pci/ops-gt64111.c @@ -38,18 +38,18 @@ static int gt64111_pci_read_config(struct pci_bus *bus, unsigned int devfn, switch (size) { case 4: PCI_CFG_SET(devfn, where); - *val = GT_READ(GT_PCI0_CFGDATA_OFS); + *val = GALILEO_INL(GT_PCI0_CFGDATA_OFS); return PCIBIOS_SUCCESSFUL; case 2: PCI_CFG_SET(devfn, (where & ~0x3)); - *val = GT_READ(GT_PCI0_CFGDATA_OFS) + *val = GALILEO_INL(GT_PCI0_CFGDATA_OFS) >> ((where & 3) * 8); return PCIBIOS_SUCCESSFUL; case 1: PCI_CFG_SET(devfn, (where & ~0x3)); - *val = GT_READ(GT_PCI0_CFGDATA_OFS) + *val = GALILEO_INL(GT_PCI0_CFGDATA_OFS) >> ((where & 3) * 8); return PCIBIOS_SUCCESSFUL; } @@ -68,25 +68,25 @@ static int gt64111_pci_write_config(struct pci_bus *bus, unsigned int devfn, switch (size) { case 4: PCI_CFG_SET(devfn, where); - GT_WRITE(GT_PCI0_CFGDATA_OFS, val); + GALILEO_OUTL(val, GT_PCI0_CFGDATA_OFS); return PCIBIOS_SUCCESSFUL; case 2: PCI_CFG_SET(devfn, (where & ~0x3)); - tmp = GT_READ(GT_PCI0_CFGDATA_OFS); + tmp = GALILEO_INL(GT_PCI0_CFGDATA_OFS); tmp &= ~(0xffff << ((where & 0x3) * 8)); tmp |= (val << ((where & 0x3) * 8)); - GT_WRITE(GT_PCI0_CFGDATA_OFS, tmp); + GALILEO_OUTL(tmp, GT_PCI0_CFGDATA_OFS); return PCIBIOS_SUCCESSFUL; case 1: PCI_CFG_SET(devfn, (where & ~0x3)); - tmp = GT_READ(GT_PCI0_CFGDATA_OFS); + tmp = GALILEO_INL(GT_PCI0_CFGDATA_OFS); tmp &= ~(0xff << ((where & 0x3) * 8)); tmp |= (val << ((where & 0x3) * 8)); - GT_WRITE(GT_PCI0_CFGDATA_OFS, tmp); + GALILEO_OUTL(tmp, GT_PCI0_CFGDATA_OFS); return PCIBIOS_SUCCESSFUL; } diff --git a/trunk/arch/mips/pci/pci-ev64120.c b/trunk/arch/mips/pci/pci-ev64120.c deleted file mode 100644 index 9cd859ef1842..000000000000 --- a/trunk/arch/mips/pci/pci-ev64120.c +++ /dev/null @@ -1,21 +0,0 @@ -#include - -int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) -{ - int irq; - - if (!pin) - return 0; - - irq = allocate_irqno(); - if (irq < 0) - return 0; - - return irq; -} - -/* Do platform specific device initialization at pci_enable_device() time */ -int pcibios_plat_dev_init(struct pci_dev *dev) -{ - return 0; -} diff --git a/trunk/arch/mips/pci/pci-ip32.c b/trunk/arch/mips/pci/pci-ip32.c index 618ea7dbc474..17c7932cf0ae 100644 --- a/trunk/arch/mips/pci/pci-ip32.c +++ b/trunk/arch/mips/pci/pci-ip32.c @@ -22,7 +22,7 @@ * registered on the bridge error irq. It's conceivable that some of these * conditions warrant a panic. Anybody care to say which ones? */ -static irqreturn_t macepci_error(int irq, void *dev) +static irqreturn_t macepci_error(int irq, void *dev, struct pt_regs *regs) { char s; unsigned int flags = mace->pci.error; diff --git a/trunk/arch/mips/philips/pnx8550/common/int.c b/trunk/arch/mips/philips/pnx8550/common/int.c index 0dc23930edbd..3c93512be1ec 100644 --- a/trunk/arch/mips/philips/pnx8550/common/int.c +++ b/trunk/arch/mips/philips/pnx8550/common/int.c @@ -23,7 +23,6 @@ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. * */ -#include #include #include #include @@ -38,6 +37,8 @@ #include #include +static DEFINE_SPINLOCK(irq_lock); + /* default prio for interrupts */ /* first one is a no-no so therefore always prio 0 (disabled) */ static char gic_prio[PNX8550_INT_GIC_TOTINT] = { @@ -51,7 +52,7 @@ static char gic_prio[PNX8550_INT_GIC_TOTINT] = { 1 // 70 }; -static void hw0_irqdispatch(int irq) +static void hw0_irqdispatch(int irq, struct pt_regs *regs) { /* find out which interrupt */ irq = PNX8550_GIC_VECTOR_0 >> 3; @@ -60,39 +61,42 @@ static void hw0_irqdispatch(int irq) printk("hw0_irqdispatch: irq 0, spurious interrupt?\n"); return; } - do_IRQ(PNX8550_INT_GIC_MIN + irq); + do_IRQ(PNX8550_INT_GIC_MIN + irq, regs); } -static void timer_irqdispatch(int irq) +static void timer_irqdispatch(int irq, struct pt_regs *regs) { irq = (0x01c0 & read_c0_config7()) >> 6; - if (unlikely(irq == 0)) { + if (irq == 0) { printk("timer_irqdispatch: irq 0, spurious interrupt?\n"); return; } - if (irq & 0x1) - do_IRQ(PNX8550_INT_TIMER1); - if (irq & 0x2) - do_IRQ(PNX8550_INT_TIMER2); - if (irq & 0x4) - do_IRQ(PNX8550_INT_TIMER3); + if (irq & 0x1) { + do_IRQ(PNX8550_INT_TIMER1, regs); + } + if (irq & 0x2) { + do_IRQ(PNX8550_INT_TIMER2, regs); + } + if (irq & 0x4) { + do_IRQ(PNX8550_INT_TIMER3, regs); + } } -asmlinkage void plat_irq_dispatch(void) +asmlinkage void plat_irq_dispatch(struct pt_regs *regs) { unsigned int pending = read_c0_status() & read_c0_cause(); if (pending & STATUSF_IP2) - hw0_irqdispatch(2); + hw0_irqdispatch(2, regs); else if (pending & STATUSF_IP7) { if (read_c0_config7() & 0x01c0) - timer_irqdispatch(7); + timer_irqdispatch(7, regs); } - spurious_interrupt(); + spurious_interrupt(regs); } static inline void modify_cp0_intmask(unsigned clr_mask, unsigned set_mask) @@ -147,6 +151,38 @@ static inline void unmask_irq(unsigned int irq_nr) } } +#define pnx8550_disable pnx8550_ack +static void pnx8550_ack(unsigned int irq) +{ + unsigned long flags; + + spin_lock_irqsave(&irq_lock, flags); + mask_irq(irq); + spin_unlock_irqrestore(&irq_lock, flags); +} + +#define pnx8550_enable pnx8550_unmask +static void pnx8550_unmask(unsigned int irq) +{ + unsigned long flags; + + spin_lock_irqsave(&irq_lock, flags); + unmask_irq(irq); + spin_unlock_irqrestore(&irq_lock, flags); +} + +static unsigned int startup_irq(unsigned int irq_nr) +{ + pnx8550_unmask(irq_nr); + return 0; +} + +static void shutdown_irq(unsigned int irq_nr) +{ + pnx8550_ack(irq_nr); + return; +} + int pnx8550_set_gic_priority(int irq, int priority) { int gic_irq = irq-PNX8550_INT_GIC_MIN; @@ -158,19 +194,26 @@ int pnx8550_set_gic_priority(int irq, int priority) return prev_priority; } +static inline void mask_and_ack_level_irq(unsigned int irq) +{ + pnx8550_disable(irq); + return; +} + static void end_irq(unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) { - unmask_irq(irq); + pnx8550_enable(irq); } } static struct irq_chip level_irq_type = { .typename = "PNX Level IRQ", - .ack = mask_irq, - .mask = mask_irq, - .mask_ack = mask_irq, - .unmask = unmask_irq, + .startup = startup_irq, + .shutdown = shutdown_irq, + .enable = pnx8550_enable, + .disable = pnx8550_disable, + .ack = mask_and_ack_level_irq, .end = end_irq, }; @@ -192,8 +235,8 @@ void __init arch_init_irq(void) int configPR; for (i = 0; i < PNX8550_INT_CP0_TOTINT; i++) { - set_irq_chip_and_handler(i, &level_irq_type, handle_level_irq); - mask_irq(i); /* mask the irq just in case */ + irq_desc[i].chip = &level_irq_type; + pnx8550_ack(i); /* mask the irq just in case */ } /* init of GIC/IPC interrupts */ @@ -229,7 +272,7 @@ void __init arch_init_irq(void) /* mask/priority is still 0 so we will not get any * interrupts until it is unmasked */ - set_irq_chip_and_handler(i, &level_irq_type, handle_level_irq); + irq_desc[i].chip = &level_irq_type; } /* Priority level 0 */ @@ -238,21 +281,20 @@ void __init arch_init_irq(void) /* Set int vector table address */ PNX8550_GIC_VECTOR_0 = PNX8550_GIC_VECTOR_1 = 0; - set_irq_chip_and_handler(MIPS_CPU_GIC_IRQ, &level_irq_type, - handle_level_irq); + irq_desc[MIPS_CPU_GIC_IRQ].chip = &level_irq_type; setup_irq(MIPS_CPU_GIC_IRQ, &gic_action); /* init of Timer interrupts */ - for (i = PNX8550_INT_TIMER_MIN; i <= PNX8550_INT_TIMER_MAX; i++) - set_irq_chip_and_handler(i, &level_irq_type, handle_level_irq); + for (i = PNX8550_INT_TIMER_MIN; i <= PNX8550_INT_TIMER_MAX; i++) { + irq_desc[i].chip = &level_irq_type; + } /* Stop Timer 1-3 */ configPR = read_c0_config7(); configPR |= 0x00000038; write_c0_config7(configPR); - set_irq_chip_and_handler(MIPS_CPU_TIMER_IRQ, &level_irq_type, - handle_level_irq); + irq_desc[MIPS_CPU_TIMER_IRQ].chip = &level_irq_type; setup_irq(MIPS_CPU_TIMER_IRQ, &timer_action); } diff --git a/trunk/arch/mips/philips/pnx8550/common/time.c b/trunk/arch/mips/philips/pnx8550/common/time.c index 65c440e8480b..0af655b1f330 100644 --- a/trunk/arch/mips/philips/pnx8550/common/time.c +++ b/trunk/arch/mips/philips/pnx8550/common/time.c @@ -41,8 +41,8 @@ extern unsigned int mips_hpt_frequency; * 1) board_time_init() - * a) (optional) set up RTC routines, * b) (optional) calibrate and set the mips_hpt_frequency - * (only needed if you intended to use cpu counter as timer interrupt - * source) + * (only needed if you intended to use fixed_rate_gettimeoffset + * or use cpu counter as timer interrupt source) */ void pnx8550_time_init(void) diff --git a/trunk/arch/mips/pmc-sierra/yosemite/i2c-yosemite.c b/trunk/arch/mips/pmc-sierra/yosemite/i2c-yosemite.c index 85b14c73c226..416da22b3bf4 100644 --- a/trunk/arch/mips/pmc-sierra/yosemite/i2c-yosemite.c +++ b/trunk/arch/mips/pmc-sierra/yosemite/i2c-yosemite.c @@ -74,7 +74,7 @@ static int titan_i2c_poll(void) int titan_i2c_xfer(unsigned int slave_addr, titan_i2c_command * cmd, int size, unsigned int *addr) { - int loop, bytes = 0, i; + int loop = 0, bytes, i; unsigned int *write_data, data, *read_data; unsigned long reg_val, val; diff --git a/trunk/arch/mips/pmc-sierra/yosemite/irq.c b/trunk/arch/mips/pmc-sierra/yosemite/irq.c index adb048527e76..b91d0aa3b7ed 100644 --- a/trunk/arch/mips/pmc-sierra/yosemite/irq.c +++ b/trunk/arch/mips/pmc-sierra/yosemite/irq.c @@ -56,13 +56,15 @@ #define HYPERTRANSPORT_INTC 0x7a /* INTC# */ #define HYPERTRANSPORT_INTD 0x7b /* INTD# */ +extern void jaguar_mailbox_irq(struct pt_regs *); + /* * Handle hypertransport & SMP interrupts. The interrupt lines are scarce. * For interprocessor interrupts, the best thing to do is to use the INTMSG * register. We use the same external interrupt line, i.e. INTB3 and monitor * another status bit */ -static void ll_ht_smp_irq_handler(int irq) +asmlinkage void ll_ht_smp_irq_handler(int irq, struct pt_regs *regs) { u32 status = OCD_READ(RM9000x2_OCD_INTP0STATUS4); @@ -105,35 +107,50 @@ static void ll_ht_smp_irq_handler(int irq) } #endif /* CONFIG_HT_LEVEL_TRIGGER */ - do_IRQ(irq); + do_IRQ(irq, regs); +} + +asmlinkage void do_extended_irq(struct pt_regs *regs) +{ + unsigned int intcontrol = read_c0_intcontrol(); + unsigned int cause = read_c0_cause(); + unsigned int status = read_c0_status(); + unsigned int pending_sr, pending_ic; + + pending_sr = status & cause & 0xff00; + pending_ic = (cause >> 8) & intcontrol & 0xff00; + + if (pending_ic & (1 << 13)) + do_IRQ(13, regs); + } -asmlinkage void plat_irq_dispatch(void) +asmlinkage void plat_irq_dispatch(struct pt_regs *regs) { unsigned int cause = read_c0_cause(); unsigned int status = read_c0_status(); unsigned int pending = cause & status; if (pending & STATUSF_IP7) { - do_IRQ(7); + do_IRQ(7, regs); } else if (pending & STATUSF_IP2) { #ifdef CONFIG_HYPERTRANSPORT - ll_ht_smp_irq_handler(2); + ll_ht_smp_irq_handler(2, regs); #else - do_IRQ(2); + do_IRQ(2, regs); #endif } else if (pending & STATUSF_IP3) { - do_IRQ(3); + do_IRQ(3, regs); } else if (pending & STATUSF_IP4) { - do_IRQ(4); + do_IRQ(4, regs); } else if (pending & STATUSF_IP5) { #ifdef CONFIG_SMP - titan_mailbox_irq(); + titan_mailbox_irq(regs); #else - do_IRQ(5); + do_IRQ(5, regs); #endif } else if (pending & STATUSF_IP6) { - do_IRQ(4); + do_IRQ(4, regs); } } @@ -161,3 +178,18 @@ void __init arch_init_irq(void) register_gdb_console(); #endif } + +#ifdef CONFIG_KGDB +/* + * The 16550 DUART has two ports, but is allocated one IRQ + * for the serial console. Hence, a generic framework for + * serial IRQ routing in place. Currently, just calls the + * do_IRQ fuction. But, going in the future, need to check + * DUART registers for channel A and B, then decide the + * appropriate action + */ +asmlinkage void yosemite_kgdb_irq(int irq, struct pt_regs *regs) +{ + do_IRQ(irq, regs); +} +#endif diff --git a/trunk/arch/mips/pmc-sierra/yosemite/setup.c b/trunk/arch/mips/pmc-sierra/yosemite/setup.c index 1b9b0d396d3e..0a6ee8e5eec2 100644 --- a/trunk/arch/mips/pmc-sierra/yosemite/setup.c +++ b/trunk/arch/mips/pmc-sierra/yosemite/setup.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/mips/pmc-sierra/yosemite/smp.c b/trunk/arch/mips/pmc-sierra/yosemite/smp.c index 305491e74dbe..c197311e15d3 100644 --- a/trunk/arch/mips/pmc-sierra/yosemite/smp.c +++ b/trunk/arch/mips/pmc-sierra/yosemite/smp.c @@ -3,7 +3,9 @@ #include #include -#include + +extern unsigned int (*mips_hpt_read)(void); +extern void (*mips_hpt_init)(unsigned int); #define LAUNCHSTACK_SIZE 256 @@ -99,6 +101,8 @@ void prom_cpus_done(void) */ void prom_init_secondary(void) { + mips_hpt_init(mips_hpt_read()); + set_c0_status(ST0_CO | ST0_IE | ST0_IM); } @@ -106,7 +110,7 @@ void prom_smp_finish(void) { } -asmlinkage void titan_mailbox_irq(void) +asmlinkage void titan_mailbox_irq(struct pt_regs *regs) { int cpu = smp_processor_id(); unsigned long status; diff --git a/trunk/arch/mips/qemu/q-irq.c b/trunk/arch/mips/qemu/q-irq.c index f5ea2fe10f14..3352374c4c7d 100644 --- a/trunk/arch/mips/qemu/q-irq.c +++ b/trunk/arch/mips/qemu/q-irq.c @@ -9,19 +9,19 @@ extern asmlinkage void qemu_handle_int(void); -asmlinkage void plat_irq_dispatch(void) +asmlinkage void plat_irq_dispatch(struct pt_regs *regs) { unsigned int pending = read_c0_status() & read_c0_cause(); if (pending & 0x8000) { - ll_timer_interrupt(Q_COUNT_COMPARE_IRQ); + ll_timer_interrupt(Q_COUNT_COMPARE_IRQ, regs); return; } if (pending & 0x0400) { int irq = i8259_irq(); if (likely(irq >= 0)) - do_IRQ(irq); + do_IRQ(irq, regs); return; } diff --git a/trunk/arch/mips/sgi-ip22/ip22-berr.c b/trunk/arch/mips/sgi-ip22/ip22-berr.c index de6a0cc32fea..a28dc7800072 100644 --- a/trunk/arch/mips/sgi-ip22/ip22-berr.c +++ b/trunk/arch/mips/sgi-ip22/ip22-berr.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -86,10 +85,9 @@ static void print_buserr(void) * and then clear the interrupt when this happens. */ -void ip22_be_interrupt(int irq) +void ip22_be_interrupt(int irq, struct pt_regs *regs) { const int field = 2 * sizeof(unsigned long); - const struct pt_regs *regs = get_irq_regs(); save_and_clear_buserr(); print_buserr(); diff --git a/trunk/arch/mips/sgi-ip22/ip22-eisa.c b/trunk/arch/mips/sgi-ip22/ip22-eisa.c index a1a9af6da7bf..ee0514a29922 100644 --- a/trunk/arch/mips/sgi-ip22/ip22-eisa.c +++ b/trunk/arch/mips/sgi-ip22/ip22-eisa.c @@ -70,7 +70,7 @@ static char __init *decode_eisa_sig(unsigned long addr) return sig_str; } -static irqreturn_t ip22_eisa_intr(int irq, void *dev_id) +static irqreturn_t ip22_eisa_intr(int irq, void *dev_id, struct pt_regs *regs) { u8 eisa_irq; u8 dma1, dma2; @@ -80,7 +80,7 @@ static irqreturn_t ip22_eisa_intr(int irq, void *dev_id) dma2 = inb(EISA_DMA2_STATUS); if (eisa_irq < EISA_MAX_IRQ) { - do_IRQ(eisa_irq); + do_IRQ(eisa_irq, regs); return IRQ_HANDLED; } @@ -89,17 +89,21 @@ static irqreturn_t ip22_eisa_intr(int irq, void *dev_id) outb(0x20, EISA_INT2_CTRL); outb(0x20, EISA_INT1_CTRL); - return IRQ_NONE; } static void enable_eisa1_irq(unsigned int irq) { + unsigned long flags; u8 mask; + local_irq_save(flags); + mask = inb(EISA_INT1_MASK); mask &= ~((u8) (1 << irq)); outb(mask, EISA_INT1_MASK); + + local_irq_restore(flags); } static unsigned int startup_eisa1_irq(unsigned int irq) @@ -125,6 +129,8 @@ static void disable_eisa1_irq(unsigned int irq) outb(mask, EISA_INT1_MASK); } +#define shutdown_eisa1_irq disable_eisa1_irq + static void mask_and_ack_eisa1_irq(unsigned int irq) { disable_eisa1_irq(irq); @@ -141,20 +147,25 @@ static void end_eisa1_irq(unsigned int irq) static struct irq_chip ip22_eisa1_irq_type = { .typename = "IP22 EISA", .startup = startup_eisa1_irq, + .shutdown = shutdown_eisa1_irq, + .enable = enable_eisa1_irq, + .disable = disable_eisa1_irq, .ack = mask_and_ack_eisa1_irq, - .mask = disable_eisa1_irq, - .mask_ack = mask_and_ack_eisa1_irq, - .unmask = enable_eisa1_irq, .end = end_eisa1_irq, }; static void enable_eisa2_irq(unsigned int irq) { + unsigned long flags; u8 mask; + local_irq_save(flags); + mask = inb(EISA_INT2_MASK); mask &= ~((u8) (1 << (irq - 8))); outb(mask, EISA_INT2_MASK); + + local_irq_restore(flags); } static unsigned int startup_eisa2_irq(unsigned int irq) @@ -180,6 +191,8 @@ static void disable_eisa2_irq(unsigned int irq) outb(mask, EISA_INT2_MASK); } +#define shutdown_eisa2_irq disable_eisa2_irq + static void mask_and_ack_eisa2_irq(unsigned int irq) { disable_eisa2_irq(irq); @@ -196,10 +209,10 @@ static void end_eisa2_irq(unsigned int irq) static struct irq_chip ip22_eisa2_irq_type = { .typename = "IP22 EISA", .startup = startup_eisa2_irq, + .shutdown = shutdown_eisa2_irq, + .enable = enable_eisa2_irq, + .disable = disable_eisa2_irq, .ack = mask_and_ack_eisa2_irq, - .mask = disable_eisa2_irq, - .mask_ack = mask_and_ack_eisa2_irq, - .unmask = enable_eisa2_irq, .end = end_eisa2_irq, }; @@ -261,10 +274,13 @@ int __init ip22_eisa_init(void) outb(0, EISA_DMA2_WRITE_SINGLE); for (i = SGINT_EISA; i < (SGINT_EISA + EISA_MAX_IRQ); i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 1; if (i < (SGINT_EISA + 8)) - set_irq_chip(i, &ip22_eisa1_irq_type); + irq_desc[i].chip = &ip22_eisa1_irq_type; else - set_irq_chip(i, &ip22_eisa2_irq_type); + irq_desc[i].chip = &ip22_eisa2_irq_type; } /* Cannot use request_irq because of kmalloc not being ready at such diff --git a/trunk/arch/mips/sgi-ip22/ip22-int.c b/trunk/arch/mips/sgi-ip22/ip22-int.c index c7b138053159..f66026e5d64b 100644 --- a/trunk/arch/mips/sgi-ip22/ip22-int.c +++ b/trunk/arch/mips/sgi-ip22/ip22-int.c @@ -40,17 +40,34 @@ extern int ip22_eisa_init(void); static void enable_local0_irq(unsigned int irq) { + unsigned long flags; + + local_irq_save(flags); /* don't allow mappable interrupt to be enabled from setup_irq, * we have our own way to do so */ if (irq != SGI_MAP_0_IRQ) sgint->imask0 |= (1 << (irq - SGINT_LOCAL0)); + local_irq_restore(flags); +} + +static unsigned int startup_local0_irq(unsigned int irq) +{ + enable_local0_irq(irq); + return 0; /* Never anything pending */ } static void disable_local0_irq(unsigned int irq) { + unsigned long flags; + + local_irq_save(flags); sgint->imask0 &= ~(1 << (irq - SGINT_LOCAL0)); + local_irq_restore(flags); } +#define shutdown_local0_irq disable_local0_irq +#define mask_and_ack_local0_irq disable_local0_irq + static void end_local0_irq (unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) @@ -59,26 +76,44 @@ static void end_local0_irq (unsigned int irq) static struct irq_chip ip22_local0_irq_type = { .typename = "IP22 local 0", - .ack = disable_local0_irq, - .mask = disable_local0_irq, - .mask_ack = disable_local0_irq, - .unmask = enable_local0_irq, + .startup = startup_local0_irq, + .shutdown = shutdown_local0_irq, + .enable = enable_local0_irq, + .disable = disable_local0_irq, + .ack = mask_and_ack_local0_irq, .end = end_local0_irq, }; static void enable_local1_irq(unsigned int irq) { + unsigned long flags; + + local_irq_save(flags); /* don't allow mappable interrupt to be enabled from setup_irq, * we have our own way to do so */ if (irq != SGI_MAP_1_IRQ) sgint->imask1 |= (1 << (irq - SGINT_LOCAL1)); + local_irq_restore(flags); +} + +static unsigned int startup_local1_irq(unsigned int irq) +{ + enable_local1_irq(irq); + return 0; /* Never anything pending */ } void disable_local1_irq(unsigned int irq) { + unsigned long flags; + + local_irq_save(flags); sgint->imask1 &= ~(1 << (irq - SGINT_LOCAL1)); + local_irq_restore(flags); } +#define shutdown_local1_irq disable_local1_irq +#define mask_and_ack_local1_irq disable_local1_irq + static void end_local1_irq (unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) @@ -87,26 +122,44 @@ static void end_local1_irq (unsigned int irq) static struct irq_chip ip22_local1_irq_type = { .typename = "IP22 local 1", - .ack = disable_local1_irq, - .mask = disable_local1_irq, - .mask_ack = disable_local1_irq, - .unmask = enable_local1_irq, + .startup = startup_local1_irq, + .shutdown = shutdown_local1_irq, + .enable = enable_local1_irq, + .disable = disable_local1_irq, + .ack = mask_and_ack_local1_irq, .end = end_local1_irq, }; static void enable_local2_irq(unsigned int irq) { + unsigned long flags; + + local_irq_save(flags); sgint->imask0 |= (1 << (SGI_MAP_0_IRQ - SGINT_LOCAL0)); sgint->cmeimask0 |= (1 << (irq - SGINT_LOCAL2)); + local_irq_restore(flags); +} + +static unsigned int startup_local2_irq(unsigned int irq) +{ + enable_local2_irq(irq); + return 0; /* Never anything pending */ } void disable_local2_irq(unsigned int irq) { + unsigned long flags; + + local_irq_save(flags); sgint->cmeimask0 &= ~(1 << (irq - SGINT_LOCAL2)); if (!sgint->cmeimask0) sgint->imask0 &= ~(1 << (SGI_MAP_0_IRQ - SGINT_LOCAL0)); + local_irq_restore(flags); } +#define shutdown_local2_irq disable_local2_irq +#define mask_and_ack_local2_irq disable_local2_irq + static void end_local2_irq (unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) @@ -115,26 +168,44 @@ static void end_local2_irq (unsigned int irq) static struct irq_chip ip22_local2_irq_type = { .typename = "IP22 local 2", - .ack = disable_local2_irq, - .mask = disable_local2_irq, - .mask_ack = disable_local2_irq, - .unmask = enable_local2_irq, + .startup = startup_local2_irq, + .shutdown = shutdown_local2_irq, + .enable = enable_local2_irq, + .disable = disable_local2_irq, + .ack = mask_and_ack_local2_irq, .end = end_local2_irq, }; static void enable_local3_irq(unsigned int irq) { + unsigned long flags; + + local_irq_save(flags); sgint->imask1 |= (1 << (SGI_MAP_1_IRQ - SGINT_LOCAL1)); sgint->cmeimask1 |= (1 << (irq - SGINT_LOCAL3)); + local_irq_restore(flags); +} + +static unsigned int startup_local3_irq(unsigned int irq) +{ + enable_local3_irq(irq); + return 0; /* Never anything pending */ } void disable_local3_irq(unsigned int irq) { + unsigned long flags; + + local_irq_save(flags); sgint->cmeimask1 &= ~(1 << (irq - SGINT_LOCAL3)); if (!sgint->cmeimask1) sgint->imask1 &= ~(1 << (SGI_MAP_1_IRQ - SGINT_LOCAL1)); + local_irq_restore(flags); } +#define shutdown_local3_irq disable_local3_irq +#define mask_and_ack_local3_irq disable_local3_irq + static void end_local3_irq (unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) @@ -143,14 +214,15 @@ static void end_local3_irq (unsigned int irq) static struct irq_chip ip22_local3_irq_type = { .typename = "IP22 local 3", - .ack = disable_local3_irq, - .mask = disable_local3_irq, - .mask_ack = disable_local3_irq, - .unmask = enable_local3_irq, + .startup = startup_local3_irq, + .shutdown = shutdown_local3_irq, + .enable = enable_local3_irq, + .disable = disable_local3_irq, + .ack = mask_and_ack_local3_irq, .end = end_local3_irq, }; -static void indy_local0_irqdispatch(void) +static void indy_local0_irqdispatch(struct pt_regs *regs) { u8 mask = sgint->istat0 & sgint->imask0; u8 mask2; @@ -164,10 +236,11 @@ static void indy_local0_irqdispatch(void) /* if irq == 0, then the interrupt has already been cleared */ if (irq) - do_IRQ(irq); + do_IRQ(irq, regs); + return; } -static void indy_local1_irqdispatch(void) +static void indy_local1_irqdispatch(struct pt_regs *regs) { u8 mask = sgint->istat1 & sgint->imask1; u8 mask2; @@ -181,18 +254,19 @@ static void indy_local1_irqdispatch(void) /* if irq == 0, then the interrupt has already been cleared */ if (irq) - do_IRQ(irq); + do_IRQ(irq, regs); + return; } -extern void ip22_be_interrupt(int irq); +extern void ip22_be_interrupt(int irq, struct pt_regs *regs); -static void indy_buserror_irq(void) +static void indy_buserror_irq(struct pt_regs *regs) { int irq = SGI_BUSERR_IRQ; irq_enter(); kstat_this_cpu.irqs[irq]++; - ip22_be_interrupt(irq); + ip22_be_interrupt(irq, regs); irq_exit(); } @@ -231,8 +305,8 @@ static struct irqaction map1_cascade = { #define SGI_INTERRUPTS SGINT_LOCAL3 #endif -extern void indy_r4k_timer_interrupt(void); -extern void indy_8254timer_irq(void); +extern void indy_r4k_timer_interrupt(struct pt_regs *regs); +extern void indy_8254timer_irq(struct pt_regs *regs); /* * IRQs on the INDY look basically (barring software IRQs which we don't use @@ -262,7 +336,7 @@ extern void indy_8254timer_irq(void); * another exception, big deal. */ -asmlinkage void plat_irq_dispatch(void) +asmlinkage void plat_irq_dispatch(struct pt_regs *regs) { unsigned int pending = read_c0_cause(); @@ -270,15 +344,15 @@ asmlinkage void plat_irq_dispatch(void) * First we check for r4k counter/timer IRQ. */ if (pending & CAUSEF_IP7) - indy_r4k_timer_interrupt(); + indy_r4k_timer_interrupt(regs); else if (pending & CAUSEF_IP2) - indy_local0_irqdispatch(); + indy_local0_irqdispatch(regs); else if (pending & CAUSEF_IP3) - indy_local1_irqdispatch(); + indy_local1_irqdispatch(regs); else if (pending & CAUSEF_IP6) - indy_buserror_irq(); + indy_buserror_irq(regs); else if (pending & (CAUSEF_IP4 | CAUSEF_IP5)) - indy_8254timer_irq(); + indy_8254timer_irq(regs); } extern void mips_cpu_irq_init(unsigned int irq_base); @@ -358,7 +432,10 @@ void __init arch_init_irq(void) else handler = &ip22_local3_irq_type; - set_irq_chip_and_handler(i, handler, handle_level_irq); + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 1; + irq_desc[i].chip = handler; } /* vector handler. this register the IRQ as non-sharable */ diff --git a/trunk/arch/mips/sgi-ip22/ip22-reset.c b/trunk/arch/mips/sgi-ip22/ip22-reset.c index 66df5ac8f089..7a941ecff3bb 100644 --- a/trunk/arch/mips/sgi-ip22/ip22-reset.c +++ b/trunk/arch/mips/sgi-ip22/ip22-reset.c @@ -169,7 +169,7 @@ static inline void volume_down_button(unsigned long data) } } -static irqreturn_t panel_int(int irq, void *dev_id) +static irqreturn_t panel_int(int irq, void *dev_id, struct pt_regs *regs) { unsigned int buttons; diff --git a/trunk/arch/mips/sgi-ip22/ip22-time.c b/trunk/arch/mips/sgi-ip22/ip22-time.c index 205554734099..0e061890f797 100644 --- a/trunk/arch/mips/sgi-ip22/ip22-time.c +++ b/trunk/arch/mips/sgi-ip22/ip22-time.c @@ -175,7 +175,7 @@ static __init void indy_time_init(void) } /* Generic SGI handler for (spurious) 8254 interrupts */ -void indy_8254timer_irq(void) +void indy_8254timer_irq(struct pt_regs *regs) { int irq = SGI_8254_0_IRQ; ULONG cnt; @@ -189,13 +189,13 @@ void indy_8254timer_irq(void) irq_exit(); } -void indy_r4k_timer_interrupt(void) +void indy_r4k_timer_interrupt(struct pt_regs *regs) { int irq = SGI_TIMER_IRQ; irq_enter(); kstat_this_cpu.irqs[irq]++; - timer_interrupt(irq, NULL); + timer_interrupt(irq, NULL, regs); irq_exit(); } diff --git a/trunk/arch/mips/sgi-ip27/ip27-irq.c b/trunk/arch/mips/sgi-ip27/ip27-irq.c index 5f8835b4e84a..24a85372284f 100644 --- a/trunk/arch/mips/sgi-ip27/ip27-irq.c +++ b/trunk/arch/mips/sgi-ip27/ip27-irq.c @@ -30,6 +30,7 @@ #include #include +#include #include #include #include @@ -128,7 +129,7 @@ static int ms1bit(unsigned long x) * Kanoj 05.13.00 */ -static void ip27_do_irq_mask0(void) +static void ip27_do_irq_mask0(struct pt_regs *regs) { int irq, swlevel; hubreg_t pend0, mask0; @@ -163,13 +164,13 @@ static void ip27_do_irq_mask0(void) struct slice_data *si = cpu_data[cpu].data; irq = si->level_to_irq[swlevel]; - do_IRQ(irq); + do_IRQ(irq, regs); } LOCAL_HUB_L(PI_INT_PEND0); } -static void ip27_do_irq_mask1(void) +static void ip27_do_irq_mask1(struct pt_regs *regs) { int irq, swlevel; hubreg_t pend1, mask1; @@ -189,17 +190,17 @@ static void ip27_do_irq_mask1(void) /* "map" swlevel to irq */ irq = si->level_to_irq[swlevel]; LOCAL_HUB_CLR_INTR(swlevel); - do_IRQ(irq); + do_IRQ(irq, regs); LOCAL_HUB_L(PI_INT_PEND1); } -static void ip27_prof_timer(void) +static void ip27_prof_timer(struct pt_regs *regs) { panic("CPU %d got a profiling interrupt", smp_processor_id()); } -static void ip27_hub_error(void) +static void ip27_hub_error(struct pt_regs *regs) { panic("CPU %d got a hub error interrupt", smp_processor_id()); } @@ -332,6 +333,11 @@ static inline void disable_bridge_irq(unsigned int irq) intr_disconnect_level(cpu, swlevel); } +static void mask_and_ack_bridge_irq(unsigned int irq) +{ + disable_bridge_irq(irq); +} + static void end_bridge_irq(unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)) && @@ -343,16 +349,41 @@ static struct irq_chip bridge_irq_type = { .typename = "bridge", .startup = startup_bridge_irq, .shutdown = shutdown_bridge_irq, - .ack = disable_bridge_irq, - .mask = disable_bridge_irq, - .mask_ack = disable_bridge_irq, - .unmask = enable_bridge_irq, + .enable = enable_bridge_irq, + .disable = disable_bridge_irq, + .ack = mask_and_ack_bridge_irq, .end = end_bridge_irq, }; +static unsigned long irq_map[NR_IRQS / BITS_PER_LONG]; + +int allocate_irqno(void) +{ + int irq; + +again: + irq = find_first_zero_bit(irq_map, NR_IRQS); + + if (irq >= NR_IRQS) + return -ENOSPC; + + if (test_and_set_bit(irq, irq_map)) + goto again; + + return irq; +} + +void free_irqno(unsigned int irq) +{ + clear_bit(irq, irq_map); +} + void __devinit register_bridge_irq(unsigned int irq) { - set_irq_chip_and_handler(irq, &bridge_irq_type, handle_level_irq); + irq_desc[irq].status = IRQ_DISABLED; + irq_desc[irq].action = 0; + irq_desc[irq].depth = 1; + irq_desc[irq].chip = &bridge_irq_type; } int __devinit request_bridge_irq(struct bridge_controller *bc) @@ -387,22 +418,22 @@ int __devinit request_bridge_irq(struct bridge_controller *bc) return irq; } -extern void ip27_rt_timer_interrupt(void); +extern void ip27_rt_timer_interrupt(struct pt_regs *regs); -asmlinkage void plat_irq_dispatch(void) +asmlinkage void plat_irq_dispatch(struct pt_regs *regs) { unsigned long pending = read_c0_cause() & read_c0_status(); if (pending & CAUSEF_IP4) - ip27_rt_timer_interrupt(); + ip27_rt_timer_interrupt(regs); else if (pending & CAUSEF_IP2) /* PI_INT_PEND_0 or CC_PEND_{A|B} */ - ip27_do_irq_mask0(); + ip27_do_irq_mask0(regs); else if (pending & CAUSEF_IP3) /* PI_INT_PEND_1 */ - ip27_do_irq_mask1(); + ip27_do_irq_mask1(regs); else if (pending & CAUSEF_IP5) - ip27_prof_timer(); + ip27_prof_timer(regs); else if (pending & CAUSEF_IP6) - ip27_hub_error(); + ip27_hub_error(regs); } void __init arch_init_irq(void) diff --git a/trunk/arch/mips/sgi-ip27/ip27-klnuma.c b/trunk/arch/mips/sgi-ip27/ip27-klnuma.c index f9f404a8ddad..d777b7d1a9fe 100644 --- a/trunk/arch/mips/sgi-ip27/ip27-klnuma.c +++ b/trunk/arch/mips/sgi-ip27/ip27-klnuma.c @@ -26,7 +26,7 @@ static cpumask_t ktext_repmask; * kernel. For example, we should never put a copy on a headless node, * and we should respect the topology of the machine. */ -void __init setup_replication_mask(void) +void __init setup_replication_mask() { cnodeid_t cnode; diff --git a/trunk/arch/mips/sgi-ip27/ip27-timer.c b/trunk/arch/mips/sgi-ip27/ip27-timer.c index 7d361726bbfb..257ce118e380 100644 --- a/trunk/arch/mips/sgi-ip27/ip27-timer.c +++ b/trunk/arch/mips/sgi-ip27/ip27-timer.c @@ -89,7 +89,7 @@ static int set_rtc_mmss(unsigned long nowtime) static unsigned int rt_timer_irq; -void ip27_rt_timer_interrupt(void) +void ip27_rt_timer_interrupt(struct pt_regs *regs) { int cpu = smp_processor_id(); int cpuA = cputoslice(cpu) == 0; @@ -111,7 +111,7 @@ void ip27_rt_timer_interrupt(void) if (cpu == 0) do_timer(1); - update_process_times(user_mode(get_irq_regs())); + update_process_times(user_mode(regs)); /* * If we have an externally synchronized Linux clock, then update @@ -134,6 +134,13 @@ void ip27_rt_timer_interrupt(void) irq_exit(); } +unsigned long ip27_do_gettimeoffset(void) +{ + unsigned long ct_cur1; + ct_cur1 = REMOTE_HUB_L(cputonasid(0), PI_RT_COUNT) + CYCLES_PER_JIFFY; + return (ct_cur1 - ct_cur[0]) * NSEC_PER_CYCLE / 1000; +} + /* Includes for ioc3_init(). */ #include #include @@ -172,6 +179,15 @@ static __init unsigned long get_m48t35_time(void) return mktime(year, month, date, hour, min, sec); } +static unsigned int startup_rt_irq(unsigned int irq) +{ + return 0; +} + +static void shutdown_rt_irq(unsigned int irq) +{ +} + static void enable_rt_irq(unsigned int irq) { } @@ -180,17 +196,21 @@ static void disable_rt_irq(unsigned int irq) { } +static void mask_and_ack_rt(unsigned int irq) +{ +} + static void end_rt_irq(unsigned int irq) { } static struct irq_chip rt_irq_type = { .typename = "SN HUB RT timer", - .ack = disable_rt_irq, - .mask = disable_rt_irq, - .mask_ack = disable_rt_irq, - .unmask = enable_rt_irq, - .eoi = enable_rt_irq, + .startup = startup_rt_irq, + .shutdown = shutdown_rt_irq, + .enable = enable_rt_irq, + .disable = disable_rt_irq, + .ack = mask_and_ack_rt, .end = end_rt_irq, }; @@ -201,6 +221,8 @@ static struct irqaction rt_irqaction = { .name = "timer" }; +extern int allocate_irqno(void); + void __init plat_timer_setup(struct irqaction *irq) { int irqno = allocate_irqno(); @@ -208,7 +230,10 @@ void __init plat_timer_setup(struct irqaction *irq) if (irqno < 0) panic("Can't allocate interrupt number for timer interrupt"); - set_irq_chip_and_handler(irqno, &rt_irq_type, handle_percpu_irq); + irq_desc[irqno].status = IRQ_DISABLED; + irq_desc[irqno].action = NULL; + irq_desc[irqno].depth = 1; + irq_desc[irqno].chip = &rt_irq_type; /* over-write the handler, we use our own way */ irq->handler = no_action; @@ -223,17 +248,12 @@ void __init plat_timer_setup(struct irqaction *irq) setup_irq(irqno, &rt_irqaction); } -static cycle_t ip27_hpt_read(void) -{ - return REMOTE_HUB_L(cputonasid(0), PI_RT_COUNT); -} - void __init ip27_time_init(void) { - clocksource_mips.read = ip27_hpt_read; - mips_hpt_frequency = CYCLES_PER_SEC; xtime.tv_sec = get_m48t35_time(); xtime.tv_nsec = 0; + + do_gettimeoffset = ip27_do_gettimeoffset; } void __init cpu_time_init(void) diff --git a/trunk/arch/mips/sgi-ip32/crime.c b/trunk/arch/mips/sgi-ip32/crime.c index bff508704d03..41b5eca1148c 100644 --- a/trunk/arch/mips/sgi-ip32/crime.c +++ b/trunk/arch/mips/sgi-ip32/crime.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -39,7 +40,8 @@ void __init crime_init(void) id, rev, field, (unsigned long) CRIME_BASE); } -irqreturn_t crime_memerr_intr(unsigned int irq, void *dev_id) +irqreturn_t +crime_memerr_intr (unsigned int irq, void *dev_id, struct pt_regs *regs) { unsigned long stat, addr; int fatal = 0; @@ -90,7 +92,8 @@ irqreturn_t crime_memerr_intr(unsigned int irq, void *dev_id) return IRQ_HANDLED; } -irqreturn_t crime_cpuerr_intr(unsigned int irq, void *dev_id) +irqreturn_t +crime_cpuerr_intr (unsigned int irq, void *dev_id, struct pt_regs *regs) { unsigned long stat = crime->cpu_error_stat & CRIME_CPU_ERROR_MASK; unsigned long addr = crime->cpu_error_addr & CRIME_CPU_ERROR_ADDR_MASK; diff --git a/trunk/arch/mips/sgi-ip32/ip32-irq.c b/trunk/arch/mips/sgi-ip32/ip32-irq.c index ae063864c026..c64a820373de 100644 --- a/trunk/arch/mips/sgi-ip32/ip32-irq.c +++ b/trunk/arch/mips/sgi-ip32/ip32-irq.c @@ -113,9 +113,17 @@ static void inline flush_mace_bus(void) * is quite different anyway. */ +/* + * IRQ spinlock - Ralf says not to disable CPU interrupts, + * and I think he knows better. + */ +static DEFINE_SPINLOCK(ip32_irq_lock); + /* Some initial interrupts to set up */ -extern irqreturn_t crime_memerr_intr(int irq, void *dev_id); -extern irqreturn_t crime_cpuerr_intr(int irq, void *dev_id); +extern irqreturn_t crime_memerr_intr (int irq, void *dev_id, + struct pt_regs *regs); +extern irqreturn_t crime_cpuerr_intr (int irq, void *dev_id, + struct pt_regs *regs); struct irqaction memerr_irq = { crime_memerr_intr, IRQF_DISABLED, CPU_MASK_NONE, "CRIME memory error", NULL, NULL }; @@ -132,6 +140,12 @@ static void enable_cpu_irq(unsigned int irq) set_c0_status(STATUSF_IP7); } +static unsigned int startup_cpu_irq(unsigned int irq) +{ + enable_cpu_irq(irq); + return 0; +} + static void disable_cpu_irq(unsigned int irq) { clear_c0_status(STATUSF_IP7); @@ -143,12 +157,16 @@ static void end_cpu_irq(unsigned int irq) enable_cpu_irq (irq); } +#define shutdown_cpu_irq disable_cpu_irq +#define mask_and_ack_cpu_irq disable_cpu_irq + static struct irq_chip ip32_cpu_interrupt = { .typename = "IP32 CPU", - .ack = disable_cpu_irq, - .mask = disable_cpu_irq, - .mask_ack = disable_cpu_irq, - .unmask = enable_cpu_irq, + .startup = startup_cpu_irq, + .shutdown = shutdown_cpu_irq, + .enable = enable_cpu_irq, + .disable = disable_cpu_irq, + .ack = mask_and_ack_cpu_irq, .end = end_cpu_irq, }; @@ -161,27 +179,45 @@ static uint64_t crime_mask; static void enable_crime_irq(unsigned int irq) { + unsigned long flags; + + spin_lock_irqsave(&ip32_irq_lock, flags); crime_mask |= 1 << (irq - 1); crime->imask = crime_mask; + spin_unlock_irqrestore(&ip32_irq_lock, flags); +} + +static unsigned int startup_crime_irq(unsigned int irq) +{ + enable_crime_irq(irq); + return 0; /* This is probably not right; we could have pending irqs */ } static void disable_crime_irq(unsigned int irq) { + unsigned long flags; + + spin_lock_irqsave(&ip32_irq_lock, flags); crime_mask &= ~(1 << (irq - 1)); crime->imask = crime_mask; flush_crime_bus(); + spin_unlock_irqrestore(&ip32_irq_lock, flags); } static void mask_and_ack_crime_irq(unsigned int irq) { + unsigned long flags; + /* Edge triggered interrupts must be cleared. */ if ((irq >= CRIME_GBE0_IRQ && irq <= CRIME_GBE3_IRQ) || (irq >= CRIME_RE_EMPTY_E_IRQ && irq <= CRIME_RE_IDLE_E_IRQ) || (irq >= CRIME_SOFT0_IRQ && irq <= CRIME_SOFT2_IRQ)) { uint64_t crime_int; + spin_lock_irqsave(&ip32_irq_lock, flags); crime_int = crime->hard_int; crime_int &= ~(1 << (irq - 1)); crime->hard_int = crime_int; + spin_unlock_irqrestore(&ip32_irq_lock, flags); } disable_crime_irq(irq); } @@ -192,12 +228,15 @@ static void end_crime_irq(unsigned int irq) enable_crime_irq(irq); } +#define shutdown_crime_irq disable_crime_irq + static struct irq_chip ip32_crime_interrupt = { .typename = "IP32 CRIME", + .startup = startup_crime_irq, + .shutdown = shutdown_crime_irq, + .enable = enable_crime_irq, + .disable = disable_crime_irq, .ack = mask_and_ack_crime_irq, - .mask = disable_crime_irq, - .mask_ack = mask_and_ack_crime_irq, - .unmask = enable_crime_irq, .end = end_crime_irq, }; @@ -211,20 +250,34 @@ static unsigned long macepci_mask; static void enable_macepci_irq(unsigned int irq) { + unsigned long flags; + + spin_lock_irqsave(&ip32_irq_lock, flags); macepci_mask |= MACEPCI_CONTROL_INT(irq - 9); mace->pci.control = macepci_mask; crime_mask |= 1 << (irq - 1); crime->imask = crime_mask; + spin_unlock_irqrestore(&ip32_irq_lock, flags); +} + +static unsigned int startup_macepci_irq(unsigned int irq) +{ + enable_macepci_irq (irq); + return 0; } static void disable_macepci_irq(unsigned int irq) { + unsigned long flags; + + spin_lock_irqsave(&ip32_irq_lock, flags); crime_mask &= ~(1 << (irq - 1)); crime->imask = crime_mask; flush_crime_bus(); macepci_mask &= ~MACEPCI_CONTROL_INT(irq - 9); mace->pci.control = macepci_mask; flush_mace_bus(); + spin_unlock_irqrestore(&ip32_irq_lock, flags); } static void end_macepci_irq(unsigned int irq) @@ -233,12 +286,16 @@ static void end_macepci_irq(unsigned int irq) enable_macepci_irq(irq); } +#define shutdown_macepci_irq disable_macepci_irq +#define mask_and_ack_macepci_irq disable_macepci_irq + static struct irq_chip ip32_macepci_interrupt = { .typename = "IP32 MACE PCI", - .ack = disable_macepci_irq, - .mask = disable_macepci_irq, - .mask_ack = disable_macepci_irq, - .unmask = enable_macepci_irq, + .startup = startup_macepci_irq, + .shutdown = shutdown_macepci_irq, + .enable = enable_macepci_irq, + .disable = disable_macepci_irq, + .ack = mask_and_ack_macepci_irq, .end = end_macepci_irq, }; @@ -284,6 +341,7 @@ static unsigned long maceisa_mask; static void enable_maceisa_irq (unsigned int irq) { unsigned int crime_int = 0; + unsigned long flags; DBG ("maceisa enable: %u\n", irq); @@ -299,16 +357,26 @@ static void enable_maceisa_irq (unsigned int irq) break; } DBG ("crime_int %08x enabled\n", crime_int); + spin_lock_irqsave(&ip32_irq_lock, flags); crime_mask |= crime_int; crime->imask = crime_mask; maceisa_mask |= 1 << (irq - 33); mace->perif.ctrl.imask = maceisa_mask; + spin_unlock_irqrestore(&ip32_irq_lock, flags); +} + +static unsigned int startup_maceisa_irq(unsigned int irq) +{ + enable_maceisa_irq(irq); + return 0; } static void disable_maceisa_irq(unsigned int irq) { unsigned int crime_int = 0; + unsigned long flags; + spin_lock_irqsave(&ip32_irq_lock, flags); maceisa_mask &= ~(1 << (irq - 33)); if(!(maceisa_mask & MACEISA_AUDIO_INT)) crime_int |= MACE_AUDIO_INT; @@ -321,20 +389,23 @@ static void disable_maceisa_irq(unsigned int irq) flush_crime_bus(); mace->perif.ctrl.imask = maceisa_mask; flush_mace_bus(); + spin_unlock_irqrestore(&ip32_irq_lock, flags); } static void mask_and_ack_maceisa_irq(unsigned int irq) { - unsigned long mace_int; + unsigned long mace_int, flags; switch (irq) { case MACEISA_PARALLEL_IRQ: case MACEISA_SERIAL1_TDMAPR_IRQ: case MACEISA_SERIAL2_TDMAPR_IRQ: /* edge triggered */ + spin_lock_irqsave(&ip32_irq_lock, flags); mace_int = mace->perif.ctrl.istat; mace_int &= ~(1 << (irq - 33)); mace->perif.ctrl.istat = mace_int; + spin_unlock_irqrestore(&ip32_irq_lock, flags); break; } disable_maceisa_irq(irq); @@ -346,12 +417,15 @@ static void end_maceisa_irq(unsigned irq) enable_maceisa_irq(irq); } +#define shutdown_maceisa_irq disable_maceisa_irq + static struct irq_chip ip32_maceisa_interrupt = { .typename = "IP32 MACE ISA", + .startup = startup_maceisa_irq, + .shutdown = shutdown_maceisa_irq, + .enable = enable_maceisa_irq, + .disable = disable_maceisa_irq, .ack = mask_and_ack_maceisa_irq, - .mask = disable_maceisa_irq, - .mask_ack = mask_and_ack_maceisa_irq, - .unmask = enable_maceisa_irq, .end = end_maceisa_irq, }; @@ -361,15 +435,29 @@ static struct irq_chip ip32_maceisa_interrupt = { static void enable_mace_irq(unsigned int irq) { + unsigned long flags; + + spin_lock_irqsave(&ip32_irq_lock, flags); crime_mask |= 1 << (irq - 1); crime->imask = crime_mask; + spin_unlock_irqrestore(&ip32_irq_lock, flags); +} + +static unsigned int startup_mace_irq(unsigned int irq) +{ + enable_mace_irq(irq); + return 0; } static void disable_mace_irq(unsigned int irq) { + unsigned long flags; + + spin_lock_irqsave(&ip32_irq_lock, flags); crime_mask &= ~(1 << (irq - 1)); crime->imask = crime_mask; flush_crime_bus(); + spin_unlock_irqrestore(&ip32_irq_lock, flags); } static void end_mace_irq(unsigned int irq) @@ -378,16 +466,20 @@ static void end_mace_irq(unsigned int irq) enable_mace_irq(irq); } +#define shutdown_mace_irq disable_mace_irq +#define mask_and_ack_mace_irq disable_mace_irq + static struct irq_chip ip32_mace_interrupt = { .typename = "IP32 MACE", - .ack = disable_mace_irq, - .mask = disable_mace_irq, - .mask_ack = disable_mace_irq, - .unmask = enable_mace_irq, + .startup = startup_mace_irq, + .shutdown = shutdown_mace_irq, + .enable = enable_mace_irq, + .disable = disable_mace_irq, + .ack = mask_and_ack_mace_irq, .end = end_mace_irq, }; -static void ip32_unknown_interrupt(void) +static void ip32_unknown_interrupt(struct pt_regs *regs) { printk ("Unknown interrupt occurred!\n"); printk ("cp0_status: %08x\n", read_c0_status()); @@ -400,7 +492,7 @@ static void ip32_unknown_interrupt(void) printk ("MACE PCI control register: %08x\n", mace->pci.control); printk("Register dump:\n"); - show_regs(get_irq_regs()); + show_regs(regs); printk("Please mail this report to linux-mips@linux-mips.org\n"); printk("Spinning..."); @@ -409,7 +501,7 @@ static void ip32_unknown_interrupt(void) /* CRIME 1.1 appears to deliver all interrupts to this one pin. */ /* change this to loop over all edge-triggered irqs, exception masked out ones */ -static void ip32_irq0(void) +static void ip32_irq0(struct pt_regs *regs) { uint64_t crime_int; int irq = 0; @@ -424,50 +516,50 @@ static void ip32_irq0(void) } irq++; DBG("*irq %u*\n", irq); - do_IRQ(irq); + do_IRQ(irq, regs); } -static void ip32_irq1(void) +static void ip32_irq1(struct pt_regs *regs) { - ip32_unknown_interrupt(); + ip32_unknown_interrupt(regs); } -static void ip32_irq2(void) +static void ip32_irq2(struct pt_regs *regs) { - ip32_unknown_interrupt(); + ip32_unknown_interrupt(regs); } -static void ip32_irq3(void) +static void ip32_irq3(struct pt_regs *regs) { - ip32_unknown_interrupt(); + ip32_unknown_interrupt(regs); } -static void ip32_irq4(void) +static void ip32_irq4(struct pt_regs *regs) { - ip32_unknown_interrupt(); + ip32_unknown_interrupt(regs); } -static void ip32_irq5(void) +static void ip32_irq5(struct pt_regs *regs) { - ll_timer_interrupt(IP32_R4K_TIMER_IRQ); + ll_timer_interrupt(IP32_R4K_TIMER_IRQ, regs); } -asmlinkage void plat_irq_dispatch(void) +asmlinkage void plat_irq_dispatch(struct pt_regs *regs) { unsigned int pending = read_c0_cause(); if (likely(pending & IE_IRQ0)) - ip32_irq0(); + ip32_irq0(regs); else if (unlikely(pending & IE_IRQ1)) - ip32_irq1(); + ip32_irq1(regs); else if (unlikely(pending & IE_IRQ2)) - ip32_irq2(); + ip32_irq2(regs); else if (unlikely(pending & IE_IRQ3)) - ip32_irq3(); + ip32_irq3(regs); else if (unlikely(pending & IE_IRQ4)) - ip32_irq4(); + ip32_irq4(regs); else if (likely(pending & IE_IRQ5)) - ip32_irq5(); + ip32_irq5(regs); } void __init arch_init_irq(void) @@ -496,7 +588,10 @@ void __init arch_init_irq(void) else controller = &ip32_maceisa_interrupt; - set_irq_chip(irq, controller); + irq_desc[irq].status = IRQ_DISABLED; + irq_desc[irq].action = 0; + irq_desc[irq].depth = 0; + irq_desc[irq].chip = controller; } setup_irq(CRIME_MEMERR_IRQ, &memerr_irq); setup_irq(CRIME_CPUERR_IRQ, &cpuerr_irq); diff --git a/trunk/arch/mips/sgi-ip32/ip32-reset.c b/trunk/arch/mips/sgi-ip32/ip32-reset.c index db8084411538..fd0932b2d521 100644 --- a/trunk/arch/mips/sgi-ip32/ip32-reset.c +++ b/trunk/arch/mips/sgi-ip32/ip32-reset.c @@ -135,7 +135,7 @@ static inline void ip32_power_button(void) add_timer(&power_timer); } -static irqreturn_t ip32_rtc_int(int irq, void *dev_id) +static irqreturn_t ip32_rtc_int(int irq, void *dev_id, struct pt_regs *regs) { volatile unsigned char reg_c; diff --git a/trunk/arch/mips/sibyte/bcm1480/irq.c b/trunk/arch/mips/sibyte/bcm1480/irq.c index 2e8f6b2e2420..a46b75b23ecb 100644 --- a/trunk/arch/mips/sibyte/bcm1480/irq.c +++ b/trunk/arch/mips/sibyte/bcm1480/irq.c @@ -25,9 +25,9 @@ #include #include -#include #include #include +#include #include #include @@ -45,9 +45,11 @@ */ +#define shutdown_bcm1480_irq disable_bcm1480_irq static void end_bcm1480_irq(unsigned int irq); static void enable_bcm1480_irq(unsigned int irq); static void disable_bcm1480_irq(unsigned int irq); +static unsigned int startup_bcm1480_irq(unsigned int irq); static void ack_bcm1480_irq(unsigned int irq); #ifdef CONFIG_SMP static void bcm1480_set_affinity(unsigned int irq, cpumask_t mask); @@ -83,10 +85,11 @@ extern char sb1250_duart_present[]; static struct irq_chip bcm1480_irq_type = { .typename = "BCM1480-IMR", + .startup = startup_bcm1480_irq, + .shutdown = shutdown_bcm1480_irq, + .enable = enable_bcm1480_irq, + .disable = disable_bcm1480_irq, .ack = ack_bcm1480_irq, - .mask = disable_bcm1480_irq, - .mask_ack = ack_bcm1480_irq, - .unmask = enable_bcm1480_irq, .end = end_bcm1480_irq, #ifdef CONFIG_SMP .set_affinity = bcm1480_set_affinity @@ -185,6 +188,14 @@ static void bcm1480_set_affinity(unsigned int irq, cpumask_t mask) /*****************************************************************************/ +static unsigned int startup_bcm1480_irq(unsigned int irq) +{ + bcm1480_unmask_irq(bcm1480_irq_owner[irq], irq); + + return 0; /* never anything pending */ +} + + static void disable_bcm1480_irq(unsigned int irq) { bcm1480_mask_irq(bcm1480_irq_owner[irq], irq); @@ -259,14 +270,22 @@ void __init init_bcm1480_irqs(void) { int i; - for (i = 0; i < BCM1480_NR_IRQS; i++) { - set_irq_chip(i, &bcm1480_irq_type); - bcm1480_irq_owner[i] = 0; + for (i = 0; i < NR_IRQS; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 1; + if (i < BCM1480_NR_IRQS) { + irq_desc[i].chip = &bcm1480_irq_type; + bcm1480_irq_owner[i] = 0; + } else { + irq_desc[i].chip = &no_irq_chip; + } } } -static irqreturn_t bcm1480_dummy_handler(int irq, void *dev_id) +static irqreturn_t bcm1480_dummy_handler(int irq, void *dev_id, + struct pt_regs *regs) { return IRQ_NONE; } @@ -434,7 +453,7 @@ void __init arch_init_irq(void) #define duart_out(reg, val) csr_out32(val, IOADDR(A_DUART_CHANREG(kgdb_port,reg))) #define duart_in(reg) csr_in32(IOADDR(A_DUART_CHANREG(kgdb_port,reg))) -static void bcm1480_kgdb_interrupt(void) +void bcm1480_kgdb_interrupt(struct pt_regs *regs) { /* * Clear break-change status (allow some time for the remote @@ -445,15 +464,16 @@ static void bcm1480_kgdb_interrupt(void) mdelay(500); duart_out(R_DUART_CMD, V_DUART_MISC_CMD_RESET_BREAK_INT | M_DUART_RX_EN | M_DUART_TX_EN); - set_async_breakpoint(&get_irq_regs()->cp0_epc); + set_async_breakpoint(®s->cp0_epc); } #endif /* CONFIG_KGDB */ -extern void bcm1480_timer_interrupt(void); -extern void bcm1480_mailbox_interrupt(void); +extern void bcm1480_timer_interrupt(struct pt_regs *regs); +extern void bcm1480_mailbox_interrupt(struct pt_regs *regs); +extern void bcm1480_kgdb_interrupt(struct pt_regs *regs); -asmlinkage void plat_irq_dispatch(void) +asmlinkage void plat_irq_dispatch(struct pt_regs *regs) { unsigned int pending; @@ -466,21 +486,21 @@ asmlinkage void plat_irq_dispatch(void) #ifdef CONFIG_SIBYTE_BCM1480_PROF if (pending & CAUSEF_IP7) /* Cpu performance counter interrupt */ - sbprof_cpu_intr(); + sbprof_cpu_intr(exception_epc(regs)); else #endif if (pending & CAUSEF_IP4) - bcm1480_timer_interrupt(); + bcm1480_timer_interrupt(regs); #ifdef CONFIG_SMP else if (pending & CAUSEF_IP3) - bcm1480_mailbox_interrupt(); + bcm1480_mailbox_interrupt(regs); #endif #ifdef CONFIG_KGDB else if (pending & CAUSEF_IP6) - bcm1480_kgdb_interrupt(); /* KGDB (uart 1) */ + bcm1480_kgdb_interrupt(regs); /* KGDB (uart 1) */ #endif else if (pending & CAUSEF_IP2) { @@ -501,9 +521,9 @@ asmlinkage void plat_irq_dispatch(void) if (mask_h) { if (mask_h ^ 1) - do_IRQ(fls64(mask_h) - 1); + do_IRQ(fls64(mask_h) - 1, regs); else - do_IRQ(63 + fls64(mask_l)); + do_IRQ(63 + fls64(mask_l), regs); } } } diff --git a/trunk/arch/mips/sibyte/bcm1480/smp.c b/trunk/arch/mips/sibyte/bcm1480/smp.c index bf328277c775..584a4b33faac 100644 --- a/trunk/arch/mips/sibyte/bcm1480/smp.c +++ b/trunk/arch/mips/sibyte/bcm1480/smp.c @@ -34,21 +34,21 @@ extern void smp_call_function_interrupt(void); * independent of board/firmware */ -static volatile void *mailbox_0_set_regs[] = { +static void *mailbox_0_set_regs[] = { IOADDR(A_BCM1480_IMR_CPU0_BASE + R_BCM1480_IMR_MAILBOX_0_SET_CPU), IOADDR(A_BCM1480_IMR_CPU1_BASE + R_BCM1480_IMR_MAILBOX_0_SET_CPU), IOADDR(A_BCM1480_IMR_CPU2_BASE + R_BCM1480_IMR_MAILBOX_0_SET_CPU), IOADDR(A_BCM1480_IMR_CPU3_BASE + R_BCM1480_IMR_MAILBOX_0_SET_CPU), }; -static volatile void *mailbox_0_clear_regs[] = { +static void *mailbox_0_clear_regs[] = { IOADDR(A_BCM1480_IMR_CPU0_BASE + R_BCM1480_IMR_MAILBOX_0_CLR_CPU), IOADDR(A_BCM1480_IMR_CPU1_BASE + R_BCM1480_IMR_MAILBOX_0_CLR_CPU), IOADDR(A_BCM1480_IMR_CPU2_BASE + R_BCM1480_IMR_MAILBOX_0_CLR_CPU), IOADDR(A_BCM1480_IMR_CPU3_BASE + R_BCM1480_IMR_MAILBOX_0_CLR_CPU), }; -static volatile void *mailbox_0_regs[] = { +static void *mailbox_0_regs[] = { IOADDR(A_BCM1480_IMR_CPU0_BASE + R_BCM1480_IMR_MAILBOX_0_CPU), IOADDR(A_BCM1480_IMR_CPU1_BASE + R_BCM1480_IMR_MAILBOX_0_CPU), IOADDR(A_BCM1480_IMR_CPU2_BASE + R_BCM1480_IMR_MAILBOX_0_CPU), @@ -88,7 +88,7 @@ void core_send_ipi(int cpu, unsigned int action) __raw_writeq((((u64)action)<< 48), mailbox_0_set_regs[cpu]); } -void bcm1480_mailbox_interrupt(void) +void bcm1480_mailbox_interrupt(struct pt_regs *regs) { int cpu = smp_processor_id(); unsigned int action; diff --git a/trunk/arch/mips/sibyte/bcm1480/time.c b/trunk/arch/mips/sibyte/bcm1480/time.c index 6f3f71bf4244..7e088f6c4a86 100644 --- a/trunk/arch/mips/sibyte/bcm1480/time.c +++ b/trunk/arch/mips/sibyte/bcm1480/time.c @@ -31,6 +31,7 @@ #include #include +#include #include #include #include @@ -47,12 +48,6 @@ #define IMR_IP3_VAL K_BCM1480_INT_MAP_I1 #define IMR_IP4_VAL K_BCM1480_INT_MAP_I2 -#ifdef CONFIG_SIMULATION -#define BCM1480_HPT_VALUE 50000 -#else -#define BCM1480_HPT_VALUE 1000000 -#endif - extern int bcm1480_steal_irq(int irq); void bcm1480_time_init(void) @@ -65,6 +60,11 @@ void bcm1480_time_init(void) BUG(); } + if (!cpu) { + /* Use our own gettimeoffset() routine */ + do_gettimeoffset = bcm1480_gettimeoffset; + } + bcm1480_mask_irq(cpu, irq); /* Map the timer interrupt to ip[4] of this cpu */ @@ -75,7 +75,11 @@ void bcm1480_time_init(void) /* Disable the timer and set up the count */ __raw_writeq(0, IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG))); __raw_writeq( - BCM1480_HPT_VALUE/HZ +#ifndef CONFIG_SIMULATION + 1000000/HZ +#else + 50000/HZ +#endif , IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT))); /* Set the timer running */ @@ -94,10 +98,12 @@ void bcm1480_time_init(void) */ } -void bcm1480_timer_interrupt(void) +#include + +void bcm1480_timer_interrupt(struct pt_regs *regs) { int cpu = smp_processor_id(); - int irq = K_BCM1480_INT_TIMER_0 + cpu; + int irq = K_BCM1480_INT_TIMER_0+cpu; /* Reset the timer */ __raw_writeq(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS, @@ -107,26 +113,26 @@ void bcm1480_timer_interrupt(void) /* * CPU 0 handles the global timer interrupt job */ - ll_timer_interrupt(irq); + ll_timer_interrupt(irq, regs); } else { /* * other CPUs should just do profiling and process accounting */ - ll_local_timer_interrupt(irq); + ll_local_timer_interrupt(irq, regs); } } -static cycle_t bcm1480_hpt_read(void) +/* + * We use our own do_gettimeoffset() instead of the generic one, + * because the generic one does not work for SMP case. + * In addition, since we use general timer 0 for system time, + * we can get accurate intra-jiffy offset without calibration. + */ +unsigned long bcm1480_gettimeoffset(void) { - /* We assume this function is called xtime_lock held. */ unsigned long count = __raw_readq(IOADDR(A_SCD_TIMER_REGISTER(0, R_SCD_TIMER_CNT))); - return (jiffies + 1) * (BCM1480_HPT_VALUE / HZ) - count; -} -void __init bcm1480_hpt_setup(void) -{ - clocksource_mips.read = bcm1480_hpt_read; - mips_hpt_frequency = BCM1480_HPT_VALUE; + return 1000000/HZ - count; } diff --git a/trunk/arch/mips/sibyte/sb1250/bcm1250_tbprof.c b/trunk/arch/mips/sibyte/sb1250/bcm1250_tbprof.c index d1a906e683b2..992e0d8dbb67 100644 --- a/trunk/arch/mips/sibyte/sb1250/bcm1250_tbprof.c +++ b/trunk/arch/mips/sibyte/sb1250/bcm1250_tbprof.c @@ -88,7 +88,7 @@ static void arm_tb(void) sbp.tb_armed = 1; } -static irqreturn_t sbprof_tb_intr(int irq, void *dev_id) +static irqreturn_t sbprof_tb_intr(int irq, void *dev_id, struct pt_regs *regs) { int i; DBG(printk(DEVNAME ": tb_intr\n")); @@ -138,7 +138,7 @@ static irqreturn_t sbprof_tb_intr(int irq, void *dev_id) return IRQ_HANDLED; } -static irqreturn_t sbprof_pc_intr(int irq, void *dev_id) +static irqreturn_t sbprof_pc_intr(int irq, void *dev_id, struct pt_regs *regs) { printk(DEVNAME ": unexpected pc_intr"); return IRQ_NONE; diff --git a/trunk/arch/mips/sibyte/sb1250/bus_watcher.c b/trunk/arch/mips/sibyte/sb1250/bus_watcher.c index 45274bd3cd8b..bb90649fbc48 100644 --- a/trunk/arch/mips/sibyte/sb1250/bus_watcher.c +++ b/trunk/arch/mips/sibyte/sb1250/bus_watcher.c @@ -171,7 +171,7 @@ static void create_proc_decoder(struct bw_stats_struct *stats) * notes: possible re-entry due to multiple sources * should check/indicate saturation */ -static irqreturn_t sibyte_bw_int(int irq, void *data) +static irqreturn_t sibyte_bw_int(int irq, void *data, struct pt_regs *regs) { struct bw_stats_struct *stats = data; unsigned long cntr; diff --git a/trunk/arch/mips/sibyte/sb1250/irq.c b/trunk/arch/mips/sibyte/sb1250/irq.c index 82ce7533053f..f9bd9f074517 100644 --- a/trunk/arch/mips/sibyte/sb1250/irq.c +++ b/trunk/arch/mips/sibyte/sb1250/irq.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -44,9 +45,11 @@ */ +#define shutdown_sb1250_irq disable_sb1250_irq static void end_sb1250_irq(unsigned int irq); static void enable_sb1250_irq(unsigned int irq); static void disable_sb1250_irq(unsigned int irq); +static unsigned int startup_sb1250_irq(unsigned int irq); static void ack_sb1250_irq(unsigned int irq); #ifdef CONFIG_SMP static void sb1250_set_affinity(unsigned int irq, cpumask_t mask); @@ -68,10 +71,11 @@ extern char sb1250_duart_present[]; static struct irq_chip sb1250_irq_type = { .typename = "SB1250-IMR", + .startup = startup_sb1250_irq, + .shutdown = shutdown_sb1250_irq, + .enable = enable_sb1250_irq, + .disable = disable_sb1250_irq, .ack = ack_sb1250_irq, - .mask = disable_sb1250_irq, - .mask_ack = ack_sb1250_irq, - .unmask = enable_sb1250_irq, .end = end_sb1250_irq, #ifdef CONFIG_SMP .set_affinity = sb1250_set_affinity @@ -160,6 +164,14 @@ static void sb1250_set_affinity(unsigned int irq, cpumask_t mask) /*****************************************************************************/ +static unsigned int startup_sb1250_irq(unsigned int irq) +{ + sb1250_unmask_irq(sb1250_irq_owner[irq], irq); + + return 0; /* never anything pending */ +} + + static void disable_sb1250_irq(unsigned int irq) { sb1250_mask_irq(sb1250_irq_owner[irq], irq); @@ -228,14 +240,22 @@ void __init init_sb1250_irqs(void) { int i; - for (i = 0; i < SB1250_NR_IRQS; i++) { - set_irq_chip(i, &sb1250_irq_type); - sb1250_irq_owner[i] = 0; + for (i = 0; i < NR_IRQS; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 1; + if (i < SB1250_NR_IRQS) { + irq_desc[i].chip = &sb1250_irq_type; + sb1250_irq_owner[i] = 0; + } else { + irq_desc[i].chip = &no_irq_chip; + } } } -static irqreturn_t sb1250_dummy_handler(int irq, void *dev_id) +static irqreturn_t sb1250_dummy_handler(int irq, void *dev_id, + struct pt_regs *regs) { return IRQ_NONE; } @@ -383,7 +403,7 @@ void __init arch_init_irq(void) #define duart_out(reg, val) csr_out32(val, IOADDR(A_DUART_CHANREG(kgdb_port,reg))) #define duart_in(reg) csr_in32(IOADDR(A_DUART_CHANREG(kgdb_port,reg))) -static void sb1250_kgdb_interrupt(void) +static void sb1250_kgdb_interrupt(struct pt_regs *regs) { /* * Clear break-change status (allow some time for the remote @@ -394,15 +414,16 @@ static void sb1250_kgdb_interrupt(void) mdelay(500); duart_out(R_DUART_CMD, V_DUART_MISC_CMD_RESET_BREAK_INT | M_DUART_RX_EN | M_DUART_TX_EN); - set_async_breakpoint(&get_irq_regs()->cp0_epc); + set_async_breakpoint(®s->cp0_epc); } #endif /* CONFIG_KGDB */ -extern void sb1250_timer_interrupt(void); -extern void sb1250_mailbox_interrupt(void); +extern void sb1250_timer_interrupt(struct pt_regs *regs); +extern void sb1250_mailbox_interrupt(struct pt_regs *regs); +extern void sb1250_kgdb_interrupt(struct pt_regs *regs); -asmlinkage void plat_irq_dispatch(void) +asmlinkage void plat_irq_dispatch(struct pt_regs *regs) { unsigned int pending; @@ -425,21 +446,21 @@ asmlinkage void plat_irq_dispatch(void) #ifdef CONFIG_SIBYTE_SB1250_PROF if (pending & CAUSEF_IP7) /* Cpu performance counter interrupt */ - sbprof_cpu_intr(); + sbprof_cpu_intr(exception_epc(regs)); else #endif if (pending & CAUSEF_IP4) - sb1250_timer_interrupt(); + sb1250_timer_interrupt(regs); #ifdef CONFIG_SMP else if (pending & CAUSEF_IP3) - sb1250_mailbox_interrupt(); + sb1250_mailbox_interrupt(regs); #endif #ifdef CONFIG_KGDB else if (pending & CAUSEF_IP6) /* KGDB (uart 1) */ - sb1250_kgdb_interrupt(); + sb1250_kgdb_interrupt(regs); #endif else if (pending & CAUSEF_IP2) { @@ -454,9 +475,9 @@ asmlinkage void plat_irq_dispatch(void) mask = __raw_readq(IOADDR(A_IMR_REGISTER(smp_processor_id(), R_IMR_INTERRUPT_STATUS_BASE))); if (mask) - do_IRQ(fls64(mask) - 1); + do_IRQ(fls64(mask) - 1, regs); else - spurious_interrupt(); + spurious_interrupt(regs); } else - spurious_interrupt(); + spurious_interrupt(regs); } diff --git a/trunk/arch/mips/sibyte/sb1250/smp.c b/trunk/arch/mips/sibyte/sb1250/smp.c index c38e1f34460d..f859db02d3c9 100644 --- a/trunk/arch/mips/sibyte/sb1250/smp.c +++ b/trunk/arch/mips/sibyte/sb1250/smp.c @@ -76,7 +76,7 @@ void core_send_ipi(int cpu, unsigned int action) __raw_writeq((((u64)action) << 48), mailbox_set_regs[cpu]); } -void sb1250_mailbox_interrupt(void) +void sb1250_mailbox_interrupt(struct pt_regs *regs) { int cpu = smp_processor_id(); unsigned int action; diff --git a/trunk/arch/mips/sibyte/sb1250/time.c b/trunk/arch/mips/sibyte/sb1250/time.c index 2efffe15ff23..4b669dc86ef4 100644 --- a/trunk/arch/mips/sibyte/sb1250/time.c +++ b/trunk/arch/mips/sibyte/sb1250/time.c @@ -31,6 +31,7 @@ #include #include +#include #include #include #include @@ -47,11 +48,15 @@ #define SB1250_HPT_NUM 3 #define SB1250_HPT_VALUE M_SCD_TIMER_CNT /* max value */ +#define SB1250_HPT_SHIFT ((sizeof(unsigned int)*8)-V_SCD_TIMER_WIDTH) extern int sb1250_steal_irq(int irq); -static cycle_t sb1250_hpt_read(void); +static unsigned int sb1250_hpt_read(void); +static void sb1250_hpt_init(unsigned int); + +static unsigned int hpt_offset; void __init sb1250_hpt_setup(void) { @@ -65,9 +70,13 @@ void __init sb1250_hpt_setup(void) __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS, IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, R_SCD_TIMER_CFG))); - mips_hpt_frequency = V_SCD_TIMER_FREQ; - clocksource_mips.read = sb1250_hpt_read; - clocksource_mips.mask = M_SCD_TIMER_INIT; + /* + * we need to fill 32 bits, so just use the upper 23 bits and pretend + * the timer is going 512Mhz instead of 1Mhz + */ + mips_hpt_frequency = V_SCD_TIMER_FREQ << SB1250_HPT_SHIFT; + mips_hpt_init = sb1250_hpt_init; + mips_hpt_read = sb1250_hpt_read; } } @@ -116,7 +125,7 @@ void sb1250_time_init(void) */ } -void sb1250_timer_interrupt(void) +void sb1250_timer_interrupt(struct pt_regs *regs) { int cpu = smp_processor_id(); int irq = K_INT_TIMER_0 + cpu; @@ -129,25 +138,37 @@ void sb1250_timer_interrupt(void) /* * CPU 0 handles the global timer interrupt job */ - ll_timer_interrupt(irq); + ll_timer_interrupt(irq, regs); } else { /* * other CPUs should just do profiling and process accounting */ - ll_local_timer_interrupt(irq); + ll_local_timer_interrupt(irq, regs); } } /* * The HPT is free running from SB1250_HPT_VALUE down to 0 then starts over - * again. + * again. There's no easy way to set to a specific value so store init value + * in hpt_offset and subtract each time. + * + * Note: Timer isn't full 32bits so shift it into the upper part making + * it appear to run at a higher frequency. */ -static cycle_t sb1250_hpt_read(void) +static unsigned int sb1250_hpt_read(void) { unsigned int count; count = G_SCD_TIMER_CNT(__raw_readq(IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, R_SCD_TIMER_CNT)))); - return SB1250_HPT_VALUE - count; + count = (SB1250_HPT_VALUE - count) << SB1250_HPT_SHIFT; + + return count - hpt_offset; +} + +static void sb1250_hpt_init(unsigned int count) +{ + hpt_offset = count; + return; } diff --git a/trunk/arch/mips/sni/irq.c b/trunk/arch/mips/sni/irq.c index 8511bcc6d99d..cda165f42b6a 100644 --- a/trunk/arch/mips/sni/irq.c +++ b/trunk/arch/mips/sni/irq.c @@ -11,25 +11,44 @@ #include #include #include +#include #include #include #include +DEFINE_SPINLOCK(pciasic_lock); + static void enable_pciasic_irq(unsigned int irq) { unsigned int mask = 1 << (irq - PCIMT_IRQ_INT2); + unsigned long flags; + spin_lock_irqsave(&pciasic_lock, flags); *(volatile u8 *) PCIMT_IRQSEL |= mask; + spin_unlock_irqrestore(&pciasic_lock, flags); +} + +static unsigned int startup_pciasic_irq(unsigned int irq) +{ + enable_pciasic_irq(irq); + return 0; /* never anything pending */ } +#define shutdown_pciasic_irq disable_pciasic_irq + void disable_pciasic_irq(unsigned int irq) { unsigned int mask = ~(1 << (irq - PCIMT_IRQ_INT2)); + unsigned long flags; + spin_lock_irqsave(&pciasic_lock, flags); *(volatile u8 *) PCIMT_IRQSEL &= mask; + spin_unlock_irqrestore(&pciasic_lock, flags); } +#define mask_and_ack_pciasic_irq disable_pciasic_irq + static void end_pciasic_irq(unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) @@ -38,10 +57,11 @@ static void end_pciasic_irq(unsigned int irq) static struct irq_chip pciasic_irq_type = { .typename = "ASIC-PCI", - .ack = disable_pciasic_irq, - .mask = disable_pciasic_irq, - .mask_ack = disable_pciasic_irq, - .unmask = enable_pciasic_irq, + .startup = startup_pciasic_irq, + .shutdown = shutdown_pciasic_irq, + .enable = enable_pciasic_irq, + .disable = disable_pciasic_irq, + .ack = mask_and_ack_pciasic_irq, .end = end_pciasic_irq, }; @@ -49,20 +69,20 @@ static struct irq_chip pciasic_irq_type = { * hwint0 should deal with MP agent, ASIC PCI, EISA NMI and debug * button interrupts. Later ... */ -static void pciasic_hwint0(void) +static void pciasic_hwint0(struct pt_regs *regs) { panic("Received int0 but no handler yet ..."); } /* This interrupt was used for the com1 console on the first prototypes. */ -static void pciasic_hwint2(void) +static void pciasic_hwint2(struct pt_regs *regs) { /* I think this shouldn't happen on production machines. */ panic("hwint2 and no handler yet"); } /* hwint5 is the r4k count / compare interrupt */ -static void pciasic_hwint5(void) +static void pciasic_hwint5(struct pt_regs *regs) { panic("hwint5 and no handler yet"); } @@ -83,7 +103,7 @@ static unsigned int ls1bit8(unsigned int x) * * The EISA_INT bit in CSITPEND is high active, all others are low active. */ -static void pciasic_hwint1(void) +static void pciasic_hwint1(struct pt_regs *regs) { u8 pend = *(volatile char *)PCIMT_CSITPEND; unsigned long flags; @@ -99,13 +119,13 @@ static void pciasic_hwint1(void) if (unlikely(irq < 0)) return; - do_IRQ(irq); + do_IRQ(irq, regs); } if (!(pend & IT_SCSI)) { flags = read_c0_status(); clear_c0_status(ST0_IM); - do_IRQ(PCIMT_IRQ_SCSI); + do_IRQ(PCIMT_IRQ_SCSI, regs); write_c0_status(flags); } } @@ -113,7 +133,7 @@ static void pciasic_hwint1(void) /* * hwint 3 should deal with the PCI A - D interrupts, */ -static void pciasic_hwint3(void) +static void pciasic_hwint3(struct pt_regs *regs) { u8 pend = *(volatile char *)PCIMT_CSITPEND; int irq; @@ -121,21 +141,21 @@ static void pciasic_hwint3(void) pend &= (IT_INTA | IT_INTB | IT_INTC | IT_INTD); clear_c0_status(IE_IRQ3); irq = PCIMT_IRQ_INT2 + ls1bit8(pend); - do_IRQ(irq); + do_IRQ(irq, regs); set_c0_status(IE_IRQ3); } /* * hwint 4 is used for only the onboard PCnet 32. */ -static void pciasic_hwint4(void) +static void pciasic_hwint4(struct pt_regs *regs) { clear_c0_status(IE_IRQ4); - do_IRQ(PCIMT_IRQ_ETHERNET); + do_IRQ(PCIMT_IRQ_ETHERNET, regs); set_c0_status(IE_IRQ4); } -asmlinkage void plat_irq_dispatch(void) +asmlinkage void plat_irq_dispatch(struct pt_regs *regs) { unsigned int pending = read_c0_status() & read_c0_cause(); static unsigned char led_cache; @@ -143,23 +163,27 @@ asmlinkage void plat_irq_dispatch(void) *(volatile unsigned char *) PCIMT_CSLED = ++led_cache; if (pending & 0x0800) - pciasic_hwint1(); + pciasic_hwint1(regs); else if (pending & 0x4000) - pciasic_hwint4(); + pciasic_hwint4(regs); else if (pending & 0x2000) - pciasic_hwint3(); + pciasic_hwint3(regs); else if (pending & 0x1000) - pciasic_hwint2(); + pciasic_hwint2(regs); else if (pending & 0x8000) - pciasic_hwint5(); + pciasic_hwint5(regs); else if (pending & 0x0400) - pciasic_hwint0(); + pciasic_hwint0(regs); } void __init init_pciasic(void) { + unsigned long flags; + + spin_lock_irqsave(&pciasic_lock, flags); * (volatile u8 *) PCIMT_IRQSEL = IT_EISA | IT_INTA | IT_INTB | IT_INTC | IT_INTD; + spin_unlock_irqrestore(&pciasic_lock, flags); } /* @@ -175,8 +199,12 @@ void __init arch_init_irq(void) init_pciasic(); /* Actually we've got more interrupts to handle ... */ - for (i = PCIMT_IRQ_INT2; i <= PCIMT_IRQ_ETHERNET; i++) - set_irq_chip(i, &pciasic_irq_type); + for (i = PCIMT_IRQ_INT2; i <= PCIMT_IRQ_ETHERNET; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 1; + irq_desc[i].chip = &pciasic_irq_type; + } change_c0_status(ST0_IM, IE_IRQ1|IE_IRQ2|IE_IRQ3|IE_IRQ4); } diff --git a/trunk/arch/mips/sni/setup.c b/trunk/arch/mips/sni/setup.c index afeb7f13e5b5..4e98feb15410 100644 --- a/trunk/arch/mips/sni/setup.c +++ b/trunk/arch/mips/sni/setup.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/mips/tx4927/common/smsc_fdc37m81x.c b/trunk/arch/mips/tx4927/common/smsc_fdc37m81x.c deleted file mode 100644 index 33f517bc9a08..000000000000 --- a/trunk/arch/mips/tx4927/common/smsc_fdc37m81x.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Interface for smsc fdc48m81x Super IO chip - * - * Author: MontaVista Software, Inc. source@mvista.com - * - * 2001-2003 (c) MontaVista Software, Inc. 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. - * - * Copyright 2004 (c) MontaVista Software, Inc. - */ -#include -#include -#include -#include - -#define DEBUG - -/* Common Registers */ -#define SMSC_FDC37M81X_CONFIG_INDEX 0x00 -#define SMSC_FDC37M81X_CONFIG_DATA 0x01 -#define SMSC_FDC37M81X_CONF 0x02 -#define SMSC_FDC37M81X_INDEX 0x03 -#define SMSC_FDC37M81X_DNUM 0x07 -#define SMSC_FDC37M81X_DID 0x20 -#define SMSC_FDC37M81X_DREV 0x21 -#define SMSC_FDC37M81X_PCNT 0x22 -#define SMSC_FDC37M81X_PMGT 0x23 -#define SMSC_FDC37M81X_OSC 0x24 -#define SMSC_FDC37M81X_CONFPA0 0x26 -#define SMSC_FDC37M81X_CONFPA1 0x27 -#define SMSC_FDC37M81X_TEST4 0x2B -#define SMSC_FDC37M81X_TEST5 0x2C -#define SMSC_FDC37M81X_TEST1 0x2D -#define SMSC_FDC37M81X_TEST2 0x2E -#define SMSC_FDC37M81X_TEST3 0x2F - -/* Logical device numbers */ -#define SMSC_FDC37M81X_FDD 0x00 -#define SMSC_FDC37M81X_SERIAL1 0x04 -#define SMSC_FDC37M81X_SERIAL2 0x05 -#define SMSC_FDC37M81X_KBD 0x07 - -/* Logical device Config Registers */ -#define SMSC_FDC37M81X_ACTIVE 0x30 -#define SMSC_FDC37M81X_BASEADDR0 0x60 -#define SMSC_FDC37M81X_BASEADDR1 0x61 -#define SMSC_FDC37M81X_INT 0x70 -#define SMSC_FDC37M81X_INT2 0x72 -#define SMSC_FDC37M81X_MODE 0xF0 - -/* Chip Config Values */ -#define SMSC_FDC37M81X_CONFIG_ENTER 0x55 -#define SMSC_FDC37M81X_CONFIG_EXIT 0xaa -#define SMSC_FDC37M81X_CHIP_ID 0x4d - -static unsigned long g_smsc_fdc37m81x_base = 0; - -static inline unsigned char smsc_fdc37m81x_rd(unsigned char index) -{ - outb(index, g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX); - - return inb(g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_DATA); -} - -static inline void smsc_dc37m81x_wr(unsigned char index, unsigned char data) -{ - outb(index, g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX); - outb(data, g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_DATA); -} - -void smsc_fdc37m81x_config_beg(void) -{ - if (g_smsc_fdc37m81x_base) { - outb(SMSC_FDC37M81X_CONFIG_ENTER, - g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX); - } -} - -void smsc_fdc37m81x_config_end(void) -{ - if (g_smsc_fdc37m81x_base) - outb(SMSC_FDC37M81X_CONFIG_EXIT, - g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX); -} - -u8 smsc_fdc37m81x_config_get(u8 reg) -{ - u8 val = 0; - - if (g_smsc_fdc37m81x_base) - val = smsc_fdc37m81x_rd(reg); - - return val; -} - -void smsc_fdc37m81x_config_set(u8 reg, u8 val) -{ - if (g_smsc_fdc37m81x_base) - smsc_dc37m81x_wr(reg, val); -} - -unsigned long __init smsc_fdc37m81x_init(unsigned long port) -{ - const int field = sizeof(unsigned long) * 2; - u8 chip_id; - - if (g_smsc_fdc37m81x_base) - printk("smsc_fdc37m81x_init() stepping on old base=0x%0*lx\n", - field, g_smsc_fdc37m81x_base); - - g_smsc_fdc37m81x_base = port; - - smsc_fdc37m81x_config_beg(); - - chip_id = smsc_fdc37m81x_rd(SMSC_FDC37M81X_DID); - if (chip_id == SMSC_FDC37M81X_CHIP_ID) - smsc_fdc37m81x_config_end(); - else { - printk("smsc_fdc37m81x_init() unknow chip id 0x%02x\n", - chip_id); - g_smsc_fdc37m81x_base = 0; - } - - return g_smsc_fdc37m81x_base; -} - -#ifdef DEBUG -void smsc_fdc37m81x_config_dump_one(char *key, u8 dev, u8 reg) -{ - printk("%s: dev=0x%02x reg=0x%02x val=0x%02x\n", key, dev, reg, - smsc_fdc37m81x_rd(reg)); -} - -void smsc_fdc37m81x_config_dump(void) -{ - u8 orig; - char *fname = "smsc_fdc37m81x_config_dump()"; - - smsc_fdc37m81x_config_beg(); - - orig = smsc_fdc37m81x_rd(SMSC_FDC37M81X_DNUM); - - printk("%s: common\n", fname); - smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE, - SMSC_FDC37M81X_DNUM); - smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE, - SMSC_FDC37M81X_DID); - smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE, - SMSC_FDC37M81X_DREV); - smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE, - SMSC_FDC37M81X_PCNT); - smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE, - SMSC_FDC37M81X_PMGT); - - printk("%s: keyboard\n", fname); - smsc_dc37m81x_wr(SMSC_FDC37M81X_DNUM, SMSC_FDC37M81X_KBD); - smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD, - SMSC_FDC37M81X_ACTIVE); - smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD, - SMSC_FDC37M81X_INT); - smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD, - SMSC_FDC37M81X_INT2); - smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD, - SMSC_FDC37M81X_LDCR_F0); - - smsc_dc37m81x_wr(SMSC_FDC37M81X_DNUM, orig); - - smsc_fdc37m81x_config_end(); -} -#endif diff --git a/trunk/arch/mips/tx4927/common/tx4927_irq.c b/trunk/arch/mips/tx4927/common/tx4927_irq.c index 21873de49aa8..cd176f6a06c8 100644 --- a/trunk/arch/mips/tx4927/common/tx4927_irq.c +++ b/trunk/arch/mips/tx4927/common/tx4927_irq.c @@ -64,13 +64,19 @@ #define TX4927_IRQ_NEST4 ( 1 << 9 ) #define TX4927_IRQ_CP0_INIT ( 1 << 10 ) +#define TX4927_IRQ_CP0_STARTUP ( 1 << 11 ) +#define TX4927_IRQ_CP0_SHUTDOWN ( 1 << 12 ) #define TX4927_IRQ_CP0_ENABLE ( 1 << 13 ) #define TX4927_IRQ_CP0_DISABLE ( 1 << 14 ) +#define TX4927_IRQ_CP0_MASK ( 1 << 15 ) #define TX4927_IRQ_CP0_ENDIRQ ( 1 << 16 ) #define TX4927_IRQ_PIC_INIT ( 1 << 20 ) +#define TX4927_IRQ_PIC_STARTUP ( 1 << 21 ) +#define TX4927_IRQ_PIC_SHUTDOWN ( 1 << 22 ) #define TX4927_IRQ_PIC_ENABLE ( 1 << 23 ) #define TX4927_IRQ_PIC_DISABLE ( 1 << 24 ) +#define TX4927_IRQ_PIC_MASK ( 1 << 25 ) #define TX4927_IRQ_PIC_ENDIRQ ( 1 << 26 ) #define TX4927_IRQ_ALL 0xffffffff @@ -81,12 +87,18 @@ static const u32 tx4927_irq_debug_flag = (TX4927_IRQ_NONE | TX4927_IRQ_INFO | TX4927_IRQ_WARN | TX4927_IRQ_EROR // | TX4927_IRQ_CP0_INIT +// | TX4927_IRQ_CP0_STARTUP +// | TX4927_IRQ_CP0_SHUTDOWN // | TX4927_IRQ_CP0_ENABLE // | TX4927_IRQ_CP0_DISABLE +// | TX4927_IRQ_CP0_MASK // | TX4927_IRQ_CP0_ENDIRQ // | TX4927_IRQ_PIC_INIT +// | TX4927_IRQ_PIC_STARTUP +// | TX4927_IRQ_PIC_SHUTDOWN // | TX4927_IRQ_PIC_ENABLE // | TX4927_IRQ_PIC_DISABLE +// | TX4927_IRQ_PIC_MASK // | TX4927_IRQ_PIC_ENDIRQ // | TX4927_IRQ_INIT // | TX4927_IRQ_NEST1 @@ -112,36 +124,49 @@ static const u32 tx4927_irq_debug_flag = (TX4927_IRQ_NONE * Forwad definitions for all pic's */ +static unsigned int tx4927_irq_cp0_startup(unsigned int irq); +static void tx4927_irq_cp0_shutdown(unsigned int irq); static void tx4927_irq_cp0_enable(unsigned int irq); static void tx4927_irq_cp0_disable(unsigned int irq); +static void tx4927_irq_cp0_mask_and_ack(unsigned int irq); static void tx4927_irq_cp0_end(unsigned int irq); +static unsigned int tx4927_irq_pic_startup(unsigned int irq); +static void tx4927_irq_pic_shutdown(unsigned int irq); static void tx4927_irq_pic_enable(unsigned int irq); static void tx4927_irq_pic_disable(unsigned int irq); +static void tx4927_irq_pic_mask_and_ack(unsigned int irq); static void tx4927_irq_pic_end(unsigned int irq); /* * Kernel structs for all pic's */ +static DEFINE_SPINLOCK(tx4927_cp0_lock); +static DEFINE_SPINLOCK(tx4927_pic_lock); + #define TX4927_CP0_NAME "TX4927-CP0" static struct irq_chip tx4927_irq_cp0_type = { .typename = TX4927_CP0_NAME, - .ack = tx4927_irq_cp0_disable, - .mask = tx4927_irq_cp0_disable, - .mask_ack = tx4927_irq_cp0_disable, - .unmask = tx4927_irq_cp0_enable, + .startup = tx4927_irq_cp0_startup, + .shutdown = tx4927_irq_cp0_shutdown, + .enable = tx4927_irq_cp0_enable, + .disable = tx4927_irq_cp0_disable, + .ack = tx4927_irq_cp0_mask_and_ack, .end = tx4927_irq_cp0_end, + .set_affinity = NULL }; #define TX4927_PIC_NAME "TX4927-PIC" static struct irq_chip tx4927_irq_pic_type = { .typename = TX4927_PIC_NAME, - .ack = tx4927_irq_pic_disable, - .mask = tx4927_irq_pic_disable, - .mask_ack = tx4927_irq_pic_disable, - .unmask = tx4927_irq_pic_enable, + .startup = tx4927_irq_pic_startup, + .shutdown = tx4927_irq_pic_shutdown, + .enable = tx4927_irq_pic_enable, + .disable = tx4927_irq_pic_disable, + .ack = tx4927_irq_pic_mask_and_ack, .end = tx4927_irq_pic_end, + .set_affinity = NULL }; #define TX4927_PIC_ACTION(s) { no_action, 0, CPU_MASK_NONE, s, NULL, NULL } @@ -186,6 +211,8 @@ tx4927_irq_cp0_modify(unsigned cp0_reg, unsigned clr_bits, unsigned set_bits) break; } } + + return; } static void __init tx4927_irq_cp0_init(void) @@ -195,23 +222,71 @@ static void __init tx4927_irq_cp0_init(void) TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_INIT, "beg=%d end=%d\n", TX4927_IRQ_CP0_BEG, TX4927_IRQ_CP0_END); - for (i = TX4927_IRQ_CP0_BEG; i <= TX4927_IRQ_CP0_END; i++) - set_irq_chip_and_handler(i, &tx4927_irq_cp0_type, - handle_level_irq); + for (i = TX4927_IRQ_CP0_BEG; i <= TX4927_IRQ_CP0_END; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 1; + irq_desc[i].chip = &tx4927_irq_cp0_type; + } + + return; +} + +static unsigned int tx4927_irq_cp0_startup(unsigned int irq) +{ + TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_STARTUP, "irq=%d \n", irq); + + tx4927_irq_cp0_enable(irq); + + return (0); +} + +static void tx4927_irq_cp0_shutdown(unsigned int irq) +{ + TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_SHUTDOWN, "irq=%d \n", irq); + + tx4927_irq_cp0_disable(irq); + + return; } static void tx4927_irq_cp0_enable(unsigned int irq) { + unsigned long flags; + TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_ENABLE, "irq=%d \n", irq); + spin_lock_irqsave(&tx4927_cp0_lock, flags); + tx4927_irq_cp0_modify(CCP0_STATUS, 0, tx4927_irq_cp0_mask(irq)); + + spin_unlock_irqrestore(&tx4927_cp0_lock, flags); + + return; } static void tx4927_irq_cp0_disable(unsigned int irq) { + unsigned long flags; + TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_DISABLE, "irq=%d \n", irq); + spin_lock_irqsave(&tx4927_cp0_lock, flags); + tx4927_irq_cp0_modify(CCP0_STATUS, tx4927_irq_cp0_mask(irq), 0); + + spin_unlock_irqrestore(&tx4927_cp0_lock, flags); + + return; +} + +static void tx4927_irq_cp0_mask_and_ack(unsigned int irq) +{ + TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_MASK, "irq=%d \n", irq); + + tx4927_irq_cp0_disable(irq); + + return; } static void tx4927_irq_cp0_end(unsigned int irq) @@ -221,6 +296,8 @@ static void tx4927_irq_cp0_end(unsigned int irq) if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { tx4927_irq_cp0_enable(irq); } + + return; } /* @@ -341,39 +418,94 @@ static void tx4927_irq_pic_modify(unsigned pic_reg, unsigned clr_bits, val &= (~clr_bits); val |= (set_bits); TX4927_WR(pic_reg, val); + + return; } static void __init tx4927_irq_pic_init(void) { + unsigned long flags; int i; TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_INIT, "beg=%d end=%d\n", TX4927_IRQ_PIC_BEG, TX4927_IRQ_PIC_END); - for (i = TX4927_IRQ_PIC_BEG; i <= TX4927_IRQ_PIC_END; i++) - set_irq_chip_and_handler(i, &tx4927_irq_pic_type, - handle_level_irq); + for (i = TX4927_IRQ_PIC_BEG; i <= TX4927_IRQ_PIC_END; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 2; + irq_desc[i].chip = &tx4927_irq_pic_type; + } setup_irq(TX4927_IRQ_NEST_PIC_ON_CP0, &tx4927_irq_pic_action); + spin_lock_irqsave(&tx4927_pic_lock, flags); + TX4927_WR(0xff1ff640, 0x6); /* irq level mask -- only accept hightest */ TX4927_WR(0xff1ff600, TX4927_RD(0xff1ff600) | 0x1); /* irq enable */ + + spin_unlock_irqrestore(&tx4927_pic_lock, flags); + + return; +} + +static unsigned int tx4927_irq_pic_startup(unsigned int irq) +{ + TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_STARTUP, "irq=%d\n", irq); + + tx4927_irq_pic_enable(irq); + + return (0); +} + +static void tx4927_irq_pic_shutdown(unsigned int irq) +{ + TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_SHUTDOWN, "irq=%d\n", irq); + + tx4927_irq_pic_disable(irq); + + return; } static void tx4927_irq_pic_enable(unsigned int irq) { + unsigned long flags; + TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_ENABLE, "irq=%d\n", irq); + spin_lock_irqsave(&tx4927_pic_lock, flags); + tx4927_irq_pic_modify(tx4927_irq_pic_addr(irq), 0, tx4927_irq_pic_mask(irq)); + + spin_unlock_irqrestore(&tx4927_pic_lock, flags); + + return; } static void tx4927_irq_pic_disable(unsigned int irq) { + unsigned long flags; + TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_DISABLE, "irq=%d\n", irq); + spin_lock_irqsave(&tx4927_pic_lock, flags); + tx4927_irq_pic_modify(tx4927_irq_pic_addr(irq), tx4927_irq_pic_mask(irq), 0); + + spin_unlock_irqrestore(&tx4927_pic_lock, flags); + + return; +} + +static void tx4927_irq_pic_mask_and_ack(unsigned int irq) +{ + TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_MASK, "irq=%d\n", irq); + + tx4927_irq_pic_disable(irq); + + return; } static void tx4927_irq_pic_end(unsigned int irq) @@ -383,6 +515,8 @@ static void tx4927_irq_pic_end(unsigned int irq) if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { tx4927_irq_pic_enable(irq); } + + return; } /* @@ -399,6 +533,8 @@ void __init tx4927_irq_init(void) tx4927_irq_pic_init(); TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "+\n"); + + return; } static int tx4927_irq_nested(void) @@ -440,24 +576,24 @@ static int tx4927_irq_nested(void) return (sw_irq); } -asmlinkage void plat_irq_dispatch(void) +asmlinkage void plat_irq_dispatch(struct pt_regs *regs) { unsigned int pending = read_c0_status() & read_c0_cause(); if (pending & STATUSF_IP7) /* cpu timer */ - do_IRQ(TX4927_IRQ_CPU_TIMER); + do_IRQ(TX4927_IRQ_CPU_TIMER, regs); else if (pending & STATUSF_IP2) { /* tx4927 pic */ unsigned int irq = tx4927_irq_nested(); if (unlikely(irq == 0)) { - spurious_interrupt(); + spurious_interrupt(regs); return; } - do_IRQ(irq); + do_IRQ(irq, regs); } else if (pending & STATUSF_IP0) /* user line 0 */ - do_IRQ(TX4927_IRQ_USER0); + do_IRQ(TX4927_IRQ_USER0, regs); else if (pending & STATUSF_IP1) /* user line 1 */ - do_IRQ(TX4927_IRQ_USER1); + do_IRQ(TX4927_IRQ_USER1, regs); else - spurious_interrupt(); + spurious_interrupt(regs); } diff --git a/trunk/arch/mips/tx4927/common/tx4927_setup.c b/trunk/arch/mips/tx4927/common/tx4927_setup.c index 941c441729b0..3ace4037343e 100644 --- a/trunk/arch/mips/tx4927/common/tx4927_setup.c +++ b/trunk/arch/mips/tx4927/common/tx4927_setup.c @@ -53,9 +53,19 @@ void __init tx4927_time_init(void); void dump_cp0(char *key); +void (*__wbflush) (void); + +static void tx4927_write_buffer_flush(void) +{ + __asm__ __volatile__ + ("sync\n\t" "nop\n\t" "loop: bc0f loop\n\t" "nop\n\t"); +} + + void __init plat_mem_setup(void) { board_time_init = tx4927_time_init; + __wbflush = tx4927_write_buffer_flush; #ifdef CONFIG_TOSHIBA_RBTX4927 { @@ -112,6 +122,8 @@ void print_cp0(char *key, int num, char *name, u32 val) return; } +indent: Standard input:25: Error:Unexpected end of file + void dump_cp0(char *key) { diff --git a/trunk/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c b/trunk/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c index 34cdb2a240e9..b0f021f2a6c4 100644 --- a/trunk/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c +++ b/trunk/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c @@ -127,9 +127,9 @@ JP7 is not bus master -- do NOT use -- only 4 pci bus master's allowed -- SouthB #include #include #include +#include #include #include -#include #include #include #ifdef CONFIG_RTC_DS1742 @@ -151,11 +151,16 @@ JP7 is not bus master -- do NOT use -- only 4 pci bus master's allowed -- SouthB #define TOSHIBA_RBTX4927_IRQ_EROR ( 1 << 2 ) #define TOSHIBA_RBTX4927_IRQ_IOC_INIT ( 1 << 10 ) +#define TOSHIBA_RBTX4927_IRQ_IOC_STARTUP ( 1 << 11 ) +#define TOSHIBA_RBTX4927_IRQ_IOC_SHUTDOWN ( 1 << 12 ) #define TOSHIBA_RBTX4927_IRQ_IOC_ENABLE ( 1 << 13 ) #define TOSHIBA_RBTX4927_IRQ_IOC_DISABLE ( 1 << 14 ) +#define TOSHIBA_RBTX4927_IRQ_IOC_MASK ( 1 << 15 ) #define TOSHIBA_RBTX4927_IRQ_IOC_ENDIRQ ( 1 << 16 ) #define TOSHIBA_RBTX4927_IRQ_ISA_INIT ( 1 << 20 ) +#define TOSHIBA_RBTX4927_IRQ_ISA_STARTUP ( 1 << 21 ) +#define TOSHIBA_RBTX4927_IRQ_ISA_SHUTDOWN ( 1 << 22 ) #define TOSHIBA_RBTX4927_IRQ_ISA_ENABLE ( 1 << 23 ) #define TOSHIBA_RBTX4927_IRQ_ISA_DISABLE ( 1 << 24 ) #define TOSHIBA_RBTX4927_IRQ_ISA_MASK ( 1 << 25 ) @@ -170,10 +175,15 @@ static const u32 toshiba_rbtx4927_irq_debug_flag = (TOSHIBA_RBTX4927_IRQ_NONE | TOSHIBA_RBTX4927_IRQ_INFO | TOSHIBA_RBTX4927_IRQ_WARN | TOSHIBA_RBTX4927_IRQ_EROR // | TOSHIBA_RBTX4927_IRQ_IOC_INIT +// | TOSHIBA_RBTX4927_IRQ_IOC_STARTUP +// | TOSHIBA_RBTX4927_IRQ_IOC_SHUTDOWN // | TOSHIBA_RBTX4927_IRQ_IOC_ENABLE // | TOSHIBA_RBTX4927_IRQ_IOC_DISABLE +// | TOSHIBA_RBTX4927_IRQ_IOC_MASK // | TOSHIBA_RBTX4927_IRQ_IOC_ENDIRQ // | TOSHIBA_RBTX4927_IRQ_ISA_INIT +// | TOSHIBA_RBTX4927_IRQ_ISA_STARTUP +// | TOSHIBA_RBTX4927_IRQ_ISA_SHUTDOWN // | TOSHIBA_RBTX4927_IRQ_ISA_ENABLE // | TOSHIBA_RBTX4927_IRQ_ISA_DISABLE // | TOSHIBA_RBTX4927_IRQ_ISA_MASK @@ -221,25 +231,35 @@ extern void disable_8259A_irq(unsigned int irq); extern void mask_and_ack_8259A(unsigned int irq); #endif +static unsigned int toshiba_rbtx4927_irq_ioc_startup(unsigned int irq); +static void toshiba_rbtx4927_irq_ioc_shutdown(unsigned int irq); static void toshiba_rbtx4927_irq_ioc_enable(unsigned int irq); static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq); +static void toshiba_rbtx4927_irq_ioc_mask_and_ack(unsigned int irq); static void toshiba_rbtx4927_irq_ioc_end(unsigned int irq); #ifdef CONFIG_TOSHIBA_FPCIB0 +static unsigned int toshiba_rbtx4927_irq_isa_startup(unsigned int irq); +static void toshiba_rbtx4927_irq_isa_shutdown(unsigned int irq); static void toshiba_rbtx4927_irq_isa_enable(unsigned int irq); static void toshiba_rbtx4927_irq_isa_disable(unsigned int irq); static void toshiba_rbtx4927_irq_isa_mask_and_ack(unsigned int irq); static void toshiba_rbtx4927_irq_isa_end(unsigned int irq); #endif +static DEFINE_SPINLOCK(toshiba_rbtx4927_ioc_lock); + + #define TOSHIBA_RBTX4927_IOC_NAME "RBTX4927-IOC" static struct irq_chip toshiba_rbtx4927_irq_ioc_type = { .typename = TOSHIBA_RBTX4927_IOC_NAME, - .ack = toshiba_rbtx4927_irq_ioc_disable, - .mask = toshiba_rbtx4927_irq_ioc_disable, - .mask_ack = toshiba_rbtx4927_irq_ioc_disable, - .unmask = toshiba_rbtx4927_irq_ioc_enable, + .startup = toshiba_rbtx4927_irq_ioc_startup, + .shutdown = toshiba_rbtx4927_irq_ioc_shutdown, + .enable = toshiba_rbtx4927_irq_ioc_enable, + .disable = toshiba_rbtx4927_irq_ioc_disable, + .ack = toshiba_rbtx4927_irq_ioc_mask_and_ack, .end = toshiba_rbtx4927_irq_ioc_end, + .set_affinity = NULL }; #define TOSHIBA_RBTX4927_IOC_INTR_ENAB 0xbc002000 #define TOSHIBA_RBTX4927_IOC_INTR_STAT 0xbc002006 @@ -249,11 +269,13 @@ static struct irq_chip toshiba_rbtx4927_irq_ioc_type = { #define TOSHIBA_RBTX4927_ISA_NAME "RBTX4927-ISA" static struct irq_chip toshiba_rbtx4927_irq_isa_type = { .typename = TOSHIBA_RBTX4927_ISA_NAME, + .startup = toshiba_rbtx4927_irq_isa_startup, + .shutdown = toshiba_rbtx4927_irq_isa_shutdown, + .enable = toshiba_rbtx4927_irq_isa_enable, + .disable = toshiba_rbtx4927_irq_isa_disable, .ack = toshiba_rbtx4927_irq_isa_mask_and_ack, - .mask = toshiba_rbtx4927_irq_isa_disable, - .mask_ack = toshiba_rbtx4927_irq_isa_mask_and_ack, - .unmask = toshiba_rbtx4927_irq_isa_enable, .end = toshiba_rbtx4927_irq_isa_end, + .set_affinity = NULL }; #endif @@ -341,16 +363,58 @@ static void __init toshiba_rbtx4927_irq_ioc_init(void) TOSHIBA_RBTX4927_IRQ_IOC_END); for (i = TOSHIBA_RBTX4927_IRQ_IOC_BEG; - i <= TOSHIBA_RBTX4927_IRQ_IOC_END; i++) - set_irq_chip_and_handler(i, &toshiba_rbtx4927_irq_ioc_type, - handle_level_irq); + i <= TOSHIBA_RBTX4927_IRQ_IOC_END; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 3; + irq_desc[i].chip = &toshiba_rbtx4927_irq_ioc_type; + } setup_irq(TOSHIBA_RBTX4927_IRQ_NEST_IOC_ON_PIC, &toshiba_rbtx4927_irq_ioc_action); + + return; } +static unsigned int toshiba_rbtx4927_irq_ioc_startup(unsigned int irq) +{ + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_STARTUP, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_IOC_BEG + || irq > TOSHIBA_RBTX4927_IRQ_IOC_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + toshiba_rbtx4927_irq_ioc_enable(irq); + + return (0); +} + + +static void toshiba_rbtx4927_irq_ioc_shutdown(unsigned int irq) +{ + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_SHUTDOWN, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_IOC_BEG + || irq > TOSHIBA_RBTX4927_IRQ_IOC_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + toshiba_rbtx4927_irq_ioc_disable(irq); + + return; +} + + static void toshiba_rbtx4927_irq_ioc_enable(unsigned int irq) { + unsigned long flags; volatile unsigned char v; TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_ENABLE, @@ -363,14 +427,21 @@ static void toshiba_rbtx4927_irq_ioc_enable(unsigned int irq) panic("\n"); } + spin_lock_irqsave(&toshiba_rbtx4927_ioc_lock, flags); + v = TX4927_RD08(TOSHIBA_RBTX4927_IOC_INTR_ENAB); v |= (1 << (irq - TOSHIBA_RBTX4927_IRQ_IOC_BEG)); TOSHIBA_RBTX4927_WR08(TOSHIBA_RBTX4927_IOC_INTR_ENAB, v); + + spin_unlock_irqrestore(&toshiba_rbtx4927_ioc_lock, flags); + + return; } static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq) { + unsigned long flags; volatile unsigned char v; TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_DISABLE, @@ -383,11 +454,36 @@ static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq) panic("\n"); } + spin_lock_irqsave(&toshiba_rbtx4927_ioc_lock, flags); + v = TX4927_RD08(TOSHIBA_RBTX4927_IOC_INTR_ENAB); v &= ~(1 << (irq - TOSHIBA_RBTX4927_IRQ_IOC_BEG)); TOSHIBA_RBTX4927_WR08(TOSHIBA_RBTX4927_IOC_INTR_ENAB, v); + + spin_unlock_irqrestore(&toshiba_rbtx4927_ioc_lock, flags); + + return; } + +static void toshiba_rbtx4927_irq_ioc_mask_and_ack(unsigned int irq) +{ + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_MASK, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_IOC_BEG + || irq > TOSHIBA_RBTX4927_IRQ_IOC_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + toshiba_rbtx4927_irq_ioc_disable(irq); + + return; +} + + static void toshiba_rbtx4927_irq_ioc_end(unsigned int irq) { TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_ENDIRQ, @@ -403,6 +499,8 @@ static void toshiba_rbtx4927_irq_ioc_end(unsigned int irq) if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { toshiba_rbtx4927_irq_ioc_enable(irq); } + + return; } @@ -422,8 +520,13 @@ static void __init toshiba_rbtx4927_irq_isa_init(void) TOSHIBA_RBTX4927_IRQ_ISA_END); for (i = TOSHIBA_RBTX4927_IRQ_ISA_BEG; - i <= TOSHIBA_RBTX4927_IRQ_ISA_END; i++) - set_irq_chip(i, &toshiba_rbtx4927_irq_isa_type); + i <= TOSHIBA_RBTX4927_IRQ_ISA_END; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = + ((i < TOSHIBA_RBTX4927_IRQ_ISA_MID) ? (4) : (5)); + irq_desc[i].chip = &toshiba_rbtx4927_irq_isa_type; + } setup_irq(TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_IOC, &toshiba_rbtx4927_irq_isa_master); @@ -433,6 +536,48 @@ static void __init toshiba_rbtx4927_irq_isa_init(void) /* make sure we are looking at IRR (not ISR) */ outb(0x0A, 0x20); outb(0x0A, 0xA0); + + return; +} +#endif + + +#ifdef CONFIG_TOSHIBA_FPCIB0 +static unsigned int toshiba_rbtx4927_irq_isa_startup(unsigned int irq) +{ + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_ISA_STARTUP, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_ISA_BEG + || irq > TOSHIBA_RBTX4927_IRQ_ISA_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + toshiba_rbtx4927_irq_isa_enable(irq); + + return (0); +} +#endif + + +#ifdef CONFIG_TOSHIBA_FPCIB0 +static void toshiba_rbtx4927_irq_isa_shutdown(unsigned int irq) +{ + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_ISA_SHUTDOWN, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_ISA_BEG + || irq > TOSHIBA_RBTX4927_IRQ_ISA_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + toshiba_rbtx4927_irq_isa_disable(irq); + + return; } #endif @@ -451,6 +596,8 @@ static void toshiba_rbtx4927_irq_isa_enable(unsigned int irq) } enable_8259A_irq(irq); + + return; } #endif @@ -469,6 +616,8 @@ static void toshiba_rbtx4927_irq_isa_disable(unsigned int irq) } disable_8259A_irq(irq); + + return; } #endif @@ -487,6 +636,8 @@ static void toshiba_rbtx4927_irq_isa_mask_and_ack(unsigned int irq) } mask_and_ack_8259A(irq); + + return; } #endif @@ -507,6 +658,8 @@ static void toshiba_rbtx4927_irq_isa_end(unsigned int irq) if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { toshiba_rbtx4927_irq_isa_enable(irq); } + + return; } #endif @@ -515,6 +668,8 @@ void __init arch_init_irq(void) { extern void tx4927_irq_init(void); + local_irq_disable(); + tx4927_irq_init(); toshiba_rbtx4927_irq_ioc_init(); #ifdef CONFIG_TOSHIBA_FPCIB0 @@ -526,6 +681,8 @@ void __init arch_init_irq(void) #endif wbflush(); + + return; } void toshiba_rbtx4927_irq_dump(char *key) @@ -558,6 +715,7 @@ void toshiba_rbtx4927_irq_dump(char *key) } } #endif + return; } void toshiba_rbtx4927_irq_dump_pics(char *s) @@ -622,4 +780,6 @@ void toshiba_rbtx4927_irq_dump_pics(char *s) level5_s); TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO, "[%s]\n", s); + + return; } diff --git a/trunk/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c b/trunk/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c index 735cb8778f4c..f0d70c476005 100644 --- a/trunk/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c +++ b/trunk/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c @@ -58,8 +58,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -160,7 +160,8 @@ int tx4927_pci66 = 0; /* 0:auto */ char *toshiba_name = ""; #ifdef CONFIG_PCI -static void tx4927_pcierr_interrupt(int irq, void *dev_id) +static void tx4927_pcierr_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { #ifdef CONFIG_BLK_DEV_IDEPCI /* ignore MasterAbort for ide probing... */ @@ -184,7 +185,7 @@ static void tx4927_pcierr_interrupt(int irq, void *dev_id) (unsigned long) tx4927_ccfgptr->ccfg, (unsigned long) (tx4927_ccfgptr->tear >> 32), (unsigned long) tx4927_ccfgptr->tear); - show_regs(get_irq_regs()); + show_regs(regs); } void __init toshiba_rbtx4927_pci_irq_init(void) diff --git a/trunk/arch/mips/tx4938/common/irq.c b/trunk/arch/mips/tx4938/common/irq.c index 42e127683ae9..cbfb34221b59 100644 --- a/trunk/arch/mips/tx4938/common/irq.c +++ b/trunk/arch/mips/tx4938/common/irq.c @@ -30,43 +30,54 @@ #include #include #include -#include #include /**********************************************************************************/ /* Forwad definitions for all pic's */ /**********************************************************************************/ +static unsigned int tx4938_irq_cp0_startup(unsigned int irq); +static void tx4938_irq_cp0_shutdown(unsigned int irq); static void tx4938_irq_cp0_enable(unsigned int irq); static void tx4938_irq_cp0_disable(unsigned int irq); +static void tx4938_irq_cp0_mask_and_ack(unsigned int irq); static void tx4938_irq_cp0_end(unsigned int irq); +static unsigned int tx4938_irq_pic_startup(unsigned int irq); +static void tx4938_irq_pic_shutdown(unsigned int irq); static void tx4938_irq_pic_enable(unsigned int irq); static void tx4938_irq_pic_disable(unsigned int irq); +static void tx4938_irq_pic_mask_and_ack(unsigned int irq); static void tx4938_irq_pic_end(unsigned int irq); /**********************************************************************************/ /* Kernel structs for all pic's */ /**********************************************************************************/ +DEFINE_SPINLOCK(tx4938_cp0_lock); +DEFINE_SPINLOCK(tx4938_pic_lock); #define TX4938_CP0_NAME "TX4938-CP0" static struct irq_chip tx4938_irq_cp0_type = { .typename = TX4938_CP0_NAME, - .ack = tx4938_irq_cp0_disable, - .mask = tx4938_irq_cp0_disable, - .mask_ack = tx4938_irq_cp0_disable, - .unmask = tx4938_irq_cp0_enable, + .startup = tx4938_irq_cp0_startup, + .shutdown = tx4938_irq_cp0_shutdown, + .enable = tx4938_irq_cp0_enable, + .disable = tx4938_irq_cp0_disable, + .ack = tx4938_irq_cp0_mask_and_ack, .end = tx4938_irq_cp0_end, + .set_affinity = NULL }; #define TX4938_PIC_NAME "TX4938-PIC" static struct irq_chip tx4938_irq_pic_type = { .typename = TX4938_PIC_NAME, - .ack = tx4938_irq_pic_disable, - .mask = tx4938_irq_pic_disable, - .mask_ack = tx4938_irq_pic_disable, - .unmask = tx4938_irq_pic_enable, + .startup = tx4938_irq_pic_startup, + .shutdown = tx4938_irq_pic_shutdown, + .enable = tx4938_irq_pic_enable, + .disable = tx4938_irq_pic_disable, + .ack = tx4938_irq_pic_mask_and_ack, .end = tx4938_irq_pic_end, + .set_affinity = NULL }; static struct irqaction tx4938_irq_pic_action = { @@ -87,21 +98,62 @@ tx4938_irq_cp0_init(void) { int i; - for (i = TX4938_IRQ_CP0_BEG; i <= TX4938_IRQ_CP0_END; i++) - set_irq_chip_and_handler(i, &tx4938_irq_cp0_type, - handle_level_irq); + for (i = TX4938_IRQ_CP0_BEG; i <= TX4938_IRQ_CP0_END; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 1; + irq_desc[i].chip = &tx4938_irq_cp0_type; + } + + return; +} + +static unsigned int +tx4938_irq_cp0_startup(unsigned int irq) +{ + tx4938_irq_cp0_enable(irq); + + return (0); +} + +static void +tx4938_irq_cp0_shutdown(unsigned int irq) +{ + tx4938_irq_cp0_disable(irq); } static void tx4938_irq_cp0_enable(unsigned int irq) { + unsigned long flags; + + spin_lock_irqsave(&tx4938_cp0_lock, flags); + set_c0_status(tx4938_irq_cp0_mask(irq)); + + spin_unlock_irqrestore(&tx4938_cp0_lock, flags); } static void tx4938_irq_cp0_disable(unsigned int irq) { + unsigned long flags; + + spin_lock_irqsave(&tx4938_cp0_lock, flags); + clear_c0_status(tx4938_irq_cp0_mask(irq)); + + spin_unlock_irqrestore(&tx4938_cp0_lock, flags); + + return; +} + +static void +tx4938_irq_cp0_mask_and_ack(unsigned int irq) +{ + tx4938_irq_cp0_disable(irq); + + return; } static void @@ -110,6 +162,8 @@ tx4938_irq_cp0_end(unsigned int irq) if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { tx4938_irq_cp0_enable(irq); } + + return; } /**********************************************************************************/ @@ -173,7 +227,7 @@ tx4938_irq_pic_addr(int irq) } } - return 0; + return (0); } u32 @@ -224,7 +278,7 @@ tx4938_irq_pic_mask(int irq) return (0x00000007); } } - return 0x00000000; + return (0x00000000); } static void @@ -238,35 +292,87 @@ tx4938_irq_pic_modify(unsigned pic_reg, unsigned clr_bits, unsigned set_bits) TX4938_WR(pic_reg, val); mmiowb(); TX4938_RD(pic_reg); + + return; } static void __init tx4938_irq_pic_init(void) { + unsigned long flags; int i; - for (i = TX4938_IRQ_PIC_BEG; i <= TX4938_IRQ_PIC_END; i++) - set_irq_chip_and_handler(i, &tx4938_irq_pic_type, - handle_level_irq); + for (i = TX4938_IRQ_PIC_BEG; i <= TX4938_IRQ_PIC_END; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 2; + irq_desc[i].chip = &tx4938_irq_pic_type; + } setup_irq(TX4938_IRQ_NEST_PIC_ON_CP0, &tx4938_irq_pic_action); + spin_lock_irqsave(&tx4938_pic_lock, flags); + TX4938_WR(0xff1ff640, 0x6); /* irq level mask -- only accept hightest */ TX4938_WR(0xff1ff600, TX4938_RD(0xff1ff600) | 0x1); /* irq enable */ + + spin_unlock_irqrestore(&tx4938_pic_lock, flags); + + return; +} + +static unsigned int +tx4938_irq_pic_startup(unsigned int irq) +{ + tx4938_irq_pic_enable(irq); + + return (0); +} + +static void +tx4938_irq_pic_shutdown(unsigned int irq) +{ + tx4938_irq_pic_disable(irq); + + return; } static void tx4938_irq_pic_enable(unsigned int irq) { + unsigned long flags; + + spin_lock_irqsave(&tx4938_pic_lock, flags); + tx4938_irq_pic_modify(tx4938_irq_pic_addr(irq), 0, tx4938_irq_pic_mask(irq)); + + spin_unlock_irqrestore(&tx4938_pic_lock, flags); + + return; } static void tx4938_irq_pic_disable(unsigned int irq) { + unsigned long flags; + + spin_lock_irqsave(&tx4938_pic_lock, flags); + tx4938_irq_pic_modify(tx4938_irq_pic_addr(irq), tx4938_irq_pic_mask(irq), 0); + + spin_unlock_irqrestore(&tx4938_pic_lock, flags); + + return; +} + +static void +tx4938_irq_pic_mask_and_ack(unsigned int irq) +{ + tx4938_irq_pic_disable(irq); + + return; } static void @@ -275,6 +381,8 @@ tx4938_irq_pic_end(unsigned int irq) if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { tx4938_irq_pic_enable(irq); } + + return; } /**********************************************************************************/ @@ -286,6 +394,8 @@ tx4938_irq_init(void) { tx4938_irq_cp0_init(); tx4938_irq_pic_init(); + + return; } int @@ -307,23 +417,23 @@ tx4938_irq_nested(void) } wbflush(); - return sw_irq; + return (sw_irq); } -asmlinkage void plat_irq_dispatch(void) +asmlinkage void plat_irq_dispatch(struct pt_regs *regs) { unsigned int pending = read_c0_cause() & read_c0_status(); if (pending & STATUSF_IP7) - do_IRQ(TX4938_IRQ_CPU_TIMER); + do_IRQ(TX4938_IRQ_CPU_TIMER, regs); else if (pending & STATUSF_IP2) { int irq = tx4938_irq_nested(); if (irq) - do_IRQ(irq); + do_IRQ(irq, regs); else - spurious_interrupt(); + spurious_interrupt(regs); } else if (pending & STATUSF_IP1) - do_IRQ(TX4938_IRQ_USER1); + do_IRQ(TX4938_IRQ_USER1, regs); else if (pending & STATUSF_IP0) - do_IRQ(TX4938_IRQ_USER0); + do_IRQ(TX4938_IRQ_USER0, regs); } diff --git a/trunk/arch/mips/tx4938/common/setup.c b/trunk/arch/mips/tx4938/common/setup.c index dc87d92bb08d..71859c4fee84 100644 --- a/trunk/arch/mips/tx4938/common/setup.c +++ b/trunk/arch/mips/tx4938/common/setup.c @@ -31,6 +31,7 @@ #include #include #include +#include #include extern void toshiba_rbtx4938_setup(void); @@ -40,10 +41,29 @@ void __init tx4938_setup(void); void __init tx4938_time_init(void); void dump_cp0(char *key); +void (*__wbflush) (void); + +static void +tx4938_write_buffer_flush(void) +{ + mmiowb(); + + __asm__ __volatile__( + ".set push\n\t" + ".set noreorder\n\t" + "lw $0,%0\n\t" + "nop\n\t" + ".set pop" + : /* no output */ + : "m" (*(int *)KSEG1) + : "memory"); +} + void __init plat_mem_setup(void) { board_time_init = tx4938_time_init; + __wbflush = tx4938_write_buffer_flush; toshiba_rbtx4938_setup(); } diff --git a/trunk/arch/mips/tx4938/toshiba_rbtx4938/irq.c b/trunk/arch/mips/tx4938/toshiba_rbtx4938/irq.c index 8c87a35f3068..83f2750825a4 100644 --- a/trunk/arch/mips/tx4938/toshiba_rbtx4938/irq.c +++ b/trunk/arch/mips/tx4938/toshiba_rbtx4938/irq.c @@ -81,24 +81,31 @@ IRQ Device #include #include #include +#include #include #include -#include #include #include +static unsigned int toshiba_rbtx4938_irq_ioc_startup(unsigned int irq); +static void toshiba_rbtx4938_irq_ioc_shutdown(unsigned int irq); static void toshiba_rbtx4938_irq_ioc_enable(unsigned int irq); static void toshiba_rbtx4938_irq_ioc_disable(unsigned int irq); +static void toshiba_rbtx4938_irq_ioc_mask_and_ack(unsigned int irq); static void toshiba_rbtx4938_irq_ioc_end(unsigned int irq); +DEFINE_SPINLOCK(toshiba_rbtx4938_ioc_lock); + #define TOSHIBA_RBTX4938_IOC_NAME "RBTX4938-IOC" static struct irq_chip toshiba_rbtx4938_irq_ioc_type = { .typename = TOSHIBA_RBTX4938_IOC_NAME, - .ack = toshiba_rbtx4938_irq_ioc_disable, - .mask = toshiba_rbtx4938_irq_ioc_disable, - .mask_ack = toshiba_rbtx4938_irq_ioc_disable, - .unmask = toshiba_rbtx4938_irq_ioc_enable, + .startup = toshiba_rbtx4938_irq_ioc_startup, + .shutdown = toshiba_rbtx4938_irq_ioc_shutdown, + .enable = toshiba_rbtx4938_irq_ioc_enable, + .disable = toshiba_rbtx4938_irq_ioc_disable, + .ack = toshiba_rbtx4938_irq_ioc_mask_and_ack, .end = toshiba_rbtx4938_irq_ioc_end, + .set_affinity = NULL }; #define TOSHIBA_RBTX4938_IOC_INTR_ENAB 0xb7f02000 @@ -135,36 +142,69 @@ toshiba_rbtx4938_irq_ioc_init(void) int i; for (i = TOSHIBA_RBTX4938_IRQ_IOC_BEG; - i <= TOSHIBA_RBTX4938_IRQ_IOC_END; i++) - set_irq_chip_and_handler(i, &toshiba_rbtx4938_irq_ioc_type, - handle_level_irq); + i <= TOSHIBA_RBTX4938_IRQ_IOC_END; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 3; + irq_desc[i].chip = &toshiba_rbtx4938_irq_ioc_type; + } setup_irq(RBTX4938_IRQ_IOCINT, &toshiba_rbtx4938_irq_ioc_action); } +static unsigned int +toshiba_rbtx4938_irq_ioc_startup(unsigned int irq) +{ + toshiba_rbtx4938_irq_ioc_enable(irq); + + return 0; +} + +static void +toshiba_rbtx4938_irq_ioc_shutdown(unsigned int irq) +{ + toshiba_rbtx4938_irq_ioc_disable(irq); +} + static void toshiba_rbtx4938_irq_ioc_enable(unsigned int irq) { + unsigned long flags; volatile unsigned char v; + spin_lock_irqsave(&toshiba_rbtx4938_ioc_lock, flags); + v = TX4938_RD08(TOSHIBA_RBTX4938_IOC_INTR_ENAB); v |= (1 << (irq - TOSHIBA_RBTX4938_IRQ_IOC_BEG)); TX4938_WR08(TOSHIBA_RBTX4938_IOC_INTR_ENAB, v); mmiowb(); TX4938_RD08(TOSHIBA_RBTX4938_IOC_INTR_ENAB); + + spin_unlock_irqrestore(&toshiba_rbtx4938_ioc_lock, flags); } static void toshiba_rbtx4938_irq_ioc_disable(unsigned int irq) { + unsigned long flags; volatile unsigned char v; + spin_lock_irqsave(&toshiba_rbtx4938_ioc_lock, flags); + v = TX4938_RD08(TOSHIBA_RBTX4938_IOC_INTR_ENAB); v &= ~(1 << (irq - TOSHIBA_RBTX4938_IRQ_IOC_BEG)); TX4938_WR08(TOSHIBA_RBTX4938_IOC_INTR_ENAB, v); mmiowb(); TX4938_RD08(TOSHIBA_RBTX4938_IOC_INTR_ENAB); + + spin_unlock_irqrestore(&toshiba_rbtx4938_ioc_lock, flags); +} + +static void +toshiba_rbtx4938_irq_ioc_mask_and_ack(unsigned int irq) +{ + toshiba_rbtx4938_irq_ioc_disable(irq); } static void diff --git a/trunk/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c b/trunk/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c index 08b20cdfd7b3..fae3136f462d 100644 --- a/trunk/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c +++ b/trunk/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c @@ -35,19 +35,14 @@ void __init txx9_spi_init(unsigned long base, int (*cs_func)(int chipid, int on) } static DECLARE_WAIT_QUEUE_HEAD(txx9_spi_wait); - -static irqreturn_t txx9_spi_interrupt(int irq, void *dev_id) +static void txx9_spi_interrupt(int irq, void *dev_id, struct pt_regs *regs) { /* disable rx intr */ tx4938_spiptr->cr0 &= ~TXx9_SPCR0_RBSIE; wake_up(&txx9_spi_wait); - - return IRQ_HANDLED; } - static struct irqaction txx9_spi_action = { - .handler = txx9_spi_interrupt, - .name = "spi", + txx9_spi_interrupt, 0, 0, "spi", NULL, NULL, }; void __init txx9_spi_irqinit(int irc_irq) diff --git a/trunk/arch/mips/vr41xx/common/icu.c b/trunk/arch/mips/vr41xx/common/icu.c index 54b92a74c7ac..7a5c31d58378 100644 --- a/trunk/arch/mips/vr41xx/common/icu.c +++ b/trunk/arch/mips/vr41xx/common/icu.c @@ -417,7 +417,14 @@ void vr41xx_disable_bcuint(void) EXPORT_SYMBOL(vr41xx_disable_bcuint); -static void disable_sysint1_irq(unsigned int irq) +static unsigned int startup_sysint1_irq(unsigned int irq) +{ + icu1_set(MSYSINT1REG, 1 << SYSINT1_IRQ_TO_PIN(irq)); + + return 0; /* never anything pending */ +} + +static void shutdown_sysint1_irq(unsigned int irq) { icu1_clear(MSYSINT1REG, 1 << SYSINT1_IRQ_TO_PIN(irq)); } @@ -427,6 +434,9 @@ static void enable_sysint1_irq(unsigned int irq) icu1_set(MSYSINT1REG, 1 << SYSINT1_IRQ_TO_PIN(irq)); } +#define disable_sysint1_irq shutdown_sysint1_irq +#define ack_sysint1_irq shutdown_sysint1_irq + static void end_sysint1_irq(unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) @@ -435,14 +445,22 @@ static void end_sysint1_irq(unsigned int irq) static struct irq_chip sysint1_irq_type = { .typename = "SYSINT1", - .ack = disable_sysint1_irq, - .mask = disable_sysint1_irq, - .mask_ack = disable_sysint1_irq, - .unmask = enable_sysint1_irq, + .startup = startup_sysint1_irq, + .shutdown = shutdown_sysint1_irq, + .enable = enable_sysint1_irq, + .disable = disable_sysint1_irq, + .ack = ack_sysint1_irq, .end = end_sysint1_irq, }; -static void disable_sysint2_irq(unsigned int irq) +static unsigned int startup_sysint2_irq(unsigned int irq) +{ + icu2_set(MSYSINT2REG, 1 << SYSINT2_IRQ_TO_PIN(irq)); + + return 0; /* never anything pending */ +} + +static void shutdown_sysint2_irq(unsigned int irq) { icu2_clear(MSYSINT2REG, 1 << SYSINT2_IRQ_TO_PIN(irq)); } @@ -452,6 +470,9 @@ static void enable_sysint2_irq(unsigned int irq) icu2_set(MSYSINT2REG, 1 << SYSINT2_IRQ_TO_PIN(irq)); } +#define disable_sysint2_irq shutdown_sysint2_irq +#define ack_sysint2_irq shutdown_sysint2_irq + static void end_sysint2_irq(unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) @@ -460,10 +481,11 @@ static void end_sysint2_irq(unsigned int irq) static struct irq_chip sysint2_irq_type = { .typename = "SYSINT2", - .ack = disable_sysint2_irq, - .mask = disable_sysint2_irq, - .mask_ack = disable_sysint2_irq, - .unmask = enable_sysint2_irq, + .startup = startup_sysint2_irq, + .shutdown = shutdown_sysint2_irq, + .enable = enable_sysint2_irq, + .disable = disable_sysint2_irq, + .ack = ack_sysint2_irq, .end = end_sysint2_irq, }; @@ -613,7 +635,7 @@ int vr41xx_set_intassign(unsigned int irq, unsigned char intassign) EXPORT_SYMBOL(vr41xx_set_intassign); -static int icu_get_irq(unsigned int irq) +static int icu_get_irq(unsigned int irq, struct pt_regs *regs) { uint16_t pend1, pend2; uint16_t mask1, mask2; @@ -701,12 +723,10 @@ static int __init vr41xx_icu_init(void) icu2_write(MGIUINTHREG, 0xffff); for (i = SYSINT1_IRQ_BASE; i <= SYSINT1_IRQ_LAST; i++) - set_irq_chip_and_handler(i, &sysint1_irq_type, - handle_level_irq); + irq_desc[i].chip = &sysint1_irq_type; for (i = SYSINT2_IRQ_BASE; i <= SYSINT2_IRQ_LAST; i++) - set_irq_chip_and_handler(i, &sysint2_irq_type, - handle_level_irq); + irq_desc[i].chip = &sysint2_irq_type; cascade_irq(INT0_IRQ, icu_get_irq); cascade_irq(INT1_IRQ, icu_get_irq); diff --git a/trunk/arch/mips/vr41xx/common/irq.c b/trunk/arch/mips/vr41xx/common/irq.c index 397ba94cd7ec..4733c5344467 100644 --- a/trunk/arch/mips/vr41xx/common/irq.c +++ b/trunk/arch/mips/vr41xx/common/irq.c @@ -25,7 +25,7 @@ #include typedef struct irq_cascade { - int (*get_irq)(unsigned int); + int (*get_irq)(unsigned int, struct pt_regs *); } irq_cascade_t; static irq_cascade_t irq_cascade[NR_IRQS] __cacheline_aligned; @@ -36,7 +36,7 @@ static struct irqaction cascade_irqaction = { .name = "cascade", }; -int cascade_irq(unsigned int irq, int (*get_irq)(unsigned int)) +int cascade_irq(unsigned int irq, int (*get_irq)(unsigned int, struct pt_regs *)) { int retval = 0; @@ -59,7 +59,7 @@ int cascade_irq(unsigned int irq, int (*get_irq)(unsigned int)) EXPORT_SYMBOL_GPL(cascade_irq); -static void irq_dispatch(unsigned int irq) +static void irq_dispatch(unsigned int irq, struct pt_regs *regs) { irq_cascade_t *cascade; struct irq_desc *desc; @@ -74,39 +74,39 @@ static void irq_dispatch(unsigned int irq) unsigned int source_irq = irq; desc = irq_desc + source_irq; desc->chip->ack(source_irq); - irq = cascade->get_irq(irq); + irq = cascade->get_irq(irq, regs); if (irq < 0) atomic_inc(&irq_err_count); else - irq_dispatch(irq); + irq_dispatch(irq, regs); desc->chip->end(source_irq); } else - do_IRQ(irq); + do_IRQ(irq, regs); } -asmlinkage void plat_irq_dispatch(void) +asmlinkage void plat_irq_dispatch(struct pt_regs *regs) { unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; if (pending & CAUSEF_IP7) - do_IRQ(7); + do_IRQ(7, regs); else if (pending & 0x7800) { if (pending & CAUSEF_IP3) - irq_dispatch(3); + irq_dispatch(3, regs); else if (pending & CAUSEF_IP4) - irq_dispatch(4); + irq_dispatch(4, regs); else if (pending & CAUSEF_IP5) - irq_dispatch(5); + irq_dispatch(5, regs); else if (pending & CAUSEF_IP6) - irq_dispatch(6); + irq_dispatch(6, regs); } else if (pending & CAUSEF_IP2) - irq_dispatch(2); + irq_dispatch(2, regs); else if (pending & CAUSEF_IP0) - do_IRQ(0); + do_IRQ(0, regs); else if (pending & CAUSEF_IP1) - do_IRQ(1); + do_IRQ(1, regs); else - spurious_interrupt(); + spurious_interrupt(regs); } void __init arch_init_irq(void) diff --git a/trunk/arch/mips/vr41xx/nec-cmbvr4133/irq.c b/trunk/arch/mips/vr41xx/nec-cmbvr4133/irq.c index a039bb7251ff..2483487344c2 100644 --- a/trunk/arch/mips/vr41xx/nec-cmbvr4133/irq.c +++ b/trunk/arch/mips/vr41xx/nec-cmbvr4133/irq.c @@ -30,6 +30,17 @@ extern void init_8259A(int hoge); extern int vr4133_rockhopper; +static unsigned int startup_i8259_irq(unsigned int irq) +{ + enable_8259A_irq(irq - I8259_IRQ_BASE); + return 0; +} + +static void shutdown_i8259_irq(unsigned int irq) +{ + disable_8259A_irq(irq - I8259_IRQ_BASE); +} + static void enable_i8259_irq(unsigned int irq) { enable_8259A_irq(irq - I8259_IRQ_BASE); @@ -53,10 +64,11 @@ static void end_i8259_irq(unsigned int irq) static struct irq_chip i8259_irq_type = { .typename = "XT-PIC", + .startup = startup_i8259_irq, + .shutdown = shutdown_i8259_irq, + .enable = enable_i8259_irq, + .disable = disable_i8259_irq, .ack = ack_i8259_irq, - .mask = disable_i8259_irq, - .mask_ack = ack_i8259_irq, - .unmask = enable_i8259_irq, .end = end_i8259_irq, }; @@ -92,7 +104,7 @@ void __init rockhopper_init_irq(void) } for (i = I8259_IRQ_BASE; i <= I8259_IRQ_LAST; i++) - set_irq_chip(i, &i8259_irq_type); + irq_desc[i].chip = &i8259_irq_type; setup_irq(I8259_SLAVE_IRQ, &i8259_slave_cascade); diff --git a/trunk/arch/parisc/hpux/fs.c b/trunk/arch/parisc/hpux/fs.c index 4204cd1f3cf9..2d58b92b57e3 100644 --- a/trunk/arch/parisc/hpux/fs.c +++ b/trunk/arch/parisc/hpux/fs.c @@ -73,7 +73,7 @@ struct getdents_callback { #define ROUND_UP(x) (((x)+sizeof(long)-1) & ~(sizeof(long)-1)) static int filldir(void * __buf, const char * name, int namlen, loff_t offset, - u64 ino, unsigned d_type) + ino_t ino, unsigned d_type) { struct hpux_dirent * dirent; struct getdents_callback * buf = (struct getdents_callback *) __buf; diff --git a/trunk/arch/parisc/kernel/drivers.c b/trunk/arch/parisc/kernel/drivers.c index d6c486e9501c..3d569a485a1a 100644 --- a/trunk/arch/parisc/kernel/drivers.c +++ b/trunk/arch/parisc/kernel/drivers.c @@ -424,10 +424,7 @@ struct parisc_device * create_tree_node(char id, struct device *parent) /* make the generic dma mask a pointer to the parisc one */ dev->dev.dma_mask = &dev->dma_mask; dev->dev.coherent_dma_mask = dev->dma_mask; - if (device_register(&dev->dev)) { - kfree(dev); - return NULL; - } + device_register(&dev->dev); return dev; } @@ -853,10 +850,8 @@ static void print_parisc_device(struct parisc_device *dev) */ void init_parisc_bus(void) { - if (bus_register(&parisc_bus_type)) - panic("Could not register PA-RISC bus type\n"); - if (device_register(&root)) - panic("Could not register PA-RISC root device\n"); + bus_register(&parisc_bus_type); + device_register(&root); get_device(&root); } diff --git a/trunk/arch/parisc/kernel/firmware.c b/trunk/arch/parisc/kernel/firmware.c index 9158b707c0dd..c2531ae032cf 100644 --- a/trunk/arch/parisc/kernel/firmware.c +++ b/trunk/arch/parisc/kernel/firmware.c @@ -160,14 +160,13 @@ void __init set_firmware_width(void) { #ifdef __LP64__ int retval; - unsigned long flags; - spin_lock_irqsave(&pdc_lock, flags); + spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_CAPABILITIES, __pa(pdc_result), 0); convert_to_wide(pdc_result); if(pdc_result[0] != NARROW_FIRMWARE) parisc_narrow_firmware = 0; - spin_unlock_irqrestore(&pdc_lock, flags); + spin_unlock_irq(&pdc_lock); #endif } @@ -197,11 +196,10 @@ void pdc_emergency_unlock(void) int pdc_add_valid(unsigned long address) { int retval; - unsigned long flags; - spin_lock_irqsave(&pdc_lock, flags); + spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_ADD_VALID, PDC_ADD_VALID_VERIFY, address); - spin_unlock_irqrestore(&pdc_lock, flags); + spin_unlock_irq(&pdc_lock); return retval; } @@ -218,16 +216,15 @@ EXPORT_SYMBOL(pdc_add_valid); int __init pdc_chassis_info(struct pdc_chassis_info *chassis_info, void *led_info, unsigned long len) { int retval; - unsigned long flags; - spin_lock_irqsave(&pdc_lock, flags); + spin_lock_irq(&pdc_lock); memcpy(&pdc_result, chassis_info, sizeof(*chassis_info)); memcpy(&pdc_result2, led_info, len); retval = mem_pdc_call(PDC_CHASSIS, PDC_RETURN_CHASSIS_INFO, __pa(pdc_result), __pa(pdc_result2), len); memcpy(chassis_info, pdc_result, sizeof(*chassis_info)); memcpy(led_info, pdc_result2, len); - spin_unlock_irqrestore(&pdc_lock, flags); + spin_unlock_irq(&pdc_lock); return retval; } @@ -242,14 +239,13 @@ int __init pdc_chassis_info(struct pdc_chassis_info *chassis_info, void *led_inf int pdc_pat_chassis_send_log(unsigned long state, unsigned long data) { int retval = 0; - unsigned long flags; if (!is_pdc_pat()) return -1; - spin_lock_irqsave(&pdc_lock, flags); + spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_PAT_CHASSIS_LOG, PDC_PAT_CHASSIS_WRITE_LOG, __pa(&state), __pa(&data)); - spin_unlock_irqrestore(&pdc_lock, flags); + spin_unlock_irq(&pdc_lock); return retval; } @@ -262,11 +258,10 @@ int pdc_pat_chassis_send_log(unsigned long state, unsigned long data) int pdc_chassis_disp(unsigned long disp) { int retval = 0; - unsigned long flags; - spin_lock_irqsave(&pdc_lock, flags); + spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_CHASSIS, PDC_CHASSIS_DISP, disp); - spin_unlock_irqrestore(&pdc_lock, flags); + spin_unlock_irq(&pdc_lock); return retval; } @@ -278,12 +273,11 @@ int pdc_chassis_disp(unsigned long disp) int pdc_chassis_warn(unsigned long *warn) { int retval = 0; - unsigned long flags; - spin_lock_irqsave(&pdc_lock, flags); + spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_CHASSIS, PDC_CHASSIS_WARN, __pa(pdc_result)); *warn = pdc_result[0]; - spin_unlock_irqrestore(&pdc_lock, flags); + spin_unlock_irq(&pdc_lock); return retval; } @@ -298,16 +292,15 @@ int pdc_chassis_warn(unsigned long *warn) int __init pdc_coproc_cfg(struct pdc_coproc_cfg *pdc_coproc_info) { int retval; - unsigned long flags; - spin_lock_irqsave(&pdc_lock, flags); + spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_COPROC, PDC_COPROC_CFG, __pa(pdc_result)); convert_to_wide(pdc_result); pdc_coproc_info->ccr_functional = pdc_result[0]; pdc_coproc_info->ccr_present = pdc_result[1]; pdc_coproc_info->revision = pdc_result[17]; pdc_coproc_info->model = pdc_result[18]; - spin_unlock_irqrestore(&pdc_lock, flags); + spin_unlock_irq(&pdc_lock); return retval; } @@ -327,15 +320,14 @@ int pdc_iodc_read(unsigned long *actcnt, unsigned long hpa, unsigned int index, void *iodc_data, unsigned int iodc_data_size) { int retval; - unsigned long flags; - spin_lock_irqsave(&pdc_lock, flags); + spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_IODC, PDC_IODC_READ, __pa(pdc_result), hpa, index, __pa(pdc_result2), iodc_data_size); convert_to_wide(pdc_result); *actcnt = pdc_result[0]; memcpy(iodc_data, pdc_result2, iodc_data_size); - spin_unlock_irqrestore(&pdc_lock, flags); + spin_unlock_irq(&pdc_lock); return retval; } @@ -354,15 +346,14 @@ int pdc_system_map_find_mods(struct pdc_system_map_mod_info *pdc_mod_info, struct pdc_module_path *mod_path, long mod_index) { int retval; - unsigned long flags; - spin_lock_irqsave(&pdc_lock, flags); + spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_SYSTEM_MAP, PDC_FIND_MODULE, __pa(pdc_result), __pa(pdc_result2), mod_index); convert_to_wide(pdc_result); memcpy(pdc_mod_info, pdc_result, sizeof(*pdc_mod_info)); memcpy(mod_path, pdc_result2, sizeof(*mod_path)); - spin_unlock_irqrestore(&pdc_lock, flags); + spin_unlock_irq(&pdc_lock); pdc_mod_info->mod_addr = f_extend(pdc_mod_info->mod_addr); return retval; @@ -381,14 +372,13 @@ int pdc_system_map_find_addrs(struct pdc_system_map_addr_info *pdc_addr_info, long mod_index, long addr_index) { int retval; - unsigned long flags; - spin_lock_irqsave(&pdc_lock, flags); + spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_SYSTEM_MAP, PDC_FIND_ADDRESS, __pa(pdc_result), mod_index, addr_index); convert_to_wide(pdc_result); memcpy(pdc_addr_info, pdc_result, sizeof(*pdc_addr_info)); - spin_unlock_irqrestore(&pdc_lock, flags); + spin_unlock_irq(&pdc_lock); pdc_addr_info->mod_addr = f_extend(pdc_addr_info->mod_addr); return retval; @@ -403,13 +393,12 @@ int pdc_system_map_find_addrs(struct pdc_system_map_addr_info *pdc_addr_info, int pdc_model_info(struct pdc_model *model) { int retval; - unsigned long flags; - spin_lock_irqsave(&pdc_lock, flags); + spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_INFO, __pa(pdc_result), 0); convert_to_wide(pdc_result); memcpy(model, pdc_result, sizeof(*model)); - spin_unlock_irqrestore(&pdc_lock, flags); + spin_unlock_irq(&pdc_lock); return retval; } @@ -425,9 +414,8 @@ int pdc_model_info(struct pdc_model *model) int pdc_model_sysmodel(char *name) { int retval; - unsigned long flags; - spin_lock_irqsave(&pdc_lock, flags); + spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_SYSMODEL, __pa(pdc_result), OS_ID_HPUX, __pa(name)); convert_to_wide(pdc_result); @@ -437,7 +425,7 @@ int pdc_model_sysmodel(char *name) } else { name[0] = 0; } - spin_unlock_irqrestore(&pdc_lock, flags); + spin_unlock_irq(&pdc_lock); return retval; } @@ -455,13 +443,12 @@ int pdc_model_sysmodel(char *name) int pdc_model_versions(unsigned long *versions, int id) { int retval; - unsigned long flags; - spin_lock_irqsave(&pdc_lock, flags); + spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_VERSIONS, __pa(pdc_result), id); convert_to_wide(pdc_result); *versions = pdc_result[0]; - spin_unlock_irqrestore(&pdc_lock, flags); + spin_unlock_irq(&pdc_lock); return retval; } @@ -476,14 +463,13 @@ int pdc_model_versions(unsigned long *versions, int id) int pdc_model_cpuid(unsigned long *cpu_id) { int retval; - unsigned long flags; - spin_lock_irqsave(&pdc_lock, flags); + spin_lock_irq(&pdc_lock); pdc_result[0] = 0; /* preset zero (call may not be implemented!) */ retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_CPU_ID, __pa(pdc_result), 0); convert_to_wide(pdc_result); *cpu_id = pdc_result[0]; - spin_unlock_irqrestore(&pdc_lock, flags); + spin_unlock_irq(&pdc_lock); return retval; } @@ -498,14 +484,13 @@ int pdc_model_cpuid(unsigned long *cpu_id) int pdc_model_capabilities(unsigned long *capabilities) { int retval; - unsigned long flags; - spin_lock_irqsave(&pdc_lock, flags); + spin_lock_irq(&pdc_lock); pdc_result[0] = 0; /* preset zero (call may not be implemented!) */ retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_CAPABILITIES, __pa(pdc_result), 0); convert_to_wide(pdc_result); *capabilities = pdc_result[0]; - spin_unlock_irqrestore(&pdc_lock, flags); + spin_unlock_irq(&pdc_lock); return retval; } @@ -519,13 +504,12 @@ int pdc_model_capabilities(unsigned long *capabilities) int pdc_cache_info(struct pdc_cache_info *cache_info) { int retval; - unsigned long flags; - spin_lock_irqsave(&pdc_lock, flags); + spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_CACHE, PDC_CACHE_INFO, __pa(pdc_result), 0); convert_to_wide(pdc_result); memcpy(cache_info, pdc_result, sizeof(*cache_info)); - spin_unlock_irqrestore(&pdc_lock, flags); + spin_unlock_irq(&pdc_lock); return retval; } @@ -539,14 +523,13 @@ int pdc_cache_info(struct pdc_cache_info *cache_info) int pdc_spaceid_bits(unsigned long *space_bits) { int retval; - unsigned long flags; - spin_lock_irqsave(&pdc_lock, flags); + spin_lock_irq(&pdc_lock); pdc_result[0] = 0; retval = mem_pdc_call(PDC_CACHE, PDC_CACHE_RET_SPID, __pa(pdc_result), 0); convert_to_wide(pdc_result); *space_bits = pdc_result[0]; - spin_unlock_irqrestore(&pdc_lock, flags); + spin_unlock_irq(&pdc_lock); return retval; } @@ -561,12 +544,11 @@ int pdc_spaceid_bits(unsigned long *space_bits) int pdc_btlb_info(struct pdc_btlb_info *btlb) { int retval; - unsigned long flags; - spin_lock_irqsave(&pdc_lock, flags); + spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_BLOCK_TLB, PDC_BTLB_INFO, __pa(pdc_result), 0); memcpy(btlb, pdc_result, sizeof(*btlb)); - spin_unlock_irqrestore(&pdc_lock, flags); + spin_unlock_irq(&pdc_lock); if(retval < 0) { btlb->max_size = 0; @@ -590,14 +572,13 @@ int pdc_mem_map_hpa(struct pdc_memory_map *address, struct pdc_module_path *mod_path) { int retval; - unsigned long flags; - spin_lock_irqsave(&pdc_lock, flags); + spin_lock_irq(&pdc_lock); memcpy(pdc_result2, mod_path, sizeof(*mod_path)); retval = mem_pdc_call(PDC_MEM_MAP, PDC_MEM_MAP_HPA, __pa(pdc_result), __pa(pdc_result2)); memcpy(address, pdc_result, sizeof(*address)); - spin_unlock_irqrestore(&pdc_lock, flags); + spin_unlock_irq(&pdc_lock); return retval; } @@ -613,9 +594,8 @@ int pdc_mem_map_hpa(struct pdc_memory_map *address, int pdc_lan_station_id(char *lan_addr, unsigned long hpa) { int retval; - unsigned long flags; - spin_lock_irqsave(&pdc_lock, flags); + spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_LAN_STATION_ID, PDC_LAN_STATION_ID_READ, __pa(pdc_result), hpa); if (retval < 0) { @@ -624,7 +604,7 @@ int pdc_lan_station_id(char *lan_addr, unsigned long hpa) } else { memcpy(lan_addr, pdc_result, PDC_LAN_STATION_ID_SIZE); } - spin_unlock_irqrestore(&pdc_lock, flags); + spin_unlock_irq(&pdc_lock); return retval; } @@ -643,14 +623,13 @@ EXPORT_SYMBOL(pdc_lan_station_id); int pdc_stable_read(unsigned long staddr, void *memaddr, unsigned long count) { int retval; - unsigned long flags; - spin_lock_irqsave(&pdc_lock, flags); + spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_STABLE, PDC_STABLE_READ, staddr, __pa(pdc_result), count); convert_to_wide(pdc_result); memcpy(memaddr, pdc_result, count); - spin_unlock_irqrestore(&pdc_lock, flags); + spin_unlock_irq(&pdc_lock); return retval; } @@ -669,14 +648,13 @@ EXPORT_SYMBOL(pdc_stable_read); int pdc_stable_write(unsigned long staddr, void *memaddr, unsigned long count) { int retval; - unsigned long flags; - spin_lock_irqsave(&pdc_lock, flags); + spin_lock_irq(&pdc_lock); memcpy(pdc_result, memaddr, count); convert_to_wide(pdc_result); retval = mem_pdc_call(PDC_STABLE, PDC_STABLE_WRITE, staddr, __pa(pdc_result), count); - spin_unlock_irqrestore(&pdc_lock, flags); + spin_unlock_irq(&pdc_lock); return retval; } @@ -694,12 +672,11 @@ EXPORT_SYMBOL(pdc_stable_write); int pdc_stable_get_size(unsigned long *size) { int retval; - unsigned long flags; - spin_lock_irqsave(&pdc_lock, flags); + spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_STABLE, PDC_STABLE_RETURN_SIZE, __pa(pdc_result)); *size = pdc_result[0]; - spin_unlock_irqrestore(&pdc_lock, flags); + spin_unlock_irq(&pdc_lock); return retval; } @@ -714,11 +691,10 @@ EXPORT_SYMBOL(pdc_stable_get_size); int pdc_stable_verify_contents(void) { int retval; - unsigned long flags; - spin_lock_irqsave(&pdc_lock, flags); + spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_STABLE, PDC_STABLE_VERIFY_CONTENTS); - spin_unlock_irqrestore(&pdc_lock, flags); + spin_unlock_irq(&pdc_lock); return retval; } @@ -733,11 +709,10 @@ EXPORT_SYMBOL(pdc_stable_verify_contents); int pdc_stable_initialize(void) { int retval; - unsigned long flags; - spin_lock_irqsave(&pdc_lock, flags); + spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_STABLE, PDC_STABLE_INITIALIZE); - spin_unlock_irqrestore(&pdc_lock, flags); + spin_unlock_irq(&pdc_lock); return retval; } @@ -760,9 +735,8 @@ EXPORT_SYMBOL(pdc_stable_initialize); int pdc_get_initiator(struct hardware_path *hwpath, struct pdc_initiator *initiator) { int retval; - unsigned long flags; - spin_lock_irqsave(&pdc_lock, flags); + spin_lock_irq(&pdc_lock); /* BCJ-XXXX series boxes. E.G. "9000/785/C3000" */ #define IS_SPROCKETS() (strlen(boot_cpu_data.pdc.sys_model_name) == 14 && \ @@ -802,8 +776,7 @@ int pdc_get_initiator(struct hardware_path *hwpath, struct pdc_initiator *initia } out: - spin_unlock_irqrestore(&pdc_lock, flags); - + spin_unlock_irq(&pdc_lock); return (retval >= PDC_OK); } EXPORT_SYMBOL(pdc_get_initiator); @@ -821,14 +794,13 @@ EXPORT_SYMBOL(pdc_get_initiator); int pdc_pci_irt_size(unsigned long *num_entries, unsigned long hpa) { int retval; - unsigned long flags; - spin_lock_irqsave(&pdc_lock, flags); + spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_PCI_INDEX, PDC_PCI_GET_INT_TBL_SIZE, __pa(pdc_result), hpa); convert_to_wide(pdc_result); *num_entries = pdc_result[0]; - spin_unlock_irqrestore(&pdc_lock, flags); + spin_unlock_irq(&pdc_lock); return retval; } @@ -845,15 +817,14 @@ int pdc_pci_irt_size(unsigned long *num_entries, unsigned long hpa) int pdc_pci_irt(unsigned long num_entries, unsigned long hpa, void *tbl) { int retval; - unsigned long flags; BUG_ON((unsigned long)tbl & 0x7); - spin_lock_irqsave(&pdc_lock, flags); + spin_lock_irq(&pdc_lock); pdc_result[0] = num_entries; retval = mem_pdc_call(PDC_PCI_INDEX, PDC_PCI_GET_INT_TBL, __pa(pdc_result), hpa, __pa(tbl)); - spin_unlock_irqrestore(&pdc_lock, flags); + spin_unlock_irq(&pdc_lock); return retval; } @@ -871,15 +842,12 @@ int pdc_pci_irt(unsigned long num_entries, unsigned long hpa, void *tbl) unsigned int pdc_pci_config_read(void *hpa, unsigned long cfg_addr) { int retval; - unsigned long flags; - - spin_lock_irqsave(&pdc_lock, flags); + spin_lock_irq(&pdc_lock); pdc_result[0] = 0; pdc_result[1] = 0; retval = mem_pdc_call(PDC_PCI_INDEX, PDC_PCI_READ_CONFIG, __pa(pdc_result), hpa, cfg_addr&~3UL, 4UL); - spin_unlock_irqrestore(&pdc_lock, flags); - + spin_unlock_irq(&pdc_lock); return retval ? ~0 : (unsigned int) pdc_result[0]; } @@ -895,15 +863,12 @@ unsigned int pdc_pci_config_read(void *hpa, unsigned long cfg_addr) void pdc_pci_config_write(void *hpa, unsigned long cfg_addr, unsigned int val) { int retval; - unsigned long flags; - - spin_lock_irqsave(&pdc_lock, flags); + spin_lock_irq(&pdc_lock); pdc_result[0] = 0; retval = mem_pdc_call(PDC_PCI_INDEX, PDC_PCI_WRITE_CONFIG, __pa(pdc_result), hpa, cfg_addr&~3UL, 4UL, (unsigned long) val); - spin_unlock_irqrestore(&pdc_lock, flags); - + spin_unlock_irq(&pdc_lock); return retval; } #endif /* UNTESTED CODE */ @@ -917,13 +882,12 @@ void pdc_pci_config_write(void *hpa, unsigned long cfg_addr, unsigned int val) int pdc_tod_read(struct pdc_tod *tod) { int retval; - unsigned long flags; - spin_lock_irqsave(&pdc_lock, flags); + spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_TOD, PDC_TOD_READ, __pa(pdc_result), 0); convert_to_wide(pdc_result); memcpy(tod, pdc_result, sizeof(*tod)); - spin_unlock_irqrestore(&pdc_lock, flags); + spin_unlock_irq(&pdc_lock); return retval; } @@ -939,11 +903,10 @@ EXPORT_SYMBOL(pdc_tod_read); int pdc_tod_set(unsigned long sec, unsigned long usec) { int retval; - unsigned long flags; - spin_lock_irqsave(&pdc_lock, flags); + spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_TOD, PDC_TOD_WRITE, sec, usec); - spin_unlock_irqrestore(&pdc_lock, flags); + spin_unlock_irq(&pdc_lock); return retval; } @@ -954,14 +917,13 @@ int pdc_mem_mem_table(struct pdc_memory_table_raddr *r_addr, struct pdc_memory_table *tbl, unsigned long entries) { int retval; - unsigned long flags; - spin_lock_irqsave(&pdc_lock, flags); + spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_MEM, PDC_MEM_TABLE, __pa(pdc_result), __pa(pdc_result2), entries); convert_to_wide(pdc_result); memcpy(r_addr, pdc_result, sizeof(*r_addr)); memcpy(tbl, pdc_result2, entries * sizeof(*tbl)); - spin_unlock_irqrestore(&pdc_lock, flags); + spin_unlock_irq(&pdc_lock); return retval; } @@ -974,12 +936,11 @@ int pdc_mem_mem_table(struct pdc_memory_table_raddr *r_addr, int pdc_do_firm_test_reset(unsigned long ftc_bitmap) { int retval; - unsigned long flags; - spin_lock_irqsave(&pdc_lock, flags); + spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_BROADCAST_RESET, PDC_DO_FIRM_TEST_RESET, PDC_FIRM_TEST_MAGIC, ftc_bitmap); - spin_unlock_irqrestore(&pdc_lock, flags); + spin_unlock_irq(&pdc_lock); return retval; } @@ -992,11 +953,10 @@ int pdc_do_firm_test_reset(unsigned long ftc_bitmap) int pdc_do_reset(void) { int retval; - unsigned long flags; - spin_lock_irqsave(&pdc_lock, flags); + spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_BROADCAST_RESET, PDC_DO_RESET); - spin_unlock_irqrestore(&pdc_lock, flags); + spin_unlock_irq(&pdc_lock); return retval; } @@ -1010,17 +970,16 @@ int pdc_do_reset(void) int __init pdc_soft_power_info(unsigned long *power_reg) { int retval; - unsigned long flags; *power_reg = (unsigned long) (-1); - spin_lock_irqsave(&pdc_lock, flags); + spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_SOFT_POWER, PDC_SOFT_POWER_INFO, __pa(pdc_result), 0); if (retval == PDC_OK) { convert_to_wide(pdc_result); *power_reg = f_extend(pdc_result[0]); } - spin_unlock_irqrestore(&pdc_lock, flags); + spin_unlock_irq(&pdc_lock); return retval; } @@ -1039,12 +998,9 @@ int __init pdc_soft_power_info(unsigned long *power_reg) int pdc_soft_power_button(int sw_control) { int retval; - unsigned long flags; - - spin_lock_irqsave(&pdc_lock, flags); + spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_SOFT_POWER, PDC_SOFT_POWER_ENABLE, __pa(pdc_result), sw_control); - spin_unlock_irqrestore(&pdc_lock, flags); - + spin_unlock_irq(&pdc_lock); return retval; } @@ -1055,11 +1011,9 @@ int pdc_soft_power_button(int sw_control) */ void pdc_io_reset(void) { - unsigned long flags; - - spin_lock_irqsave(&pdc_lock, flags); + spin_lock_irq(&pdc_lock); mem_pdc_call(PDC_IO, PDC_IO_RESET, 0); - spin_unlock_irqrestore(&pdc_lock, flags); + spin_unlock_irq(&pdc_lock); } /* @@ -1073,11 +1027,9 @@ void pdc_io_reset(void) */ void pdc_io_reset_devices(void) { - unsigned long flags; - - spin_lock_irqsave(&pdc_lock, flags); + spin_lock_irq(&pdc_lock); mem_pdc_call(PDC_IO, PDC_IO_RESET_DEVICES, 0); - spin_unlock_irqrestore(&pdc_lock, flags); + spin_unlock_irq(&pdc_lock); } @@ -1194,11 +1146,10 @@ int pdc_sti_call(unsigned long func, unsigned long flags, unsigned long glob_cfg) { int retval; - unsigned long irqflags; - spin_lock_irqsave(&pdc_lock, irqflags); + spin_lock_irq(&pdc_lock); retval = real32_call(func, flags, inptr, outputr, glob_cfg); - spin_unlock_irqrestore(&pdc_lock, irqflags); + spin_unlock_irq(&pdc_lock); return retval; } @@ -1215,12 +1166,11 @@ EXPORT_SYMBOL(pdc_sti_call); int pdc_pat_cell_get_number(struct pdc_pat_cell_num *cell_info) { int retval; - unsigned long flags; - spin_lock_irqsave(&pdc_lock, flags); + spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_PAT_CELL, PDC_PAT_CELL_GET_NUMBER, __pa(pdc_result)); memcpy(cell_info, pdc_result, sizeof(*cell_info)); - spin_unlock_irqrestore(&pdc_lock, flags); + spin_unlock_irq(&pdc_lock); return retval; } @@ -1240,17 +1190,16 @@ int pdc_pat_cell_module(unsigned long *actcnt, unsigned long ploc, unsigned long unsigned long view_type, void *mem_addr) { int retval; - unsigned long flags; static struct pdc_pat_cell_mod_maddr_block result __attribute__ ((aligned (8))); - spin_lock_irqsave(&pdc_lock, flags); + spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_PAT_CELL, PDC_PAT_CELL_MODULE, __pa(pdc_result), ploc, mod, view_type, __pa(&result)); if(!retval) { *actcnt = pdc_result[0]; memcpy(mem_addr, &result, *actcnt); } - spin_unlock_irqrestore(&pdc_lock, flags); + spin_unlock_irq(&pdc_lock); return retval; } @@ -1265,13 +1214,12 @@ int pdc_pat_cell_module(unsigned long *actcnt, unsigned long ploc, unsigned long int pdc_pat_cpu_get_number(struct pdc_pat_cpu_num *cpu_info, void *hpa) { int retval; - unsigned long flags; - spin_lock_irqsave(&pdc_lock, flags); + spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_PAT_CPU, PDC_PAT_CPU_GET_NUMBER, __pa(&pdc_result), hpa); memcpy(cpu_info, pdc_result, sizeof(*cpu_info)); - spin_unlock_irqrestore(&pdc_lock, flags); + spin_unlock_irq(&pdc_lock); return retval; } @@ -1287,13 +1235,12 @@ int pdc_pat_cpu_get_number(struct pdc_pat_cpu_num *cpu_info, void *hpa) int pdc_pat_get_irt_size(unsigned long *num_entries, unsigned long cell_num) { int retval; - unsigned long flags; - spin_lock_irqsave(&pdc_lock, flags); + spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_PAT_IO, PDC_PAT_IO_GET_PCI_ROUTING_TABLE_SIZE, __pa(pdc_result), cell_num); *num_entries = pdc_result[0]; - spin_unlock_irqrestore(&pdc_lock, flags); + spin_unlock_irq(&pdc_lock); return retval; } @@ -1308,12 +1255,11 @@ int pdc_pat_get_irt_size(unsigned long *num_entries, unsigned long cell_num) int pdc_pat_get_irt(void *r_addr, unsigned long cell_num) { int retval; - unsigned long flags; - spin_lock_irqsave(&pdc_lock, flags); + spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_PAT_IO, PDC_PAT_IO_GET_PCI_ROUTING_TABLE, __pa(r_addr), cell_num); - spin_unlock_irqrestore(&pdc_lock, flags); + spin_unlock_irq(&pdc_lock); return retval; } @@ -1330,14 +1276,13 @@ int pdc_pat_pd_get_addr_map(unsigned long *actual_len, void *mem_addr, unsigned long count, unsigned long offset) { int retval; - unsigned long flags; - spin_lock_irqsave(&pdc_lock, flags); + spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_PAT_PD, PDC_PAT_PD_GET_ADDR_MAP, __pa(pdc_result), __pa(pdc_result2), count, offset); *actual_len = pdc_result[0]; memcpy(mem_addr, pdc_result2, *actual_len); - spin_unlock_irqrestore(&pdc_lock, flags); + spin_unlock_irq(&pdc_lock); return retval; } @@ -1352,9 +1297,7 @@ int pdc_pat_pd_get_addr_map(unsigned long *actual_len, void *mem_addr, int pdc_pat_io_pci_cfg_read(unsigned long pci_addr, int pci_size, u32 *mem_addr) { int retval; - unsigned long flags; - - spin_lock_irqsave(&pdc_lock, flags); + spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_PAT_IO, PDC_PAT_IO_PCI_CONFIG_READ, __pa(pdc_result), pci_addr, pci_size); switch(pci_size) { @@ -1362,7 +1305,7 @@ int pdc_pat_io_pci_cfg_read(unsigned long pci_addr, int pci_size, u32 *mem_addr) case 2: *(u16 *)mem_addr = (u16) pdc_result[0]; case 4: *(u32 *)mem_addr = (u32) pdc_result[0]; } - spin_unlock_irqrestore(&pdc_lock, flags); + spin_unlock_irq(&pdc_lock); return retval; } @@ -1378,12 +1321,11 @@ int pdc_pat_io_pci_cfg_read(unsigned long pci_addr, int pci_size, u32 *mem_addr) int pdc_pat_io_pci_cfg_write(unsigned long pci_addr, int pci_size, u32 val) { int retval; - unsigned long flags; - spin_lock_irqsave(&pdc_lock, flags); + spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_PAT_IO, PDC_PAT_IO_PCI_CONFIG_WRITE, pci_addr, pci_size, val); - spin_unlock_irqrestore(&pdc_lock, flags); + spin_unlock_irq(&pdc_lock); return retval; } diff --git a/trunk/arch/parisc/kernel/irq.c b/trunk/arch/parisc/kernel/irq.c index b39c5b9aff46..9bdd0197ceb7 100644 --- a/trunk/arch/parisc/kernel/irq.c +++ b/trunk/arch/parisc/kernel/irq.c @@ -35,8 +35,8 @@ #undef PARISC_IRQ_CR16_COUNTS -extern irqreturn_t timer_interrupt(int, void *); -extern irqreturn_t ipi_interrupt(int, void *); +extern irqreturn_t timer_interrupt(int, void *, struct pt_regs *); +extern irqreturn_t ipi_interrupt(int, void *, struct pt_regs *); #define EIEM_MASK(irq) (1UL<<(CPU_IRQ_MAX - irq)) @@ -347,14 +347,12 @@ static inline int eirr_to_irq(unsigned long eirr) /* ONLY called from entry.S:intr_extint() */ void do_cpu_irq_mask(struct pt_regs *regs) { - struct pt_regs *old_regs; unsigned long eirr_val; int irq, cpu = smp_processor_id(); #ifdef CONFIG_SMP cpumask_t dest; #endif - old_regs = set_irq_regs(regs); local_irq_disable(); irq_enter(); @@ -377,11 +375,10 @@ void do_cpu_irq_mask(struct pt_regs *regs) goto set_out; } #endif - __do_IRQ(irq); + __do_IRQ(irq, regs); out: irq_exit(); - set_irq_regs(old_regs); return; set_out: diff --git a/trunk/arch/parisc/kernel/parisc_ksyms.c b/trunk/arch/parisc/kernel/parisc_ksyms.c index 8f6a0b312f7a..6d57553d8ef8 100644 --- a/trunk/arch/parisc/kernel/parisc_ksyms.c +++ b/trunk/arch/parisc/kernel/parisc_ksyms.c @@ -69,6 +69,10 @@ EXPORT_SYMBOL(memcpy_toio); EXPORT_SYMBOL(memcpy_fromio); EXPORT_SYMBOL(memset_io); +#include +EXPORT_SYMBOL(sys_lseek); +EXPORT_SYMBOL(sys_write); + #include EXPORT_SYMBOL(__up); EXPORT_SYMBOL(__down_interruptible); diff --git a/trunk/arch/parisc/kernel/pci.c b/trunk/arch/parisc/kernel/pci.c index 199887a61c76..d3b8fc52dfc1 100644 --- a/trunk/arch/parisc/kernel/pci.c +++ b/trunk/arch/parisc/kernel/pci.c @@ -290,7 +290,7 @@ EXPORT_SYMBOL(pcibios_bus_to_resource); void pcibios_align_resource(void *data, struct resource *res, resource_size_t size, resource_size_t alignment) { - resource_size_t mask, align; + unsigned long mask, align; DBG_RES("pcibios_align_resource(%s, (%p) [%lx,%lx]/%x, 0x%lx, 0x%lx)\n", pci_name(((struct pci_dev *) data)), diff --git a/trunk/arch/parisc/kernel/smp.c b/trunk/arch/parisc/kernel/smp.c index 4a23a97b06cd..faad338f310e 100644 --- a/trunk/arch/parisc/kernel/smp.c +++ b/trunk/arch/parisc/kernel/smp.c @@ -154,7 +154,7 @@ halt_processor(void) irqreturn_t -ipi_interrupt(int irq, void *dev_id) +ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs) { int this_cpu = smp_processor_id(); struct cpuinfo_parisc *p = &cpu_data[this_cpu]; @@ -414,6 +414,19 @@ smp_flush_tlb_all(void) on_each_cpu(flush_tlb_all_local, NULL, 1, 1); } + +void +smp_do_timer(struct pt_regs *regs) +{ + int cpu = smp_processor_id(); + struct cpuinfo_parisc *data = &cpu_data[cpu]; + + if (!--data->prof_counter) { + data->prof_counter = data->prof_multiplier; + update_process_times(user_mode(regs)); + } +} + /* * Called by secondaries to update state and initialize CPU registers. */ diff --git a/trunk/arch/parisc/kernel/sys_parisc.c b/trunk/arch/parisc/kernel/sys_parisc.c index 512642d8f707..1db5588ceacf 100644 --- a/trunk/arch/parisc/kernel/sys_parisc.c +++ b/trunk/arch/parisc/kernel/sys_parisc.c @@ -266,17 +266,30 @@ long parisc_personality(unsigned long personality) return err; } -long parisc_newuname(struct new_utsname __user *name) -{ - int err = sys_newuname(name); - +static inline int override_machine(char __user *mach) { #ifdef CONFIG_COMPAT - if (!err && personality(current->personality) == PER_LINUX32) { - if (__put_user(0, name->machine + 6) || - __put_user(0, name->machine + 7)) - err = -EFAULT; + if (personality(current->personality) == PER_LINUX32) { + if (__put_user(0, mach + 6) || + __put_user(0, mach + 7)) + return -EFAULT; } -#endif - return err; + return 0; +#else /*!CONFIG_COMPAT*/ + return 0; +#endif /*CONFIG_COMPAT*/ +} + +long parisc_newuname(struct new_utsname __user *utsname) +{ + int err = 0; + + down_read(&uts_sem); + if (copy_to_user(utsname, &system_utsname, sizeof(*utsname))) + err = -EFAULT; + up_read(&uts_sem); + + err = override_machine(utsname->machine); + + return (long)err; } diff --git a/trunk/arch/parisc/kernel/sys_parisc32.c b/trunk/arch/parisc/kernel/sys_parisc32.c index 29be4377aca6..e3b30bc36453 100644 --- a/trunk/arch/parisc/kernel/sys_parisc32.c +++ b/trunk/arch/parisc/kernel/sys_parisc32.c @@ -111,14 +111,13 @@ struct __sysctl_args32 { asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args) { -#ifndef CONFIG_SYSCTL_SYSCALL - return -ENOSYS; -#else struct __sysctl_args32 tmp; int error; unsigned int oldlen32; - size_t oldlen, __user *oldlenp = NULL; + size_t oldlen, *oldlenp = NULL; unsigned long addr = (((long __force)&args->__unused[0]) + 7) & ~7; + extern int do_sysctl(int *name, int nlen, void *oldval, size_t *oldlenp, + void *newval, size_t newlen); DBG(("sysctl32(%p)\n", args)); @@ -145,9 +144,8 @@ asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args) } lock_kernel(); - error = do_sysctl((int __user *)(u64)tmp.name, tmp.nlen, - (void __user *)(u64)tmp.oldval, oldlenp, - (void __user *)(u64)tmp.newval, tmp.newlen); + error = do_sysctl((int *)(u64)tmp.name, tmp.nlen, (void *)(u64)tmp.oldval, + oldlenp, (void *)(u64)tmp.newval, tmp.newlen); unlock_kernel(); if (oldlenp) { if (!error) { @@ -159,11 +157,10 @@ asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args) error = -EFAULT; } } - if (copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused))) + if (copy_to_user(&args->__unused[0], tmp.__unused, sizeof(tmp.__unused))) error = -EFAULT; } return error; -#endif } #endif /* CONFIG_SYSCTL */ @@ -313,8 +310,9 @@ struct readdir32_callback { #define ROUND_UP(x,a) ((__typeof__(x))(((unsigned long)(x) + ((a) - 1)) & ~((a) - 1))) #define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de))) -static int filldir32 (void *__buf, const char *name, int namlen, - loff_t offset, u64 ino, unsigned int d_type) +static int +filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino, + unsigned int d_type) { struct linux32_dirent __user * dirent; struct getdents32_callback * buf = (struct getdents32_callback *) __buf; @@ -376,8 +374,9 @@ sys32_getdents (unsigned int fd, void __user * dirent, unsigned int count) return error; } -static int fillonedir32(void * __buf, const char * name, int namlen, - loff_t offset, u64 ino, unsigned int d_type) +static int +fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, ino_t ino, + unsigned int d_type) { struct readdir32_callback * buf = (struct readdir32_callback *) __buf; struct old_linux32_dirent __user * dirent; diff --git a/trunk/arch/parisc/kernel/time.c b/trunk/arch/parisc/kernel/time.c index bad7d1eb62b9..b3496b592a2d 100644 --- a/trunk/arch/parisc/kernel/time.c +++ b/trunk/arch/parisc/kernel/time.c @@ -34,39 +34,25 @@ static unsigned long clocktick __read_mostly; /* timer cycles per tick */ -/* - * We keep time on PA-RISC Linux by using the Interval Timer which is - * a pair of registers; one is read-only and one is write-only; both - * accessed through CR16. The read-only register is 32 or 64 bits wide, - * and increments by 1 every CPU clock tick. The architecture only - * guarantees us a rate between 0.5 and 2, but all implementations use a - * rate of 1. The write-only register is 32-bits wide. When the lowest - * 32 bits of the read-only register compare equal to the write-only - * register, it raises a maskable external interrupt. Each processor has - * an Interval Timer of its own and they are not synchronised. - * - * We want to generate an interrupt every 1/HZ seconds. So we program - * CR16 to interrupt every @clocktick cycles. The it_value in cpu_data - * is programmed with the intended time of the next tick. We can be - * held off for an arbitrarily long period of time by interrupts being - * disabled, so we may miss one or more ticks. - */ -irqreturn_t timer_interrupt(int irq, void *dev_id) +#ifdef CONFIG_SMP +extern void smp_do_timer(struct pt_regs *regs); +#endif + +irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { unsigned long now; unsigned long next_tick; - unsigned long cycles_elapsed, ticks_elapsed; + unsigned long cycles_elapsed; unsigned long cycles_remainder; unsigned int cpu = smp_processor_id(); - struct cpuinfo_parisc *cpuinfo = &cpu_data[cpu]; /* gcc can optimize for "read-only" case with a local clocktick */ unsigned long cpt = clocktick; - profile_tick(CPU_PROFILING); + profile_tick(CPU_PROFILING, regs); /* Initialize next_tick to the expected tick time. */ - next_tick = cpuinfo->it_value; + next_tick = cpu_data[cpu].it_value; /* Get current interval timer. * CR16 reads as 64 bits in CPU wide mode. @@ -81,14 +67,11 @@ irqreturn_t timer_interrupt(int irq, void *dev_id) * of the more expensive div/mul method */ cycles_remainder = cycles_elapsed; - ticks_elapsed = 1; while (cycles_remainder > cpt) { cycles_remainder -= cpt; - ticks_elapsed++; } } else { cycles_remainder = cycles_elapsed % cpt; - ticks_elapsed = 1 + cycles_elapsed / cpt; } /* Can we differentiate between "early CR16" (aka Scenario 1) and @@ -98,7 +81,18 @@ irqreturn_t timer_interrupt(int irq, void *dev_id) * cycles after the IT fires. But it's arbitrary how much time passes * before we call it "late". I've picked one second. */ - if (ticks_elapsed > HZ) { +/* aproximate HZ with shifts. Intended math is "(elapsed/clocktick) > HZ" */ +#if HZ == 1000 + if (cycles_elapsed > (cpt << 10) ) +#elif HZ == 250 + if (cycles_elapsed > (cpt << 8) ) +#elif HZ == 100 + if (cycles_elapsed > (cpt << 7) ) +#else +#warn WTF is HZ set to anyway? + if (cycles_elapsed > (HZ * cpt) ) +#endif + { /* Scenario 3: very long delay? bad in any case */ printk (KERN_CRIT "timer_interrupt(CPU %d): delayed!" " cycles %lX rem %lX " @@ -117,7 +111,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id) */ next_tick = now + cycles_remainder; - cpuinfo->it_value = next_tick; + cpu_data[cpu].it_value = next_tick; /* Skip one clocktick on purpose if we are likely to miss next_tick. * We want to avoid the new next_tick being less than CR16. @@ -128,22 +122,21 @@ irqreturn_t timer_interrupt(int irq, void *dev_id) next_tick += cpt; /* Program the IT when to deliver the next interrupt. */ - /* Only bottom 32-bits of next_tick are written to cr16. */ + /* Only bottom 32-bits of next_tick are written to cr16. */ mtctl(next_tick, 16); /* Done mucking with unreliable delivery of interrupts. * Go do system house keeping. */ - - if (!--cpuinfo->prof_counter) { - cpuinfo->prof_counter = cpuinfo->prof_multiplier; - update_process_times(user_mode(get_irq_regs())); - } - +#ifdef CONFIG_SMP + smp_do_timer(regs); +#else + update_process_times(user_mode(regs)); +#endif if (cpu == 0) { write_seqlock(&xtime_lock); - do_timer(ticks_elapsed); + do_timer(regs); write_sequnlock(&xtime_lock); } @@ -317,15 +310,13 @@ void __init time_init(void) start_cpu_itimer(); /* get CPU 0 started */ - if (pdc_tod_read(&tod_data) == 0) { - unsigned long flags; - - write_seqlock_irqsave(&xtime_lock, flags); + if(pdc_tod_read(&tod_data) == 0) { + write_seqlock_irq(&xtime_lock); xtime.tv_sec = tod_data.tod_sec; xtime.tv_nsec = tod_data.tod_usec * 1000; set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec); - write_sequnlock_irqrestore(&xtime_lock, flags); + write_sequnlock_irq(&xtime_lock); } else { printk(KERN_ERR "Error reading tod clock\n"); xtime.tv_sec = 0; diff --git a/trunk/arch/parisc/kernel/vmlinux.lds.S b/trunk/arch/parisc/kernel/vmlinux.lds.S index 7b943b45f7cd..b3677fc8eef5 100644 --- a/trunk/arch/parisc/kernel/vmlinux.lds.S +++ b/trunk/arch/parisc/kernel/vmlinux.lds.S @@ -153,7 +153,13 @@ SECTIONS __setup_end = .; __initcall_start = .; .initcall.init : { - INITCALLS + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) } __initcall_end = .; __con_initcall_start = .; diff --git a/trunk/arch/powerpc/Kconfig b/trunk/arch/powerpc/Kconfig index 116d7d3683ed..8b6910465578 100644 --- a/trunk/arch/powerpc/Kconfig +++ b/trunk/arch/powerpc/Kconfig @@ -425,7 +425,7 @@ config PPC_MAPLE default n help This option enables support for the Maple 970FX Evaluation Board. - For more information, refer to + For more informations, refer to config PPC_PASEMI depends on PPC_MULTIPLATFORM && PPC64 @@ -740,7 +740,7 @@ config ARCH_SPARSEMEM_ENABLE config ARCH_SPARSEMEM_DEFAULT def_bool y - depends on (SMP && PPC_PSERIES) || PPC_CELL + depends on SMP && PPC_PSERIES config ARCH_POPULATES_NODE_MAP def_bool y @@ -751,15 +751,6 @@ config ARCH_MEMORY_PROBE def_bool y depends on MEMORY_HOTPLUG -# Some NUMA nodes have memory ranges that span -# other nodes. Even though a pfn is valid and -# between a node's start and end pfns, it may not -# reside on that node. See memmap_init_zone() -# for details. -config NODES_SPAN_OTHER_NODES - def_bool y - depends on NEED_MULTIPLE_NODES - config PPC_64K_PAGES bool "64k page size" depends on PPC64 diff --git a/trunk/arch/powerpc/boot/Makefile b/trunk/arch/powerpc/boot/Makefile index 4b2be611f77f..003520b56303 100644 --- a/trunk/arch/powerpc/boot/Makefile +++ b/trunk/arch/powerpc/boot/Makefile @@ -105,17 +105,17 @@ wrapperbits := $(extra-y) $(addprefix $(obj)/,addnote hack-coff) # Bits for building various flavours of zImage ifneq ($(CROSS32_COMPILE),) -CROSSWRAP := -C "$(CROSS32_COMPILE)" +CROSSWRAP := -C $(CROSS32_COMPILE) else ifneq ($(CROSS_COMPILE),) -CROSSWRAP := -C "$(CROSS_COMPILE)" +CROSSWRAP := -C $(CROSS_COMPILE) endif endif quiet_cmd_wrap = WRAP $@ cmd_wrap =$(CONFIG_SHELL) $(wrapper) -c -o $@ -p $2 $(CROSSWRAP) vmlinux quiet_cmd_wrap_initrd = WRAP $@ - cmd_wrap_initrd =$(CONFIG_SHELL) $(wrapper) -c -o $@ -p $2 $(CROSSWRAP) \ + cmd_wrap_initrd =$(wrapper) -c -o $@ -p $2 $(CROSSWRAP) \ -i $(obj)/ramdisk.image.gz vmlinux $(obj)/zImage.chrp: vmlinux $(wrapperbits) @@ -151,12 +151,12 @@ $(obj)/zImage.initrd.miboot: vmlinux $(wrapperbits) $(obj)/uImage: vmlinux $(wrapperbits) $(call cmd,wrap,uboot) -image-$(CONFIG_PPC_PSERIES) += zImage.pseries -image-$(CONFIG_PPC_MAPLE) += zImage.pseries -image-$(CONFIG_PPC_IBM_CELL_BLADE) += zImage.pseries -image-$(CONFIG_PPC_CHRP) += zImage.chrp -image-$(CONFIG_PPC_PMAC) += zImage.pmac -image-$(CONFIG_DEFAULT_UIMAGE) += uImage +image-$(CONFIG_PPC_PSERIES) += zImage.pseries +image-$(CONFIG_PPC_MAPLE) += zImage.pseries +image-$(CONFIG_PPC_CELL) += zImage.pseries +image-$(CONFIG_PPC_CHRP) += zImage.chrp +image-$(CONFIG_PPC_PMAC) += zImage.pmac +image-$(CONFIG_DEFAULT_UIMAGE) += uImage # For 32-bit powermacs, build the COFF and miboot images # as well as the ELF images. diff --git a/trunk/arch/powerpc/boot/dts/mpc8349emitx.dts b/trunk/arch/powerpc/boot/dts/mpc8349emitx.dts deleted file mode 100644 index 27807fc45888..000000000000 --- a/trunk/arch/powerpc/boot/dts/mpc8349emitx.dts +++ /dev/null @@ -1,246 +0,0 @@ -/* - * MPC8349E-mITX Device Tree Source - * - * Copyright 2006 Freescale Semiconductor Inc. - * - * 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. - */ -/ { - model = "MPC8349EMITX"; - compatible = "MPC834xMITX"; - #address-cells = <1>; - #size-cells = <1>; - - cpus { - #cpus = <1>; - #address-cells = <1>; - #size-cells = <0>; - - PowerPC,8349@0 { - device_type = "cpu"; - reg = <0>; - d-cache-line-size = <20>; - i-cache-line-size = <20>; - d-cache-size = <8000>; - i-cache-size = <8000>; - timebase-frequency = <0>; // from bootloader - bus-frequency = <0>; // from bootloader - clock-frequency = <0>; // from bootloader - 32-bit; - }; - }; - - memory { - device_type = "memory"; - reg = <00000000 10000000>; - }; - - soc8349@e0000000 { - #address-cells = <1>; - #size-cells = <1>; - #interrupt-cells = <2>; - device_type = "soc"; - ranges = <0 e0000000 00100000>; - reg = ; - bus-frequency = <0>; // from bootloader - - wdt@200 { - device_type = "watchdog"; - compatible = "mpc83xx_wdt"; - reg = <200 100>; - }; - - i2c@3000 { - device_type = "i2c"; - compatible = "fsl-i2c"; - reg = <3000 100>; - interrupts = ; - interrupt-parent = <700>; - dfsrr; - }; - - i2c@3100 { - device_type = "i2c"; - compatible = "fsl-i2c"; - reg = <3100 100>; - interrupts = ; - interrupt-parent = <700>; - dfsrr; - }; - - spi@7000 { - device_type = "spi"; - compatible = "mpc83xx_spi"; - reg = <7000 1000>; - interrupts = <10 8>; - interrupt-parent = <700>; - mode = <0>; - }; - - usb@22000 { - device_type = "usb"; - compatible = "fsl-usb2-mph"; - reg = <22000 1000>; - #address-cells = <1>; - #size-cells = <0>; - interrupt-parent = <700>; - interrupts = <27 2>; - phy_type = "ulpi"; - port1; - }; - - usb@23000 { - device_type = "usb"; - compatible = "fsl-usb2-dr"; - reg = <23000 1000>; - #address-cells = <1>; - #size-cells = <0>; - interrupt-parent = <700>; - interrupts = <26 2>; - phy_type = "ulpi"; - }; - - mdio@24520 { - device_type = "mdio"; - compatible = "gianfar"; - reg = <24520 20>; - #address-cells = <1>; - #size-cells = <0>; - linux,phandle = <24520>; - - /* Vitesse 8201 */ - ethernet-phy@1c { - linux,phandle = <245201c>; - interrupt-parent = <700>; - interrupts = <12 2>; - reg = <1c>; - device_type = "ethernet-phy"; - }; - - /* Vitesse 7385 */ - ethernet-phy@1f { - linux,phandle = <245201f>; - interrupt-parent = <700>; - interrupts = <12 2>; - reg = <1f>; - device_type = "ethernet-phy"; - }; - }; - - ethernet@24000 { - device_type = "network"; - model = "TSEC"; - compatible = "gianfar"; - reg = <24000 1000>; - address = [ 00 00 00 00 00 00 ]; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <20 8 21 8 22 8>; - interrupt-parent = <700>; - phy-handle = <245201c>; - }; - - ethernet@25000 { - #address-cells = <1>; - #size-cells = <0>; - device_type = "network"; - model = "TSEC"; - compatible = "gianfar"; - reg = <25000 1000>; - address = [ 00 00 00 00 00 00 ]; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <23 8 24 8 25 8>; - interrupt-parent = <700>; - phy-handle = <245201f>; - }; - - serial@4500 { - device_type = "serial"; - compatible = "ns16550"; - reg = <4500 100>; - clock-frequency = <0>; // from bootloader - interrupts = <9 8>; - interrupt-parent = <700>; - }; - - serial@4600 { - device_type = "serial"; - compatible = "ns16550"; - reg = <4600 100>; - clock-frequency = <0>; // from bootloader - interrupts = ; - interrupt-parent = <700>; - }; - - pci@8500 { - interrupt-map-mask = ; - interrupt-map = < - /* IDSEL 0x10 - SATA */ - 8000 0 0 1 700 16 8 /* SATA_INTA */ - >; - interrupt-parent = <700>; - interrupts = <42 8>; - bus-range = <0 0>; - ranges = <42000000 0 80000000 80000000 0 10000000 - 02000000 0 90000000 90000000 0 10000000 - 01000000 0 00000000 e2000000 0 01000000>; - clock-frequency = <3f940aa>; - #interrupt-cells = <1>; - #size-cells = <2>; - #address-cells = <3>; - reg = <8500 100>; - compatible = "83xx"; - device_type = "pci"; - }; - - pci@8600 { - interrupt-map-mask = ; - interrupt-map = < - /* IDSEL 0x0E - MiniPCI Slot */ - 7000 0 0 1 700 15 8 /* PCI_INTA */ - - /* IDSEL 0x0F - PCI Slot */ - 7800 0 0 1 700 14 8 /* PCI_INTA */ - 7800 0 0 2 700 15 8 /* PCI_INTB */ - >; - interrupt-parent = <700>; - interrupts = <43 8>; - bus-range = <1 1>; - ranges = <42000000 0 a0000000 a0000000 0 10000000 - 02000000 0 b0000000 b0000000 0 10000000 - 01000000 0 00000000 e3000000 0 01000000>; - clock-frequency = <3f940aa>; - #interrupt-cells = <1>; - #size-cells = <2>; - #address-cells = <3>; - reg = <8600 100>; - compatible = "83xx"; - device_type = "pci"; - }; - - crypto@30000 { - device_type = "crypto"; - model = "SEC2"; - compatible = "talitos"; - reg = <30000 10000>; - interrupts = ; - interrupt-parent = <700>; - num-channels = <4>; - channel-fifo-len = <18>; - exec-units-mask = <0000007e>; - descriptor-types-mask = <01010ebf>; - }; - - pic@700 { - linux,phandle = <700>; - interrupt-controller; - #address-cells = <0>; - #interrupt-cells = <2>; - reg = <700 100>; - built-in; - device_type = "ipic"; - }; - }; -}; diff --git a/trunk/arch/powerpc/boot/of.c b/trunk/arch/powerpc/boot/of.c index 3a71845afc6c..fd99f789a37b 100644 --- a/trunk/arch/powerpc/boot/of.c +++ b/trunk/arch/powerpc/boot/of.c @@ -176,9 +176,12 @@ static void *claim(unsigned long virt, unsigned long size, unsigned long align) static void *of_try_claim(u32 size) { unsigned long addr = 0; + static u8 first_time = 1; - if (claim_base == 0) + if (first_time) { claim_base = _ALIGN_UP((unsigned long)_end, ONE_MB); + first_time = 0; + } for(; claim_base < RAM_END; claim_base += ONE_MB) { #ifdef DEBUG diff --git a/trunk/arch/powerpc/boot/wrapper b/trunk/arch/powerpc/boot/wrapper index b5fb1fee76f8..eab7318729e9 100755 --- a/trunk/arch/powerpc/boot/wrapper +++ b/trunk/arch/powerpc/boot/wrapper @@ -179,11 +179,11 @@ if [ -z "$cacheit" ]; then fi if [ -n "$initrd" ]; then - addsec $tmp "$initrd" $isection + addsec $tmp "$initrd" initrd fi if [ -n "$dtb" ]; then - addsec $tmp "$dtb" .kernel:dtb + addsec $tmp "$dtb" dtb fi if [ "$platform" != "miboot" ]; then diff --git a/trunk/arch/powerpc/boot/zImage.lds.S b/trunk/arch/powerpc/boot/zImage.lds.S index 4be3c6414b04..4b6bb3ffe3dc 100644 --- a/trunk/arch/powerpc/boot/zImage.lds.S +++ b/trunk/arch/powerpc/boot/zImage.lds.S @@ -21,11 +21,6 @@ SECTIONS __got2_end = .; } - . = ALIGN(8); - _dtb_start = .; - .kernel:dtb : { *(.kernel:dtb) } - _dtb_end = .; - . = ALIGN(4096); _vmlinux_start = .; .kernel:vmlinux.strip : { *(.kernel:vmlinux.strip) } diff --git a/trunk/arch/powerpc/configs/cell_defconfig b/trunk/arch/powerpc/configs/cell_defconfig index 0aba06d7d2ec..6fd9e7acec29 100644 --- a/trunk/arch/powerpc/configs/cell_defconfig +++ b/trunk/arch/powerpc/configs/cell_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18 -# Wed Oct 4 15:30:50 2006 +# Linux kernel version: 2.6.18-rc6 +# Sun Sep 10 10:20:32 2006 # CONFIG_PPC64=y CONFIG_64BIT=y @@ -22,7 +22,6 @@ CONFIG_ARCH_MAY_HAVE_PC_FDC=y CONFIG_PPC_OF=y CONFIG_PPC_UDBG_16550=y # CONFIG_GENERIC_TBSYNC is not set -CONFIG_AUDIT_ARCH=y # CONFIG_DEFAULT_UIMAGE is not set # @@ -53,11 +52,10 @@ CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set +CONFIG_SYSCTL=y # CONFIG_AUDIT is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y @@ -65,9 +63,7 @@ CONFIG_CPUSETS=y # CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_SYSCTL=y # CONFIG_EMBEDDED is not set -# CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set @@ -76,12 +72,12 @@ CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y +CONFIG_RT_MUTEXES=y CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_SHMEM=y CONFIG_SLAB=y CONFIG_VM_EVENT_COUNTERS=y -CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 # CONFIG_SLOB is not set @@ -100,7 +96,6 @@ CONFIG_STOP_MACHINE=y # # Block layer # -CONFIG_BLOCK=y # CONFIG_BLK_DEV_IO_TRACE is not set # @@ -120,13 +115,12 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # Platform support # CONFIG_PPC_MULTIPLATFORM=y +# CONFIG_PPC_ISERIES is not set # CONFIG_EMBEDDED6xx is not set # CONFIG_APUS is not set # CONFIG_PPC_PSERIES is not set -# CONFIG_PPC_ISERIES is not set # CONFIG_PPC_PMAC is not set # CONFIG_PPC_MAPLE is not set -# CONFIG_PPC_PASEMI is not set CONFIG_PPC_CELL=y CONFIG_PPC_CELL_NATIVE=y CONFIG_PPC_IBM_CELL_BLADE=y @@ -148,6 +142,7 @@ CONFIG_MMIO_NVRAM=y # CONFIG_SPU_FS=m CONFIG_SPU_BASE=y +CONFIG_SPUFS_MMAP=y CONFIG_CBE_RAS=y # @@ -163,7 +158,7 @@ CONFIG_PREEMPT_NONE=y CONFIG_PREEMPT_BKL=y CONFIG_BINFMT_ELF=y CONFIG_BINFMT_MISC=m -CONFIG_FORCE_MAX_ZONEORDER=9 +CONFIG_FORCE_MAX_ZONEORDER=13 # CONFIG_IOMMU_VMERGE is not set CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_KEXEC=y @@ -173,7 +168,6 @@ CONFIG_NUMA=y CONFIG_NODES_SHIFT=4 CONFIG_ARCH_SELECT_MEMORY_MODEL=y CONFIG_ARCH_SPARSEMEM_ENABLE=y -CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_SELECT_MEMORY_MODEL=y # CONFIG_FLATMEM_MANUAL is not set # CONFIG_DISCONTIGMEM_MANUAL is not set @@ -184,12 +178,12 @@ CONFIG_HAVE_MEMORY_PRESENT=y # CONFIG_SPARSEMEM_STATIC is not set CONFIG_SPARSEMEM_EXTREME=y CONFIG_MEMORY_HOTPLUG=y -CONFIG_MEMORY_HOTPLUG_SPARSE=y CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_MIGRATION=y CONFIG_RESOURCES_64BIT=y +CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y CONFIG_ARCH_MEMORY_PROBE=y -CONFIG_PPC_64K_PAGES=y +# CONFIG_PPC_64K_PAGES is not set CONFIG_SCHED_SMT=y CONFIG_PROC_DEVICETREE=y # CONFIG_CMDLINE_BOOL is not set @@ -207,7 +201,6 @@ CONFIG_GENERIC_ISA_DMA=y CONFIG_PCI=y CONFIG_PCI_DOMAINS=y CONFIG_PCIEPORTBUS=y -# CONFIG_PCI_MULTITHREAD_PROBE is not set # CONFIG_PCI_DEBUG is not set # @@ -235,7 +228,6 @@ CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set # CONFIG_NET_KEY is not set CONFIG_INET=y CONFIG_IP_MULTICAST=y @@ -254,12 +246,10 @@ CONFIG_SYN_COOKIES=y CONFIG_INET_TUNNEL=y CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y -# CONFIG_INET_XFRM_MODE_BEET is not set CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" +CONFIG_TCP_CONG_BIC=y # # IP: Virtual Server Configuration @@ -271,17 +261,11 @@ CONFIG_IPV6=y CONFIG_INET6_AH=m CONFIG_INET6_ESP=m CONFIG_INET6_IPCOMP=m -# CONFIG_IPV6_MIP6 is not set CONFIG_INET6_XFRM_TUNNEL=m CONFIG_INET6_TUNNEL=m CONFIG_INET6_XFRM_MODE_TRANSPORT=y CONFIG_INET6_XFRM_MODE_TUNNEL=y -# CONFIG_INET6_XFRM_MODE_BEET is not set -# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set -# CONFIG_IPV6_SIT is not set CONFIG_IPV6_TUNNEL=m -# CONFIG_IPV6_SUBTREES is not set -# CONFIG_IPV6_MULTIPLE_TABLES is not set # CONFIG_NETWORK_SECMARK is not set CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set @@ -338,6 +322,7 @@ CONFIG_IP_NF_QUEUE=m # CONFIG_ATALK is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set @@ -408,12 +393,6 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set -# -# Misc devices -# -# CONFIG_SGI_IOC4 is not set -# CONFIG_TIFM_CORE is not set - # # ATA/ATAPI/MFM/RLL support # @@ -455,7 +434,6 @@ CONFIG_BLK_DEV_AEC62XX=y # CONFIG_BLK_DEV_CS5530 is not set # CONFIG_BLK_DEV_HPT34X is not set # CONFIG_BLK_DEV_HPT366 is not set -# CONFIG_BLK_DEV_JMICRON is not set # CONFIG_BLK_DEV_SC1200 is not set # CONFIG_BLK_DEV_PIIX is not set # CONFIG_BLK_DEV_IT821X is not set @@ -478,12 +456,6 @@ CONFIG_IDEDMA_AUTO=y # # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set -# CONFIG_SCSI_NETLINK is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# -# CONFIG_ATA is not set # # Multi-device support (RAID and LVM) @@ -498,7 +470,6 @@ CONFIG_MD_RAID1=m # CONFIG_MD_MULTIPATH is not set # CONFIG_MD_FAULTY is not set CONFIG_BLK_DEV_DM=m -# CONFIG_DM_DEBUG is not set CONFIG_DM_CRYPT=m CONFIG_DM_SNAPSHOT=m CONFIG_DM_MIRROR=m @@ -533,7 +504,7 @@ CONFIG_NETDEVICES=y # CONFIG_DUMMY is not set CONFIG_BONDING=y # CONFIG_EQUALIZER is not set -CONFIG_TUN=y +# CONFIG_TUN is not set # # ARCnet devices @@ -581,7 +552,7 @@ CONFIG_SKGE=m # CONFIG_TIGON3 is not set # CONFIG_BNX2 is not set CONFIG_SPIDER_NET=m -# CONFIG_QLA3XXX is not set +# CONFIG_MV643XX_ETH is not set # # Ethernet (10000 Mbit) @@ -628,7 +599,6 @@ CONFIG_SPIDER_NET=m # Input device support # CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set # # Userland interfaces @@ -747,6 +717,7 @@ CONFIG_GEN_RTC=y # TPM devices # # CONFIG_TCG_TPM is not set +# CONFIG_TELCLOCK is not set # # I2C support @@ -810,7 +781,6 @@ CONFIG_I2C_ALGOBIT=y # # Dallas's 1-wire bus # -# CONFIG_W1 is not set # # Hardware Monitoring support @@ -818,10 +788,15 @@ CONFIG_I2C_ALGOBIT=y # CONFIG_HWMON is not set # CONFIG_HWMON_VID is not set +# +# Misc devices +# + # # Multimedia devices # # CONFIG_VIDEO_DEV is not set +CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices @@ -890,7 +865,6 @@ CONFIG_INFINIBAND_USER_ACCESS=m CONFIG_INFINIBAND_ADDR_TRANS=y CONFIG_INFINIBAND_MTHCA=m CONFIG_INFINIBAND_MTHCA_DEBUG=y -# CONFIG_INFINIBAND_AMSO1100 is not set CONFIG_INFINIBAND_IPOIB=m CONFIG_INFINIBAND_IPOIB_DEBUG=y CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y @@ -927,7 +901,6 @@ CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y # CONFIG_EXT3_FS_POSIX_ACL is not set # CONFIG_EXT3_FS_SECURITY is not set -# CONFIG_EXT4DEV_FS is not set CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set CONFIG_FS_MBCACHE=y @@ -935,7 +908,6 @@ CONFIG_FS_MBCACHE=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set @@ -944,7 +916,7 @@ CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set -CONFIG_AUTOFS4_FS=m +# CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set # @@ -971,10 +943,8 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" # CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y -CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set CONFIG_HUGETLBFS=y CONFIG_HUGETLB_PAGE=y CONFIG_RAMFS=y @@ -1114,7 +1084,6 @@ CONFIG_PLIST=y # Kernel hacking # # CONFIG_PRINTK_TIME is not set -# CONFIG_ENABLE_MUST_CHECK is not set CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_KERNEL=y @@ -1133,9 +1102,7 @@ CONFIG_DEBUG_SPINLOCK_SLEEP=y # CONFIG_DEBUG_INFO is not set CONFIG_DEBUG_FS=y # CONFIG_DEBUG_VM is not set -# CONFIG_DEBUG_LIST is not set # CONFIG_FORCED_INLINING is not set -# CONFIG_HEADERS_CHECK is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_DEBUG_STACKOVERFLOW is not set # CONFIG_DEBUG_STACK_USAGE is not set @@ -1156,10 +1123,6 @@ CONFIG_IRQSTACKS=y # Cryptographic options # CONFIG_CRYPTO=y -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_BLKCIPHER=m -CONFIG_CRYPTO_HASH=y -# CONFIG_CRYPTO_MANAGER is not set CONFIG_CRYPTO_HMAC=y # CONFIG_CRYPTO_NULL is not set # CONFIG_CRYPTO_MD4 is not set @@ -1169,8 +1132,6 @@ CONFIG_CRYPTO_SHA1=m # CONFIG_CRYPTO_SHA512 is not set # CONFIG_CRYPTO_WP512 is not set # CONFIG_CRYPTO_TGR192 is not set -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_CBC=m CONFIG_CRYPTO_DES=m # CONFIG_CRYPTO_BLOWFISH is not set # CONFIG_CRYPTO_TWOFISH is not set diff --git a/trunk/arch/powerpc/configs/iseries_defconfig b/trunk/arch/powerpc/configs/iseries_defconfig index b5005506c2f8..d58f82f836f8 100644 --- a/trunk/arch/powerpc/configs/iseries_defconfig +++ b/trunk/arch/powerpc/configs/iseries_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.19-rc1 -# Fri Oct 6 13:25:04 2006 +# Linux kernel version: 2.6.18-rc6 +# Sun Sep 10 10:22:57 2006 # CONFIG_PPC64=y CONFIG_64BIT=y @@ -22,7 +22,6 @@ CONFIG_ARCH_MAY_HAVE_PC_FDC=y CONFIG_PPC_OF=y # CONFIG_PPC_UDBG_16550 is not set # CONFIG_GENERIC_TBSYNC is not set -CONFIG_AUDIT_ARCH=y # CONFIG_DEFAULT_UIMAGE is not set # @@ -53,11 +52,10 @@ CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set CONFIG_POSIX_MQUEUE=y # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set +CONFIG_SYSCTL=y CONFIG_AUDIT=y CONFIG_AUDITSYSCALL=y CONFIG_IKCONFIG=y @@ -66,9 +64,7 @@ CONFIG_IKCONFIG_PROC=y # CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_SYSCTL=y # CONFIG_EMBEDDED is not set -# CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set @@ -77,12 +73,12 @@ CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y +CONFIG_RT_MUTEXES=y CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_SHMEM=y CONFIG_SLAB=y CONFIG_VM_EVENT_COUNTERS=y -CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 # CONFIG_SLOB is not set @@ -101,7 +97,6 @@ CONFIG_STOP_MACHINE=y # # Block layer # -CONFIG_BLOCK=y # CONFIG_BLK_DEV_IO_TRACE is not set # @@ -120,18 +115,13 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # # Platform support # -CONFIG_PPC_MULTIPLATFORM=y +# CONFIG_PPC_MULTIPLATFORM is not set +CONFIG_PPC_ISERIES=y # CONFIG_EMBEDDED6xx is not set # CONFIG_APUS is not set -# CONFIG_PPC_PSERIES is not set -CONFIG_PPC_ISERIES=y -# CONFIG_PPC_PMAC is not set -# CONFIG_PPC_MAPLE is not set -# CONFIG_PPC_PASEMI is not set # CONFIG_PPC_CELL is not set # CONFIG_PPC_CELL_NATIVE is not set -# CONFIG_PPC_IBM_CELL_BLADE is not set -# CONFIG_U3_DART is not set +# CONFIG_UDBG_RTAS_CONSOLE is not set # CONFIG_PPC_RTAS is not set # CONFIG_MMIO_NVRAM is not set CONFIG_IBMVIO=y @@ -157,15 +147,12 @@ CONFIG_BINFMT_ELF=y CONFIG_FORCE_MAX_ZONEORDER=13 CONFIG_IOMMU_VMERGE=y CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y -# CONFIG_KEXEC is not set -# CONFIG_CRASH_DUMP is not set CONFIG_IRQ_ALL_CPUS=y CONFIG_LPARCFG=y # CONFIG_NUMA is not set CONFIG_ARCH_SELECT_MEMORY_MODEL=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_SPARSEMEM_ENABLE=y -CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y # CONFIG_DISCONTIGMEM_MANUAL is not set @@ -192,7 +179,6 @@ CONFIG_GENERIC_ISA_DMA=y CONFIG_PCI=y CONFIG_PCI_DOMAINS=y # CONFIG_PCIEPORTBUS is not set -# CONFIG_PCI_MULTITHREAD_PROBE is not set # CONFIG_PCI_DEBUG is not set # @@ -220,7 +206,6 @@ CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_XFRM=y CONFIG_XFRM_USER=m -CONFIG_XFRM_SUB_POLICY=y CONFIG_NET_KEY=m CONFIG_INET=y CONFIG_IP_MULTICAST=y @@ -239,12 +224,10 @@ CONFIG_INET_XFRM_TUNNEL=m CONFIG_INET_TUNNEL=y CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=m CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" +CONFIG_TCP_CONG_BIC=y # # IP: Virtual Server Configuration @@ -264,7 +247,6 @@ CONFIG_NETFILTER=y CONFIG_NETFILTER_XTABLES=m CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m CONFIG_NETFILTER_XT_TARGET_CONNMARK=m -CONFIG_NETFILTER_XT_TARGET_DSCP=m CONFIG_NETFILTER_XT_TARGET_MARK=m CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m CONFIG_NETFILTER_XT_TARGET_NOTRACK=m @@ -273,7 +255,6 @@ CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m CONFIG_NETFILTER_XT_MATCH_CONNMARK=m CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m # CONFIG_NETFILTER_XT_MATCH_DCCP is not set -CONFIG_NETFILTER_XT_MATCH_DSCP=m # CONFIG_NETFILTER_XT_MATCH_ESP is not set CONFIG_NETFILTER_XT_MATCH_HELPER=m CONFIG_NETFILTER_XT_MATCH_LENGTH=m @@ -313,6 +294,7 @@ CONFIG_IP_NF_MATCH_IPRANGE=m CONFIG_IP_NF_MATCH_TOS=m CONFIG_IP_NF_MATCH_RECENT=m CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_DSCP=m # CONFIG_IP_NF_MATCH_AH is not set CONFIG_IP_NF_MATCH_TTL=m CONFIG_IP_NF_MATCH_OWNER=m @@ -337,6 +319,7 @@ CONFIG_IP_NF_NAT_AMANDA=m CONFIG_IP_NF_MANGLE=m CONFIG_IP_NF_TARGET_TOS=m CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_DSCP=m CONFIG_IP_NF_TARGET_TTL=m CONFIG_IP_NF_TARGET_CLUSTERIP=m CONFIG_IP_NF_RAW=m @@ -368,6 +351,7 @@ CONFIG_LLC=y # CONFIG_ATALK is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set @@ -449,7 +433,6 @@ CONFIG_BLK_DEV_INITRD=y # # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y -CONFIG_SCSI_NETLINK=y CONFIG_SCSI_PROC_FS=y # @@ -471,14 +454,12 @@ CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_LOGGING is not set # -# SCSI Transports +# SCSI Transport Attributes # CONFIG_SCSI_SPI_ATTRS=y CONFIG_SCSI_FC_ATTRS=y # CONFIG_SCSI_ISCSI_ATTRS is not set -CONFIG_SCSI_SAS_ATTRS=m -CONFIG_SCSI_SAS_LIBSAS=m -CONFIG_SCSI_SAS_LIBSAS_DEBUG=y +# CONFIG_SCSI_SAS_ATTRS is not set # # SCSI low-level drivers @@ -491,11 +472,10 @@ CONFIG_SCSI_SAS_LIBSAS_DEBUG=y # CONFIG_SCSI_AIC7XXX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_AIC79XX is not set -# CONFIG_SCSI_AIC94XX is not set -# CONFIG_SCSI_ARCMSR is not set # CONFIG_MEGARAID_NEWGEN is not set # CONFIG_MEGARAID_LEGACY is not set # CONFIG_MEGARAID_SAS is not set +# CONFIG_ATA is not set # CONFIG_SCSI_HPTIOP is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_DMX3191D is not set @@ -506,21 +486,15 @@ CONFIG_SCSI_SAS_LIBSAS_DEBUG=y CONFIG_SCSI_IBMVSCSI=m # CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_STEX is not set # CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set # CONFIG_SCSI_QLOGIC_1280 is not set # CONFIG_SCSI_QLA_FC is not set -# CONFIG_SCSI_QLA_ISCSI is not set # CONFIG_SCSI_LPFC is not set # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_DEBUG is not set -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# -# CONFIG_ATA is not set - # # Multi-device support (RAID and LVM) # @@ -534,7 +508,6 @@ CONFIG_MD_RAID10=m CONFIG_MD_MULTIPATH=m CONFIG_MD_FAULTY=m CONFIG_BLK_DEV_DM=y -# CONFIG_DM_DEBUG is not set CONFIG_DM_CRYPT=m CONFIG_DM_SNAPSHOT=m CONFIG_DM_MIRROR=m @@ -600,7 +573,6 @@ CONFIG_MII=y # CONFIG_HP100 is not set CONFIG_NET_PCI=y CONFIG_PCNET32=y -CONFIG_PCNET32_NAPI=y # CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_B44 is not set @@ -638,7 +610,6 @@ CONFIG_E1000=m # CONFIG_VIA_VELOCITY is not set # CONFIG_TIGON3 is not set # CONFIG_BNX2 is not set -# CONFIG_QLA3XXX is not set # # Ethernet (10000 Mbit) @@ -678,7 +649,6 @@ CONFIG_PPP_BSDCOMP=m # CONFIG_PPP_MPPE is not set CONFIG_PPPOE=m # CONFIG_SLIP is not set -CONFIG_SLHC=m # CONFIG_NET_FC is not set # CONFIG_SHAPER is not set CONFIG_NETCONSOLE=y @@ -701,7 +671,6 @@ CONFIG_NET_POLL_CONTROLLER=y # Input device support # CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set # # Userland interfaces @@ -805,12 +774,12 @@ CONFIG_MAX_RAW_DEVS=256 # # Misc devices # -# CONFIG_TIFM_CORE is not set # # Multimedia devices # # CONFIG_VIDEO_DEV is not set +CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices @@ -924,9 +893,6 @@ CONFIG_XFS_FS=m CONFIG_XFS_SECURITY=y CONFIG_XFS_POSIX_ACL=y # CONFIG_XFS_RT is not set -CONFIG_GFS2_FS=m -CONFIG_GFS2_FS_LOCKING_NOLOCK=m -CONFIG_GFS2_FS_LOCKING_DLM=m # CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set @@ -963,14 +929,12 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" # CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y -CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y CONFIG_TMPFS=y -CONFIG_TMPFS_POSIX_ACL=y # CONFIG_HUGETLBFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y -CONFIG_CONFIGFS_FS=m +# CONFIG_CONFIGFS_FS is not set # # Miscellaneous filesystems @@ -1024,7 +988,6 @@ CONFIG_CIFS_POSIX=y # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set # CONFIG_9P_FS is not set -CONFIG_GENERIC_ACL=y # # Partition Types @@ -1076,12 +1039,6 @@ CONFIG_NLS_ISO8859_1=y # CONFIG_NLS_KOI8_U is not set # CONFIG_NLS_UTF8 is not set -# -# Distributed Lock Manager -# -CONFIG_DLM=m -# CONFIG_DLM_DEBUG is not set - # # iSeries device drivers # @@ -1116,7 +1073,6 @@ CONFIG_PLIST=y # Kernel hacking # # CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_MUST_CHECK=y CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_KERNEL=y @@ -1135,7 +1091,6 @@ CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_DEBUG_INFO is not set CONFIG_DEBUG_FS=y # CONFIG_DEBUG_VM is not set -# CONFIG_DEBUG_LIST is not set # CONFIG_FORCED_INLINING is not set # CONFIG_RCU_TORTURE_TEST is not set CONFIG_DEBUG_STACKOVERFLOW=y @@ -1154,10 +1109,6 @@ CONFIG_IRQSTACKS=y # Cryptographic options # CONFIG_CRYPTO=y -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_BLKCIPHER=m -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_MANAGER=m CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_NULL=m CONFIG_CRYPTO_MD4=m @@ -1167,12 +1118,9 @@ CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m CONFIG_CRYPTO_WP512=m CONFIG_CRYPTO_TGR192=m -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_CBC=m CONFIG_CRYPTO_DES=y CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_TWOFISH_COMMON=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_AES=m CONFIG_CRYPTO_CAST5=m diff --git a/trunk/arch/powerpc/configs/maple_defconfig b/trunk/arch/powerpc/configs/maple_defconfig index ae96a5b2f00d..62ba66091a13 100644 --- a/trunk/arch/powerpc/configs/maple_defconfig +++ b/trunk/arch/powerpc/configs/maple_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18 -# Mon Oct 9 11:59:34 2006 +# Linux kernel version: 2.6.18-rc6 +# Sun Sep 10 10:24:55 2006 # CONFIG_PPC64=y CONFIG_64BIT=y @@ -22,7 +22,6 @@ CONFIG_ARCH_MAY_HAVE_PC_FDC=y CONFIG_PPC_OF=y CONFIG_PPC_UDBG_16550=y CONFIG_GENERIC_TBSYNC=y -CONFIG_AUDIT_ARCH=y # CONFIG_DEFAULT_UIMAGE is not set # @@ -35,7 +34,7 @@ CONFIG_PPC_FPU=y CONFIG_PPC_STD_MMU=y CONFIG_VIRT_CPU_ACCOUNTING=y CONFIG_SMP=y -CONFIG_NR_CPUS=4 +CONFIG_NR_CPUS=2 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -52,11 +51,10 @@ CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set CONFIG_POSIX_MQUEUE=y # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set +CONFIG_SYSCTL=y # CONFIG_AUDIT is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y @@ -64,9 +62,7 @@ CONFIG_IKCONFIG_PROC=y # CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_SYSCTL=y # CONFIG_EMBEDDED is not set -# CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y # CONFIG_KALLSYMS_EXTRA_PASS is not set @@ -75,12 +71,12 @@ CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y +CONFIG_RT_MUTEXES=y CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_SHMEM=y CONFIG_SLAB=y CONFIG_VM_EVENT_COUNTERS=y -CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 # CONFIG_SLOB is not set @@ -99,7 +95,6 @@ CONFIG_STOP_MACHINE=y # # Block layer # -CONFIG_BLOCK=y # CONFIG_BLK_DEV_IO_TRACE is not set # @@ -119,16 +114,16 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # Platform support # CONFIG_PPC_MULTIPLATFORM=y +# CONFIG_PPC_ISERIES is not set # CONFIG_EMBEDDED6xx is not set # CONFIG_APUS is not set # CONFIG_PPC_PSERIES is not set -# CONFIG_PPC_ISERIES is not set # CONFIG_PPC_PMAC is not set CONFIG_PPC_MAPLE=y -# CONFIG_PPC_PASEMI is not set # CONFIG_PPC_CELL is not set # CONFIG_PPC_CELL_NATIVE is not set # CONFIG_PPC_IBM_CELL_BLADE is not set +# CONFIG_UDBG_RTAS_CONSOLE is not set CONFIG_U3_DART=y # CONFIG_PPC_RTAS is not set # CONFIG_MMIO_NVRAM is not set @@ -162,7 +157,6 @@ CONFIG_IRQ_ALL_CPUS=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_SPARSEMEM_ENABLE=y -CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y # CONFIG_DISCONTIGMEM_MANUAL is not set @@ -190,7 +184,6 @@ CONFIG_GENERIC_ISA_DMA=y CONFIG_PCI=y CONFIG_PCI_DOMAINS=y # CONFIG_PCIEPORTBUS is not set -# CONFIG_PCI_MULTITHREAD_PROBE is not set # CONFIG_PCI_DEBUG is not set # @@ -218,7 +211,6 @@ CONFIG_PACKET_MMAP=y CONFIG_UNIX=y CONFIG_XFRM=y CONFIG_XFRM_USER=m -# CONFIG_XFRM_SUB_POLICY is not set # CONFIG_NET_KEY is not set CONFIG_INET=y CONFIG_IP_MULTICAST=y @@ -240,12 +232,10 @@ CONFIG_IP_PNP_DHCP=y # CONFIG_INET_TUNNEL is not set CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=y CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" +CONFIG_TCP_CONG_BIC=y # CONFIG_IPV6 is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set @@ -275,6 +265,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_ATALK is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set @@ -386,7 +377,6 @@ CONFIG_BLK_DEV_AMD74XX=y # CONFIG_BLK_DEV_CS5530 is not set # CONFIG_BLK_DEV_HPT34X is not set # CONFIG_BLK_DEV_HPT366 is not set -# CONFIG_BLK_DEV_JMICRON is not set # CONFIG_BLK_DEV_SC1200 is not set # CONFIG_BLK_DEV_PIIX is not set # CONFIG_BLK_DEV_IT821X is not set @@ -409,12 +399,6 @@ CONFIG_IDEDMA_AUTO=y # # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set -# CONFIG_SCSI_NETLINK is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# -# CONFIG_ATA is not set # # Multi-device support (RAID and LVM) @@ -514,7 +498,7 @@ CONFIG_E1000=y # CONFIG_VIA_VELOCITY is not set CONFIG_TIGON3=y # CONFIG_BNX2 is not set -# CONFIG_QLA3XXX is not set +# CONFIG_MV643XX_ETH is not set # # Ethernet (10000 Mbit) @@ -561,7 +545,6 @@ CONFIG_TIGON3=y # Input device support # CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set # # Userland interfaces @@ -721,7 +704,6 @@ CONFIG_I2C_AMD8111=y # # Misc devices # -# CONFIG_TIFM_CORE is not set # # Multimedia devices @@ -797,6 +779,7 @@ CONFIG_USB_UHCI_HCD=y # # may also be needed; see USB_STORAGE Help for more information # +# CONFIG_USB_STORAGE is not set # CONFIG_USB_LIBUSUAL is not set # @@ -819,7 +802,6 @@ CONFIG_USB_HIDINPUT=y # CONFIG_USB_ATI_REMOTE2 is not set # CONFIG_USB_KEYSPAN_REMOTE is not set # CONFIG_USB_APPLETOUCH is not set -# CONFIG_USB_TRANCEVIBRATOR is not set # # USB Imaging devices @@ -846,7 +828,6 @@ CONFIG_USB_MON=y CONFIG_USB_SERIAL=y # CONFIG_USB_SERIAL_CONSOLE is not set CONFIG_USB_SERIAL_GENERIC=y -# CONFIG_USB_SERIAL_AIRCABLE is not set # CONFIG_USB_SERIAL_AIRPRIME is not set # CONFIG_USB_SERIAL_ARK3116 is not set # CONFIG_USB_SERIAL_BELKIN is not set @@ -881,7 +862,6 @@ CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y # CONFIG_USB_SERIAL_KLSI is not set # CONFIG_USB_SERIAL_KOBIL_SCT is not set # CONFIG_USB_SERIAL_MCT_U232 is not set -# CONFIG_USB_SERIAL_MOS7840 is not set # CONFIG_USB_SERIAL_NAVMAN is not set # CONFIG_USB_SERIAL_PL2303 is not set # CONFIG_USB_SERIAL_HP4X is not set @@ -899,7 +879,6 @@ CONFIG_USB_EZUSB=y # # CONFIG_USB_EMI62 is not set # CONFIG_USB_EMI26 is not set -# CONFIG_USB_ADUTUX is not set # CONFIG_USB_AUERSWALD is not set # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set @@ -907,9 +886,9 @@ CONFIG_USB_EZUSB=y # CONFIG_USB_LED is not set # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set -# CONFIG_USB_PHIDGET is not set +# CONFIG_USB_PHIDGETKIT is not set +# CONFIG_USB_PHIDGETSERVO is not set # CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_FTDI_ELAN is not set # CONFIG_USB_APPLEDISPLAY is not set # CONFIG_USB_SISUSBVGA is not set # CONFIG_USB_LD is not set @@ -1016,10 +995,8 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" # CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y -CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set CONFIG_HUGETLBFS=y CONFIG_HUGETLB_PAGE=y CONFIG_RAMFS=y @@ -1152,7 +1129,6 @@ CONFIG_PLIST=y # Kernel hacking # # CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_MUST_CHECK=y CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_KERNEL=y @@ -1172,7 +1148,6 @@ CONFIG_DEBUG_SPINLOCK_SLEEP=y # CONFIG_DEBUG_INFO is not set CONFIG_DEBUG_FS=y # CONFIG_DEBUG_VM is not set -# CONFIG_DEBUG_LIST is not set # CONFIG_FORCED_INLINING is not set # CONFIG_RCU_TORTURE_TEST is not set CONFIG_DEBUG_STACKOVERFLOW=y @@ -1194,9 +1169,6 @@ CONFIG_BOOTX_TEXT=y # Cryptographic options # CONFIG_CRYPTO=y -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_BLKCIPHER=m -CONFIG_CRYPTO_MANAGER=m # CONFIG_CRYPTO_HMAC is not set # CONFIG_CRYPTO_NULL is not set # CONFIG_CRYPTO_MD4 is not set @@ -1206,8 +1178,6 @@ CONFIG_CRYPTO_MD5=y # CONFIG_CRYPTO_SHA512 is not set # CONFIG_CRYPTO_WP512 is not set # CONFIG_CRYPTO_TGR192 is not set -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_CBC=m CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_BLOWFISH is not set # CONFIG_CRYPTO_TWOFISH is not set diff --git a/trunk/arch/powerpc/configs/mpc834x_itx_defconfig b/trunk/arch/powerpc/configs/mpc834x_itx_defconfig index 0561b73a918f..cd3535e1a095 100644 --- a/trunk/arch/powerpc/configs/mpc834x_itx_defconfig +++ b/trunk/arch/powerpc/configs/mpc834x_itx_defconfig @@ -1248,7 +1248,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_AMIGA_PARTITION is not set # CONFIG_ATARI_PARTITION is not set # CONFIG_MAC_PARTITION is not set -CONFIG_MSDOS_PARTITION=y +# CONFIG_MSDOS_PARTITION is not set # CONFIG_LDM_PARTITION is not set # CONFIG_SGI_PARTITION is not set # CONFIG_ULTRIX_PARTITION is not set diff --git a/trunk/arch/powerpc/configs/pseries_defconfig b/trunk/arch/powerpc/configs/pseries_defconfig index d2833c1a1f3d..44175fb7adec 100644 --- a/trunk/arch/powerpc/configs/pseries_defconfig +++ b/trunk/arch/powerpc/configs/pseries_defconfig @@ -184,7 +184,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_MIGRATION=y CONFIG_RESOURCES_64BIT=y CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y -CONFIG_NODES_SPAN_OTHER_NODES=y # CONFIG_PPC_64K_PAGES is not set CONFIG_SCHED_SMT=y CONFIG_PROC_DEVICETREE=y @@ -507,7 +506,7 @@ CONFIG_SCSI_SAS_ATTRS=m # CONFIG_MEGARAID_NEWGEN is not set # CONFIG_MEGARAID_LEGACY is not set # CONFIG_MEGARAID_SAS is not set -CONFIG_ATA=y +# CONFIG_ATA is not set # CONFIG_SCSI_HPTIOP is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_DMX3191D is not set diff --git a/trunk/arch/powerpc/kernel/Makefile b/trunk/arch/powerpc/kernel/Makefile index 7af23c43fd4b..8b133afbdc20 100644 --- a/trunk/arch/powerpc/kernel/Makefile +++ b/trunk/arch/powerpc/kernel/Makefile @@ -38,6 +38,7 @@ obj-$(CONFIG_6xx) += idle_6xx.o l2cr_6xx.o cpu_setup_6xx.o obj-$(CONFIG_TAU) += tau_6xx.o obj32-$(CONFIG_SOFTWARE_SUSPEND) += swsusp_32.o obj32-$(CONFIG_MODULES) += module_32.o +obj-$(CONFIG_E500) += perfmon_fsl_booke.o ifeq ($(CONFIG_PPC_MERGE),y) diff --git a/trunk/arch/powerpc/kernel/btext.c b/trunk/arch/powerpc/kernel/btext.c index 93f21aaf7c8e..995fcef156fd 100644 --- a/trunk/arch/powerpc/kernel/btext.c +++ b/trunk/arch/powerpc/kernel/btext.c @@ -182,7 +182,7 @@ int btext_initialize(struct device_node *np) prop = get_property(np, "linux,bootx-linebytes", NULL); if (prop == NULL) prop = get_property(np, "linebytes", NULL); - if (prop && *prop != 0xffffffffu) + if (prop) pitch = *prop; if (pitch == 1) pitch = 0x1000; diff --git a/trunk/arch/powerpc/kernel/cputable.c b/trunk/arch/powerpc/kernel/cputable.c index bfd499ee3753..47a613cdd775 100644 --- a/trunk/arch/powerpc/kernel/cputable.c +++ b/trunk/arch/powerpc/kernel/cputable.c @@ -18,7 +18,6 @@ #include #include -#include /* for PTRRELOC on ARCH=ppc */ struct cpu_spec* cur_cpu_spec = NULL; EXPORT_SYMBOL(cur_cpu_spec); @@ -74,7 +73,7 @@ extern void __restore_cpu_ppc970(void); #define PPC_FEATURE_SPE_COMP 0 #endif -static struct cpu_spec cpu_specs[] = { +struct cpu_spec cpu_specs[] = { #ifdef CONFIG_PPC64 { /* Power3 */ .pvr_mask = 0xffff0000, @@ -228,21 +227,6 @@ static struct cpu_spec cpu_specs[] = { .oprofile_type = PPC_OPROFILE_POWER4, .platform = "ppc970", }, - { /* PPC970GX */ - .pvr_mask = 0xffff0000, - .pvr_value = 0x00450000, - .cpu_name = "PPC970GX", - .cpu_features = CPU_FTRS_PPC970, - .cpu_user_features = COMMON_USER_POWER4 | - PPC_FEATURE_HAS_ALTIVEC_COMP, - .icache_bsize = 128, - .dcache_bsize = 128, - .num_pmcs = 8, - .cpu_setup = __setup_cpu_ppc970, - .oprofile_cpu_type = "ppc64/970", - .oprofile_type = PPC_OPROFILE_POWER4, - .platform = "ppc970", - }, { /* Power5 GR */ .pvr_mask = 0xffff0000, .pvr_value = 0x003a0000, @@ -284,7 +268,7 @@ static struct cpu_spec cpu_specs[] = { .cpu_user_features = COMMON_USER_POWER6, .icache_bsize = 128, .dcache_bsize = 128, - .num_pmcs = 6, + .num_pmcs = 8, .oprofile_cpu_type = "ppc64/power6", .oprofile_type = PPC_OPROFILE_POWER4, .oprofile_mmcra_sihv = POWER6_MMCRA_SIHV, @@ -1168,71 +1152,3 @@ static struct cpu_spec cpu_specs[] = { #endif /* !CLASSIC_PPC */ #endif /* CONFIG_PPC32 */ }; - -struct cpu_spec *identify_cpu(unsigned long offset) -{ - struct cpu_spec *s = cpu_specs; - struct cpu_spec **cur = &cur_cpu_spec; - unsigned int pvr = mfspr(SPRN_PVR); - int i; - - s = PTRRELOC(s); - cur = PTRRELOC(cur); - - if (*cur != NULL) - return PTRRELOC(*cur); - - for (i = 0; i < ARRAY_SIZE(cpu_specs); i++,s++) - if ((pvr & s->pvr_mask) == s->pvr_value) { - *cur = cpu_specs + i; -#ifdef CONFIG_PPC64 - /* ppc64 expects identify_cpu to also call setup_cpu - * for that processor. I will consolidate that at a - * later time, for now, just use our friend #ifdef. - * we also don't need to PTRRELOC the function pointer - * on ppc64 as we are running at 0 in real mode. - */ - if (s->cpu_setup) { - s->cpu_setup(offset, s); - } -#endif /* CONFIG_PPC64 */ - return s; - } - BUG(); - return NULL; -} - -void do_feature_fixups(unsigned long value, void *fixup_start, void *fixup_end) -{ - struct fixup_entry { - unsigned long mask; - unsigned long value; - long start_off; - long end_off; - } *fcur, *fend; - - fcur = fixup_start; - fend = fixup_end; - - for (; fcur < fend; fcur++) { - unsigned int *pstart, *pend, *p; - - if ((value & fcur->mask) == fcur->value) - continue; - - /* These PTRRELOCs will disappear once the new scheme for - * modules and vdso is implemented - */ - pstart = ((unsigned int *)fcur) + (fcur->start_off / 4); - pend = ((unsigned int *)fcur) + (fcur->end_off / 4); - - for (p = pstart; p < pend; p++) { - *p = 0x60000000u; - asm volatile ("dcbst 0, %0" : : "r" (p)); - } - asm volatile ("sync" : : : "memory"); - for (p = pstart; p < pend; p++) - asm volatile ("icbi 0,%0" : : "r" (p)); - asm volatile ("sync; isync" : : : "memory"); - } -} diff --git a/trunk/arch/powerpc/kernel/head_64.S b/trunk/arch/powerpc/kernel/head_64.S index e720729f3e55..645c7f10fb28 100644 --- a/trunk/arch/powerpc/kernel/head_64.S +++ b/trunk/arch/powerpc/kernel/head_64.S @@ -487,7 +487,7 @@ BEGIN_FTR_SECTION rlwimi r13,r12,16,0x20 mfcr r12 cmpwi r13,0x2c - beq do_stab_bolted_pSeries + beq .do_stab_bolted_pSeries mtcrf 0x80,r12 mfspr r12,SPRN_SPRG2 END_FTR_SECTION_IFCLR(CPU_FTR_SLB) @@ -600,7 +600,7 @@ system_call_pSeries: STD_EXCEPTION_PSERIES(., performance_monitor) .align 7 -do_stab_bolted_pSeries: +_GLOBAL(do_stab_bolted_pSeries) mtcrf 0x80,r12 mfspr r12,SPRN_SPRG2 EXCEPTION_PROLOG_PSERIES(PACA_EXSLB, .do_stab_bolted) @@ -1046,7 +1046,7 @@ slb_miss_fault: li r5,0 std r4,_DAR(r1) std r5,_DSISR(r1) - b handle_page_fault + b .handle_page_fault unrecov_user_slb: EXCEPTION_PROLOG_COMMON(0x4200, PACA_EXGEN) @@ -1174,13 +1174,12 @@ program_check_common: .globl fp_unavailable_common fp_unavailable_common: EXCEPTION_PROLOG_COMMON(0x800, PACA_EXGEN) - bne 1f /* if from user, just load it up */ + bne .load_up_fpu /* if from user, just load it up */ bl .save_nvgprs addi r3,r1,STACK_FRAME_OVERHEAD ENABLE_INTS bl .kernel_fp_unavailable_exception BUG_OPCODE -1: b .load_up_fpu .align 7 .globl altivec_unavailable_common @@ -1280,10 +1279,10 @@ _GLOBAL(do_hash_page) std r4,_DSISR(r1) andis. r0,r4,0xa450 /* weird error? */ - bne- handle_page_fault /* if not, try to insert a HPTE */ + bne- .handle_page_fault /* if not, try to insert a HPTE */ BEGIN_FTR_SECTION andis. r0,r4,0x0020 /* Is it a segment table fault? */ - bne- do_ste_alloc /* If so handle it */ + bne- .do_ste_alloc /* If so handle it */ END_FTR_SECTION_IFCLR(CPU_FTR_SLB) /* @@ -1325,7 +1324,7 @@ BEGIN_FW_FTR_SECTION * because ret_from_except_lite will check for and handle pending * interrupts if necessary. */ - beq 13f + beq .ret_from_except_lite /* For a hash failure, we don't bother re-enabling interrupts */ ble- 12f @@ -1347,14 +1346,14 @@ BEGIN_FW_FTR_SECTION END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES) /* Here we have a page fault that hash_page can't handle. */ -handle_page_fault: +_GLOBAL(handle_page_fault) ENABLE_INTS 11: ld r4,_DAR(r1) ld r5,_DSISR(r1) addi r3,r1,STACK_FRAME_OVERHEAD bl .do_page_fault cmpdi r3,0 - beq+ 13f + beq+ .ret_from_except_lite bl .save_nvgprs mr r5,r3 addi r3,r1,STACK_FRAME_OVERHEAD @@ -1371,14 +1370,12 @@ handle_page_fault: bl .low_hash_fault b .ret_from_except -13: b .ret_from_except_lite - /* here we have a segment miss */ -do_ste_alloc: +_GLOBAL(do_ste_alloc) bl .ste_allocate /* try to insert stab entry */ cmpdi r3,0 - bne- handle_page_fault - b fast_exception_return + beq+ fast_exception_return + b .handle_page_fault /* * r13 points to the PACA, r9 contains the saved CR, @@ -1583,6 +1580,11 @@ _STATIC(__start_initialization_iSeries) li r0,0 stdu r0,-STACK_FRAME_OVERHEAD(r1) + LOAD_REG_IMMEDIATE(r3,cpu_specs) + LOAD_REG_IMMEDIATE(r4,cur_cpu_spec) + li r5,0 + bl .identify_cpu + LOAD_REG_IMMEDIATE(r2,__toc_start) addi r2,r2,0x4000 addi r2,r2,0x4000 @@ -1644,8 +1646,6 @@ _GLOBAL(__start_initialization_multiplatform) cmpwi r0,0x3c /* 970FX */ beq 1f cmpwi r0,0x44 /* 970MP */ - beq 1f - cmpwi r0,0x45 /* 970GX */ bne 2f 1: bl .__cpu_preinit_ppc970 2: @@ -1964,6 +1964,13 @@ _STATIC(start_here_multiplatform) addi r2,r2,0x4000 add r2,r2,r26 + LOAD_REG_IMMEDIATE(r3, cpu_specs) + add r3,r3,r26 + LOAD_REG_IMMEDIATE(r4,cur_cpu_spec) + add r4,r4,r26 + mr r5,r26 + bl .identify_cpu + /* Do very early kernel initializations, including initial hash table, * stab and slb setup before we turn on relocation. */ @@ -1993,6 +2000,13 @@ _STATIC(start_here_common) li r0,0 stdu r0,-STACK_FRAME_OVERHEAD(r1) + /* Apply the CPUs-specific fixups (nop out sections not relevant + * to this CPU + */ + li r3,0 + bl .do_cpu_ftr_fixups + bl .do_fw_ftr_fixups + /* ptr to current */ LOAD_REG_IMMEDIATE(r4, init_task) std r4,PACACURRENT(r13) diff --git a/trunk/arch/powerpc/kernel/ibmebus.c b/trunk/arch/powerpc/kernel/ibmebus.c index 39db7a3affe1..124dbcba94a8 100644 --- a/trunk/arch/powerpc/kernel/ibmebus.c +++ b/trunk/arch/powerpc/kernel/ibmebus.c @@ -319,7 +319,7 @@ EXPORT_SYMBOL(ibmebus_unregister_driver); int ibmebus_request_irq(struct ibmebus_dev *dev, u32 ist, - irq_handler_t handler, + irqreturn_t (*handler)(int, void*, struct pt_regs *), unsigned long irq_flags, const char * devname, void *dev_id) { diff --git a/trunk/arch/powerpc/kernel/iommu.c b/trunk/arch/powerpc/kernel/iommu.c index ba6b7256084b..ba0694071728 100644 --- a/trunk/arch/powerpc/kernel/iommu.c +++ b/trunk/arch/powerpc/kernel/iommu.c @@ -47,17 +47,6 @@ static int novmerge = 0; static int novmerge = 1; #endif -static inline unsigned long iommu_num_pages(unsigned long vaddr, - unsigned long slen) -{ - unsigned long npages; - - npages = IOMMU_PAGE_ALIGN(vaddr + slen) - (vaddr & IOMMU_PAGE_MASK); - npages >>= IOMMU_PAGE_SHIFT; - - return npages; -} - static int __init setup_iommu(char *str) { if (!strcmp(str, "novmerge")) @@ -86,7 +75,7 @@ static unsigned long iommu_range_alloc(struct iommu_table *tbl, /* This allocator was derived from x86_64's bit string search */ /* Sanity check */ - if (unlikely(npages == 0)) { + if (unlikely(npages) == 0) { if (printk_ratelimit()) WARN_ON(1); return DMA_ERROR_CODE; @@ -189,10 +178,10 @@ static dma_addr_t iommu_alloc(struct iommu_table *tbl, void *page, } entry += tbl->it_offset; /* Offset into real TCE table */ - ret = entry << IOMMU_PAGE_SHIFT; /* Set the return dma address */ + ret = entry << PAGE_SHIFT; /* Set the return dma address */ /* Put the TCEs in the HW table */ - ppc_md.tce_build(tbl, entry, npages, (unsigned long)page & IOMMU_PAGE_MASK, + ppc_md.tce_build(tbl, entry, npages, (unsigned long)page & PAGE_MASK, direction); @@ -214,7 +203,7 @@ static void __iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr, unsigned long entry, free_entry; unsigned long i; - entry = dma_addr >> IOMMU_PAGE_SHIFT; + entry = dma_addr >> PAGE_SHIFT; free_entry = entry - tbl->it_offset; if (((free_entry + npages) > tbl->it_size) || @@ -281,7 +270,7 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl, /* Init first segment length for backout at failure */ outs->dma_length = 0; - DBG("sg mapping %d elements:\n", nelems); + DBG("mapping %d elements:\n", nelems); spin_lock_irqsave(&(tbl->it_lock), flags); @@ -296,8 +285,9 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl, } /* Allocate iommu entries for that segment */ vaddr = (unsigned long)page_address(s->page) + s->offset; - npages = iommu_num_pages(vaddr, slen); - entry = iommu_range_alloc(tbl, npages, &handle, mask >> IOMMU_PAGE_SHIFT, 0); + npages = PAGE_ALIGN(vaddr + slen) - (vaddr & PAGE_MASK); + npages >>= PAGE_SHIFT; + entry = iommu_range_alloc(tbl, npages, &handle, mask >> PAGE_SHIFT, 0); DBG(" - vaddr: %lx, size: %lx\n", vaddr, slen); @@ -311,14 +301,14 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl, /* Convert entry to a dma_addr_t */ entry += tbl->it_offset; - dma_addr = entry << IOMMU_PAGE_SHIFT; - dma_addr |= (s->offset & ~IOMMU_PAGE_MASK); + dma_addr = entry << PAGE_SHIFT; + dma_addr |= s->offset; - DBG(" - %lu pages, entry: %lx, dma_addr: %lx\n", + DBG(" - %lx pages, entry: %lx, dma_addr: %lx\n", npages, entry, dma_addr); /* Insert into HW table */ - ppc_md.tce_build(tbl, entry, npages, vaddr & IOMMU_PAGE_MASK, direction); + ppc_md.tce_build(tbl, entry, npages, vaddr & PAGE_MASK, direction); /* If we are in an open segment, try merging */ if (segstart != s) { @@ -333,7 +323,7 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl, DBG(" can't merge, new segment.\n"); } else { outs->dma_length += s->length; - DBG(" merged, new len: %ux\n", outs->dma_length); + DBG(" merged, new len: %lx\n", outs->dma_length); } } @@ -377,8 +367,9 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl, if (s->dma_length != 0) { unsigned long vaddr, npages; - vaddr = s->dma_address & IOMMU_PAGE_MASK; - npages = iommu_num_pages(s->dma_address, s->dma_length); + vaddr = s->dma_address & PAGE_MASK; + npages = (PAGE_ALIGN(s->dma_address + s->dma_length) - vaddr) + >> PAGE_SHIFT; __iommu_free(tbl, vaddr, npages); s->dma_address = DMA_ERROR_CODE; s->dma_length = 0; @@ -407,7 +398,8 @@ void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist, if (sglist->dma_length == 0) break; - npages = iommu_num_pages(dma_handle,sglist->dma_length); + npages = (PAGE_ALIGN(dma_handle + sglist->dma_length) + - (dma_handle & PAGE_MASK)) >> PAGE_SHIFT; __iommu_free(tbl, dma_handle, npages); sglist++; } @@ -540,11 +532,12 @@ dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr, BUG_ON(direction == DMA_NONE); uaddr = (unsigned long)vaddr; - npages = iommu_num_pages(uaddr, size); + npages = PAGE_ALIGN(uaddr + size) - (uaddr & PAGE_MASK); + npages >>= PAGE_SHIFT; if (tbl) { dma_handle = iommu_alloc(tbl, vaddr, npages, direction, - mask >> IOMMU_PAGE_SHIFT, 0); + mask >> PAGE_SHIFT, 0); if (dma_handle == DMA_ERROR_CODE) { if (printk_ratelimit()) { printk(KERN_INFO "iommu_alloc failed, " @@ -552,7 +545,7 @@ dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr, tbl, vaddr, npages); } } else - dma_handle |= (uaddr & ~IOMMU_PAGE_MASK); + dma_handle |= (uaddr & ~PAGE_MASK); } return dma_handle; @@ -561,14 +554,11 @@ dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr, void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle, size_t size, enum dma_data_direction direction) { - unsigned int npages; - BUG_ON(direction == DMA_NONE); - if (tbl) { - npages = iommu_num_pages(dma_handle, size); - iommu_free(tbl, dma_handle, npages); - } + if (tbl) + iommu_free(tbl, dma_handle, (PAGE_ALIGN(dma_handle + size) - + (dma_handle & PAGE_MASK)) >> PAGE_SHIFT); } /* Allocates a contiguous real buffer and creates mappings over it. @@ -580,11 +570,11 @@ void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size, { void *ret = NULL; dma_addr_t mapping; - unsigned int order; - unsigned int nio_pages, io_order; + unsigned int npages, order; struct page *page; size = PAGE_ALIGN(size); + npages = size >> PAGE_SHIFT; order = get_order(size); /* @@ -608,10 +598,8 @@ void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size, memset(ret, 0, size); /* Set up tces to cover the allocated range */ - nio_pages = size >> IOMMU_PAGE_SHIFT; - io_order = get_iommu_order(size); - mapping = iommu_alloc(tbl, ret, nio_pages, DMA_BIDIRECTIONAL, - mask >> IOMMU_PAGE_SHIFT, io_order); + mapping = iommu_alloc(tbl, ret, npages, DMA_BIDIRECTIONAL, + mask >> PAGE_SHIFT, order); if (mapping == DMA_ERROR_CODE) { free_pages((unsigned long)ret, order); return NULL; @@ -623,13 +611,12 @@ void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size, void iommu_free_coherent(struct iommu_table *tbl, size_t size, void *vaddr, dma_addr_t dma_handle) { - if (tbl) { - unsigned int nio_pages; + unsigned int npages; + if (tbl) { size = PAGE_ALIGN(size); - nio_pages = size >> IOMMU_PAGE_SHIFT; - iommu_free(tbl, dma_handle, nio_pages); - size = PAGE_ALIGN(size); + npages = size >> PAGE_SHIFT; + iommu_free(tbl, dma_handle, npages); free_pages((unsigned long)vaddr, get_order(size)); } } diff --git a/trunk/arch/powerpc/kernel/irq.c b/trunk/arch/powerpc/kernel/irq.c index 5e37bf14ef2d..c3f58f2f9f52 100644 --- a/trunk/arch/powerpc/kernel/irq.c +++ b/trunk/arch/powerpc/kernel/irq.c @@ -187,7 +187,6 @@ void fixup_irqs(cpumask_t map) void do_IRQ(struct pt_regs *regs) { - struct pt_regs *old_regs = set_irq_regs(regs); unsigned int irq; #ifdef CONFIG_IRQSTACKS struct thread_info *curtp, *irqtp; @@ -217,7 +216,7 @@ void do_IRQ(struct pt_regs *regs) * The value -2 is for buggy hardware and means that this IRQ * has already been handled. -- Tom */ - irq = ppc_md.get_irq(); + irq = ppc_md.get_irq(regs); if (irq != NO_IRQ && irq != NO_IRQ_IGNORE) { #ifdef CONFIG_IRQSTACKS @@ -231,19 +230,18 @@ void do_IRQ(struct pt_regs *regs) handler = &__do_IRQ; irqtp->task = curtp->task; irqtp->flags = 0; - call_handle_irq(irq, desc, irqtp, handler); + call_handle_irq(irq, desc, regs, irqtp, handler); irqtp->task = NULL; if (irqtp->flags) set_bits(irqtp->flags, &curtp->flags); } else #endif - generic_handle_irq(irq); + generic_handle_irq(irq, regs); } else if (irq != NO_IRQ_IGNORE) /* That's not SMP safe ... but who cares ? */ ppc_spurious_interrupts++; irq_exit(); - set_irq_regs(old_regs); #ifdef CONFIG_PPC_ISERIES if (get_lppaca()->int_dword.fields.decr_int) { @@ -572,8 +570,8 @@ unsigned int irq_create_mapping(struct irq_host *host, } EXPORT_SYMBOL_GPL(irq_create_mapping); -unsigned int irq_create_of_mapping(struct device_node *controller, - u32 *intspec, unsigned int intsize) +extern unsigned int irq_create_of_mapping(struct device_node *controller, + u32 *intspec, unsigned int intsize) { struct irq_host *host; irq_hw_number_t hwirq; diff --git a/trunk/arch/powerpc/kernel/misc_32.S b/trunk/arch/powerpc/kernel/misc_32.S index 412bea3cf813..88fd73fdf048 100644 --- a/trunk/arch/powerpc/kernel/misc_32.S +++ b/trunk/arch/powerpc/kernel/misc_32.S @@ -101,6 +101,80 @@ _GLOBAL(reloc_got2) mtlr r11 blr +/* + * identify_cpu, + * called with r3 = data offset and r4 = CPU number + * doesn't change r3 + */ +_GLOBAL(identify_cpu) + addis r8,r3,cpu_specs@ha + addi r8,r8,cpu_specs@l + mfpvr r7 +1: + lwz r5,CPU_SPEC_PVR_MASK(r8) + and r5,r5,r7 + lwz r6,CPU_SPEC_PVR_VALUE(r8) + cmplw 0,r6,r5 + beq 1f + addi r8,r8,CPU_SPEC_ENTRY_SIZE + b 1b +1: + addis r6,r3,cur_cpu_spec@ha + addi r6,r6,cur_cpu_spec@l + sub r8,r8,r3 + stw r8,0(r6) + blr + +/* + * do_cpu_ftr_fixups - goes through the list of CPU feature fixups + * and writes nop's over sections of code that don't apply for this cpu. + * r3 = data offset (not changed) + */ +_GLOBAL(do_cpu_ftr_fixups) + /* Get CPU 0 features */ + addis r6,r3,cur_cpu_spec@ha + addi r6,r6,cur_cpu_spec@l + lwz r4,0(r6) + add r4,r4,r3 + lwz r4,CPU_SPEC_FEATURES(r4) + + /* Get the fixup table */ + addis r6,r3,__start___ftr_fixup@ha + addi r6,r6,__start___ftr_fixup@l + addis r7,r3,__stop___ftr_fixup@ha + addi r7,r7,__stop___ftr_fixup@l + + /* Do the fixup */ +1: cmplw 0,r6,r7 + bgelr + addi r6,r6,16 + lwz r8,-16(r6) /* mask */ + and r8,r8,r4 + lwz r9,-12(r6) /* value */ + cmplw 0,r8,r9 + beq 1b + lwz r8,-8(r6) /* section begin */ + lwz r9,-4(r6) /* section end */ + subf. r9,r8,r9 + beq 1b + /* write nops over the section of code */ + /* todo: if large section, add a branch at the start of it */ + srwi r9,r9,2 + mtctr r9 + add r8,r8,r3 + lis r0,0x60000000@h /* nop */ +3: stw r0,0(r8) + andi. r10,r4,CPU_FTR_SPLIT_ID_CACHE@l + beq 2f + dcbst 0,r8 /* suboptimal, but simpler */ + sync + icbi 0,r8 +2: addi r8,r8,4 + bdnz 3b + sync /* additional sync needed on g4 */ + isync + b 1b + /* * call_setup_cpu - call the setup_cpu function for this cpu * r3 = data offset, r24 = cpu number diff --git a/trunk/arch/powerpc/kernel/misc_64.S b/trunk/arch/powerpc/kernel/misc_64.S index 21fd2c662a99..41521b30c3cd 100644 --- a/trunk/arch/powerpc/kernel/misc_64.S +++ b/trunk/arch/powerpc/kernel/misc_64.S @@ -52,12 +52,12 @@ _GLOBAL(call_do_softirq) blr _GLOBAL(call_handle_irq) - ld r8,0(r6) + ld r8,0(r7) mflr r0 std r0,16(r1) mtctr r8 - stdu r1,THREAD_SIZE-112(r5) - mr r1,r5 + stdu r1,THREAD_SIZE-112(r6) + mr r1,r6 bctrl ld r1,0(r1) ld r0,16(r1) @@ -246,6 +246,130 @@ _GLOBAL(__flush_dcache_icache) isync blr +/* + * identify_cpu and calls setup_cpu + * In: r3 = base of the cpu_specs array + * r4 = address of cur_cpu_spec + * r5 = relocation offset + */ +_GLOBAL(identify_cpu) + mfpvr r7 +1: + lwz r8,CPU_SPEC_PVR_MASK(r3) + and r8,r8,r7 + lwz r9,CPU_SPEC_PVR_VALUE(r3) + cmplw 0,r9,r8 + beq 1f + addi r3,r3,CPU_SPEC_ENTRY_SIZE + b 1b +1: + sub r0,r3,r5 + std r0,0(r4) + ld r4,CPU_SPEC_SETUP(r3) + cmpdi 0,r4,0 + add r4,r4,r5 + beqlr + ld r4,0(r4) + add r4,r4,r5 + mtctr r4 + /* Calling convention for cpu setup is r3=offset, r4=cur_cpu_spec */ + mr r4,r3 + mr r3,r5 + bctr + +/* + * do_cpu_ftr_fixups - goes through the list of CPU feature fixups + * and writes nop's over sections of code that don't apply for this cpu. + * r3 = data offset (not changed) + */ +_GLOBAL(do_cpu_ftr_fixups) + /* Get CPU 0 features */ + LOAD_REG_IMMEDIATE(r6,cur_cpu_spec) + sub r6,r6,r3 + ld r4,0(r6) + sub r4,r4,r3 + ld r4,CPU_SPEC_FEATURES(r4) + /* Get the fixup table */ + LOAD_REG_IMMEDIATE(r6,__start___ftr_fixup) + sub r6,r6,r3 + LOAD_REG_IMMEDIATE(r7,__stop___ftr_fixup) + sub r7,r7,r3 + /* Do the fixup */ +1: cmpld r6,r7 + bgelr + addi r6,r6,32 + ld r8,-32(r6) /* mask */ + and r8,r8,r4 + ld r9,-24(r6) /* value */ + cmpld r8,r9 + beq 1b + ld r8,-16(r6) /* section begin */ + ld r9,-8(r6) /* section end */ + subf. r9,r8,r9 + beq 1b + /* write nops over the section of code */ + /* todo: if large section, add a branch at the start of it */ + srwi r9,r9,2 + mtctr r9 + sub r8,r8,r3 + lis r0,0x60000000@h /* nop */ +3: stw r0,0(r8) + andi. r10,r4,CPU_FTR_SPLIT_ID_CACHE@l + beq 2f + dcbst 0,r8 /* suboptimal, but simpler */ + sync + icbi 0,r8 +2: addi r8,r8,4 + bdnz 3b + sync /* additional sync needed on g4 */ + isync + b 1b + +/* + * do_fw_ftr_fixups - goes through the list of firmware feature fixups + * and writes nop's over sections of code that don't apply for this firmware. + * r3 = data offset (not changed) + */ +_GLOBAL(do_fw_ftr_fixups) + /* Get firmware features */ + LOAD_REG_IMMEDIATE(r6,powerpc_firmware_features) + sub r6,r6,r3 + ld r4,0(r6) + /* Get the fixup table */ + LOAD_REG_IMMEDIATE(r6,__start___fw_ftr_fixup) + sub r6,r6,r3 + LOAD_REG_IMMEDIATE(r7,__stop___fw_ftr_fixup) + sub r7,r7,r3 + /* Do the fixup */ +1: cmpld r6,r7 + bgelr + addi r6,r6,32 + ld r8,-32(r6) /* mask */ + and r8,r8,r4 + ld r9,-24(r6) /* value */ + cmpld r8,r9 + beq 1b + ld r8,-16(r6) /* section begin */ + ld r9,-8(r6) /* section end */ + subf. r9,r8,r9 + beq 1b + /* write nops over the section of code */ + /* todo: if large section, add a branch at the start of it */ + srwi r9,r9,2 + mtctr r9 + sub r8,r8,r3 + lis r0,0x60000000@h /* nop */ +3: stw r0,0(r8) +BEGIN_FTR_SECTION + dcbst 0,r8 /* suboptimal, but simpler */ + sync + icbi 0,r8 +END_FTR_SECTION_IFSET(CPU_FTR_SPLIT_ID_CACHE) + addi r8,r8,4 + bdnz 3b + sync /* additional sync needed on g4 */ + isync + b 1b #if defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE) /* diff --git a/trunk/arch/powerpc/kernel/module_32.c b/trunk/arch/powerpc/kernel/module_32.c index e2c3c6a85f33..92f4e5f64f02 100644 --- a/trunk/arch/powerpc/kernel/module_32.c +++ b/trunk/arch/powerpc/kernel/module_32.c @@ -24,8 +24,6 @@ #include #include -#include "setup.h" - #if 0 #define DEBUGP printk #else @@ -271,50 +269,33 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, return 0; } -static const Elf_Shdr *find_section(const Elf_Ehdr *hdr, - const Elf_Shdr *sechdrs, - const char *name) -{ - char *secstrings; - unsigned int i; - - secstrings = (char *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; - for (i = 1; i < hdr->e_shnum; i++) - if (strcmp(secstrings+sechdrs[i].sh_name, name) == 0) - return &sechdrs[i]; - return NULL; -} - int module_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, struct module *me) { - const Elf_Shdr *sect; + char *secstrings; + unsigned int i; me->arch.bug_table = NULL; me->arch.num_bugs = 0; /* Find the __bug_table section, if present */ - sect = find_section(hdr, sechdrs, "__bug_table"); - if (sect != NULL) { - me->arch.bug_table = (void *) sect->sh_addr; - me->arch.num_bugs = sect->sh_size / sizeof(struct bug_entry); + secstrings = (char *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; + for (i = 1; i < hdr->e_shnum; i++) { + if (strcmp(secstrings+sechdrs[i].sh_name, "__bug_table")) + continue; + me->arch.bug_table = (void *) sechdrs[i].sh_addr; + me->arch.num_bugs = sechdrs[i].sh_size / sizeof(struct bug_entry); + break; } - /* + /* * Strictly speaking this should have a spinlock to protect against * traversals, but since we only traverse on BUG()s, a spinlock * could potentially lead to deadlock and thus be counter-productive. */ list_add(&me->arch.bug_list, &module_bug_list); - /* Apply feature fixups */ - sect = find_section(hdr, sechdrs, "__ftr_fixup"); - if (sect != NULL) - do_feature_fixups(cur_cpu_spec->cpu_features, - (void *)sect->sh_addr, - (void *)sect->sh_addr + sect->sh_size); - return 0; } diff --git a/trunk/arch/powerpc/kernel/module_64.c b/trunk/arch/powerpc/kernel/module_64.c index 8dd1f0aae5d6..ba34001fca8e 100644 --- a/trunk/arch/powerpc/kernel/module_64.c +++ b/trunk/arch/powerpc/kernel/module_64.c @@ -22,9 +22,6 @@ #include #include #include -#include - -#include "setup.h" /* FIXME: We don't do .init separately. To do this, we'd need to have a separate r2 value in the init and core section, and stub between @@ -403,11 +400,6 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, | (value & 0x03fffffc); break; - case R_PPC64_REL64: - /* 64 bits relative (used by features fixups) */ - *location = value - (unsigned long)location; - break; - default: printk("%s: Unknown ADD relocation: %lu\n", me->name, @@ -421,33 +413,23 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, LIST_HEAD(module_bug_list); -static const Elf_Shdr *find_section(const Elf_Ehdr *hdr, - const Elf_Shdr *sechdrs, - const char *name) -{ - char *secstrings; - unsigned int i; - - secstrings = (char *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; - for (i = 1; i < hdr->e_shnum; i++) - if (strcmp(secstrings+sechdrs[i].sh_name, name) == 0) - return &sechdrs[i]; - return NULL; -} - int module_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, struct module *me) { - const Elf_Shdr *sect; + char *secstrings; + unsigned int i; me->arch.bug_table = NULL; me->arch.num_bugs = 0; /* Find the __bug_table section, if present */ - sect = find_section(hdr, sechdrs, "__bug_table"); - if (sect != NULL) { - me->arch.bug_table = (void *) sect->sh_addr; - me->arch.num_bugs = sect->sh_size / sizeof(struct bug_entry); + secstrings = (char *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; + for (i = 1; i < hdr->e_shnum; i++) { + if (strcmp(secstrings+sechdrs[i].sh_name, "__bug_table")) + continue; + me->arch.bug_table = (void *) sechdrs[i].sh_addr; + me->arch.num_bugs = sechdrs[i].sh_size / sizeof(struct bug_entry); + break; } /* @@ -457,19 +439,6 @@ int module_finalize(const Elf_Ehdr *hdr, */ list_add(&me->arch.bug_list, &module_bug_list); - /* Apply feature fixups */ - sect = find_section(hdr, sechdrs, "__ftr_fixup"); - if (sect != NULL) - do_feature_fixups(cur_cpu_spec->cpu_features, - (void *)sect->sh_addr, - (void *)sect->sh_addr + sect->sh_size); - - sect = find_section(hdr, sechdrs, "__fw_ftr_fixup"); - if (sect != NULL) - do_feature_fixups(powerpc_firmware_features, - (void *)sect->sh_addr, - (void *)sect->sh_addr + sect->sh_size); - return 0; } diff --git a/trunk/arch/powerpc/kernel/pci_32.c b/trunk/arch/powerpc/kernel/pci_32.c index 0d9ff72e2852..9b49f8691d29 100644 --- a/trunk/arch/powerpc/kernel/pci_32.c +++ b/trunk/arch/powerpc/kernel/pci_32.c @@ -441,14 +441,14 @@ update_bridge_base(struct pci_bus *bus, int i) end = res->end - off; io_base_lo = (start >> 8) & PCI_IO_RANGE_MASK; io_limit_lo = (end >> 8) & PCI_IO_RANGE_MASK; - if (end > 0xffff) + if (end > 0xffff) { + pci_write_config_word(dev, PCI_IO_BASE_UPPER16, + start >> 16); + pci_write_config_word(dev, PCI_IO_LIMIT_UPPER16, + end >> 16); io_base_lo |= PCI_IO_RANGE_TYPE_32; - else + } else io_base_lo |= PCI_IO_RANGE_TYPE_16; - pci_write_config_word(dev, PCI_IO_BASE_UPPER16, - start >> 16); - pci_write_config_word(dev, PCI_IO_LIMIT_UPPER16, - end >> 16); pci_write_config_byte(dev, PCI_IO_BASE, io_base_lo); pci_write_config_byte(dev, PCI_IO_LIMIT, io_limit_lo); diff --git a/trunk/arch/powerpc/kernel/pci_64.c b/trunk/arch/powerpc/kernel/pci_64.c index 9bae8a5bf671..78d3c0fc8dfb 100644 --- a/trunk/arch/powerpc/kernel/pci_64.c +++ b/trunk/arch/powerpc/kernel/pci_64.c @@ -199,14 +199,8 @@ struct pci_controller * pcibios_alloc_controller(struct device_node *dev) pci_setup_pci_controller(phb); phb->arch_data = dev; phb->is_dynamic = mem_init_done; - if (dev) { - int nid = of_node_to_nid(dev); - - if (nid < 0 || !node_online(nid)) - nid = -1; - - PHB_SET_NODE(phb, nid); - } + if (dev) + PHB_SET_NODE(phb, of_node_to_nid(dev)); return phb; } diff --git a/trunk/arch/powerpc/kernel/perfmon_fsl_booke.c b/trunk/arch/powerpc/kernel/perfmon_fsl_booke.c new file mode 100644 index 000000000000..e0dcf2b41fbe --- /dev/null +++ b/trunk/arch/powerpc/kernel/perfmon_fsl_booke.c @@ -0,0 +1,221 @@ +/* arch/powerpc/kernel/perfmon_fsl_booke.c + * Freescale Book-E Performance Monitor code + * + * Author: Andy Fleming + * Copyright (c) 2004 Freescale Semiconductor, Inc + * + * 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 +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +static inline u32 get_pmlca(int ctr); +static inline void set_pmlca(int ctr, u32 pmlca); + +static inline u32 get_pmlca(int ctr) +{ + u32 pmlca; + + switch (ctr) { + case 0: + pmlca = mfpmr(PMRN_PMLCA0); + break; + case 1: + pmlca = mfpmr(PMRN_PMLCA1); + break; + case 2: + pmlca = mfpmr(PMRN_PMLCA2); + break; + case 3: + pmlca = mfpmr(PMRN_PMLCA3); + break; + default: + panic("Bad ctr number\n"); + } + + return pmlca; +} + +static inline void set_pmlca(int ctr, u32 pmlca) +{ + switch (ctr) { + case 0: + mtpmr(PMRN_PMLCA0, pmlca); + break; + case 1: + mtpmr(PMRN_PMLCA1, pmlca); + break; + case 2: + mtpmr(PMRN_PMLCA2, pmlca); + break; + case 3: + mtpmr(PMRN_PMLCA3, pmlca); + break; + default: + panic("Bad ctr number\n"); + } +} + +void init_pmc_stop(int ctr) +{ + u32 pmlca = (PMLCA_FC | PMLCA_FCS | PMLCA_FCU | + PMLCA_FCM1 | PMLCA_FCM0); + u32 pmlcb = 0; + + switch (ctr) { + case 0: + mtpmr(PMRN_PMLCA0, pmlca); + mtpmr(PMRN_PMLCB0, pmlcb); + break; + case 1: + mtpmr(PMRN_PMLCA1, pmlca); + mtpmr(PMRN_PMLCB1, pmlcb); + break; + case 2: + mtpmr(PMRN_PMLCA2, pmlca); + mtpmr(PMRN_PMLCB2, pmlcb); + break; + case 3: + mtpmr(PMRN_PMLCA3, pmlca); + mtpmr(PMRN_PMLCB3, pmlcb); + break; + default: + panic("Bad ctr number!\n"); + } +} + +void set_pmc_event(int ctr, int event) +{ + u32 pmlca; + + pmlca = get_pmlca(ctr); + + pmlca = (pmlca & ~PMLCA_EVENT_MASK) | + ((event << PMLCA_EVENT_SHIFT) & + PMLCA_EVENT_MASK); + + set_pmlca(ctr, pmlca); +} + +void set_pmc_user_kernel(int ctr, int user, int kernel) +{ + u32 pmlca; + + pmlca = get_pmlca(ctr); + + if(user) + pmlca &= ~PMLCA_FCU; + else + pmlca |= PMLCA_FCU; + + if(kernel) + pmlca &= ~PMLCA_FCS; + else + pmlca |= PMLCA_FCS; + + set_pmlca(ctr, pmlca); +} + +void set_pmc_marked(int ctr, int mark0, int mark1) +{ + u32 pmlca = get_pmlca(ctr); + + if(mark0) + pmlca &= ~PMLCA_FCM0; + else + pmlca |= PMLCA_FCM0; + + if(mark1) + pmlca &= ~PMLCA_FCM1; + else + pmlca |= PMLCA_FCM1; + + set_pmlca(ctr, pmlca); +} + +void pmc_start_ctr(int ctr, int enable) +{ + u32 pmlca = get_pmlca(ctr); + + pmlca &= ~PMLCA_FC; + + if (enable) + pmlca |= PMLCA_CE; + else + pmlca &= ~PMLCA_CE; + + set_pmlca(ctr, pmlca); +} + +void pmc_start_ctrs(int enable) +{ + u32 pmgc0 = mfpmr(PMRN_PMGC0); + + pmgc0 &= ~PMGC0_FAC; + pmgc0 |= PMGC0_FCECE; + + if (enable) + pmgc0 |= PMGC0_PMIE; + else + pmgc0 &= ~PMGC0_PMIE; + + mtpmr(PMRN_PMGC0, pmgc0); +} + +void pmc_stop_ctrs(void) +{ + u32 pmgc0 = mfpmr(PMRN_PMGC0); + + pmgc0 |= PMGC0_FAC; + + pmgc0 &= ~(PMGC0_PMIE | PMGC0_FCECE); + + mtpmr(PMRN_PMGC0, pmgc0); +} + +void dump_pmcs(void) +{ + printk("pmgc0: %x\n", mfpmr(PMRN_PMGC0)); + printk("pmc\t\tpmlca\t\tpmlcb\n"); + printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC0), + mfpmr(PMRN_PMLCA0), mfpmr(PMRN_PMLCB0)); + printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC1), + mfpmr(PMRN_PMLCA1), mfpmr(PMRN_PMLCB1)); + printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC2), + mfpmr(PMRN_PMLCA2), mfpmr(PMRN_PMLCB2)); + printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC3), + mfpmr(PMRN_PMLCA3), mfpmr(PMRN_PMLCB3)); +} + +EXPORT_SYMBOL(init_pmc_stop); +EXPORT_SYMBOL(set_pmc_event); +EXPORT_SYMBOL(set_pmc_user_kernel); +EXPORT_SYMBOL(set_pmc_marked); +EXPORT_SYMBOL(pmc_start_ctr); +EXPORT_SYMBOL(pmc_start_ctrs); +EXPORT_SYMBOL(pmc_stop_ctrs); +EXPORT_SYMBOL(dump_pmcs); diff --git a/trunk/arch/powerpc/kernel/pmc.c b/trunk/arch/powerpc/kernel/pmc.c index 3d8f6f44641e..a0a2efadeabf 100644 --- a/trunk/arch/powerpc/kernel/pmc.c +++ b/trunk/arch/powerpc/kernel/pmc.c @@ -71,7 +71,7 @@ int reserve_pmc_hardware(perf_irq_t new_perf_irq) } pmc_owner_caller = __builtin_return_address(0); - perf_irq = new_perf_irq ? new_perf_irq : dummy_perf; + perf_irq = new_perf_irq ? : dummy_perf; out: spin_unlock(&pmc_owner_lock); diff --git a/trunk/arch/powerpc/kernel/process.c b/trunk/arch/powerpc/kernel/process.c index f3d4dd580dd6..7b2f6452ba72 100644 --- a/trunk/arch/powerpc/kernel/process.c +++ b/trunk/arch/powerpc/kernel/process.c @@ -341,6 +341,13 @@ struct task_struct *__switch_to(struct task_struct *prev, static int instructions_to_print = 16; +#ifdef CONFIG_PPC64 +#define BAD_PC(pc) ((REGION_ID(pc) != KERNEL_REGION_ID) && \ + (REGION_ID(pc) != VMALLOC_REGION_ID)) +#else +#define BAD_PC(pc) ((pc) < KERNELBASE) +#endif + static void show_instructions(struct pt_regs *regs) { int i; @@ -359,8 +366,7 @@ static void show_instructions(struct pt_regs *regs) * bad address because the pc *should* only be a * kernel address. */ - if (!__kernel_text_address(pc) || - __get_user(instr, (unsigned int __user *)pc)) { + if (BAD_PC(pc) || __get_user(instr, (unsigned int __user *)pc)) { printk("XXXXXXXX "); } else { if (regs->nip == pc) diff --git a/trunk/arch/powerpc/kernel/prom.c b/trunk/arch/powerpc/kernel/prom.c index bdb412d4b748..eb913f80bfb1 100644 --- a/trunk/arch/powerpc/kernel/prom.c +++ b/trunk/arch/powerpc/kernel/prom.c @@ -724,7 +724,7 @@ static int __init early_init_dt_scan_chosen(unsigned long node, strlcpy(cmd_line, p, min((int)l, COMMAND_LINE_SIZE)); #ifdef CONFIG_CMDLINE - if (p == NULL || l == 0 || (l == 1 && (*p) == 0)) + if (l == 0 || (l == 1 && (*p) == 0)) strlcpy(cmd_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE); #endif /* CONFIG_CMDLINE */ @@ -1014,7 +1014,7 @@ EXPORT_SYMBOL(find_all_nodes); /** Checks if the given "compat" string matches one of the strings in * the device's "compatible" property */ -int device_is_compatible(const struct device_node *device, const char *compat) +int device_is_compatible(struct device_node *device, const char *compat) { const char* cp; int cplen, l; @@ -1491,8 +1491,7 @@ static int __init prom_reconfig_setup(void) __initcall(prom_reconfig_setup); #endif -struct property *of_find_property(const struct device_node *np, - const char *name, +struct property *of_find_property(struct device_node *np, const char *name, int *lenp) { struct property *pp; @@ -1513,8 +1512,7 @@ struct property *of_find_property(const struct device_node *np, * Find a property with a given name for a given node * and return the value. */ -const void *get_property(const struct device_node *np, const char *name, - int *lenp) +const void *get_property(struct device_node *np, const char *name, int *lenp) { struct property *pp = of_find_property(np,name,lenp); return pp ? pp->value : NULL; diff --git a/trunk/arch/powerpc/kernel/rtas_flash.c b/trunk/arch/powerpc/kernel/rtas_flash.c index 6f6fc977cb39..1442b63a75da 100644 --- a/trunk/arch/powerpc/kernel/rtas_flash.c +++ b/trunk/arch/powerpc/kernel/rtas_flash.c @@ -72,10 +72,6 @@ #define VALIDATE_BUF_SIZE 4096 #define RTAS_MSG_MAXLEN 64 -/* Quirk - RTAS requires 4k list length and block size */ -#define RTAS_BLKLIST_LENGTH 4096 -#define RTAS_BLK_SIZE 4096 - struct flash_block { char *data; unsigned long length; @@ -87,7 +83,7 @@ struct flash_block { * into a version/length and translate the pointers * to absolute. */ -#define FLASH_BLOCKS_PER_NODE ((RTAS_BLKLIST_LENGTH - 16) / sizeof(struct flash_block)) +#define FLASH_BLOCKS_PER_NODE ((PAGE_SIZE - 16) / sizeof(struct flash_block)) struct flash_block_list { unsigned long num_blocks; struct flash_block_list *next; @@ -100,9 +96,6 @@ 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 kmem_cache_t *flash_block_cache = NULL; - #define FLASH_BLOCK_LIST_VERSION (1UL) /* Local copy of the flash block list. @@ -160,7 +153,7 @@ static int flash_list_valid(struct flash_block_list *flist) return FLASH_IMG_NULL_DATA; } block_size = f->blocks[i].length; - if (block_size <= 0 || block_size > RTAS_BLK_SIZE) { + if (block_size <= 0 || block_size > PAGE_SIZE) { return FLASH_IMG_BAD_LEN; } image_size += block_size; @@ -184,9 +177,9 @@ static void free_flash_list(struct flash_block_list *f) while (f) { for (i = 0; i < f->num_blocks; i++) - kmem_cache_free(flash_block_cache, f->blocks[i].data); + free_page((unsigned long)(f->blocks[i].data)); next = f->next; - kmem_cache_free(flash_block_cache, f); + free_page((unsigned long)f); f = next; } } @@ -285,12 +278,6 @@ static ssize_t rtas_flash_read(struct file *file, char __user *buf, return msglen; } -/* constructor for flash_block_cache */ -void rtas_block_ctor(void *ptr, kmem_cache_t *cache, unsigned long flags) -{ - memset(ptr, 0, RTAS_BLK_SIZE); -} - /* We could be much more efficient here. But to keep this function * simple we allocate a page to the block list no matter how small the * count is. If the system is low on memory it will be just as well @@ -315,7 +302,7 @@ static ssize_t rtas_flash_write(struct file *file, const char __user *buffer, * proc file */ if (uf->flist == NULL) { - uf->flist = kmem_cache_alloc(flash_block_cache, GFP_KERNEL); + uf->flist = (struct flash_block_list *) get_zeroed_page(GFP_KERNEL); if (!uf->flist) return -ENOMEM; } @@ -326,21 +313,21 @@ static ssize_t rtas_flash_write(struct file *file, const char __user *buffer, next_free = fl->num_blocks; if (next_free == FLASH_BLOCKS_PER_NODE) { /* Need to allocate another block_list */ - fl->next = kmem_cache_alloc(flash_block_cache, GFP_KERNEL); + fl->next = (struct flash_block_list *)get_zeroed_page(GFP_KERNEL); if (!fl->next) return -ENOMEM; fl = fl->next; next_free = 0; } - if (count > RTAS_BLK_SIZE) - count = RTAS_BLK_SIZE; - p = kmem_cache_alloc(flash_block_cache, GFP_KERNEL); + if (count > PAGE_SIZE) + count = PAGE_SIZE; + p = (char *)get_zeroed_page(GFP_KERNEL); if (!p) return -ENOMEM; if(copy_from_user(p, buffer, count)) { - kmem_cache_free(flash_block_cache, p); + free_page((unsigned long)p); return -EFAULT; } fl->blocks[next_free].data = p; @@ -804,16 +791,6 @@ int __init rtas_flash_init(void) goto cleanup; rtas_flash_term_hook = rtas_flash_firmware; - - flash_block_cache = kmem_cache_create("rtas_flash_cache", - RTAS_BLK_SIZE, RTAS_BLK_SIZE, 0, - rtas_block_ctor, NULL); - if (!flash_block_cache) { - printk(KERN_ERR "%s: failed to create block cache\n", - __FUNCTION__); - rc = -ENOMEM; - goto cleanup; - } return 0; cleanup: @@ -828,10 +805,6 @@ int __init rtas_flash_init(void) void __exit rtas_flash_cleanup(void) { rtas_flash_term_hook = NULL; - - if (flash_block_cache) - kmem_cache_destroy(flash_block_cache); - remove_flash_pde(firmware_flash_pde); remove_flash_pde(firmware_update_pde); remove_flash_pde(validate_pde); diff --git a/trunk/arch/powerpc/kernel/setup_32.c b/trunk/arch/powerpc/kernel/setup_32.c index a4c2964a3ca6..191d0ab09222 100644 --- a/trunk/arch/powerpc/kernel/setup_32.c +++ b/trunk/arch/powerpc/kernel/setup_32.c @@ -91,7 +91,6 @@ int ucache_bsize; unsigned long __init early_init(unsigned long dt_ptr) { unsigned long offset = reloc_offset(); - struct cpu_spec *spec; /* First zero the BSS -- use memset_io, some platforms don't have * caches on yet */ @@ -101,11 +100,8 @@ unsigned long __init early_init(unsigned long dt_ptr) * Identify the CPU type and fix up code sections * that depend on which cpu we have. */ - spec = identify_cpu(offset); - - do_feature_fixups(spec->cpu_features, - PTRRELOC(&__start___ftr_fixup), - PTRRELOC(&__stop___ftr_fixup)); + identify_cpu(offset, 0); + do_cpu_ftr_fixups(offset); return KERNELBASE + offset; } diff --git a/trunk/arch/powerpc/kernel/setup_64.c b/trunk/arch/powerpc/kernel/setup_64.c index 16278968dab6..4b2e32eab9dc 100644 --- a/trunk/arch/powerpc/kernel/setup_64.c +++ b/trunk/arch/powerpc/kernel/setup_64.c @@ -170,9 +170,6 @@ void __init setup_paca(int cpu) void __init early_setup(unsigned long dt_ptr) { - /* Identify CPU type */ - identify_cpu(0); - /* Assume we're on cpu 0 for now. Don't write to the paca yet! */ setup_paca(0); @@ -351,14 +348,6 @@ void __init setup_system(void) { DBG(" -> setup_system()\n"); - /* Apply the CPUs-specific and firmware specific fixups to kernel - * text (nop out sections not relevant to this CPU or this firmware) - */ - do_feature_fixups(cur_cpu_spec->cpu_features, - &__start___ftr_fixup, &__stop___ftr_fixup); - do_feature_fixups(powerpc_firmware_features, - &__start___fw_ftr_fixup, &__stop___fw_ftr_fixup); - /* * Unflatten the device-tree passed by prom_init or kexec */ diff --git a/trunk/arch/powerpc/kernel/smp.c b/trunk/arch/powerpc/kernel/smp.c index 35c6309bdb76..6a9bc9ce54e0 100644 --- a/trunk/arch/powerpc/kernel/smp.c +++ b/trunk/arch/powerpc/kernel/smp.c @@ -115,7 +115,7 @@ void __devinit smp_generic_kick_cpu(int nr) } #endif -void smp_message_recv(int msg) +void smp_message_recv(int msg, struct pt_regs *regs) { switch(msg) { case PPC_MSG_CALL_FUNCTION: @@ -127,11 +127,11 @@ void smp_message_recv(int msg) break; case PPC_MSG_DEBUGGER_BREAK: if (crash_ipi_function_ptr) { - crash_ipi_function_ptr(get_irq_regs()); + crash_ipi_function_ptr(regs); break; } #ifdef CONFIG_DEBUGGER - debugger_ipi(get_irq_regs()); + debugger_ipi(regs); break; #endif /* CONFIG_DEBUGGER */ /* FALLTHROUGH */ diff --git a/trunk/arch/powerpc/kernel/time.c b/trunk/arch/powerpc/kernel/time.c index 46a24de36fec..85b9244a098c 100644 --- a/trunk/arch/powerpc/kernel/time.c +++ b/trunk/arch/powerpc/kernel/time.c @@ -51,7 +51,6 @@ #include #include #include -#include #include #include @@ -220,8 +219,11 @@ static void account_process_time(struct pt_regs *regs) */ struct cpu_purr_data { int initialized; /* thread is running */ + u64 tb0; /* timebase at origin time */ + u64 purr0; /* PURR at origin time */ u64 tb; /* last TB value read */ u64 purr; /* last PURR value read */ + u64 stolen; /* stolen time so far */ spinlock_t lock; }; @@ -231,8 +233,10 @@ static void snapshot_tb_and_purr(void *data) { struct cpu_purr_data *p = &__get_cpu_var(cpu_purr_data); - p->tb = mftb(); - p->purr = mfspr(SPRN_PURR); + p->tb0 = mftb(); + p->purr0 = mfspr(SPRN_PURR); + p->tb = p->tb0; + p->purr = 0; wmb(); p->initialized = 1; } @@ -253,24 +257,37 @@ void snapshot_timebases(void) void calculate_steal_time(void) { - u64 tb, purr; + u64 tb, purr, t0; s64 stolen; - struct cpu_purr_data *pme; + struct cpu_purr_data *p0, *pme, *phim; + int cpu; if (!cpu_has_feature(CPU_FTR_PURR)) return; - pme = &per_cpu(cpu_purr_data, smp_processor_id()); + cpu = smp_processor_id(); + pme = &per_cpu(cpu_purr_data, cpu); if (!pme->initialized) return; /* this can happen in early boot */ - spin_lock(&pme->lock); + p0 = &per_cpu(cpu_purr_data, cpu & ~1); + phim = &per_cpu(cpu_purr_data, cpu ^ 1); + spin_lock(&p0->lock); tb = mftb(); - purr = mfspr(SPRN_PURR); - stolen = (tb - pme->tb) - (purr - pme->purr); - if (stolen > 0) + purr = mfspr(SPRN_PURR) - pme->purr0; + if (!phim->initialized || !cpu_online(cpu ^ 1)) { + stolen = (tb - pme->tb) - (purr - pme->purr); + } else { + t0 = pme->tb0; + if (phim->tb0 < t0) + t0 = phim->tb0; + stolen = phim->tb - t0 - phim->purr - purr - p0->stolen; + } + if (stolen > 0) { account_steal_time(current, stolen); + p0->stolen += stolen; + } pme->tb = tb; pme->purr = purr; - spin_unlock(&pme->lock); + spin_unlock(&p0->lock); } /* @@ -279,17 +296,30 @@ void calculate_steal_time(void) */ static void snapshot_purr(void) { - struct cpu_purr_data *pme; + int cpu; + u64 purr; + struct cpu_purr_data *p0, *pme, *phim; unsigned long flags; if (!cpu_has_feature(CPU_FTR_PURR)) return; - pme = &per_cpu(cpu_purr_data, smp_processor_id()); - spin_lock_irqsave(&pme->lock, flags); - pme->tb = mftb(); - pme->purr = mfspr(SPRN_PURR); + cpu = smp_processor_id(); + pme = &per_cpu(cpu_purr_data, cpu); + p0 = &per_cpu(cpu_purr_data, cpu & ~1); + phim = &per_cpu(cpu_purr_data, cpu ^ 1); + spin_lock_irqsave(&p0->lock, flags); + pme->tb = pme->tb0 = mftb(); + purr = mfspr(SPRN_PURR); + if (!phim->initialized) { + pme->purr = 0; + pme->purr0 = purr; + } else { + /* set p->purr and p->purr0 for no change in p0->stolen */ + pme->purr = phim->tb - phim->tb0 - phim->purr - p0->stolen; + pme->purr0 = purr - pme->purr; + } pme->initialized = 1; - spin_unlock_irqrestore(&pme->lock, flags); + spin_unlock_irqrestore(&p0->lock, flags); } #endif /* CONFIG_PPC_SPLPAR */ @@ -613,7 +643,6 @@ static void iSeries_tb_recal(void) */ void timer_interrupt(struct pt_regs * regs) { - struct pt_regs *old_regs; int next_dec; int cpu = smp_processor_id(); unsigned long ticks; @@ -624,10 +653,9 @@ void timer_interrupt(struct pt_regs * regs) do_IRQ(regs); #endif - old_regs = set_irq_regs(regs); irq_enter(); - profile_tick(CPU_PROFILING); + profile_tick(CPU_PROFILING, regs); calculate_steal_time(); #ifdef CONFIG_PPC_ISERIES @@ -675,7 +703,7 @@ void timer_interrupt(struct pt_regs * regs) #ifdef CONFIG_PPC_ISERIES if (hvlpevent_is_pending()) - process_hvlpevents(); + process_hvlpevents(regs); #endif #ifdef CONFIG_PPC64 @@ -687,7 +715,6 @@ void timer_interrupt(struct pt_regs * regs) #endif irq_exit(); - set_irq_regs(old_regs); } void wakeup_decrementer(void) @@ -1014,6 +1041,48 @@ void __init time_init(void) set_dec(tb_ticks_per_jiffy); } +#ifdef CONFIG_RTC_CLASS +static int set_rtc_class_time(struct rtc_time *tm) +{ + int err; + struct class_device *class_dev = + rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE); + + if (class_dev == NULL) + return -ENODEV; + + err = rtc_set_time(class_dev, tm); + + rtc_class_close(class_dev); + + return 0; +} + +static void get_rtc_class_time(struct rtc_time *tm) +{ + int err; + struct class_device *class_dev = + rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE); + + if (class_dev == NULL) + return; + + err = rtc_read_time(class_dev, tm); + + rtc_class_close(class_dev); + + return; +} + +int __init rtc_class_hookup(void) +{ + ppc_md.get_rtc_time = get_rtc_class_time; + ppc_md.set_rtc_time = set_rtc_class_time; + + return 0; +} +#endif /* CONFIG_RTC_CLASS */ + #define FEBRUARY 2 #define STARTOFTIME 1970 diff --git a/trunk/arch/powerpc/kernel/traps.c b/trunk/arch/powerpc/kernel/traps.c index c66b4771ef44..d9f10f2fc372 100644 --- a/trunk/arch/powerpc/kernel/traps.c +++ b/trunk/arch/powerpc/kernel/traps.c @@ -843,7 +843,7 @@ void __kprobes program_check_exception(struct pt_regs *regs) void alignment_exception(struct pt_regs *regs) { - int sig, code, fixed = 0; + int fixed = 0; /* we don't implement logging of alignment exceptions */ if (!(current->thread.align_ctl & PR_UNALIGN_SIGBUS)) @@ -857,16 +857,14 @@ void alignment_exception(struct pt_regs *regs) /* Operand address was bad */ if (fixed == -EFAULT) { - sig = SIGSEGV; - code = SEGV_ACCERR; - } else { - sig = SIGBUS; - code = BUS_ADRALN; + if (user_mode(regs)) + _exception(SIGSEGV, regs, SEGV_ACCERR, regs->dar); + else + /* Search exception table */ + bad_page_fault(regs, regs->dar, SIGSEGV); + return; } - if (user_mode(regs)) - _exception(sig, regs, code, regs->dar); - else - bad_page_fault(regs, regs->dar, sig); + _exception(SIGBUS, regs, BUS_ADRALN, regs->dar); } void StackOverflow(struct pt_regs *regs) @@ -902,13 +900,14 @@ void kernel_fp_unavailable_exception(struct pt_regs *regs) void altivec_unavailable_exception(struct pt_regs *regs) { +#if !defined(CONFIG_ALTIVEC) if (user_mode(regs)) { /* A user program has executed an altivec instruction, but this kernel doesn't support altivec. */ _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); return; } - +#endif printk(KERN_EMERG "Unrecoverable VMX/Altivec Unavailable Exception " "%lx at %lx\n", regs->trap, regs->nip); die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT); diff --git a/trunk/arch/powerpc/kernel/vdso.c b/trunk/arch/powerpc/kernel/vdso.c index c913ad5cad29..1a7e19cdab39 100644 --- a/trunk/arch/powerpc/kernel/vdso.c +++ b/trunk/arch/powerpc/kernel/vdso.c @@ -36,8 +36,6 @@ #include #include -#include "setup.h" - #undef DEBUG #ifdef DEBUG @@ -588,43 +586,6 @@ static __init int vdso_fixup_datapage(struct lib32_elfinfo *v32, return 0; } - -static __init int vdso_fixup_features(struct lib32_elfinfo *v32, - struct lib64_elfinfo *v64) -{ - void *start32; - unsigned long size32; - -#ifdef CONFIG_PPC64 - void *start64; - unsigned long size64; - - start64 = find_section64(v64->hdr, "__ftr_fixup", &size64); - if (start64) - do_feature_fixups(cur_cpu_spec->cpu_features, - start64, start64 + size64); - - start64 = find_section64(v64->hdr, "__fw_ftr_fixup", &size64); - if (start64) - do_feature_fixups(powerpc_firmware_features, - start64, start64 + size64); -#endif /* CONFIG_PPC64 */ - - start32 = find_section32(v32->hdr, "__ftr_fixup", &size32); - if (start32) - do_feature_fixups(cur_cpu_spec->cpu_features, - start32, start32 + size32); - -#ifdef CONFIG_PPC64 - start32 = find_section32(v32->hdr, "__fw_ftr_fixup", &size32); - if (start32) - do_feature_fixups(powerpc_firmware_features, - start32, start32 + size32); -#endif /* CONFIG_PPC64 */ - - return 0; -} - static __init int vdso_fixup_alt_funcs(struct lib32_elfinfo *v32, struct lib64_elfinfo *v64) { @@ -673,9 +634,6 @@ static __init int vdso_setup(void) if (vdso_fixup_datapage(&v32, &v64)) return -1; - if (vdso_fixup_features(&v32, &v64)) - return -1; - if (vdso_fixup_alt_funcs(&v32, &v64)) return -1; @@ -756,7 +714,6 @@ void __init vdso_init(void) * Setup the syscall map in the vDOS */ vdso_setup_syscall_map(); - /* * Initialize the vDSO images in memory, that is do necessary * fixups of vDSO symbols, locate trampolines, etc... diff --git a/trunk/arch/powerpc/kernel/vdso32/vdso32.lds.S b/trunk/arch/powerpc/kernel/vdso32/vdso32.lds.S index 26e138c4ce17..6187af2d54c3 100644 --- a/trunk/arch/powerpc/kernel/vdso32/vdso32.lds.S +++ b/trunk/arch/powerpc/kernel/vdso32/vdso32.lds.S @@ -32,18 +32,6 @@ SECTIONS PROVIDE (_etext = .); PROVIDE (etext = .); - . = ALIGN(8); - __ftr_fixup : { - *(__ftr_fixup) - } - -#ifdef CONFIG_PPC64 - . = ALIGN(8); - __fw_ftr_fixup : { - *(__fw_ftr_fixup) - } -#endif - /* Other stuff is appended to the text segment: */ .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } .rodata1 : { *(.rodata1) } diff --git a/trunk/arch/powerpc/kernel/vdso64/gettimeofday.S b/trunk/arch/powerpc/kernel/vdso64/gettimeofday.S index 40ffd9b6cef7..56e76ff5498f 100644 --- a/trunk/arch/powerpc/kernel/vdso64/gettimeofday.S +++ b/trunk/arch/powerpc/kernel/vdso64/gettimeofday.S @@ -229,10 +229,8 @@ V_FUNCTION_BEGIN(__do_get_xsec) xor r0,r8,r8 /* create dependency */ add r3,r3,r0 - /* Get TB & offset it. We use the MFTB macro which will generate - * workaround code for Cell. - */ - MFTB(r7) + /* Get TB & offset it */ + mftb r7 ld r9,CFG_TB_ORIG_STAMP(r3) subf r7,r9,r7 diff --git a/trunk/arch/powerpc/kernel/vdso64/vdso64.lds.S b/trunk/arch/powerpc/kernel/vdso64/vdso64.lds.S index 2d70f35d50b5..4a2b6dc0960c 100644 --- a/trunk/arch/powerpc/kernel/vdso64/vdso64.lds.S +++ b/trunk/arch/powerpc/kernel/vdso64/vdso64.lds.S @@ -31,16 +31,6 @@ SECTIONS PROVIDE (_etext = .); PROVIDE (etext = .); - . = ALIGN(8); - __ftr_fixup : { - *(__ftr_fixup) - } - - . = ALIGN(8); - __fw_ftr_fixup : { - *(__fw_ftr_fixup) - } - /* Other stuff is appended to the text segment: */ .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } .rodata1 : { *(.rodata1) } diff --git a/trunk/arch/powerpc/kernel/vio.c b/trunk/arch/powerpc/kernel/vio.c index ed007878d1bf..cb87e71eec66 100644 --- a/trunk/arch/powerpc/kernel/vio.c +++ b/trunk/arch/powerpc/kernel/vio.c @@ -92,9 +92,9 @@ static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev) &tbl->it_index, &offset, &size); /* TCE table size - measured in tce entries */ - tbl->it_size = size >> IOMMU_PAGE_SHIFT; + tbl->it_size = size >> PAGE_SHIFT; /* offset for VIO should always be 0 */ - tbl->it_offset = offset >> IOMMU_PAGE_SHIFT; + tbl->it_offset = offset >> PAGE_SHIFT; tbl->it_busno = 0; tbl->it_type = TCE_VB; diff --git a/trunk/arch/powerpc/kernel/vmlinux.lds.S b/trunk/arch/powerpc/kernel/vmlinux.lds.S index e8342d867536..cb0e8d46c3e8 100644 --- a/trunk/arch/powerpc/kernel/vmlinux.lds.S +++ b/trunk/arch/powerpc/kernel/vmlinux.lds.S @@ -108,7 +108,13 @@ SECTIONS .initcall.init : { __initcall_start = .; - INITCALLS + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) __initcall_end = .; } diff --git a/trunk/arch/powerpc/lib/sstep.c b/trunk/arch/powerpc/lib/sstep.c index 7e8ded051b5b..9590ba780b98 100644 --- a/trunk/arch/powerpc/lib/sstep.c +++ b/trunk/arch/powerpc/lib/sstep.c @@ -9,7 +9,6 @@ * 2 of the License, or (at your option) any later version. */ #include -#include #include #include #include @@ -26,7 +25,7 @@ extern char system_call_common[]; /* * Determine whether a conditional branch instruction would branch. */ -static int __kprobes branch_taken(unsigned int instr, struct pt_regs *regs) +static int branch_taken(unsigned int instr, struct pt_regs *regs) { unsigned int bo = (instr >> 21) & 0x1f; unsigned int bi; @@ -52,7 +51,7 @@ static int __kprobes branch_taken(unsigned int instr, struct pt_regs *regs) * or -1 if the instruction is one that should not be stepped, * such as an rfid, or a mtmsrd that would clear MSR_RI. */ -int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr) +int emulate_step(struct pt_regs *regs, unsigned int instr) { unsigned int opcode, rd; unsigned long int imm; diff --git a/trunk/arch/powerpc/mm/hugetlbpage.c b/trunk/arch/powerpc/mm/hugetlbpage.c index 506d89768d45..5615acc29527 100644 --- a/trunk/arch/powerpc/mm/hugetlbpage.c +++ b/trunk/arch/powerpc/mm/hugetlbpage.c @@ -480,6 +480,9 @@ static int open_high_hpage_areas(struct mm_struct *mm, u16 newareas) mm->context.high_htlb_areas |= newareas; + /* update the paca copy of the context struct */ + get_paca()->context = mm->context; + /* the context change must make it to memory before the flush, * so that further SLB misses do the right thing. */ mb(); @@ -491,15 +494,11 @@ static int open_high_hpage_areas(struct mm_struct *mm, u16 newareas) return 0; } -int prepare_hugepage_range(unsigned long addr, unsigned long len, pgoff_t pgoff) +int prepare_hugepage_range(unsigned long addr, unsigned long len) { int err = 0; - if (pgoff & (~HPAGE_MASK >> PAGE_SHIFT)) - return -EINVAL; - if (len & ~HPAGE_MASK) - return -EINVAL; - if (addr & ~HPAGE_MASK) + if ( (addr+len) < addr ) return -EINVAL; if (addr < 0x100000000UL) diff --git a/trunk/arch/powerpc/mm/mem.c b/trunk/arch/powerpc/mm/mem.c index d1c0758c5611..16fe027bbc12 100644 --- a/trunk/arch/powerpc/mm/mem.c +++ b/trunk/arch/powerpc/mm/mem.c @@ -307,12 +307,11 @@ void __init paging_init(void) top_of_ram, total_ram); printk(KERN_DEBUG "Memory hole size: %ldMB\n", (top_of_ram - total_ram) >> 20); - memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); #ifdef CONFIG_HIGHMEM - max_zone_pfns[ZONE_DMA] = total_lowmem >> PAGE_SHIFT; - max_zone_pfns[ZONE_HIGHMEM] = top_of_ram >> PAGE_SHIFT; + max_zone_pfns[0] = total_lowmem >> PAGE_SHIFT; + max_zone_pfns[1] = top_of_ram >> PAGE_SHIFT; #else - max_zone_pfns[ZONE_DMA] = top_of_ram >> PAGE_SHIFT; + max_zone_pfns[0] = top_of_ram >> PAGE_SHIFT; #endif free_area_init_nodes(max_zone_pfns); } diff --git a/trunk/arch/powerpc/mm/numa.c b/trunk/arch/powerpc/mm/numa.c index 9da01dc8cfd9..43c272075e1a 100644 --- a/trunk/arch/powerpc/mm/numa.c +++ b/trunk/arch/powerpc/mm/numa.c @@ -617,9 +617,9 @@ void __init do_init_bootmem(void) void __init paging_init(void) { - unsigned long max_zone_pfns[MAX_NR_ZONES]; - memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); - max_zone_pfns[ZONE_DMA] = lmb_end_of_DRAM() >> PAGE_SHIFT; + unsigned long max_zone_pfns[MAX_NR_ZONES] = { + lmb_end_of_DRAM() >> PAGE_SHIFT + }; free_area_init_nodes(max_zone_pfns); } diff --git a/trunk/arch/powerpc/oprofile/Makefile b/trunk/arch/powerpc/oprofile/Makefile index 0b5df9c96ae0..3145d610b5b0 100644 --- a/trunk/arch/powerpc/oprofile/Makefile +++ b/trunk/arch/powerpc/oprofile/Makefile @@ -13,4 +13,4 @@ DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \ oprofile-y := $(DRIVER_OBJS) common.o backtrace.o oprofile-$(CONFIG_PPC64) += op_model_rs64.o op_model_power4.o oprofile-$(CONFIG_FSL_BOOKE) += op_model_fsl_booke.o -oprofile-$(CONFIG_6xx) += op_model_7450.o +oprofile-$(CONFIG_PPC32) += op_model_7450.o diff --git a/trunk/arch/powerpc/oprofile/common.c b/trunk/arch/powerpc/oprofile/common.c index 63bbef3b63f1..fd0bbbe7a4de 100644 --- a/trunk/arch/powerpc/oprofile/common.c +++ b/trunk/arch/powerpc/oprofile/common.c @@ -34,11 +34,6 @@ static void op_handle_interrupt(struct pt_regs *regs) model->handle_interrupt(regs, ctr); } -static void op_powerpc_cpu_setup(void *dummy) -{ - model->cpu_setup(ctr); -} - static int op_powerpc_setup(void) { int err; @@ -52,7 +47,7 @@ static int op_powerpc_setup(void) model->reg_setup(ctr, &sys, model->num_counters); /* Configure the registers on all cpus. */ - on_each_cpu(op_powerpc_cpu_setup, NULL, 0, 1); + on_each_cpu(model->cpu_setup, NULL, 0, 1); return 0; } @@ -147,8 +142,7 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) case PPC_OPROFILE_POWER4: model = &op_model_power4; break; -#endif -#ifdef CONFIG_6xx +#else case PPC_OPROFILE_G4: model = &op_model_7450; break; diff --git a/trunk/arch/powerpc/oprofile/op_model_7450.c b/trunk/arch/powerpc/oprofile/op_model_7450.c index f481c0ed5e67..d8ee3aea83f8 100644 --- a/trunk/arch/powerpc/oprofile/op_model_7450.c +++ b/trunk/arch/powerpc/oprofile/op_model_7450.c @@ -81,7 +81,7 @@ static void pmc_stop_ctrs(void) /* Configures the counters on this CPU based on the global * settings */ -static void fsl7450_cpu_setup(struct op_counter_config *ctr) +static void fsl7450_cpu_setup(void *unused) { /* freeze all counters */ pmc_stop_ctrs(); diff --git a/trunk/arch/powerpc/oprofile/op_model_fsl_booke.c b/trunk/arch/powerpc/oprofile/op_model_fsl_booke.c index 0b3c31f5209e..e29dede31423 100644 --- a/trunk/arch/powerpc/oprofile/op_model_fsl_booke.c +++ b/trunk/arch/powerpc/oprofile/op_model_fsl_booke.c @@ -32,152 +32,42 @@ static unsigned long reset_value[OP_MAX_COUNTER]; static int num_counters; static int oprofile_running; -static void init_pmc_stop(int ctr) +static inline unsigned int ctr_read(unsigned int i) { - u32 pmlca = (PMLCA_FC | PMLCA_FCS | PMLCA_FCU | - PMLCA_FCM1 | PMLCA_FCM0); - u32 pmlcb = 0; + switch(i) { + case 0: + return mfpmr(PMRN_PMC0); + case 1: + return mfpmr(PMRN_PMC1); + case 2: + return mfpmr(PMRN_PMC2); + case 3: + return mfpmr(PMRN_PMC3); + default: + return 0; + } +} - switch (ctr) { +static inline void ctr_write(unsigned int i, unsigned int val) +{ + switch(i) { case 0: - mtpmr(PMRN_PMLCA0, pmlca); - mtpmr(PMRN_PMLCB0, pmlcb); + mtpmr(PMRN_PMC0, val); break; case 1: - mtpmr(PMRN_PMLCA1, pmlca); - mtpmr(PMRN_PMLCB1, pmlcb); + mtpmr(PMRN_PMC1, val); break; case 2: - mtpmr(PMRN_PMLCA2, pmlca); - mtpmr(PMRN_PMLCB2, pmlcb); + mtpmr(PMRN_PMC2, val); break; case 3: - mtpmr(PMRN_PMLCA3, pmlca); - mtpmr(PMRN_PMLCB3, pmlcb); + mtpmr(PMRN_PMC3, val); break; default: - panic("Bad ctr number!\n"); + break; } } -static void set_pmc_event(int ctr, int event) -{ - u32 pmlca; - - pmlca = get_pmlca(ctr); - - pmlca = (pmlca & ~PMLCA_EVENT_MASK) | - ((event << PMLCA_EVENT_SHIFT) & - PMLCA_EVENT_MASK); - - set_pmlca(ctr, pmlca); -} - -static void set_pmc_user_kernel(int ctr, int user, int kernel) -{ - u32 pmlca; - - pmlca = get_pmlca(ctr); - - if(user) - pmlca &= ~PMLCA_FCU; - else - pmlca |= PMLCA_FCU; - - if(kernel) - pmlca &= ~PMLCA_FCS; - else - pmlca |= PMLCA_FCS; - - set_pmlca(ctr, pmlca); -} - -static void set_pmc_marked(int ctr, int mark0, int mark1) -{ - u32 pmlca = get_pmlca(ctr); - - if(mark0) - pmlca &= ~PMLCA_FCM0; - else - pmlca |= PMLCA_FCM0; - - if(mark1) - pmlca &= ~PMLCA_FCM1; - else - pmlca |= PMLCA_FCM1; - - set_pmlca(ctr, pmlca); -} - -static void pmc_start_ctr(int ctr, int enable) -{ - u32 pmlca = get_pmlca(ctr); - - pmlca &= ~PMLCA_FC; - - if (enable) - pmlca |= PMLCA_CE; - else - pmlca &= ~PMLCA_CE; - - set_pmlca(ctr, pmlca); -} - -static void pmc_start_ctrs(int enable) -{ - u32 pmgc0 = mfpmr(PMRN_PMGC0); - - pmgc0 &= ~PMGC0_FAC; - pmgc0 |= PMGC0_FCECE; - - if (enable) - pmgc0 |= PMGC0_PMIE; - else - pmgc0 &= ~PMGC0_PMIE; - - mtpmr(PMRN_PMGC0, pmgc0); -} - -static void pmc_stop_ctrs(void) -{ - u32 pmgc0 = mfpmr(PMRN_PMGC0); - - pmgc0 |= PMGC0_FAC; - - pmgc0 &= ~(PMGC0_PMIE | PMGC0_FCECE); - - mtpmr(PMRN_PMGC0, pmgc0); -} - -static void dump_pmcs(void) -{ - printk("pmgc0: %x\n", mfpmr(PMRN_PMGC0)); - printk("pmc\t\tpmlca\t\tpmlcb\n"); - printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC0), - mfpmr(PMRN_PMLCA0), mfpmr(PMRN_PMLCB0)); - printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC1), - mfpmr(PMRN_PMLCA1), mfpmr(PMRN_PMLCB1)); - printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC2), - mfpmr(PMRN_PMLCA2), mfpmr(PMRN_PMLCB2)); - printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC3), - mfpmr(PMRN_PMLCA3), mfpmr(PMRN_PMLCB3)); -} - -static void fsl_booke_cpu_setup(struct op_counter_config *ctr) -{ - int i; - - /* freeze all counters */ - pmc_stop_ctrs(); - - for (i = 0;i < num_counters;i++) { - init_pmc_stop(i); - - set_pmc_event(i, ctr[i].event); - - set_pmc_user_kernel(i, ctr[i].user, ctr[i].kernel); - } -} static void fsl_booke_reg_setup(struct op_counter_config *ctr, struct op_system_config *sys, @@ -187,14 +77,23 @@ static void fsl_booke_reg_setup(struct op_counter_config *ctr, num_counters = num_ctrs; + /* freeze all counters */ + pmc_stop_ctrs(); + /* Our counters count up, and "count" refers to * how much before the next interrupt, and we interrupt * on overflow. So we calculate the starting value * which will give us "count" until overflow. * Then we set the events on the enabled counters */ - for (i = 0; i < num_counters; ++i) + for (i = 0; i < num_counters; ++i) { reset_value[i] = 0x80000000UL - ctr[i].count; + init_pmc_stop(i); + + set_pmc_event(i, ctr[i].event); + + set_pmc_user_kernel(i, ctr[i].user, ctr[i].kernel); + } } static void fsl_booke_start(struct op_counter_config *ctr) @@ -206,8 +105,8 @@ static void fsl_booke_start(struct op_counter_config *ctr) for (i = 0; i < num_counters; ++i) { if (ctr[i].enabled) { ctr_write(i, reset_value[i]); - /* Set each enabled counter to only - * count when the Mark bit is *not* set */ + /* Set Each enabled counterd to only + * count when the Mark bit is not set */ set_pmc_marked(i, 1, 0); pmc_start_ctr(i, 1); } else { @@ -278,7 +177,6 @@ static void fsl_booke_handle_interrupt(struct pt_regs *regs, struct op_powerpc_model op_model_fsl_booke = { .reg_setup = fsl_booke_reg_setup, - .cpu_setup = fsl_booke_cpu_setup, .start = fsl_booke_start, .stop = fsl_booke_stop, .handle_interrupt = fsl_booke_handle_interrupt, diff --git a/trunk/arch/powerpc/oprofile/op_model_power4.c b/trunk/arch/powerpc/oprofile/op_model_power4.c index 356709d515b9..506f6b79f893 100644 --- a/trunk/arch/powerpc/oprofile/op_model_power4.c +++ b/trunk/arch/powerpc/oprofile/op_model_power4.c @@ -76,13 +76,13 @@ static inline int mmcra_must_set_sample(void) { if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p) || __is_processor(PV_970) || __is_processor(PV_970FX) || - __is_processor(PV_970MP) || __is_processor(PV_970GX)) + __is_processor(PV_970MP)) return 1; return 0; } -static void power4_cpu_setup(struct op_counter_config *ctr) +static void power4_cpu_setup(void *unused) { unsigned int mmcr0 = mmcr0_val; unsigned long mmcra = mmcra_val; diff --git a/trunk/arch/powerpc/oprofile/op_model_rs64.c b/trunk/arch/powerpc/oprofile/op_model_rs64.c index 19c5ee089bc9..042f8f4867ad 100644 --- a/trunk/arch/powerpc/oprofile/op_model_rs64.c +++ b/trunk/arch/powerpc/oprofile/op_model_rs64.c @@ -102,7 +102,7 @@ static void rs64_reg_setup(struct op_counter_config *ctr, /* XXX setup user and kernel profiling */ } -static void rs64_cpu_setup(struct op_counter_config *ctr) +static void rs64_cpu_setup(void *unused) { unsigned int mmcr0; diff --git a/trunk/arch/powerpc/platforms/82xx/mpc82xx.c b/trunk/arch/powerpc/platforms/82xx/mpc82xx.c index 0f5b30dc60da..89d702de4863 100644 --- a/trunk/arch/powerpc/platforms/82xx/mpc82xx.c +++ b/trunk/arch/powerpc/platforms/82xx/mpc82xx.c @@ -11,6 +11,7 @@ * option) any later version. */ +#include #include #include #include diff --git a/trunk/arch/powerpc/platforms/82xx/mpc82xx_ads.c b/trunk/arch/powerpc/platforms/82xx/mpc82xx_ads.c index bb9acbb98176..4276f087f26e 100644 --- a/trunk/arch/powerpc/platforms/82xx/mpc82xx_ads.c +++ b/trunk/arch/powerpc/platforms/82xx/mpc82xx_ads.c @@ -12,6 +12,8 @@ * option) any later version. */ + +#include #include #include #include @@ -382,7 +384,8 @@ struct hw_interrupt_type m82xx_pci_ic = { }; static void -m82xx_pci_irq_demux(unsigned int irq, struct irq_desc *desc) +m82xx_pci_irq_demux(unsigned int irq, struct irq_desc *desc, + struct pt_regs *regs) { unsigned long stat, mask, pend; int bit; @@ -395,7 +398,7 @@ m82xx_pci_irq_demux(unsigned int irq, struct irq_desc *desc) break; for (bit = 0; pend != 0; ++bit, pend <<= 1) { if (pend & 0x80000000) - __do_IRQ(pci_int_base + bit); + __do_IRQ(pci_int_base + bit, regs); } } } diff --git a/trunk/arch/powerpc/platforms/82xx/pq2ads.h b/trunk/arch/powerpc/platforms/82xx/pq2ads.h index fb2f92bcd770..a7348213508f 100644 --- a/trunk/arch/powerpc/platforms/82xx/pq2ads.h +++ b/trunk/arch/powerpc/platforms/82xx/pq2ads.h @@ -22,6 +22,8 @@ #ifndef __MACH_ADS8260_DEFS #define __MACH_ADS8260_DEFS +#include + #include /* For our show_cpuinfo hooks. */ diff --git a/trunk/arch/powerpc/platforms/83xx/Kconfig b/trunk/arch/powerpc/platforms/83xx/Kconfig index edcd5b875b66..0975e94ac7c4 100644 --- a/trunk/arch/powerpc/platforms/83xx/Kconfig +++ b/trunk/arch/powerpc/platforms/83xx/Kconfig @@ -21,7 +21,7 @@ config MPC834x_SYS Be aware that PCI buses can only function when SYS board is plugged into the PIB (Platform IO Board) board from Freescale which provide 3 PCI slots. The PIBs PCI initialization is the bootloader's - responsibility. + responsiblilty. config MPC834x_ITX bool "Freescale MPC834x ITX" @@ -30,14 +30,7 @@ config MPC834x_ITX This option enables support for the MPC 834x ITX evaluation board. Be aware that PCI initialization is the bootloader's - responsibility. - -config MPC8360E_PB - bool "Freescale MPC8360E PB" - select DEFAULT_UIMAGE - select QUICC_ENGINE - help - This option enables support for the MPC836x EMDS Processor Board. + responsiblilty. endchoice @@ -53,10 +46,4 @@ config MPC834x select PPC_INDIRECT_PCI default y if MPC834x_SYS || MPC834x_ITX -config PPC_MPC836x - bool - select PPC_UDBG_16550 - select PPC_INDIRECT_PCI - default y if MPC8360E_PB - endmenu diff --git a/trunk/arch/powerpc/platforms/83xx/Makefile b/trunk/arch/powerpc/platforms/83xx/Makefile index f1aa7e24a938..9387a110d28a 100644 --- a/trunk/arch/powerpc/platforms/83xx/Makefile +++ b/trunk/arch/powerpc/platforms/83xx/Makefile @@ -5,5 +5,3 @@ obj-y := misc.o obj-$(CONFIG_PCI) += pci.o obj-$(CONFIG_MPC834x_SYS) += mpc834x_sys.o obj-$(CONFIG_MPC834x_ITX) += mpc834x_itx.o -obj-$(CONFIG_MPC8360E_PB) += mpc8360e_pb.o -obj-$(CONFIG_MPC832x_MDS) += mpc832x_mds.o diff --git a/trunk/arch/powerpc/platforms/83xx/mpc832x_mds.c b/trunk/arch/powerpc/platforms/83xx/mpc832x_mds.c index a43ac71ab740..54dea9d42dc9 100644 --- a/trunk/arch/powerpc/platforms/83xx/mpc832x_mds.c +++ b/trunk/arch/powerpc/platforms/83xx/mpc832x_mds.c @@ -24,7 +24,6 @@ #include #include -#include #include #include #include @@ -137,24 +136,6 @@ static void __init mpc832x_sys_setup_arch(void) #endif } -static int __init mpc832x_declare_of_platform_devices(void) -{ - struct device_node *np; - - for (np = NULL; (np = of_find_compatible_node(np, "network", - "ucc_geth")) != NULL;) { - int ucc_num; - char bus_id[BUS_ID_SIZE]; - - ucc_num = *((uint *) get_property(np, "device-id", NULL)) - 1; - snprintf(bus_id, BUS_ID_SIZE, "ucc_geth.%u", ucc_num); - of_platform_device_create(np, bus_id, NULL); - } - - return 0; -} -device_initcall(mpc832x_declare_of_platform_devices); - void __init mpc832x_sys_init_IRQ(void) { diff --git a/trunk/arch/powerpc/platforms/83xx/mpc834x_itx.c b/trunk/arch/powerpc/platforms/83xx/mpc834x_itx.c index e2bcaaf6b329..5446bab08eca 100644 --- a/trunk/arch/powerpc/platforms/83xx/mpc834x_itx.c +++ b/trunk/arch/powerpc/platforms/83xx/mpc834x_itx.c @@ -108,6 +108,10 @@ static int __init mpc834x_itx_probe(void) return 1; } +#ifdef CONFIG_RTC_CLASS +late_initcall(rtc_class_hookup); +#endif + define_machine(mpc834x_itx) { .name = "MPC834x ITX", .probe = mpc834x_itx_probe, diff --git a/trunk/arch/powerpc/platforms/83xx/mpc8360e_pb.c b/trunk/arch/powerpc/platforms/83xx/mpc8360e_pb.c index 1a523c81c06e..c0191900fc25 100644 --- a/trunk/arch/powerpc/platforms/83xx/mpc8360e_pb.c +++ b/trunk/arch/powerpc/platforms/83xx/mpc8360e_pb.c @@ -30,7 +30,6 @@ #include #include -#include #include #include #include @@ -142,24 +141,6 @@ static void __init mpc8360_sys_setup_arch(void) #endif } -static int __init mpc8360_declare_of_platform_devices(void) -{ - struct device_node *np; - - for (np = NULL; (np = of_find_compatible_node(np, "network", - "ucc_geth")) != NULL;) { - int ucc_num; - char bus_id[BUS_ID_SIZE]; - - ucc_num = *((uint *) get_property(np, "device-id", NULL)) - 1; - snprintf(bus_id, BUS_ID_SIZE, "ucc_geth.%u", ucc_num); - of_platform_device_create(np, bus_id, NULL); - } - - return 0; -} -device_initcall(mpc8360_declare_of_platform_devices); - void __init mpc8360_sys_init_IRQ(void) { diff --git a/trunk/arch/powerpc/platforms/85xx/mpc85xx_ads.c b/trunk/arch/powerpc/platforms/85xx/mpc85xx_ads.c index d3e669d69c73..28070e7ae507 100644 --- a/trunk/arch/powerpc/platforms/85xx/mpc85xx_ads.c +++ b/trunk/arch/powerpc/platforms/85xx/mpc85xx_ads.c @@ -66,12 +66,13 @@ mpc85xx_pcibios_fixup(void) #ifdef CONFIG_CPM2 -static void cpm2_cascade(unsigned int irq, struct irq_desc *desc) +static void cpm2_cascade(unsigned int irq, struct irq_desc *desc, + struct pt_regs *regs) { int cascade_irq; - while ((cascade_irq = cpm2_get_irq()) >= 0) { - generic_handle_irq(cascade_irq); + while ((cascade_irq = cpm2_get_irq(regs)) >= 0) { + generic_handle_irq(cascade_irq, regs); } desc->chip->eoi(irq); } diff --git a/trunk/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/trunk/arch/powerpc/platforms/85xx/mpc85xx_cds.c index 953cd5dd3f54..193a5d7921b5 100644 --- a/trunk/arch/powerpc/platforms/85xx/mpc85xx_cds.c +++ b/trunk/arch/powerpc/platforms/85xx/mpc85xx_cds.c @@ -132,12 +132,13 @@ mpc85xx_cds_pcibios_fixup(void) #ifdef CONFIG_PPC_I8259 #warning The i8259 PIC support is currently broken -static void mpc85xx_8259_cascade(unsigned int irq, struct irq_desc *desc) +static void mpc85xx_8259_cascade(unsigned int irq, struct + irq_desc *desc, struct pt_regs *regs) { - unsigned int cascade_irq = i8259_irq(); + unsigned int cascade_irq = i8259_irq(regs); if (cascade_irq != NO_IRQ) - generic_handle_irq(cascade_irq); + generic_handle_irq(cascade_irq, regs); desc->chip->eoi(irq); } @@ -149,10 +150,8 @@ void __init mpc85xx_cds_pic_init(void) struct mpic *mpic; struct resource r; struct device_node *np = NULL; -#ifdef CONFIG_PPC_I8259 struct device_node *cascade_node = NULL; int cascade_irq; -#endif np = of_find_node_by_type(np, "open-pic"); diff --git a/trunk/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/trunk/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c index 1a1c226ad4d9..b637e8157f7b 100644 --- a/trunk/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c +++ b/trunk/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c @@ -53,11 +53,12 @@ unsigned long pci_dram_offset = 0; #ifdef CONFIG_PCI -static void mpc86xx_8259_cascade(unsigned int irq, struct irq_desc *desc) +static void mpc86xx_8259_cascade(unsigned int irq, struct irq_desc *desc, + struct pt_regs *regs) { - unsigned int cascade_irq = i8259_irq(); + unsigned int cascade_irq = i8259_irq(regs); if (cascade_irq != NO_IRQ) - generic_handle_irq(cascade_irq); + generic_handle_irq(cascade_irq, regs); desc->chip->eoi(irq); } #endif /* CONFIG_PCI */ diff --git a/trunk/arch/powerpc/platforms/cell/Kconfig b/trunk/arch/powerpc/platforms/cell/Kconfig index 3e430b489bb7..0c8c7b6ab897 100644 --- a/trunk/arch/powerpc/platforms/cell/Kconfig +++ b/trunk/arch/powerpc/platforms/cell/Kconfig @@ -16,6 +16,11 @@ config SPU_BASE bool default n +config SPUFS_MMAP + bool + depends on SPU_FS && SPARSEMEM + default y + config CBE_RAS bool "RAS features for bare metal Cell BE" default y diff --git a/trunk/arch/powerpc/platforms/cell/interrupt.c b/trunk/arch/powerpc/platforms/cell/interrupt.c index a914c12b4060..6cc59e0b4582 100644 --- a/trunk/arch/powerpc/platforms/cell/interrupt.c +++ b/trunk/arch/powerpc/platforms/cell/interrupt.c @@ -98,9 +98,10 @@ static void iic_ioexc_eoi(unsigned int irq) { } -static void iic_ioexc_cascade(unsigned int irq, struct irq_desc *desc) +static void iic_ioexc_cascade(unsigned int irq, struct irq_desc *desc, + struct pt_regs *regs) { - struct cbe_iic_regs __iomem *node_iic = (void __iomem *)desc->handler_data; + struct cbe_iic_regs *node_iic = desc->handler_data; unsigned int base = (irq & 0xffffff00) | IIC_IRQ_TYPE_IOEXC; unsigned long bits, ack; int cascade; @@ -120,7 +121,7 @@ static void iic_ioexc_cascade(unsigned int irq, struct irq_desc *desc) irq_linear_revmap(iic_host, base | cascade); if (cirq != NO_IRQ) - generic_handle_irq(cirq); + generic_handle_irq(cirq, regs); } /* post-ack level interrupts */ ack = bits & ~IIC_ISR_EDGE_MASK; @@ -139,7 +140,7 @@ static struct irq_chip iic_ioexc_chip = { }; /* Get an IRQ number from the pending state register of the IIC */ -static unsigned int iic_get_irq(void) +static unsigned int iic_get_irq(struct pt_regs *regs) { struct cbe_iic_pending_bits pending; struct iic *iic; @@ -189,11 +190,11 @@ struct irq_host *iic_get_irq_host(int node) EXPORT_SYMBOL_GPL(iic_get_irq_host); -static irqreturn_t iic_ipi_action(int irq, void *dev_id) +static irqreturn_t iic_ipi_action(int irq, void *dev_id, struct pt_regs *regs) { int ipi = (int)(long)dev_id; - smp_message_recv(ipi); + smp_message_recv(ipi, regs); return IRQ_HANDLED; } @@ -319,7 +320,7 @@ static int __init setup_iic(void) struct device_node *dn; struct resource r0, r1; unsigned int node, cascade, found = 0; - struct cbe_iic_regs __iomem *node_iic; + struct cbe_iic_regs *node_iic; const u32 *np; for (dn = NULL; @@ -356,11 +357,7 @@ static int __init setup_iic(void) cascade = irq_create_mapping(iic_host, cascade); if (cascade == NO_IRQ) continue; - /* - * irq_data is a generic pointer that gets passed back - * to us later, so the forced cast is fine. - */ - set_irq_data(cascade, (void __force *)node_iic); + set_irq_data(cascade, node_iic); set_irq_chained_handler(cascade , iic_ioexc_cascade); out_be64(&node_iic->iic_ir, (1 << 12) /* priority */ | diff --git a/trunk/arch/powerpc/platforms/cell/iommu.c b/trunk/arch/powerpc/platforms/cell/iommu.c index aca4c3db0dde..d2b20eba5b87 100644 --- a/trunk/arch/powerpc/platforms/cell/iommu.c +++ b/trunk/arch/powerpc/platforms/cell/iommu.c @@ -345,8 +345,8 @@ static int cell_map_iommu_hardcoded(int num_nodes) /* node 0 */ iommu = &cell_iommus[0]; - iommu->mapped_base = ioremap(0x20000511000ul, 0x1000); - iommu->mapped_mmio_base = ioremap(0x20000510000ul, 0x1000); + iommu->mapped_base = ioremap(0x20000511000, 0x1000); + iommu->mapped_mmio_base = ioremap(0x20000510000, 0x1000); enable_mapping(iommu->mapped_base, iommu->mapped_mmio_base); @@ -358,8 +358,8 @@ static int cell_map_iommu_hardcoded(int num_nodes) /* node 1 */ iommu = &cell_iommus[1]; - iommu->mapped_base = ioremap(0x30000511000ul, 0x1000); - iommu->mapped_mmio_base = ioremap(0x30000510000ul, 0x1000); + iommu->mapped_base = ioremap(0x30000511000, 0x1000); + iommu->mapped_mmio_base = ioremap(0x30000510000, 0x1000); enable_mapping(iommu->mapped_base, iommu->mapped_mmio_base); diff --git a/trunk/arch/powerpc/platforms/cell/spider-pic.c b/trunk/arch/powerpc/platforms/cell/spider-pic.c index 21a9ebd4978e..608b1ebc56b2 100644 --- a/trunk/arch/powerpc/platforms/cell/spider-pic.c +++ b/trunk/arch/powerpc/platforms/cell/spider-pic.c @@ -213,7 +213,8 @@ static struct irq_host_ops spider_host_ops = { .xlate = spider_host_xlate, }; -static void spider_irq_cascade(unsigned int irq, struct irq_desc *desc) +static void spider_irq_cascade(unsigned int irq, struct irq_desc *desc, + struct pt_regs *regs) { struct spider_pic *pic = desc->handler_data; unsigned int cs, virq; @@ -224,7 +225,7 @@ static void spider_irq_cascade(unsigned int irq, struct irq_desc *desc) else virq = irq_linear_revmap(pic->host, cs); if (virq != NO_IRQ) - generic_handle_irq(virq); + generic_handle_irq(virq, regs); desc->chip->eoi(irq); } @@ -243,6 +244,7 @@ static unsigned int __init spider_find_cascade_and_node(struct spider_pic *pic) int imaplen, intsize, unit; struct device_node *iic; +#if 0 /* Enable that when we have a way to retreive the node as well */ /* First, we check wether we have a real "interrupts" in the device * tree in case the device-tree is ever fixed */ @@ -250,8 +252,9 @@ static unsigned int __init spider_find_cascade_and_node(struct spider_pic *pic) if (of_irq_map_one(pic->of_node, 0, &oirq) == 0) { virq = irq_create_of_mapping(oirq.controller, oirq.specifier, oirq.size); - return virq; + goto bail; } +#endif /* Now do the horrible hacks */ tmp = get_property(pic->of_node, "#interrupt-cells", NULL); @@ -366,7 +369,7 @@ void __init spider_init_IRQ(void) } else if (device_is_compatible(dn, "sti,platform-spider-pic") && (chip < 2)) { static long hard_coded_pics[] = - { 0x24000008000ul, 0x34000008000ul}; + { 0x24000008000, 0x34000008000 }; r.start = hard_coded_pics[chip]; } else continue; diff --git a/trunk/arch/powerpc/platforms/cell/spu_base.c b/trunk/arch/powerpc/platforms/cell/spu_base.c index 7aa809d5a244..f78680346e5f 100644 --- a/trunk/arch/powerpc/platforms/cell/spu_base.c +++ b/trunk/arch/powerpc/platforms/cell/spu_base.c @@ -25,13 +25,11 @@ #include #include #include -#include #include #include #include #include -#include #include #include #include @@ -48,21 +46,21 @@ EXPORT_SYMBOL_GPL(spu_priv1_ops); static int __spu_trap_invalid_dma(struct spu *spu) { pr_debug("%s\n", __FUNCTION__); - spu->dma_callback(spu, SPE_EVENT_INVALID_DMA); + force_sig(SIGBUS, /* info, */ current); return 0; } static int __spu_trap_dma_align(struct spu *spu) { pr_debug("%s\n", __FUNCTION__); - spu->dma_callback(spu, SPE_EVENT_DMA_ALIGNMENT); + force_sig(SIGBUS, /* info, */ current); return 0; } static int __spu_trap_error(struct spu *spu) { pr_debug("%s\n", __FUNCTION__); - spu->dma_callback(spu, SPE_EVENT_SPE_ERROR); + force_sig(SIGILL, /* info, */ current); return 0; } @@ -147,7 +145,7 @@ static int __spu_trap_data_map(struct spu *spu, unsigned long ea, u64 dsisr) } static irqreturn_t -spu_irq_class_0(int irq, void *data) +spu_irq_class_0(int irq, void *data, struct pt_regs *regs) { struct spu *spu; @@ -186,7 +184,7 @@ spu_irq_class_0_bottom(struct spu *spu) EXPORT_SYMBOL_GPL(spu_irq_class_0_bottom); static irqreturn_t -spu_irq_class_1(int irq, void *data) +spu_irq_class_1(int irq, void *data, struct pt_regs *regs) { struct spu *spu; unsigned long stat, mask, dar, dsisr; @@ -224,7 +222,7 @@ spu_irq_class_1(int irq, void *data) EXPORT_SYMBOL_GPL(spu_irq_class_1_bottom); static irqreturn_t -spu_irq_class_2(int irq, void *data) +spu_irq_class_2(int irq, void *data, struct pt_regs *regs) { struct spu *spu; unsigned long stat; @@ -319,7 +317,7 @@ static void spu_free_irqs(struct spu *spu) free_irq(spu->irqs[2], spu); } -static struct list_head spu_list[MAX_NUMNODES]; +static LIST_HEAD(spu_list); static DEFINE_MUTEX(spu_mutex); static void spu_init_channels(struct spu *spu) @@ -356,42 +354,32 @@ static void spu_init_channels(struct spu *spu) } } -struct spu *spu_alloc_node(int node) +struct spu *spu_alloc(void) { - struct spu *spu = NULL; + struct spu *spu; mutex_lock(&spu_mutex); - if (!list_empty(&spu_list[node])) { - spu = list_entry(spu_list[node].next, struct spu, list); + if (!list_empty(&spu_list)) { + spu = list_entry(spu_list.next, struct spu, list); list_del_init(&spu->list); - pr_debug("Got SPU %x %d %d\n", - spu->isrc, spu->number, spu->node); - spu_init_channels(spu); + pr_debug("Got SPU %x %d\n", spu->isrc, spu->number); + } else { + pr_debug("No SPU left\n"); + spu = NULL; } mutex_unlock(&spu_mutex); - return spu; -} -EXPORT_SYMBOL_GPL(spu_alloc_node); - -struct spu *spu_alloc(void) -{ - struct spu *spu = NULL; - int node; - - for (node = 0; node < MAX_NUMNODES; node++) { - spu = spu_alloc_node(node); - if (spu) - break; - } + if (spu) + spu_init_channels(spu); return spu; } +EXPORT_SYMBOL_GPL(spu_alloc); void spu_free(struct spu *spu) { mutex_lock(&spu_mutex); - list_add_tail(&spu->list, &spu_list[spu->node]); + list_add_tail(&spu->list, &spu_list); mutex_unlock(&spu_mutex); } EXPORT_SYMBOL_GPL(spu_free); @@ -578,7 +566,7 @@ static void spu_unmap(struct spu *spu) } /* This function shall be abstracted for HV platforms */ -static int __init spu_map_interrupts_old(struct spu *spu, struct device_node *np) +static int __init spu_map_interrupts(struct spu *spu, struct device_node *np) { unsigned int isrc; const u32 *tmp; @@ -602,7 +590,7 @@ static int __init spu_map_interrupts_old(struct spu *spu, struct device_node *np return spu->irqs[2] == NO_IRQ ? -EINVAL : 0; } -static int __init spu_map_device_old(struct spu *spu, struct device_node *node) +static int __init spu_map_device(struct spu *spu, struct device_node *node) { const char *prop; int ret; @@ -647,113 +635,6 @@ static int __init spu_map_device_old(struct spu *spu, struct device_node *node) return ret; } -static int __init spu_map_interrupts(struct spu *spu, struct device_node *np) -{ - struct of_irq oirq; - int ret; - int i; - - for (i=0; i < 3; i++) { - ret = of_irq_map_one(np, i, &oirq); - if (ret) { - pr_debug("spu_new: failed to get irq %d\n", i); - goto err; - } - ret = -EINVAL; - pr_debug(" irq %d no 0x%x on %s\n", i, oirq.specifier[0], - oirq.controller->full_name); - spu->irqs[i] = irq_create_of_mapping(oirq.controller, - oirq.specifier, oirq.size); - if (spu->irqs[i] == NO_IRQ) { - pr_debug("spu_new: failed to map it !\n"); - goto err; - } - } - return 0; - -err: - pr_debug("failed to map irq %x for spu %s\n", *oirq.specifier, spu->name); - for (; i >= 0; i--) { - if (spu->irqs[i] != NO_IRQ) - irq_dispose_mapping(spu->irqs[i]); - } - return ret; -} - -static int spu_map_resource(struct device_node *node, int nr, - void __iomem** virt, unsigned long *phys) -{ - struct resource resource = { }; - int ret; - - ret = of_address_to_resource(node, nr, &resource); - if (ret) - goto out; - - if (phys) - *phys = resource.start; - *virt = ioremap(resource.start, resource.end - resource.start); - if (!*virt) - ret = -EINVAL; - -out: - return ret; -} - -static int __init spu_map_device(struct spu *spu, struct device_node *node) -{ - int ret = -ENODEV; - spu->name = get_property(node, "name", NULL); - if (!spu->name) - goto out; - - ret = spu_map_resource(node, 0, (void __iomem**)&spu->local_store, - &spu->local_store_phys); - if (ret) { - pr_debug("spu_new: failed to map %s resource 0\n", - node->full_name); - goto out; - } - ret = spu_map_resource(node, 1, (void __iomem**)&spu->problem, - &spu->problem_phys); - if (ret) { - pr_debug("spu_new: failed to map %s resource 1\n", - node->full_name); - goto out_unmap; - } - ret = spu_map_resource(node, 2, (void __iomem**)&spu->priv2, - NULL); - if (ret) { - pr_debug("spu_new: failed to map %s resource 2\n", - node->full_name); - goto out_unmap; - } - - if (!firmware_has_feature(FW_FEATURE_LPAR)) - ret = spu_map_resource(node, 3, (void __iomem**)&spu->priv1, - NULL); - if (ret) { - pr_debug("spu_new: failed to map %s resource 3\n", - node->full_name); - goto out_unmap; - } - pr_debug("spu_new: %s maps:\n", node->full_name); - pr_debug(" local store : 0x%016lx -> 0x%p\n", - spu->local_store_phys, spu->local_store); - pr_debug(" problem state : 0x%016lx -> 0x%p\n", - spu->problem_phys, spu->problem); - pr_debug(" priv2 : 0x%p\n", spu->priv2); - pr_debug(" priv1 : 0x%p\n", spu->priv1); - - return 0; - -out_unmap: - spu_unmap(spu); -out: - pr_debug("failed to map spe %s: %d\n", spu->name, ret); - return ret; -} - struct sysdev_class spu_sysdev_class = { set_kset_name("spu") }; @@ -806,27 +687,15 @@ static int __init create_spu(struct device_node *spe) if (!spu) goto out; - spu->node = find_spu_node_id(spe); - if (spu->node >= MAX_NUMNODES) { - printk(KERN_WARNING "SPE %s on node %d ignored," - " node number too big\n", spe->full_name, spu->node); - printk(KERN_WARNING "Check if CONFIG_NUMA is enabled.\n"); - return -ENODEV; - } - spu->nid = of_node_to_nid(spe); - if (spu->nid == -1) - spu->nid = 0; - ret = spu_map_device(spu, spe); - /* try old method */ - if (ret) - ret = spu_map_device_old(spu, spe); if (ret) goto out_free; + spu->node = find_spu_node_id(spe); + spu->nid = of_node_to_nid(spe); + if (spu->nid == -1) + spu->nid = 0; ret = spu_map_interrupts(spu, spe); - if (ret) - ret = spu_map_interrupts_old(spu, spe); if (ret) goto out_unmap; spin_lock_init(&spu->register_lock); @@ -837,13 +706,13 @@ static int __init create_spu(struct device_node *spe) spu->number = number++; ret = spu_request_irqs(spu); if (ret) - goto out_unlock; + goto out_unmap; ret = spu_create_sysdev(spu); if (ret) goto out_free_irqs; - list_add(&spu->list, &spu_list[spu->node]); + list_add(&spu->list, &spu_list); mutex_unlock(&spu_mutex); pr_debug(KERN_DEBUG "Using SPE %s %02x %p %p %p %p %d\n", @@ -853,9 +722,9 @@ static int __init create_spu(struct device_node *spe) out_free_irqs: spu_free_irqs(spu); -out_unlock: - mutex_unlock(&spu_mutex); + out_unmap: + mutex_unlock(&spu_mutex); spu_unmap(spu); out_free: kfree(spu); @@ -876,13 +745,9 @@ static void destroy_spu(struct spu *spu) static void cleanup_spu_base(void) { struct spu *spu, *tmp; - int node; - mutex_lock(&spu_mutex); - for (node = 0; node < MAX_NUMNODES; node++) { - list_for_each_entry_safe(spu, tmp, &spu_list[node], list) - destroy_spu(spu); - } + list_for_each_entry_safe(spu, tmp, &spu_list, list) + destroy_spu(spu); mutex_unlock(&spu_mutex); sysdev_class_unregister(&spu_sysdev_class); } @@ -891,16 +756,13 @@ module_exit(cleanup_spu_base); static int __init init_spu_base(void) { struct device_node *node; - int i, ret; + int ret; /* create sysdev class for spus */ ret = sysdev_class_register(&spu_sysdev_class); if (ret) return ret; - for (i = 0; i < MAX_NUMNODES; i++) - INIT_LIST_HEAD(&spu_list[i]); - ret = -ENODEV; for (node = of_find_node_by_type(NULL, "spe"); node; node = of_find_node_by_type(node, "spe")) { @@ -912,6 +774,18 @@ static int __init init_spu_base(void) break; } } + /* in some old firmware versions, the spe is called 'spc', so we + look for that as well */ + for (node = of_find_node_by_type(NULL, "spc"); + node; node = of_find_node_by_type(node, "spc")) { + ret = create_spu(node); + if (ret) { + printk(KERN_WARNING "%s: Error initializing %s\n", + __FUNCTION__, node->name); + cleanup_spu_base(); + break; + } + } return ret; } module_init(init_spu_base); diff --git a/trunk/arch/powerpc/platforms/cell/spufs/Makefile b/trunk/arch/powerpc/platforms/cell/spufs/Makefile index ecdfbb35f82e..bb5dc634272c 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/Makefile +++ b/trunk/arch/powerpc/platforms/cell/spufs/Makefile @@ -2,7 +2,7 @@ obj-y += switch.o obj-$(CONFIG_SPU_FS) += spufs.o spufs-y += inode.o file.o context.o syscalls.o -spufs-y += sched.o backing_ops.o hw_ops.o run.o gang.o +spufs-y += sched.o backing_ops.o hw_ops.o run.o # Rules to build switch.o with the help of SPU tool chain SPU_CROSS := spu- diff --git a/trunk/arch/powerpc/platforms/cell/spufs/context.c b/trunk/arch/powerpc/platforms/cell/spufs/context.c index 034cf6af53a2..36439c5e9f2d 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/context.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/context.c @@ -27,7 +27,7 @@ #include #include "spufs.h" -struct spu_context *alloc_spu_context(struct spu_gang *gang) +struct spu_context *alloc_spu_context(void) { struct spu_context *ctx; ctx = kzalloc(sizeof *ctx, GFP_KERNEL); @@ -51,8 +51,6 @@ struct spu_context *alloc_spu_context(struct spu_gang *gang) ctx->state = SPU_STATE_SAVED; ctx->ops = &spu_backing_ops; ctx->owner = get_task_mm(current); - if (gang) - spu_gang_add_ctx(gang, ctx); goto out; out_free: kfree(ctx); @@ -69,8 +67,6 @@ void destroy_spu_context(struct kref *kref) spu_deactivate(ctx); up_write(&ctx->state_sema); spu_fini_csa(&ctx->csa); - if (ctx->gang) - spu_gang_remove_ctx(ctx->gang, ctx); kfree(ctx); } diff --git a/trunk/arch/powerpc/platforms/cell/spufs/file.c b/trunk/arch/powerpc/platforms/cell/spufs/file.c index 533e2723e184..51fd197ab5dd 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/file.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/file.c @@ -36,8 +36,6 @@ #include "spufs.h" -#define SPUFS_MMAP_4K (PAGE_SIZE == 0x1000) - static int spufs_mem_open(struct inode *inode, struct file *file) @@ -90,6 +88,7 @@ spufs_mem_write(struct file *file, const char __user *buffer, return ret; } +#ifdef CONFIG_SPUFS_MMAP static struct page * spufs_mem_mmap_nopage(struct vm_area_struct *vma, unsigned long address, int *type) @@ -102,16 +101,12 @@ spufs_mem_mmap_nopage(struct vm_area_struct *vma, spu_acquire(ctx); - if (ctx->state == SPU_STATE_SAVED) { - vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) - & ~(_PAGE_NO_CACHE | _PAGE_GUARDED)); + if (ctx->state == SPU_STATE_SAVED) page = vmalloc_to_page(ctx->csa.lscsa->ls + offset); - } else { - vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) - | _PAGE_NO_CACHE | _PAGE_GUARDED); + else page = pfn_to_page((ctx->spu->local_store_phys + offset) >> PAGE_SHIFT); - } + spu_release(ctx); if (type) @@ -138,19 +133,22 @@ spufs_mem_mmap(struct file *file, struct vm_area_struct *vma) vma->vm_ops = &spufs_mem_mmap_vmops; return 0; } +#endif static struct file_operations spufs_mem_fops = { .open = spufs_mem_open, .read = spufs_mem_read, .write = spufs_mem_write, .llseek = generic_file_llseek, +#ifdef CONFIG_SPUFS_MMAP .mmap = spufs_mem_mmap, +#endif }; +#ifdef CONFIG_SPUFS_MMAP static struct page *spufs_ps_nopage(struct vm_area_struct *vma, unsigned long address, - int *type, unsigned long ps_offs, - unsigned long ps_size) + int *type, unsigned long ps_offs) { struct page *page = NOPAGE_SIGBUS; int fault_type = VM_FAULT_SIGBUS; @@ -160,7 +158,7 @@ static struct page *spufs_ps_nopage(struct vm_area_struct *vma, int ret; offset += vma->vm_pgoff << PAGE_SHIFT; - if (offset >= ps_size) + if (offset >= 0x4000) goto out; ret = spu_acquire_runnable(ctx); @@ -181,11 +179,10 @@ static struct page *spufs_ps_nopage(struct vm_area_struct *vma, return page; } -#if SPUFS_MMAP_4K static struct page *spufs_cntl_mmap_nopage(struct vm_area_struct *vma, unsigned long address, int *type) { - return spufs_ps_nopage(vma, address, type, 0x4000, 0x1000); + return spufs_ps_nopage(vma, address, type, 0x4000); } static struct vm_operations_struct spufs_cntl_mmap_vmops = { @@ -194,12 +191,17 @@ static struct vm_operations_struct spufs_cntl_mmap_vmops = { /* * mmap support for problem state control area [0x4000 - 0x4fff]. + * Mapping this area requires that the application have CAP_SYS_RAWIO, + * as these registers require special care when read/writing. */ static int spufs_cntl_mmap(struct file *file, struct vm_area_struct *vma) { if (!(vma->vm_flags & VM_SHARED)) return -EINVAL; + if (!capable(CAP_SYS_RAWIO)) + return -EPERM; + vma->vm_flags |= VM_RESERVED; vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) | _PAGE_NO_CACHE | _PAGE_GUARDED); @@ -207,30 +209,7 @@ static int spufs_cntl_mmap(struct file *file, struct vm_area_struct *vma) vma->vm_ops = &spufs_cntl_mmap_vmops; return 0; } -#else /* SPUFS_MMAP_4K */ -#define spufs_cntl_mmap NULL -#endif /* !SPUFS_MMAP_4K */ - -static u64 spufs_cntl_get(void *data) -{ - struct spu_context *ctx = data; - u64 val; - - spu_acquire(ctx); - val = ctx->ops->status_read(ctx); - spu_release(ctx); - - return val; -} - -static void spufs_cntl_set(void *data, u64 val) -{ - struct spu_context *ctx = data; - - spu_acquire(ctx); - ctx->ops->runcntl_write(ctx, val); - spu_release(ctx); -} +#endif static int spufs_cntl_open(struct inode *inode, struct file *file) { @@ -240,16 +219,32 @@ static int spufs_cntl_open(struct inode *inode, struct file *file) file->private_data = ctx; file->f_mapping = inode->i_mapping; ctx->cntl = inode->i_mapping; - return simple_attr_open(inode, file, spufs_cntl_get, - spufs_cntl_set, "0x%08lx"); + return 0; +} + +static ssize_t +spufs_cntl_read(struct file *file, char __user *buffer, + size_t size, loff_t *pos) +{ + /* FIXME: read from spu status */ + return -EINVAL; +} + +static ssize_t +spufs_cntl_write(struct file *file, const char __user *buffer, + size_t size, loff_t *pos) +{ + /* FIXME: write to runctl bit */ + return -EINVAL; } static struct file_operations spufs_cntl_fops = { .open = spufs_cntl_open, - .release = simple_attr_close, - .read = simple_attr_read, - .write = simple_attr_write, + .read = spufs_cntl_read, + .write = spufs_cntl_write, +#ifdef CONFIG_SPUFS_MMAP .mmap = spufs_cntl_mmap, +#endif }; static int @@ -361,54 +356,27 @@ static int spufs_pipe_open(struct inode *inode, struct file *file) return nonseekable_open(inode, file); } -/* - * Read as many bytes from the mailbox as possible, until - * one of the conditions becomes true: - * - * - no more data available in the mailbox - * - end of the user provided buffer - * - end of the mapped area - */ static ssize_t spufs_mbox_read(struct file *file, char __user *buf, size_t len, loff_t *pos) { struct spu_context *ctx = file->private_data; - u32 mbox_data, __user *udata; - ssize_t count; + u32 mbox_data; + int ret; if (len < 4) return -EINVAL; - if (!access_ok(VERIFY_WRITE, buf, len)) - return -EFAULT; - - udata = (void __user *)buf; - spu_acquire(ctx); - for (count = 0; (count + 4) <= len; count += 4, udata++) { - int ret; - ret = ctx->ops->mbox_read(ctx, &mbox_data); - if (ret == 0) - break; - - /* - * at the end of the mapped area, we can fault - * but still need to return the data we have - * read successfully so far. - */ - ret = __put_user(mbox_data, udata); - if (ret) { - if (!count) - count = -EFAULT; - break; - } - } + ret = ctx->ops->mbox_read(ctx, &mbox_data); spu_release(ctx); - if (!count) - count = -EAGAIN; + if (!ret) + return -EAGAIN; + + if (copy_to_user(buf, &mbox_data, sizeof mbox_data)) + return -EFAULT; - return count; + return 4; } static struct file_operations spufs_mbox_fops = { @@ -464,70 +432,36 @@ void spufs_ibox_callback(struct spu *spu) kill_fasync(&ctx->ibox_fasync, SIGIO, POLLIN); } -/* - * Read as many bytes from the interrupt mailbox as possible, until - * one of the conditions becomes true: - * - * - no more data available in the mailbox - * - end of the user provided buffer - * - end of the mapped area - * - * If the file is opened without O_NONBLOCK, we wait here until - * any data is available, but return when we have been able to - * read something. - */ static ssize_t spufs_ibox_read(struct file *file, char __user *buf, size_t len, loff_t *pos) { struct spu_context *ctx = file->private_data; - u32 ibox_data, __user *udata; - ssize_t count; + u32 ibox_data; + ssize_t ret; if (len < 4) return -EINVAL; - if (!access_ok(VERIFY_WRITE, buf, len)) - return -EFAULT; - - udata = (void __user *)buf; - spu_acquire(ctx); - /* wait only for the first element */ - count = 0; + ret = 0; if (file->f_flags & O_NONBLOCK) { if (!spu_ibox_read(ctx, &ibox_data)) - count = -EAGAIN; + ret = -EAGAIN; } else { - count = spufs_wait(ctx->ibox_wq, spu_ibox_read(ctx, &ibox_data)); + ret = spufs_wait(ctx->ibox_wq, spu_ibox_read(ctx, &ibox_data)); } - if (count) - goto out; - /* if we can't write at all, return -EFAULT */ - count = __put_user(ibox_data, udata); - if (count) - goto out; + spu_release(ctx); - for (count = 4, udata++; (count + 4) <= len; count += 4, udata++) { - int ret; - ret = ctx->ops->ibox_read(ctx, &ibox_data); - if (ret == 0) - break; - /* - * at the end of the mapped area, we can fault - * but still need to return the data we have - * read successfully so far. - */ - ret = __put_user(ibox_data, udata); - if (ret) - break; - } + if (ret) + return ret; -out: - spu_release(ctx); + ret = 4; + if (copy_to_user(buf, &ibox_data, sizeof ibox_data)) + ret = -EFAULT; - return count; + return ret; } static unsigned int spufs_ibox_poll(struct file *file, poll_table *wait) @@ -600,67 +534,32 @@ void spufs_wbox_callback(struct spu *spu) kill_fasync(&ctx->wbox_fasync, SIGIO, POLLOUT); } -/* - * Write as many bytes to the interrupt mailbox as possible, until - * one of the conditions becomes true: - * - * - the mailbox is full - * - end of the user provided buffer - * - end of the mapped area - * - * If the file is opened without O_NONBLOCK, we wait here until - * space is availabyl, but return when we have been able to - * write something. - */ static ssize_t spufs_wbox_write(struct file *file, const char __user *buf, size_t len, loff_t *pos) { struct spu_context *ctx = file->private_data; - u32 wbox_data, __user *udata; - ssize_t count; + u32 wbox_data; + int ret; if (len < 4) return -EINVAL; - udata = (void __user *)buf; - if (!access_ok(VERIFY_READ, buf, len)) - return -EFAULT; - - if (__get_user(wbox_data, udata)) + if (copy_from_user(&wbox_data, buf, sizeof wbox_data)) return -EFAULT; spu_acquire(ctx); - /* - * make sure we can at least write one element, by waiting - * in case of !O_NONBLOCK - */ - count = 0; + ret = 0; if (file->f_flags & O_NONBLOCK) { if (!spu_wbox_write(ctx, wbox_data)) - count = -EAGAIN; + ret = -EAGAIN; } else { - count = spufs_wait(ctx->wbox_wq, spu_wbox_write(ctx, wbox_data)); + ret = spufs_wait(ctx->wbox_wq, spu_wbox_write(ctx, wbox_data)); } - if (count) - goto out; - - /* write aÑ• much as possible */ - for (count = 4, udata++; (count + 4) <= len; count += 4, udata++) { - int ret; - ret = __get_user(wbox_data, udata); - if (ret) - break; - - ret = spu_wbox_write(ctx, wbox_data); - if (ret == 0) - break; - } - -out: spu_release(ctx); - return count; + + return ret ? ret : sizeof wbox_data; } static unsigned int spufs_wbox_poll(struct file *file, poll_table *wait) @@ -758,19 +657,11 @@ static ssize_t spufs_signal1_write(struct file *file, const char __user *buf, return 4; } +#ifdef CONFIG_SPUFS_MMAP static struct page *spufs_signal1_mmap_nopage(struct vm_area_struct *vma, unsigned long address, int *type) { -#if PAGE_SIZE == 0x1000 - return spufs_ps_nopage(vma, address, type, 0x14000, 0x1000); -#elif PAGE_SIZE == 0x10000 - /* For 64k pages, both signal1 and signal2 can be used to mmap the whole - * signal 1 and 2 area - */ - return spufs_ps_nopage(vma, address, type, 0x10000, 0x10000); -#else -#error unsupported page size -#endif + return spufs_ps_nopage(vma, address, type, 0x14000); } static struct vm_operations_struct spufs_signal1_mmap_vmops = { @@ -789,12 +680,15 @@ static int spufs_signal1_mmap(struct file *file, struct vm_area_struct *vma) vma->vm_ops = &spufs_signal1_mmap_vmops; return 0; } +#endif static struct file_operations spufs_signal1_fops = { .open = spufs_signal1_open, .read = spufs_signal1_read, .write = spufs_signal1_write, +#ifdef CONFIG_SPUFS_MMAP .mmap = spufs_signal1_mmap, +#endif }; static int spufs_signal2_open(struct inode *inode, struct file *file) @@ -849,20 +743,11 @@ static ssize_t spufs_signal2_write(struct file *file, const char __user *buf, return 4; } -#if SPUFS_MMAP_4K +#ifdef CONFIG_SPUFS_MMAP static struct page *spufs_signal2_mmap_nopage(struct vm_area_struct *vma, unsigned long address, int *type) { -#if PAGE_SIZE == 0x1000 - return spufs_ps_nopage(vma, address, type, 0x1c000, 0x1000); -#elif PAGE_SIZE == 0x10000 - /* For 64k pages, both signal1 and signal2 can be used to mmap the whole - * signal 1 and 2 area - */ - return spufs_ps_nopage(vma, address, type, 0x10000, 0x10000); -#else -#error unsupported page size -#endif + return spufs_ps_nopage(vma, address, type, 0x1c000); } static struct vm_operations_struct spufs_signal2_mmap_vmops = { @@ -882,15 +767,15 @@ static int spufs_signal2_mmap(struct file *file, struct vm_area_struct *vma) vma->vm_ops = &spufs_signal2_mmap_vmops; return 0; } -#else /* SPUFS_MMAP_4K */ -#define spufs_signal2_mmap NULL -#endif /* !SPUFS_MMAP_4K */ +#endif static struct file_operations spufs_signal2_fops = { .open = spufs_signal2_open, .read = spufs_signal2_read, .write = spufs_signal2_write, +#ifdef CONFIG_SPUFS_MMAP .mmap = spufs_signal2_mmap, +#endif }; static void spufs_signal1_type_set(void *data, u64 val) @@ -939,11 +824,11 @@ static u64 spufs_signal2_type_get(void *data) DEFINE_SIMPLE_ATTRIBUTE(spufs_signal2_type, spufs_signal2_type_get, spufs_signal2_type_set, "%llu"); -#if SPUFS_MMAP_4K +#ifdef CONFIG_SPUFS_MMAP static struct page *spufs_mss_mmap_nopage(struct vm_area_struct *vma, unsigned long address, int *type) { - return spufs_ps_nopage(vma, address, type, 0x0000, 0x1000); + return spufs_ps_nopage(vma, address, type, 0x0000); } static struct vm_operations_struct spufs_mss_mmap_vmops = { @@ -952,12 +837,17 @@ static struct vm_operations_struct spufs_mss_mmap_vmops = { /* * mmap support for problem state MFC DMA area [0x0000 - 0x0fff]. + * Mapping this area requires that the application have CAP_SYS_RAWIO, + * as these registers require special care when read/writing. */ static int spufs_mss_mmap(struct file *file, struct vm_area_struct *vma) { if (!(vma->vm_flags & VM_SHARED)) return -EINVAL; + if (!capable(CAP_SYS_RAWIO)) + return -EPERM; + vma->vm_flags |= VM_RESERVED; vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) | _PAGE_NO_CACHE | _PAGE_GUARDED); @@ -965,9 +855,7 @@ static int spufs_mss_mmap(struct file *file, struct vm_area_struct *vma) vma->vm_ops = &spufs_mss_mmap_vmops; return 0; } -#else /* SPUFS_MMAP_4K */ -#define spufs_mss_mmap NULL -#endif /* !SPUFS_MMAP_4K */ +#endif static int spufs_mss_open(struct inode *inode, struct file *file) { @@ -979,54 +867,17 @@ static int spufs_mss_open(struct inode *inode, struct file *file) static struct file_operations spufs_mss_fops = { .open = spufs_mss_open, +#ifdef CONFIG_SPUFS_MMAP .mmap = spufs_mss_mmap, -}; - -static struct page *spufs_psmap_mmap_nopage(struct vm_area_struct *vma, - unsigned long address, int *type) -{ - return spufs_ps_nopage(vma, address, type, 0x0000, 0x20000); -} - -static struct vm_operations_struct spufs_psmap_mmap_vmops = { - .nopage = spufs_psmap_mmap_nopage, -}; - -/* - * mmap support for full problem state area [0x00000 - 0x1ffff]. - */ -static int spufs_psmap_mmap(struct file *file, struct vm_area_struct *vma) -{ - if (!(vma->vm_flags & VM_SHARED)) - return -EINVAL; - - vma->vm_flags |= VM_RESERVED; - vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) - | _PAGE_NO_CACHE | _PAGE_GUARDED); - - vma->vm_ops = &spufs_psmap_mmap_vmops; - return 0; -} - -static int spufs_psmap_open(struct inode *inode, struct file *file) -{ - struct spufs_inode_info *i = SPUFS_I(inode); - - file->private_data = i->i_ctx; - return nonseekable_open(inode, file); -} - -static struct file_operations spufs_psmap_fops = { - .open = spufs_psmap_open, - .mmap = spufs_psmap_mmap, +#endif }; -#if SPUFS_MMAP_4K +#ifdef CONFIG_SPUFS_MMAP static struct page *spufs_mfc_mmap_nopage(struct vm_area_struct *vma, unsigned long address, int *type) { - return spufs_ps_nopage(vma, address, type, 0x3000, 0x1000); + return spufs_ps_nopage(vma, address, type, 0x3000); } static struct vm_operations_struct spufs_mfc_mmap_vmops = { @@ -1035,12 +886,17 @@ static struct vm_operations_struct spufs_mfc_mmap_vmops = { /* * mmap support for problem state MFC DMA area [0x0000 - 0x0fff]. + * Mapping this area requires that the application have CAP_SYS_RAWIO, + * as these registers require special care when read/writing. */ static int spufs_mfc_mmap(struct file *file, struct vm_area_struct *vma) { if (!(vma->vm_flags & VM_SHARED)) return -EINVAL; + if (!capable(CAP_SYS_RAWIO)) + return -EPERM; + vma->vm_flags |= VM_RESERVED; vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) | _PAGE_NO_CACHE | _PAGE_GUARDED); @@ -1048,9 +904,7 @@ static int spufs_mfc_mmap(struct file *file, struct vm_area_struct *vma) vma->vm_ops = &spufs_mfc_mmap_vmops; return 0; } -#else /* SPUFS_MMAP_4K */ -#define spufs_mfc_mmap NULL -#endif /* !SPUFS_MMAP_4K */ +#endif static int spufs_mfc_open(struct inode *inode, struct file *file) { @@ -1340,7 +1194,9 @@ static struct file_operations spufs_mfc_fops = { .flush = spufs_mfc_flush, .fsync = spufs_mfc_fsync, .fasync = spufs_mfc_fasync, +#ifdef CONFIG_SPUFS_MMAP .mmap = spufs_mfc_mmap, +#endif }; static void spufs_npc_set(void *data, u64 val) @@ -1488,21 +1344,6 @@ static u64 spufs_id_get(void *data) } DEFINE_SIMPLE_ATTRIBUTE(spufs_id_ops, spufs_id_get, NULL, "0x%llx\n") -static u64 spufs_object_id_get(void *data) -{ - struct spu_context *ctx = data; - return ctx->object_id; -} - -static void spufs_object_id_set(void *data, u64 id) -{ - struct spu_context *ctx = data; - ctx->object_id = id; -} - -DEFINE_SIMPLE_ATTRIBUTE(spufs_object_id_ops, spufs_object_id_get, - spufs_object_id_set, "0x%llx\n"); - struct tree_descr spufs_dir_contents[] = { { "mem", &spufs_mem_fops, 0666, }, { "regs", &spufs_regs_fops, 0666, }, @@ -1526,8 +1367,6 @@ struct tree_descr spufs_dir_contents[] = { { "spu_tag_mask", &spufs_spu_tag_mask_ops, 0666, }, { "event_mask", &spufs_event_mask_ops, 0666, }, { "srr0", &spufs_srr0_ops, 0666, }, - { "psmap", &spufs_psmap_fops, 0666, }, { "phys-id", &spufs_id_ops, 0666, }, - { "object-id", &spufs_object_id_ops, 0666, }, {}, }; diff --git a/trunk/arch/powerpc/platforms/cell/spufs/gang.c b/trunk/arch/powerpc/platforms/cell/spufs/gang.c deleted file mode 100644 index 212ea78f9051..000000000000 --- a/trunk/arch/powerpc/platforms/cell/spufs/gang.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * SPU file system - * - * (C) Copyright IBM Deutschland Entwicklung GmbH 2005 - * - * Author: Arnd Bergmann - * - * 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include - -#include "spufs.h" - -struct spu_gang *alloc_spu_gang(void) -{ - struct spu_gang *gang; - - gang = kzalloc(sizeof *gang, GFP_KERNEL); - if (!gang) - goto out; - - kref_init(&gang->kref); - mutex_init(&gang->mutex); - INIT_LIST_HEAD(&gang->list); - -out: - return gang; -} - -static void destroy_spu_gang(struct kref *kref) -{ - struct spu_gang *gang; - gang = container_of(kref, struct spu_gang, kref); - WARN_ON(gang->contexts || !list_empty(&gang->list)); - kfree(gang); -} - -struct spu_gang *get_spu_gang(struct spu_gang *gang) -{ - kref_get(&gang->kref); - return gang; -} - -int put_spu_gang(struct spu_gang *gang) -{ - return kref_put(&gang->kref, &destroy_spu_gang); -} - -void spu_gang_add_ctx(struct spu_gang *gang, struct spu_context *ctx) -{ - mutex_lock(&gang->mutex); - ctx->gang = get_spu_gang(gang); - list_add(&ctx->gang_list, &gang->list); - gang->contexts++; - mutex_unlock(&gang->mutex); -} - -void spu_gang_remove_ctx(struct spu_gang *gang, struct spu_context *ctx) -{ - mutex_lock(&gang->mutex); - WARN_ON(ctx->gang != gang); - list_del_init(&ctx->gang_list); - gang->contexts--; - mutex_unlock(&gang->mutex); - - put_spu_gang(gang); -} diff --git a/trunk/arch/powerpc/platforms/cell/spufs/hw_ops.c b/trunk/arch/powerpc/platforms/cell/spufs/hw_ops.c index d805ffed892d..efc452e71ab0 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/hw_ops.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/hw_ops.c @@ -147,7 +147,7 @@ static void spu_hw_signal1_write(struct spu_context *ctx, u32 data) static u32 spu_hw_signal2_read(struct spu_context *ctx) { - return in_be32(&ctx->spu->problem->signal_notify2); + return in_be32(&ctx->spu->problem->signal_notify1); } static void spu_hw_signal2_write(struct spu_context *ctx, u32 data) diff --git a/trunk/arch/powerpc/platforms/cell/spufs/inode.c b/trunk/arch/powerpc/platforms/cell/spufs/inode.c index 427d00a4f6a0..3950ddccb2c8 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/inode.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/inode.c @@ -50,10 +50,6 @@ spufs_alloc_inode(struct super_block *sb) ei = kmem_cache_alloc(spufs_inode_cache, SLAB_KERNEL); if (!ei) return NULL; - - ei->i_gang = NULL; - ei->i_ctx = NULL; - return &ei->vfs_inode; } @@ -132,19 +128,14 @@ spufs_new_file(struct super_block *sb, struct dentry *dentry, static void spufs_delete_inode(struct inode *inode) { - struct spufs_inode_info *ei = SPUFS_I(inode); - - if (ei->i_ctx) - put_spu_context(ei->i_ctx); - if (ei->i_gang) - put_spu_gang(ei->i_gang); + if (SPUFS_I(inode)->i_ctx) + put_spu_context(SPUFS_I(inode)->i_ctx); clear_inode(inode); } static void spufs_prune_dir(struct dentry *dir) { struct dentry *dentry, *tmp; - mutex_lock(&dir->d_inode->i_mutex); list_for_each_entry_safe(dentry, tmp, &dir->d_subdirs, d_u.d_child) { spin_lock(&dcache_lock); @@ -165,13 +156,13 @@ static void spufs_prune_dir(struct dentry *dir) mutex_unlock(&dir->d_inode->i_mutex); } -/* Caller must hold parent->i_mutex */ -static int spufs_rmdir(struct inode *parent, struct dentry *dir) +/* Caller must hold root->i_mutex */ +static int spufs_rmdir(struct inode *root, struct dentry *dir_dentry) { /* remove all entries */ - spufs_prune_dir(dir); + spufs_prune_dir(dir_dentry); - return simple_rmdir(parent, dir); + return simple_rmdir(root, dir_dentry); } static int spufs_fill_dir(struct dentry *dir, struct tree_descr *files, @@ -200,17 +191,17 @@ static int spufs_fill_dir(struct dentry *dir, struct tree_descr *files, static int spufs_dir_close(struct inode *inode, struct file *file) { struct spu_context *ctx; - struct inode *parent; - struct dentry *dir; + struct inode *dir; + struct dentry *dentry; int ret; - dir = file->f_dentry; - parent = dir->d_parent->d_inode; - ctx = SPUFS_I(dir->d_inode)->i_ctx; + dentry = file->f_dentry; + dir = dentry->d_parent->d_inode; + ctx = SPUFS_I(dentry->d_inode)->i_ctx; - mutex_lock(&parent->i_mutex); - ret = spufs_rmdir(parent, dir); - mutex_unlock(&parent->i_mutex); + mutex_lock(&dir->i_mutex); + ret = spufs_rmdir(dir, dentry); + mutex_unlock(&dir->i_mutex); WARN_ON(ret); /* We have to give up the mm_struct */ @@ -233,8 +224,7 @@ struct file_operations spufs_context_fops = { }; static int -spufs_mkdir(struct inode *dir, struct dentry *dentry, unsigned int flags, - int mode) +spufs_mkdir(struct inode *dir, struct dentry *dentry, int mode) { int ret; struct inode *inode; @@ -249,13 +239,11 @@ spufs_mkdir(struct inode *dir, struct dentry *dentry, unsigned int flags, inode->i_gid = dir->i_gid; inode->i_mode &= S_ISGID; } - ctx = alloc_spu_context(SPUFS_I(dir)->i_gang); /* XXX gang */ + ctx = alloc_spu_context(); SPUFS_I(inode)->i_ctx = ctx; if (!ctx) goto out_iput; - ctx->flags = flags; - inode->i_op = &spufs_dir_inode_operations; inode->i_fop = &simple_dir_operations; ret = spufs_fill_dir(dentry, spufs_dir_contents, mode, ctx); @@ -301,177 +289,24 @@ static int spufs_context_open(struct dentry *dentry, struct vfsmount *mnt) return ret; } -static int spufs_create_context(struct inode *inode, - struct dentry *dentry, - struct vfsmount *mnt, int flags, int mode) -{ - int ret; - - ret = spufs_mkdir(inode, dentry, flags, mode & S_IRWXUGO); - if (ret) - goto out_unlock; - - /* - * get references for dget and mntget, will be released - * in error path of *_open(). - */ - ret = spufs_context_open(dget(dentry), mntget(mnt)); - if (ret < 0) { - WARN_ON(spufs_rmdir(inode, dentry)); - mutex_unlock(&inode->i_mutex); - spu_forget(SPUFS_I(dentry->d_inode)->i_ctx); - goto out; - } - -out_unlock: - mutex_unlock(&inode->i_mutex); -out: - dput(dentry); - return ret; -} - -static int spufs_rmgang(struct inode *root, struct dentry *dir) -{ - /* FIXME: this fails if the dir is not empty, - which causes a leak of gangs. */ - return simple_rmdir(root, dir); -} - -static int spufs_gang_close(struct inode *inode, struct file *file) -{ - struct inode *parent; - struct dentry *dir; - int ret; - - dir = file->f_dentry; - parent = dir->d_parent->d_inode; - - ret = spufs_rmgang(parent, dir); - WARN_ON(ret); - - return dcache_dir_close(inode, file); -} - -struct file_operations spufs_gang_fops = { - .open = dcache_dir_open, - .release = spufs_gang_close, - .llseek = dcache_dir_lseek, - .read = generic_read_dir, - .readdir = dcache_readdir, - .fsync = simple_sync_file, -}; - -static int -spufs_mkgang(struct inode *dir, struct dentry *dentry, int mode) -{ - int ret; - struct inode *inode; - struct spu_gang *gang; - - ret = -ENOSPC; - inode = spufs_new_inode(dir->i_sb, mode | S_IFDIR); - if (!inode) - goto out; - - ret = 0; - if (dir->i_mode & S_ISGID) { - inode->i_gid = dir->i_gid; - inode->i_mode &= S_ISGID; - } - gang = alloc_spu_gang(); - SPUFS_I(inode)->i_ctx = NULL; - SPUFS_I(inode)->i_gang = gang; - if (!gang) - goto out_iput; - - inode->i_op = &spufs_dir_inode_operations; - inode->i_fop = &simple_dir_operations; - - d_instantiate(dentry, inode); - dget(dentry); - dir->i_nlink++; - dentry->d_inode->i_nlink++; - return ret; - -out_iput: - iput(inode); -out: - return ret; -} - -static int spufs_gang_open(struct dentry *dentry, struct vfsmount *mnt) -{ - int ret; - struct file *filp; - - ret = get_unused_fd(); - if (ret < 0) { - dput(dentry); - mntput(mnt); - goto out; - } - - filp = dentry_open(dentry, mnt, O_RDONLY); - if (IS_ERR(filp)) { - put_unused_fd(ret); - ret = PTR_ERR(filp); - goto out; - } - - filp->f_op = &spufs_gang_fops; - fd_install(ret, filp); -out: - return ret; -} - -static int spufs_create_gang(struct inode *inode, - struct dentry *dentry, - struct vfsmount *mnt, int mode) -{ - int ret; - - ret = spufs_mkgang(inode, dentry, mode & S_IRWXUGO); - if (ret) - goto out; - - /* - * get references for dget and mntget, will be released - * in error path of *_open(). - */ - ret = spufs_gang_open(dget(dentry), mntget(mnt)); - if (ret < 0) - WARN_ON(spufs_rmgang(inode, dentry)); - -out: - mutex_unlock(&inode->i_mutex); - dput(dentry); - return ret; -} - - static struct file_system_type spufs_type; -long spufs_create(struct nameidata *nd, unsigned int flags, mode_t mode) +long spufs_create_thread(struct nameidata *nd, + unsigned int flags, mode_t mode) { struct dentry *dentry; int ret; + /* need to be at the root of spufs */ ret = -EINVAL; - /* check if we are on spufs */ - if (nd->dentry->d_sb->s_type != &spufs_type) + if (nd->dentry->d_sb->s_type != &spufs_type || + nd->dentry != nd->dentry->d_sb->s_root) goto out; - /* don't accept undefined flags */ - if (flags & (~SPU_CREATE_FLAG_ALL)) + /* all flags are reserved */ + if (flags) goto out; - /* only threads can be underneath a gang */ - if (nd->dentry != nd->dentry->d_sb->s_root) { - if ((flags & SPU_CREATE_GANG) || - !SPUFS_I(nd->dentry->d_inode)->i_gang) - goto out; - } - dentry = lookup_create(nd, 1); ret = PTR_ERR(dentry); if (IS_ERR(dentry)) @@ -482,13 +317,22 @@ long spufs_create(struct nameidata *nd, unsigned int flags, mode_t mode) goto out_dput; mode &= ~current->fs->umask; + ret = spufs_mkdir(nd->dentry->d_inode, dentry, mode & S_IRWXUGO); + if (ret) + goto out_dput; - if (flags & SPU_CREATE_GANG) - return spufs_create_gang(nd->dentry->d_inode, - dentry, nd->mnt, mode); - else - return spufs_create_context(nd->dentry->d_inode, - dentry, nd->mnt, flags, mode); + /* + * get references for dget and mntget, will be released + * in error path of *_open(). + */ + ret = spufs_context_open(dget(dentry), mntget(nd->mnt)); + if (ret < 0) { + WARN_ON(spufs_rmdir(nd->dentry->d_inode, dentry)); + mutex_unlock(&nd->dentry->d_inode->i_mutex); + spu_forget(SPUFS_I(dentry->d_inode)->i_ctx); + dput(dentry); + goto out; + } out_dput: dput(dentry); diff --git a/trunk/arch/powerpc/platforms/cell/spufs/run.c b/trunk/arch/powerpc/platforms/cell/spufs/run.c index 63df8cf4ba16..483c8b76232c 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/run.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/run.c @@ -14,26 +14,6 @@ void spufs_stop_callback(struct spu *spu) wake_up_all(&ctx->stop_wq); } -void spufs_dma_callback(struct spu *spu, int type) -{ - struct spu_context *ctx = spu->ctx; - - if (ctx->flags & SPU_CREATE_EVENTS_ENABLED) { - ctx->event_return |= type; - wake_up_all(&ctx->stop_wq); - } else { - switch (type) { - case SPE_EVENT_DMA_ALIGNMENT: - case SPE_EVENT_INVALID_DMA: - force_sig(SIGBUS, /* info, */ current); - break; - case SPE_EVENT_SPE_ERROR: - force_sig(SIGILL, /* info */ current); - break; - } - } -} - static inline int spu_stopped(struct spu_context *ctx, u32 * stat) { struct spu *spu; @@ -48,7 +28,8 @@ static inline int spu_stopped(struct spu_context *ctx, u32 * stat) return (!(*stat & 0x1) || pte_fault || spu->class_0_pending) ? 1 : 0; } -static inline int spu_run_init(struct spu_context *ctx, u32 * npc) +static inline int spu_run_init(struct spu_context *ctx, u32 * npc, + u32 * status) { int ret; @@ -91,7 +72,7 @@ static inline int spu_reacquire_runnable(struct spu_context *ctx, u32 *npc, SPU_STATUS_STOPPED_BY_HALT)) { return *status; } - if ((ret = spu_run_init(ctx, npc)) != 0) + if ((ret = spu_run_init(ctx, npc, status)) != 0) return ret; return 0; } @@ -196,49 +177,46 @@ static inline int spu_process_events(struct spu_context *ctx) } long spufs_run_spu(struct file *file, struct spu_context *ctx, - u32 *npc, u32 *event) + u32 * npc, u32 * status) { int ret; - u32 status; if (down_interruptible(&ctx->run_sema)) return -ERESTARTSYS; - ctx->event_return = 0; - ret = spu_run_init(ctx, npc); + ret = spu_run_init(ctx, npc, status); if (ret) goto out; do { - ret = spufs_wait(ctx->stop_wq, spu_stopped(ctx, &status)); + ret = spufs_wait(ctx->stop_wq, spu_stopped(ctx, status)); if (unlikely(ret)) break; - if ((status & SPU_STATUS_STOPPED_BY_STOP) && - (status >> SPU_STOP_STATUS_SHIFT == 0x2104)) { + if ((*status & SPU_STATUS_STOPPED_BY_STOP) && + (*status >> SPU_STOP_STATUS_SHIFT == 0x2104)) { ret = spu_process_callback(ctx); if (ret) break; - status &= ~SPU_STATUS_STOPPED_BY_STOP; + *status &= ~SPU_STATUS_STOPPED_BY_STOP; } if (unlikely(ctx->state != SPU_STATE_RUNNABLE)) { - ret = spu_reacquire_runnable(ctx, npc, &status); + ret = spu_reacquire_runnable(ctx, npc, status); if (ret) goto out; continue; } ret = spu_process_events(ctx); - } while (!ret && !(status & (SPU_STATUS_STOPPED_BY_STOP | + } while (!ret && !(*status & (SPU_STATUS_STOPPED_BY_STOP | SPU_STATUS_STOPPED_BY_HALT))); ctx->ops->runcntl_stop(ctx); - ret = spu_run_fini(ctx, npc, &status); + ret = spu_run_fini(ctx, npc, status); if (!ret) - ret = status; + ret = *status; spu_yield(ctx); out: - *event = ctx->event_return; up(&ctx->run_sema); return ret; } diff --git a/trunk/arch/powerpc/platforms/cell/spufs/sched.c b/trunk/arch/powerpc/platforms/cell/spufs/sched.c index bd6fe4b7a84b..1350294484b6 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/sched.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/sched.c @@ -3,7 +3,11 @@ * Copyright (C) IBM 2005 * Author: Mark Nutter * - * 2006-03-31 NUMA domains added. + * SPU scheduler, based on Linux thread priority. For now use + * a simple "cooperative" yield model with no preemption. SPU + * scheduling will eventually be preemptive: When a thread with + * a higher static priority gets ready to run, then an active SPU + * context will be preempted and returned to the waitq. * * 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 @@ -33,9 +37,6 @@ #include #include #include -#include -#include -#include #include #include @@ -48,59 +49,128 @@ #define SPU_BITMAP_SIZE (((MAX_PRIO+BITS_PER_LONG)/BITS_PER_LONG)+1) struct spu_prio_array { + atomic_t nr_blocked; unsigned long bitmap[SPU_BITMAP_SIZE]; wait_queue_head_t waitq[MAX_PRIO]; - struct list_head active_list[MAX_NUMNODES]; - struct mutex active_mutex[MAX_NUMNODES]; }; -static struct spu_prio_array *spu_prio; +/* spu_runqueue - This is the main runqueue data structure for SPUs. */ +struct spu_runqueue { + struct semaphore sem; + unsigned long nr_active; + unsigned long nr_idle; + unsigned long nr_switches; + struct list_head active_list; + struct list_head idle_list; + struct spu_prio_array prio; +}; + +static struct spu_runqueue *spu_runqueues = NULL; -static inline int node_allowed(int node) +static inline struct spu_runqueue *spu_rq(void) { - cpumask_t mask; + /* Future: make this a per-NODE array, + * and use cpu_to_node(smp_processor_id()) + */ + return spu_runqueues; +} - if (!nr_cpus_node(node)) - return 0; - mask = node_to_cpumask(node); - if (!cpus_intersects(mask, current->cpus_allowed)) - return 0; - return 1; +static inline struct spu *del_idle(struct spu_runqueue *rq) +{ + struct spu *spu; + + BUG_ON(rq->nr_idle <= 0); + BUG_ON(list_empty(&rq->idle_list)); + /* Future: Move SPU out of low-power SRI state. */ + spu = list_entry(rq->idle_list.next, struct spu, sched_list); + list_del_init(&spu->sched_list); + rq->nr_idle--; + return spu; } -static inline void mm_needs_global_tlbie(struct mm_struct *mm) +static inline void del_active(struct spu_runqueue *rq, struct spu *spu) { - int nr = (NR_CPUS > 1) ? NR_CPUS : NR_CPUS + 1; + BUG_ON(rq->nr_active <= 0); + BUG_ON(list_empty(&rq->active_list)); + list_del_init(&spu->sched_list); + rq->nr_active--; +} - /* Global TLBIE broadcast required with SPEs. */ - __cpus_setall(&mm->cpu_vm_mask, nr); +static inline void add_idle(struct spu_runqueue *rq, struct spu *spu) +{ + /* Future: Put SPU into low-power SRI state. */ + list_add_tail(&spu->sched_list, &rq->idle_list); + rq->nr_idle++; } -static BLOCKING_NOTIFIER_HEAD(spu_switch_notifier); +static inline void add_active(struct spu_runqueue *rq, struct spu *spu) +{ + rq->nr_active++; + rq->nr_switches++; + list_add_tail(&spu->sched_list, &rq->active_list); +} -static void spu_switch_notify(struct spu *spu, struct spu_context *ctx) +static void prio_wakeup(struct spu_runqueue *rq) { - blocking_notifier_call_chain(&spu_switch_notifier, - ctx ? ctx->object_id : 0, spu); + if (atomic_read(&rq->prio.nr_blocked) && rq->nr_idle) { + int best = sched_find_first_bit(rq->prio.bitmap); + if (best < MAX_PRIO) { + wait_queue_head_t *wq = &rq->prio.waitq[best]; + wake_up_interruptible_nr(wq, 1); + } + } } -int spu_switch_event_register(struct notifier_block * n) +static void prio_wait(struct spu_runqueue *rq, struct spu_context *ctx, + u64 flags) { - return blocking_notifier_chain_register(&spu_switch_notifier, n); + int prio = current->prio; + wait_queue_head_t *wq = &rq->prio.waitq[prio]; + DEFINE_WAIT(wait); + + __set_bit(prio, rq->prio.bitmap); + atomic_inc(&rq->prio.nr_blocked); + prepare_to_wait_exclusive(wq, &wait, TASK_INTERRUPTIBLE); + if (!signal_pending(current)) { + up(&rq->sem); + up_write(&ctx->state_sema); + pr_debug("%s: pid=%d prio=%d\n", __FUNCTION__, + current->pid, current->prio); + schedule(); + down_write(&ctx->state_sema); + down(&rq->sem); + } + finish_wait(wq, &wait); + atomic_dec(&rq->prio.nr_blocked); + if (!waitqueue_active(wq)) + __clear_bit(prio, rq->prio.bitmap); } -int spu_switch_event_unregister(struct notifier_block * n) +static inline int is_best_prio(struct spu_runqueue *rq) { - return blocking_notifier_chain_unregister(&spu_switch_notifier, n); + int best_prio; + + best_prio = sched_find_first_bit(rq->prio.bitmap); + return (current->prio < best_prio) ? 1 : 0; } +static inline void mm_needs_global_tlbie(struct mm_struct *mm) +{ + /* Global TLBIE broadcast required with SPEs. */ +#if (NR_CPUS > 1) + __cpus_setall(&mm->cpu_vm_mask, NR_CPUS); +#else + __cpus_setall(&mm->cpu_vm_mask, NR_CPUS+1); /* is this ok? */ +#endif +} static inline void bind_context(struct spu *spu, struct spu_context *ctx) { - pr_debug("%s: pid=%d SPU=%d NODE=%d\n", __FUNCTION__, current->pid, - spu->number, spu->node); + pr_debug("%s: pid=%d SPU=%d\n", __FUNCTION__, current->pid, + spu->number); spu->ctx = ctx; spu->flags = 0; + ctx->flags = 0; ctx->spu = spu; ctx->ops = &spu_hw_ops; spu->pid = current->pid; @@ -111,20 +181,16 @@ static inline void bind_context(struct spu *spu, struct spu_context *ctx) spu->wbox_callback = spufs_wbox_callback; spu->stop_callback = spufs_stop_callback; spu->mfc_callback = spufs_mfc_callback; - spu->dma_callback = spufs_dma_callback; mb(); spu_unmap_mappings(ctx); spu_restore(&ctx->csa, spu); spu->timestamp = jiffies; - spu_cpu_affinity_set(spu, raw_smp_processor_id()); - spu_switch_notify(spu, ctx); } static inline void unbind_context(struct spu *spu, struct spu_context *ctx) { - pr_debug("%s: unbind pid=%d SPU=%d NODE=%d\n", __FUNCTION__, - spu->pid, spu->number, spu->node); - spu_switch_notify(spu, NULL); + pr_debug("%s: unbind pid=%d SPU=%d\n", __FUNCTION__, + spu->pid, spu->number); spu_unmap_mappings(ctx); spu_save(&ctx->csa, spu); spu->timestamp = jiffies; @@ -133,158 +199,173 @@ static inline void unbind_context(struct spu *spu, struct spu_context *ctx) spu->wbox_callback = NULL; spu->stop_callback = NULL; spu->mfc_callback = NULL; - spu->dma_callback = NULL; spu->mm = NULL; spu->pid = 0; spu->prio = MAX_PRIO; ctx->ops = &spu_backing_ops; ctx->spu = NULL; + ctx->flags = 0; spu->flags = 0; spu->ctx = NULL; } -static inline void spu_add_wq(wait_queue_head_t * wq, wait_queue_t * wait, - int prio) +static void spu_reaper(void *data) { - prepare_to_wait_exclusive(wq, wait, TASK_INTERRUPTIBLE); - set_bit(prio, spu_prio->bitmap); + struct spu_context *ctx = data; + struct spu *spu; + + down_write(&ctx->state_sema); + spu = ctx->spu; + if (spu && test_bit(SPU_CONTEXT_PREEMPT, &ctx->flags)) { + if (atomic_read(&spu->rq->prio.nr_blocked)) { + pr_debug("%s: spu=%d\n", __func__, spu->number); + ctx->ops->runcntl_stop(ctx); + spu_deactivate(ctx); + wake_up_all(&ctx->stop_wq); + } else { + clear_bit(SPU_CONTEXT_PREEMPT, &ctx->flags); + } + } + up_write(&ctx->state_sema); + put_spu_context(ctx); } -static inline void spu_del_wq(wait_queue_head_t * wq, wait_queue_t * wait, - int prio) +static void schedule_spu_reaper(struct spu_runqueue *rq, struct spu *spu) { - u64 flags; - - __set_current_state(TASK_RUNNING); - - spin_lock_irqsave(&wq->lock, flags); - - remove_wait_queue_locked(wq, wait); - if (list_empty(&wq->task_list)) - clear_bit(prio, spu_prio->bitmap); - - spin_unlock_irqrestore(&wq->lock, flags); + struct spu_context *ctx = get_spu_context(spu->ctx); + unsigned long now = jiffies; + unsigned long expire = spu->timestamp + SPU_MIN_TIMESLICE; + + set_bit(SPU_CONTEXT_PREEMPT, &ctx->flags); + INIT_WORK(&ctx->reap_work, spu_reaper, ctx); + if (time_after(now, expire)) + schedule_work(&ctx->reap_work); + else + schedule_delayed_work(&ctx->reap_work, expire - now); } -static void spu_prio_wait(struct spu_context *ctx, u64 flags) +static void check_preempt_active(struct spu_runqueue *rq) { - int prio = current->prio; - wait_queue_head_t *wq = &spu_prio->waitq[prio]; - DEFINE_WAIT(wait); - - if (ctx->spu) - return; + struct list_head *p; + struct spu *worst = NULL; + + list_for_each(p, &rq->active_list) { + struct spu *spu = list_entry(p, struct spu, sched_list); + struct spu_context *ctx = spu->ctx; + if (!test_bit(SPU_CONTEXT_PREEMPT, &ctx->flags)) { + if (!worst || (spu->prio > worst->prio)) { + worst = spu; + } + } + } + if (worst && (current->prio < worst->prio)) + schedule_spu_reaper(rq, worst); +} - spu_add_wq(wq, &wait, prio); +static struct spu *get_idle_spu(struct spu_context *ctx, u64 flags) +{ + struct spu_runqueue *rq; + struct spu *spu = NULL; - if (!signal_pending(current)) { - up_write(&ctx->state_sema); - pr_debug("%s: pid=%d prio=%d\n", __FUNCTION__, - current->pid, current->prio); - schedule(); - down_write(&ctx->state_sema); + rq = spu_rq(); + down(&rq->sem); + for (;;) { + if (rq->nr_idle > 0) { + if (is_best_prio(rq)) { + /* Fall through. */ + spu = del_idle(rq); + break; + } else { + prio_wakeup(rq); + up(&rq->sem); + yield(); + if (signal_pending(current)) { + return NULL; + } + rq = spu_rq(); + down(&rq->sem); + continue; + } + } else { + check_preempt_active(rq); + prio_wait(rq, ctx, flags); + if (signal_pending(current)) { + prio_wakeup(rq); + spu = NULL; + break; + } + continue; + } } - - spu_del_wq(wq, &wait, prio); + up(&rq->sem); + return spu; } -static void spu_prio_wakeup(void) +static void put_idle_spu(struct spu *spu) { - int best = sched_find_first_bit(spu_prio->bitmap); - if (best < MAX_PRIO) { - wait_queue_head_t *wq = &spu_prio->waitq[best]; - wake_up_interruptible_nr(wq, 1); - } + struct spu_runqueue *rq = spu->rq; + + down(&rq->sem); + add_idle(rq, spu); + prio_wakeup(rq); + up(&rq->sem); } static int get_active_spu(struct spu *spu) { - int node = spu->node; + struct spu_runqueue *rq = spu->rq; + struct list_head *p; struct spu *tmp; int rc = 0; - mutex_lock(&spu_prio->active_mutex[node]); - list_for_each_entry(tmp, &spu_prio->active_list[node], list) { + down(&rq->sem); + list_for_each(p, &rq->active_list) { + tmp = list_entry(p, struct spu, sched_list); if (tmp == spu) { - list_del_init(&spu->list); + del_active(rq, spu); rc = 1; break; } } - mutex_unlock(&spu_prio->active_mutex[node]); + up(&rq->sem); return rc; } static void put_active_spu(struct spu *spu) { - int node = spu->node; - - mutex_lock(&spu_prio->active_mutex[node]); - list_add_tail(&spu->list, &spu_prio->active_list[node]); - mutex_unlock(&spu_prio->active_mutex[node]); -} - -static struct spu *spu_get_idle(struct spu_context *ctx, u64 flags) -{ - struct spu *spu = NULL; - int node = cpu_to_node(raw_smp_processor_id()); - int n; + struct spu_runqueue *rq = spu->rq; - for (n = 0; n < MAX_NUMNODES; n++, node++) { - node = (node < MAX_NUMNODES) ? node : 0; - if (!node_allowed(node)) - continue; - spu = spu_alloc_node(node); - if (spu) - break; - } - return spu; + down(&rq->sem); + add_active(rq, spu); + up(&rq->sem); } -static inline struct spu *spu_get(struct spu_context *ctx, u64 flags) -{ - /* Future: spu_get_idle() if possible, - * otherwise try to preempt an active - * context. - */ - return spu_get_idle(ctx, flags); -} - -/* The three externally callable interfaces - * for the scheduler begin here. +/* Lock order: + * spu_activate() & spu_deactivate() require the + * caller to have down_write(&ctx->state_sema). * - * spu_activate - bind a context to SPU, waiting as needed. - * spu_deactivate - unbind a context from its SPU. - * spu_yield - yield an SPU if others are waiting. + * The rq->sem is breifly held (inside or outside a + * given ctx lock) for list management, but is never + * held during save/restore. */ int spu_activate(struct spu_context *ctx, u64 flags) { struct spu *spu; - int ret = 0; - for (;;) { - if (ctx->spu) - return 0; - spu = spu_get(ctx, flags); - if (spu != NULL) { - if (ctx->spu != NULL) { - spu_free(spu); - spu_prio_wakeup(); - break; - } - bind_context(spu, ctx); - put_active_spu(spu); - break; - } - spu_prio_wait(ctx, flags); - if (signal_pending(current)) { - ret = -ERESTARTSYS; - spu_prio_wakeup(); - break; - } - } - return ret; + if (ctx->spu) + return 0; + spu = get_idle_spu(ctx, flags); + if (!spu) + return (signal_pending(current)) ? -ERESTARTSYS : -EAGAIN; + bind_context(spu, ctx); + /* + * We're likely to wait for interrupts on the same + * CPU that we are now on, so send them here. + */ + spu_cpu_affinity_set(spu, raw_smp_processor_id()); + put_active_spu(spu); + return 0; } void spu_deactivate(struct spu_context *ctx) @@ -297,10 +378,8 @@ void spu_deactivate(struct spu_context *ctx) return; needs_idle = get_active_spu(spu); unbind_context(spu, ctx); - if (needs_idle) { - spu_free(spu); - spu_prio_wakeup(); - } + if (needs_idle) + put_idle_spu(spu); } void spu_yield(struct spu_context *ctx) @@ -308,60 +387,77 @@ void spu_yield(struct spu_context *ctx) struct spu *spu; int need_yield = 0; - if (down_write_trylock(&ctx->state_sema)) { - if ((spu = ctx->spu) != NULL) { - int best = sched_find_first_bit(spu_prio->bitmap); - if (best < MAX_PRIO) { - pr_debug("%s: yielding SPU %d NODE %d\n", - __FUNCTION__, spu->number, spu->node); - spu_deactivate(ctx); - ctx->state = SPU_STATE_SAVED; - need_yield = 1; - } else { - spu->prio = MAX_PRIO; - } - } - up_write(&ctx->state_sema); + down_write(&ctx->state_sema); + spu = ctx->spu; + if (spu && (sched_find_first_bit(spu->rq->prio.bitmap) < MAX_PRIO)) { + pr_debug("%s: yielding SPU %d\n", __FUNCTION__, spu->number); + spu_deactivate(ctx); + ctx->state = SPU_STATE_SAVED; + need_yield = 1; + } else if (spu) { + spu->prio = MAX_PRIO; } + up_write(&ctx->state_sema); if (unlikely(need_yield)) yield(); } int __init spu_sched_init(void) { + struct spu_runqueue *rq; + struct spu *spu; int i; - spu_prio = kzalloc(sizeof(struct spu_prio_array), GFP_KERNEL); - if (!spu_prio) { - printk(KERN_WARNING "%s: Unable to allocate priority queue.\n", + rq = spu_runqueues = kmalloc(sizeof(struct spu_runqueue), GFP_KERNEL); + if (!rq) { + printk(KERN_WARNING "%s: Unable to allocate runqueues.\n", __FUNCTION__); return 1; } + memset(rq, 0, sizeof(struct spu_runqueue)); + init_MUTEX(&rq->sem); + INIT_LIST_HEAD(&rq->active_list); + INIT_LIST_HEAD(&rq->idle_list); + rq->nr_active = 0; + rq->nr_idle = 0; + rq->nr_switches = 0; + atomic_set(&rq->prio.nr_blocked, 0); for (i = 0; i < MAX_PRIO; i++) { - init_waitqueue_head(&spu_prio->waitq[i]); - __clear_bit(i, spu_prio->bitmap); + init_waitqueue_head(&rq->prio.waitq[i]); + __clear_bit(i, rq->prio.bitmap); } - __set_bit(MAX_PRIO, spu_prio->bitmap); - for (i = 0; i < MAX_NUMNODES; i++) { - mutex_init(&spu_prio->active_mutex[i]); - INIT_LIST_HEAD(&spu_prio->active_list[i]); + __set_bit(MAX_PRIO, rq->prio.bitmap); + for (;;) { + spu = spu_alloc(); + if (!spu) + break; + pr_debug("%s: adding SPU[%d]\n", __FUNCTION__, spu->number); + add_idle(rq, spu); + spu->rq = rq; + spu->timestamp = jiffies; + } + if (!rq->nr_idle) { + printk(KERN_WARNING "%s: No available SPUs.\n", __FUNCTION__); + kfree(rq); + return 1; } return 0; } void __exit spu_sched_exit(void) { - struct spu *spu, *tmp; - int node; - - for (node = 0; node < MAX_NUMNODES; node++) { - mutex_lock(&spu_prio->active_mutex[node]); - list_for_each_entry_safe(spu, tmp, &spu_prio->active_list[node], - list) { - list_del_init(&spu->list); - spu_free(spu); - } - mutex_unlock(&spu_prio->active_mutex[node]); + struct spu_runqueue *rq = spu_rq(); + struct spu *spu; + + if (!rq) { + printk(KERN_WARNING "%s: no runqueues!\n", __FUNCTION__); + return; + } + while (rq->nr_idle > 0) { + spu = del_idle(rq); + if (!spu) + break; + spu_free(spu); } - kfree(spu_prio); + kfree(rq); } diff --git a/trunk/arch/powerpc/platforms/cell/spufs/spufs.h b/trunk/arch/powerpc/platforms/cell/spufs/spufs.h index a0f55ca2d488..4485738e2102 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/spufs.h +++ b/trunk/arch/powerpc/platforms/cell/spufs/spufs.h @@ -39,8 +39,6 @@ struct spu_context_ops; #define SPU_CONTEXT_PREEMPT 0UL -struct spu_gang; - struct spu_context { struct spu *spu; /* pointer to a physical SPU */ struct spu_state csa; /* SPU context save area. */ @@ -50,7 +48,6 @@ struct spu_context { struct address_space *cntl; /* 'control' area mappings. */ struct address_space *signal1; /* 'signal1' area mappings. */ struct address_space *signal2; /* 'signal2' area mappings. */ - u64 object_id; /* user space pointer for oprofile */ enum { SPU_STATE_RUNNABLE, SPU_STATE_SAVED } state; struct rw_semaphore state_sema; @@ -69,18 +66,7 @@ struct spu_context { u32 tagwait; struct spu_context_ops *ops; struct work_struct reap_work; - unsigned long flags; - unsigned long event_return; - - struct list_head gang_list; - struct spu_gang *gang; -}; - -struct spu_gang { - struct list_head list; - struct mutex mutex; - struct kref kref; - int contexts; + u64 flags; }; struct mfc_dma_command { @@ -128,7 +114,6 @@ extern struct spu_context_ops spu_backing_ops; struct spufs_inode_info { struct spu_context *i_ctx; - struct spu_gang *i_gang; struct inode vfs_inode; }; #define SPUFS_I(inode) \ @@ -139,19 +124,12 @@ extern struct tree_descr spufs_dir_contents[]; /* system call implementation */ long spufs_run_spu(struct file *file, struct spu_context *ctx, u32 *npc, u32 *status); -long spufs_create(struct nameidata *nd, +long spufs_create_thread(struct nameidata *nd, unsigned int flags, mode_t mode); extern struct file_operations spufs_context_fops; -/* gang management */ -struct spu_gang *alloc_spu_gang(void); -struct spu_gang *get_spu_gang(struct spu_gang *gang); -int put_spu_gang(struct spu_gang *gang); -void spu_gang_remove_ctx(struct spu_gang *gang, struct spu_context *ctx); -void spu_gang_add_ctx(struct spu_gang *gang, struct spu_context *ctx); - /* context management */ -struct spu_context * alloc_spu_context(struct spu_gang *gang); +struct spu_context * alloc_spu_context(void); void destroy_spu_context(struct kref *kref); struct spu_context * get_spu_context(struct spu_context *ctx); int put_spu_context(struct spu_context *ctx); @@ -205,6 +183,5 @@ void spufs_ibox_callback(struct spu *spu); void spufs_wbox_callback(struct spu *spu); void spufs_stop_callback(struct spu *spu); void spufs_mfc_callback(struct spu *spu); -void spufs_dma_callback(struct spu *spu, int type); #endif diff --git a/trunk/arch/powerpc/platforms/cell/spufs/switch.c b/trunk/arch/powerpc/platforms/cell/spufs/switch.c index 0f782ca662ba..9d9d82dd32ba 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/switch.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/switch.c @@ -1779,15 +1779,6 @@ static inline void restore_mfc_cntl(struct spu_state *csa, struct spu *spu) */ out_be64(&priv2->mfc_control_RW, csa->priv2.mfc_control_RW); eieio(); - /* - * FIXME: this is to restart a DMA that we were processing - * before the save. better remember the fault information - * in the csa instead. - */ - if ((csa->priv2.mfc_control_RW & MFC_CNTL_SUSPEND_DMA_QUEUE_MASK)) { - out_be64(&priv2->mfc_control_RW, MFC_CNTL_RESTART_DMA_COMMAND); - eieio(); - } } static inline void enable_user_access(struct spu_state *csa, struct spu *spu) diff --git a/trunk/arch/powerpc/platforms/cell/spufs/syscalls.c b/trunk/arch/powerpc/platforms/cell/spufs/syscalls.c index a6d1ae4dc2a3..e6565a949ddc 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/syscalls.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/syscalls.c @@ -38,7 +38,7 @@ static long do_spu_run(struct file *filp, u32 npc, status; ret = -EFAULT; - if (get_user(npc, unpc)) + if (get_user(npc, unpc) || get_user(status, ustatus)) goto out; /* check if this file was created by spu_create */ @@ -49,10 +49,7 @@ static long do_spu_run(struct file *filp, i = SPUFS_I(filp->f_dentry->d_inode); ret = spufs_run_spu(filp, i->i_ctx, &npc, &status); - if (put_user(npc, unpc)) - ret = -EFAULT; - - if (ustatus && put_user(status, ustatus)) + if (put_user(npc, unpc) || put_user(status, ustatus)) ret = -EFAULT; out: return ret; @@ -90,7 +87,7 @@ asmlinkage long sys_spu_create(const char __user *pathname, ret = path_lookup(tmp, LOOKUP_PARENT| LOOKUP_OPEN|LOOKUP_CREATE, &nd); if (!ret) { - ret = spufs_create(&nd, flags, mode); + ret = spufs_create_thread(&nd, flags, mode); path_release(&nd); } putname(tmp); diff --git a/trunk/arch/powerpc/platforms/chrp/setup.c b/trunk/arch/powerpc/platforms/chrp/setup.c index 49b8dabcbc99..488dbd9b51ae 100644 --- a/trunk/arch/powerpc/platforms/chrp/setup.c +++ b/trunk/arch/powerpc/platforms/chrp/setup.c @@ -70,7 +70,7 @@ unsigned long event_scan_interval; * has to include (to get irqreturn_t), which * causes all sorts of problems. -- paulus */ -extern irqreturn_t xmon_irq(int, void *); +extern irqreturn_t xmon_irq(int, void *, struct pt_regs *); extern unsigned long loops_per_jiffy; @@ -335,11 +335,12 @@ chrp_event_scan(unsigned long unused) jiffies + event_scan_interval); } -static void chrp_8259_cascade(unsigned int irq, struct irq_desc *desc) +static void chrp_8259_cascade(unsigned int irq, struct irq_desc *desc, + struct pt_regs *regs) { - unsigned int cascade_irq = i8259_irq(); + unsigned int cascade_irq = i8259_irq(regs); if (cascade_irq != NO_IRQ) - generic_handle_irq(cascade_irq); + generic_handle_irq(cascade_irq, regs); desc->chip->eoi(irq); } @@ -477,10 +478,8 @@ static void __init chrp_find_8259(void) " address, polling\n"); i8259_init(pic, chrp_int_ack); - if (ppc_md.get_irq == NULL) { + if (ppc_md.get_irq == NULL) ppc_md.get_irq = i8259_irq; - irq_set_default_host(i8259_get_host()); - } if (chrp_mpic != NULL) { cascade_irq = irq_of_parse_and_map(pic, 0); if (cascade_irq == NO_IRQ) diff --git a/trunk/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c b/trunk/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c index bdb475c65cba..cb6f084844f2 100644 --- a/trunk/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c +++ b/trunk/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c @@ -61,7 +61,8 @@ pci_dram_offset = MPC7448_HPC2_PCI_MEM_OFFSET; extern int tsi108_setup_pci(struct device_node *dev); extern void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val); extern void tsi108_pci_int_init(void); -extern void tsi108_irq_cascade(unsigned int irq, struct irq_desc *desc); +extern void tsi108_irq_cascade(unsigned int irq, struct irq_desc *desc, + struct pt_regs *regs); int mpc7448_hpc2_exclude_device(u_char bus, u_char devfn) { @@ -199,7 +200,7 @@ static void __init mpc7448_hpc2_init_IRQ(void) tsi_pic = of_find_node_by_type(NULL, "open-pic"); if (tsi_pic) { unsigned int size; - const void *prop = get_property(tsi_pic, "reg", &size); + void *prop = get_property(tsi_pic, "reg", &size); mpic_paddr = of_translate_address(tsi_pic, prop); } diff --git a/trunk/arch/powerpc/platforms/iseries/iommu.c b/trunk/arch/powerpc/platforms/iseries/iommu.c index 218817d13c5c..f4cbbcf8773a 100644 --- a/trunk/arch/powerpc/platforms/iseries/iommu.c +++ b/trunk/arch/powerpc/platforms/iseries/iommu.c @@ -43,6 +43,9 @@ static void tce_build_iSeries(struct iommu_table *tbl, long index, long npages, u64 rc; u64 tce, rpn; + index <<= TCE_PAGE_FACTOR; + npages <<= TCE_PAGE_FACTOR; + while (npages--) { rpn = virt_to_abs(uaddr) >> TCE_SHIFT; tce = (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT; @@ -72,6 +75,9 @@ static void tce_free_iSeries(struct iommu_table *tbl, long index, long npages) { u64 rc; + npages <<= TCE_PAGE_FACTOR; + index <<= TCE_PAGE_FACTOR; + while (npages--) { rc = HvCallXm_setTce((u64)tbl->it_index, (u64)index, 0); if (rc) @@ -130,9 +136,10 @@ void iommu_table_getparms_iSeries(unsigned long busno, panic("PCI_DMA: parms->size is zero, parms is 0x%p", parms); /* itc_size is in pages worth of table, it_size is in # of entries */ - tbl->it_size = (parms->itc_size * TCE_PAGE_SIZE) / TCE_ENTRY_SIZE; + tbl->it_size = ((parms->itc_size * TCE_PAGE_SIZE) / + TCE_ENTRY_SIZE) >> TCE_PAGE_FACTOR; tbl->it_busno = parms->itc_busno; - tbl->it_offset = parms->itc_offset; + tbl->it_offset = parms->itc_offset >> TCE_PAGE_FACTOR; tbl->it_index = parms->itc_index; tbl->it_blocksize = 1; tbl->it_type = virtbus ? TCE_VB : TCE_PCI; diff --git a/trunk/arch/powerpc/platforms/iseries/irq.c b/trunk/arch/powerpc/platforms/iseries/irq.c index 5225abfafd9b..e32446877e78 100644 --- a/trunk/arch/powerpc/platforms/iseries/irq.c +++ b/trunk/arch/powerpc/platforms/iseries/irq.c @@ -43,7 +43,10 @@ #include "irq.h" #include "pci.h" #include "call_pci.h" -#include "smp.h" + +#if defined(CONFIG_SMP) +extern void iSeries_smp_message_recv(struct pt_regs *); +#endif #ifdef CONFIG_PCI @@ -85,7 +88,7 @@ static DEFINE_SPINLOCK(pending_irqs_lock); static int num_pending_irqs; static int pending_irqs[NR_IRQS]; -static void int_received(struct pci_event *event) +static void int_received(struct pci_event *event, struct pt_regs *regs) { int irq; @@ -143,11 +146,11 @@ static void int_received(struct pci_event *event) } } -static void pci_event_handler(struct HvLpEvent *event) +static void pci_event_handler(struct HvLpEvent *event, struct pt_regs *regs) { if (event && (event->xType == HvLpEvent_Type_PciIo)) { if (hvlpevent_is_int(event)) - int_received((struct pci_event *)event); + int_received((struct pci_event *)event, regs); else printk(KERN_ERR "pci_event_handler: unexpected ack received\n"); @@ -305,18 +308,18 @@ int __init iSeries_allocate_IRQ(HvBusNumber bus, /* * Get the next pending IRQ. */ -unsigned int iSeries_get_irq(void) +unsigned int iSeries_get_irq(struct pt_regs *regs) { int irq = NO_IRQ_IGNORE; #ifdef CONFIG_SMP if (get_lppaca()->int_dword.fields.ipi_cnt) { get_lppaca()->int_dword.fields.ipi_cnt = 0; - iSeries_smp_message_recv(); + iSeries_smp_message_recv(regs); } #endif /* CONFIG_SMP */ if (hvlpevent_is_pending()) - process_hvlpevents(); + process_hvlpevents(regs); #ifdef CONFIG_PCI if (num_pending_irqs) { diff --git a/trunk/arch/powerpc/platforms/iseries/irq.h b/trunk/arch/powerpc/platforms/iseries/irq.h index 69f1b437fc7b..1ee8985140e5 100644 --- a/trunk/arch/powerpc/platforms/iseries/irq.h +++ b/trunk/arch/powerpc/platforms/iseries/irq.h @@ -4,6 +4,6 @@ extern void iSeries_init_IRQ(void); extern int iSeries_allocate_IRQ(HvBusNumber, HvSubBusNumber, u32); extern void iSeries_activate_IRQs(void); -extern unsigned int iSeries_get_irq(void); +extern unsigned int iSeries_get_irq(struct pt_regs *); #endif /* _ISERIES_IRQ_H */ diff --git a/trunk/arch/powerpc/platforms/iseries/lpevents.c b/trunk/arch/powerpc/platforms/iseries/lpevents.c index e3e929e1b460..98c1c2440aad 100644 --- a/trunk/arch/powerpc/platforms/iseries/lpevents.c +++ b/trunk/arch/powerpc/platforms/iseries/lpevents.c @@ -116,7 +116,7 @@ static void hvlpevent_clear_valid(struct HvLpEvent * event) hvlpevent_invalidate(event); } -void process_hvlpevents(void) +void process_hvlpevents(struct pt_regs *regs) { struct HvLpEvent * event; @@ -144,7 +144,7 @@ void process_hvlpevents(void) __get_cpu_var(hvlpevent_counts)[event->xType]++; if (event->xType < HvLpEvent_Type_NumTypes && lpEventHandler[event->xType]) - lpEventHandler[event->xType](event); + lpEventHandler[event->xType](event, regs); else printk(KERN_INFO "Unexpected Lp Event type=%d\n", event->xType ); diff --git a/trunk/arch/powerpc/platforms/iseries/mf.c b/trunk/arch/powerpc/platforms/iseries/mf.c index b5737d68d6c4..1983b640bac1 100644 --- a/trunk/arch/powerpc/platforms/iseries/mf.c +++ b/trunk/arch/powerpc/platforms/iseries/mf.c @@ -513,7 +513,7 @@ static void handle_ack(struct io_mf_lp_event *event) * parse it enough to know if it is an interrupt or an * acknowledge. */ -static void hv_handler(struct HvLpEvent *event) +static void hv_handler(struct HvLpEvent *event, struct pt_regs *regs) { if ((event != NULL) && (event->xType == HvLpEvent_Type_MachineFac)) { if (hvlpevent_is_ack(event)) @@ -847,7 +847,7 @@ static int mf_get_boot_rtc(struct rtc_time *tm) /* We need to poll here as we are not yet taking interrupts */ while (rtc_data.busy) { if (hvlpevent_is_pending()) - process_hvlpevents(); + process_hvlpevents(NULL); } return rtc_set_tm(rtc_data.rc, rtc_data.ce_msg.ce_msg, tm); } diff --git a/trunk/arch/powerpc/platforms/iseries/setup.c b/trunk/arch/powerpc/platforms/iseries/setup.c index 6f73469fd3b0..a0ff7ba7d666 100644 --- a/trunk/arch/powerpc/platforms/iseries/setup.c +++ b/trunk/arch/powerpc/platforms/iseries/setup.c @@ -694,11 +694,6 @@ void * __init iSeries_early_setup(void) { unsigned long phys_mem_size; - /* Identify CPU type. This is done again by the common code later - * on but calling this function multiple times is fine. - */ - identify_cpu(0); - powerpc_firmware_features |= FW_FEATURE_ISERIES; powerpc_firmware_features |= FW_FEATURE_LPAR; diff --git a/trunk/arch/powerpc/platforms/iseries/smp.c b/trunk/arch/powerpc/platforms/iseries/smp.c index aee5908df700..2eb095edb472 100644 --- a/trunk/arch/powerpc/platforms/iseries/smp.c +++ b/trunk/arch/powerpc/platforms/iseries/smp.c @@ -43,11 +43,9 @@ #include #include -#include "smp.h" - static unsigned long iSeries_smp_message[NR_CPUS]; -void iSeries_smp_message_recv(void) +void iSeries_smp_message_recv(struct pt_regs *regs) { int cpu = smp_processor_id(); int msg; @@ -57,7 +55,7 @@ void iSeries_smp_message_recv(void) for (msg = 0; msg < 4; msg++) if (test_and_clear_bit(msg, &iSeries_smp_message[cpu])) - smp_message_recv(msg); + smp_message_recv(msg, regs); } static inline void smp_iSeries_do_message(int cpu, int msg) diff --git a/trunk/arch/powerpc/platforms/iseries/smp.h b/trunk/arch/powerpc/platforms/iseries/smp.h deleted file mode 100644 index d501f7de01e7..000000000000 --- a/trunk/arch/powerpc/platforms/iseries/smp.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _PLATFORMS_ISERIES_SMP_H -#define _PLATFORMS_ISERIES_SMP_H - -extern void iSeries_smp_message_recv(void); - -#endif /* _PLATFORMS_ISERIES_SMP_H */ diff --git a/trunk/arch/powerpc/platforms/iseries/viopath.c b/trunk/arch/powerpc/platforms/iseries/viopath.c index 04e07e5da0c1..9baa4ee82592 100644 --- a/trunk/arch/powerpc/platforms/iseries/viopath.c +++ b/trunk/arch/powerpc/platforms/iseries/viopath.c @@ -378,7 +378,7 @@ void vio_set_hostlp(void) } EXPORT_SYMBOL(vio_set_hostlp); -static void vio_handleEvent(struct HvLpEvent *event) +static void vio_handleEvent(struct HvLpEvent *event, struct pt_regs *regs) { HvLpIndex remoteLp; int subtype = (event->xSubtype & VIOMAJOR_SUBTYPE_MASK) diff --git a/trunk/arch/powerpc/platforms/maple/pci.c b/trunk/arch/powerpc/platforms/maple/pci.c index 63b4d1bff359..1b827618e05f 100644 --- a/trunk/arch/powerpc/platforms/maple/pci.c +++ b/trunk/arch/powerpc/platforms/maple/pci.c @@ -8,7 +8,7 @@ * 2 of the License, or (at your option) any later version. */ -#undef DEBUG +#define DEBUG #include #include @@ -16,7 +16,6 @@ #include #include #include -#include #include #include @@ -34,7 +33,7 @@ #define DBG(x...) #endif -static struct pci_controller *u3_agp, *u3_ht, *u4_pcie; +static struct pci_controller *u3_agp, *u3_ht; static int __init fixup_one_level_bus_range(struct device_node *node, int higher) { @@ -288,114 +287,6 @@ static struct pci_ops u3_ht_pci_ops = u3_ht_write_config }; -static unsigned int u4_pcie_cfa0(unsigned int devfn, unsigned int off) -{ - return (1 << PCI_SLOT(devfn)) | - (PCI_FUNC(devfn) << 8) | - ((off >> 8) << 28) | - (off & 0xfcu); -} - -static unsigned int u4_pcie_cfa1(unsigned int bus, unsigned int devfn, - unsigned int off) -{ - return (bus << 16) | - (devfn << 8) | - ((off >> 8) << 28) | - (off & 0xfcu) | 1u; -} - -static volatile void __iomem *u4_pcie_cfg_access(struct pci_controller* hose, - u8 bus, u8 dev_fn, int offset) -{ - unsigned int caddr; - - if (bus == hose->first_busno) - caddr = u4_pcie_cfa0(dev_fn, offset); - else - caddr = u4_pcie_cfa1(bus, dev_fn, offset); - - /* Uninorth will return garbage if we don't read back the value ! */ - do { - out_le32(hose->cfg_addr, caddr); - } while (in_le32(hose->cfg_addr) != caddr); - - offset &= 0x03; - return hose->cfg_data + offset; -} - -static int u4_pcie_read_config(struct pci_bus *bus, unsigned int devfn, - int offset, int len, u32 *val) -{ - struct pci_controller *hose; - volatile void __iomem *addr; - - hose = pci_bus_to_host(bus); - if (hose == NULL) - return PCIBIOS_DEVICE_NOT_FOUND; - if (offset >= 0x1000) - return PCIBIOS_BAD_REGISTER_NUMBER; - addr = u4_pcie_cfg_access(hose, bus->number, devfn, offset); - if (!addr) - return PCIBIOS_DEVICE_NOT_FOUND; - /* - * Note: the caller has already checked that offset is - * suitably aligned and that len is 1, 2 or 4. - */ - switch (len) { - case 1: - *val = in_8(addr); - break; - case 2: - *val = in_le16(addr); - break; - default: - *val = in_le32(addr); - break; - } - return PCIBIOS_SUCCESSFUL; -} -static int u4_pcie_write_config(struct pci_bus *bus, unsigned int devfn, - int offset, int len, u32 val) -{ - struct pci_controller *hose; - volatile void __iomem *addr; - - hose = pci_bus_to_host(bus); - if (hose == NULL) - return PCIBIOS_DEVICE_NOT_FOUND; - if (offset >= 0x1000) - return PCIBIOS_BAD_REGISTER_NUMBER; - addr = u4_pcie_cfg_access(hose, bus->number, devfn, offset); - if (!addr) - return PCIBIOS_DEVICE_NOT_FOUND; - /* - * Note: the caller has already checked that offset is - * suitably aligned and that len is 1, 2 or 4. - */ - switch (len) { - case 1: - out_8(addr, val); - (void) in_8(addr); - break; - case 2: - out_le16(addr, val); - (void) in_le16(addr); - break; - default: - out_le32(addr, val); - (void) in_le32(addr); - break; - } - return PCIBIOS_SUCCESSFUL; -} - -static struct pci_ops u4_pcie_pci_ops = -{ - u4_pcie_read_config, - u4_pcie_write_config -}; - static void __init setup_u3_agp(struct pci_controller* hose) { /* On G5, we move AGP up to high bus number so we don't need @@ -416,26 +307,6 @@ static void __init setup_u3_agp(struct pci_controller* hose) u3_agp = hose; } -static void __init setup_u4_pcie(struct pci_controller* hose) -{ - /* We currently only implement the "non-atomic" config space, to - * be optimised later. - */ - hose->ops = &u4_pcie_pci_ops; - hose->cfg_addr = ioremap(0xf0000000 + 0x800000, 0x1000); - hose->cfg_data = ioremap(0xf0000000 + 0xc00000, 0x1000); - - /* The bus contains a bridge from root -> device, we need to - * make it visible on bus 0 so that we pick the right type - * of config cycles. If we didn't, we would have to force all - * config cycles to be type 1. So we override the "bus-range" - * property here - */ - hose->first_busno = 0x00; - hose->last_busno = 0xff; - u4_pcie = hose; -} - static void __init setup_u3_ht(struct pci_controller* hose) { hose->ops = &u3_ht_pci_ops; @@ -483,10 +354,6 @@ static int __init add_bridge(struct device_node *dev) setup_u3_ht(hose); disp_name = "U3-HT"; primary = 1; - } else if (device_is_compatible(dev, "u4-pcie")) { - setup_u4_pcie(hose); - disp_name = "U4-PCIE"; - primary = 0; } printk(KERN_INFO "Found %s PCI host bridge. Firmware bus number: %d->%d\n", disp_name, hose->first_busno, hose->last_busno); @@ -494,6 +361,7 @@ static int __init add_bridge(struct device_node *dev) /* Interpret the "ranges" property */ /* This also maps the I/O region and sets isa_io/mem_base */ pci_process_bridge_OF_ranges(hose, dev, primary); + pci_setup_phb_io(hose, primary); /* Fixup "bus-range" OF property */ fixup_bus_range(dev); @@ -508,30 +376,8 @@ void __init maple_pcibios_fixup(void) DBG(" -> maple_pcibios_fixup\n"); - for_each_pci_dev(dev) { - /* Fixup IRQ for PCIe host */ - if (u4_pcie != NULL && dev->bus->number == 0 && - pci_bus_to_host(dev->bus) == u4_pcie) { - printk(KERN_DEBUG "Fixup U4 PCIe IRQ\n"); - dev->irq = irq_create_mapping(NULL, 1); - if (dev->irq != NO_IRQ) - set_irq_type(dev->irq, IRQ_TYPE_LEVEL_LOW); - continue; - } - - /* Hide AMD8111 IDE interrupt when in legacy mode so - * the driver calls pci_get_legacy_ide_irq() - */ - if (dev->vendor == PCI_VENDOR_ID_AMD && - dev->device == PCI_DEVICE_ID_AMD_8111_IDE && - (dev->class & 5) != 5) { - dev->irq = NO_IRQ; - continue; - } - - /* For all others, map the interrupt from the device-tree */ + for_each_pci_dev(dev) pci_read_irq_line(dev); - } DBG(" <- maple_pcibios_fixup\n"); } @@ -542,10 +388,8 @@ static void __init maple_fixup_phb_resources(void) list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { unsigned long offset = (unsigned long)hose->io_base_virt - pci_io_base; - hose->io_resource.start += offset; hose->io_resource.end += offset; - printk(KERN_INFO "PCI Host %d, io start: %llx; io end: %llx\n", hose->global_number, (unsigned long long)hose->io_resource.start, @@ -587,19 +431,6 @@ void __init maple_pci_init(void) if (ht && add_bridge(ht) != 0) of_node_put(ht); - /* - * We need to call pci_setup_phb_io for the HT bridge first - * so it gets the I/O port numbers starting at 0, and we - * need to call it for the AGP bridge after that so it gets - * small positive I/O port numbers. - */ - if (u3_ht) - pci_setup_phb_io(u3_ht, 1); - if (u3_agp) - pci_setup_phb_io(u3_agp, 0); - if (u4_pcie) - pci_setup_phb_io(u4_pcie, 0); - /* Fixup the IO resources on our host bridges as the common code * does it only for childs of the host bridges */ @@ -634,11 +465,8 @@ int maple_pci_get_legacy_ide_irq(struct pci_dev *pdev, int channel) return defirq; np = pci_device_to_OF_node(pdev); - if (np == NULL) { - printk("Failed to locate OF node for IDE %s\n", - pci_name(pdev)); + if (np == NULL) return defirq; - } irq = irq_of_parse_and_map(np, channel & 0x1); if (irq == NO_IRQ) { printk("Failed to map onboard IDE interrupt for channel %d\n", @@ -651,9 +479,6 @@ int maple_pci_get_legacy_ide_irq(struct pci_dev *pdev, int channel) /* XXX: To remove once all firmwares are ok */ static void fixup_maple_ide(struct pci_dev* dev) { - if (!machine_is(maple)) - return; - #if 0 /* Enable this to enable IDE port 0 */ { u8 v; @@ -670,7 +495,7 @@ static void fixup_maple_ide(struct pci_dev* dev) dev->resource[4].start = 0xcc00; dev->resource[4].end = 0xcc10; #endif -#if 0 /* Enable this to fixup IDE sense/polarity of irqs in IO-APICs */ +#if 1 /* Enable this to fixup IDE sense/polarity of irqs in IO-APICs */ { struct pci_dev *apicdev; u32 v; diff --git a/trunk/arch/powerpc/platforms/pasemi/pci.c b/trunk/arch/powerpc/platforms/pasemi/pci.c index 39020c1fa13d..4679c5230413 100644 --- a/trunk/arch/powerpc/platforms/pasemi/pci.c +++ b/trunk/arch/powerpc/platforms/pasemi/pci.c @@ -35,17 +35,17 @@ #define CONFIG_OFFSET_VALID(off) ((off) < 4096) -static void volatile __iomem *pa_pxp_cfg_addr(struct pci_controller *hose, +static unsigned long pa_pxp_cfg_addr(struct pci_controller *hose, u8 bus, u8 devfn, int offset) { - return hose->cfg_data + PA_PXP_CFA(bus, devfn, offset); + return ((unsigned long)hose->cfg_data) + PA_PXP_CFA(bus, devfn, offset); } static int pa_pxp_read_config(struct pci_bus *bus, unsigned int devfn, int offset, int len, u32 *val) { struct pci_controller *hose; - void volatile __iomem *addr; + unsigned long addr; hose = pci_bus_to_host(bus); if (!hose) @@ -62,13 +62,13 @@ static int pa_pxp_read_config(struct pci_bus *bus, unsigned int devfn, */ switch (len) { case 1: - *val = in_8(addr); + *val = in_8((u8 *)addr); break; case 2: - *val = in_le16(addr); + *val = in_le16((u16 *)addr); break; default: - *val = in_le32(addr); + *val = in_le32((u32 *)addr); break; } @@ -79,7 +79,7 @@ static int pa_pxp_write_config(struct pci_bus *bus, unsigned int devfn, int offset, int len, u32 val) { struct pci_controller *hose; - void volatile __iomem *addr; + unsigned long addr; hose = pci_bus_to_host(bus); if (!hose) @@ -96,16 +96,16 @@ static int pa_pxp_write_config(struct pci_bus *bus, unsigned int devfn, */ switch (len) { case 1: - out_8(addr, val); - (void) in_8(addr); + out_8((u8 *)addr, val); + (void) in_8((u8 *)addr); break; case 2: - out_le16(addr, val); - (void) in_le16(addr); + out_le16((u16 *)addr, val); + (void) in_le16((u16 *)addr); break; default: - out_le32(addr, val); - (void) in_le32(addr); + out_le32((u32 *)addr, val); + (void) in_le32((u32 *)addr); break; } return PCIBIOS_SUCCESSFUL; diff --git a/trunk/arch/powerpc/platforms/powermac/low_i2c.c b/trunk/arch/powerpc/platforms/powermac/low_i2c.c index bfc4829162f1..c2c7cf75dd5f 100644 --- a/trunk/arch/powerpc/platforms/powermac/low_i2c.c +++ b/trunk/arch/powerpc/platforms/powermac/low_i2c.c @@ -342,7 +342,7 @@ static void kw_i2c_handle_interrupt(struct pmac_i2c_host_kw *host, u8 isr) } /* Interrupt handler */ -static irqreturn_t kw_i2c_irq(int irq, void *dev_id) +static irqreturn_t kw_i2c_irq(int irq, void *dev_id, struct pt_regs *regs) { struct pmac_i2c_host_kw *host = dev_id; unsigned long flags; diff --git a/trunk/arch/powerpc/platforms/powermac/pci.c b/trunk/arch/powerpc/platforms/powermac/pci.c index 257dc9068468..9923adc5248e 100644 --- a/trunk/arch/powerpc/platforms/powermac/pci.c +++ b/trunk/arch/powerpc/platforms/powermac/pci.c @@ -48,6 +48,7 @@ static struct pci_controller *u3_ht; static int has_second_ohare; #endif /* CONFIG_PPC64 */ +extern u8 pci_cache_line_size; extern int pcibios_assign_bus_offset; struct device_node *k2_skiplist[2]; diff --git a/trunk/arch/powerpc/platforms/powermac/pfunc_base.c b/trunk/arch/powerpc/platforms/powermac/pfunc_base.c index 5c6c15c5f9a3..ee3b223ab17a 100644 --- a/trunk/arch/powerpc/platforms/powermac/pfunc_base.c +++ b/trunk/arch/powerpc/platforms/powermac/pfunc_base.c @@ -15,7 +15,7 @@ #define DBG(fmt...) #endif -static irqreturn_t macio_gpio_irq(int irq, void *data) +static irqreturn_t macio_gpio_irq(int irq, void *data, struct pt_regs *regs) { pmf_do_irq(data); diff --git a/trunk/arch/powerpc/platforms/powermac/pic.c b/trunk/arch/powerpc/platforms/powermac/pic.c index 39db12890214..39f7ddb554ea 100644 --- a/trunk/arch/powerpc/platforms/powermac/pic.c +++ b/trunk/arch/powerpc/platforms/powermac/pic.c @@ -42,7 +42,7 @@ * has to include (to get irqreturn_t), which * causes all sorts of problems. -- paulus */ -extern irqreturn_t xmon_irq(int, void *); +extern irqreturn_t xmon_irq(int, void *, struct pt_regs *); #ifdef CONFIG_PPC32 struct pmac_irq_hw { @@ -210,7 +210,7 @@ static struct irq_chip pmac_pic = { .retrigger = pmac_retrigger, }; -static irqreturn_t gatwick_action(int cpl, void *dev_id) +static irqreturn_t gatwick_action(int cpl, void *dev_id, struct pt_regs *regs) { unsigned long flags; int irq, bits; @@ -227,7 +227,7 @@ static irqreturn_t gatwick_action(int cpl, void *dev_id) continue; irq += __ilog2(bits); spin_unlock_irqrestore(&pmac_pic_lock, flags); - __do_IRQ(irq); + __do_IRQ(irq, regs); spin_lock_irqsave(&pmac_pic_lock, flags); rc = IRQ_HANDLED; } @@ -235,18 +235,18 @@ static irqreturn_t gatwick_action(int cpl, void *dev_id) return rc; } -static unsigned int pmac_pic_get_irq(void) +static unsigned int pmac_pic_get_irq(struct pt_regs *regs) { int irq; unsigned long bits = 0; unsigned long flags; #ifdef CONFIG_SMP - void psurge_smp_message_recv(void); + void psurge_smp_message_recv(struct pt_regs *); /* IPI's are a hack on the powersurge -- Cort */ if ( smp_processor_id() != 0 ) { - psurge_smp_message_recv(); + psurge_smp_message_recv(regs); return NO_IRQ_IGNORE; /* ignore, already handled */ } #endif /* CONFIG_SMP */ @@ -440,13 +440,14 @@ static void __init pmac_pic_probe_oldstyle(void) } #endif /* CONFIG_PPC32 */ -static void pmac_u3_cascade(unsigned int irq, struct irq_desc *desc) +static void pmac_u3_cascade(unsigned int irq, struct irq_desc *desc, + struct pt_regs *regs) { struct mpic *mpic = desc->handler_data; - unsigned int cascade_irq = mpic_get_one_irq(mpic); + unsigned int cascade_irq = mpic_get_one_irq(mpic, regs); if (cascade_irq != NO_IRQ) - generic_handle_irq(cascade_irq); + generic_handle_irq(cascade_irq, regs); desc->chip->eoi(irq); } diff --git a/trunk/arch/powerpc/platforms/powermac/pic.h b/trunk/arch/powerpc/platforms/powermac/pic.h index c44c89f5e532..664103dfeef9 100644 --- a/trunk/arch/powerpc/platforms/powermac/pic.h +++ b/trunk/arch/powerpc/platforms/powermac/pic.h @@ -5,7 +5,7 @@ extern struct hw_interrupt_type pmac_pic; -extern void pmac_pic_init(void); -extern int pmac_get_irq(void); +void pmac_pic_init(void); +int pmac_get_irq(struct pt_regs *regs); #endif /* __PPC_PLATFORMS_PMAC_PIC_H */ diff --git a/trunk/arch/powerpc/platforms/powermac/sleep.S b/trunk/arch/powerpc/platforms/powermac/sleep.S index adee28da353f..1174ca128efa 100644 --- a/trunk/arch/powerpc/platforms/powermac/sleep.S +++ b/trunk/arch/powerpc/platforms/powermac/sleep.S @@ -45,8 +45,7 @@ .section .text .align 5 -#if defined(CONFIG_PM) || defined(CONFIG_CPU_FREQ_PMAC) || \ - (defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32)) +#if defined(CONFIG_PM) || defined(CONFIG_CPU_FREQ_PMAC) /* This gets called by via-pmu.c late during the sleep process. * The PMU was already send the sleep command and will shut us down diff --git a/trunk/arch/powerpc/platforms/powermac/smp.c b/trunk/arch/powerpc/platforms/powermac/smp.c index eeb2ae5ffc58..1949b657b092 100644 --- a/trunk/arch/powerpc/platforms/powermac/smp.c +++ b/trunk/arch/powerpc/platforms/powermac/smp.c @@ -160,7 +160,7 @@ static inline void psurge_clr_ipi(int cpu) */ static unsigned long psurge_smp_message[NR_CPUS]; -void psurge_smp_message_recv(void) +void psurge_smp_message_recv(struct pt_regs *regs) { int cpu = smp_processor_id(); int msg; @@ -174,12 +174,12 @@ void psurge_smp_message_recv(void) /* make sure there is a message there */ for (msg = 0; msg < 4; msg++) if (test_and_clear_bit(msg, &psurge_smp_message[cpu])) - smp_message_recv(msg); + smp_message_recv(msg, regs); } -irqreturn_t psurge_primary_intr(int irq, void *d) +irqreturn_t psurge_primary_intr(int irq, void *d, struct pt_regs *regs) { - psurge_smp_message_recv(); + psurge_smp_message_recv(regs); return IRQ_HANDLED; } @@ -328,7 +328,6 @@ static void __init smp_psurge_kick_cpu(int nr) { unsigned long start = __pa(__secondary_start_pmac_0) + nr * 8; unsigned long a; - int i; /* may need to flush here if secondary bats aren't setup */ for (a = KERNELBASE; a < KERNELBASE + 0x800000; a += 32) @@ -341,11 +340,7 @@ static void __init smp_psurge_kick_cpu(int nr) mb(); psurge_set_ipi(nr); - /* - * We can't use udelay here because the timebase is now frozen. - */ - for (i = 0; i < 2000; ++i) - barrier(); + udelay(10); psurge_clr_ipi(nr); if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu - done", 0x354); diff --git a/trunk/arch/powerpc/platforms/pseries/iommu.c b/trunk/arch/powerpc/platforms/pseries/iommu.c index 556c279a789d..bbf2e34dc358 100644 --- a/trunk/arch/powerpc/platforms/pseries/iommu.c +++ b/trunk/arch/powerpc/platforms/pseries/iommu.c @@ -57,6 +57,9 @@ static void tce_build_pSeries(struct iommu_table *tbl, long index, u64 *tcep; u64 rpn; + index <<= TCE_PAGE_FACTOR; + npages <<= TCE_PAGE_FACTOR; + proto_tce = TCE_PCI_READ; // Read allowed if (direction != DMA_TO_DEVICE) @@ -79,6 +82,9 @@ static void tce_free_pSeries(struct iommu_table *tbl, long index, long npages) { u64 *tcep; + npages <<= TCE_PAGE_FACTOR; + index <<= TCE_PAGE_FACTOR; + tcep = ((u64 *)tbl->it_base) + index; while (npages--) @@ -89,6 +95,7 @@ static unsigned long tce_get_pseries(struct iommu_table *tbl, long index) { u64 *tcep; + index <<= TCE_PAGE_FACTOR; tcep = ((u64 *)tbl->it_base) + index; return *tcep; @@ -102,6 +109,9 @@ static void tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum, u64 proto_tce, tce; u64 rpn; + tcenum <<= TCE_PAGE_FACTOR; + npages <<= TCE_PAGE_FACTOR; + rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT; proto_tce = TCE_PCI_READ; if (direction != DMA_TO_DEVICE) @@ -136,7 +146,7 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, u64 rpn; long l, limit; - if (npages == 1) + if (TCE_PAGE_FACTOR == 0 && npages == 1) return tce_build_pSeriesLP(tbl, tcenum, npages, uaddr, direction); @@ -154,6 +164,9 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, __get_cpu_var(tce_page) = tcep; } + tcenum <<= TCE_PAGE_FACTOR; + npages <<= TCE_PAGE_FACTOR; + rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT; proto_tce = TCE_PCI_READ; if (direction != DMA_TO_DEVICE) @@ -194,6 +207,9 @@ static void tce_free_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages { u64 rc; + tcenum <<= TCE_PAGE_FACTOR; + npages <<= TCE_PAGE_FACTOR; + while (npages--) { rc = plpar_tce_put((u64)tbl->it_index, (u64)tcenum << 12, 0); @@ -213,6 +229,9 @@ static void tce_freemulti_pSeriesLP(struct iommu_table *tbl, long tcenum, long n { u64 rc; + tcenum <<= TCE_PAGE_FACTOR; + npages <<= TCE_PAGE_FACTOR; + rc = plpar_tce_stuff((u64)tbl->it_index, (u64)tcenum << 12, 0, npages); if (rc && printk_ratelimit()) { @@ -229,6 +248,7 @@ static unsigned long tce_get_pSeriesLP(struct iommu_table *tbl, long tcenum) u64 rc; unsigned long tce_ret; + tcenum <<= TCE_PAGE_FACTOR; rc = plpar_tce_get((u64)tbl->it_index, (u64)tcenum << 12, &tce_ret); if (rc && printk_ratelimit()) { @@ -247,8 +267,7 @@ static void iommu_table_setparms(struct pci_controller *phb, struct iommu_table *tbl) { struct device_node *node; - const unsigned long *basep; - const u32 *sizep; + const unsigned long *basep, *sizep; node = (struct device_node *)phb->arch_data; @@ -269,7 +288,7 @@ static void iommu_table_setparms(struct pci_controller *phb, tbl->it_busno = phb->bus->number; /* Units of tce entries */ - tbl->it_offset = phb->dma_window_base_cur >> IOMMU_PAGE_SHIFT; + tbl->it_offset = phb->dma_window_base_cur >> PAGE_SHIFT; /* Test if we are going over 2GB of DMA space */ if (phb->dma_window_base_cur + phb->dma_window_size > 0x80000000ul) { @@ -280,7 +299,7 @@ static void iommu_table_setparms(struct pci_controller *phb, phb->dma_window_base_cur += phb->dma_window_size; /* Set the tce table size - measured in entries */ - tbl->it_size = phb->dma_window_size >> IOMMU_PAGE_SHIFT; + tbl->it_size = phb->dma_window_size >> PAGE_SHIFT; tbl->it_index = 0; tbl->it_blocksize = 16; @@ -305,8 +324,8 @@ static void iommu_table_setparms_lpar(struct pci_controller *phb, tbl->it_base = 0; tbl->it_blocksize = 16; tbl->it_type = TCE_PCI; - tbl->it_offset = offset >> IOMMU_PAGE_SHIFT; - tbl->it_size = size >> IOMMU_PAGE_SHIFT; + tbl->it_offset = offset >> PAGE_SHIFT; + tbl->it_size = size >> PAGE_SHIFT; } static void iommu_bus_setup_pSeries(struct pci_bus *bus) @@ -502,6 +521,8 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev) const void *dma_window = NULL; struct pci_dn *pci; + DBG("iommu_dev_setup_pSeriesLP, dev %p (%s)\n", dev, pci_name(dev)); + /* dev setup for LPAR is a little tricky, since the device tree might * contain the dma-window properties per-device and not neccesarily * for the bus. So we need to search upwards in the tree until we @@ -510,9 +531,6 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev) */ dn = pci_device_to_OF_node(dev); - DBG("iommu_dev_setup_pSeriesLP, dev %p (%s) %s\n", - dev, pci_name(dev), dn->full_name); - for (pdn = dn; pdn && PCI_DN(pdn) && !PCI_DN(pdn)->iommu_table; pdn = pdn->parent) { dma_window = get_property(pdn, "ibm,dma-window", NULL); diff --git a/trunk/arch/powerpc/platforms/pseries/ras.c b/trunk/arch/powerpc/platforms/pseries/ras.c index b1d3d161249e..311ed1993fc0 100644 --- a/trunk/arch/powerpc/platforms/pseries/ras.c +++ b/trunk/arch/powerpc/platforms/pseries/ras.c @@ -65,14 +65,16 @@ static int ras_check_exception_token; #define EPOW_SENSOR_INDEX 0 #define RAS_VECTOR_OFFSET 0x500 -static irqreturn_t ras_epow_interrupt(int irq, void *dev_id); -static irqreturn_t ras_error_interrupt(int irq, void *dev_id); +static irqreturn_t ras_epow_interrupt(int irq, void *dev_id, + struct pt_regs * regs); +static irqreturn_t ras_error_interrupt(int irq, void *dev_id, + struct pt_regs * regs); /* #define DEBUG */ static void request_ras_irqs(struct device_node *np, - irq_handler_t handler, + irqreturn_t (*handler)(int, void *, struct pt_regs *), const char *name) { int i, index, count = 0; @@ -164,7 +166,8 @@ __initcall(init_ras_IRQ); * to examine the type of power failure and take appropriate action where * the time horizon permits something useful to be done. */ -static irqreturn_t ras_epow_interrupt(int irq, void *dev_id) +static irqreturn_t +ras_epow_interrupt(int irq, void *dev_id, struct pt_regs * regs) { int status = 0xdeadbeef; int state = 0; @@ -207,7 +210,8 @@ static irqreturn_t ras_epow_interrupt(int irq, void *dev_id) * For nonrecoverable errors, an error is logged and we stop all processing * as quickly as possible in order to prevent propagation of the failure. */ -static irqreturn_t ras_error_interrupt(int irq, void *dev_id) +static irqreturn_t +ras_error_interrupt(int irq, void *dev_id, struct pt_regs * regs) { struct rtas_error_log *rtas_elog; int status = 0xdeadbeef; diff --git a/trunk/arch/powerpc/platforms/pseries/setup.c b/trunk/arch/powerpc/platforms/pseries/setup.c index 89a8119f988d..f82b13e531a3 100644 --- a/trunk/arch/powerpc/platforms/pseries/setup.c +++ b/trunk/arch/powerpc/platforms/pseries/setup.c @@ -121,11 +121,12 @@ static void __init fwnmi_init(void) fwnmi_active = 1; } -void pseries_8259_cascade(unsigned int irq, struct irq_desc *desc) +void pseries_8259_cascade(unsigned int irq, struct irq_desc *desc, + struct pt_regs *regs) { - unsigned int cascade_irq = i8259_irq(); + unsigned int cascade_irq = i8259_irq(regs); if (cascade_irq != NO_IRQ) - generic_handle_irq(cascade_irq); + generic_handle_irq(cascade_irq, regs); desc->chip->eoi(irq); } diff --git a/trunk/arch/powerpc/platforms/pseries/xics.c b/trunk/arch/powerpc/platforms/pseries/xics.c index d071abe78ab1..253972e5479f 100644 --- a/trunk/arch/powerpc/platforms/pseries/xics.c +++ b/trunk/arch/powerpc/platforms/pseries/xics.c @@ -308,14 +308,14 @@ static inline unsigned int xics_remap_irq(unsigned int vec) return NO_IRQ; } -static unsigned int xics_get_irq_direct(void) +static unsigned int xics_get_irq_direct(struct pt_regs *regs) { unsigned int cpu = smp_processor_id(); return xics_remap_irq(direct_xirr_info_get(cpu)); } -static unsigned int xics_get_irq_lpar(void) +static unsigned int xics_get_irq_lpar(struct pt_regs *regs) { unsigned int cpu = smp_processor_id(); @@ -324,7 +324,7 @@ static unsigned int xics_get_irq_lpar(void) #ifdef CONFIG_SMP -static irqreturn_t xics_ipi_dispatch(int cpu) +static irqreturn_t xics_ipi_dispatch(int cpu, struct pt_regs *regs) { WARN_ON(cpu_is_offline(cpu)); @@ -332,47 +332,47 @@ static irqreturn_t xics_ipi_dispatch(int cpu) if (test_and_clear_bit(PPC_MSG_CALL_FUNCTION, &xics_ipi_message[cpu].value)) { mb(); - smp_message_recv(PPC_MSG_CALL_FUNCTION); + smp_message_recv(PPC_MSG_CALL_FUNCTION, regs); } if (test_and_clear_bit(PPC_MSG_RESCHEDULE, &xics_ipi_message[cpu].value)) { mb(); - smp_message_recv(PPC_MSG_RESCHEDULE); + smp_message_recv(PPC_MSG_RESCHEDULE, regs); } #if 0 if (test_and_clear_bit(PPC_MSG_MIGRATE_TASK, &xics_ipi_message[cpu].value)) { mb(); - smp_message_recv(PPC_MSG_MIGRATE_TASK); + smp_message_recv(PPC_MSG_MIGRATE_TASK, regs); } #endif #if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC) if (test_and_clear_bit(PPC_MSG_DEBUGGER_BREAK, &xics_ipi_message[cpu].value)) { mb(); - smp_message_recv(PPC_MSG_DEBUGGER_BREAK); + smp_message_recv(PPC_MSG_DEBUGGER_BREAK, regs); } #endif } return IRQ_HANDLED; } -static irqreturn_t xics_ipi_action_direct(int irq, void *dev_id) +static irqreturn_t xics_ipi_action_direct(int irq, void *dev_id, struct pt_regs *regs) { int cpu = smp_processor_id(); direct_qirr_info(cpu, 0xff); - return xics_ipi_dispatch(cpu); + return xics_ipi_dispatch(cpu, regs); } -static irqreturn_t xics_ipi_action_lpar(int irq, void *dev_id) +static irqreturn_t xics_ipi_action_lpar(int irq, void *dev_id, struct pt_regs *regs) { int cpu = smp_processor_id(); lpar_qirr_info(cpu, 0xff); - return xics_ipi_dispatch(cpu); + return xics_ipi_dispatch(cpu, regs); } void xics_cause_IPI(int cpu) diff --git a/trunk/arch/powerpc/platforms/pseries/xics.h b/trunk/arch/powerpc/platforms/pseries/xics.h index db0ec3ba3ae2..6ee1055b0ffb 100644 --- a/trunk/arch/powerpc/platforms/pseries/xics.h +++ b/trunk/arch/powerpc/platforms/pseries/xics.h @@ -31,6 +31,7 @@ struct xics_ipi_struct { extern struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned; struct irq_desc; -extern void pseries_8259_cascade(unsigned int irq, struct irq_desc *desc); +extern void pseries_8259_cascade(unsigned int irq, struct irq_desc *desc, + struct pt_regs *regs); #endif /* _POWERPC_KERNEL_XICS_H */ diff --git a/trunk/arch/powerpc/sysdev/cpm2_pic.c b/trunk/arch/powerpc/sysdev/cpm2_pic.c index 767ee6651adc..28b018994746 100644 --- a/trunk/arch/powerpc/sysdev/cpm2_pic.c +++ b/trunk/arch/powerpc/sysdev/cpm2_pic.c @@ -147,7 +147,7 @@ static struct irq_chip cpm2_pic = { .end = cpm2_end_irq, }; -unsigned int cpm2_get_irq(void) +unsigned int cpm2_get_irq(struct pt_regs *regs) { int irq; unsigned long bits; diff --git a/trunk/arch/powerpc/sysdev/cpm2_pic.h b/trunk/arch/powerpc/sysdev/cpm2_pic.h index 2840616529e4..3c513e5a688e 100644 --- a/trunk/arch/powerpc/sysdev/cpm2_pic.h +++ b/trunk/arch/powerpc/sysdev/cpm2_pic.h @@ -3,7 +3,7 @@ extern intctl_cpm2_t *cpm2_intctl; -extern unsigned int cpm2_get_irq(void); +extern unsigned int cpm2_get_irq(struct pt_regs *regs); extern void cpm2_pic_init(struct device_node*); diff --git a/trunk/arch/powerpc/sysdev/dart.h b/trunk/arch/powerpc/sysdev/dart.h index ff202edb0591..1c8817c4835e 100644 --- a/trunk/arch/powerpc/sysdev/dart.h +++ b/trunk/arch/powerpc/sysdev/dart.h @@ -72,6 +72,7 @@ #define DART_PAGE_SHIFT 12 #define DART_PAGE_SIZE (1 << DART_PAGE_SHIFT) +#define DART_PAGE_FACTOR (PAGE_SHIFT - DART_PAGE_SHIFT) #endif /* _POWERPC_SYSDEV_DART_H */ diff --git a/trunk/arch/powerpc/sysdev/dart_iommu.c b/trunk/arch/powerpc/sysdev/dart_iommu.c index 572b7846cc77..03b4477dd7f0 100644 --- a/trunk/arch/powerpc/sysdev/dart_iommu.c +++ b/trunk/arch/powerpc/sysdev/dart_iommu.c @@ -156,6 +156,9 @@ static void dart_build(struct iommu_table *tbl, long index, DBG("dart: build at: %lx, %lx, addr: %x\n", index, npages, uaddr); + index <<= DART_PAGE_FACTOR; + npages <<= DART_PAGE_FACTOR; + dp = ((unsigned int*)tbl->it_base) + index; /* On U3, all memory is contigous, so we can move this @@ -196,6 +199,9 @@ static void dart_free(struct iommu_table *tbl, long index, long npages) DBG("dart: free at: %lx, %lx\n", index, npages); + index <<= DART_PAGE_FACTOR; + npages <<= DART_PAGE_FACTOR; + dp = ((unsigned int *)tbl->it_base) + index; while (npages--) @@ -275,7 +281,7 @@ static void iommu_table_dart_setup(void) iommu_table_dart.it_busno = 0; iommu_table_dart.it_offset = 0; /* it_size is in number of entries */ - iommu_table_dart.it_size = dart_tablesize / sizeof(u32); + iommu_table_dart.it_size = (dart_tablesize / sizeof(u32)) >> DART_PAGE_FACTOR; /* Initialize the common IOMMU code */ iommu_table_dart.it_base = (unsigned long)dart_vbase; diff --git a/trunk/arch/powerpc/sysdev/fsl_soc.c b/trunk/arch/powerpc/sysdev/fsl_soc.c index dbe92ae20333..7d759f1c26b1 100644 --- a/trunk/arch/powerpc/sysdev/fsl_soc.c +++ b/trunk/arch/powerpc/sysdev/fsl_soc.c @@ -567,7 +567,7 @@ static int __init fs_enet_of_init(void) struct resource r[4]; struct device_node *phy, *mdio; struct fs_platform_info fs_enet_data; - const unsigned int *id, *phy_addr, *phy_irq; + const unsigned int *id, *phy_addr, phy_irq; const void *mac_addr; const phandle *ph; const char *model; @@ -641,7 +641,7 @@ static int __init fs_enet_of_init(void) if (strstr(model, "FCC")) { int fcc_index = *id - 1; - const unsigned char *mdio_bb_prop; + unsigned char* mdio_bb_prop; fs_enet_data.dpram_offset = (u32)cpm_dpram_addr(0); fs_enet_data.rx_ring = 32; @@ -708,9 +708,8 @@ static int __init fs_enet_of_init(void) ret = platform_device_add_data(fs_enet_dev, &fs_enet_data, sizeof(struct fs_platform_info)); - if (ret) - goto unreg; - } + if (ret) + goto unreg; } return 0; diff --git a/trunk/arch/powerpc/sysdev/i8259.c b/trunk/arch/powerpc/sysdev/i8259.c index ad87adc975bc..26a6a3becd66 100644 --- a/trunk/arch/powerpc/sysdev/i8259.c +++ b/trunk/arch/powerpc/sysdev/i8259.c @@ -34,7 +34,7 @@ static struct irq_host *i8259_host; * which is called. It should be noted that polling is broken on some * IBM and Motorola PReP boxes so we must use the int-ack feature on them. */ -unsigned int i8259_irq(void) +unsigned int i8259_irq(struct pt_regs *regs) { int irq; int lock = 0; @@ -224,11 +224,6 @@ static struct irq_host_ops i8259_host_ops = { .xlate = i8259_host_xlate, }; -struct irq_host *i8259_get_host(void) -{ - return i8259_host; -} - /** * i8259_init - Initialize the legacy controller * @node: device node of the legacy PIC (can be NULL, but then, it will match diff --git a/trunk/arch/powerpc/sysdev/ipic.c b/trunk/arch/powerpc/sysdev/ipic.c index 746f78c15375..6ebdae8e6f69 100644 --- a/trunk/arch/powerpc/sysdev/ipic.c +++ b/trunk/arch/powerpc/sysdev/ipic.c @@ -473,9 +473,9 @@ static int ipic_set_irq_type(unsigned int virq, unsigned int flow_type) desc->status |= flow_type & IRQ_TYPE_SENSE_MASK; if (flow_type & IRQ_TYPE_LEVEL_LOW) { desc->status |= IRQ_LEVEL; - desc->handle_irq = handle_level_irq; + set_irq_handler(virq, handle_level_irq); } else { - desc->handle_irq = handle_edge_irq; + set_irq_handler(virq, handle_edge_irq); } /* only EXT IRQ senses are programmable on ipic @@ -709,7 +709,7 @@ void ipic_clear_mcp_status(u32 mask) } /* Return an interrupt vector or NO_IRQ if no interrupt is pending. */ -unsigned int ipic_get_irq(void) +unsigned int ipic_get_irq(struct pt_regs *regs) { int irq; diff --git a/trunk/arch/powerpc/sysdev/mpic.c b/trunk/arch/powerpc/sysdev/mpic.c index ba4833f57d47..3ee03a9a98fa 100644 --- a/trunk/arch/powerpc/sysdev/mpic.c +++ b/trunk/arch/powerpc/sysdev/mpic.c @@ -489,9 +489,9 @@ static inline void mpic_eoi(struct mpic *mpic) } #ifdef CONFIG_SMP -static irqreturn_t mpic_ipi_action(int irq, void *dev_id) +static irqreturn_t mpic_ipi_action(int irq, void *dev_id, struct pt_regs *regs) { - smp_message_recv(mpic_irq_to_hw(irq) - MPIC_VEC_IPI_0); + smp_message_recv(mpic_irq_to_hw(irq) - MPIC_VEC_IPI_0, regs); return IRQ_HANDLED; } #endif /* CONFIG_SMP */ @@ -1217,7 +1217,7 @@ void mpic_send_ipi(unsigned int ipi_no, unsigned int cpu_mask) mpic_physmask(cpu_mask & cpus_addr(cpu_online_map)[0])); } -unsigned int mpic_get_one_irq(struct mpic *mpic) +unsigned int mpic_get_one_irq(struct mpic *mpic, struct pt_regs *regs) { u32 src; @@ -1230,13 +1230,13 @@ unsigned int mpic_get_one_irq(struct mpic *mpic) return irq_linear_revmap(mpic->irqhost, src); } -unsigned int mpic_get_irq(void) +unsigned int mpic_get_irq(struct pt_regs *regs) { struct mpic *mpic = mpic_primary; BUG_ON(mpic == NULL); - return mpic_get_one_irq(mpic); + return mpic_get_one_irq(mpic, regs); } diff --git a/trunk/arch/powerpc/sysdev/qe_lib/qe.c b/trunk/arch/powerpc/sysdev/qe_lib/qe.c index e4223226a7a8..2bae632d3ad7 100644 --- a/trunk/arch/powerpc/sysdev/qe_lib/qe.c +++ b/trunk/arch/powerpc/sysdev/qe_lib/qe.c @@ -122,7 +122,8 @@ int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, u32 cmd_input) mcn_shift = QE_CR_MCN_NORMAL_SHIFT; } - out_be32(&qe_immr->cp.cecdr, cmd_input); + out_be32(&qe_immr->cp.cecdr, + immrbar_virt_to_phys((void *)cmd_input)); out_be32(&qe_immr->cp.cecr, (cmd | QE_CR_FLG | ((u32) device << dev_shift) | (u32) mcn_protocol << mcn_shift)); diff --git a/trunk/arch/powerpc/sysdev/qe_lib/qe_ic.c b/trunk/arch/powerpc/sysdev/qe_lib/qe_ic.c index 6995f51b9488..c229d07d4957 100644 --- a/trunk/arch/powerpc/sysdev/qe_lib/qe_ic.c +++ b/trunk/arch/powerpc/sysdev/qe_lib/qe_ic.c @@ -300,7 +300,7 @@ static struct irq_host_ops qe_ic_host_ops = { }; /* Return an interrupt vector or NO_IRQ if no interrupt is pending. */ -unsigned int qe_ic_get_low_irq(struct qe_ic *qe_ic) +unsigned int qe_ic_get_low_irq(struct qe_ic *qe_ic, struct pt_regs *regs) { int irq; @@ -316,7 +316,7 @@ unsigned int qe_ic_get_low_irq(struct qe_ic *qe_ic) } /* Return an interrupt vector or NO_IRQ if no interrupt is pending. */ -unsigned int qe_ic_get_high_irq(struct qe_ic *qe_ic) +unsigned int qe_ic_get_high_irq(struct qe_ic *qe_ic, struct pt_regs *regs) { int irq; @@ -333,31 +333,33 @@ unsigned int qe_ic_get_high_irq(struct qe_ic *qe_ic) /* FIXME: We mask all the QE Low interrupts while handling. We should * let other interrupt come in, but BAD interrupts are generated */ -void fastcall qe_ic_cascade_low(unsigned int irq, struct irq_desc *desc) +void fastcall qe_ic_cascade_low(unsigned int irq, struct irq_desc *desc, + struct pt_regs *regs) { struct qe_ic *qe_ic = desc->handler_data; struct irq_chip *chip = irq_desc[irq].chip; - unsigned int cascade_irq = qe_ic_get_low_irq(qe_ic); + unsigned int cascade_irq = qe_ic_get_low_irq(qe_ic, regs); chip->mask_ack(irq); if (cascade_irq != NO_IRQ) - generic_handle_irq(cascade_irq); + generic_handle_irq(cascade_irq, regs); chip->unmask(irq); } /* FIXME: We mask all the QE High interrupts while handling. We should * let other interrupt come in, but BAD interrupts are generated */ -void fastcall qe_ic_cascade_high(unsigned int irq, struct irq_desc *desc) +void fastcall qe_ic_cascade_high(unsigned int irq, struct irq_desc *desc, + struct pt_regs *regs) { struct qe_ic *qe_ic = desc->handler_data; struct irq_chip *chip = irq_desc[irq].chip; - unsigned int cascade_irq = qe_ic_get_high_irq(qe_ic); + unsigned int cascade_irq = qe_ic_get_high_irq(qe_ic, regs); chip->mask_ack(irq); if (cascade_irq != NO_IRQ) - generic_handle_irq(cascade_irq); + generic_handle_irq(cascade_irq, regs); chip->unmask(irq); } diff --git a/trunk/arch/powerpc/sysdev/qe_lib/qe_io.c b/trunk/arch/powerpc/sysdev/qe_lib/qe_io.c index 0afe6bfe3714..aea435970389 100644 --- a/trunk/arch/powerpc/sysdev/qe_lib/qe_io.c +++ b/trunk/arch/powerpc/sysdev/qe_lib/qe_io.c @@ -14,6 +14,7 @@ * option) any later version. */ +#include #include #include #include diff --git a/trunk/arch/powerpc/sysdev/qe_lib/ucc.c b/trunk/arch/powerpc/sysdev/qe_lib/ucc.c index ac12a44d516f..916c9e5df57f 100644 --- a/trunk/arch/powerpc/sysdev/qe_lib/ucc.c +++ b/trunk/arch/powerpc/sysdev/qe_lib/ucc.c @@ -207,7 +207,6 @@ int ucc_set_qe_mux_rxtx(int ucc_num, enum qe_clock clock, enum comm_dir mode) case QE_CLK18: source = 8; break; case QE_CLK7: source = 9; break; case QE_CLK8: source = 10; break; - case QE_CLK16: source = 11; break; default: source = -1; break; } break; @@ -223,7 +222,6 @@ int ucc_set_qe_mux_rxtx(int ucc_num, enum qe_clock clock, enum comm_dir mode) case QE_CLK22: source = 8; break; case QE_CLK7: source = 9; break; case QE_CLK8: source = 10; break; - case QE_CLK16: source = 11; break; default: source = -1; break; } break; diff --git a/trunk/arch/powerpc/sysdev/qe_lib/ucc_fast.c b/trunk/arch/powerpc/sysdev/qe_lib/ucc_fast.c index 75fa3104a43a..c2be7348fcbd 100644 --- a/trunk/arch/powerpc/sysdev/qe_lib/ucc_fast.c +++ b/trunk/arch/powerpc/sysdev/qe_lib/ucc_fast.c @@ -163,7 +163,7 @@ int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** ucc /* check if the UCC port number is in range. */ if ((uf_info->ucc_num < 0) || (uf_info->ucc_num > UCC_MAX_NUM - 1)) { - uccf_err("ucc_fast_init: Illegal UCC number!"); + uccf_err("ucc_fast_init: Illagal UCC number!"); return -EINVAL; } diff --git a/trunk/arch/powerpc/sysdev/qe_lib/ucc_slow.c b/trunk/arch/powerpc/sysdev/qe_lib/ucc_slow.c index a49da6b73ecf..1fb88ef7cf06 100644 --- a/trunk/arch/powerpc/sysdev/qe_lib/ucc_slow.c +++ b/trunk/arch/powerpc/sysdev/qe_lib/ucc_slow.c @@ -152,7 +152,7 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc /* check if the UCC port number is in range. */ if ((us_info->ucc_num < 0) || (us_info->ucc_num > UCC_MAX_NUM - 1)) { - uccs_err("ucc_slow_init: Illegal UCC number!"); + uccs_err("ucc_slow_init: Illagal UCC number!"); return -EINVAL; } diff --git a/trunk/arch/powerpc/sysdev/tsi108_dev.c b/trunk/arch/powerpc/sysdev/tsi108_dev.c index 97f37ef4bbbf..11de090eb901 100644 --- a/trunk/arch/powerpc/sysdev/tsi108_dev.c +++ b/trunk/arch/powerpc/sysdev/tsi108_dev.c @@ -48,7 +48,7 @@ phys_addr_t get_csrbase(void) tsi = of_find_node_by_type(NULL, "tsi-bridge"); if (tsi) { unsigned int size; - const void *prop = get_property(tsi, "reg", &size); + void *prop = get_property(tsi, "reg", &size); tsi108_csr_base = of_translate_address(tsi, prop); of_node_put(tsi); }; @@ -79,7 +79,7 @@ static int __init tsi108_eth_of_init(void) hw_info tsi_eth_data; unsigned int *id; unsigned int *phy_id; - const void *mac_addr; + void *mac_addr; phandle *ph; memset(r, 0, sizeof(r)); diff --git a/trunk/arch/powerpc/sysdev/tsi108_pci.c b/trunk/arch/powerpc/sysdev/tsi108_pci.c index 322f86e93de5..c28f69bef8e2 100644 --- a/trunk/arch/powerpc/sysdev/tsi108_pci.c +++ b/trunk/arch/powerpc/sysdev/tsi108_pci.c @@ -405,10 +405,11 @@ void __init tsi108_pci_int_init(void) init_pci_source(); } -void tsi108_irq_cascade(unsigned int irq, struct irq_desc *desc) +void tsi108_irq_cascade(unsigned int irq, struct irq_desc *desc, + struct pt_regs *regs) { unsigned int cascade_irq = get_pci_source(); if (cascade_irq != NO_IRQ) - generic_handle_irq(cascade_irq); + generic_handle_irq(cascade_irq, regs); desc->chip->eoi(irq); } diff --git a/trunk/arch/powerpc/xmon/xmon.c b/trunk/arch/powerpc/xmon/xmon.c index f56ffef4defa..708236f34746 100644 --- a/trunk/arch/powerpc/xmon/xmon.c +++ b/trunk/arch/powerpc/xmon/xmon.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include @@ -36,7 +35,6 @@ #include #include #include -#include #ifdef CONFIG_PPC64 #include @@ -522,12 +520,13 @@ int xmon(struct pt_regs *excp) } EXPORT_SYMBOL(xmon); -irqreturn_t xmon_irq(int irq, void *d) +irqreturn_t +xmon_irq(int irq, void *d, struct pt_regs *regs) { unsigned long flags; local_irq_save(flags); printf("Keyboard interrupt\n"); - xmon(get_irq_regs()); + xmon(regs); local_irq_restore(flags); return IRQ_HANDLED; } @@ -2578,11 +2577,12 @@ void xmon_init(int enable) } #ifdef CONFIG_MAGIC_SYSRQ -static void sysrq_handle_xmon(int key, struct tty_struct *tty) +static void sysrq_handle_xmon(int key, struct pt_regs *pt_regs, + struct tty_struct *tty) { /* ensure xmon is enabled */ xmon_init(1); - debugger(get_irq_regs()); + debugger(pt_regs); } static struct sysrq_key_op sysrq_xmon_op = diff --git a/trunk/arch/ppc/4xx_io/serial_sicc.c b/trunk/arch/ppc/4xx_io/serial_sicc.c index e35483961b90..87fe9a89dba7 100644 --- a/trunk/arch/ppc/4xx_io/serial_sicc.c +++ b/trunk/arch/ppc/4xx_io/serial_sicc.c @@ -414,7 +414,7 @@ static void siccuart_event(struct SICC_info *info, int event) } static void -siccuart_rx_chars(struct SICC_info *info) +siccuart_rx_chars(struct SICC_info *info, struct pt_regs *regs) { struct tty_struct *tty = info->tty; unsigned int status, ch, rsr, flg, ignored = 0; @@ -441,7 +441,7 @@ siccuart_rx_chars(struct SICC_info *info) #ifdef SUPPORT_SYSRQ if (info->sysrq) { if (ch && time_before(jiffies, info->sysrq)) { - handle_sysrq(ch, NULL); + handle_sysrq(ch, regs, NULL); info->sysrq = 0; goto ignore_char; } @@ -553,15 +553,15 @@ static void siccuart_tx_chars(struct SICC_info *info) } -static irqreturn_t siccuart_int_rx(int irq, void *dev_id) +static irqreturn_t siccuart_int_rx(int irq, void *dev_id, struct pt_regs *regs) { struct SICC_info *info = dev_id; - siccuart_rx_chars(info) + siccuart_rx_chars(info, regs); return IRQ_HANDLED; } -static irqreturn_t siccuart_int_tx(int irq, void *dev_id) +static irqreturn_t siccuart_int_tx(int irq, void *dev_id, struct pt_regs *regs) { struct SICC_info *info = dev_id; siccuart_tx_chars(info); diff --git a/trunk/arch/ppc/8260_io/enet.c b/trunk/arch/ppc/8260_io/enet.c index a6056c29cf00..ac6d55fe2235 100644 --- a/trunk/arch/ppc/8260_io/enet.c +++ b/trunk/arch/ppc/8260_io/enet.c @@ -122,7 +122,7 @@ struct scc_enet_private { static int scc_enet_open(struct net_device *dev); static int scc_enet_start_xmit(struct sk_buff *skb, struct net_device *dev); static int scc_enet_rx(struct net_device *dev); -static irqreturn_t scc_enet_interrupt(int irq, void *dev_id); +static irqreturn_t scc_enet_interrupt(int irq, void *dev_id, struct pt_regs *); static int scc_enet_close(struct net_device *dev); static struct net_device_stats *scc_enet_get_stats(struct net_device *dev); static void set_multicast_list(struct net_device *dev); @@ -273,7 +273,7 @@ scc_enet_timeout(struct net_device *dev) * This is called from the CPM handler, not the MPC core interrupt. */ static irqreturn_t -scc_enet_interrupt(int irq, void * dev_id) +scc_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs) { struct net_device *dev = dev_id; volatile struct scc_enet_private *cep; diff --git a/trunk/arch/ppc/8260_io/fcc_enet.c b/trunk/arch/ppc/8260_io/fcc_enet.c index 2e1943e27819..e347fe88316d 100644 --- a/trunk/arch/ppc/8260_io/fcc_enet.c +++ b/trunk/arch/ppc/8260_io/fcc_enet.c @@ -140,7 +140,7 @@ typedef struct { static int fcc_enet_open(struct net_device *dev); static int fcc_enet_start_xmit(struct sk_buff *skb, struct net_device *dev); static int fcc_enet_rx(struct net_device *dev); -static irqreturn_t fcc_enet_interrupt(int irq, void *dev_id); +static irqreturn_t fcc_enet_interrupt(int irq, void *dev_id, struct pt_regs *); static int fcc_enet_close(struct net_device *dev); static struct net_device_stats *fcc_enet_get_stats(struct net_device *dev); /* static void set_multicast_list(struct net_device *dev); */ @@ -524,7 +524,7 @@ fcc_enet_timeout(struct net_device *dev) /* The interrupt handler. */ static irqreturn_t -fcc_enet_interrupt(int irq, void * dev_id) +fcc_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs) { struct net_device *dev = dev_id; volatile struct fcc_enet_private *cep; @@ -1563,7 +1563,7 @@ mii_discover_phy(uint mii_reg, struct net_device *dev) #ifdef PHY_INTERRUPT /* This interrupt occurs when the PHY detects a link change. */ static irqreturn_t -mii_link_interrupt(int irq, void * dev_id) +mii_link_interrupt(int irq, void * dev_id, struct pt_regs * regs) { struct net_device *dev = dev_id; struct fcc_enet_private *fep = dev->priv; diff --git a/trunk/arch/ppc/8xx_io/commproc.c b/trunk/arch/ppc/8xx_io/commproc.c index 3b23bcb35b7a..9b3ace26280c 100644 --- a/trunk/arch/ppc/8xx_io/commproc.c +++ b/trunk/arch/ppc/8xx_io/commproc.c @@ -47,12 +47,12 @@ cpm8xx_t *cpmp; /* Pointer to comm processor space */ /* CPM interrupt vector functions. */ struct cpm_action { - void (*handler)(void *); + void (*handler)(void *, struct pt_regs * regs); void *dev_id; }; static struct cpm_action cpm_vecs[CPMVEC_NR]; -static irqreturn_t cpm_interrupt(int irq, void * dev); -static irqreturn_t cpm_error_interrupt(int irq, void *dev); +static irqreturn_t cpm_interrupt(int irq, void * dev, struct pt_regs * regs); +static irqreturn_t cpm_error_interrupt(int irq, void *dev, struct pt_regs * regs); static void alloc_host_memory(void); /* Define a table of names to identify CPM interrupt handlers in * /proc/interrupts. @@ -205,7 +205,7 @@ cpm_interrupt_init(void) * Get the CPM interrupt vector. */ int -cpm_get_irq(void) +cpm_get_irq(struct pt_regs *regs) { int cpm_vec; @@ -222,7 +222,7 @@ cpm_get_irq(void) /* CPM interrupt controller cascade interrupt. */ static irqreturn_t -cpm_interrupt(int irq, void * dev) +cpm_interrupt(int irq, void * dev, struct pt_regs * regs) { /* This interrupt handler never actually gets called. It is * installed only to unmask the CPM cascade interrupt in the SIU @@ -237,7 +237,7 @@ cpm_interrupt(int irq, void * dev) * tests in the interrupt handler. */ static irqreturn_t -cpm_error_interrupt(int irq, void *dev) +cpm_error_interrupt(int irq, void *dev, struct pt_regs *regs) { return IRQ_HANDLED; } @@ -246,11 +246,11 @@ cpm_error_interrupt(int irq, void *dev) * request_irq() to the handler prototype required by cpm_install_handler(). */ static irqreturn_t -cpm_handler_helper(int irq, void *dev_id) +cpm_handler_helper(int irq, void *dev_id, struct pt_regs *regs) { int cpm_vec = irq - CPM_IRQ_OFFSET; - (*cpm_vecs[cpm_vec].handler)(dev_id); + (*cpm_vecs[cpm_vec].handler)(dev_id, regs); return IRQ_HANDLED; } @@ -267,7 +267,8 @@ cpm_handler_helper(int irq, void *dev_id) * request_irq() or cpm_install_handler(). */ void -cpm_install_handler(int cpm_vec, void (*handler)(void *), void *dev_id) +cpm_install_handler(int cpm_vec, void (*handler)(void *, struct pt_regs *regs), + void *dev_id) { int err; diff --git a/trunk/arch/ppc/8xx_io/cs4218_tdm.c b/trunk/arch/ppc/8xx_io/cs4218_tdm.c index 959d31c26cbb..f5f300fc213d 100644 --- a/trunk/arch/ppc/8xx_io/cs4218_tdm.c +++ b/trunk/arch/ppc/8xx_io/cs4218_tdm.c @@ -331,7 +331,7 @@ static int CS_SetFormat(int format); static int CS_SetVolume(int volume); static void cs4218_tdm_tx_intr(void *devid); static void cs4218_tdm_rx_intr(void *devid); -static void cs4218_intr(void *devid); +static void cs4218_intr(void *devid, struct pt_regs *regs); static int cs_get_volume(uint reg); static int cs_volume_setter(int volume, int mute); static int cs_get_gain(uint reg); @@ -2646,7 +2646,7 @@ int __init tdm8xx_sound_init(void) * full duplex operation. */ static void -cs4218_intr(void *dev_id) +cs4218_intr(void *dev_id, struct pt_regs *regs) { volatile smc_t *sp; volatile cpm8xx_t *cp; diff --git a/trunk/arch/ppc/8xx_io/enet.c b/trunk/arch/ppc/8xx_io/enet.c index b23c45bc151a..a695375c3e4c 100644 --- a/trunk/arch/ppc/8xx_io/enet.c +++ b/trunk/arch/ppc/8xx_io/enet.c @@ -149,7 +149,7 @@ struct scc_enet_private { static int scc_enet_open(struct net_device *dev); static int scc_enet_start_xmit(struct sk_buff *skb, struct net_device *dev); static int scc_enet_rx(struct net_device *dev); -static void scc_enet_interrupt(void *dev_id); +static void scc_enet_interrupt(void *dev_id, struct pt_regs *regs); static int scc_enet_close(struct net_device *dev); static struct net_device_stats *scc_enet_get_stats(struct net_device *dev); static void set_multicast_list(struct net_device *dev); @@ -305,7 +305,7 @@ scc_enet_timeout(struct net_device *dev) * This is called from the CPM handler, not the MPC core interrupt. */ static void -scc_enet_interrupt(void *dev_id) +scc_enet_interrupt(void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; volatile struct scc_enet_private *cep; diff --git a/trunk/arch/ppc/8xx_io/fec.c b/trunk/arch/ppc/8xx_io/fec.c index 2f9fa9e3d331..8b6295bbb564 100644 --- a/trunk/arch/ppc/8xx_io/fec.c +++ b/trunk/arch/ppc/8xx_io/fec.c @@ -198,7 +198,8 @@ static int fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev); #ifdef CONFIG_USE_MDIO static void fec_enet_mii(struct net_device *dev); #endif /* CONFIG_USE_MDIO */ -static irqreturn_t fec_enet_interrupt(int irq, void * dev_id); +static irqreturn_t fec_enet_interrupt(int irq, void * dev_id, + struct pt_regs * regs); #ifdef CONFIG_FEC_PACKETHOOK static void fec_enet_tx(struct net_device *dev, __u32 regval); static void fec_enet_rx(struct net_device *dev, __u32 regval); @@ -471,7 +472,7 @@ fec_timeout(struct net_device *dev) * This is called from the MPC core interrupt. */ static irqreturn_t -fec_enet_interrupt(int irq, void * dev_id) +fec_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs) { struct net_device *dev = dev_id; volatile fec_t *fecp; @@ -1407,7 +1408,7 @@ static #ifdef CONFIG_RPXCLASSIC void mii_link_interrupt(void *dev_id) #else -irqreturn_t mii_link_interrupt(int irq, void * dev_id) +irqreturn_t mii_link_interrupt(int irq, void * dev_id, struct pt_regs * regs) #endif { #ifdef CONFIG_USE_MDIO diff --git a/trunk/arch/ppc/Kconfig b/trunk/arch/ppc/Kconfig index ef018e25fb07..077711e63104 100644 --- a/trunk/arch/ppc/Kconfig +++ b/trunk/arch/ppc/Kconfig @@ -724,7 +724,7 @@ config MPC834x_SYS Be aware that PCI buses can only function when SYS board is plugged into the PIB (Platform IO Board) board from Freescale which provide 3 PCI slots. The PIBs PCI initialization is the bootloader's - responsibility. + responsiblilty. config EV64360 bool "Marvell-EV64360BP" diff --git a/trunk/arch/ppc/boot/simple/relocate.S b/trunk/arch/ppc/boot/simple/relocate.S index 1bbbcd2f2bcb..0c021556d78e 100644 --- a/trunk/arch/ppc/boot/simple/relocate.S +++ b/trunk/arch/ppc/boot/simple/relocate.S @@ -154,8 +154,8 @@ do_relocate_out: start_ldr: /* Clear all of BSS and set up stack for C calls */ - lis r3,__bss_start@h - ori r3,r3,__bss_start@l + lis r3,edata@h + ori r3,r3,edata@l lis r4,end@h ori r4,r4,end@l subi r3,r3,4 @@ -163,7 +163,7 @@ start_ldr: li r0,0 50: stwu r0,4(r3) cmpw cr0,r3,r4 - blt 50b + bne 50b 90: mr r9,r1 /* Save old stack pointer (in case it matters) */ lis r1,.stack@h ori r1,r1,.stack@l diff --git a/trunk/arch/ppc/kernel/misc.S b/trunk/arch/ppc/kernel/misc.S index d319f9ba2379..5f6684012ded 100644 --- a/trunk/arch/ppc/kernel/misc.S +++ b/trunk/arch/ppc/kernel/misc.S @@ -109,6 +109,80 @@ _GLOBAL(reloc_got2) mtlr r11 blr +/* + * identify_cpu, + * called with r3 = data offset and r4 = CPU number + * doesn't change r3 + */ +_GLOBAL(identify_cpu) + addis r8,r3,cpu_specs@ha + addi r8,r8,cpu_specs@l + mfpvr r7 +1: + lwz r5,CPU_SPEC_PVR_MASK(r8) + and r5,r5,r7 + lwz r6,CPU_SPEC_PVR_VALUE(r8) + cmplw 0,r6,r5 + beq 1f + addi r8,r8,CPU_SPEC_ENTRY_SIZE + b 1b +1: + addis r6,r3,cur_cpu_spec@ha + addi r6,r6,cur_cpu_spec@l + sub r8,r8,r3 + stw r8,0(r6) + blr + +/* + * do_cpu_ftr_fixups - goes through the list of CPU feature fixups + * and writes nop's over sections of code that don't apply for this cpu. + * r3 = data offset (not changed) + */ +_GLOBAL(do_cpu_ftr_fixups) + /* Get CPU 0 features */ + addis r6,r3,cur_cpu_spec@ha + addi r6,r6,cur_cpu_spec@l + lwz r4,0(r6) + add r4,r4,r3 + lwz r4,CPU_SPEC_FEATURES(r4) + + /* Get the fixup table */ + addis r6,r3,__start___ftr_fixup@ha + addi r6,r6,__start___ftr_fixup@l + addis r7,r3,__stop___ftr_fixup@ha + addi r7,r7,__stop___ftr_fixup@l + + /* Do the fixup */ +1: cmplw 0,r6,r7 + bgelr + addi r6,r6,16 + lwz r8,-16(r6) /* mask */ + and r8,r8,r4 + lwz r9,-12(r6) /* value */ + cmplw 0,r8,r9 + beq 1b + lwz r8,-8(r6) /* section begin */ + lwz r9,-4(r6) /* section end */ + subf. r9,r8,r9 + beq 1b + /* write nops over the section of code */ + /* todo: if large section, add a branch at the start of it */ + srwi r9,r9,2 + mtctr r9 + add r8,r8,r3 + lis r0,0x60000000@h /* nop */ +3: stw r0,0(r8) + andi. r10,r4,CPU_FTR_SPLIT_ID_CACHE@l + beq 2f + dcbst 0,r8 /* suboptimal, but simpler */ + sync + icbi 0,r8 +2: addi r8,r8,4 + bdnz 3b + sync /* additional sync needed on g4 */ + isync + b 1b + /* * call_setup_cpu - call the setup_cpu function for this cpu * r3 = data offset, r24 = cpu number diff --git a/trunk/arch/ppc/kernel/setup.c b/trunk/arch/ppc/kernel/setup.c index 27faeca2c7a2..75fe13815be2 100644 --- a/trunk/arch/ppc/kernel/setup.c +++ b/trunk/arch/ppc/kernel/setup.c @@ -38,7 +38,6 @@ #include #include #include -#include #define USES_PPC_SYS (defined(CONFIG_85xx) || defined(CONFIG_83xx) || \ defined(CONFIG_MPC10X_BRIDGE) || defined(CONFIG_8260) || \ @@ -54,6 +53,8 @@ extern void platform_init(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7); +extern void identify_cpu(unsigned long offset, unsigned long cpu); +extern void do_cpu_ftr_fixups(unsigned long offset); extern void reloc_got2(unsigned long offset); extern void ppc6xx_idle(void); @@ -300,7 +301,6 @@ early_init(int r3, int r4, int r5) { unsigned long phys; unsigned long offset = reloc_offset(); - struct cpu_spec *spec; /* Default */ phys = offset + KERNELBASE; @@ -313,10 +313,8 @@ early_init(int r3, int r4, int r5) * Identify the CPU type and fix up code sections * that depend on which cpu we have. */ - spec = identify_cpu(offset); - do_feature_fixups(spec->cpu_features, - PTRRELOC(&__start___ftr_fixup), - PTRRELOC(&__stop___ftr_fixup)); + identify_cpu(offset, 0); + do_cpu_ftr_fixups(offset); return phys; } diff --git a/trunk/arch/ppc/kernel/smp.c b/trunk/arch/ppc/kernel/smp.c index 96a55972b986..ca57e896a36c 100644 --- a/trunk/arch/ppc/kernel/smp.c +++ b/trunk/arch/ppc/kernel/smp.c @@ -84,7 +84,7 @@ smp_message_pass(int target, int msg) /* * Common functions */ -void smp_message_recv(int msg) +void smp_message_recv(int msg, struct pt_regs *regs) { atomic_inc(&ipi_recv); @@ -100,7 +100,7 @@ void smp_message_recv(int msg) break; #ifdef CONFIG_XMON case PPC_MSG_XMON_BREAK: - xmon(get_irq_regs()); + xmon(regs); break; #endif /* CONFIG_XMON */ default: diff --git a/trunk/arch/ppc/kernel/time.c b/trunk/arch/ppc/kernel/time.c index 18ee851e33e3..187388625a76 100644 --- a/trunk/arch/ppc/kernel/time.c +++ b/trunk/arch/ppc/kernel/time.c @@ -62,7 +62,6 @@ #include #include #include -#include #include @@ -130,7 +129,6 @@ void wakeup_decrementer(void) */ void timer_interrupt(struct pt_regs * regs) { - struct pt_regs *old_regs; int next_dec; unsigned long cpu = smp_processor_id(); unsigned jiffy_stamp = last_jiffy_stamp(cpu); @@ -139,13 +137,12 @@ void timer_interrupt(struct pt_regs * regs) if (atomic_read(&ppc_n_lost_interrupts) != 0) do_IRQ(regs); - old_regs = set_irq_regs(regs); irq_enter(); while ((next_dec = tb_ticks_per_jiffy - tb_delta(&jiffy_stamp)) <= 0) { jiffy_stamp += tb_ticks_per_jiffy; - profile_tick(CPU_PROFILING); + profile_tick(CPU_PROFILING, regs); update_process_times(user_mode(regs)); if (smp_processor_id()) @@ -191,7 +188,6 @@ void timer_interrupt(struct pt_regs * regs) ppc_md.heartbeat(); irq_exit(); - set_irq_regs(old_regs); } /* diff --git a/trunk/arch/ppc/kernel/traps.c b/trunk/arch/ppc/kernel/traps.c index 9661a91183b3..aafc8e8893d1 100644 --- a/trunk/arch/ppc/kernel/traps.c +++ b/trunk/arch/ppc/kernel/traps.c @@ -708,7 +708,7 @@ void single_step_exception(struct pt_regs *regs) void alignment_exception(struct pt_regs *regs) { - int sig, code, fixed = 0; + int fixed; fixed = fix_alignment(regs); if (fixed == 1) { @@ -717,16 +717,14 @@ void alignment_exception(struct pt_regs *regs) return; } if (fixed == -EFAULT) { - sig = SIGSEGV; - code = SEGV_ACCERR; - } else { - sig = SIGBUS; - code = BUS_ADRALN; + /* fixed == -EFAULT means the operand address was bad */ + if (user_mode(regs)) + _exception(SIGSEGV, regs, SEGV_ACCERR, regs->dar); + else + bad_page_fault(regs, regs->dar, SIGSEGV); + return; } - if (user_mode(regs)) - _exception(sig, regs, code, regs->dar); - else - bad_page_fault(regs, regs->dar, sig); + _exception(SIGBUS, regs, BUS_ADRALN, regs->dar); } void StackOverflow(struct pt_regs *regs) diff --git a/trunk/arch/ppc/kernel/vmlinux.lds.S b/trunk/arch/ppc/kernel/vmlinux.lds.S index 16e8661e1fec..095fd3323323 100644 --- a/trunk/arch/ppc/kernel/vmlinux.lds.S +++ b/trunk/arch/ppc/kernel/vmlinux.lds.S @@ -115,7 +115,13 @@ SECTIONS __setup_end = .; __initcall_start = .; .initcall.init : { - INITCALLS + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) } __initcall_end = .; diff --git a/trunk/arch/ppc/mm/init.c b/trunk/arch/ppc/mm/init.c index c374e53ae03a..410200046af1 100644 --- a/trunk/arch/ppc/mm/init.c +++ b/trunk/arch/ppc/mm/init.c @@ -374,12 +374,11 @@ void __init paging_init(void) end_pfn = start_pfn + (total_memory >> PAGE_SHIFT); add_active_range(0, start_pfn, end_pfn); - memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); #ifdef CONFIG_HIGHMEM - max_zone_pfns[ZONE_DMA] = total_lowmem >> PAGE_SHIFT; - max_zone_pfns[ZONE_HIGHMEM] = total_memory >> PAGE_SHIFT; + max_zone_pfns[0] = total_lowmem >> PAGE_SHIFT; + max_zone_pfns[1] = total_memory >> PAGE_SHIFT; #else - max_zone_pfns[ZONE_DMA] = total_memory >> PAGE_SHIFT; + max_zone_pfns[0] = total_memory >> PAGE_SHIFT; #endif /* CONFIG_HIGHMEM */ free_area_init_nodes(max_zone_pfns); } diff --git a/trunk/arch/ppc/platforms/85xx/mpc8560_ads.c b/trunk/arch/ppc/platforms/85xx/mpc8560_ads.c index 14ecec7bbed7..94badafe4ef1 100644 --- a/trunk/arch/ppc/platforms/85xx/mpc8560_ads.c +++ b/trunk/arch/ppc/platforms/85xx/mpc8560_ads.c @@ -211,10 +211,10 @@ mpc8560ads_setup_arch(void) #endif } -static irqreturn_t cpm2_cascade(int irq, void *dev_id) +static irqreturn_t cpm2_cascade(int irq, void *dev_id, struct pt_regs *regs) { - while ((irq = cpm2_get_irq()) >= 0) - __do_IRQ(irq); + while ((irq = cpm2_get_irq(regs)) >= 0) + __do_IRQ(irq, regs); return IRQ_HANDLED; } diff --git a/trunk/arch/ppc/platforms/85xx/mpc85xx_cds_common.c b/trunk/arch/ppc/platforms/85xx/mpc85xx_cds_common.c index 5ce0f69c1db6..75204588a3e7 100644 --- a/trunk/arch/ppc/platforms/85xx/mpc85xx_cds_common.c +++ b/trunk/arch/ppc/platforms/85xx/mpc85xx_cds_common.c @@ -127,10 +127,10 @@ mpc85xx_cds_show_cpuinfo(struct seq_file *m) } #ifdef CONFIG_CPM2 -static irqreturn_t cpm2_cascade(int irq, void *dev_id) +static irqreturn_t cpm2_cascade(int irq, void *dev_id, struct pt_regs *regs) { - while((irq = cpm2_get_irq()) >= 0) - __do_IRQ(irq); + while((irq = cpm2_get_irq(regs)) >= 0) + __do_IRQ(irq, regs); return IRQ_HANDLED; } diff --git a/trunk/arch/ppc/platforms/85xx/stx_gp3.c b/trunk/arch/ppc/platforms/85xx/stx_gp3.c index 4bb18ab27672..495aa79bb3a1 100644 --- a/trunk/arch/ppc/platforms/85xx/stx_gp3.c +++ b/trunk/arch/ppc/platforms/85xx/stx_gp3.c @@ -156,10 +156,10 @@ gp3_setup_arch(void) printk ("bi_immr_base = %8.8lx\n", binfo->bi_immr_base); } -static irqreturn_t cpm2_cascade(int irq, void *dev_id) +static irqreturn_t cpm2_cascade(int irq, void *dev_id, struct pt_regs *regs) { - while ((irq = cpm2_get_irq()) >= 0) - __do_IRQ(irq); + while ((irq = cpm2_get_irq(regs)) >= 0) + __do_IRQ(irq, regs); return IRQ_HANDLED; } diff --git a/trunk/arch/ppc/platforms/85xx/tqm85xx.c b/trunk/arch/ppc/platforms/85xx/tqm85xx.c index dd45f2e18449..189ed4175f9f 100644 --- a/trunk/arch/ppc/platforms/85xx/tqm85xx.c +++ b/trunk/arch/ppc/platforms/85xx/tqm85xx.c @@ -181,10 +181,10 @@ tqm85xx_setup_arch(void) } #ifdef CONFIG_MPC8560 -static irqreturn_t cpm2_cascade(int irq, void *dev_id) +static irqreturn_t cpm2_cascade(int irq, void *dev_id, struct pt_regs *regs) { - while ((irq = cpm2_get_irq()) >= 0) - __do_IRQ(irq); + while ((irq = cpm2_get_irq(regs)) >= 0) + __do_IRQ(irq, regs); return IRQ_HANDLED; } diff --git a/trunk/arch/ppc/platforms/apus_setup.c b/trunk/arch/ppc/platforms/apus_setup.c index 063274d2c503..1d034ead2c9a 100644 --- a/trunk/arch/ppc/platforms/apus_setup.c +++ b/trunk/arch/ppc/platforms/apus_setup.c @@ -492,7 +492,7 @@ apus_halt(void) static unsigned char last_ipl[8]; -int apus_get_irq(void) +int apus_get_irq(struct pt_regs* regs) { unsigned char ipl_emu, mask; unsigned int level; diff --git a/trunk/arch/ppc/platforms/hdpu.c b/trunk/arch/ppc/platforms/hdpu.c index d809e17aa536..e0f112a1fd0b 100644 --- a/trunk/arch/ppc/platforms/hdpu.c +++ b/trunk/arch/ppc/platforms/hdpu.c @@ -659,7 +659,8 @@ static void __init hdpu_map_io(void) char hdpu_smp0[] = "SMP Cpu #0"; char hdpu_smp1[] = "SMP Cpu #1"; -static irqreturn_t hdpu_smp_cpu0_int_handler(int irq, void *dev_id) +static irqreturn_t hdpu_smp_cpu0_int_handler(int irq, void *dev_id, + struct pt_regs *regs) { volatile unsigned int doorbell; @@ -669,21 +670,22 @@ static irqreturn_t hdpu_smp_cpu0_int_handler(int irq, void *dev_id) mv64x60_write(&bh, MV64360_CPU0_DOORBELL_CLR, doorbell); if (doorbell & 1) { - smp_message_recv(0); + smp_message_recv(0, regs); } if (doorbell & 2) { - smp_message_recv(1); + smp_message_recv(1, regs); } if (doorbell & 4) { - smp_message_recv(2); + smp_message_recv(2, regs); } if (doorbell & 8) { - smp_message_recv(3); + smp_message_recv(3, regs); } return IRQ_HANDLED; } -static irqreturn_t hdpu_smp_cpu1_int_handler(int irq, void *dev_id) +static irqreturn_t hdpu_smp_cpu1_int_handler(int irq, void *dev_id, + struct pt_regs *regs) { volatile unsigned int doorbell; @@ -693,16 +695,16 @@ static irqreturn_t hdpu_smp_cpu1_int_handler(int irq, void *dev_id) mv64x60_write(&bh, MV64360_CPU1_DOORBELL_CLR, doorbell); if (doorbell & 1) { - smp_message_recv(0); + smp_message_recv(0, regs); } if (doorbell & 2) { - smp_message_recv(1); + smp_message_recv(1, regs); } if (doorbell & 4) { - smp_message_recv(2); + smp_message_recv(2, regs); } if (doorbell & 8) { - smp_message_recv(3); + smp_message_recv(3, regs); } return IRQ_HANDLED; } diff --git a/trunk/arch/ppc/platforms/mpc8272ads_setup.c b/trunk/arch/ppc/platforms/mpc8272ads_setup.c index 1f9ea36837b1..d7b3a6afa78f 100644 --- a/trunk/arch/ppc/platforms/mpc8272ads_setup.c +++ b/trunk/arch/ppc/platforms/mpc8272ads_setup.c @@ -196,7 +196,7 @@ static void __init mpc8272ads_fixup_enet_pdata(struct platform_device *pdev, bd_t* bi = (void*)__res; int fs_no = fsid_fcc1+pdev->id-1; - if(fs_no >= ARRAY_SIZE(mpc82xx_enet_pdata)) { + if(fs_no > ARRAY_SIZE(mpc82xx_enet_pdata)) { return; } @@ -222,7 +222,7 @@ static void mpc8272ads_fixup_uart_pdata(struct platform_device *pdev, int id = fs_uart_id_scc2fsid(idx); /* no need to alter anything if console */ - if ((id < num) && (!pdev->dev.platform_data)) { + if ((id <= num) && (!pdev->dev.platform_data)) { pinfo = &mpc8272_uart_pdata[id]; pinfo->uart_clk = bd->bi_intfreq; pdev->dev.platform_data = pinfo; diff --git a/trunk/arch/ppc/platforms/mpc866ads_setup.c b/trunk/arch/ppc/platforms/mpc866ads_setup.c index e95d2c111747..5f130dca3770 100644 --- a/trunk/arch/ppc/platforms/mpc866ads_setup.c +++ b/trunk/arch/ppc/platforms/mpc866ads_setup.c @@ -259,7 +259,7 @@ static void mpc866ads_fixup_enet_pdata(struct platform_device *pdev, int fs_no) /* Get pointer to Communication Processor */ cp = cpmp; - if(fs_no >= ARRAY_SIZE(mpc8xx_enet_pdata)) { + if(fs_no > ARRAY_SIZE(mpc8xx_enet_pdata)) { printk(KERN_ERR"No network-suitable #%d device on bus", fs_no); return; } @@ -305,7 +305,7 @@ static void __init mpc866ads_fixup_uart_pdata(struct platform_device *pdev, int id = fs_uart_id_smc2fsid(idx); /* no need to alter anything if console */ - if ((id < num) && (!pdev->dev.platform_data)) { + if ((id <= num) && (!pdev->dev.platform_data)) { pinfo = &mpc866_uart_pdata[id]; pinfo->uart_clk = bd->bi_intfreq; pdev->dev.platform_data = pinfo; diff --git a/trunk/arch/ppc/platforms/mpc885ads_setup.c b/trunk/arch/ppc/platforms/mpc885ads_setup.c index f8161f3557f5..02293141efb5 100644 --- a/trunk/arch/ppc/platforms/mpc885ads_setup.c +++ b/trunk/arch/ppc/platforms/mpc885ads_setup.c @@ -263,7 +263,7 @@ static void mpc885ads_fixup_enet_pdata(struct platform_device *pdev, int fs_no) char *e; int i; - if(fs_no >= ARRAY_SIZE(mpc8xx_enet_pdata)) { + if(fs_no > ARRAY_SIZE(mpc8xx_enet_pdata)) { printk(KERN_ERR"No network-suitable #%d device on bus", fs_no); return; } @@ -371,7 +371,7 @@ static void __init mpc885ads_fixup_uart_pdata(struct platform_device *pdev, int id = fs_uart_id_smc2fsid(idx); /* no need to alter anything if console */ - if ((id < num) && (!pdev->dev.platform_data)) { + if ((id <= num) && (!pdev->dev.platform_data)) { pinfo = &mpc885_uart_pdata[id]; pinfo->uart_clk = bd->bi_intfreq; pdev->dev.platform_data = pinfo; diff --git a/trunk/arch/ppc/platforms/radstone_ppc7d.c b/trunk/arch/ppc/platforms/radstone_ppc7d.c index 13d70ab50bf1..3bb530af0297 100644 --- a/trunk/arch/ppc/platforms/radstone_ppc7d.c +++ b/trunk/arch/ppc/platforms/radstone_ppc7d.c @@ -451,11 +451,11 @@ static void __init ppc7d_calibrate_decr(void) * Interrupt stuff *****************************************************************************/ -static irqreturn_t ppc7d_i8259_intr(int irq, void *dev_id) +static irqreturn_t ppc7d_i8259_intr(int irq, void *dev_id, struct pt_regs *regs) { u32 temp = mv64x60_read(&bh, MV64x60_GPP_INTR_CAUSE); if (temp & (1 << 28)) { - i8259_irq(); + i8259_irq(regs); mv64x60_write(&bh, MV64x60_GPP_INTR_CAUSE, temp & (~(1 << 28))); return IRQ_HANDLED; } @@ -536,13 +536,13 @@ static u32 ppc7d_irq_canonicalize(u32 irq) return irq; } -static int ppc7d_get_irq(void) +static int ppc7d_get_irq(struct pt_regs *regs) { int irq; - irq = mv64360_get_irq(); + irq = mv64360_get_irq(regs); if (irq == (mv64360_irq_base + MV64x60_IRQ_GPP28)) - irq = i8259_irq(); + irq = i8259_irq(regs); return irq; } diff --git a/trunk/arch/ppc/platforms/sbc82xx.c b/trunk/arch/ppc/platforms/sbc82xx.c index cc0935ccab7a..60b769c7f3fc 100644 --- a/trunk/arch/ppc/platforms/sbc82xx.c +++ b/trunk/arch/ppc/platforms/sbc82xx.c @@ -121,7 +121,7 @@ struct hw_interrupt_type sbc82xx_i8259_ic = { .end = sbc82xx_i8259_end_irq, }; -static irqreturn_t sbc82xx_i8259_demux(int irq, void *dev_id) +static irqreturn_t sbc82xx_i8259_demux(int irq, void *dev_id, struct pt_regs *regs) { spin_lock(&sbc82xx_i8259_lock); @@ -139,7 +139,7 @@ static irqreturn_t sbc82xx_i8259_demux(int irq, void *dev_id) return IRQ_HANDLED; } } - __do_IRQ(NR_SIU_INTS + irq); + __do_IRQ(NR_SIU_INTS + irq, regs); return IRQ_HANDLED; } diff --git a/trunk/arch/ppc/syslib/cpc700.h b/trunk/arch/ppc/syslib/cpc700.h index 987e9aa0dd45..0a8a5d84390f 100644 --- a/trunk/arch/ppc/syslib/cpc700.h +++ b/trunk/arch/ppc/syslib/cpc700.h @@ -91,6 +91,6 @@ extern struct hw_interrupt_type cpc700_pic; extern unsigned int cpc700_irq_assigns[32][2]; extern void __init cpc700_init_IRQ(void); -extern int cpc700_get_irq(void); +extern int cpc700_get_irq(struct pt_regs *); #endif /* __PPC_SYSLIB_CPC700_H__ */ diff --git a/trunk/arch/ppc/syslib/cpc700_pic.c b/trunk/arch/ppc/syslib/cpc700_pic.c index d48e8f45c050..172aa215fdb0 100644 --- a/trunk/arch/ppc/syslib/cpc700_pic.c +++ b/trunk/arch/ppc/syslib/cpc700_pic.c @@ -158,7 +158,7 @@ cpc700_init_IRQ(void) * Find the highest IRQ that generating an interrupt, if any. */ int -cpc700_get_irq(void) +cpc700_get_irq(struct pt_regs *regs) { int irq = 0; u_int irq_status, irq_test = 1; diff --git a/trunk/arch/ppc/syslib/cpm2_pic.c b/trunk/arch/ppc/syslib/cpm2_pic.c index fb2d5842641a..c0fee0beb815 100644 --- a/trunk/arch/ppc/syslib/cpm2_pic.c +++ b/trunk/arch/ppc/syslib/cpm2_pic.c @@ -123,7 +123,7 @@ static struct hw_interrupt_type cpm2_pic = { .end = cpm2_end_irq, }; -int cpm2_get_irq(void) +int cpm2_get_irq(struct pt_regs *regs) { int irq; unsigned long bits; diff --git a/trunk/arch/ppc/syslib/cpm2_pic.h b/trunk/arch/ppc/syslib/cpm2_pic.h index 467339337a78..97cab8f13a1a 100644 --- a/trunk/arch/ppc/syslib/cpm2_pic.h +++ b/trunk/arch/ppc/syslib/cpm2_pic.h @@ -1,7 +1,7 @@ #ifndef _PPC_KERNEL_CPM2_H #define _PPC_KERNEL_CPM2_H -extern int cpm2_get_irq(void); +extern int cpm2_get_irq(struct pt_regs *regs); extern void cpm2_init_IRQ(void); diff --git a/trunk/arch/ppc/syslib/gt64260_pic.c b/trunk/arch/ppc/syslib/gt64260_pic.c index e84d432c0657..7fd550a7d586 100644 --- a/trunk/arch/ppc/syslib/gt64260_pic.c +++ b/trunk/arch/ppc/syslib/gt64260_pic.c @@ -110,6 +110,9 @@ gt64260_init_irq(void) * This function returns the lowest interrupt number of all interrupts that * are currently asserted. * + * Input Variable(s): + * struct pt_regs* not used + * * Output Variable(s): * None. * @@ -117,7 +120,7 @@ gt64260_init_irq(void) * int or -2 (bogus interrupt) */ int -gt64260_get_irq(void) +gt64260_get_irq(struct pt_regs *regs) { int irq; int irq_gpp; @@ -226,7 +229,7 @@ gt64260_mask_irq(unsigned int irq) } static irqreturn_t -gt64260_cpu_error_int_handler(int irq, void *dev_id) +gt64260_cpu_error_int_handler(int irq, void *dev_id, struct pt_regs *regs) { printk(KERN_ERR "gt64260_cpu_error_int_handler: %s 0x%08x\n", "Error on CPU interface - Cause regiser", @@ -247,7 +250,7 @@ gt64260_cpu_error_int_handler(int irq, void *dev_id) } static irqreturn_t -gt64260_pci_error_int_handler(int irq, void *dev_id) +gt64260_pci_error_int_handler(int irq, void *dev_id, struct pt_regs *regs) { u32 val; unsigned int pci_bus = (unsigned int)dev_id; diff --git a/trunk/arch/ppc/syslib/i8259.c b/trunk/arch/ppc/syslib/i8259.c index a43dda5a8334..eb35353af837 100644 --- a/trunk/arch/ppc/syslib/i8259.c +++ b/trunk/arch/ppc/syslib/i8259.c @@ -28,7 +28,7 @@ static int i8259_pic_irq_offset; * which is called. It should be noted that polling is broken on some * IBM and Motorola PReP boxes so we must use the int-ack feature on them. */ -int i8259_irq(void) +int i8259_irq(struct pt_regs *regs) { int irq; diff --git a/trunk/arch/ppc/syslib/ibm440gx_common.c b/trunk/arch/ppc/syslib/ibm440gx_common.c index 6ad52f4a26e1..4b77e6c8c87f 100644 --- a/trunk/arch/ppc/syslib/ibm440gx_common.c +++ b/trunk/arch/ppc/syslib/ibm440gx_common.c @@ -119,7 +119,7 @@ static inline u32 l2c_diag(u32 addr) return mfdcr(DCRN_L2C0_DATA); } -static irqreturn_t l2c_error_handler(int irq, void* dev) +static irqreturn_t l2c_error_handler(int irq, void* dev, struct pt_regs* regs) { u32 sr = mfdcr(DCRN_L2C0_SR); if (sr & L2C_SR_CPE){ diff --git a/trunk/arch/ppc/syslib/ipic.c b/trunk/arch/ppc/syslib/ipic.c index 10659c24b1be..46801f5ec03f 100644 --- a/trunk/arch/ppc/syslib/ipic.c +++ b/trunk/arch/ppc/syslib/ipic.c @@ -601,7 +601,7 @@ void ipic_clear_mcp_status(u32 mask) } /* Return an interrupt vector or -1 if no interrupt is pending. */ -int ipic_get_irq(void) +int ipic_get_irq(struct pt_regs *regs) { int irq; diff --git a/trunk/arch/ppc/syslib/m82xx_pci.c b/trunk/arch/ppc/syslib/m82xx_pci.c index e3b586b1ede9..d3fa264e179e 100644 --- a/trunk/arch/ppc/syslib/m82xx_pci.c +++ b/trunk/arch/ppc/syslib/m82xx_pci.c @@ -117,7 +117,7 @@ struct hw_interrupt_type pq2pci_ic = { }; static irqreturn_t -pq2pci_irq_demux(int irq, void *dev_id) +pq2pci_irq_demux(int irq, void *dev_id, struct pt_regs *regs) { unsigned long stat, mask, pend; int bit; @@ -130,7 +130,7 @@ pq2pci_irq_demux(int irq, void *dev_id) break; for (bit = 0; pend != 0; ++bit, pend <<= 1) { if (pend & 0x80000000) - __do_IRQ(NR_CPM_INTS + bit); + __do_IRQ(NR_CPM_INTS + bit, regs); } } diff --git a/trunk/arch/ppc/syslib/m8xx_setup.c b/trunk/arch/ppc/syslib/m8xx_setup.c index d8d299bd1a12..54303a7b4e69 100644 --- a/trunk/arch/ppc/syslib/m8xx_setup.c +++ b/trunk/arch/ppc/syslib/m8xx_setup.c @@ -169,7 +169,7 @@ abort(void) } /* A place holder for time base interrupts, if they are ever enabled. */ -irqreturn_t timebase_interrupt(int irq, void * dev) +irqreturn_t timebase_interrupt(int irq, void * dev, struct pt_regs * regs) { printk ("timebase_interrupt()\n"); diff --git a/trunk/arch/ppc/syslib/m8xx_wdt.c b/trunk/arch/ppc/syslib/m8xx_wdt.c index fffac8cbeb51..ac11d7bab443 100644 --- a/trunk/arch/ppc/syslib/m8xx_wdt.c +++ b/trunk/arch/ppc/syslib/m8xx_wdt.c @@ -21,7 +21,7 @@ static int wdt_timeout; int m8xx_has_internal_rtc = 0; -static irqreturn_t m8xx_wdt_interrupt(int, void *); +static irqreturn_t m8xx_wdt_interrupt(int, void *, struct pt_regs *); static struct irqaction m8xx_wdt_irqaction = { .handler = m8xx_wdt_interrupt, .name = "watchdog", @@ -35,7 +35,7 @@ void m8xx_wdt_reset(void) out_be16(&imap->im_siu_conf.sc_swsr, 0xaa39); /* write magic2 */ } -static irqreturn_t m8xx_wdt_interrupt(int irq, void *dev) +static irqreturn_t m8xx_wdt_interrupt(int irq, void *dev, struct pt_regs *regs) { volatile immap_t *imap = (volatile immap_t *)IMAP_ADDR; diff --git a/trunk/arch/ppc/syslib/mpc52xx_pic.c b/trunk/arch/ppc/syslib/mpc52xx_pic.c index af35a316544a..6425b5cee7db 100644 --- a/trunk/arch/ppc/syslib/mpc52xx_pic.c +++ b/trunk/arch/ppc/syslib/mpc52xx_pic.c @@ -220,7 +220,7 @@ mpc52xx_init_irq(void) } int -mpc52xx_get_irq(void) +mpc52xx_get_irq(struct pt_regs *regs) { u32 status; int irq = -1; diff --git a/trunk/arch/ppc/syslib/mv64360_pic.c b/trunk/arch/ppc/syslib/mv64360_pic.c index 4b7a3338e122..3f6d162f87cf 100644 --- a/trunk/arch/ppc/syslib/mv64360_pic.c +++ b/trunk/arch/ppc/syslib/mv64360_pic.c @@ -55,9 +55,10 @@ static void mv64360_unmask_irq(unsigned int); static void mv64360_mask_irq(unsigned int); -static irqreturn_t mv64360_cpu_error_int_handler(int, void *); -static irqreturn_t mv64360_sram_error_int_handler(int, void *); -static irqreturn_t mv64360_pci_error_int_handler(int, void *); +static irqreturn_t mv64360_cpu_error_int_handler(int, void *, struct pt_regs *); +static irqreturn_t mv64360_sram_error_int_handler(int, void *, + struct pt_regs *); +static irqreturn_t mv64360_pci_error_int_handler(int, void *, struct pt_regs *); /* ========================== local declarations =========================== */ @@ -130,6 +131,9 @@ mv64360_init_irq(void) * This function returns the lowest interrupt number of all interrupts that * are currently asserted. * + * Input Variable(s): + * struct pt_regs* not used + * * Output Variable(s): * None. * @@ -138,7 +142,7 @@ mv64360_init_irq(void) * */ int -mv64360_get_irq(void) +mv64360_get_irq(struct pt_regs *regs) { int irq; int irq_gpp; @@ -279,7 +283,7 @@ mv64360_mask_irq(unsigned int irq) } static irqreturn_t -mv64360_cpu_error_int_handler(int irq, void *dev_id) +mv64360_cpu_error_int_handler(int irq, void *dev_id, struct pt_regs *regs) { printk(KERN_ERR "mv64360_cpu_error_int_handler: %s 0x%08x\n", "Error on CPU interface - Cause regiser", @@ -300,7 +304,7 @@ mv64360_cpu_error_int_handler(int irq, void *dev_id) } static irqreturn_t -mv64360_sram_error_int_handler(int irq, void *dev_id) +mv64360_sram_error_int_handler(int irq, void *dev_id, struct pt_regs *regs) { printk(KERN_ERR "mv64360_sram_error_int_handler: %s 0x%08x\n", "Error in internal SRAM - Cause register", @@ -321,7 +325,7 @@ mv64360_sram_error_int_handler(int irq, void *dev_id) } static irqreturn_t -mv64360_pci_error_int_handler(int irq, void *dev_id) +mv64360_pci_error_int_handler(int irq, void *dev_id, struct pt_regs *regs) { u32 val; unsigned int pci_bus = (unsigned int)dev_id; @@ -376,7 +380,7 @@ mv64360_register_hdlrs(void) /* Clear old errors and register CPU interface error intr handler */ mv64x60_write(&bh, MV64x60_CPU_ERR_CAUSE, 0); if ((rc = request_irq(MV64x60_IRQ_CPU_ERR + mv64360_irq_base, - mv64360_cpu_error_int_handler, IRQF_DISABLED, CPU_INTR_STR, NULL))) + mv64360_cpu_error_int_handler, IRQF_DISABLED, CPU_INTR_STR, 0))) printk(KERN_WARNING "Can't register cpu error handler: %d", rc); mv64x60_write(&bh, MV64x60_CPU_ERR_MASK, 0); @@ -385,7 +389,7 @@ mv64360_register_hdlrs(void) /* Clear old errors and register internal SRAM error intr handler */ mv64x60_write(&bh, MV64360_SRAM_ERR_CAUSE, 0); if ((rc = request_irq(MV64360_IRQ_SRAM_PAR_ERR + mv64360_irq_base, - mv64360_sram_error_int_handler,IRQF_DISABLED,SRAM_INTR_STR, NULL))) + mv64360_sram_error_int_handler,IRQF_DISABLED,SRAM_INTR_STR, 0))) printk(KERN_WARNING "Can't register SRAM error handler: %d",rc); /* Clear old errors and register PCI 0 error intr handler */ diff --git a/trunk/arch/ppc/syslib/open_pic.c b/trunk/arch/ppc/syslib/open_pic.c index 18ec94733293..aa0b95788705 100644 --- a/trunk/arch/ppc/syslib/open_pic.c +++ b/trunk/arch/ppc/syslib/open_pic.c @@ -45,7 +45,7 @@ static u_int NumSources; static int open_pic_irq_offset; static volatile OpenPIC_Source __iomem *ISR[NR_IRQS]; static int openpic_cascade_irq = -1; -static int (*openpic_cascade_fn)(void); +static int (*openpic_cascade_fn)(struct pt_regs *); /* Global Operations */ static void openpic_disable_8259_pass_through(void); @@ -54,7 +54,7 @@ static void openpic_set_spurious(u_int vector); #ifdef CONFIG_SMP /* Interprocessor Interrupts */ static void openpic_initipi(u_int ipi, u_int pri, u_int vector); -static irqreturn_t openpic_ipi_action(int cpl, void *dev_id); +static irqreturn_t openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *); #endif /* Timer Interrupts */ @@ -700,7 +700,7 @@ static struct irqaction openpic_cascade_irqaction = { void __init openpic_hookup_cascade(u_int irq, char *name, - int (*cascade_fn)(void)) + int (*cascade_fn)(struct pt_regs *)) { openpic_cascade_irq = irq; openpic_cascade_fn = cascade_fn; @@ -857,16 +857,16 @@ static void openpic_end_ipi(unsigned int irq_nr) { } -static irqreturn_t openpic_ipi_action(int cpl, void *dev_id) +static irqreturn_t openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs) { - smp_message_recv(cpl-OPENPIC_VEC_IPI-open_pic_irq_offset); + smp_message_recv(cpl-OPENPIC_VEC_IPI-open_pic_irq_offset, regs); return IRQ_HANDLED; } #endif /* CONFIG_SMP */ int -openpic_get_irq(void) +openpic_get_irq(struct pt_regs *regs) { int irq = openpic_irq(); @@ -876,7 +876,7 @@ openpic_get_irq(void) * This should move to irq.c eventually. -- paulus */ if (irq == openpic_cascade_irq && openpic_cascade_fn != NULL) { - int cirq = openpic_cascade_fn(); + int cirq = openpic_cascade_fn(regs); /* Allow for the cascade being shared with other devices */ if (cirq != -1) { diff --git a/trunk/arch/ppc/syslib/open_pic2.c b/trunk/arch/ppc/syslib/open_pic2.c index d585207f9f77..e1ff971539ea 100644 --- a/trunk/arch/ppc/syslib/open_pic2.c +++ b/trunk/arch/ppc/syslib/open_pic2.c @@ -529,7 +529,7 @@ static void openpic2_end_irq(unsigned int irq_nr) } int -openpic2_get_irq(void) +openpic2_get_irq(struct pt_regs *regs) { int irq = openpic2_irq(); diff --git a/trunk/arch/ppc/syslib/ppc403_pic.c b/trunk/arch/ppc/syslib/ppc403_pic.c index 607ebd111d44..1584c8b1229f 100644 --- a/trunk/arch/ppc/syslib/ppc403_pic.c +++ b/trunk/arch/ppc/syslib/ppc403_pic.c @@ -42,7 +42,7 @@ static struct hw_interrupt_type ppc403_aic = { }; int -ppc403_pic_get_irq(void) +ppc403_pic_get_irq(struct pt_regs *regs) { int irq; unsigned long bits; diff --git a/trunk/arch/ppc/syslib/ppc4xx_pic.c b/trunk/arch/ppc/syslib/ppc4xx_pic.c index ee0da4b4b993..745685df5984 100644 --- a/trunk/arch/ppc/syslib/ppc4xx_pic.c +++ b/trunk/arch/ppc/syslib/ppc4xx_pic.c @@ -96,7 +96,7 @@ UIC_HANDLERS(1); UIC_HANDLERS(2); UIC_HANDLERS(3); -static int ppc4xx_pic_get_irq(void) +static int ppc4xx_pic_get_irq(struct pt_regs *regs) { u32 uic0 = mfdcr(DCRN_UIC_MSR(UIC0)); if (uic0 & UIC0_UIC1NC) @@ -125,7 +125,7 @@ UIC_HANDLERS(0); UIC_HANDLERS(1); UIC_HANDLERS(2); -static int ppc4xx_pic_get_irq(void) +static int ppc4xx_pic_get_irq(struct pt_regs *regs) { u32 uicb = mfdcr(DCRN_UIC_MSR(UICB)); if (uicb & UICB_UIC0NC) @@ -158,7 +158,7 @@ static void __init ppc4xx_pic_impl_init(void) UIC_HANDLERS(0); UIC_HANDLERS(1); -static int ppc4xx_pic_get_irq(void) +static int ppc4xx_pic_get_irq(struct pt_regs *regs) { u32 uic0 = mfdcr(DCRN_UIC_MSR(UIC0)); if (uic0 & UIC0_UIC1NC) @@ -179,7 +179,7 @@ static void __init ppc4xx_pic_impl_init(void) #define ACK_UIC0_PARENT UIC_HANDLERS(0); -static int ppc4xx_pic_get_irq(void) +static int ppc4xx_pic_get_irq(struct pt_regs *regs) { u32 uic0 = mfdcr(DCRN_UIC_MSR(UIC0)); return uic0 ? 32 - ffs(uic0) : -1; diff --git a/trunk/arch/ppc/syslib/ppc85xx_rio.c b/trunk/arch/ppc/syslib/ppc85xx_rio.c index 05b0e9415085..d9b471b4d695 100644 --- a/trunk/arch/ppc/syslib/ppc85xx_rio.c +++ b/trunk/arch/ppc/syslib/ppc85xx_rio.c @@ -349,12 +349,13 @@ EXPORT_SYMBOL_GPL(rio_hw_add_outb_message); * mpc85xx_rio_tx_handler - MPC85xx outbound message interrupt handler * @irq: Linux interrupt number * @dev_instance: Pointer to interrupt-specific data + * @regs: Register context * * Handles outbound message interrupts. Executes a register outbound * mailbox event handler and acks the interrupt occurence. */ static irqreturn_t -mpc85xx_rio_tx_handler(int irq, void *dev_instance) +mpc85xx_rio_tx_handler(int irq, void *dev_instance, struct pt_regs *regs) { int osr; struct rio_mport *port = (struct rio_mport *)dev_instance; @@ -516,12 +517,13 @@ void rio_close_outb_mbox(struct rio_mport *mport, int mbox) * mpc85xx_rio_rx_handler - MPC85xx inbound message interrupt handler * @irq: Linux interrupt number * @dev_instance: Pointer to interrupt-specific data + * @regs: Register context * * Handles inbound message interrupts. Executes a registered inbound * mailbox event handler and acks the interrupt occurence. */ static irqreturn_t -mpc85xx_rio_rx_handler(int irq, void *dev_instance) +mpc85xx_rio_rx_handler(int irq, void *dev_instance, struct pt_regs *regs) { int isr; struct rio_mport *port = (struct rio_mport *)dev_instance; @@ -734,12 +736,13 @@ EXPORT_SYMBOL_GPL(rio_hw_get_inb_message); * mpc85xx_rio_dbell_handler - MPC85xx doorbell interrupt handler * @irq: Linux interrupt number * @dev_instance: Pointer to interrupt-specific data + * @regs: Register context * * Handles doorbell interrupts. Parses a list of registered * doorbell event handlers and executes a matching event handler. */ static irqreturn_t -mpc85xx_rio_dbell_handler(int irq, void *dev_instance) +mpc85xx_rio_dbell_handler(int irq, void *dev_instance, struct pt_regs *regs) { int dsr; struct rio_mport *port = (struct rio_mport *)dev_instance; diff --git a/trunk/arch/ppc/syslib/ppc8xx_pic.c b/trunk/arch/ppc/syslib/ppc8xx_pic.c index e8619c750732..d6c25fe25011 100644 --- a/trunk/arch/ppc/syslib/ppc8xx_pic.c +++ b/trunk/arch/ppc/syslib/ppc8xx_pic.c @@ -10,7 +10,7 @@ #include #include "ppc8xx_pic.h" -extern int cpm_get_irq(void); +extern int cpm_get_irq(struct pt_regs *regs); /* The 8xx internal interrupt controller. It is usually * the only interrupt controller. Some boards, like the MBX and @@ -96,7 +96,7 @@ m8xx_get_irq(struct pt_regs *regs) * get back SIU_LEVEL7. In this case, return -1 */ if (irq == CPM_INTERRUPT) - irq = CPM_IRQ_OFFSET + cpm_get_irq(); + irq = CPM_IRQ_OFFSET + cpm_get_irq(regs); #if defined(CONFIG_PCI) else if (irq == ISA_BRIDGE_INT) { int isa_irq; diff --git a/trunk/arch/ppc/syslib/xilinx_pic.c b/trunk/arch/ppc/syslib/xilinx_pic.c index 6fd4cdbada72..39a93dc6375b 100644 --- a/trunk/arch/ppc/syslib/xilinx_pic.c +++ b/trunk/arch/ppc/syslib/xilinx_pic.c @@ -86,7 +86,7 @@ static struct hw_interrupt_type xilinx_intc = { }; int -xilinx_pic_get_irq(void) +xilinx_pic_get_irq(struct pt_regs *regs) { int irq; diff --git a/trunk/arch/s390/Kconfig b/trunk/arch/s390/Kconfig index 245b81bc7157..51c2dfe89c62 100644 --- a/trunk/arch/s390/Kconfig +++ b/trunk/arch/s390/Kconfig @@ -30,9 +30,6 @@ config GENERIC_CALIBRATE_DELAY bool default y -config GENERIC_TIME - def_bool y - config GENERIC_BUST_SPINLOCK bool @@ -236,6 +233,9 @@ config WARN_STACK_SIZE This allows you to specify the maximum frame size a function may have without the compiler complaining about it. +config ARCH_POPULATES_NODE_MAP + def_bool y + source "mm/Kconfig" comment "I/O subsystem configuration" diff --git a/trunk/arch/s390/appldata/appldata_base.c b/trunk/arch/s390/appldata/appldata_base.c index af1e8fc7d985..2b1e6c9a6e0e 100644 --- a/trunk/arch/s390/appldata/appldata_base.c +++ b/trunk/arch/s390/appldata/appldata_base.c @@ -109,7 +109,7 @@ static LIST_HEAD(appldata_ops_list); * * schedule work and reschedule timer */ -static void appldata_timer_function(unsigned long data) +static void appldata_timer_function(unsigned long data, struct pt_regs *regs) { P_DEBUG(" -= Timer =-\n"); P_DEBUG("CPU: %i, expire_count: %i\n", smp_processor_id(), @@ -310,7 +310,6 @@ appldata_interval_handler(ctl_table *ctl, int write, struct file *filp, if (copy_from_user(buf, buffer, len > sizeof(buf) ? sizeof(buf) : len)) { return -EFAULT; } - interval = 0; sscanf(buf, "%i", &interval); if (interval <= 0) { P_ERROR("Timer CPU interval has to be > 0!\n"); diff --git a/trunk/arch/s390/defconfig b/trunk/arch/s390/defconfig index 7cd51e73e274..b6cad75fd1f4 100644 --- a/trunk/arch/s390/defconfig +++ b/trunk/arch/s390/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.19-rc2 -# Wed Oct 18 17:11:10 2006 +# Linux kernel version: 2.6.18 +# Wed Oct 4 19:45:46 2006 # CONFIG_MMU=y CONFIG_LOCKDEP_SUPPORT=y @@ -9,7 +9,6 @@ CONFIG_STACKTRACE_SUPPORT=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_TIME=y CONFIG_S390=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" @@ -119,6 +118,7 @@ CONFIG_PACK_STACK=y CONFIG_CHECK_STACK=y CONFIG_STACK_GUARD=256 # CONFIG_WARN_STACK is not set +CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y # CONFIG_DISCONTIGMEM_MANUAL is not set @@ -210,7 +210,6 @@ CONFIG_INET6_XFRM_MODE_TRANSPORT=y CONFIG_INET6_XFRM_MODE_TUNNEL=y CONFIG_INET6_XFRM_MODE_BEET=y # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set -CONFIG_IPV6_SIT=y # CONFIG_IPV6_TUNNEL is not set # CONFIG_IPV6_SUBTREES is not set # CONFIG_IPV6_MULTIPLE_TABLES is not set @@ -528,7 +527,6 @@ CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y # CONFIG_EXT3_FS_POSIX_ACL is not set # CONFIG_EXT3_FS_SECURITY is not set -# CONFIG_EXT4DEV_FS is not set CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set CONFIG_FS_MBCACHE=y @@ -646,6 +644,10 @@ CONFIG_MSDOS_PARTITION=y # # CONFIG_NLS is not set +# +# Distributed Lock Manager +# + # # Instrumentation Support # @@ -666,6 +668,7 @@ CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_KERNEL=y CONFIG_LOG_BUF_SHIFT=17 +# CONFIG_DETECT_SOFTLOCKUP is not set # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set CONFIG_DEBUG_PREEMPT=y @@ -686,7 +689,6 @@ CONFIG_DEBUG_FS=y # CONFIG_FRAME_POINTER is not set # CONFIG_UNWIND_INFO is not set CONFIG_FORCED_INLINING=y -CONFIG_HEADERS_CHECK=y # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_LKDTM is not set diff --git a/trunk/arch/s390/kernel/compat_linux.c b/trunk/arch/s390/kernel/compat_linux.c index 5b33f823863a..e15e1489aef5 100644 --- a/trunk/arch/s390/kernel/compat_linux.c +++ b/trunk/arch/s390/kernel/compat_linux.c @@ -295,7 +295,6 @@ static inline long put_tv32(struct compat_timeval __user *o, struct timeval *i) * * This is really horribly ugly. */ -#ifdef CONFIG_SYSVIPC asmlinkage long sys32_ipc(u32 call, int first, int second, int third, u32 ptr) { if (call >> 16) /* hack for backward compatibility */ @@ -339,7 +338,6 @@ asmlinkage long sys32_ipc(u32 call, int first, int second, int third, u32 ptr) return -ENOSYS; } -#endif asmlinkage long sys32_truncate64(const char __user * path, unsigned long high, unsigned long low) { @@ -757,9 +755,7 @@ asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args) put_user(oldlen, (u32 __user *)compat_ptr(tmp.oldlenp))) error = -EFAULT; } - if (copy_to_user(args->__unused, tmp.__unused, - sizeof(tmp.__unused))) - error = -EFAULT; + copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused)); } return error; } diff --git a/trunk/arch/s390/kernel/compat_signal.c b/trunk/arch/s390/kernel/compat_signal.c index 861888ab8c13..d49b876a83bf 100644 --- a/trunk/arch/s390/kernel/compat_signal.c +++ b/trunk/arch/s390/kernel/compat_signal.c @@ -169,12 +169,12 @@ sys32_sigaction(int sig, const struct old_sigaction32 __user *act, compat_old_sigset_t mask; if (!access_ok(VERIFY_READ, act, sizeof(*act)) || __get_user(sa_handler, &act->sa_handler) || - __get_user(sa_restorer, &act->sa_restorer) || - __get_user(new_ka.sa.sa_flags, &act->sa_flags) || - __get_user(mask, &act->sa_mask)) + __get_user(sa_restorer, &act->sa_restorer)) return -EFAULT; new_ka.sa.sa_handler = (__sighandler_t) sa_handler; new_ka.sa.sa_restorer = (void (*)(void)) sa_restorer; + __get_user(new_ka.sa.sa_flags, &act->sa_flags); + __get_user(mask, &act->sa_mask); siginitset(&new_ka.sa.sa_mask, mask); } @@ -185,10 +185,10 @@ sys32_sigaction(int sig, const struct old_sigaction32 __user *act, sa_restorer = (unsigned long) old_ka.sa.sa_restorer; if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || __put_user(sa_handler, &oact->sa_handler) || - __put_user(sa_restorer, &oact->sa_restorer) || - __put_user(old_ka.sa.sa_flags, &oact->sa_flags) || - __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask)) + __put_user(sa_restorer, &oact->sa_restorer)) return -EFAULT; + __put_user(old_ka.sa.sa_flags, &oact->sa_flags); + __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); } return ret; diff --git a/trunk/arch/s390/kernel/compat_wrapper.S b/trunk/arch/s390/kernel/compat_wrapper.S index 71e54ef0931e..cb0efae6802f 100644 --- a/trunk/arch/s390/kernel/compat_wrapper.S +++ b/trunk/arch/s390/kernel/compat_wrapper.S @@ -1664,4 +1664,4 @@ sys_getcpu_wrapper: llgtr %r2,%r2 # unsigned * llgtr %r3,%r3 # unsigned * llgtr %r4,%r4 # struct getcpu_cache * - jg sys_getcpu + jg sys_tee diff --git a/trunk/arch/s390/kernel/s390_ext.c b/trunk/arch/s390/kernel/s390_ext.c index 4faf96f8a834..c1b383537fec 100644 --- a/trunk/arch/s390/kernel/s390_ext.c +++ b/trunk/arch/s390/kernel/s390_ext.c @@ -16,7 +16,6 @@ #include #include -#include #include /* @@ -115,9 +114,7 @@ void do_extint(struct pt_regs *regs, unsigned short code) { ext_int_info_t *p; int index; - struct pt_regs *old_regs; - old_regs = set_irq_regs(regs); irq_enter(); asm volatile ("mc 0,0"); if (S390_lowcore.int_clock >= S390_lowcore.jiffy_timer) @@ -125,18 +122,18 @@ void do_extint(struct pt_regs *regs, unsigned short code) * Make sure that the i/o interrupt did not "overtake" * the last HZ timer interrupt. */ - account_ticks(); + account_ticks(regs); kstat_cpu(smp_processor_id()).irqs[EXTERNAL_INTERRUPT]++; index = ext_hash(code); for (p = ext_int_hash[index]; p; p = p->next) { if (likely(p->code == code)) { if (likely(p->handler)) - p->handler(code); + p->handler(regs, code); } } irq_exit(); - set_irq_regs(old_regs); } EXPORT_SYMBOL(register_external_interrupt); EXPORT_SYMBOL(unregister_external_interrupt); + diff --git a/trunk/arch/s390/kernel/s390_ksyms.c b/trunk/arch/s390/kernel/s390_ksyms.c index 90b5ef529eb7..9f19e833a562 100644 --- a/trunk/arch/s390/kernel/s390_ksyms.c +++ b/trunk/arch/s390/kernel/s390_ksyms.c @@ -51,3 +51,4 @@ EXPORT_SYMBOL(csum_fold); EXPORT_SYMBOL(console_mode); EXPORT_SYMBOL(console_devno); EXPORT_SYMBOL(console_irq); +EXPORT_SYMBOL(sys_wait4); diff --git a/trunk/arch/s390/kernel/setup.c b/trunk/arch/s390/kernel/setup.c index 2aa13e8e000a..49f2b68e32b1 100644 --- a/trunk/arch/s390/kernel/setup.c +++ b/trunk/arch/s390/kernel/setup.c @@ -70,7 +70,6 @@ struct { #define CHUNK_READ_WRITE 0 #define CHUNK_READ_ONLY 1 volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */ -unsigned long __initdata zholes_size[MAX_NR_ZONES]; static unsigned long __initdata memory_end; /* @@ -358,21 +357,6 @@ void machine_power_off(void) */ void (*pm_power_off)(void) = machine_power_off; -static void __init -add_memory_hole(unsigned long start, unsigned long end) -{ - unsigned long dma_pfn = MAX_DMA_ADDRESS >> PAGE_SHIFT; - - if (end <= dma_pfn) - zholes_size[ZONE_DMA] += end - start + 1; - else if (start > dma_pfn) - zholes_size[ZONE_NORMAL] += end - start + 1; - else { - zholes_size[ZONE_DMA] += dma_pfn - start + 1; - zholes_size[ZONE_NORMAL] += end - dma_pfn; - } -} - static int __init early_parse_mem(char *p) { memory_end = memparse(p, &p); @@ -450,7 +434,7 @@ setup_lowcore(void) lc->extended_save_area_addr = (__u32) __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0); /* enable extended save area */ - __ctl_set_bit(14, 29); + ctl_set_bit(14, 29); } #endif set_prefix((u32)(unsigned long) lc); @@ -494,7 +478,6 @@ setup_memory(void) { unsigned long bootmap_size; unsigned long start_pfn, end_pfn, init_pfn; - unsigned long last_rw_end; int i; /* @@ -550,39 +533,27 @@ setup_memory(void) /* * Register RAM areas with the bootmem allocator. */ - last_rw_end = start_pfn; for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) { - unsigned long start_chunk, end_chunk; + unsigned long start_chunk, end_chunk, pfn; if (memory_chunk[i].type != CHUNK_READ_WRITE) continue; - start_chunk = (memory_chunk[i].addr + PAGE_SIZE - 1); - start_chunk >>= PAGE_SHIFT; - end_chunk = (memory_chunk[i].addr + memory_chunk[i].size); - end_chunk >>= PAGE_SHIFT; - if (start_chunk < start_pfn) - start_chunk = start_pfn; - if (end_chunk > end_pfn) - end_chunk = end_pfn; - if (start_chunk < end_chunk) { - /* Initialize storage key for RAM pages */ - for (init_pfn = start_chunk ; init_pfn < end_chunk; - init_pfn++) - page_set_storage_key(init_pfn << PAGE_SHIFT, - PAGE_DEFAULT_KEY); - free_bootmem(start_chunk << PAGE_SHIFT, - (end_chunk - start_chunk) << PAGE_SHIFT); - if (last_rw_end < start_chunk) - add_memory_hole(last_rw_end, start_chunk - 1); - last_rw_end = end_chunk; - } + start_chunk = PFN_DOWN(memory_chunk[i].addr); + end_chunk = start_chunk + PFN_DOWN(memory_chunk[i].size) - 1; + end_chunk = min(end_chunk, end_pfn); + if (start_chunk >= end_chunk) + continue; + add_active_range(0, start_chunk, end_chunk); + pfn = max(start_chunk, start_pfn); + for (; pfn <= end_chunk; pfn++) + page_set_storage_key(PFN_PHYS(pfn), PAGE_DEFAULT_KEY); } psw_set_key(PAGE_DEFAULT_KEY); - if (last_rw_end < end_pfn - 1) - add_memory_hole(last_rw_end, end_pfn - 1); + free_bootmem_with_active_regions(0, max_pfn); + reserve_bootmem(0, PFN_PHYS(start_pfn)); /* * Reserve the bootmem bitmap itself as well. We do this in two diff --git a/trunk/arch/s390/kernel/signal.c b/trunk/arch/s390/kernel/signal.c index 4c8a7954ef48..4392a77cbae8 100644 --- a/trunk/arch/s390/kernel/signal.c +++ b/trunk/arch/s390/kernel/signal.c @@ -80,10 +80,10 @@ sys_sigaction(int sig, const struct old_sigaction __user *act, old_sigset_t mask; if (!access_ok(VERIFY_READ, act, sizeof(*act)) || __get_user(new_ka.sa.sa_handler, &act->sa_handler) || - __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) || - __get_user(new_ka.sa.sa_flags, &act->sa_flags) || - __get_user(mask, &act->sa_mask)) + __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) return -EFAULT; + __get_user(new_ka.sa.sa_flags, &act->sa_flags); + __get_user(mask, &act->sa_mask); siginitset(&new_ka.sa.sa_mask, mask); } @@ -92,10 +92,10 @@ sys_sigaction(int sig, const struct old_sigaction __user *act, if (!ret && oact) { if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || - __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) || - __put_user(old_ka.sa.sa_flags, &oact->sa_flags) || - __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask)) + __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) return -EFAULT; + __put_user(old_ka.sa.sa_flags, &oact->sa_flags); + __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); } return ret; diff --git a/trunk/arch/s390/kernel/smp.c b/trunk/arch/s390/kernel/smp.c index 62822245f9be..a8e6199755d4 100644 --- a/trunk/arch/s390/kernel/smp.c +++ b/trunk/arch/s390/kernel/smp.c @@ -339,7 +339,7 @@ void machine_power_off_smp(void) * cpus are handled. */ -void do_ext_call_interrupt(__u16 code) +void do_ext_call_interrupt(struct pt_regs *regs, __u16 code) { unsigned long bits; diff --git a/trunk/arch/s390/kernel/stacktrace.c b/trunk/arch/s390/kernel/stacktrace.c index 0d14a4789bf2..d9428a0fc8fb 100644 --- a/trunk/arch/s390/kernel/stacktrace.c +++ b/trunk/arch/s390/kernel/stacktrace.c @@ -62,26 +62,27 @@ static inline unsigned long save_context_stack(struct stack_trace *trace, void save_stack_trace(struct stack_trace *trace, struct task_struct *task) { register unsigned long sp asm ("15"); - unsigned long orig_sp, new_sp; + unsigned long orig_sp; - orig_sp = sp & PSW_ADDR_INSN; + sp &= PSW_ADDR_INSN; + orig_sp = sp; - new_sp = save_context_stack(trace, &trace->skip, orig_sp, + sp = save_context_stack(trace, &trace->skip, sp, S390_lowcore.panic_stack - PAGE_SIZE, S390_lowcore.panic_stack); - if ((new_sp != orig_sp) && !trace->all_contexts) + if ((sp != orig_sp) && !trace->all_contexts) return; - new_sp = save_context_stack(trace, &trace->skip, new_sp, + sp = save_context_stack(trace, &trace->skip, sp, S390_lowcore.async_stack - ASYNC_SIZE, S390_lowcore.async_stack); - if ((new_sp != orig_sp) && !trace->all_contexts) + if ((sp != orig_sp) && !trace->all_contexts) return; if (task) - save_context_stack(trace, &trace->skip, new_sp, + save_context_stack(trace, &trace->skip, sp, (unsigned long) task_stack_page(task), (unsigned long) task_stack_page(task) + THREAD_SIZE); else - save_context_stack(trace, &trace->skip, new_sp, + save_context_stack(trace, &trace->skip, sp, S390_lowcore.thread_info, S390_lowcore.thread_info + THREAD_SIZE); return; diff --git a/trunk/arch/s390/kernel/syscalls.S b/trunk/arch/s390/kernel/syscalls.S index a4ceae3dbcf1..e59baec56520 100644 --- a/trunk/arch/s390/kernel/syscalls.S +++ b/trunk/arch/s390/kernel/syscalls.S @@ -320,4 +320,3 @@ SYSCALL(sys_tee,sys_tee,sys_tee_wrapper) SYSCALL(sys_vmsplice,sys_vmsplice,compat_sys_vmsplice_wrapper) NI_SYSCALL /* 310 sys_move_pages */ SYSCALL(sys_getcpu,sys_getcpu,sys_getcpu_wrapper) -SYSCALL(sys_epoll_pwait,sys_epoll_pwait,sys_ni_syscall) diff --git a/trunk/arch/s390/kernel/time.c b/trunk/arch/s390/kernel/time.c index 6cceed4df73e..4bf66cc4a267 100644 --- a/trunk/arch/s390/kernel/time.c +++ b/trunk/arch/s390/kernel/time.c @@ -28,14 +28,12 @@ #include #include #include -#include #include #include #include #include #include -#include #include /* change this if you have some constant time drift */ @@ -83,10 +81,78 @@ void tod_to_timeval(__u64 todval, struct timespec *xtime) xtime->tv_nsec = ((todval * 1000) >> 12); } +static inline unsigned long do_gettimeoffset(void) +{ + __u64 now; + + now = (get_clock() - jiffies_timer_cc) >> 12; + now -= (__u64) jiffies * USECS_PER_JIFFY; + return (unsigned long) now; +} + +/* + * This version of gettimeofday has microsecond resolution. + */ +void do_gettimeofday(struct timeval *tv) +{ + unsigned long flags; + unsigned long seq; + unsigned long usec, sec; + + do { + seq = read_seqbegin_irqsave(&xtime_lock, flags); + + sec = xtime.tv_sec; + usec = xtime.tv_nsec / 1000 + do_gettimeoffset(); + } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); + + while (usec >= 1000000) { + usec -= 1000000; + sec++; + } + + tv->tv_sec = sec; + tv->tv_usec = usec; +} + +EXPORT_SYMBOL(do_gettimeofday); + +int do_settimeofday(struct timespec *tv) +{ + time_t wtm_sec, sec = tv->tv_sec; + long wtm_nsec, nsec = tv->tv_nsec; + + if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC) + return -EINVAL; + + write_seqlock_irq(&xtime_lock); + /* This is revolting. We need to set the xtime.tv_nsec + * correctly. However, the value in this location is + * is value at the last tick. + * Discover what correction gettimeofday + * would have done, and then undo it! + */ + nsec -= do_gettimeoffset() * 1000; + + wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); + wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec); + + set_normalized_timespec(&xtime, sec, nsec); + set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec); + + ntp_clear(); + write_sequnlock_irq(&xtime_lock); + clock_was_set(); + return 0; +} + +EXPORT_SYMBOL(do_settimeofday); + + #ifdef CONFIG_PROFILING -#define s390_do_profile() profile_tick(CPU_PROFILING) +#define s390_do_profile(regs) profile_tick(CPU_PROFILING, regs) #else -#define s390_do_profile() do { ; } while(0) +#define s390_do_profile(regs) do { ; } while(0) #endif /* CONFIG_PROFILING */ @@ -94,7 +160,7 @@ void tod_to_timeval(__u64 todval, struct timespec *xtime) * timer_interrupt() needs to keep up the real-time clock, * as well as call the "do_timer()" routine every clocktick */ -void account_ticks(void) +void account_ticks(struct pt_regs *regs) { __u64 tmp; __u32 ticks; @@ -155,10 +221,10 @@ void account_ticks(void) account_tick_vtime(current); #else while (ticks--) - update_process_times(user_mode(get_irq_regs())); + update_process_times(user_mode(regs)); #endif - s390_do_profile(); + s390_do_profile(regs); } #ifdef CONFIG_NO_IDLE_HZ @@ -219,11 +285,9 @@ static inline void stop_hz_timer(void) */ static inline void start_hz_timer(void) { - BUG_ON(!in_interrupt()); - if (!cpu_isset(smp_processor_id(), nohz_cpu_mask)) return; - account_ticks(); + account_ticks(task_pt_regs(current)); cpu_clear(smp_processor_id(), nohz_cpu_mask); } @@ -273,22 +337,6 @@ void init_cpu_timer(void) extern void vtime_init(void); -static cycle_t read_tod_clock(void) -{ - return get_clock(); -} - -static struct clocksource clocksource_tod = { - .name = "tod", - .rating = 100, - .read = read_tod_clock, - .mask = -1ULL, - .mult = 1000, - .shift = 12, - .is_continuous = 1, -}; - - /* * Initialize the TOD clock and the CPU timer of * the boot cpu. @@ -333,9 +381,6 @@ void __init time_init(void) &ext_int_info_cc) != 0) panic("Couldn't request external interrupt 0x1004"); - if (clocksource_register(&clocksource_tod) != 0) - panic("Could not register TOD clock source"); - init_cpu_timer(); #ifdef CONFIG_NO_IDLE_HZ diff --git a/trunk/arch/s390/kernel/traps.c b/trunk/arch/s390/kernel/traps.c index 92ecffbc8d82..3eb4fab048b8 100644 --- a/trunk/arch/s390/kernel/traps.c +++ b/trunk/arch/s390/kernel/traps.c @@ -61,7 +61,7 @@ extern pgm_check_handler_t do_dat_exception; #ifdef CONFIG_PFAULT extern int pfault_init(void); extern void pfault_fini(void); -extern void pfault_interrupt(__u16 error_code); +extern void pfault_interrupt(struct pt_regs *regs, __u16 error_code); static ext_int_info_t ext_int_pfault; #endif extern pgm_check_handler_t do_monitor_call; @@ -462,8 +462,7 @@ asmlinkage void illegal_op(struct pt_regs * regs, long interruption_code) local_irq_enable(); if (regs->psw.mask & PSW_MASK_PSTATE) { - if (get_user(*((__u16 *) opcode), (__u16 __user *) location)) - return; + get_user(*((__u16 *) opcode), (__u16 __user *) location); if (*((__u16 *) opcode) == S390_BREAKPOINT_U16) { if (current->ptrace & PT_PTRACED) force_sig(SIGTRAP, current); @@ -471,25 +470,20 @@ asmlinkage void illegal_op(struct pt_regs * regs, long interruption_code) signal = SIGILL; #ifdef CONFIG_MATHEMU } else if (opcode[0] == 0xb3) { - if (get_user(*((__u16 *) (opcode+2)), location+1)) - return; + get_user(*((__u16 *) (opcode+2)), location+1); signal = math_emu_b3(opcode, regs); } else if (opcode[0] == 0xed) { - if (get_user(*((__u32 *) (opcode+2)), - (__u32 __user *)(location+1))) - return; + get_user(*((__u32 *) (opcode+2)), + (__u32 *)(location+1)); signal = math_emu_ed(opcode, regs); } else if (*((__u16 *) opcode) == 0xb299) { - if (get_user(*((__u16 *) (opcode+2)), location+1)) - return; + get_user(*((__u16 *) (opcode+2)), location+1); signal = math_emu_srnm(opcode, regs); } else if (*((__u16 *) opcode) == 0xb29c) { - if (get_user(*((__u16 *) (opcode+2)), location+1)) - return; + get_user(*((__u16 *) (opcode+2)), location+1); signal = math_emu_stfpc(opcode, regs); } else if (*((__u16 *) opcode) == 0xb29d) { - if (get_user(*((__u16 *) (opcode+2)), location+1)) - return; + get_user(*((__u16 *) (opcode+2)), location+1); signal = math_emu_lfpc(opcode, regs); #endif } else @@ -505,7 +499,7 @@ asmlinkage void illegal_op(struct pt_regs * regs, long interruption_code) info.si_signo = signal; info.si_errno = 0; info.si_code = SEGV_MAPERR; - info.si_addr = (void __user *) location; + info.si_addr = (void *) location; do_trap(interruption_code, signal, "user address fault", regs, &info); } else @@ -526,10 +520,10 @@ asmlinkage void specification_exception(struct pt_regs * regs, long interruption_code) { __u8 opcode[6]; - __u16 __user *location = NULL; + __u16 *location = NULL; int signal = 0; - location = (__u16 __user *) get_check_address(regs); + location = (__u16 *) get_check_address(regs); /* * We got all needed information from the lowcore and can @@ -638,7 +632,7 @@ asmlinkage void data_exception(struct pt_regs * regs, long interruption_code) break; case 0xed: get_user(*((__u32 *) (opcode+2)), - (__u32 __user *)(location+1)); + (__u32 *)(location+1)); signal = math_emu_ed(opcode, regs); break; case 0xb2: diff --git a/trunk/arch/s390/kernel/vmlinux.lds.S b/trunk/arch/s390/kernel/vmlinux.lds.S index fe0f2e97ba7b..af9e69a03011 100644 --- a/trunk/arch/s390/kernel/vmlinux.lds.S +++ b/trunk/arch/s390/kernel/vmlinux.lds.S @@ -83,7 +83,13 @@ SECTIONS __setup_end = .; __initcall_start = .; .initcall.init : { - INITCALLS + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) } __initcall_end = .; __con_initcall_start = .; diff --git a/trunk/arch/s390/kernel/vtime.c b/trunk/arch/s390/kernel/vtime.c index 21baaf5496d6..2306cd83fca1 100644 --- a/trunk/arch/s390/kernel/vtime.c +++ b/trunk/arch/s390/kernel/vtime.c @@ -22,7 +22,6 @@ #include #include -#include static ext_int_info_t ext_int_info_timer; DEFINE_PER_CPU(struct vtimer_queue, virt_cpu_timer); @@ -209,11 +208,11 @@ static void list_add_sorted(struct vtimer_list *timer, struct list_head *head) * Do the callback functions of expired vtimer events. * Called from within the interrupt handler. */ -static void do_callbacks(struct list_head *cb_list) +static void do_callbacks(struct list_head *cb_list, struct pt_regs *regs) { struct vtimer_queue *vt_list; struct vtimer_list *event, *tmp; - void (*fn)(unsigned long); + void (*fn)(unsigned long, struct pt_regs*); unsigned long data; if (list_empty(cb_list)) @@ -224,7 +223,7 @@ static void do_callbacks(struct list_head *cb_list) list_for_each_entry_safe(event, tmp, cb_list, entry) { fn = event->function; data = event->data; - fn(data); + fn(data, regs); if (!event->interval) /* delete one shot timer */ @@ -242,7 +241,7 @@ static void do_callbacks(struct list_head *cb_list) /* * Handler for the virtual CPU timer. */ -static void do_cpu_timer_interrupt(__u16 error_code) +static void do_cpu_timer_interrupt(struct pt_regs *regs, __u16 error_code) { int cpu; __u64 next, delta; @@ -275,7 +274,7 @@ static void do_cpu_timer_interrupt(__u16 error_code) list_move_tail(&event->entry, &cb_list); } spin_unlock(&vt_list->lock); - do_callbacks(&cb_list); + do_callbacks(&cb_list, regs); /* next event is first in list */ spin_lock(&vt_list->lock); diff --git a/trunk/arch/s390/mm/fault.c b/trunk/arch/s390/mm/fault.c index 1c323bbfda91..9c3c19fe62fc 100644 --- a/trunk/arch/s390/mm/fault.c +++ b/trunk/arch/s390/mm/fault.c @@ -451,7 +451,7 @@ void pfault_fini(void) } asmlinkage void -pfault_interrupt(__u16 error_code) +pfault_interrupt(struct pt_regs *regs, __u16 error_code) { struct task_struct *tsk; __u16 subcode; diff --git a/trunk/arch/s390/mm/init.c b/trunk/arch/s390/mm/init.c index e1881c31b1cb..d99891718709 100644 --- a/trunk/arch/s390/mm/init.c +++ b/trunk/arch/s390/mm/init.c @@ -84,7 +84,6 @@ void show_mem(void) printk("%d pages swap cached\n",cached); } -extern unsigned long __initdata zholes_size[]; /* * paging_init() sets up the page tables */ @@ -101,16 +100,15 @@ void __init paging_init(void) unsigned long pgdir_k = (__pa(swapper_pg_dir) & PAGE_MASK) | _KERNSEG_TABLE; static const int ssm_mask = 0x04000000L; unsigned long ro_start_pfn, ro_end_pfn; - unsigned long zones_size[MAX_NR_ZONES]; + unsigned long max_zone_pfns[MAX_NR_ZONES]; ro_start_pfn = PFN_DOWN((unsigned long)&__start_rodata); ro_end_pfn = PFN_UP((unsigned long)&__end_rodata); - memset(zones_size, 0, sizeof(zones_size)); - zones_size[ZONE_DMA] = max_low_pfn; - free_area_init_node(0, &contig_page_data, zones_size, - __pa(PAGE_OFFSET) >> PAGE_SHIFT, - zholes_size); + memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); + max_zone_pfns[ZONE_DMA] = max_low_pfn; + max_zone_pfns[ZONE_NORMAL] = max_low_pfn; + free_area_init_nodes(max_zone_pfns); /* unmap whole virtual address space */ @@ -170,26 +168,16 @@ void __init paging_init(void) unsigned long pgdir_k = (__pa(swapper_pg_dir) & PAGE_MASK) | _KERN_REGION_TABLE; static const int ssm_mask = 0x04000000L; - unsigned long zones_size[MAX_NR_ZONES]; - unsigned long dma_pfn, high_pfn; unsigned long ro_start_pfn, ro_end_pfn; + unsigned long max_zone_pfns[MAX_NR_ZONES]; - memset(zones_size, 0, sizeof(zones_size)); - dma_pfn = MAX_DMA_ADDRESS >> PAGE_SHIFT; - high_pfn = max_low_pfn; ro_start_pfn = PFN_DOWN((unsigned long)&__start_rodata); ro_end_pfn = PFN_UP((unsigned long)&__end_rodata); - if (dma_pfn > high_pfn) - zones_size[ZONE_DMA] = high_pfn; - else { - zones_size[ZONE_DMA] = dma_pfn; - zones_size[ZONE_NORMAL] = high_pfn - dma_pfn; - } - - /* Initialize mem_map[]. */ - free_area_init_node(0, &contig_page_data, zones_size, - __pa(PAGE_OFFSET) >> PAGE_SHIFT, zholes_size); + memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); + max_zone_pfns[ZONE_DMA] = PFN_DOWN(MAX_DMA_ADDRESS); + max_zone_pfns[ZONE_NORMAL] = max_low_pfn; + free_area_init_nodes(max_zone_pfns); /* * map whole physical memory to virtual memory (identity mapping) diff --git a/trunk/arch/sh/Kconfig b/trunk/arch/sh/Kconfig index bffc7e176970..f6a0c4436168 100644 --- a/trunk/arch/sh/Kconfig +++ b/trunk/arch/sh/Kconfig @@ -45,9 +45,6 @@ config GENERIC_CALIBRATE_DELAY config GENERIC_IOMAP bool -config GENERIC_TIME - def_bool n - config ARCH_MAY_HAVE_PC_FDC bool @@ -217,7 +214,7 @@ config SH_SHMIN bool "SHMIN" select CPU_SUBTYPE_SH7706 help - Select SHMIN if configuring for the SHMIN board. + Select SHMIN if configureing for the SHMIN board config SH_UNKNOWN bool "BareCPU" @@ -360,7 +357,6 @@ config CPU_HAS_SR_RB endmenu menu "Timer support" -depends on !GENERIC_TIME config SH_TMU bool "TMU timer support" diff --git a/trunk/arch/sh/boards/hp6xx/hp6xx_apm.c b/trunk/arch/sh/boards/hp6xx/hp6xx_apm.c index d146cdaa0b8b..75f91aaae077 100644 --- a/trunk/arch/sh/boards/hp6xx/hp6xx_apm.c +++ b/trunk/arch/sh/boards/hp6xx/hp6xx_apm.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #define SH7709_PGDR 0xa400012c @@ -83,7 +83,7 @@ static int hp6x0_apm_get_info(char *buf, char **start, off_t fpos, int length) return p - buf; } -static irqreturn_t hp6x0_apm_interrupt(int irq, void *dev) +static irqreturn_t hp6x0_apm_interrupt(int irq, void *dev, struct pt_regs *regs) { if (!apm_suspended) apm_queue_event(APM_USER_SUSPEND); @@ -96,7 +96,7 @@ static int __init hp6x0_apm_init(void) int ret; ret = request_irq(HP680_BTN_IRQ, hp6x0_apm_interrupt, - IRQF_DISABLED, MODNAME, 0); + SA_INTERRUPT, MODNAME, 0); if (unlikely(ret < 0)) { printk(KERN_ERR MODNAME ": IRQ %d request failed\n", HP680_BTN_IRQ); diff --git a/trunk/arch/sh/boards/hp6xx/pm.c b/trunk/arch/sh/boards/hp6xx/pm.c index d1947732fb3e..83d327212064 100644 --- a/trunk/arch/sh/boards/hp6xx/pm.c +++ b/trunk/arch/sh/boards/hp6xx/pm.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include diff --git a/trunk/arch/sh/boards/hp6xx/setup.c b/trunk/arch/sh/boards/hp6xx/setup.c index b5a96649ed26..2d3a5b4faf58 100644 --- a/trunk/arch/sh/boards/hp6xx/setup.c +++ b/trunk/arch/sh/boards/hp6xx/setup.c @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #define SCPCR 0xa4000116 diff --git a/trunk/arch/sh/boards/landisk/landisk_pwb.c b/trunk/arch/sh/boards/landisk/landisk_pwb.c index e62524978160..0b7bee1a9ca5 100644 --- a/trunk/arch/sh/boards/landisk/landisk_pwb.c +++ b/trunk/arch/sh/boards/landisk/landisk_pwb.c @@ -135,7 +135,7 @@ static int swdrv_write(struct file *filp, const char *buff, size_t count, return count; } -static irqreturn_t sw_interrupt(int irq, void *dev_id) +static irqreturn_t sw_interrupt(int irq, void *dev_id, struct pt_regs *regs) { landisk_btn = (0x0ff & (~ctrl_inb(PA_STATUS))); disable_irq(IRQ_BUTTON); diff --git a/trunk/arch/sh/boards/mpc1211/setup.c b/trunk/arch/sh/boards/mpc1211/setup.c index 7c3d1d304157..01c10fa5c058 100644 --- a/trunk/arch/sh/boards/mpc1211/setup.c +++ b/trunk/arch/sh/boards/mpc1211/setup.c @@ -69,6 +69,7 @@ static void __init pci_write_config(unsigned long busNo, static unsigned char m_irq_mask = 0xfb; static unsigned char s_irq_mask = 0xff; +volatile unsigned long irq_err_count; static void disable_mpc1211_irq(unsigned int irq) { @@ -117,7 +118,7 @@ static void mask_and_ack_mpc1211(unsigned int irq) if(irq < 8) { if(m_irq_mask & (1< #include #include -#include +#include #include extern void *area6_io8_base; /* Area 6 8bit I/O Base address */ diff --git a/trunk/arch/sh/boards/renesas/hs7751rvoip/irq.c b/trunk/arch/sh/boards/renesas/hs7751rvoip/irq.c index 943f93aa6052..c617b188258a 100644 --- a/trunk/arch/sh/boards/renesas/hs7751rvoip/irq.c +++ b/trunk/arch/sh/boards/renesas/hs7751rvoip/irq.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include static int mask_pos[] = {8, 9, 10, 11, 12, 13, 0, 1, 2, 3, 4, 5, 6, 7}; diff --git a/trunk/arch/sh/boards/renesas/hs7751rvoip/setup.c b/trunk/arch/sh/boards/renesas/hs7751rvoip/setup.c index f7d0e304d899..0414c15c3458 100644 --- a/trunk/arch/sh/boards/renesas/hs7751rvoip/setup.c +++ b/trunk/arch/sh/boards/renesas/hs7751rvoip/setup.c @@ -10,21 +10,22 @@ #include #include #include +#include +#include +#include #include -#include #include +#include #include - -static struct ipr_data hs77501rvoip_ipr_map[] = { -#if defined(CONFIG_HS7751RVOIP_CODEC) - { DMTE0_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY }, - { DMTE1_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY }, -#endif -}; +#include +#include static void __init hs7751rvoip_init_irq(void) { - make_ipr_irq(hs77501rvoip_ipr_map, ARRAY_SIZE(hs77501rvoip_ipr_map)); +#if defined(CONFIG_HS7751RVOIP_CODEC) + make_ipr_irq(DMTE0_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY); + make_ipr_irq(DMTE1_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY); +#endif init_hs7751rvoip_IRQ(); } diff --git a/trunk/arch/sh/boards/renesas/r7780rp/io.c b/trunk/arch/sh/boards/renesas/r7780rp/io.c index 311ccccba718..db92d6e6ae99 100644 --- a/trunk/arch/sh/boards/renesas/r7780rp/io.c +++ b/trunk/arch/sh/boards/renesas/r7780rp/io.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include diff --git a/trunk/arch/sh/boards/renesas/r7780rp/irq.c b/trunk/arch/sh/boards/renesas/r7780rp/irq.c index aa15ec5bc69e..2d960e9a3143 100644 --- a/trunk/arch/sh/boards/renesas/r7780rp/irq.c +++ b/trunk/arch/sh/boards/renesas/r7780rp/irq.c @@ -1,17 +1,18 @@ /* - * Renesas Solutions Highlander R7780RP-1 Support. + * linux/arch/sh/boards/renesas/r7780rp/irq.c + * + * Copyright (C) 2000 Kazumoto Kojima * - * Copyright (C) 2002 Atom Create Engineering Co., Ltd. - * Copyright (C) 2006 Paul Mundt + * Renesas Solutions Highlander R7780RP-1 Support. * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. + * Modified for R7780RP-1 by + * Atom Create Engineering Co., Ltd. 2002. */ #include #include -#include -#include +#include +#include +#include #ifdef CONFIG_SH_R7780MP static int mask_pos[] = {12, 11, 9, 14, 15, 8, 13, 6, 5, 4, 3, 2, 0, 0, 1, 0}; @@ -19,26 +20,71 @@ static int mask_pos[] = {12, 11, 9, 14, 15, 8, 13, 6, 5, 4, 3, 2, 0, 0, 1, 0}; static int mask_pos[] = {15, 14, 13, 12, 11, 10, 9, 8, 7, 5, 6, 4, 0, 1, 2, 0}; #endif -static void enable_r7780rp_irq(unsigned int irq) +static void enable_r7780rp_irq(unsigned int irq); +static void disable_r7780rp_irq(unsigned int irq); + +/* shutdown is same as "disable" */ +#define shutdown_r7780rp_irq disable_r7780rp_irq + +static void ack_r7780rp_irq(unsigned int irq); +static void end_r7780rp_irq(unsigned int irq); + +static unsigned int startup_r7780rp_irq(unsigned int irq) { - /* Set priority in IPR back to original value */ - ctrl_outw(ctrl_inw(IRLCNTR1) | (1 << mask_pos[irq]), IRLCNTR1); + enable_r7780rp_irq(irq); + return 0; /* never anything pending */ } static void disable_r7780rp_irq(unsigned int irq) { + unsigned short val; + unsigned short mask = 0xffff ^ (0x0001 << mask_pos[irq]); + /* Set the priority in IPR to 0 */ - ctrl_outw(ctrl_inw(IRLCNTR1) & (0xffff ^ (1 << mask_pos[irq])), - IRLCNTR1); + val = ctrl_inw(IRLCNTR1); + val &= mask; + ctrl_outw(val, IRLCNTR1); } -static struct irq_chip r7780rp_irq_chip __read_mostly = { - .name = "R7780RP", - .mask = disable_r7780rp_irq, - .unmask = enable_r7780rp_irq, - .mask_ack = disable_r7780rp_irq, +static void enable_r7780rp_irq(unsigned int irq) +{ + unsigned short val; + unsigned short value = (0x0001 << mask_pos[irq]); + + /* Set priority in IPR back to original value */ + val = ctrl_inw(IRLCNTR1); + val |= value; + ctrl_outw(val, IRLCNTR1); +} + +static void ack_r7780rp_irq(unsigned int irq) +{ + disable_r7780rp_irq(irq); +} + +static void end_r7780rp_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + enable_r7780rp_irq(irq); +} + +static struct hw_interrupt_type r7780rp_irq_type = { + .typename = "R7780RP-IRQ", + .startup = startup_r7780rp_irq, + .shutdown = shutdown_r7780rp_irq, + .enable = enable_r7780rp_irq, + .disable = disable_r7780rp_irq, + .ack = ack_r7780rp_irq, + .end = end_r7780rp_irq, }; +static void make_r7780rp_irq(unsigned int irq) +{ + disable_irq_nosync(irq); + irq_desc[irq].chip = &r7780rp_irq_type; + disable_r7780rp_irq(irq); +} + /* * Initialize IRQ setting */ @@ -46,10 +92,24 @@ void __init init_r7780rp_IRQ(void) { int i; - for (i = 0; i < 15; i++) { - disable_irq_nosync(i); - set_irq_chip_and_handler_name(i, &r7780rp_irq_chip, - handle_level_irq, "level"); - enable_r7780rp_irq(i); - } + /* IRL0=PCI Slot #A + * IRL1=PCI Slot #B + * IRL2=PCI Slot #C + * IRL3=PCI Slot #D + * IRL4=CF Card + * IRL5=CF Card Insert + * IRL6=M66596 + * IRL7=SD Card + * IRL8=Touch Panel + * IRL9=SCI + * IRL10=Serial + * IRL11=Extention #A + * IRL11=Extention #B + * IRL12=Debug LAN + * IRL13=Push Switch + * IRL14=ZiggBee IO + */ + + for (i=0; i<15; i++) + make_r7780rp_irq(i); } diff --git a/trunk/arch/sh/boards/renesas/r7780rp/setup.c b/trunk/arch/sh/boards/renesas/r7780rp/setup.c index c331caeb694b..b941aa0aa34e 100644 --- a/trunk/arch/sh/boards/renesas/r7780rp/setup.c +++ b/trunk/arch/sh/boards/renesas/r7780rp/setup.c @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include diff --git a/trunk/arch/sh/boards/renesas/rts7751r2d/io.c b/trunk/arch/sh/boards/renesas/rts7751r2d/io.c index f2507a804979..135aa0b5e62d 100644 --- a/trunk/arch/sh/boards/renesas/rts7751r2d/io.c +++ b/trunk/arch/sh/boards/renesas/rts7751r2d/io.c @@ -11,8 +11,8 @@ #include #include #include -#include -#include +#include +#include #include /* diff --git a/trunk/arch/sh/boards/renesas/rts7751r2d/irq.c b/trunk/arch/sh/boards/renesas/rts7751r2d/irq.c index cb0eb20d1b43..c915e7a3693a 100644 --- a/trunk/arch/sh/boards/renesas/rts7751r2d/irq.c +++ b/trunk/arch/sh/boards/renesas/rts7751r2d/irq.c @@ -8,10 +8,12 @@ * Modified for RTS7751R2D by * Atom Create Engineering Co., Ltd. 2002. */ + #include #include -#include -#include +#include +#include +#include #if defined(CONFIG_RTS7751R2D_REV11) static int mask_pos[] = {11, 9, 8, 12, 10, 6, 5, 4, 7, 14, 13, 0, 0, 0, 0}; diff --git a/trunk/arch/sh/boards/renesas/rts7751r2d/led.c b/trunk/arch/sh/boards/renesas/rts7751r2d/led.c index 509f548bdce0..a7ce66c1e4f0 100644 --- a/trunk/arch/sh/boards/renesas/rts7751r2d/led.c +++ b/trunk/arch/sh/boards/renesas/rts7751r2d/led.c @@ -8,9 +8,13 @@ * * This file contains Renesas Technology Sales RTS7751R2D specific LED code. */ -#include + +#include +#include + +#ifdef CONFIG_HEARTBEAT + #include -#include /* Cycle the LED's in the clasic Knightriger/Sun pattern */ void heartbeat_rts7751r2d(void) @@ -42,3 +46,10 @@ void heartbeat_rts7751r2d(void) else bit--; } +#endif /* CONFIG_HEARTBEAT */ + +void rts7751r2d_led(unsigned short value) +{ + ctrl_outw(value, PA_OUTPORT); +} + diff --git a/trunk/arch/sh/boards/renesas/rts7751r2d/setup.c b/trunk/arch/sh/boards/renesas/rts7751r2d/setup.c index 5c042d35ec91..20597a6e6702 100644 --- a/trunk/arch/sh/boards/renesas/rts7751r2d/setup.c +++ b/trunk/arch/sh/boards/renesas/rts7751r2d/setup.c @@ -12,9 +12,9 @@ #include #include #include +#include #include #include -#include #include extern void heartbeat_rts7751r2d(void); diff --git a/trunk/arch/sh/boards/renesas/sh7710voipgw/setup.c b/trunk/arch/sh/boards/renesas/sh7710voipgw/setup.c index 180810b12107..e57e7afab8c6 100644 --- a/trunk/arch/sh/boards/renesas/sh7710voipgw/setup.c +++ b/trunk/arch/sh/boards/renesas/sh7710voipgw/setup.c @@ -13,51 +13,6 @@ #include #include -static struct ipr_data sh7710voipgw_ipr_map[] = { - { TIMER2_IRQ, TIMER2_IPR_ADDR, TIMER2_IPR_POS, TIMER2_PRIORITY }, - { WDT_IRQ, WDT_IPR_ADDR, WDT_IPR_POS, WDT_PRIORITY }, - - /* SCIF0 */ - { SCIF0_ERI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY }, - { SCIF0_RXI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY }, - { SCIF0_BRI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY }, - { SCIF0_TXI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY }, - - /* DMAC-1 */ - { DMTE0_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY }, - { DMTE1_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY }, - { DMTE2_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY }, - { DMTE3_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY }, - - /* DMAC-2 */ - { DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY }, - { DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY }, - - /* IPSEC */ - { IPSEC_IRQ, IPSEC_IPR_ADDR, IPSEC_IPR_POS, IPSEC_PRIORITY }, - - /* EDMAC */ - { EDMAC0_IRQ, EDMAC0_IPR_ADDR, EDMAC0_IPR_POS, EDMAC0_PRIORITY }, - { EDMAC1_IRQ, EDMAC1_IPR_ADDR, EDMAC1_IPR_POS, EDMAC1_PRIORITY }, - { EDMAC2_IRQ, EDMAC2_IPR_ADDR, EDMAC2_IPR_POS, EDMAC2_PRIORITY }, - - /* SIOF0 */ - { SIOF0_ERI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY }, - { SIOF0_TXI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY }, - { SIOF0_RXI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY }, - { SIOF0_CCI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY }, - - /* SIOF1 */ - { SIOF1_ERI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS, SIOF1_PRIORITY }, - { SIOF1_TXI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS, SIOF1_PRIORITY }, - { SIOF1_RXI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS, SIOF1_PRIORITY }, - { SIOF1_CCI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS, SIOF1_PRIORITY }, - - /* SLIC IRQ's */ - { IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, IRQ1_PRIORITY }, - { IRQ2_IRQ, IRQ2_IPR_ADDR, IRQ2_IPR_POS, IRQ2_PRIORITY }, -}; - /* * Initialize IRQ setting */ @@ -82,7 +37,65 @@ static void __init sh7710voipgw_init_irq(void) */ ctrl_outw(0x2aa, INTC_ICR1); - make_ipr_irq(sh7710voipgw_ipr_map, ARRAY_SIZE(sh7710voipgw_ipr_map)); + /* Now make IPR interrupts */ + make_ipr_irq(TIMER2_IRQ, TIMER2_IPR_ADDR, + TIMER2_IPR_POS, TIMER2_PRIORITY); + make_ipr_irq(WDT_IRQ, WDT_IPR_ADDR, WDT_IPR_POS, WDT_PRIORITY); + + /* SCIF0 */ + make_ipr_irq(SCIF0_ERI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, + SCIF0_PRIORITY); + make_ipr_irq(SCIF0_RXI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, + SCIF0_PRIORITY); + make_ipr_irq(SCIF0_BRI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, + SCIF0_PRIORITY); + make_ipr_irq(SCIF0_TXI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, + SCIF0_PRIORITY); + + /* DMAC-1 */ + make_ipr_irq(DMTE0_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY); + make_ipr_irq(DMTE1_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY); + make_ipr_irq(DMTE2_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY); + make_ipr_irq(DMTE3_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY); + + /* DMAC-2 */ + make_ipr_irq(DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY); + make_ipr_irq(DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY); + + /* IPSEC */ + make_ipr_irq(IPSEC_IRQ, IPSEC_IPR_ADDR, IPSEC_IPR_POS, IPSEC_PRIORITY); + + /* EDMAC */ + make_ipr_irq(EDMAC0_IRQ, EDMAC0_IPR_ADDR, EDMAC0_IPR_POS, + EDMAC0_PRIORITY); + make_ipr_irq(EDMAC1_IRQ, EDMAC1_IPR_ADDR, EDMAC1_IPR_POS, + EDMAC1_PRIORITY); + make_ipr_irq(EDMAC2_IRQ, EDMAC2_IPR_ADDR, EDMAC2_IPR_POS, + EDMAC2_PRIORITY); + + /* SIOF0 */ + make_ipr_irq(SIOF0_ERI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, + SIOF0_PRIORITY); + make_ipr_irq(SIOF0_TXI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, + SIOF0_PRIORITY); + make_ipr_irq(SIOF0_RXI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, + SIOF0_PRIORITY); + make_ipr_irq(SIOF0_CCI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, + SIOF0_PRIORITY); + + /* SIOF1 */ + make_ipr_irq(SIOF1_ERI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS, + SIOF1_PRIORITY); + make_ipr_irq(SIOF1_TXI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS, + SIOF1_PRIORITY); + make_ipr_irq(SIOF1_RXI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS, + SIOF1_PRIORITY); + make_ipr_irq(SIOF1_CCI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS, + SIOF1_PRIORITY); + + /* SLIC IRQ's */ + make_ipr_irq(IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, IRQ1_PRIORITY); + make_ipr_irq(IRQ2_IRQ, IRQ2_IPR_ADDR, IRQ2_IPR_POS, IRQ2_PRIORITY); } /* diff --git a/trunk/arch/sh/boards/se/7300/irq.c b/trunk/arch/sh/boards/se/7300/irq.c index 1279d776d60f..ad1034f98a29 100644 --- a/trunk/arch/sh/boards/se/7300/irq.c +++ b/trunk/arch/sh/boards/se/7300/irq.c @@ -13,17 +13,6 @@ #include #include -static struct ipr_data se7300_ipr_map[] = { - /* PC_IRQ[0-3] -> IRQ0 (32) */ - { IRQ0_IRQ, IRQ0_IPR_ADDR, IRQ0_IPR_POS, 0x0f - IRQ0_IRQ }, - /* A_IRQ[0-3] -> IRQ1 (33) */ - { IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, 0x0f - IRQ1_IRQ }, - { SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY }, - { DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY }, - { DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY }, - { VIO_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY }, -}; - /* * Initialize IRQ setting */ @@ -34,7 +23,14 @@ init_7300se_IRQ(void) ctrl_outw(0xa000, INTC_ICR1); /* IRQ mode; IRQ0,1 enable. */ ctrl_outw(0x0000, PORT_PFCR); /* use F for IRQ[3:0] and SIU. */ - make_ipr_irq(se7300_ipr_map, ARRAY_SIZE(se7300_ipr_map)); + /* PC_IRQ[0-3] -> IRQ0 (32) */ + make_ipr_irq(IRQ0_IRQ, IRQ0_IPR_ADDR, IRQ0_IPR_POS, 0x0f - IRQ0_IRQ); + /* A_IRQ[0-3] -> IRQ1 (33) */ + make_ipr_irq(IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, 0x0f - IRQ1_IRQ); + make_ipr_irq(SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY); + make_ipr_irq(DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY); + make_ipr_irq(DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY); + make_ipr_irq(VIO_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY); ctrl_outw(0x2000, PA_MRSHPC + 0x0c); /* mrshpc irq enable */ } diff --git a/trunk/arch/sh/boards/se/73180/irq.c b/trunk/arch/sh/boards/se/73180/irq.c index e7200c56bb45..2c62b8ea350e 100644 --- a/trunk/arch/sh/boards/se/73180/irq.c +++ b/trunk/arch/sh/boards/se/73180/irq.c @@ -87,38 +87,13 @@ shmse_irq_demux(int irq) return irq; } -static struct ipr_data se73180_siof0_ipr_map[] = { - { SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY }, -}; -static struct ipr_data se73180_vpu_ipr_map[] = { - { VPU_IRQ, VPU_IPR_ADDR, VPU_IPR_POS, 8 }, -}; -static struct ipr_data se73180_other_ipr_map[] = { - { DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY }, - { DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY }, - { DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY }, - { IIC0_ALI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY }, - { IIC0_TACKI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY }, - { IIC0_WAITI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY }, - { IIC0_DTEI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY }, - { SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY }, - { SIU_IRQ, SIU_IPR_ADDR, SIU_IPR_POS, SIU_PRIORITY }, - - /* VIO interrupt */ - { CEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY }, - { BEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY }, - { VEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY }, - - { LCDC_IRQ, LCDC_IPR_ADDR, LCDC_IPR_POS, LCDC_PRIORITY }, -}; - /* * Initialize IRQ setting */ void __init init_73180se_IRQ(void) { - make_ipr_irq(se73180_siof0_ipr_map, ARRAY_SIZE(se73180_siof0_ipr_map)); + make_ipr_irq(SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY); ctrl_outw(0x2000, 0xb03fffec); /* mrshpc irq enable */ ctrl_outw(0x2000, 0xb07fffec); /* mrshpc irq enable */ @@ -126,11 +101,27 @@ init_73180se_IRQ(void) ctrl_outw(2 << ((7 - 5) * 2), INTC_ICR1); /* low-level irq */ make_intreq_irq(10); - make_ipr_irq(se73180_vpu_ipr_map, ARRAY_SIZE(se73180_vpu_ipr_map)); + make_ipr_irq(VPU_IRQ, VPU_IPR_ADDR, VPU_IPR_POS, 8); ctrl_outb(0x0f, INTC_IMCR5); /* enable SCIF IRQ */ - make_ipr_irq(se73180_other_ipr_map, ARRAY_SIZE(se73180_other_ipr_map)); + make_ipr_irq(DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY); + make_ipr_irq(DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY); + make_ipr_irq(DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY); + make_ipr_irq(IIC0_ALI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY); + make_ipr_irq(IIC0_TACKI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, + IIC0_PRIORITY); + make_ipr_irq(IIC0_WAITI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, + IIC0_PRIORITY); + make_ipr_irq(IIC0_DTEI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY); + make_ipr_irq(SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY); + make_ipr_irq(SIU_IRQ, SIU_IPR_ADDR, SIU_IPR_POS, SIU_PRIORITY); + + /* VIO interrupt */ + make_ipr_irq(CEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY); + make_ipr_irq(BEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY); + make_ipr_irq(VEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY); + make_ipr_irq(LCDC_IRQ, LCDC_IPR_ADDR, LCDC_IPR_POS, LCDC_PRIORITY); ctrl_outw(0x2000, PA_MRSHPC + 0x0c); /* mrshpc irq enable */ } diff --git a/trunk/arch/sh/boards/se/7343/irq.c b/trunk/arch/sh/boards/se/7343/irq.c index 360153ecc55b..288b62f59419 100644 --- a/trunk/arch/sh/boards/se/7343/irq.c +++ b/trunk/arch/sh/boards/se/7343/irq.c @@ -102,51 +102,6 @@ shmse_irq_demux(int irq) static struct irqaction irq5 = { no_action, 0, CPU_MASK_NONE, "IRQ5-cascade", NULL, NULL}; -static struct ipr_data se7343_irq5_ipr_map[] = { - { IRQ5_IRQ, IRQ5_IPR_ADDR+2, IRQ5_IPR_POS, IRQ5_PRIORITY }, -}; -static struct ipr_data se7343_siof0_vpu_ipr_map[] = { - { SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY }, - { VPU_IRQ, VPU_IPR_ADDR, VPU_IPR_POS, 8 }, -}; -static struct ipr_data se7343_other_ipr_map[] = { - { DMTE0_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY }, - { DMTE1_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY }, - { DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY }, - { DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY }, - { DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY }, - { DMTE5_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY }, - - /* I2C block */ - { IIC0_ALI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY }, - { IIC0_TACKI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY }, - { IIC0_WAITI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY }, - { IIC0_DTEI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY }, - - { IIC1_ALI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS, IIC1_PRIORITY }, - { IIC1_TACKI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS, IIC1_PRIORITY }, - { IIC1_WAITI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS, IIC1_PRIORITY }, - { IIC1_DTEI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS, IIC1_PRIORITY }, - - /* SIOF */ - { SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY }, - - /* SIU */ - { SIU_IRQ, SIU_IPR_ADDR, SIU_IPR_POS, SIU_PRIORITY }, - - /* VIO interrupt */ - { CEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY }, - { BEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY }, - { VEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY }, - - /*MFI interrupt*/ - - { MFI_IRQ, MFI_IPR_ADDR, MFI_IPR_POS, MFI_PRIORITY }, - - /* LCD controller */ - { LCDC_IRQ, LCDC_IPR_ADDR, LCDC_IPR_POS, LCDC_PRIORITY }, -}; - /* * Initialize IRQ setting */ @@ -183,17 +138,54 @@ init_7343se_IRQ(void) /* Setup all external interrupts to be active low */ ctrl_outw(0xaaaa, INTC_ICR1); - make_ipr_irq(se7343_irq5_ipr_map, ARRAY_SIZE(se7343_irq5_ipr_map)); - + make_ipr_irq(IRQ5_IRQ, IRQ5_IPR_ADDR+2, IRQ5_IPR_POS, IRQ5_PRIORITY); setup_irq(IRQ5_IRQ, &irq5); /* Set port control to use IRQ5 */ *(u16 *)0xA4050108 &= ~0xc; - make_ipr_irq(se7343_siof0_vpu_ipr_map, ARRAY_SIZE(se7343_siof0_vpu_ipr_map)); + make_ipr_irq(SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY); + make_ipr_irq(VPU_IRQ, VPU_IPR_ADDR, VPU_IPR_POS, 8); ctrl_outb(0x0f, INTC_IMCR5); /* enable SCIF IRQ */ - make_ipr_irq(se7343_other_ipr_map, ARRAY_SIZE(se7343_other_ipr_map)); + make_ipr_irq(DMTE0_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY); + make_ipr_irq(DMTE1_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY); + make_ipr_irq(DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY); + make_ipr_irq(DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY); + make_ipr_irq(DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY); + make_ipr_irq(DMTE5_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY); + + /* I2C block */ + make_ipr_irq(IIC0_ALI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY); + make_ipr_irq(IIC0_TACKI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, + IIC0_PRIORITY); + make_ipr_irq(IIC0_WAITI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, + IIC0_PRIORITY); + make_ipr_irq(IIC0_DTEI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY); + + make_ipr_irq(IIC1_ALI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS, IIC1_PRIORITY); + make_ipr_irq(IIC1_TACKI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS, + IIC1_PRIORITY); + make_ipr_irq(IIC1_WAITI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS, + IIC1_PRIORITY); + make_ipr_irq(IIC1_DTEI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS, IIC1_PRIORITY); + + /* SIOF */ + make_ipr_irq(SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY); + /* SIU */ + make_ipr_irq(SIU_IRQ, SIU_IPR_ADDR, SIU_IPR_POS, SIU_PRIORITY); + + /* VIO interrupt */ + make_ipr_irq(CEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY); + make_ipr_irq(BEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY); + make_ipr_irq(VEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY); + + /*MFI interrupt*/ + + make_ipr_irq(MFI_IRQ, MFI_IPR_ADDR, MFI_IPR_POS, MFI_PRIORITY); + + /* LCD controller */ + make_ipr_irq(LCDC_IRQ, LCDC_IPR_ADDR, LCDC_IPR_POS, LCDC_PRIORITY); ctrl_outw(0x2000, PA_MRSHPC + 0x0c); /* mrshpc irq enable */ } diff --git a/trunk/arch/sh/boards/se/770x/irq.c b/trunk/arch/sh/boards/se/770x/irq.c index fcd7cd7fa05f..cff6700bbafd 100644 --- a/trunk/arch/sh/boards/se/770x/irq.c +++ b/trunk/arch/sh/boards/se/770x/irq.c @@ -13,48 +13,6 @@ #include #include -static struct ipr_data se770x_ipr_map[] = { -#if defined(CONFIG_CPU_SUBTYPE_SH7705) - /* This is default value */ - { 0xf-0x2, BCR_ILCRA, 2, 0x2 }, - { 0xf-0xa, BCR_ILCRA, 1, 0xa }, - { 0xf-0x5, BCR_ILCRB, 0, 0x5 }, - { 0xf-0x8, BCR_ILCRC, 1, 0x8 }, - { 0xf-0xc, BCR_ILCRC, 0, 0xc }, - { 0xf-0xe, BCR_ILCRD, 3, 0xe }, - { 0xf-0x3, BCR_ILCRD, 1, 0x3 }, /* LAN */ - { 0xf-0xd, BCR_ILCRE, 2, 0xd }, - { 0xf-0x9, BCR_ILCRE, 1, 0x9 }, - { 0xf-0x1, BCR_ILCRE, 0, 0x1 }, - { 0xf-0xf, BCR_ILCRF, 3, 0xf }, - { 0xf-0xb, BCR_ILCRF, 1, 0xb }, - { 0xf-0x7, BCR_ILCRG, 3, 0x7 }, - { 0xf-0x6, BCR_ILCRG, 2, 0x6 }, - { 0xf-0x4, BCR_ILCRG, 1, 0x4 }, -#else - { 14, BCR_ILCRA, 2, 0x0f-14 }, - { 12, BCR_ILCRA, 1, 0x0f-12 }, - { 8, BCR_ILCRB, 1, 0x0f- 8 }, - { 6, BCR_ILCRC, 3, 0x0f- 6 }, - { 5, BCR_ILCRC, 2, 0x0f- 5 }, - { 4, BCR_ILCRC, 1, 0x0f- 4 }, - { 3, BCR_ILCRC, 0, 0x0f- 3 }, - { 1, BCR_ILCRD, 3, 0x0f- 1 }, - - { 10, BCR_ILCRD, 1, 0x0f-10 }, /* LAN */ - - { 0, BCR_ILCRE, 3, 0x0f- 0 }, /* PCIRQ3 */ - { 11, BCR_ILCRE, 2, 0x0f-11 }, /* PCIRQ2 */ - { 9, BCR_ILCRE, 1, 0x0f- 9 }, /* PCIRQ1 */ - { 7, BCR_ILCRE, 0, 0x0f- 7 }, /* PCIRQ0 */ - - /* #2, #13 are allocated for SLOT IRQ #1 and #2 (for now) */ - /* NOTE: #2 and #13 are not used on PC */ - { 13, BCR_ILCRG, 1, 0x0f-13 }, /* SLOTIRQ2 */ - { 2, BCR_ILCRG, 0, 0x0f- 2 }, /* SLOTIRQ1 */ -#endif -}; - /* * Initialize IRQ setting */ @@ -80,6 +38,42 @@ void __init init_se_IRQ(void) ctrl_outw(0, BCR_ILCRE); ctrl_outw(0, BCR_ILCRF); ctrl_outw(0, BCR_ILCRG); + /* This is default value */ + make_ipr_irq(0xf-0x2, BCR_ILCRA, 2, 0x2); + make_ipr_irq(0xf-0xa, BCR_ILCRA, 1, 0xa); + make_ipr_irq(0xf-0x5, BCR_ILCRB, 0, 0x5); + make_ipr_irq(0xf-0x8, BCR_ILCRC, 1, 0x8); + make_ipr_irq(0xf-0xc, BCR_ILCRC, 0, 0xc); + make_ipr_irq(0xf-0xe, BCR_ILCRD, 3, 0xe); + make_ipr_irq(0xf-0x3, BCR_ILCRD, 1, 0x3); /* LAN */ + make_ipr_irq(0xf-0xd, BCR_ILCRE, 2, 0xd); + make_ipr_irq(0xf-0x9, BCR_ILCRE, 1, 0x9); + make_ipr_irq(0xf-0x1, BCR_ILCRE, 0, 0x1); + make_ipr_irq(0xf-0xf, BCR_ILCRF, 3, 0xf); + make_ipr_irq(0xf-0xb, BCR_ILCRF, 1, 0xb); + make_ipr_irq(0xf-0x7, BCR_ILCRG, 3, 0x7); + make_ipr_irq(0xf-0x6, BCR_ILCRG, 2, 0x6); + make_ipr_irq(0xf-0x4, BCR_ILCRG, 1, 0x4); +#else + make_ipr_irq(14, BCR_ILCRA, 2, 0x0f-14); + make_ipr_irq(12, BCR_ILCRA, 1, 0x0f-12); + make_ipr_irq( 8, BCR_ILCRB, 1, 0x0f- 8); + make_ipr_irq( 6, BCR_ILCRC, 3, 0x0f- 6); + make_ipr_irq( 5, BCR_ILCRC, 2, 0x0f- 5); + make_ipr_irq( 4, BCR_ILCRC, 1, 0x0f- 4); + make_ipr_irq( 3, BCR_ILCRC, 0, 0x0f- 3); + make_ipr_irq( 1, BCR_ILCRD, 3, 0x0f- 1); + + make_ipr_irq(10, BCR_ILCRD, 1, 0x0f-10); /* LAN */ + + make_ipr_irq( 0, BCR_ILCRE, 3, 0x0f- 0); /* PCIRQ3 */ + make_ipr_irq(11, BCR_ILCRE, 2, 0x0f-11); /* PCIRQ2 */ + make_ipr_irq( 9, BCR_ILCRE, 1, 0x0f- 9); /* PCIRQ1 */ + make_ipr_irq( 7, BCR_ILCRE, 0, 0x0f- 7); /* PCIRQ0 */ + + /* #2, #13 are allocated for SLOT IRQ #1 and #2 (for now) */ + /* NOTE: #2 and #13 are not used on PC */ + make_ipr_irq(13, BCR_ILCRG, 1, 0x0f-13); /* SLOTIRQ2 */ + make_ipr_irq( 2, BCR_ILCRG, 0, 0x0f- 2); /* SLOTIRQ1 */ #endif - make_ipr_irq(se770x_ipr_map, ARRAY_SIZE(se770x_ipr_map)); } diff --git a/trunk/arch/sh/boards/se/7751/irq.c b/trunk/arch/sh/boards/se/7751/irq.c index e4c63a48296c..c607b0a48479 100644 --- a/trunk/arch/sh/boards/se/7751/irq.c +++ b/trunk/arch/sh/boards/se/7751/irq.c @@ -14,50 +14,53 @@ #include #include -static struct ipr_data se7751_ipr_map[] = { - /* Leave old Solution Engine code in for reference. */ -#if defined(CONFIG_SH_SOLUTION_ENGINE) - /* - * Super I/O (Just mimic PC): - * 1: keyboard - * 3: serial 0 - * 4: serial 1 - * 5: printer - * 6: floppy - * 8: rtc - * 12: mouse - * 14: ide0 - */ - { 14, BCR_ILCRA, 2, 0x0f-14 }, - { 12, BCR_ILCRA, 1, 0x0f-12 }, - { 8, BCR_ILCRB, 1, 0x0f- 8 }, - { 6, BCR_ILCRC, 3, 0x0f- 6 }, - { 5, BCR_ILCRC, 2, 0x0f- 5 }, - { 4, BCR_ILCRC, 1, 0x0f- 4 }, - { 3, BCR_ILCRC, 0, 0x0f- 3 }, - { 1, BCR_ILCRD, 3, 0x0f- 1 }, - - { 10, BCR_ILCRD, 1, 0x0f-10 }, /* LAN */ - - { 0, BCR_ILCRE, 3, 0x0f- 0 }, /* PCIRQ3 */ - { 11, BCR_ILCRE, 2, 0x0f-11 }, /* PCIRQ2 */ - { 9, BCR_ILCRE, 1, 0x0f- 9 }, /* PCIRQ1 */ - { 7, BCR_ILCRE, 0, 0x0f- 7 }, /* PCIRQ0 */ - - /* #2, #13 are allocated for SLOT IRQ #1 and #2 (for now) */ - /* NOTE: #2 and #13 are not used on PC */ - { 13, BCR_ILCRG, 1, 0x0f-13 }, /* SLOTIRQ2 */ - { 2, BCR_ILCRG, 0, 0x0f- 2 }, /* SLOTIRQ1 */ -#elif defined(CONFIG_SH_7751_SOLUTION_ENGINE) - { 13, BCR_ILCRD, 3, 2 }, - /* Add additional entries here as drivers are added and tested. */ -#endif -}; - /* * Initialize IRQ setting */ void __init init_7751se_IRQ(void) { - make_ipr_irq(se7751_ipr_map, ARRAY_SIZE(se7751_ipr_map)); + + /* Leave old Solution Engine code in for reference. */ +#if defined(CONFIG_SH_SOLUTION_ENGINE) + /* + * Super I/O (Just mimic PC): + * 1: keyboard + * 3: serial 0 + * 4: serial 1 + * 5: printer + * 6: floppy + * 8: rtc + * 12: mouse + * 14: ide0 + */ + make_ipr_irq(14, BCR_ILCRA, 2, 0x0f-14); + make_ipr_irq(12, BCR_ILCRA, 1, 0x0f-12); + make_ipr_irq( 8, BCR_ILCRB, 1, 0x0f- 8); + make_ipr_irq( 6, BCR_ILCRC, 3, 0x0f- 6); + make_ipr_irq( 5, BCR_ILCRC, 2, 0x0f- 5); + make_ipr_irq( 4, BCR_ILCRC, 1, 0x0f- 4); + make_ipr_irq( 3, BCR_ILCRC, 0, 0x0f- 3); + make_ipr_irq( 1, BCR_ILCRD, 3, 0x0f- 1); + + make_ipr_irq(10, BCR_ILCRD, 1, 0x0f-10); /* LAN */ + + make_ipr_irq( 0, BCR_ILCRE, 3, 0x0f- 0); /* PCIRQ3 */ + make_ipr_irq(11, BCR_ILCRE, 2, 0x0f-11); /* PCIRQ2 */ + make_ipr_irq( 9, BCR_ILCRE, 1, 0x0f- 9); /* PCIRQ1 */ + make_ipr_irq( 7, BCR_ILCRE, 0, 0x0f- 7); /* PCIRQ0 */ + + /* #2, #13 are allocated for SLOT IRQ #1 and #2 (for now) */ + /* NOTE: #2 and #13 are not used on PC */ + make_ipr_irq(13, BCR_ILCRG, 1, 0x0f-13); /* SLOTIRQ2 */ + make_ipr_irq( 2, BCR_ILCRG, 0, 0x0f- 2); /* SLOTIRQ1 */ + +#elif defined(CONFIG_SH_7751_SOLUTION_ENGINE) + + make_ipr_irq(13, BCR_ILCRD, 3, 2); + + /* Add additional calls to make_ipr_irq() as drivers are added + * and tested. + */ +#endif + } diff --git a/trunk/arch/sh/boards/sh03/setup.c b/trunk/arch/sh/boards/sh03/setup.c index 5ad1e19771be..137e2ba9243e 100644 --- a/trunk/arch/sh/boards/sh03/setup.c +++ b/trunk/arch/sh/boards/sh03/setup.c @@ -14,17 +14,14 @@ #include #include -static struct ipr_data sh03_ipr_map[] = { - { IRL0_IRQ, IRL0_IPR_ADDR, IRL0_IPR_POS, IRL0_PRIORITY }, - { IRL1_IRQ, IRL1_IPR_ADDR, IRL1_IPR_POS, IRL1_PRIORITY }, - { IRL2_IRQ, IRL2_IPR_ADDR, IRL2_IPR_POS, IRL2_PRIORITY }, - { IRL3_IRQ, IRL3_IPR_ADDR, IRL3_IPR_POS, IRL3_PRIORITY }, -}; - static void __init init_sh03_IRQ(void) { ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); - make_ipr_irq(sh03_ipr_map, ARRAY_SIZE(sh03_ipr_map)); + + make_ipr_irq(IRL0_IRQ, IRL0_IPR_ADDR, IRL0_IPR_POS, IRL0_PRIORITY); + make_ipr_irq(IRL1_IRQ, IRL1_IPR_ADDR, IRL1_IPR_POS, IRL1_PRIORITY); + make_ipr_irq(IRL2_IRQ, IRL2_IPR_ADDR, IRL2_IPR_POS, IRL2_PRIORITY); + make_ipr_irq(IRL3_IRQ, IRL3_IPR_ADDR, IRL3_IPR_POS, IRL3_PRIORITY); } extern void *cf_io_base; diff --git a/trunk/arch/sh/boards/shmin/setup.c b/trunk/arch/sh/boards/shmin/setup.c index a31a1d1e2681..2f0c19706cf9 100644 --- a/trunk/arch/sh/boards/shmin/setup.c +++ b/trunk/arch/sh/boards/shmin/setup.c @@ -7,7 +7,7 @@ */ #include #include -#include +#include #include #include #include diff --git a/trunk/arch/sh/boards/snapgear/setup.c b/trunk/arch/sh/boards/snapgear/setup.c index 650fb3645947..f5e98c56b530 100644 --- a/trunk/arch/sh/boards/snapgear/setup.c +++ b/trunk/arch/sh/boards/snapgear/setup.c @@ -33,7 +33,7 @@ extern void pcibios_init(void); * EraseConfig handling functions */ -static irqreturn_t eraseconfig_interrupt(int irq, void *dev_id) +static irqreturn_t eraseconfig_interrupt(int irq, void *dev_id, struct pt_regs *regs) { volatile char dummy __attribute__((unused)) = * (volatile char *) 0xb8000000; @@ -68,13 +68,6 @@ module_init(eraseconfig_init); * IRL3 = crypto */ -static struct ipr_data snapgear_ipr_map[] = { - make_ipr_irq(IRL0_IRQ, IRL0_IPR_ADDR, IRL0_IPR_POS, IRL0_PRIORITY); - make_ipr_irq(IRL1_IRQ, IRL1_IPR_ADDR, IRL1_IPR_POS, IRL1_PRIORITY); - make_ipr_irq(IRL2_IRQ, IRL2_IPR_ADDR, IRL2_IPR_POS, IRL2_PRIORITY); - make_ipr_irq(IRL3_IRQ, IRL3_IPR_ADDR, IRL3_IPR_POS, IRL3_PRIORITY); -}; - static void __init init_snapgear_IRQ(void) { /* enable individual interrupt mode for externals */ @@ -82,7 +75,10 @@ static void __init init_snapgear_IRQ(void) printk("Setup SnapGear IRQ/IPR ...\n"); - make_ipr_irq(snapgear_ipr_map, ARRAY_SIZE(snapgear_ipr_map)); + make_ipr_irq(IRL0_IRQ, IRL0_IPR_ADDR, IRL0_IPR_POS, IRL0_PRIORITY); + make_ipr_irq(IRL1_IRQ, IRL1_IPR_ADDR, IRL1_IPR_POS, IRL1_PRIORITY); + make_ipr_irq(IRL2_IRQ, IRL2_IPR_ADDR, IRL2_IPR_POS, IRL2_PRIORITY); + make_ipr_irq(IRL3_IRQ, IRL3_IPR_ADDR, IRL3_IPR_POS, IRL3_PRIORITY); } /* diff --git a/trunk/arch/sh/boards/titan/setup.c b/trunk/arch/sh/boards/titan/setup.c index a6046d93758b..52b66d8b8d2a 100644 --- a/trunk/arch/sh/boards/titan/setup.c +++ b/trunk/arch/sh/boards/titan/setup.c @@ -9,19 +9,15 @@ extern void __init pcibios_init_platform(void); -static struct ipr_data titan_ipr_map[] = { - { TITAN_IRQ_WAN, IRL0_IPR_ADDR, IRL0_IPR_POS, IRL0_PRIORITY }, - { TITAN_IRQ_LAN, IRL1_IPR_ADDR, IRL1_IPR_POS, IRL1_PRIORITY }, - { TITAN_IRQ_MPCIA, IRL2_IPR_ADDR, IRL2_IPR_POS, IRL2_PRIORITY }, - { TITAN_IRQ_USB, IRL3_IPR_ADDR, IRL3_IPR_POS, IRL3_PRIORITY }, -}; - static void __init init_titan_irq(void) { /* enable individual interrupt mode for externals */ ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); - make_ipr_irq(titan_ipr_map, ARRAY_SIZE(titan_ipr_map)); + make_ipr_irq( TITAN_IRQ_WAN, IRL0_IPR_ADDR, IRL0_IPR_POS, IRL0_PRIORITY); /* PCIRQ0 */ + make_ipr_irq( TITAN_IRQ_LAN, IRL1_IPR_ADDR, IRL1_IPR_POS, IRL1_PRIORITY); /* PCIRQ1 */ + make_ipr_irq( TITAN_IRQ_MPCIA, IRL2_IPR_ADDR, IRL2_IPR_POS, IRL2_PRIORITY); /* PCIRQ2 */ + make_ipr_irq( TITAN_IRQ_USB, IRL3_IPR_ADDR, IRL3_IPR_POS, IRL3_PRIORITY); /* PCIRQ3 */ } struct sh_machine_vector mv_titan __initmv = { diff --git a/trunk/arch/sh/cchips/hd6446x/hd64461/setup.c b/trunk/arch/sh/cchips/hd6446x/hd64461/setup.c index 4d49b5cbcc13..38f1e8171a3a 100644 --- a/trunk/arch/sh/cchips/hd6446x/hd64461/setup.c +++ b/trunk/arch/sh/cchips/hd6446x/hd64461/setup.c @@ -71,7 +71,7 @@ static struct hw_interrupt_type hd64461_irq_type = { .end = end_hd64461_irq, }; -static irqreturn_t hd64461_interrupt(int irq, void *dev_id) +static irqreturn_t hd64461_interrupt(int irq, void *dev_id, struct pt_regs *regs) { printk(KERN_INFO "HD64461: spurious interrupt, nirr: 0x%x nimr: 0x%x\n", diff --git a/trunk/arch/sh/cchips/hd6446x/hd64465/gpio.c b/trunk/arch/sh/cchips/hd6446x/hd64465/gpio.c index 43431855ec86..72320d02d69a 100644 --- a/trunk/arch/sh/cchips/hd6446x/hd64465/gpio.c +++ b/trunk/arch/sh/cchips/hd6446x/hd64465/gpio.c @@ -85,7 +85,7 @@ static struct { void *dev; } handlers[GPIO_NPORTS * 8]; -static irqreturn_t hd64465_gpio_interrupt(int irq, void *dev) +static irqreturn_t hd64465_gpio_interrupt(int irq, void *dev, struct pt_regs *regs) { unsigned short port, pin, isr, mask, portpin; diff --git a/trunk/arch/sh/cchips/hd6446x/hd64465/setup.c b/trunk/arch/sh/cchips/hd6446x/hd64465/setup.c index d126e1f30dee..30573d3e1966 100644 --- a/trunk/arch/sh/cchips/hd6446x/hd64465/setup.c +++ b/trunk/arch/sh/cchips/hd6446x/hd64465/setup.c @@ -84,7 +84,7 @@ static struct hw_interrupt_type hd64465_irq_type = { }; -static irqreturn_t hd64465_interrupt(int irq, void *dev_id) +static irqreturn_t hd64465_interrupt(int irq, void *dev_id, struct pt_regs *regs) { printk(KERN_INFO "HD64465: spurious interrupt, nirr: 0x%x nimr: 0x%x\n", diff --git a/trunk/arch/sh/cchips/voyagergx/irq.c b/trunk/arch/sh/cchips/voyagergx/irq.c index f7ea700d05ae..392c8b12ce36 100644 --- a/trunk/arch/sh/cchips/voyagergx/irq.c +++ b/trunk/arch/sh/cchips/voyagergx/irq.c @@ -17,18 +17,29 @@ Copyright 2003 (c) Lineo uSolutions,Inc. */ +/* -------------------------------------------------------------------- */ + +#undef DEBUG + +#include +#include +#include +#include +#include #include #include -#include +#include + +#include +#include #include -#include static void disable_voyagergx_irq(unsigned int irq) { unsigned long val; unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE); - pr_debug("disable_voyagergx_irq(%d): mask=%lx\n", irq, mask); + pr_debug("disable_voyagergx_irq(%d): mask=%x\n", irq, mask); val = inl(VOYAGER_INT_MASK); val &= ~mask; outl(val, VOYAGER_INT_MASK); @@ -39,7 +50,7 @@ static void enable_voyagergx_irq(unsigned int irq) unsigned long val; unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE); - pr_debug("disable_voyagergx_irq(%d): mask=%lx\n", irq, mask); + pr_debug("disable_voyagergx_irq(%d): mask=%x\n", irq, mask); val = inl(VOYAGER_INT_MASK); val |= mask; outl(val, VOYAGER_INT_MASK); @@ -77,7 +88,8 @@ static struct hw_interrupt_type voyagergx_irq_type = { .end = end_voyagergx_irq, }; -static irqreturn_t voyagergx_interrupt(int irq, void *dev_id) +static irqreturn_t voyagergx_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { printk(KERN_INFO "VoyagerGX: spurious interrupt, status: 0x%x\n", @@ -126,7 +138,7 @@ int voyagergx_irq_demux(int irq) } else { printk("Unexpected IRQ irq = %d status = 0x%08lx\n", irq, val); } - pr_debug("voyagergx_irq_demux %ld\n", i); + pr_debug("voyagergx_irq_demux %d \n", i); #else for (bit = 1, i = 0 ; i < VOYAGER_IRQ_NUM ; bit <<= 1, i++) if (val & bit) @@ -174,3 +186,4 @@ void __init setup_voyagergx_irq(void) setup_irq(IRQ_VOYAGER, &irq0); } + diff --git a/trunk/arch/sh/configs/r7780rp_defconfig b/trunk/arch/sh/configs/r7780rp_defconfig index 34e2046c3213..2470364948e7 100644 --- a/trunk/arch/sh/configs/r7780rp_defconfig +++ b/trunk/arch/sh/configs/r7780rp_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.19-rc3 -# Tue Oct 31 12:32:06 2006 +# Linux kernel version: 2.6.18 +# Tue Oct 3 11:32:47 2006 # CONFIG_SUPERH=y CONFIG_RWSEM_GENERIC_SPINLOCK=y @@ -10,7 +10,6 @@ CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y CONFIG_GENERIC_CALIBRATE_DELAY=y -# CONFIG_GENERIC_TIME is not set CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -179,7 +178,7 @@ CONFIG_MMU=y CONFIG_PAGE_OFFSET=0x80000000 CONFIG_MEMORY_START=0x08000000 CONFIG_MEMORY_SIZE=0x08000000 -# CONFIG_32BIT is not set +CONFIG_32BIT=y CONFIG_VSYSCALL=y CONFIG_HUGETLB_PAGE_SIZE_64K=y # CONFIG_HUGETLB_PAGE_SIZE_1MB is not set @@ -230,7 +229,9 @@ CONFIG_SH_PCLK_FREQ=32000000 # # DMA support # -# CONFIG_SH_DMA is not set +CONFIG_SH_DMA=y +CONFIG_NR_ONCHIP_DMA_CHANNELS=6 +# CONFIG_NR_DMA_CHANNELS_BOOL is not set # # Companion Chips @@ -258,7 +259,7 @@ CONFIG_ZERO_PAGE_OFFSET=0x00001000 CONFIG_BOOT_LINK_OFFSET=0x00800000 # CONFIG_UBC_WAKEUP is not set CONFIG_CMDLINE_BOOL=y -CONFIG_CMDLINE="mem=128M console=ttySC0,115200 root=/dev/sda1" +CONFIG_CMDLINE="mem=128M console=ttySC0,115200 root=/dev/hda1" # # Bus options @@ -335,7 +336,6 @@ CONFIG_IP_PNP_DHCP=y # CONFIG_INET_TUNNEL is not set CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=y CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set @@ -440,29 +440,77 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set -# -# Misc devices -# -# CONFIG_SGI_IOC4 is not set -# CONFIG_TIFM_CORE is not set - # # ATA/ATAPI/MFM/RLL support # -# CONFIG_IDE is not set +CONFIG_IDE=m +CONFIG_IDE_MAX_HWIFS=4 +CONFIG_BLK_DEV_IDE=m + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +CONFIG_BLK_DEV_IDE_SATA=y +CONFIG_BLK_DEV_IDEDISK=m +CONFIG_IDEDISK_MULTI_MODE=y +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +CONFIG_BLK_DEV_IDESCSI=m +# CONFIG_IDE_TASK_IOCTL is not set + +# +# IDE chipset support/bugfixes +# +CONFIG_IDE_GENERIC=m +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_IDEPCI_SHARE_IRQ=y +# CONFIG_BLK_DEV_OFFBOARD is not set +CONFIG_BLK_DEV_GENERIC=m +# CONFIG_BLK_DEV_OPTI621 is not set +CONFIG_BLK_DEV_IDEDMA_PCI=y +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set +CONFIG_IDEDMA_PCI_AUTO=y +# CONFIG_IDEDMA_ONLYDISK is not set +CONFIG_BLK_DEV_AEC62XX=m +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD74XX is not set +# CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_TRIFLEX is not set +# CONFIG_BLK_DEV_CY82C693 is not set +# CONFIG_BLK_DEV_CS5520 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_HPT34X is not set +# CONFIG_BLK_DEV_HPT366 is not set +# CONFIG_BLK_DEV_SC1200 is not set +# CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_IT821X is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +CONFIG_BLK_DEV_PDC202XX_NEW=m +# CONFIG_BLK_DEV_SVWKS is not set +CONFIG_BLK_DEV_SIIMAGE=m +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_IDE_ARM is not set +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_IDEDMA_IVB is not set +CONFIG_IDEDMA_AUTO=y +# CONFIG_BLK_DEV_HD is not set # # SCSI device support # # CONFIG_RAID_ATTRS is not set -CONFIG_SCSI=y +CONFIG_SCSI=m # CONFIG_SCSI_NETLINK is not set CONFIG_SCSI_PROC_FS=y # # SCSI support type (disk, tape, CD-ROM) # -CONFIG_BLK_DEV_SD=y +CONFIG_BLK_DEV_SD=m # CONFIG_CHR_DEV_ST is not set # CONFIG_CHR_DEV_OSST is not set # CONFIG_BLK_DEV_SR is not set @@ -513,7 +561,6 @@ CONFIG_CHR_DEV_SG=m # CONFIG_SCSI_IPR is not set # CONFIG_SCSI_QLOGIC_1280 is not set # CONFIG_SCSI_QLA_FC is not set -# CONFIG_SCSI_QLA_ISCSI is not set # CONFIG_SCSI_LPFC is not set # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set @@ -523,55 +570,7 @@ CONFIG_CHR_DEV_SG=m # # Serial ATA (prod) and Parallel ATA (experimental) drivers # -CONFIG_ATA=y -# CONFIG_SATA_AHCI is not set -# CONFIG_SATA_SVW is not set -# CONFIG_ATA_PIIX is not set -# CONFIG_SATA_MV is not set -# CONFIG_SATA_NV is not set -# CONFIG_PDC_ADMA is not set -# CONFIG_SATA_QSTOR is not set -# CONFIG_SATA_PROMISE is not set -# CONFIG_SATA_SX4 is not set -CONFIG_SATA_SIL=y -# CONFIG_SATA_SIL24 is not set -# CONFIG_SATA_SIS is not set -# CONFIG_SATA_ULI is not set -# CONFIG_SATA_VIA is not set -# CONFIG_SATA_VITESSE is not set -# CONFIG_PATA_ALI is not set -# CONFIG_PATA_AMD is not set -# CONFIG_PATA_ARTOP is not set -# CONFIG_PATA_ATIIXP is not set -# CONFIG_PATA_CMD64X is not set -# CONFIG_PATA_CS5520 is not set -# CONFIG_PATA_CS5530 is not set -# CONFIG_PATA_CYPRESS is not set -# CONFIG_PATA_EFAR is not set -# CONFIG_ATA_GENERIC is not set -# CONFIG_PATA_HPT366 is not set -# CONFIG_PATA_HPT37X is not set -# CONFIG_PATA_HPT3X2N is not set -# CONFIG_PATA_HPT3X3 is not set -# CONFIG_PATA_IT821X is not set -# CONFIG_PATA_JMICRON is not set -# CONFIG_PATA_TRIFLEX is not set -# CONFIG_PATA_MPIIX is not set -# CONFIG_PATA_OLDPIIX is not set -# CONFIG_PATA_NETCELL is not set -# CONFIG_PATA_NS87410 is not set -# CONFIG_PATA_OPTI is not set -# CONFIG_PATA_OPTIDMA is not set -# CONFIG_PATA_PDC_OLD is not set -# CONFIG_PATA_RADISYS is not set -# CONFIG_PATA_RZ1000 is not set -# CONFIG_PATA_SC1200 is not set -# CONFIG_PATA_SERVERWORKS is not set -# CONFIG_PATA_PDC2027X is not set -# CONFIG_PATA_SIL680 is not set -# CONFIG_PATA_SIS is not set -# CONFIG_PATA_VIA is not set -# CONFIG_PATA_WINBOND is not set +# CONFIG_ATA is not set # # Multi-device support (RAID and LVM) @@ -841,6 +840,7 @@ CONFIG_HW_RANDOM=y # TPM devices # # CONFIG_TCG_TPM is not set +# CONFIG_TELCLOCK is not set # # I2C support @@ -856,7 +856,6 @@ CONFIG_HW_RANDOM=y # # Dallas's 1-wire bus # -# CONFIG_W1 is not set # # Hardware Monitoring support @@ -868,10 +867,15 @@ CONFIG_HWMON=y # CONFIG_SENSORS_VT1211 is not set # CONFIG_HWMON_DEBUG_CHIP is not set +# +# Misc devices +# + # # Multimedia devices # # CONFIG_VIDEO_DEV is not set +CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices @@ -955,29 +959,7 @@ CONFIG_USB_ARCH_HAS_EHCI=y # # Real Time Clock # -CONFIG_RTC_LIB=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_HCTOSYS=y -CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -# CONFIG_RTC_DEBUG is not set - -# -# RTC interfaces -# -CONFIG_RTC_INTF_SYSFS=y -CONFIG_RTC_INTF_PROC=y -CONFIG_RTC_INTF_DEV=y -# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set - -# -# RTC drivers -# -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_DS1742 is not set -# CONFIG_RTC_DRV_M48T86 is not set -CONFIG_RTC_DRV_SH=y -# CONFIG_RTC_DRV_TEST is not set -# CONFIG_RTC_DRV_V3020 is not set +# CONFIG_RTC_CLASS is not set # # DMA Engine support @@ -1002,7 +984,6 @@ CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y # CONFIG_EXT3_FS_POSIX_ACL is not set # CONFIG_EXT3_FS_SECURITY is not set -# CONFIG_EXT4DEV_FS is not set CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set CONFIG_FS_MBCACHE=y @@ -1010,7 +991,6 @@ CONFIG_FS_MBCACHE=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set CONFIG_MINIX_FS=y # CONFIG_ROMFS_FS is not set @@ -1047,8 +1027,7 @@ CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_TMPFS is not set CONFIG_HUGETLBFS=y CONFIG_HUGETLB_PAGE=y CONFIG_RAMFS=y @@ -1180,7 +1159,6 @@ CONFIG_DEBUG_FS=y # CONFIG_DEBUG_LIST is not set CONFIG_FRAME_POINTER=y CONFIG_FORCED_INLINING=y -# CONFIG_HEADERS_CHECK is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_SH_STANDARD_BIOS is not set # CONFIG_EARLY_SCIF_CONSOLE is not set @@ -1200,9 +1178,9 @@ CONFIG_FORCED_INLINING=y # CONFIG_CRYPTO=y CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER=m CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER=m CONFIG_CRYPTO_HMAC=y # CONFIG_CRYPTO_NULL is not set # CONFIG_CRYPTO_MD4 is not set @@ -1213,7 +1191,7 @@ CONFIG_CRYPTO_MD5=y # CONFIG_CRYPTO_WP512 is not set # CONFIG_CRYPTO_TGR192 is not set CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_CBC=m CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_BLOWFISH is not set # CONFIG_CRYPTO_TWOFISH is not set diff --git a/trunk/arch/sh/configs/titan_defconfig b/trunk/arch/sh/configs/titan_defconfig index 41049cf14b79..5e8175461138 100644 --- a/trunk/arch/sh/configs/titan_defconfig +++ b/trunk/arch/sh/configs/titan_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.19-rc3 -# Mon Oct 30 18:04:49 2006 +# Linux kernel version: 2.6.18 +# Tue Oct 3 12:59:14 2006 # CONFIG_SUPERH=y CONFIG_RWSEM_GENERIC_SPINLOCK=y @@ -10,7 +10,6 @@ CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y CONFIG_GENERIC_CALIBRATE_DELAY=y -# CONFIG_GENERIC_TIME is not set CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -24,7 +23,7 @@ CONFIG_INIT_ENV_ARG_LIMIT=32 # General setup # CONFIG_LOCALVERSION="" -# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_IPC_NS is not set @@ -237,8 +236,8 @@ CONFIG_HZ_250=y CONFIG_HZ=250 # CONFIG_KEXEC is not set # CONFIG_SMP is not set -# CONFIG_PREEMPT_NONE is not set -CONFIG_PREEMPT_VOLUNTARY=y +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set # @@ -248,7 +247,7 @@ CONFIG_ZERO_PAGE_OFFSET=0x00001000 CONFIG_BOOT_LINK_OFFSET=0x009e0000 # CONFIG_UBC_WAKEUP is not set CONFIG_CMDLINE_BOOL=y -CONFIG_CMDLINE="console=ttySC1,38400N81 root=/dev/nfs ip=:::::eth1:autoconf rw" +CONFIG_CMDLINE="console=ttySC1,38400N81 root=/dev/nfs ip=:::::eth1:autoconf" # # Bus options @@ -335,7 +334,6 @@ CONFIG_INET_XFRM_TUNNEL=y CONFIG_INET_TUNNEL=y CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=y CONFIG_INET_DIAG=m CONFIG_INET_TCP_DIAG=m # CONFIG_TCP_CONG_ADVANCED is not set @@ -357,10 +355,9 @@ CONFIG_INET6_XFRM_TUNNEL=y CONFIG_INET6_TUNNEL=y CONFIG_INET6_XFRM_MODE_TRANSPORT=y CONFIG_INET6_XFRM_MODE_TUNNEL=y -CONFIG_INET6_XFRM_MODE_BEET=y # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set -CONFIG_IPV6_SIT=m CONFIG_IPV6_TUNNEL=y +# CONFIG_IPV6_SUBTREES is not set # CONFIG_IPV6_MULTIPLE_TABLES is not set # CONFIG_NETWORK_SECMARK is not set CONFIG_NETFILTER=y @@ -716,12 +713,6 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set CONFIG_ATA_OVER_ETH=m -# -# Misc devices -# -# CONFIG_SGI_IOC4 is not set -# CONFIG_TIFM_CORE is not set - # # ATA/ATAPI/MFM/RLL support # @@ -787,9 +778,9 @@ CONFIG_CHR_DEV_SG=m # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_STEX is not set # CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set # CONFIG_SCSI_QLOGIC_1280 is not set # CONFIG_SCSI_QLA_FC is not set -# CONFIG_SCSI_QLA_ISCSI is not set # CONFIG_SCSI_LPFC is not set # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set @@ -1104,6 +1095,7 @@ CONFIG_HW_RANDOM=y # TPM devices # # CONFIG_TCG_TPM is not set +# CONFIG_TELCLOCK is not set # # I2C support @@ -1131,10 +1123,15 @@ CONFIG_HWMON=y # CONFIG_SENSORS_VT1211 is not set # CONFIG_HWMON_DEBUG_CHIP is not set +# +# Misc devices +# + # # Multimedia devices # # CONFIG_VIDEO_DEV is not set +CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices @@ -1180,9 +1177,9 @@ CONFIG_USB_DEVICEFS=y # USB Host Controller Drivers # CONFIG_USB_EHCI_HCD=y -CONFIG_USB_EHCI_SPLIT_ISO=y -CONFIG_USB_EHCI_ROOT_HUB_TT=y -CONFIG_USB_EHCI_TT_NEWSCHED=y +# CONFIG_USB_EHCI_SPLIT_ISO is not set +# CONFIG_USB_EHCI_ROOT_HUB_TT is not set +# CONFIG_USB_EHCI_TT_NEWSCHED is not set # CONFIG_USB_ISP116X_HCD is not set CONFIG_USB_OHCI_HCD=y # CONFIG_USB_OHCI_BIG_ENDIAN is not set @@ -1238,6 +1235,7 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_ATI_REMOTE2 is not set # CONFIG_USB_KEYSPAN_REMOTE is not set # CONFIG_USB_APPLETOUCH is not set +# CONFIG_USB_TRANCEVIBRATOR is not set # # USB Imaging devices @@ -1248,20 +1246,11 @@ CONFIG_USB_STORAGE=y # # USB Network Adapters # -CONFIG_USB_CATC=m -CONFIG_USB_KAWETH=m -CONFIG_USB_PEGASUS=m -CONFIG_USB_RTL8150=m -CONFIG_USB_USBNET=m -CONFIG_USB_NET_AX8817X=m -CONFIG_USB_NET_CDCETHER=m -# CONFIG_USB_NET_GL620A is not set -CONFIG_USB_NET_NET1080=m -CONFIG_USB_NET_PLUSB=m -# CONFIG_USB_NET_MCS7830 is not set -# CONFIG_USB_NET_RNDIS_HOST is not set -# CONFIG_USB_NET_CDC_SUBSET is not set -CONFIG_USB_NET_ZAURUS=m +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set CONFIG_USB_MON=y # @@ -1296,7 +1285,6 @@ CONFIG_USB_SERIAL_ARK3116=m # CONFIG_USB_SERIAL_KLSI is not set # CONFIG_USB_SERIAL_KOBIL_SCT is not set # CONFIG_USB_SERIAL_MCT_U232 is not set -# CONFIG_USB_SERIAL_MOS7720 is not set # CONFIG_USB_SERIAL_MOS7840 is not set # CONFIG_USB_SERIAL_NAVMAN is not set CONFIG_USB_SERIAL_PL2303=m @@ -1328,7 +1316,6 @@ CONFIG_USB_SERIAL_PL2303=m # CONFIG_USB_APPLEDISPLAY is not set # CONFIG_USB_SISUSBVGA is not set # CONFIG_USB_LD is not set -# CONFIG_USB_TRANCEVIBRATOR is not set # CONFIG_USB_TEST is not set # @@ -1370,26 +1357,7 @@ CONFIG_USB_SERIAL_PL2303=m # # Real Time Clock # -CONFIG_RTC_LIB=m -CONFIG_RTC_CLASS=m - -# -# RTC interfaces -# -CONFIG_RTC_INTF_SYSFS=m -CONFIG_RTC_INTF_PROC=m -CONFIG_RTC_INTF_DEV=m -# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set - -# -# RTC drivers -# -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_DS1742 is not set -# CONFIG_RTC_DRV_M48T86 is not set -CONFIG_RTC_DRV_SH=m -# CONFIG_RTC_DRV_TEST is not set -# CONFIG_RTC_DRV_V3020 is not set +# CONFIG_RTC_CLASS is not set # # DMA Engine support @@ -1412,12 +1380,8 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y # CONFIG_EXT3_FS_XATTR is not set -CONFIG_EXT4DEV_FS=m -# CONFIG_EXT4DEV_FS_XATTR is not set CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set -CONFIG_JBD2=m -# CONFIG_JBD2_DEBUG is not set CONFIG_REISERFS_FS=m # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set @@ -1429,10 +1393,9 @@ CONFIG_XFS_FS=m # CONFIG_XFS_SECURITY is not set # CONFIG_XFS_POSIX_ACL is not set # CONFIG_XFS_RT is not set -# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set -CONFIG_ROMFS_FS=y +# CONFIG_ROMFS_FS is not set CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set @@ -1517,12 +1480,7 @@ CONFIG_SUNRPC=y # CONFIG_RPCSEC_GSS_SPKM3 is not set CONFIG_SMB_FS=m # CONFIG_SMB_NLS_DEFAULT is not set -CONFIG_CIFS=m -# CONFIG_CIFS_STATS is not set -CONFIG_CIFS_WEAK_PW_HASH=y -# CONFIG_CIFS_XATTR is not set -# CONFIG_CIFS_DEBUG2 is not set -# CONFIG_CIFS_EXPERIMENTAL is not set +# CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set @@ -1625,10 +1583,9 @@ CONFIG_LOG_BUF_SHIFT=16 # CONFIG_DEBUG_LIST is not set # CONFIG_FRAME_POINTER is not set # CONFIG_FORCED_INLINING is not set -# CONFIG_HEADERS_CHECK is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_SH_STANDARD_BIOS is not set -# CONFIG_EARLY_SCIF_CONSOLE is not set +CONFIG_EARLY_SCIF_CONSOLE=y # CONFIG_EARLY_PRINTK is not set # CONFIG_DEBUG_STACKOVERFLOW is not set # CONFIG_DEBUG_STACK_USAGE is not set @@ -1648,7 +1605,7 @@ CONFIG_CRYPTO=y CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_BLKCIPHER=y CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER=m CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_NULL=m CONFIG_CRYPTO_MD4=m @@ -1658,7 +1615,7 @@ CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m CONFIG_CRYPTO_WP512=m CONFIG_CRYPTO_TGR192=m -CONFIG_CRYPTO_ECB=y +CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_CBC=y CONFIG_CRYPTO_DES=y CONFIG_CRYPTO_BLOWFISH=m diff --git a/trunk/arch/sh/drivers/dma/dma-g2.c b/trunk/arch/sh/drivers/dma/dma-g2.c index 0caf11bb7e27..9cb070924180 100644 --- a/trunk/arch/sh/drivers/dma/dma-g2.c +++ b/trunk/arch/sh/drivers/dma/dma-g2.c @@ -51,7 +51,7 @@ static volatile struct g2_dma_info *g2_dma = (volatile struct g2_dma_info *)0xa0 ((g2_dma->channel[i].size - \ g2_dma->status[i].size) & 0x0fffffff) -static irqreturn_t g2_dma_interrupt(int irq, void *dev_id) +static irqreturn_t g2_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs) { int i; diff --git a/trunk/arch/sh/drivers/dma/dma-pvr2.c b/trunk/arch/sh/drivers/dma/dma-pvr2.c index 838fad566eaf..c1b6bc23c107 100644 --- a/trunk/arch/sh/drivers/dma/dma-pvr2.c +++ b/trunk/arch/sh/drivers/dma/dma-pvr2.c @@ -21,7 +21,7 @@ static unsigned int xfer_complete; static int count; -static irqreturn_t pvr2_dma_interrupt(int irq, void *dev_id) +static irqreturn_t pvr2_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs) { if (get_dma_residue(PVR2_CASCADE_CHAN)) { printk(KERN_WARNING "DMA: SH DMAC did not complete transfer " diff --git a/trunk/arch/sh/drivers/dma/dma-sh.c b/trunk/arch/sh/drivers/dma/dma-sh.c index 660786013350..cbbe8bce3d67 100644 --- a/trunk/arch/sh/drivers/dma/dma-sh.c +++ b/trunk/arch/sh/drivers/dma/dma-sh.c @@ -19,34 +19,23 @@ #include #include "dma-sh.h" +static inline unsigned int get_dmte_irq(unsigned int chan) +{ + unsigned int irq = 0; - -#ifdef CONFIG_CPU_SH4 -static struct ipr_data dmae_ipr_map[] = { - { DMAE_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY }, -}; -#endif -static struct ipr_data dmte_ipr_map[] = { /* * Normally we could just do DMTE0_IRQ + chan outright, though in the * case of the 7751R, the DMTE IRQs for channels > 4 start right above * the SCIF */ - { DMTE0_IRQ + 0, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY }, - { DMTE0_IRQ + 1, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY }, - { DMTE0_IRQ + 2, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY }, - { DMTE0_IRQ + 3, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY }, - { DMTE4_IRQ + 0, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY }, - { DMTE4_IRQ + 1, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY }, - { DMTE4_IRQ + 2, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY }, - { DMTE4_IRQ + 3, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY }, -}; + if (chan < 4) { + irq = DMTE0_IRQ + chan; + } else { +#ifdef DMTE4_IRQ + irq = DMTE4_IRQ + chan - 4; +#endif + } -static inline unsigned int get_dmte_irq(unsigned int chan) -{ - unsigned int irq = 0; - if (chan < ARRAY_SIZE(dmte_ipr_map)) - irq = dmte_ipr_map[chan].irq; return irq; } @@ -71,9 +60,9 @@ static inline unsigned int calc_xmit_shift(struct dma_channel *chan) * Besides that it needs to waken any waiting process, which should handle * setting up the next transfer. */ -static irqreturn_t dma_tei(int irq, void *dev_id) +static irqreturn_t dma_tei(int irq, void *dev_id, struct pt_regs *regs) { - struct dma_channel *chan = dev_id; + struct dma_channel *chan = (struct dma_channel *)dev_id; u32 chcr; chcr = ctrl_inl(CHCR[chan->chan]); @@ -239,7 +228,7 @@ static inline int dmaor_reset(void) } #if defined(CONFIG_CPU_SH4) -static irqreturn_t dma_err(int irq, void *dummy) +static irqreturn_t dma_err(int irq, void *dev_id, struct pt_regs *regs) { dmaor_reset(); disable_irq(irq); @@ -269,16 +258,17 @@ static int __init sh_dmac_init(void) int i; #ifdef CONFIG_CPU_SH4 - make_ipr_irq(dmae_ipr_map, ARRAY_SIZE(dmae_ipr_map)); + make_ipr_irq(DMAE_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY); i = request_irq(DMAE_IRQ, dma_err, IRQF_DISABLED, "DMAC Address Error", 0); if (unlikely(i < 0)) return i; #endif - i = info->nr_channels; - if (i > ARRAY_SIZE(dmte_ipr_map)) - i = ARRAY_SIZE(dmte_ipr_map); - make_ipr_irq(dmte_ipr_map, i); + for (i = 0; i < info->nr_channels; i++) { + int irq = get_dmte_irq(i); + + make_ipr_irq(irq, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY); + } /* * Initialize DMAOR, and clean up any error flags that may have diff --git a/trunk/arch/sh/drivers/pci/ops-r7780rp.c b/trunk/arch/sh/drivers/pci/ops-r7780rp.c index eeea1577e112..6e3ba9c65b40 100644 --- a/trunk/arch/sh/drivers/pci/ops-r7780rp.c +++ b/trunk/arch/sh/drivers/pci/ops-r7780rp.c @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include "pci-sh4.h" diff --git a/trunk/arch/sh/drivers/pci/ops-rts7751r2d.c b/trunk/arch/sh/drivers/pci/ops-rts7751r2d.c index 4a518d948049..b68824c8b81e 100644 --- a/trunk/arch/sh/drivers/pci/ops-rts7751r2d.c +++ b/trunk/arch/sh/drivers/pci/ops-rts7751r2d.c @@ -10,24 +10,28 @@ * * PCI initialization for the Renesas SH7751R RTS7751R2D board */ + #include #include #include +#include #include -#include -#include +#include +#include +#include #include "pci-sh4.h" -static u8 rts7751r2d_irq_tab[] __initdata = { - IRQ_PCISLOT1, - IRQ_PCISLOT2, - IRQ_PCMCIA, - IRQ_PCIETH, -}; - int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) { - return rts7751r2d_irq_tab[slot]; + switch (slot) { + case 0: return IRQ_PCISLOT1; /* PCI Extend slot #1 */ + case 1: return IRQ_PCISLOT2; /* PCI Extend slot #2 */ + case 2: return IRQ_PCMCIA; /* PCI Cardbus Bridge */ + case 3: return IRQ_PCIETH; /* Realtek Ethernet controller */ + default: + printk("PCI: Bad IRQ mapping request for slot %d\n", slot); + return -1; + } } static struct resource sh7751_io_resource = { diff --git a/trunk/arch/sh/drivers/pci/pci-sh7751.c b/trunk/arch/sh/drivers/pci/pci-sh7751.c index 85e1ee2e2e7b..dbe837884983 100644 --- a/trunk/arch/sh/drivers/pci/pci-sh7751.c +++ b/trunk/arch/sh/drivers/pci/pci-sh7751.c @@ -155,7 +155,7 @@ int __init sh7751_pcic_init(struct sh4_pci_address_map *map) */ pr_debug("PCI: Mapping IO address 0x%x - 0x%x to base 0x%x\n", PCIBIOS_MIN_IO, (64 << 10), - SH7751_PCI_IO_BASE + PCIBIOS_MIN_IO); + SH4_PCI_IO_BASE + PCIBIOS_MIN_IO); /* * XXX: For now, leave this board-specific. In the event we have other @@ -163,7 +163,7 @@ int __init sh7751_pcic_init(struct sh4_pci_address_map *map) */ #ifdef CONFIG_SH_BIGSUR bigsur_port_map(PCIBIOS_MIN_IO, (64 << 10), - SH7751_PCI_IO_BASE + PCIBIOS_MIN_IO, 0); + SH4_PCI_IO_BASE + PCIBIOS_MIN_IO, 0); #endif /* Make sure the MSB's of IO window are set to access PCI space diff --git a/trunk/arch/sh/drivers/pci/pci-st40.c b/trunk/arch/sh/drivers/pci/pci-st40.c index efecb3d5995c..4ab5ea6b35fb 100644 --- a/trunk/arch/sh/drivers/pci/pci-st40.c +++ b/trunk/arch/sh/drivers/pci/pci-st40.c @@ -161,7 +161,7 @@ static char * pci_commands[16]={ "Memory Write-and-Invalidate" }; -static irqreturn_t st40_pci_irq(int irq, void *dev_instance) +static irqreturn_t st40_pci_irq(int irq, void *dev_instance, struct pt_regs *regs) { unsigned pci_int, pci_air, pci_cir, pci_aint; static int count=0; diff --git a/trunk/arch/sh/kernel/cpu/irq/intc2.c b/trunk/arch/sh/kernel/cpu/irq/intc2.c index 74ca576a7ce5..e30e4b7aa70e 100644 --- a/trunk/arch/sh/kernel/cpu/irq/intc2.c +++ b/trunk/arch/sh/kernel/cpu/irq/intc2.c @@ -10,31 +10,93 @@ * These are the "new Hitachi style" interrupts, as present on the * Hitachi 7751, the STM ST40 STB1, SH7760, and SH7780. */ + #include +#include #include -#include #include +#include +#include + +struct intc2_data { + unsigned char msk_offset; + unsigned char msk_shift; + + int (*clear_irq) (int); +}; + +static struct intc2_data intc2_data[NR_INTC2_IRQS]; + +static void enable_intc2_irq(unsigned int irq); +static void disable_intc2_irq(unsigned int irq); + +/* shutdown is same as "disable" */ +#define shutdown_intc2_irq disable_intc2_irq + +static void mask_and_ack_intc2(unsigned int); +static void end_intc2_irq(unsigned int irq); + +static unsigned int startup_intc2_irq(unsigned int irq) +{ + enable_intc2_irq(irq); + return 0; /* never anything pending */ +} + +static struct hw_interrupt_type intc2_irq_type = { + .typename = "INTC2-IRQ", + .startup = startup_intc2_irq, + .shutdown = shutdown_intc2_irq, + .enable = enable_intc2_irq, + .disable = disable_intc2_irq, + .ack = mask_and_ack_intc2, + .end = end_intc2_irq +}; static void disable_intc2_irq(unsigned int irq) { - struct intc2_data *p = get_irq_chip_data(irq); - ctrl_outl(1 << p->msk_shift, - INTC2_BASE + INTC2_INTMSK_OFFSET + p->msk_offset); + int irq_offset = irq - INTC2_FIRST_IRQ; + int msk_shift, msk_offset; + + /* Sanity check */ + if (unlikely(irq_offset < 0 || irq_offset >= NR_INTC2_IRQS)) + return; + + msk_shift = intc2_data[irq_offset].msk_shift; + msk_offset = intc2_data[irq_offset].msk_offset; + + ctrl_outl(1 << msk_shift, + INTC2_BASE + INTC2_INTMSK_OFFSET + msk_offset); } static void enable_intc2_irq(unsigned int irq) { - struct intc2_data *p = get_irq_chip_data(irq); - ctrl_outl(1 << p->msk_shift, - INTC2_BASE + INTC2_INTMSKCLR_OFFSET + p->msk_offset); + int irq_offset = irq - INTC2_FIRST_IRQ; + int msk_shift, msk_offset; + + /* Sanity check */ + if (unlikely(irq_offset < 0 || irq_offset >= NR_INTC2_IRQS)) + return; + + msk_shift = intc2_data[irq_offset].msk_shift; + msk_offset = intc2_data[irq_offset].msk_offset; + + ctrl_outl(1 << msk_shift, + INTC2_BASE + INTC2_INTMSKCLR_OFFSET + msk_offset); } -static struct irq_chip intc2_irq_chip = { - .name = "INTC2", - .mask = disable_intc2_irq, - .unmask = enable_intc2_irq, - .mask_ack = disable_intc2_irq, -}; +static void mask_and_ack_intc2(unsigned int irq) +{ + disable_intc2_irq(irq); +} + +static void end_intc2_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + enable_intc2_irq(irq); + + if (unlikely(intc2_data[irq - INTC2_FIRST_IRQ].clear_irq)) + intc2_data[irq - INTC2_FIRST_IRQ].clear_irq(irq); +} /* * Setup an INTC2 style interrupt. @@ -44,36 +106,179 @@ static struct irq_chip intc2_irq_chip = { * PIO1 which is INTPRI00[19,16] and INTMSK00[13] * would be: ^ ^ ^ ^ * | | | | - * { 84, 0, 16, 0, 13 }, - * - * in the intc2_data table. + * make_intc2_irq(84, 0, 16, 0, 13); */ -void make_intc2_irq(struct intc2_data *table, unsigned int nr_irqs) +void make_intc2_irq(unsigned int irq, + unsigned int ipr_offset, unsigned int ipr_shift, + unsigned int msk_offset, unsigned int msk_shift, + unsigned int priority) { - int i; + int irq_offset = irq - INTC2_FIRST_IRQ; + unsigned int flags; + unsigned long ipr; + + if (unlikely(irq_offset < 0 || irq_offset >= NR_INTC2_IRQS)) + return; + + disable_irq_nosync(irq); + + /* Fill the data we need */ + intc2_data[irq_offset].msk_offset = msk_offset; + intc2_data[irq_offset].msk_shift = msk_shift; + intc2_data[irq_offset].clear_irq = NULL; + + /* Set the priority level */ + local_irq_save(flags); + + ipr = ctrl_inl(INTC2_BASE + INTC2_INTPRI_OFFSET + ipr_offset); + ipr &= ~(0xf << ipr_shift); + ipr |= priority << ipr_shift; + ctrl_outl(ipr, INTC2_BASE + INTC2_INTPRI_OFFSET + ipr_offset); + + local_irq_restore(flags); - for (i = 0; i < nr_irqs; i++) { - unsigned long ipr, flags; - struct intc2_data *p = table + i; + irq_desc[irq].chip = &intc2_irq_type; - disable_irq_nosync(p->irq); + disable_intc2_irq(irq); +} - /* Set the priority level */ - local_irq_save(flags); +static struct intc2_init { + unsigned short irq; + unsigned char ipr_offset, ipr_shift; + unsigned char msk_offset, msk_shift; + unsigned char priority; +} intc2_init_data[] __initdata = { +#if defined(CONFIG_CPU_SUBTYPE_ST40) + {64, 0, 0, 0, 0, 13}, /* PCI serr */ + {65, 0, 4, 0, 1, 13}, /* PCI err */ + {66, 0, 4, 0, 2, 13}, /* PCI ad */ + {67, 0, 4, 0, 3, 13}, /* PCI pwd down */ + {72, 0, 8, 0, 5, 13}, /* DMAC INT0 */ + {73, 0, 8, 0, 6, 13}, /* DMAC INT1 */ + {74, 0, 8, 0, 7, 13}, /* DMAC INT2 */ + {75, 0, 8, 0, 8, 13}, /* DMAC INT3 */ + {76, 0, 8, 0, 9, 13}, /* DMAC INT4 */ + {78, 0, 8, 0, 11, 13}, /* DMAC ERR */ + {80, 0, 12, 0, 12, 13}, /* PIO0 */ + {84, 0, 16, 0, 13, 13}, /* PIO1 */ + {88, 0, 20, 0, 14, 13}, /* PIO2 */ + {112, 4, 0, 4, 0, 13}, /* Mailbox */ + #ifdef CONFIG_CPU_SUBTYPE_ST40GX1 + {116, 4, 4, 4, 4, 13}, /* SSC0 */ + {120, 4, 8, 4, 8, 13}, /* IR Blaster */ + {124, 4, 12, 4, 12, 13}, /* USB host */ + {128, 4, 16, 4, 16, 13}, /* Video processor BLITTER */ + {132, 4, 20, 4, 20, 13}, /* UART0 */ + {134, 4, 20, 4, 22, 13}, /* UART2 */ + {136, 4, 24, 4, 24, 13}, /* IO_PIO0 */ + {140, 4, 28, 4, 28, 13}, /* EMPI */ + {144, 8, 0, 8, 0, 13}, /* MAFE */ + {148, 8, 4, 8, 4, 13}, /* PWM */ + {152, 8, 8, 8, 8, 13}, /* SSC1 */ + {156, 8, 12, 8, 12, 13}, /* IO_PIO1 */ + {160, 8, 16, 8, 16, 13}, /* USB target */ + {164, 8, 20, 8, 20, 13}, /* UART1 */ + {168, 8, 24, 8, 24, 13}, /* Teletext */ + {172, 8, 28, 8, 28, 13}, /* VideoSync VTG */ + {173, 8, 28, 8, 29, 13}, /* VideoSync DVP0 */ + {174, 8, 28, 8, 30, 13}, /* VideoSync DVP1 */ +#endif +#elif defined(CONFIG_CPU_SUBTYPE_SH7760) +/* + * SH7760 INTC2-Style interrupts, vectors IRQ48-111 INTEVT 0x800-0xFE0 + */ + /* INTPRIO0 | INTMSK0 */ + {48, 0, 28, 0, 31, 3}, /* IRQ 4 */ + {49, 0, 24, 0, 30, 3}, /* IRQ 3 */ + {50, 0, 20, 0, 29, 3}, /* IRQ 2 */ + {51, 0, 16, 0, 28, 3}, /* IRQ 1 */ + /* 52-55 (INTEVT 0x880-0x8E0) unused/reserved */ + /* INTPRIO4 | INTMSK0 */ + {56, 4, 28, 0, 25, 3}, /* HCAN2_CHAN0 */ + {57, 4, 24, 0, 24, 3}, /* HCAN2_CHAN1 */ + {58, 4, 20, 0, 23, 3}, /* I2S_CHAN0 */ + {59, 4, 16, 0, 22, 3}, /* I2S_CHAN1 */ + {60, 4, 12, 0, 21, 3}, /* AC97_CHAN0 */ + {61, 4, 8, 0, 20, 3}, /* AC97_CHAN1 */ + {62, 4, 4, 0, 19, 3}, /* I2C_CHAN0 */ + {63, 4, 0, 0, 18, 3}, /* I2C_CHAN1 */ + /* INTPRIO8 | INTMSK0 */ + {52, 8, 16, 0, 11, 3}, /* SCIF0_ERI_IRQ */ + {53, 8, 16, 0, 10, 3}, /* SCIF0_RXI_IRQ */ + {54, 8, 16, 0, 9, 3}, /* SCIF0_BRI_IRQ */ + {55, 8, 16, 0, 8, 3}, /* SCIF0_TXI_IRQ */ + {64, 8, 28, 0, 17, 3}, /* USBHI_IRQ */ + {65, 8, 24, 0, 16, 3}, /* LCDC */ + /* 66, 67 unused */ + {68, 8, 20, 0, 14, 13}, /* DMABRGI0_IRQ */ + {69, 8, 20, 0, 13, 13}, /* DMABRGI1_IRQ */ + {70, 8, 20, 0, 12, 13}, /* DMABRGI2_IRQ */ + /* 71 unused */ + {72, 8, 12, 0, 7, 3}, /* SCIF1_ERI_IRQ */ + {73, 8, 12, 0, 6, 3}, /* SCIF1_RXI_IRQ */ + {74, 8, 12, 0, 5, 3}, /* SCIF1_BRI_IRQ */ + {75, 8, 12, 0, 4, 3}, /* SCIF1_TXI_IRQ */ + {76, 8, 8, 0, 3, 3}, /* SCIF2_ERI_IRQ */ + {77, 8, 8, 0, 2, 3}, /* SCIF2_RXI_IRQ */ + {78, 8, 8, 0, 1, 3}, /* SCIF2_BRI_IRQ */ + {79, 8, 8, 0, 0, 3}, /* SCIF2_TXI_IRQ */ + /* | INTMSK4 */ + {80, 8, 4, 4, 23, 3}, /* SIM_ERI */ + {81, 8, 4, 4, 22, 3}, /* SIM_RXI */ + {82, 8, 4, 4, 21, 3}, /* SIM_TXI */ + {83, 8, 4, 4, 20, 3}, /* SIM_TEI */ + {84, 8, 0, 4, 19, 3}, /* HSPII */ + /* INTPRIOC | INTMSK4 */ + /* 85-87 unused/reserved */ + {88, 12, 20, 4, 18, 3}, /* MMCI0 */ + {89, 12, 20, 4, 17, 3}, /* MMCI1 */ + {90, 12, 20, 4, 16, 3}, /* MMCI2 */ + {91, 12, 20, 4, 15, 3}, /* MMCI3 */ + {92, 12, 12, 4, 6, 3}, /* MFI (unsure, bug? in my 7760 manual*/ + /* 93-107 reserved/undocumented */ + {108,12, 4, 4, 1, 3}, /* ADC */ + {109,12, 0, 4, 0, 3}, /* CMTI */ + /* 110-111 reserved/unused */ +#elif defined(CONFIG_CPU_SUBTYPE_SH7780) + { TIMER_IRQ, 0, 24, 0, INTC_TMU0_MSK, 2}, + { 21, 1, 0, 0, INTC_RTC_MSK, TIMER_PRIORITY }, + { 22, 1, 1, 0, INTC_RTC_MSK, TIMER_PRIORITY }, + { 23, 1, 2, 0, INTC_RTC_MSK, TIMER_PRIORITY }, + { SCIF0_ERI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY }, + { SCIF0_RXI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY }, + { SCIF0_BRI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY }, + { SCIF0_TXI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY }, - ipr = ctrl_inl(INTC2_BASE + INTC2_INTPRI_OFFSET + - p->ipr_offset); - ipr &= ~(0xf << p->ipr_shift); - ipr |= p->priority << p->ipr_shift; - ctrl_outl(ipr, INTC2_BASE + INTC2_INTPRI_OFFSET + - p->ipr_offset); + { SCIF1_ERI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY }, + { SCIF1_RXI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY }, + { SCIF1_BRI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY }, + { SCIF1_TXI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY }, - local_irq_restore(flags); + { PCIC0_IRQ, 0x10, 8, 0, INTC_PCIC0_MSK, PCIC0_PRIORITY }, + { PCIC1_IRQ, 0x10, 0, 0, INTC_PCIC1_MSK, PCIC1_PRIORITY }, + { PCIC2_IRQ, 0x14, 24, 0, INTC_PCIC2_MSK, PCIC2_PRIORITY }, + { PCIC3_IRQ, 0x14, 16, 0, INTC_PCIC3_MSK, PCIC3_PRIORITY }, + { PCIC4_IRQ, 0x14, 8, 0, INTC_PCIC4_MSK, PCIC4_PRIORITY }, +#endif +}; - set_irq_chip_and_handler_name(p->irq, &intc2_irq_chip, - handle_level_irq, "level"); - set_irq_chip_data(p->irq, p); +void __init init_IRQ_intc2(void) +{ + int i; - enable_intc2_irq(p->irq); + for (i = 0; i < ARRAY_SIZE(intc2_init_data); i++) { + struct intc2_init *p = intc2_init_data + i; + make_intc2_irq(p->irq, p->ipr_offset, p->ipr_shift, + p-> msk_offset, p->msk_shift, p->priority); } } + +/* Adds a termination callback to the interrupt */ +void intc2_add_clear_irq(int irq, int (*fn)(int)) +{ + if (unlikely(irq < INTC2_FIRST_IRQ)) + return; + + intc2_data[irq - INTC2_FIRST_IRQ].clear_irq = fn; +} + diff --git a/trunk/arch/sh/kernel/cpu/irq/ipr.c b/trunk/arch/sh/kernel/cpu/irq/ipr.c index a0089563cbfc..f785822cd5de 100644 --- a/trunk/arch/sh/kernel/cpu/irq/ipr.c +++ b/trunk/arch/sh/kernel/cpu/irq/ipr.c @@ -1,10 +1,11 @@ /* - * Interrupt handling for IPR-based IRQ. + * arch/sh/kernel/cpu/irq/ipr.c * * Copyright (C) 1999 Niibe Yutaka & Takeshi Yaegashi * Copyright (C) 2000 Kazumoto Kojima - * Copyright (C) 2003 Takashi Kusuda - * Copyright (C) 2006 Paul Mundt + * Copyright (C) 2003 Takashi Kusuda + * + * Interrupt handling for IPR-based IRQ. * * Supported system: * On-chip supporting modules (TMU, RTC, etc.). @@ -12,92 +13,151 @@ * Hitachi SolutionEngine external I/O: * MS7709SE01, MS7709ASE01, and MS7750SE01 * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. */ + #include #include #include + #include #include #include +struct ipr_data { + unsigned int addr; /* Address of Interrupt Priority Register */ + int shift; /* Shifts of the 16-bit data */ + int priority; /* The priority */ +}; +static struct ipr_data ipr_data[NR_IRQS]; + +static void enable_ipr_irq(unsigned int irq); +static void disable_ipr_irq(unsigned int irq); + +/* shutdown is same as "disable" */ +#define shutdown_ipr_irq disable_ipr_irq + +static void mask_and_ack_ipr(unsigned int); +static void end_ipr_irq(unsigned int irq); + +static unsigned int startup_ipr_irq(unsigned int irq) +{ + enable_ipr_irq(irq); + return 0; /* never anything pending */ +} + +static struct hw_interrupt_type ipr_irq_type = { + .typename = "IPR-IRQ", + .startup = startup_ipr_irq, + .shutdown = shutdown_ipr_irq, + .enable = enable_ipr_irq, + .disable = disable_ipr_irq, + .ack = mask_and_ack_ipr, + .end = end_ipr_irq +}; static void disable_ipr_irq(unsigned int irq) { - struct ipr_data *p = get_irq_chip_data(irq); - int shift = p->shift*4; + unsigned long val; + unsigned int addr = ipr_data[irq].addr; + unsigned short mask = 0xffff ^ (0x0f << ipr_data[irq].shift); + /* Set the priority in IPR to 0 */ - ctrl_outw(ctrl_inw(p->addr) & (0xffff ^ (0xf << shift)), p->addr); + val = ctrl_inw(addr); + val &= mask; + ctrl_outw(val, addr); } static void enable_ipr_irq(unsigned int irq) { - struct ipr_data *p = get_irq_chip_data(irq); - int shift = p->shift*4; + unsigned long val; + unsigned int addr = ipr_data[irq].addr; + int priority = ipr_data[irq].priority; + unsigned short value = (priority << ipr_data[irq].shift); + /* Set priority in IPR back to original value */ - ctrl_outw(ctrl_inw(p->addr) | (p->priority << shift), p->addr); + val = ctrl_inw(addr); + val |= value; + ctrl_outw(val, addr); } -static struct irq_chip ipr_irq_chip = { - .name = "IPR", - .mask = disable_ipr_irq, - .unmask = enable_ipr_irq, - .mask_ack = disable_ipr_irq, -}; +static void mask_and_ack_ipr(unsigned int irq) +{ + disable_ipr_irq(irq); -void make_ipr_irq(struct ipr_data *table, unsigned int nr_irqs) +#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \ + defined(CONFIG_CPU_SUBTYPE_SH7706) || \ + defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705) + /* This is needed when we use edge triggered setting */ + /* XXX: Is it really needed? */ + if (IRQ0_IRQ <= irq && irq <= IRQ5_IRQ) { + /* Clear external interrupt request */ + int a = ctrl_inb(INTC_IRR0); + a &= ~(1 << (irq - IRQ0_IRQ)); + ctrl_outb(a, INTC_IRR0); + } +#endif +} + +static void end_ipr_irq(unsigned int irq) { - int i; - - for (i = 0; i < nr_irqs; i++) { - unsigned int irq = table[i].irq; - disable_irq_nosync(irq); - set_irq_chip_and_handler_name(irq, &ipr_irq_chip, - handle_level_irq, "level"); - set_irq_chip_data(irq, &table[i]); + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) enable_ipr_irq(irq); - } } -EXPORT_SYMBOL(make_ipr_irq); -static struct ipr_data sys_ipr_map[] = { +void make_ipr_irq(unsigned int irq, unsigned int addr, int pos, int priority) +{ + disable_irq_nosync(irq); + ipr_data[irq].addr = addr; + ipr_data[irq].shift = pos*4; /* POSition (0-3) x 4 means shift */ + ipr_data[irq].priority = priority; + + irq_desc[irq].chip = &ipr_irq_type; + disable_ipr_irq(irq); +} + +void __init init_IRQ(void) +{ #ifndef CONFIG_CPU_SUBTYPE_SH7780 - { TIMER_IRQ, TIMER_IPR_ADDR, TIMER_IPR_POS, TIMER_PRIORITY }, - { TIMER1_IRQ, TIMER1_IPR_ADDR, TIMER1_IPR_POS, TIMER1_PRIORITY }, + make_ipr_irq(TIMER_IRQ, TIMER_IPR_ADDR, TIMER_IPR_POS, TIMER_PRIORITY); + make_ipr_irq(TIMER1_IRQ, TIMER1_IPR_ADDR, TIMER1_IPR_POS, TIMER1_PRIORITY); #ifdef RTC_IRQ - { RTC_IRQ, RTC_IPR_ADDR, RTC_IPR_POS, RTC_PRIORITY }, + make_ipr_irq(RTC_IRQ, RTC_IPR_ADDR, RTC_IPR_POS, RTC_PRIORITY); #endif + #ifdef SCI_ERI_IRQ - { SCI_ERI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY }, - { SCI_RXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY }, - { SCI_TXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY }, + make_ipr_irq(SCI_ERI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY); + make_ipr_irq(SCI_RXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY); + make_ipr_irq(SCI_TXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY); #endif + #ifdef SCIF1_ERI_IRQ - { SCIF1_ERI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY }, - { SCIF1_RXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY }, - { SCIF1_BRI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY }, - { SCIF1_TXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY }, + make_ipr_irq(SCIF1_ERI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY); + make_ipr_irq(SCIF1_RXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY); + make_ipr_irq(SCIF1_BRI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY); + make_ipr_irq(SCIF1_TXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY); #endif + #if defined(CONFIG_CPU_SUBTYPE_SH7300) - { SCIF0_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY }, - { DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY }, - { DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY }, - { VIO_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY }, + make_ipr_irq(SCIF0_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY); + make_ipr_irq(DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY); + make_ipr_irq(DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY); + make_ipr_irq(VIO_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY); #endif + #ifdef SCIF_ERI_IRQ - { SCIF_ERI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY }, - { SCIF_RXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY }, - { SCIF_BRI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY }, - { SCIF_TXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY }, + make_ipr_irq(SCIF_ERI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY); + make_ipr_irq(SCIF_RXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY); + make_ipr_irq(SCIF_BRI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY); + make_ipr_irq(SCIF_TXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY); #endif + #ifdef IRDA_ERI_IRQ - { IRDA_ERI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY }, - { IRDA_RXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY }, - { IRDA_BRI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY }, - { IRDA_TXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY }, + make_ipr_irq(IRDA_ERI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY); + make_ipr_irq(IRDA_RXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY); + make_ipr_irq(IRDA_BRI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY); + make_ipr_irq(IRDA_TXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY); #endif + #if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \ defined(CONFIG_CPU_SUBTYPE_SH7706) || \ defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705) @@ -111,19 +171,14 @@ static struct ipr_data sys_ipr_map[] = { * You should set corresponding bits of PFC to "00" * to enable these interrupts. */ - { IRQ0_IRQ, IRQ0_IPR_ADDR, IRQ0_IPR_POS, IRQ0_PRIORITY }, - { IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, IRQ1_PRIORITY }, - { IRQ2_IRQ, IRQ2_IPR_ADDR, IRQ2_IPR_POS, IRQ2_PRIORITY }, - { IRQ3_IRQ, IRQ3_IPR_ADDR, IRQ3_IPR_POS, IRQ3_PRIORITY }, - { IRQ4_IRQ, IRQ4_IPR_ADDR, IRQ4_IPR_POS, IRQ4_PRIORITY }, - { IRQ5_IRQ, IRQ5_IPR_ADDR, IRQ5_IPR_POS, IRQ5_PRIORITY }, + make_ipr_irq(IRQ0_IRQ, IRQ0_IPR_ADDR, IRQ0_IPR_POS, IRQ0_PRIORITY); + make_ipr_irq(IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, IRQ1_PRIORITY); + make_ipr_irq(IRQ2_IRQ, IRQ2_IPR_ADDR, IRQ2_IPR_POS, IRQ2_PRIORITY); + make_ipr_irq(IRQ3_IRQ, IRQ3_IPR_ADDR, IRQ3_IPR_POS, IRQ3_PRIORITY); + make_ipr_irq(IRQ4_IRQ, IRQ4_IPR_ADDR, IRQ4_IPR_POS, IRQ4_PRIORITY); + make_ipr_irq(IRQ5_IRQ, IRQ5_IPR_ADDR, IRQ5_IPR_POS, IRQ5_PRIORITY); #endif #endif -}; - -void __init init_IRQ(void) -{ - make_ipr_irq(sys_ipr_map, ARRAY_SIZE(sys_ipr_map)); #ifdef CONFIG_CPU_HAS_PINT_IRQ init_IRQ_pint(); @@ -145,3 +200,5 @@ int ipr_irq_demux(int irq) return irq; } #endif + +EXPORT_SYMBOL(make_ipr_irq); diff --git a/trunk/arch/sh/kernel/cpu/irq/pint.c b/trunk/arch/sh/kernel/cpu/irq/pint.c index f60007783a21..17f47b373d6e 100644 --- a/trunk/arch/sh/kernel/cpu/irq/pint.c +++ b/trunk/arch/sh/kernel/cpu/irq/pint.c @@ -84,16 +84,12 @@ void make_pint_irq(unsigned int irq) disable_pint_irq(irq); } -static struct ipr_data pint_ipr_map[] = { - { PINT0_IRQ, PINT0_IPR_ADDR, PINT0_IPR_POS, PINT0_PRIORITY }, - { PINT8_IRQ, PINT8_IPR_ADDR, PINT8_IPR_POS, PINT8_PRIORITY }, -}; - void __init init_IRQ_pint(void) { int i; - make_ipr_irq(pint_ipr_map, ARRAY_SIZE(pint_ipr_map)); + make_ipr_irq(PINT0_IRQ, PINT0_IPR_ADDR, PINT0_IPR_POS, PINT0_PRIORITY); + make_ipr_irq(PINT8_IRQ, PINT8_IPR_ADDR, PINT8_IPR_POS, PINT8_PRIORITY); enable_irq(PINT0_IRQ); enable_irq(PINT8_IRQ); diff --git a/trunk/arch/sh/kernel/cpu/sh3/ex.S b/trunk/arch/sh/kernel/cpu/sh3/ex.S index ba3082d640b5..44daf44833f9 100644 --- a/trunk/arch/sh/kernel/cpu/sh3/ex.S +++ b/trunk/arch/sh/kernel/cpu/sh3/ex.S @@ -4,7 +4,7 @@ * The SH-3 exception vector table. * Copyright (C) 1999, 2000, 2002 Niibe Yutaka - * Copyright (C) 2003 - 2006 Paul Mundt + * Copyright (C) 2003 Paul Mundt * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -49,10 +49,198 @@ ENTRY(nmi_slot) #endif ENTRY(user_break_point_trap) .long break_point_trap /* 1E0 */ - - /* - * Pad the remainder of the table out, exceptions residing in far - * away offsets can be manually inserted in to their appropriate - * location via set_exception_table_{evt,vec}(). - */ - .balign 4096,0,4096 +ENTRY(interrupt_table) + ! external hardware + .long do_IRQ ! 0000 /* 200 */ + .long do_IRQ ! 0001 + .long do_IRQ ! 0010 + .long do_IRQ ! 0011 + .long do_IRQ ! 0100 + .long do_IRQ ! 0101 + .long do_IRQ ! 0110 + .long do_IRQ ! 0111 + .long do_IRQ ! 1000 /* 300 */ + .long do_IRQ ! 1001 + .long do_IRQ ! 1010 + .long do_IRQ ! 1011 + .long do_IRQ ! 1100 + .long do_IRQ ! 1101 + .long do_IRQ ! 1110 + .long exception_error + ! Internal hardware + .long do_IRQ ! TMU0 tuni0 /* 400 */ + .long do_IRQ ! TMU1 tuni1 + .long do_IRQ ! TMU2 tuni2 + .long do_IRQ ! ticpi2 + .long do_IRQ ! RTC ati + .long do_IRQ ! pri + .long do_IRQ ! cui + .long do_IRQ ! SCI eri + .long do_IRQ ! rxi /* 500 */ + .long do_IRQ ! txi + .long do_IRQ ! tei + .long do_IRQ ! WDT iti /* 560 */ + .long do_IRQ ! REF rcmi + .long do_IRQ ! rovi + .long do_IRQ + .long do_IRQ /* 5E0 */ +#if defined(CONFIG_CPU_SUBTYPE_SH7707) || \ + defined(CONFIG_CPU_SUBTYPE_SH7709) || \ + defined(CONFIG_CPU_SUBTYPE_SH7706) || \ + defined(CONFIG_CPU_SUBTYPE_SH7300) || \ + defined(CONFIG_CPU_SUBTYPE_SH7705) || \ + defined(CONFIG_CPU_SUBTYPE_SH7710) + .long do_IRQ ! 32 IRQ irq0 /* 600 */ + .long do_IRQ ! 33 irq1 + .long do_IRQ ! 34 irq2 + .long do_IRQ ! 35 irq3 + .long do_IRQ ! 36 irq4 + .long do_IRQ ! 37 irq5 + .long do_IRQ ! 38 + .long do_IRQ ! 39 + .long do_IRQ ! 40 PINT pint0-7 /* 700 */ + .long do_IRQ ! 41 pint8-15 + .long do_IRQ ! 42 + .long do_IRQ ! 43 + .long do_IRQ ! 44 + .long do_IRQ ! 45 + .long do_IRQ ! 46 + .long do_IRQ ! 47 + .long do_IRQ ! 48 DMAC dei0 /* 800 */ + .long do_IRQ ! 49 dei1 + .long do_IRQ ! 50 dei2 + .long do_IRQ ! 51 dei3 + .long do_IRQ ! 52 IrDA eri1 + .long do_IRQ ! 53 rxi1 + .long do_IRQ ! 54 bri1 + .long do_IRQ ! 55 txi1 + .long do_IRQ ! 56 SCIF eri2 + .long do_IRQ ! 57 rxi2 + .long do_IRQ ! 58 bri2 + .long do_IRQ ! 59 txi2 + .long do_IRQ ! 60 ADC adi /* 980 */ +#if defined(CONFIG_CPU_SUBTYPE_SH7705) + .long exception_none ! 61 /* 9A0 */ + .long exception_none ! 62 + .long exception_none ! 63 + .long exception_none ! 64 /* A00 */ + .long do_IRQ ! 65 USB usi0 + .long do_IRQ ! 66 usi1 + .long exception_none ! 67 + .long exception_none ! 68 + .long exception_none ! 69 + .long exception_none ! 70 + .long exception_none ! 71 + .long exception_none ! 72 /* B00 */ + .long exception_none ! 73 + .long exception_none ! 74 + .long exception_none ! 75 + .long exception_none ! 76 + .long exception_none ! 77 + .long exception_none ! 78 + .long exception_none ! 79 + .long do_IRQ ! 80 TPU0 tpi0 /* C00 */ + .long do_IRQ ! 81 TPU1 tpi1 + .long exception_none ! 82 + .long exception_none ! 83 + .long do_IRQ ! 84 TPU2 tpi2 + .long do_IRQ ! 85 TPU3 tpi3 /* CA0 */ +#endif +#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7300) + .long do_IRQ ! 61 LCDC lcdi /* 9A0 */ + .long do_IRQ ! 62 PCC pcc0i + .long do_IRQ ! 63 pcc1i /* 9E0 */ +#endif +#if defined(CONFIG_CPU_SUBTYPE_SH7710) + .long exception_none ! 61 /* 9A0 */ + .long exception_none ! 62 + .long exception_none ! 63 + .long exception_none ! 64 /* A00 */ + .long exception_none ! 65 + .long exception_none ! 66 + .long exception_none ! 67 + .long exception_none ! 68 + .long exception_none ! 69 + .long exception_none ! 70 + .long exception_none ! 71 + .long exception_none ! 72 /* B00 */ + .long exception_none ! 73 + .long exception_none ! 74 + .long exception_none ! 75 + .long do_IRQ ! 76 DMAC2 dei4 /* B80 */ + .long do_IRQ ! 77 DMAC2 dei5 + .long exception_none ! 78 + .long do_IRQ ! 79 IPSEC ipseci /* BE0 */ + .long do_IRQ ! 80 EDMAC eint0 /* C00 */ + .long do_IRQ ! 81 EDMAC eint1 + .long do_IRQ ! 82 EDMAC eint2 + .long exception_none ! 83 /* C60 */ + .long exception_none ! 84 + .long exception_none ! 85 + .long exception_none ! 86 + .long exception_none ! 87 + .long exception_none ! 88 /* D00 */ + .long exception_none ! 89 + .long exception_none ! 90 + .long exception_none ! 91 + .long exception_none ! 92 + .long exception_none ! 93 + .long exception_none ! 94 + .long exception_none ! 95 + .long do_IRQ ! 96 SIOF eri0 /* E00 */ + .long do_IRQ ! 97 txi0 + .long do_IRQ ! 98 rxi0 + .long do_IRQ ! 99 cci0 + .long do_IRQ ! 100 eri1 /* E80 */ + .long do_IRQ ! 101 txi1 + .long do_IRQ ! 102 rxi2 + .long do_IRQ ! 103 cci3 +#endif +#if defined(CONFIG_CPU_SUBTYPE_SH7300) + .long do_IRQ ! 64 + .long do_IRQ ! 65 + .long do_IRQ ! 66 + .long do_IRQ ! 67 + .long do_IRQ ! 68 + .long do_IRQ ! 69 + .long do_IRQ ! 70 + .long do_IRQ ! 71 + .long do_IRQ ! 72 + .long do_IRQ ! 73 + .long do_IRQ ! 74 + .long do_IRQ ! 75 + .long do_IRQ ! 76 + .long do_IRQ ! 77 + .long do_IRQ ! 78 + .long do_IRQ ! 79 + .long do_IRQ ! 80 SCIF0(SH7300) + .long do_IRQ ! 81 + .long do_IRQ ! 82 + .long do_IRQ ! 83 + .long do_IRQ ! 84 + .long do_IRQ ! 85 + .long do_IRQ ! 86 + .long do_IRQ ! 87 + .long do_IRQ ! 88 + .long do_IRQ ! 89 + .long do_IRQ ! 90 + .long do_IRQ ! 91 + .long do_IRQ ! 92 + .long do_IRQ ! 93 + .long do_IRQ ! 94 + .long do_IRQ ! 95 + .long do_IRQ ! 96 + .long do_IRQ ! 97 + .long do_IRQ ! 98 + .long do_IRQ ! 99 + .long do_IRQ ! 100 + .long do_IRQ ! 101 + .long do_IRQ ! 102 + .long do_IRQ ! 103 + .long do_IRQ ! 104 + .long do_IRQ ! 105 + .long do_IRQ ! 106 + .long do_IRQ ! 107 + .long do_IRQ ! 108 +#endif +#endif diff --git a/trunk/arch/sh/kernel/cpu/sh4/ex.S b/trunk/arch/sh/kernel/cpu/sh4/ex.S index ac8ab57413cc..7146893a6cca 100644 --- a/trunk/arch/sh/kernel/cpu/sh4/ex.S +++ b/trunk/arch/sh/kernel/cpu/sh4/ex.S @@ -4,7 +4,7 @@ * The SH-4 exception vector table. * Copyright (C) 1999, 2000, 2002 Niibe Yutaka - * Copyright (C) 2003 - 2006 Paul Mundt + * Copyright (C) 2003 Paul Mundt * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -53,10 +53,503 @@ ENTRY(nmi_slot) #endif ENTRY(user_break_point_trap) .long break_point_trap /* 1E0 */ +ENTRY(interrupt_table) + ! external hardware + .long do_IRQ ! 0000 /* 200 */ + .long do_IRQ ! 0001 + .long do_IRQ ! 0010 + .long do_IRQ ! 0011 + .long do_IRQ ! 0100 + .long do_IRQ ! 0101 + .long do_IRQ ! 0110 + .long do_IRQ ! 0111 + .long do_IRQ ! 1000 /* 300 */ + .long do_IRQ ! 1001 + .long do_IRQ ! 1010 + .long do_IRQ ! 1011 + .long do_IRQ ! 1100 + .long do_IRQ ! 1101 + .long do_IRQ ! 1110 + .long exception_error + ! Internal hardware +#ifndef CONFIG_CPU_SUBTYPE_SH7780 + .long do_IRQ ! TMU0 tuni0 /* 400 */ + .long do_IRQ ! TMU1 tuni1 + .long do_IRQ ! TMU2 tuni2 + .long do_IRQ ! ticpi2 +#if defined(CONFIG_CPU_SUBTYPE_SH7760) + .long exception_error + .long exception_error + .long exception_error + .long exception_error + .long exception_error /* 500 */ + .long exception_error + .long exception_error +#else + .long do_IRQ ! RTC ati + .long do_IRQ ! pri + .long do_IRQ ! cui + .long do_IRQ ! SCI eri + .long do_IRQ ! rxi /* 500 */ + .long do_IRQ ! txi + .long do_IRQ ! tei +#endif + .long do_IRQ ! WDT iti /* 560 */ + .long do_IRQ ! REF rcmi + .long do_IRQ ! rovi + .long do_IRQ + .long do_IRQ /* 5E0 */ + .long do_IRQ ! 32 Hitachi UDI /* 600 */ + .long do_IRQ ! 33 GPIO + .long do_IRQ ! 34 DMAC dmte0 + .long do_IRQ ! 35 dmte1 + .long do_IRQ ! 36 dmte2 + .long do_IRQ ! 37 dmte3 + .long do_IRQ ! 38 dmae + .long exception_error ! 39 /* 6E0 */ +#if defined(CONFIG_CPU_SUBTYPE_SH7760) + .long exception_error /* 700 */ + .long exception_error + .long exception_error + .long exception_error /* 760 */ +#else + .long do_IRQ ! 40 SCIF eri /* 700 */ + .long do_IRQ ! 41 rxi + .long do_IRQ ! 42 bri + .long do_IRQ ! 43 txi +#endif +#if CONFIG_NR_ONCHIP_DMA_CHANNELS == 8 + .long do_IRQ ! 44 DMAC dmte4 /* 780 */ + .long do_IRQ ! 45 dmte5 + .long do_IRQ ! 46 dmte6 + .long do_IRQ ! 47 dmte7 /* 7E0 */ +#elif defined(CONFIG_CPU_SUBTYPE_SH7343) + .long do_IRQ ! 44 IIC1 ali /* 780 */ + .long do_IRQ ! 45 tacki + .long do_IRQ ! 46 waiti + .long do_IRQ ! 47 dtei /* 7E0 */ + .long do_IRQ ! 48 DMAC dei0 /* 800 */ + .long do_IRQ ! 49 dei1 /* 820 */ +#else + .long exception_error ! 44 /* 780 */ + .long exception_error ! 45 + .long exception_error ! 46 + .long exception_error ! 47 +#endif +#if defined(CONFIG_SH_FPU) + .long do_fpu_state_restore ! 48 /* 800 */ + .long do_fpu_state_restore ! 49 /* 820 */ +#elif !defined(CONFIG_CPU_SUBTYPE_SH7343) && \ + !defined(CONFIG_CPU_SUBTYPE_SH73180) + .long exception_error + .long exception_error +#endif +#if defined(CONFIG_CPU_SUBTYPE_SH7751) + .long exception_error /* 840 */ + .long exception_error + .long exception_error + .long exception_error + .long exception_error + .long exception_error + .long exception_error /* 900 */ + .long exception_error + .long exception_error + .long exception_error + .long exception_error + .long exception_error + .long exception_error + .long exception_error + .long do_IRQ ! PCI serr /* A00 */ + .long do_IRQ ! dma3 + .long do_IRQ ! dma2 + .long do_IRQ ! dma1 + .long do_IRQ ! dma0 + .long do_IRQ ! pwon + .long do_IRQ ! pwdwn + .long do_IRQ ! err + .long do_IRQ ! TMU3 tuni3 /* B00 */ + .long exception_error + .long exception_error + .long exception_error + .long do_IRQ ! TMU4 tuni4 /* B80 */ +#elif defined(CONFIG_CPU_SUBTYPE_SH7760) + .long do_IRQ ! IRQ irq6 /* 840 */ + .long do_IRQ ! irq7 + .long do_IRQ ! SCIF eri0 + .long do_IRQ ! rxi0 + .long do_IRQ ! bri0 + .long do_IRQ ! txi0 + .long do_IRQ ! HCAN2 cani0 /* 900 */ + .long do_IRQ ! cani1 + .long do_IRQ ! SSI ssii0 + .long do_IRQ ! ssii1 + .long do_IRQ ! HAC haci0 + .long do_IRQ ! haci1 + .long do_IRQ ! IIC iici0 + .long do_IRQ ! iici1 + .long do_IRQ ! USB usbi /* A00 */ + .long do_IRQ ! LCDC vint + .long exception_error + .long exception_error + .long do_IRQ ! DMABRG dmabrgi0 + .long do_IRQ ! dmabrgi1 + .long do_IRQ ! dmabrgi2 + .long exception_error + .long do_IRQ ! SCIF eri1 /* B00 */ + .long do_IRQ ! rxi1 + .long do_IRQ ! bri1 + .long do_IRQ ! txi1 + .long do_IRQ ! eri2 + .long do_IRQ ! rxi2 + .long do_IRQ ! bri2 + .long do_IRQ ! txi2 + .long do_IRQ ! SIM simeri /* C00 */ + .long do_IRQ ! simrxi + .long do_IRQ ! simtxi + .long do_IRQ ! simtei + .long do_IRQ ! HSPI spii + .long exception_error + .long exception_error + .long exception_error + .long do_IRQ ! MMCIF mmci0 /* D00 */ + .long do_IRQ ! mmci1 + .long do_IRQ ! mmci2 + .long do_IRQ ! mmci3 + .long exception_error + .long exception_error + .long exception_error + .long exception_error + .long exception_error /* E00 */ + .long exception_error + .long exception_error + .long exception_error + .long do_IRQ ! MFI mfii + .long exception_error + .long exception_error + .long exception_error + .long exception_error /* F00 */ + .long exception_error + .long exception_error + .long exception_error + .long do_IRQ ! ADC adi + .long do_IRQ ! CMT cmti /* FA0 */ +#elif defined(CONFIG_CPU_SUBTYPE_SH73180) || defined(CONFIG_CPU_SUBTYPE_SH7343) + .long do_IRQ ! 50 0x840 + .long do_IRQ ! 51 0x860 + .long do_IRQ ! 52 0x880 + .long do_IRQ ! 53 0x8a0 + .long do_IRQ ! 54 0x8c0 + .long do_IRQ ! 55 0x8e0 + .long do_IRQ ! 56 0x900 + .long do_IRQ ! 57 0x920 + .long do_IRQ ! 58 0x940 + .long do_IRQ ! 59 0x960 + .long do_IRQ ! 60 0x980 + .long do_IRQ ! 61 0x9a0 + .long do_IRQ ! 62 0x9c0 + .long do_IRQ ! 63 0x9e0 + .long do_IRQ ! 64 0xa00 + .long do_IRQ ! 65 0xa20 + .long do_IRQ ! 66 0xa40 + .long do_IRQ ! 67 0xa60 + .long do_IRQ ! 68 0xa80 + .long do_IRQ ! 69 0xaa0 + .long do_IRQ ! 70 0xac0 + .long do_IRQ ! 71 0xae0 + .long do_IRQ ! 72 0xb00 + .long do_IRQ ! 73 0xb20 + .long do_IRQ ! 74 0xb40 + .long do_IRQ ! 75 0xb60 + .long do_IRQ ! 76 0xb80 + .long do_IRQ ! 77 0xba0 + .long do_IRQ ! 78 0xbc0 + .long do_IRQ ! 79 0xbe0 + .long do_IRQ ! 80 0xc00 + .long do_IRQ ! 81 0xc20 + .long do_IRQ ! 82 0xc40 + .long do_IRQ ! 83 0xc60 + .long do_IRQ ! 84 0xc80 + .long do_IRQ ! 85 0xca0 + .long do_IRQ ! 86 0xcc0 + .long do_IRQ ! 87 0xce0 + .long do_IRQ ! 88 0xd00 + .long do_IRQ ! 89 0xd20 + .long do_IRQ ! 90 0xd40 + .long do_IRQ ! 91 0xd60 + .long do_IRQ ! 92 0xd80 + .long do_IRQ ! 93 0xda0 + .long do_IRQ ! 94 0xdc0 + .long do_IRQ ! 95 0xde0 + .long do_IRQ ! 96 0xe00 + .long do_IRQ ! 97 0xe20 + .long do_IRQ ! 98 0xe40 + .long do_IRQ ! 99 0xe60 + .long do_IRQ ! 100 0xe80 + .long do_IRQ ! 101 0xea0 + .long do_IRQ ! 102 0xec0 + .long do_IRQ ! 103 0xee0 + .long do_IRQ ! 104 0xf00 + .long do_IRQ ! 105 0xf20 + .long do_IRQ ! 106 0xf40 + .long do_IRQ ! 107 0xf60 + .long do_IRQ ! 108 0xf80 +#elif defined(CONFIG_CPU_SUBTYPE_ST40STB1) + .long exception_error ! 50 0x840 + .long exception_error ! 51 0x860 + .long exception_error ! 52 0x880 + .long exception_error ! 53 0x8a0 + .long exception_error ! 54 0x8c0 + .long exception_error ! 55 0x8e0 + .long exception_error ! 56 0x900 + .long exception_error ! 57 0x920 + .long exception_error ! 58 0x940 + .long exception_error ! 59 0x960 + .long exception_error ! 60 0x980 + .long exception_error ! 61 0x9a0 + .long exception_error ! 62 0x9c0 + .long exception_error ! 63 0x9e0 + .long do_IRQ ! 64 0xa00 PCI serr + .long do_IRQ ! 65 0xa20 err + .long do_IRQ ! 66 0xa40 ad + .long do_IRQ ! 67 0xa60 pwr_dwn + .long exception_error ! 68 0xa80 + .long exception_error ! 69 0xaa0 + .long exception_error ! 70 0xac0 + .long exception_error ! 71 0xae0 + .long do_IRQ ! 72 0xb00 DMA INT0 + .long do_IRQ ! 73 0xb20 INT1 + .long do_IRQ ! 74 0xb40 INT2 + .long do_IRQ ! 75 0xb60 INT3 + .long do_IRQ ! 76 0xb80 INT4 + .long exception_error ! 77 0xba0 + .long do_IRQ ! 78 0xbc0 DMA ERR + .long exception_error ! 79 0xbe0 + .long do_IRQ ! 80 0xc00 PIO0 + .long do_IRQ ! 81 0xc20 PIO1 + .long do_IRQ ! 82 0xc40 PIO2 + .long exception_error ! 83 0xc60 + .long exception_error ! 84 0xc80 + .long exception_error ! 85 0xca0 + .long exception_error ! 86 0xcc0 + .long exception_error ! 87 0xce0 + .long exception_error ! 88 0xd00 + .long exception_error ! 89 0xd20 + .long exception_error ! 90 0xd40 + .long exception_error ! 91 0xd60 + .long exception_error ! 92 0xd80 + .long exception_error ! 93 0xda0 + .long exception_error ! 94 0xdc0 + .long exception_error ! 95 0xde0 + .long exception_error ! 96 0xe00 + .long exception_error ! 97 0xe20 + .long exception_error ! 98 0xe40 + .long exception_error ! 99 0xe60 + .long exception_error ! 100 0xe80 + .long exception_error ! 101 0xea0 + .long exception_error ! 102 0xec0 + .long exception_error ! 103 0xee0 + .long exception_error ! 104 0xf00 + .long exception_error ! 105 0xf20 + .long exception_error ! 106 0xf40 + .long exception_error ! 107 0xf60 + .long exception_error ! 108 0xf80 + .long exception_error ! 109 0xfa0 + .long exception_error ! 110 0xfc0 + .long exception_error ! 111 0xfe0 + .long do_IRQ ! 112 0x1000 Mailbox + .long exception_error ! 113 0x1020 + .long exception_error ! 114 0x1040 + .long exception_error ! 115 0x1060 + .long exception_error ! 116 0x1080 + .long exception_error ! 117 0x10a0 + .long exception_error ! 118 0x10c0 + .long exception_error ! 119 0x10e0 + .long exception_error ! 120 0x1100 + .long exception_error ! 121 0x1120 + .long exception_error ! 122 0x1140 + .long exception_error ! 123 0x1160 + .long exception_error ! 124 0x1180 + .long exception_error ! 125 0x11a0 + .long exception_error ! 126 0x11c0 + .long exception_error ! 127 0x11e0 + .long exception_error ! 128 0x1200 + .long exception_error ! 129 0x1220 + .long exception_error ! 130 0x1240 + .long exception_error ! 131 0x1260 + .long exception_error ! 132 0x1280 + .long exception_error ! 133 0x12a0 + .long exception_error ! 134 0x12c0 + .long exception_error ! 135 0x12e0 + .long exception_error ! 136 0x1300 + .long exception_error ! 137 0x1320 + .long exception_error ! 138 0x1340 + .long exception_error ! 139 0x1360 + .long do_IRQ ! 140 0x1380 EMPI INV_ADDR + .long exception_error ! 141 0x13a0 + .long exception_error ! 142 0x13c0 + .long exception_error ! 143 0x13e0 +#elif defined(CONFIG_CPU_SUBTYPE_SH7770) + .long do_IRQ ! 50 0x840 + .long do_IRQ ! 51 0x860 + .long do_IRQ ! 52 0x880 + .long do_IRQ ! 53 0x8a0 + .long do_IRQ ! 54 0x8c0 + .long do_IRQ ! 55 0x8e0 + .long do_IRQ ! 56 0x900 + .long do_IRQ ! 57 0x920 + .long do_IRQ ! 58 0x940 + .long do_IRQ ! 59 0x960 + .long do_IRQ ! 60 0x980 + .long do_IRQ ! 61 0x9a0 + .long do_IRQ ! 62 0x9c0 + .long do_IRQ ! 63 0x9e0 + .long do_IRQ ! 64 0xa00 + .long do_IRQ ! 65 0xa20 + .long do_IRQ ! 66 0xa4d + .long do_IRQ ! 67 0xa60 + .long do_IRQ ! 68 0xa80 + .long do_IRQ ! 69 0xaa0 + .long do_IRQ ! 70 0xac0 + .long do_IRQ ! 71 0xae0 + .long do_IRQ ! 72 0xb00 + .long do_IRQ ! 73 0xb20 + .long do_IRQ ! 74 0xb40 + .long do_IRQ ! 75 0xb60 + .long do_IRQ ! 76 0xb80 + .long do_IRQ ! 77 0xba0 + .long do_IRQ ! 78 0xbc0 + .long do_IRQ ! 79 0xbe0 + .long do_IRQ ! 80 0xc00 + .long do_IRQ ! 81 0xc20 + .long do_IRQ ! 82 0xc40 + .long do_IRQ ! 83 0xc60 + .long do_IRQ ! 84 0xc80 + .long do_IRQ ! 85 0xca0 + .long do_IRQ ! 86 0xcc0 + .long do_IRQ ! 87 0xce0 + .long do_IRQ ! 88 0xd00 + .long do_IRQ ! 89 0xd20 + .long do_IRQ ! 90 0xd40 + .long do_IRQ ! 91 0xd60 + .long do_IRQ ! 92 0xd80 + .long do_IRQ ! 93 0xda0 + .long do_IRQ ! 94 0xdc0 + .long do_IRQ ! 95 0xde0 + .long do_IRQ ! 96 0xe00 + .long do_IRQ ! 97 0xe20 + .long do_IRQ ! 98 0xe40 + .long do_IRQ ! 99 0xe60 + .long do_IRQ ! 100 0xe80 + .long do_IRQ ! 101 0xea0 + .long do_IRQ ! 102 0xec0 + .long do_IRQ ! 103 0xee0 + .long do_IRQ ! 104 0xf00 + .long do_IRQ ! 105 0xf20 + .long do_IRQ ! 106 0xf40 + .long do_IRQ ! 107 0xf60 + .long do_IRQ ! 108 0xf80 +#endif +#else + .long exception_error /* 400 */ + .long exception_error + .long exception_error + .long exception_error + .long do_IRQ ! RTC ati + .long do_IRQ ! pri + .long do_IRQ ! cui + .long exception_error + .long exception_error /* 500 */ + .long exception_error + .long exception_error + .long do_IRQ ! WDT iti /* 560 */ + .long do_IRQ ! TMU-ch0 + .long do_IRQ ! TMU-ch1 + .long do_IRQ ! TMU-ch2 + .long do_IRQ ! ticpi2 /* 5E0 */ + .long do_IRQ ! 32 Hitachi UDI /* 600 */ + .long exception_error + .long do_IRQ ! 34 DMAC dmte0 + .long do_IRQ ! 35 dmte1 + .long do_IRQ ! 36 dmte2 + .long do_IRQ ! 37 dmte3 + .long do_IRQ ! 38 dmae + .long exception_error ! 39 /* 6E0 */ + .long do_IRQ ! 40 SCIF-ch0 eri /* 700 */ + .long do_IRQ ! 41 rxi + .long do_IRQ ! 42 bri + .long do_IRQ ! 43 txi + .long do_IRQ ! 44 DMAC dmte4 /* 780 */ + .long do_IRQ ! 45 dmte5 + .long do_IRQ ! 46 dmte6 + .long do_IRQ ! 47 dmte7 /* 7E0 */ +#if defined(CONFIG_SH_FPU) + .long do_fpu_state_restore ! 48 /* 800 */ + .long do_fpu_state_restore ! 49 /* 820 */ +#else + .long exception_error + .long exception_error +#endif + .long exception_error /* 840 */ + .long exception_error + .long exception_error + .long exception_error + .long exception_error + .long exception_error + .long do_IRQ ! 56 CMT /* 900 */ + .long exception_error + .long exception_error + .long exception_error + .long do_IRQ ! 60 HAC + .long exception_error + .long exception_error + .long exception_error + .long do_IRQ ! PCI serr /* A00 */ + .long do_IRQ ! INTA + .long do_IRQ ! INTB + .long do_IRQ ! INTC + .long do_IRQ ! INTD + .long do_IRQ ! err + .long do_IRQ ! pwd3 + .long do_IRQ ! pwd2 + .long do_IRQ ! pwd1 /* B00 */ + .long do_IRQ ! pwd0 + .long exception_error + .long exception_error + .long do_IRQ ! SCIF-ch1 eri /* B80 */ + .long do_IRQ ! rxi + .long do_IRQ ! bri + .long do_IRQ ! txi + .long do_IRQ ! SIOF /* C00 */ + .long exception_error + .long exception_error + .long exception_error + .long do_IRQ ! HSPI /* C80 */ + .long exception_error + .long exception_error + .long exception_error + .long do_IRQ ! MMCIF fatat /* D00 */ + .long do_IRQ ! tran + .long do_IRQ ! err + .long do_IRQ ! frdy + .long do_IRQ ! DMAC dmint8 /* D80 */ + .long do_IRQ ! dmint9 + .long do_IRQ ! dmint10 + .long do_IRQ ! dmint11 + .long do_IRQ ! TMU-ch3 /* E00 */ + .long do_IRQ ! TMU-ch4 + .long do_IRQ ! TMU-ch5 + .long exception_error + .long do_IRQ ! SSI + .long exception_error + .long exception_error + .long exception_error + .long do_IRQ ! FLCTL flste /* F00 */ + .long do_IRQ ! fltend + .long do_IRQ ! fltrq0 + .long do_IRQ ! fltrq1 + .long do_IRQ ! GPIO gpioi0 /* F80 */ + .long do_IRQ ! gpioi1 + .long do_IRQ ! gpioi2 + .long do_IRQ ! gpioi3 +#endif - /* - * Pad the remainder of the table out, exceptions residing in far - * away offsets can be manually inserted in to their appropriate - * location via set_exception_table_{evt,vec}(). - */ - .balign 4096,0,4096 diff --git a/trunk/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/trunk/arch/sh/kernel/cpu/sh4/setup-sh7760.c index 07e5377bf550..97f1c9af35d6 100644 --- a/trunk/arch/sh/kernel/cpu/sh4/setup-sh7760.c +++ b/trunk/arch/sh/kernel/cpu/sh4/setup-sh7760.c @@ -51,66 +51,3 @@ static int __init sh7760_devices_setup(void) ARRAY_SIZE(sh7760_devices)); } __initcall(sh7760_devices_setup); - -/* - * SH7760 INTC2-Style interrupts, vectors IRQ48-111 INTEVT 0x800-0xFE0 - */ -static struct intc2_data intc2_irq_table[] = { - /* INTPRIO0 | INTMSK0 */ - {48, 0, 28, 0, 31, 3}, /* IRQ 4 */ - {49, 0, 24, 0, 30, 3}, /* IRQ 3 */ - {50, 0, 20, 0, 29, 3}, /* IRQ 2 */ - {51, 0, 16, 0, 28, 3}, /* IRQ 1 */ - /* 52-55 (INTEVT 0x880-0x8E0) unused/reserved */ - /* INTPRIO4 | INTMSK0 */ - {56, 4, 28, 0, 25, 3}, /* HCAN2_CHAN0 */ - {57, 4, 24, 0, 24, 3}, /* HCAN2_CHAN1 */ - {58, 4, 20, 0, 23, 3}, /* I2S_CHAN0 */ - {59, 4, 16, 0, 22, 3}, /* I2S_CHAN1 */ - {60, 4, 12, 0, 21, 3}, /* AC97_CHAN0 */ - {61, 4, 8, 0, 20, 3}, /* AC97_CHAN1 */ - {62, 4, 4, 0, 19, 3}, /* I2C_CHAN0 */ - {63, 4, 0, 0, 18, 3}, /* I2C_CHAN1 */ - /* INTPRIO8 | INTMSK0 */ - {52, 8, 16, 0, 11, 3}, /* SCIF0_ERI_IRQ */ - {53, 8, 16, 0, 10, 3}, /* SCIF0_RXI_IRQ */ - {54, 8, 16, 0, 9, 3}, /* SCIF0_BRI_IRQ */ - {55, 8, 16, 0, 8, 3}, /* SCIF0_TXI_IRQ */ - {64, 8, 28, 0, 17, 3}, /* USBHI_IRQ */ - {65, 8, 24, 0, 16, 3}, /* LCDC */ - /* 66, 67 unused */ - {68, 8, 20, 0, 14, 13}, /* DMABRGI0_IRQ */ - {69, 8, 20, 0, 13, 13}, /* DMABRGI1_IRQ */ - {70, 8, 20, 0, 12, 13}, /* DMABRGI2_IRQ */ - /* 71 unused */ - {72, 8, 12, 0, 7, 3}, /* SCIF1_ERI_IRQ */ - {73, 8, 12, 0, 6, 3}, /* SCIF1_RXI_IRQ */ - {74, 8, 12, 0, 5, 3}, /* SCIF1_BRI_IRQ */ - {75, 8, 12, 0, 4, 3}, /* SCIF1_TXI_IRQ */ - {76, 8, 8, 0, 3, 3}, /* SCIF2_ERI_IRQ */ - {77, 8, 8, 0, 2, 3}, /* SCIF2_RXI_IRQ */ - {78, 8, 8, 0, 1, 3}, /* SCIF2_BRI_IRQ */ - {79, 8, 8, 0, 0, 3}, /* SCIF2_TXI_IRQ */ - /* | INTMSK4 */ - {80, 8, 4, 4, 23, 3}, /* SIM_ERI */ - {81, 8, 4, 4, 22, 3}, /* SIM_RXI */ - {82, 8, 4, 4, 21, 3}, /* SIM_TXI */ - {83, 8, 4, 4, 20, 3}, /* SIM_TEI */ - {84, 8, 0, 4, 19, 3}, /* HSPII */ - /* INTPRIOC | INTMSK4 */ - /* 85-87 unused/reserved */ - {88, 12, 20, 4, 18, 3}, /* MMCI0 */ - {89, 12, 20, 4, 17, 3}, /* MMCI1 */ - {90, 12, 20, 4, 16, 3}, /* MMCI2 */ - {91, 12, 20, 4, 15, 3}, /* MMCI3 */ - {92, 12, 12, 4, 6, 3}, /* MFI (unsure, bug? in my 7760 manual*/ - /* 93-107 reserved/undocumented */ - {108,12, 4, 4, 1, 3}, /* ADC */ - {109,12, 0, 4, 0, 3}, /* CMTI */ - /* 110-111 reserved/unused */ -}; - -void __init init_IRQ_intc2(void) -{ - make_intc2_irq(intc2_irq_table, ARRAY_SIZE(intc2_irq_table)); -} diff --git a/trunk/arch/sh/kernel/cpu/sh4/setup-sh7780.c b/trunk/arch/sh/kernel/cpu/sh4/setup-sh7780.c index 814ddb226531..72493f259edc 100644 --- a/trunk/arch/sh/kernel/cpu/sh4/setup-sh7780.c +++ b/trunk/arch/sh/kernel/cpu/sh4/setup-sh7780.c @@ -77,30 +77,3 @@ static int __init sh7780_devices_setup(void) ARRAY_SIZE(sh7780_devices)); } __initcall(sh7780_devices_setup); - -static struct intc2_data intc2_irq_table[] = { - { TIMER_IRQ, 0, 24, 0, INTC_TMU0_MSK, 2 }, - { 21, 1, 0, 0, INTC_RTC_MSK, TIMER_PRIORITY }, - { 22, 1, 1, 0, INTC_RTC_MSK, TIMER_PRIORITY }, - { 23, 1, 2, 0, INTC_RTC_MSK, TIMER_PRIORITY }, - { SCIF0_ERI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY }, - { SCIF0_RXI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY }, - { SCIF0_BRI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY }, - { SCIF0_TXI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY }, - - { SCIF1_ERI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY }, - { SCIF1_RXI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY }, - { SCIF1_BRI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY }, - { SCIF1_TXI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY }, - - { PCIC0_IRQ, 0x10, 8, 0, INTC_PCIC0_MSK, PCIC0_PRIORITY }, - { PCIC1_IRQ, 0x10, 0, 0, INTC_PCIC1_MSK, PCIC1_PRIORITY }, - { PCIC2_IRQ, 0x14, 24, 0, INTC_PCIC2_MSK, PCIC2_PRIORITY }, - { PCIC3_IRQ, 0x14, 16, 0, INTC_PCIC3_MSK, PCIC3_PRIORITY }, - { PCIC4_IRQ, 0x14, 8, 0, INTC_PCIC4_MSK, PCIC4_PRIORITY }, -}; - -void __init init_IRQ_intc2(void) -{ - make_intc2_irq(intc2_irq_table, ARRAY_SIZE(intc2_irq_table)); -} diff --git a/trunk/arch/sh/kernel/entry.S b/trunk/arch/sh/kernel/entry.S index 39aaefb2d83f..97c571fbcdf1 100644 --- a/trunk/arch/sh/kernel/entry.S +++ b/trunk/arch/sh/kernel/entry.S @@ -1,8 +1,9 @@ -/* +/* $Id: entry.S,v 1.37 2004/06/11 13:02:46 doyu Exp $ + * * linux/arch/sh/entry.S * * Copyright (C) 1999, 2000, 2002 Niibe Yutaka - * Copyright (C) 2003 - 2006 Paul Mundt + * Copyright (C) 2003 Paul Mundt * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -77,6 +78,7 @@ OFF_TRA = (16*4+6*4) #define k3 r3 #define k4 r4 +#define k_ex_code r2_bank /* r2_bank1 */ #define g_imask r6 /* r6_bank1 */ #define k_g_imask r6_bank /* r6_bank1 */ #define current r7 /* r7_bank1 */ @@ -689,7 +691,7 @@ interrupt: 0: #endif /* defined(CONFIG_KGDB_NMI) */ bra handle_exception - mov #-1, k2 ! interrupt exception marker + mov.l @k2, k2 .align 2 1: .long EXPEVT @@ -715,7 +717,8 @@ ENTRY(handle_exception) add current, k1 mov k1, r15 ! change to kernel stack ! -1: mov.l 2f, k1 +1: mov #-1, k4 + mov.l 2f, k1 ! #ifdef CONFIG_SH_DSP mov.l r2, @-r15 ! Save r2, we need another reg @@ -760,8 +763,6 @@ skip_save: #endif ! Save the user registers on the stack. mov.l k2, @-r15 ! EXPEVT - - mov #-1, k4 mov.l k4, @-r15 ! set TRA (default: -1) ! sts.l macl, @-r15 @@ -796,21 +797,8 @@ skip_save: mov.l r2, @-r15 mov.l r1, @-r15 mov.l r0, @-r15 - - /* - * This gets a bit tricky.. in the INTEVT case we don't want to use - * the VBR offset as a destination in the jump call table, since all - * of the destinations are the same. In this case, (interrupt) sets - * a marker in r2 (now r2_bank since SR.RB changed), which we check - * to determine the exception type. For all other exceptions, we - * forcibly read EXPEVT from memory and fix up the jump address, in - * the interrupt exception case we jump to do_IRQ() and defer the - * INTEVT read until there. As a bonus, we can also clean up the SR.RB - * checks that do_IRQ() was doing.. - */ - stc r2_bank, r8 - cmp/pz r8 - bf interrupt_exception + ! Then, dispatch to the handler, according to the exception code. + stc k_ex_code, r8 shlr2 r8 shlr r8 mov.l 4f, r9 @@ -818,8 +806,6 @@ skip_save: mov.l @r9, r9 jmp @r9 nop - rts - nop .align 2 1: .long 0x00001000 ! DSP=1 @@ -827,17 +813,8 @@ skip_save: 3: .long 0xcfffffff ! RB=0, BL=0 4: .long exception_handling_table -interrupt_exception: - mov.l 1f, r9 - jmp @r9 - nop - rts - nop - - .align 2 -1: .long do_IRQ - .align 2 ENTRY(exception_none) rts nop + diff --git a/trunk/arch/sh/kernel/irq.c b/trunk/arch/sh/kernel/irq.c index 944128ce9706..c7ebd6aec951 100644 --- a/trunk/arch/sh/kernel/irq.c +++ b/trunk/arch/sh/kernel/irq.c @@ -11,15 +11,12 @@ #include #include #include -#include #include #include #include #include #include -atomic_t irq_err_count; - /* * 'what should we do if we get a hw irq event on an illegal vector'. * each architecture has to answer this themselves, it doesn't deserve @@ -27,7 +24,6 @@ atomic_t irq_err_count; */ void ack_bad_irq(unsigned int irq) { - atomic_inc(&irq_err_count); printk("unexpected IRQ trap at vector %02x\n", irq); } @@ -51,10 +47,8 @@ int show_interrupts(struct seq_file *p, void *v) if (!action) goto unlock; seq_printf(p, "%3d: ",i); - for_each_online_cpu(j) - seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); - seq_printf(p, " %14s", irq_desc[i].chip->name); - seq_printf(p, "-%-8s", irq_desc[i].name); + seq_printf(p, "%10u ", kstat_irqs(i)); + seq_printf(p, " %14s", irq_desc[i].chip->typename); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) @@ -62,9 +56,7 @@ int show_interrupts(struct seq_file *p, void *v) seq_putc(p, '\n'); unlock: spin_unlock_irqrestore(&irq_desc[i].lock, flags); - } else if (i == NR_IRQS) - seq_printf(p, "Err: %10u\n", atomic_read(&irq_err_count)); - + } return 0; } #endif @@ -86,8 +78,7 @@ asmlinkage int do_IRQ(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, struct pt_regs regs) { - struct pt_regs *old_regs = set_irq_regs(®s); - int irq; + int irq = r4; #ifdef CONFIG_4KSTACKS union irq_ctx *curctx, *irqctx; #endif @@ -111,9 +102,20 @@ asmlinkage int do_IRQ(unsigned long r4, unsigned long r5, #endif #ifdef CONFIG_CPU_HAS_INTEVT - irq = (ctrl_inl(INTEVT) >> 5) - 16; + __asm__ __volatile__ ( +#ifdef CONFIG_CPU_HAS_SR_RB + "stc r2_bank, %0\n\t" #else - irq = r4; + "mov.l @%1, %0\n\t" +#endif + "shlr2 %0\n\t" + "shlr2 %0\n\t" + "shlr %0\n\t" + "add #-16, %0\n\t" + : "=z" (irq), "=r" (r4) + : "1" (INTEVT) + : "memory" + ); #endif irq = irq_demux(irq); @@ -137,25 +139,25 @@ asmlinkage int do_IRQ(unsigned long r4, unsigned long r5, __asm__ __volatile__ ( "mov %0, r4 \n" + "mov %1, r5 \n" "mov r15, r9 \n" - "jsr @%1 \n" + "jsr @%2 \n" /* swith to the irq stack */ - " mov %2, r15 \n" + " mov %3, r15 \n" /* restore the stack (ring zero) */ "mov r9, r15 \n" : /* no outputs */ - : "r" (irq), "r" (generic_handle_irq), "r" (isp) + : "r" (irq), "r" (®s), "r" (__do_IRQ), "r" (isp) /* XXX: A somewhat excessive clobber list? -PFM */ : "memory", "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "t", "pr" ); } else #endif - generic_handle_irq(irq); + __do_IRQ(irq, ®s); irq_exit(); - set_irq_regs(old_regs); return 1; } diff --git a/trunk/arch/sh/kernel/process.c b/trunk/arch/sh/kernel/process.c index a52b13ac6b7f..0b1d5dd7a93b 100644 --- a/trunk/arch/sh/kernel/process.c +++ b/trunk/arch/sh/kernel/process.c @@ -5,7 +5,6 @@ * Copyright (C) 1995 Linus Torvalds * * SuperH version: Copyright (C) 1999, 2000 Niibe Yutaka & Kaz Kojima - * Copyright (C) 2006 Lineo Solutions Inc. support SH4A UBC */ /* @@ -105,7 +104,7 @@ void show_regs(struct pt_regs * regs) { printk("\n"); printk("Pid : %d, Comm: %20s\n", current->pid, current->comm); - print_symbol("PC is at %s\n", instruction_pointer(regs)); + print_symbol("PC is at %s\n", regs->pc); printk("PC : %08lx SP : %08lx SR : %08lx ", regs->pc, regs->regs[15], regs->sr); #ifdef CONFIG_MMU @@ -130,7 +129,15 @@ void show_regs(struct pt_regs * regs) printk("MACH: %08lx MACL: %08lx GBR : %08lx PR : %08lx\n", regs->mach, regs->macl, regs->gbr, regs->pr); - show_trace(NULL, (unsigned long *)regs->regs[15], regs); + /* + * If we're in kernel mode, dump the stack too.. + */ + if (!user_mode(regs)) { + extern void show_task(unsigned long *sp); + unsigned long sp = regs->regs[15]; + + show_task((unsigned long *)sp); + } } /* @@ -283,24 +290,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, static void ubc_set_tracing(int asid, unsigned long pc) { -#if defined(CONFIG_CPU_SH4A) - unsigned long val; - - val = (UBC_CBR_ID_INST | UBC_CBR_RW_READ | UBC_CBR_CE); - val |= (UBC_CBR_AIE | UBC_CBR_AIV_SET(asid)); - - ctrl_outl(val, UBC_CBR0); - ctrl_outl(pc, UBC_CAR0); - ctrl_outl(0x0, UBC_CAMR0); - ctrl_outl(0x0, UBC_CBCR); - - val = (UBC_CRR_RES | UBC_CRR_PCB | UBC_CRR_BIE); - ctrl_outl(val, UBC_CRR0); - - /* Read UBC register that we writed last. For chekking UBC Register changed */ - val = ctrl_inl(UBC_CRR0); - -#else /* CONFIG_CPU_SH4A */ ctrl_outl(pc, UBC_BARA); #ifdef CONFIG_MMU @@ -318,7 +307,6 @@ ubc_set_tracing(int asid, unsigned long pc) ctrl_outw(BBR_INST | BBR_READ, UBC_BBRA); ctrl_outw(BRCR_PCBA, UBC_BRCR); } -#endif /* CONFIG_CPU_SH4A */ } /* @@ -371,13 +359,8 @@ struct task_struct *__switch_to(struct task_struct *prev, struct task_struct *ne #endif ubc_set_tracing(asid, next->thread.ubc_pc); } else { -#if defined(CONFIG_CPU_SH4A) - ctrl_outl(UBC_CBR_INIT, UBC_CBR0); - ctrl_outl(UBC_CRR_INIT, UBC_CRR0); -#else ctrl_outw(0, UBC_BBRA); ctrl_outw(0, UBC_BBRB); -#endif } return prev; @@ -477,13 +460,8 @@ asmlinkage void break_point_trap(unsigned long r4, unsigned long r5, struct pt_regs regs) { /* Clear tracing. */ -#if defined(CONFIG_CPU_SH4A) - ctrl_outl(UBC_CBR_INIT, UBC_CBR0); - ctrl_outl(UBC_CRR_INIT, UBC_CRR0); -#else ctrl_outw(0, UBC_BBRA); ctrl_outw(0, UBC_BBRB); -#endif current->thread.ubc_pc = 0; ubc_usercnt -= 1; diff --git a/trunk/arch/sh/kernel/syscalls.S b/trunk/arch/sh/kernel/syscalls.S index ca81976e9e34..768334e95075 100644 --- a/trunk/arch/sh/kernel/syscalls.S +++ b/trunk/arch/sh/kernel/syscalls.S @@ -351,6 +351,3 @@ ENTRY(sys_call_table) .long sys_sync_file_range .long sys_tee /* 315 */ .long sys_vmsplice - .long sys_move_pages - .long sys_getcpu - .long sys_epoll_pwait diff --git a/trunk/arch/sh/kernel/time.c b/trunk/arch/sh/kernel/time.c index 57e708d7b52d..450c68f1df05 100644 --- a/trunk/arch/sh/kernel/time.c +++ b/trunk/arch/sh/kernel/time.c @@ -47,7 +47,6 @@ unsigned long long __attribute__ ((weak)) sched_clock(void) return (unsigned long long)jiffies * (1000000000 / HZ); } -#ifndef CONFIG_GENERIC_TIME void do_gettimeofday(struct timeval *tv) { unsigned long seq; @@ -100,7 +99,6 @@ int do_settimeofday(struct timespec *tv) return 0; } EXPORT_SYMBOL(do_settimeofday); -#endif /* !CONFIG_GENERIC_TIME */ /* last time the RTC clock got updated */ static long last_rtc_update; @@ -109,14 +107,13 @@ static long last_rtc_update; * handle_timer_tick() needs to keep up the real-time clock, * as well as call the "do_timer()" routine every clocktick */ -void handle_timer_tick(void) +void handle_timer_tick(struct pt_regs *regs) { do_timer(1); #ifndef CONFIG_SMP - update_process_times(user_mode(get_irq_regs())); + update_process_times(user_mode(regs)); #endif - if (current->pid) - profile_tick(CPU_PROFILING); + profile_tick(CPU_PROFILING, regs); #ifdef CONFIG_HEARTBEAT if (sh_mv.mv_heartbeat != NULL) diff --git a/trunk/arch/sh/kernel/timers/timer-tmu.c b/trunk/arch/sh/kernel/timers/timer-tmu.c index 24927015dc31..205816fcf0da 100644 --- a/trunk/arch/sh/kernel/timers/timer-tmu.c +++ b/trunk/arch/sh/kernel/timers/timer-tmu.c @@ -80,7 +80,8 @@ static unsigned long tmu_timer_get_offset(void) return count; } -static irqreturn_t tmu_timer_interrupt(int irq, void *dummy) +static irqreturn_t tmu_timer_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { unsigned long timer_status; @@ -97,7 +98,7 @@ static irqreturn_t tmu_timer_interrupt(int irq, void *dummy) * locally disabled. -arca */ write_seqlock(&xtime_lock); - handle_timer_tick(); + handle_timer_tick(regs); write_sequnlock(&xtime_lock); return IRQ_HANDLED; @@ -110,6 +111,60 @@ static struct irqaction tmu_irq = { .mask = CPU_MASK_NONE, }; +/* + * Hah! We'll see if this works (switching from usecs to nsecs). + */ +static unsigned long tmu_timer_get_frequency(void) +{ + u32 freq; + struct timespec ts1, ts2; + unsigned long diff_nsec; + unsigned long factor; + + /* Setup the timer: We don't want to generate interrupts, just + * have it count down at its natural rate. + */ + ctrl_outb(0, TMU_TSTR); +#if !defined(CONFIG_CPU_SUBTYPE_SH7300) && !defined(CONFIG_CPU_SUBTYPE_SH7760) + ctrl_outb(TMU_TOCR_INIT, TMU_TOCR); +#endif + ctrl_outw(TMU0_TCR_CALIB, TMU0_TCR); + ctrl_outl(0xffffffff, TMU0_TCOR); + ctrl_outl(0xffffffff, TMU0_TCNT); + + rtc_sh_get_time(&ts2); + + do { + rtc_sh_get_time(&ts1); + } while (ts1.tv_nsec == ts2.tv_nsec && ts1.tv_sec == ts2.tv_sec); + + /* actually start the timer */ + ctrl_outb(TMU_TSTR_INIT, TMU_TSTR); + + do { + rtc_sh_get_time(&ts2); + } while (ts1.tv_nsec == ts2.tv_nsec && ts1.tv_sec == ts2.tv_sec); + + freq = 0xffffffff - ctrl_inl(TMU0_TCNT); + if (ts2.tv_nsec < ts1.tv_nsec) { + ts2.tv_nsec += 1000000000; + ts2.tv_sec--; + } + + diff_nsec = (ts2.tv_sec - ts1.tv_sec) * 1000000000 + (ts2.tv_nsec - ts1.tv_nsec); + + /* this should work well if the RTC has a precision of n Hz, where + * n is an integer. I don't think we have to worry about the other + * cases. */ + factor = (1000000000 + diff_nsec/2) / diff_nsec; + + if (factor * diff_nsec > 1100000000 || + factor * diff_nsec < 900000000) + panic("weird RTC (diff_nsec %ld)", diff_nsec); + + return freq * factor; +} + static void tmu_clk_init(struct clk *clk) { u8 divisor = TMU0_TCR_INIT & 0x7; @@ -177,12 +232,12 @@ struct sys_timer_ops tmu_timer_ops = { .init = tmu_timer_init, .start = tmu_timer_start, .stop = tmu_timer_stop, -#ifndef CONFIG_GENERIC_TIME + .get_frequency = tmu_timer_get_frequency, .get_offset = tmu_timer_get_offset, -#endif }; struct sys_timer tmu_timer = { .name = "tmu", .ops = &tmu_timer_ops, }; + diff --git a/trunk/arch/sh/kernel/traps.c b/trunk/arch/sh/kernel/traps.c index 53dfa55f3156..c2c597e09482 100644 --- a/trunk/arch/sh/kernel/traps.c +++ b/trunk/arch/sh/kernel/traps.c @@ -1,25 +1,38 @@ -/* - * 'traps.c' handles hardware traps and faults after we have saved some - * state in 'entry.S'. +/* $Id: traps.c,v 1.17 2004/05/02 01:46:30 sugioka Exp $ + * + * linux/arch/sh/traps.c * * SuperH version: Copyright (C) 1999 Niibe Yutaka * Copyright (C) 2000 Philipp Rumpf * Copyright (C) 2000 David Howells - * Copyright (C) 2002 - 2006 Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. + * Copyright (C) 2002, 2003 Paul Mundt */ + +/* + * 'Traps.c' handles hardware traps and faults after we have saved some + * state in 'entry.S'. + */ +#include #include +#include +#include #include +#include +#include +#include +#include #include +#include #include #include #include -#include + #include #include +#include +#include +#include +#include #ifdef CONFIG_SH_KGDB #include @@ -40,32 +53,13 @@ #define TRAP_ILLEGAL_SLOT_INST 13 #endif -static void dump_mem(const char *str, unsigned long bottom, unsigned long top) -{ - unsigned long p; - int i; - - printk("%s(0x%08lx to 0x%08lx)\n", str, bottom, top); - - for (p = bottom & ~31; p < top; ) { - printk("%04lx: ", p & 0xffff); - - for (i = 0; i < 8; i++, p += 4) { - unsigned int val; - - if (p < bottom || p >= top) - printk(" "); - else { - if (__get_user(val, (unsigned int __user *)p)) { - printk("\n"); - return; - } - printk("%08x ", val); - } - } - printk("\n"); - } -} +/* + * These constants are for searching for possible module text + * segments. VMALLOC_OFFSET comes from mm/vmalloc.c; MODULE_RANGE is + * a guess of how much space is likely to be vmalloced. + */ +#define VMALLOC_OFFSET (8*1024*1024) +#define MODULE_RANGE (8*1024*1024) DEFINE_SPINLOCK(die_lock); @@ -75,28 +69,14 @@ void die(const char * str, struct pt_regs * regs, long err) console_verbose(); spin_lock_irq(&die_lock); - bust_spinlocks(1); - printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter); - CHK_REMOTE_DEBUG(regs); - print_modules(); show_regs(regs); - - printk("Process: %s (pid: %d, stack limit = %p)\n", - current->comm, current->pid, task_stack_page(current) + 1); - - if (!user_mode(regs) || in_interrupt()) - dump_mem("Stack: ", regs->regs[15], THREAD_SIZE + - (unsigned long)task_stack_page(current)); - - bust_spinlocks(0); spin_unlock_irq(&die_lock); do_exit(SIGSEGV); } -static inline void die_if_kernel(const char *str, struct pt_regs *regs, - long err) +static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err) { if (!user_mode(regs)) die(str, regs, err); @@ -113,7 +93,8 @@ static int handle_unaligned_notify_count = 10; */ static int die_if_no_fixup(const char * str, struct pt_regs * regs, long err) { - if (!user_mode(regs)) { + if (!user_mode(regs)) + { const struct exception_table_entry *fixup; fixup = search_exception_tables(regs->pc); if (fixup) { @@ -569,10 +550,7 @@ int is_dsp_inst(struct pt_regs *regs) #define is_dsp_inst(regs) (0) #endif /* CONFIG_SH_DSP */ -/* arch/sh/kernel/cpu/sh4/fpu.c */ -extern int do_fpu_inst(unsigned short, struct pt_regs *); -extern asmlinkage void do_fpu_state_restore(unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7, struct pt_regs regs); +extern int do_fpu_inst(unsigned short, struct pt_regs*); asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, @@ -731,20 +709,14 @@ void __init per_cpu_trap_init(void) : "memory"); } -void *set_exception_table_vec(unsigned int vec, void *handler) +void __init trap_init(void) { extern void *exception_handling_table[]; - void *old_handler; - - old_handler = exception_handling_table[vec]; - exception_handling_table[vec] = handler; - return old_handler; -} -void __init trap_init(void) -{ - set_exception_table_vec(TRAP_RESERVED_INST, do_reserved_inst); - set_exception_table_vec(TRAP_ILLEGAL_SLOT_INST, do_illegal_slot_inst); + exception_handling_table[TRAP_RESERVED_INST] + = (void *)do_reserved_inst; + exception_handling_table[TRAP_ILLEGAL_SLOT_INST] + = (void *)do_illegal_slot_inst; #if defined(CONFIG_CPU_SH4) && !defined(CONFIG_SH_FPU) || \ defined(CONFIG_SH_FPU_EMU) @@ -753,54 +725,61 @@ void __init trap_init(void) * reserved. They'll be handled in the math-emu case, or faulted on * otherwise. */ - set_exception_table_evt(0x800, do_reserved_inst); - set_exception_table_evt(0x820, do_illegal_slot_inst); -#elif defined(CONFIG_SH_FPU) - set_exception_table_evt(0x800, do_fpu_state_restore); - set_exception_table_evt(0x820, do_fpu_state_restore); + /* entry 64 corresponds to EXPEVT=0x800 */ + exception_handling_table[64] = (void *)do_reserved_inst; + exception_handling_table[65] = (void *)do_illegal_slot_inst; #endif /* Setup VBR for boot cpu */ per_cpu_trap_init(); } -void show_trace(struct task_struct *tsk, unsigned long *sp, - struct pt_regs *regs) +void show_stack(struct task_struct *tsk, unsigned long *sp) { - unsigned long addr; + unsigned long *stack, addr; + unsigned long module_start = VMALLOC_START; + unsigned long module_end = VMALLOC_END; + int i = 1; - if (regs && user_mode(regs)) - return; + if (!tsk) + tsk = current; + if (tsk == current) + sp = (unsigned long *)current_stack_pointer; + else + sp = (unsigned long *)tsk->thread.sp; + + stack = sp; printk("\nCall trace: "); #ifdef CONFIG_KALLSYMS printk("\n"); #endif - while (!kstack_end(sp)) { - addr = *sp++; - if (kernel_text_address(addr)) - print_ip_sym(addr); + while (!kstack_end(stack)) { + addr = *stack++; + if (((addr >= (unsigned long)_text) && + (addr <= (unsigned long)_etext)) || + ((addr >= module_start) && (addr <= module_end))) { + /* + * For 80-columns display, 6 entry is maximum. + * NOTE: '[<8c00abcd>] ' consumes 13 columns . + */ +#ifndef CONFIG_KALLSYMS + if (i && ((i % 6) == 0)) + printk("\n "); +#endif + printk("[<%08lx>] ", addr); + print_symbol("%s\n", addr); + i++; + } } printk("\n"); } -void show_stack(struct task_struct *tsk, unsigned long *sp) +void show_task(unsigned long *sp) { - unsigned long stack; - - if (!tsk) - tsk = current; - if (tsk == current) - sp = (unsigned long *)current_stack_pointer; - else - sp = (unsigned long *)tsk->thread.sp; - - stack = (unsigned long)sp; - dump_mem("Stack: ", stack, THREAD_SIZE + - (unsigned long)task_stack_page(tsk)); - show_trace(tsk, sp, NULL); + show_stack(NULL, sp); } void dump_stack(void) diff --git a/trunk/arch/sh/kernel/vmlinux.lds.S b/trunk/arch/sh/kernel/vmlinux.lds.S index 77b4026d5688..5eb930918186 100644 --- a/trunk/arch/sh/kernel/vmlinux.lds.S +++ b/trunk/arch/sh/kernel/vmlinux.lds.S @@ -76,7 +76,13 @@ SECTIONS __setup_end = .; __initcall_start = .; .initcall.init : { - INITCALLS + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) } __initcall_end = .; __con_initcall_start = .; diff --git a/trunk/arch/sh/mm/consistent.c b/trunk/arch/sh/mm/consistent.c index 38c82d890ffd..c81e6b67ad30 100644 --- a/trunk/arch/sh/mm/consistent.c +++ b/trunk/arch/sh/mm/consistent.c @@ -28,7 +28,6 @@ void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *handle) split_page(page, order); ret = page_address(page); - memset(ret, 0, size); *handle = virt_to_phys(ret); /* diff --git a/trunk/arch/sh64/kernel/vmlinux.lds.S b/trunk/arch/sh64/kernel/vmlinux.lds.S index 95c4d753e357..a8fcc3a71585 100644 --- a/trunk/arch/sh64/kernel/vmlinux.lds.S +++ b/trunk/arch/sh64/kernel/vmlinux.lds.S @@ -108,7 +108,13 @@ SECTIONS __setup_end = .; __initcall_start = .; .initcall.init : C_PHYS(.initcall.init) { - INITCALLS + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) } __initcall_end = .; __con_initcall_start = .; diff --git a/trunk/arch/sh64/lib/dbg.c b/trunk/arch/sh64/lib/dbg.c index 4310fc87444e..1326f45f31eb 100644 --- a/trunk/arch/sh64/lib/dbg.c +++ b/trunk/arch/sh64/lib/dbg.c @@ -383,7 +383,7 @@ void show_excp_regs(char *from, int trapnr, int signr, struct pt_regs *regs) /* ======================================================================= */ /* -** Depending on scan the MMU, Data or Instruction side +** Depending on scan the MMU, Data or Instrction side ** looking for a valid mapping matching Eaddr & asid. ** Return -1 if not found or the TLB id entry otherwise. ** Note: it works only for 4k pages! diff --git a/trunk/arch/sparc/Kconfig b/trunk/arch/sparc/Kconfig index 92a7c8a636d3..9431e967aa45 100644 --- a/trunk/arch/sparc/Kconfig +++ b/trunk/arch/sparc/Kconfig @@ -212,8 +212,8 @@ config SPARC_LED tristate "Sun4m LED driver" help This driver toggles the front-panel LED on sun4m systems - in a user-specifiable manner. Its state can be probed - by reading /proc/led and its blinking mode can be changed + in a user-specifyable manner. It's state can be probed + by reading /proc/led and it's blinking mode can be changed via writes to /proc/led source "fs/Kconfig.binfmt" @@ -289,13 +289,6 @@ endmenu source "fs/Kconfig" -menu "Instrumentation Support" - depends on EXPERIMENTAL - -source "arch/sparc/oprofile/Kconfig" - -endmenu - source "arch/sparc/Kconfig.debug" source "security/Kconfig" diff --git a/trunk/arch/sparc/Makefile b/trunk/arch/sparc/Makefile index f33c3817f014..4cdbb2d59ed0 100644 --- a/trunk/arch/sparc/Makefile +++ b/trunk/arch/sparc/Makefile @@ -30,8 +30,6 @@ HEAD_Y := $(head-y) core-y += arch/sparc/kernel/ arch/sparc/mm/ arch/sparc/math-emu/ libs-y += arch/sparc/prom/ arch/sparc/lib/ -drivers-$(CONFIG_OPROFILE) += arch/sparc/oprofile/ - # Export what is needed by arch/sparc/boot/Makefile # Renaming is done to avoid confusing pattern matching rules in 2.5.45 (multy-) INIT_Y := $(patsubst %/, %/built-in.o, $(init-y)) diff --git a/trunk/arch/sparc/kernel/ebus.c b/trunk/arch/sparc/kernel/ebus.c index ba58c3a061fd..75ac24d229b1 100644 --- a/trunk/arch/sparc/kernel/ebus.c +++ b/trunk/arch/sparc/kernel/ebus.c @@ -237,12 +237,12 @@ void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *d dev->ofdev.node = dp; dev->ofdev.dev.parent = &dev->bus->ofdev.dev; dev->ofdev.dev.bus = &ebus_bus_type; - sprintf(dev->ofdev.dev.bus_id, "ebus[%08x]", dp->node); + strcpy(dev->ofdev.dev.bus_id, dp->path_component_name); /* Register with core */ if (of_device_register(&dev->ofdev) != 0) printk(KERN_DEBUG "ebus: device registration error for %s!\n", - dp->path_component_name); + dev->ofdev.dev.bus_id); if ((dp = dp->child) != NULL) { dev->children = (struct linux_ebus_child *) @@ -332,12 +332,12 @@ void __init ebus_init(void) ebus->ofdev.node = dp; ebus->ofdev.dev.parent = &pdev->dev; ebus->ofdev.dev.bus = &ebus_bus_type; - sprintf(ebus->ofdev.dev.bus_id, "ebus%d", num_ebus); + strcpy(ebus->ofdev.dev.bus_id, dp->path_component_name); /* Register with core */ if (of_device_register(&ebus->ofdev) != 0) printk(KERN_DEBUG "ebus: device registration error for %s!\n", - dp->path_component_name); + ebus->ofdev.dev.bus_id); nd = dp->child; diff --git a/trunk/arch/sparc/kernel/entry.S b/trunk/arch/sparc/kernel/entry.S index 831f540251f8..a4edff4c3be3 100644 --- a/trunk/arch/sparc/kernel/entry.S +++ b/trunk/arch/sparc/kernel/entry.S @@ -32,12 +32,13 @@ #include #include #include -#include #include #define curptr g6 +#define NR_SYSCALLS 300 /* Each OS is different... */ + /* These are just handy. */ #define _SV save %sp, -STACKFRAME_SZ, %sp #define _RS restore diff --git a/trunk/arch/sparc/kernel/irq.c b/trunk/arch/sparc/kernel/irq.c index c8cb211b9072..72f0201051a0 100644 --- a/trunk/arch/sparc/kernel/irq.c +++ b/trunk/arch/sparc/kernel/irq.c @@ -46,7 +46,6 @@ #include #include #include -#include #ifdef CONFIG_SMP #define SMP_NOP2 "nop; nop;\n\t" @@ -134,8 +133,8 @@ static void irq_panic(void) prom_halt(); } -void (*sparc_init_timers)(irq_handler_t ) = - (void (*)(irq_handler_t )) irq_panic; +void (*sparc_init_timers)(irqreturn_t (*)(int, void *,struct pt_regs *)) = + (void (*)(irqreturn_t (*)(int, void *,struct pt_regs *))) irq_panic; /* * Dave Redman (djhr@tadpole.co.uk) @@ -320,14 +319,12 @@ void unexpected_irq(int irq, void *dev_id, struct pt_regs * regs) void handler_irq(int irq, struct pt_regs * regs) { - struct pt_regs *old_regs; struct irqaction * action; int cpu = smp_processor_id(); #ifdef CONFIG_SMP extern void smp4m_irq_rotate(int cpu); #endif - old_regs = set_irq_regs(regs); irq_enter(); disable_pil_irq(irq); #ifdef CONFIG_SMP @@ -341,31 +338,27 @@ void handler_irq(int irq, struct pt_regs * regs) do { if (!action || !action->handler) unexpected_irq(irq, NULL, regs); - action->handler(irq, action->dev_id); + action->handler(irq, action->dev_id, regs); action = action->next; } while (action); sparc_irq[irq].flags &= ~SPARC_IRQ_INPROGRESS; enable_pil_irq(irq); irq_exit(); - set_irq_regs(old_regs); } #ifdef CONFIG_BLK_DEV_FD -extern void floppy_interrupt(int irq, void *dev_id); +extern void floppy_interrupt(int irq, void *dev_id, struct pt_regs *regs); void sparc_floppy_irq(int irq, void *dev_id, struct pt_regs *regs) { - struct pt_regs *old_regs; int cpu = smp_processor_id(); - old_regs = set_irq_regs(regs); disable_pil_irq(irq); irq_enter(); kstat_cpu(cpu).irqs[irq]++; - floppy_interrupt(irq, dev_id); + floppy_interrupt(irq, dev_id, regs); irq_exit(); enable_pil_irq(irq); - set_irq_regs(old_regs); // XXX Eek, it's totally changed with preempt_count() and such // if (softirq_pending(cpu)) // do_softirq(); @@ -376,7 +369,7 @@ void sparc_floppy_irq(int irq, void *dev_id, struct pt_regs *regs) * thus no sharing possible. */ int request_fast_irq(unsigned int irq, - irq_handler_t handler, + irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long irqflags, const char *devname) { struct irqaction *action; @@ -475,7 +468,7 @@ int request_fast_irq(unsigned int irq, } int request_irq(unsigned int irq, - irq_handler_t handler, + irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long irqflags, const char * devname, void *dev_id) { struct irqaction * action, **actionp; @@ -485,7 +478,7 @@ int request_irq(unsigned int irq, if (sparc_cpu_model == sun4d) { extern int sun4d_request_irq(unsigned int, - irq_handler_t , + irqreturn_t (*)(int, void *, struct pt_regs *), unsigned long, const char *, void *); return sun4d_request_irq(irq, handler, irqflags, devname, dev_id); } diff --git a/trunk/arch/sparc/kernel/of_device.c b/trunk/arch/sparc/kernel/of_device.c index 46200c43ffb1..74bef2a2d37f 100644 --- a/trunk/arch/sparc/kernel/of_device.c +++ b/trunk/arch/sparc/kernel/of_device.c @@ -651,7 +651,7 @@ static struct of_device * __init scan_one_device(struct device_node *dp, if (!parent) strcpy(op->dev.bus_id, "root"); else - sprintf(op->dev.bus_id, "%08x", dp->node); + strcpy(op->dev.bus_id, dp->path_component_name); if (of_device_register(op)) { printk("%s: Could not register of device.\n", diff --git a/trunk/arch/sparc/kernel/pcic.c b/trunk/arch/sparc/kernel/pcic.c index 207f1b6eef53..edb6cc665f56 100644 --- a/trunk/arch/sparc/kernel/pcic.c +++ b/trunk/arch/sparc/kernel/pcic.c @@ -34,7 +34,6 @@ #include #include #include -#include unsigned int pcic_pin_to_irq(unsigned int pin, char *name); @@ -709,13 +708,13 @@ static void pcic_clear_clock_irq(void) pcic_timer_dummy = readl(pcic0.pcic_regs+PCI_SYS_LIMIT); } -static irqreturn_t pcic_timer_handler (int irq, void *h) +static irqreturn_t pcic_timer_handler (int irq, void *h, struct pt_regs *regs) { write_seqlock(&xtime_lock); /* Dummy, to show that we remember */ pcic_clear_clock_irq(); do_timer(1); #ifndef CONFIG_SMP - update_process_times(user_mode(get_irq_regs())); + update_process_times(user_mode(regs)); #endif write_sequnlock(&xtime_lock); return IRQ_HANDLED; diff --git a/trunk/arch/sparc/kernel/prom.c b/trunk/arch/sparc/kernel/prom.c index 2cc302b6bec0..4ca9e5fc97f4 100644 --- a/trunk/arch/sparc/kernel/prom.c +++ b/trunk/arch/sparc/kernel/prom.c @@ -243,7 +243,7 @@ int of_set_property(struct device_node *dp, const char *name, void *val, int len void *old_val = prop->value; int ret; - ret = prom_setprop(dp->node, (char *) name, val, len); + ret = prom_setprop(dp->node, name, val, len); err = -EINVAL; if (ret >= 0) { prop->value = new_val; @@ -477,10 +477,7 @@ static struct property * __init build_one_prop(phandle node, char *prev, char *s p->length = 0; } else { p->value = prom_early_alloc(p->length + 1); - len = prom_getproperty(node, p->name, p->value, - p->length); - if (len <= 0) - p->length = 0; + prom_getproperty(node, p->name, p->value, p->length); ((unsigned char *)p->value)[p->length] = '\0'; } } diff --git a/trunk/arch/sparc/kernel/setup.c b/trunk/arch/sparc/kernel/setup.c index 383526ad94fc..0251cab4708b 100644 --- a/trunk/arch/sparc/kernel/setup.c +++ b/trunk/arch/sparc/kernel/setup.c @@ -103,6 +103,7 @@ void prom_sync_me(void) unsigned int boot_flags __initdata = 0; #define BOOTME_DEBUG 0x1 +#define BOOTME_SINGLE 0x2 /* Exported for mm/init.c:paging_init. */ unsigned long cmdline_memory_size __initdata = 0; @@ -120,6 +121,16 @@ static struct console prom_debug_console = { .index = -1, }; +int obp_system_intr(void) +{ + if (boot_flags & BOOTME_DEBUG) { + printk("OBP: system interrupted\n"); + prom_halt(); + return 1; + } + return 0; +} + /* * Process kernel command line switches that are specific to the * SPARC or that require special low-level processing. @@ -131,6 +142,7 @@ static void __init process_switch(char c) boot_flags |= BOOTME_DEBUG; break; case 's': + boot_flags |= BOOTME_SINGLE; break; case 'h': prom_printf("boot_flags_init: Halt!\n"); diff --git a/trunk/arch/sparc/kernel/sparc_ksyms.c b/trunk/arch/sparc/kernel/sparc_ksyms.c index 33dadd9f2871..4d441a554d35 100644 --- a/trunk/arch/sparc/kernel/sparc_ksyms.c +++ b/trunk/arch/sparc/kernel/sparc_ksyms.c @@ -87,7 +87,6 @@ extern void ___set_bit(void); extern void ___clear_bit(void); extern void ___change_bit(void); extern void ___rw_read_enter(void); -extern void ___rw_read_try(void); extern void ___rw_read_exit(void); extern void ___rw_write_enter(void); @@ -105,9 +104,8 @@ extern unsigned _Urem(unsigned, unsigned); EXPORT_SYMBOL(sparc_cpu_model); EXPORT_SYMBOL(kernel_thread); #ifdef CONFIG_SMP -// XXX find what uses (or used) these. AV: see asm/spinlock.h +// XXX find what uses (or used) these. EXPORT_SYMBOL(___rw_read_enter); -EXPORT_SYMBOL(___rw_read_try); EXPORT_SYMBOL(___rw_read_exit); EXPORT_SYMBOL(___rw_write_enter); #endif diff --git a/trunk/arch/sparc/kernel/sun4c_irq.c b/trunk/arch/sparc/kernel/sun4c_irq.c index 009e891a4329..4be2c86ea540 100644 --- a/trunk/arch/sparc/kernel/sun4c_irq.c +++ b/trunk/arch/sparc/kernel/sun4c_irq.c @@ -154,7 +154,7 @@ static void sun4c_load_profile_irq(int cpu, unsigned int limit) /* Errm.. not sure how to do this.. */ } -static void __init sun4c_init_timers(irq_handler_t counter_fn) +static void __init sun4c_init_timers(irqreturn_t (*counter_fn)(int, void *, struct pt_regs *)) { int irq; diff --git a/trunk/arch/sparc/kernel/sun4d_irq.c b/trunk/arch/sparc/kernel/sun4d_irq.c index d4f9da8170c5..74eed9775ac0 100644 --- a/trunk/arch/sparc/kernel/sun4d_irq.c +++ b/trunk/arch/sparc/kernel/sun4d_irq.c @@ -38,7 +38,6 @@ #include #include #include -#include /* If you trust current SCSI layer to handle different SCSI IRQs, enable this. I don't trust it... -jj */ /* #define DISTRIBUTE_IRQS */ @@ -199,7 +198,6 @@ extern void unexpected_irq(int, void *, struct pt_regs *); void sun4d_handler_irq(int irq, struct pt_regs * regs) { - struct pt_regs *old_regs; struct irqaction * action; int cpu = smp_processor_id(); /* SBUS IRQ level (1 - 7) */ @@ -210,7 +208,6 @@ void sun4d_handler_irq(int irq, struct pt_regs * regs) cc_set_iclr(1 << irq); - old_regs = set_irq_regs(regs); irq_enter(); kstat_cpu(cpu).irqs[irq]++; if (!sbusl) { @@ -218,7 +215,7 @@ void sun4d_handler_irq(int irq, struct pt_regs * regs) if (!action) unexpected_irq(irq, NULL, regs); do { - action->handler(irq, action->dev_id); + action->handler(irq, action->dev_id, regs); action = action->next; } while (action); } else { @@ -245,7 +242,7 @@ void sun4d_handler_irq(int irq, struct pt_regs * regs) if (!action) unexpected_irq(irq, NULL, regs); do { - action->handler(irq, action->dev_id); + action->handler(irq, action->dev_id, regs); action = action->next; } while (action); release_sbi(SBI2DEVID(sbino), slot); @@ -253,7 +250,6 @@ void sun4d_handler_irq(int irq, struct pt_regs * regs) } } irq_exit(); - set_irq_regs(old_regs); } unsigned int sun4d_build_irq(struct sbus_dev *sdev, int irq) @@ -276,7 +272,7 @@ unsigned int sun4d_sbint_to_irq(struct sbus_dev *sdev, unsigned int sbint) } int sun4d_request_irq(unsigned int irq, - irq_handler_t handler, + irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long irqflags, const char * devname, void *dev_id) { struct irqaction *action, *tmp = NULL, **actionp; @@ -470,7 +466,7 @@ static void sun4d_load_profile_irq(int cpu, unsigned int limit) bw_set_prof_limit(cpu, limit); } -static void __init sun4d_init_timers(irq_handler_t counter_fn) +static void __init sun4d_init_timers(irqreturn_t (*counter_fn)(int, void *, struct pt_regs *)) { int irq; int cpu; diff --git a/trunk/arch/sparc/kernel/sun4d_smp.c b/trunk/arch/sparc/kernel/sun4d_smp.c index c80ea61e8ba0..3ff4edd32815 100644 --- a/trunk/arch/sparc/kernel/sun4d_smp.c +++ b/trunk/arch/sparc/kernel/sun4d_smp.c @@ -23,7 +23,6 @@ #include #include -#include #include #include @@ -370,12 +369,10 @@ void smp4d_message_pass(int target, int msg, unsigned long data, int wait) void smp4d_percpu_timer_interrupt(struct pt_regs *regs) { - struct pt_regs *old_regs; int cpu = hard_smp4d_processor_id(); static int cpu_tick[NR_CPUS]; static char led_mask[] = { 0xe, 0xd, 0xb, 0x7, 0xb, 0xd }; - old_regs = set_irq_regs(regs); bw_get_prof_limit(cpu); bw_clear_intr_mask(0, 1); /* INTR_TABLE[0] & 1 is Profile IRQ */ @@ -387,7 +384,7 @@ void smp4d_percpu_timer_interrupt(struct pt_regs *regs) show_leds(cpu); } - profile_tick(CPU_PROFILING); + profile_tick(CPU_PROFILING, regs); if(!--prof_counter(cpu)) { int user = user_mode(regs); @@ -398,7 +395,6 @@ void smp4d_percpu_timer_interrupt(struct pt_regs *regs) prof_counter(cpu) = prof_multiplier(cpu); } - set_irq_regs(old_regs); } extern unsigned int lvl14_resolution; diff --git a/trunk/arch/sparc/kernel/sun4m_irq.c b/trunk/arch/sparc/kernel/sun4m_irq.c index a654c16f4027..7cefa301efea 100644 --- a/trunk/arch/sparc/kernel/sun4m_irq.c +++ b/trunk/arch/sparc/kernel/sun4m_irq.c @@ -228,7 +228,7 @@ static void sun4m_load_profile_irq(int cpu, unsigned int limit) sun4m_timers->cpu_timers[cpu].l14_timer_limit = limit; } -static void __init sun4m_init_timers(irq_handler_t counter_fn) +static void __init sun4m_init_timers(irqreturn_t (*counter_fn)(int, void *, struct pt_regs *)) { int reg_count, irq, cpu; struct linux_prom_registers cnt_regs[PROMREG_MAX]; diff --git a/trunk/arch/sparc/kernel/sun4m_smp.c b/trunk/arch/sparc/kernel/sun4m_smp.c index e2d9c018bd56..7d4a649138f6 100644 --- a/trunk/arch/sparc/kernel/sun4m_smp.c +++ b/trunk/arch/sparc/kernel/sun4m_smp.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include @@ -354,14 +353,11 @@ void smp4m_cross_call_irq(void) void smp4m_percpu_timer_interrupt(struct pt_regs *regs) { - struct pt_regs *old_regs; int cpu = smp_processor_id(); - old_regs = set_irq_regs(regs); - clear_profile_irq(cpu); - profile_tick(CPU_PROFILING); + profile_tick(CPU_PROFILING, regs); if(!--prof_counter(cpu)) { int user = user_mode(regs); @@ -372,7 +368,6 @@ void smp4m_percpu_timer_interrupt(struct pt_regs *regs) prof_counter(cpu) = prof_multiplier(cpu); } - set_irq_regs(old_regs); } extern unsigned int lvl14_resolution; diff --git a/trunk/arch/sparc/kernel/systbls.S b/trunk/arch/sparc/kernel/systbls.S index ea75ca569052..10df38eeae08 100644 --- a/trunk/arch/sparc/kernel/systbls.S +++ b/trunk/arch/sparc/kernel/systbls.S @@ -78,7 +78,7 @@ sys_call_table: /*285*/ .long sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, sys_fstatat64 /*290*/ .long sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat /*295*/ .long sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare -/*300*/ .long sys_set_robust_list, sys_get_robust_list, sys_migrate_pages +/*300*/ .long sys_set_robust_list, sys_get_robust_list #ifdef CONFIG_SUNOS_EMUL /* Now the SunOS syscall table. */ @@ -190,7 +190,6 @@ sunos_sys_table: /*290*/ .long sunos_nosys, sunos_nosys, sunos_nosys .long sunos_nosys, sunos_nosys, sunos_nosys .long sunos_nosys, sunos_nosys, sunos_nosys - .long sunos_nosys -/*300*/ .long sunos_nosys, sunos_nosys, sunos_nosys + .long sunos_nosys, sunos_nosys, sunos_nosys #endif diff --git a/trunk/arch/sparc/kernel/tick14.c b/trunk/arch/sparc/kernel/tick14.c index f1a7bd19e04f..d3b4daac705f 100644 --- a/trunk/arch/sparc/kernel/tick14.c +++ b/trunk/arch/sparc/kernel/tick14.c @@ -55,7 +55,7 @@ void install_obp_ticker(void) linux_lvl14[3] = obp_lvl14[3]; } -void claim_ticker14(irq_handler_t handler, +void claim_ticker14(irqreturn_t (*handler)(int, void *, struct pt_regs *), int irq_nr, unsigned int timeout ) { int cpu = smp_processor_id(); diff --git a/trunk/arch/sparc/kernel/time.c b/trunk/arch/sparc/kernel/time.c index 6c7aa51b590f..e10dc831944d 100644 --- a/trunk/arch/sparc/kernel/time.c +++ b/trunk/arch/sparc/kernel/time.c @@ -42,7 +42,6 @@ #include #include #include -#include DEFINE_SPINLOCK(rtc_lock); enum sparc_clock_type sp_clock_typ; @@ -95,8 +94,6 @@ unsigned long profile_pc(struct pt_regs *regs) return pc; } -EXPORT_SYMBOL(profile_pc); - __volatile__ unsigned int *master_l10_counter; __volatile__ unsigned int *master_l10_limit; @@ -107,13 +104,13 @@ __volatile__ unsigned int *master_l10_limit; #define TICK_SIZE (tick_nsec / 1000) -irqreturn_t timer_interrupt(int irq, void *dev_id) +irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs * regs) { /* last time the cmos clock got updated */ static long last_rtc_update; #ifndef CONFIG_SMP - profile_tick(CPU_PROFILING); + profile_tick(CPU_PROFILING, regs); #endif /* Protect counter clear so that do_gettimeoffset works */ @@ -131,7 +128,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id) do_timer(1); #ifndef CONFIG_SMP - update_process_times(user_mode(get_irq_regs())); + update_process_times(user_mode(regs)); #endif diff --git a/trunk/arch/sparc/kernel/vmlinux.lds.S b/trunk/arch/sparc/kernel/vmlinux.lds.S index 5cc5ff7f8824..346c19a949fd 100644 --- a/trunk/arch/sparc/kernel/vmlinux.lds.S +++ b/trunk/arch/sparc/kernel/vmlinux.lds.S @@ -36,11 +36,11 @@ SECTIONS . = ALIGN(4096); __init_begin = .; - _sinittext = .; .init.text : { + _sinittext = .; *(.init.text) + _einittext = .; } - _einittext = .; __init_text_end = .; .init.data : { *(.init.data) } . = ALIGN(16); @@ -49,7 +49,13 @@ SECTIONS __setup_end = .; __initcall_start = .; .initcall.init : { - INITCALLS + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) } __initcall_end = .; __con_initcall_start = .; diff --git a/trunk/arch/sparc/lib/locks.S b/trunk/arch/sparc/lib/locks.S index b1df55cb2215..95fa48424967 100644 --- a/trunk/arch/sparc/lib/locks.S +++ b/trunk/arch/sparc/lib/locks.S @@ -25,15 +25,6 @@ ___rw_read_enter_spin_on_wlock: ldstub [%g1 + 3], %g2 b ___rw_read_enter_spin_on_wlock ldub [%g1 + 3], %g2 -___rw_read_try_spin_on_wlock: - andcc %g2, 0xff, %g0 - be,a ___rw_read_try - ldstub [%g1 + 3], %g2 - xnorcc %g2, 0x0, %o0 /* if g2 is ~0, set o0 to 0 and bugger off */ - bne,a ___rw_read_enter_spin_on_wlock - ld [%g1], %g2 - retl - mov %g4, %o7 ___rw_read_exit_spin_on_wlock: orcc %g2, 0x0, %g0 be,a ___rw_read_exit @@ -69,17 +60,6 @@ ___rw_read_exit: retl mov %g4, %o7 - .globl ___rw_read_try -___rw_read_try: - orcc %g2, 0x0, %g0 - bne ___rw_read_try_spin_on_wlock - ld [%g1], %g2 - add %g2, 1, %g2 - st %g2, [%g1] - set 1, %o1 - retl - mov %g4, %o7 - .globl ___rw_write_enter ___rw_write_enter: orcc %g2, 0x0, %g0 diff --git a/trunk/arch/sparc/mm/srmmu.c b/trunk/arch/sparc/mm/srmmu.c index 0df7121cef07..b27a506309ee 100644 --- a/trunk/arch/sparc/mm/srmmu.c +++ b/trunk/arch/sparc/mm/srmmu.c @@ -402,7 +402,7 @@ void srmmu_nocache_calcsize(void) srmmu_nocache_end = SRMMU_NOCACHE_VADDR + srmmu_nocache_size; } -void __init srmmu_nocache_init(void) +void srmmu_nocache_init(void) { unsigned int bitmap_bits; pgd_t *pgd; diff --git a/trunk/arch/sparc/oprofile/Kconfig b/trunk/arch/sparc/oprofile/Kconfig deleted file mode 100644 index d8a84088471a..000000000000 --- a/trunk/arch/sparc/oprofile/Kconfig +++ /dev/null @@ -1,17 +0,0 @@ -config PROFILING - bool "Profiling support (EXPERIMENTAL)" - help - Say Y here to enable the extended profiling support mechanisms used - by profilers such as OProfile. - - -config OPROFILE - tristate "OProfile system profiling (EXPERIMENTAL)" - depends on PROFILING - help - OProfile is a profiling system capable of profiling the - whole system, include the kernel, kernel modules, libraries, - and applications. - - If unsure, say N. - diff --git a/trunk/arch/sparc/oprofile/Makefile b/trunk/arch/sparc/oprofile/Makefile deleted file mode 100644 index e9feca1ca28b..000000000000 --- a/trunk/arch/sparc/oprofile/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -obj-$(CONFIG_OPROFILE) += oprofile.o - -DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ - oprof.o cpu_buffer.o buffer_sync.o \ - event_buffer.o oprofile_files.o \ - oprofilefs.o oprofile_stats.o \ - timer_int.o ) - -oprofile-y := $(DRIVER_OBJS) init.o diff --git a/trunk/arch/sparc/oprofile/init.c b/trunk/arch/sparc/oprofile/init.c deleted file mode 100644 index 9ab815b95b5a..000000000000 --- a/trunk/arch/sparc/oprofile/init.c +++ /dev/null @@ -1,23 +0,0 @@ -/** - * @file init.c - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - */ - -#include -#include -#include -#include - -int __init oprofile_arch_init(struct oprofile_operations * ops) -{ - return -ENODEV; -} - - -void oprofile_arch_exit(void) -{ -} diff --git a/trunk/arch/sparc64/defconfig b/trunk/arch/sparc64/defconfig index 2f4612fa81f2..f54ab375464b 100644 --- a/trunk/arch/sparc64/defconfig +++ b/trunk/arch/sparc64/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.19-rc2 -# Tue Oct 17 19:29:20 2006 +# Linux kernel version: 2.6.18 +# Mon Oct 2 14:24:40 2006 # CONFIG_SPARC=y CONFIG_SPARC64=y @@ -197,7 +197,6 @@ CONFIG_INET_XFRM_TUNNEL=y CONFIG_INET_TUNNEL=y CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=y CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set @@ -215,9 +214,7 @@ CONFIG_INET6_XFRM_TUNNEL=m CONFIG_INET6_TUNNEL=m CONFIG_INET6_XFRM_MODE_TRANSPORT=m CONFIG_INET6_XFRM_MODE_TUNNEL=m -CONFIG_INET6_XFRM_MODE_BEET=m # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set -CONFIG_IPV6_SIT=m CONFIG_IPV6_TUNNEL=m # CONFIG_IPV6_SUBTREES is not set # CONFIG_IPV6_MULTIPLE_TABLES is not set @@ -334,12 +331,6 @@ CONFIG_CDROM_PKTCDVD_BUFFERS=8 CONFIG_CDROM_PKTCDVD_WCACHE=y CONFIG_ATA_OVER_ETH=m -# -# Misc devices -# -# CONFIG_SGI_IOC4 is not set -# CONFIG_TIFM_CORE is not set - # # ATA/ATAPI/MFM/RLL support # @@ -382,7 +373,6 @@ CONFIG_BLK_DEV_ALI15X3=y # CONFIG_BLK_DEV_CS5530 is not set # CONFIG_BLK_DEV_HPT34X is not set # CONFIG_BLK_DEV_HPT366 is not set -# CONFIG_BLK_DEV_JMICRON is not set # CONFIG_BLK_DEV_SC1200 is not set # CONFIG_BLK_DEV_PIIX is not set # CONFIG_BLK_DEV_IT821X is not set @@ -459,10 +449,10 @@ CONFIG_ISCSI_TCP=m # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_STEX is not set # CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set # CONFIG_SCSI_QLOGIC_1280 is not set # CONFIG_SCSI_QLOGICPTI is not set # CONFIG_SCSI_QLA_FC is not set -# CONFIG_SCSI_QLA_ISCSI is not set # CONFIG_SCSI_LPFC is not set # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set @@ -488,7 +478,6 @@ CONFIG_MD_RAID456=m CONFIG_MD_MULTIPATH=m # CONFIG_MD_FAULTY is not set CONFIG_BLK_DEV_DM=m -# CONFIG_DM_DEBUG is not set CONFIG_DM_CRYPT=m CONFIG_DM_SNAPSHOT=m CONFIG_DM_MIRROR=m @@ -735,6 +724,7 @@ CONFIG_RTC=y # TPM devices # # CONFIG_TCG_TPM is not set +# CONFIG_TELCLOCK is not set # # I2C support @@ -847,10 +837,15 @@ CONFIG_HWMON=y # CONFIG_SENSORS_W83627EHF is not set # CONFIG_HWMON_DEBUG_CHIP is not set +# +# Misc devices +# + # # Multimedia devices # # CONFIG_VIDEO_DEV is not set +CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices @@ -863,7 +858,6 @@ CONFIG_HWMON=y # # CONFIG_FIRMWARE_EDID is not set CONFIG_FB=y -CONFIG_FB_DDC=y CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y @@ -1105,6 +1099,7 @@ CONFIG_USB_HIDDEV=y # CONFIG_USB_ATI_REMOTE2 is not set # CONFIG_USB_KEYSPAN_REMOTE is not set # CONFIG_USB_APPLETOUCH is not set +# CONFIG_USB_TRANCEVIBRATOR is not set # # USB Imaging devices @@ -1150,7 +1145,6 @@ CONFIG_USB_HIDDEV=y # CONFIG_USB_APPLEDISPLAY is not set # CONFIG_USB_SISUSBVGA is not set # CONFIG_USB_LD is not set -# CONFIG_USB_TRANCEVIBRATOR is not set # CONFIG_USB_TEST is not set # @@ -1235,7 +1229,6 @@ CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y CONFIG_EXT3_FS_POSIX_ACL=y CONFIG_EXT3_FS_SECURITY=y -# CONFIG_EXT4DEV_FS is not set CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set CONFIG_FS_MBCACHE=y @@ -1243,7 +1236,6 @@ CONFIG_FS_MBCACHE=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set @@ -1287,7 +1279,6 @@ CONFIG_RAMFS=y # # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set -# CONFIG_ECRYPT_FS is not set # CONFIG_HFS_FS is not set # CONFIG_HFSPLUS_FS is not set # CONFIG_BEFS_FS is not set @@ -1397,7 +1388,6 @@ CONFIG_DEBUG_FS=y # CONFIG_DEBUG_LIST is not set # CONFIG_UNWIND_INFO is not set CONFIG_FORCED_INLINING=y -# CONFIG_HEADERS_CHECK is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_LKDTM is not set # CONFIG_DEBUG_STACK_USAGE is not set diff --git a/trunk/arch/sparc64/kernel/central.c b/trunk/arch/sparc64/kernel/central.c index e724c54af029..b66336db00ee 100644 --- a/trunk/arch/sparc64/kernel/central.c +++ b/trunk/arch/sparc64/kernel/central.c @@ -126,10 +126,6 @@ static void probe_other_fhcs(void) int board; u32 tmp; - if (dp->parent && - dp->parent->parent != NULL) - continue; - fhc = (struct linux_fhc *) central_alloc_bootmem(sizeof(struct linux_fhc)); if (fhc == NULL) diff --git a/trunk/arch/sparc64/kernel/ebus.c b/trunk/arch/sparc64/kernel/ebus.c index 35bf895fdeee..8a9b470e1b65 100644 --- a/trunk/arch/sparc64/kernel/ebus.c +++ b/trunk/arch/sparc64/kernel/ebus.c @@ -79,7 +79,7 @@ static void __ebus_dma_reset(struct ebus_dma_info *p, int no_drain) } } -static irqreturn_t ebus_dma_irq(int irq, void *dev_id) +static irqreturn_t ebus_dma_irq(int irq, void *dev_id, struct pt_regs *regs) { struct ebus_dma_info *p = dev_id; unsigned long flags; @@ -389,12 +389,12 @@ static void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_de dev->ofdev.node = dp; dev->ofdev.dev.parent = &dev->bus->ofdev.dev; dev->ofdev.dev.bus = &ebus_bus_type; - sprintf(dev->ofdev.dev.bus_id, "ebus[%08x]", dp->node); + strcpy(dev->ofdev.dev.bus_id, dp->path_component_name); /* Register with core */ if (of_device_register(&dev->ofdev) != 0) printk(KERN_DEBUG "ebus: device registration error for %s!\n", - dp->path_component_name); + dev->ofdev.dev.bus_id); dp = dp->child; if (dp) { @@ -494,12 +494,12 @@ void __init ebus_init(void) ebus->ofdev.node = dp; ebus->ofdev.dev.parent = &pdev->dev; ebus->ofdev.dev.bus = &ebus_bus_type; - sprintf(ebus->ofdev.dev.bus_id, "ebus%d", num_ebus); + strcpy(ebus->ofdev.dev.bus_id, dp->path_component_name); /* Register with core */ if (of_device_register(&ebus->ofdev) != 0) printk(KERN_DEBUG "ebus: device registration error for %s!\n", - dp->path_component_name); + ebus->ofdev.dev.bus_id); child = dp->child; diff --git a/trunk/arch/sparc64/kernel/entry.S b/trunk/arch/sparc64/kernel/entry.S index 6f28bec0a9bf..0aaa35fc5a9c 100644 --- a/trunk/arch/sparc64/kernel/entry.S +++ b/trunk/arch/sparc64/kernel/entry.S @@ -22,10 +22,11 @@ #include #include #include -#include #define curptr g6 +#define NR_SYSCALLS 300 /* Each OS is different... */ + .text .align 32 diff --git a/trunk/arch/sparc64/kernel/irq.c b/trunk/arch/sparc64/kernel/irq.c index d64b1ea848de..4e64724cb9ae 100644 --- a/trunk/arch/sparc64/kernel/irq.c +++ b/trunk/arch/sparc64/kernel/irq.c @@ -522,13 +522,12 @@ void ack_bad_irq(unsigned int virt_irq) } #ifndef CONFIG_SMP -extern irqreturn_t timer_interrupt(int, void *); +extern irqreturn_t timer_interrupt(int, void *, struct pt_regs *); void timer_irq(int irq, struct pt_regs *regs) { unsigned long clr_mask = 1 << irq; unsigned long tick_mask = tick_ops->softint_mask; - struct pt_regs *old_regs; if (get_softint() & tick_mask) { irq = 0; @@ -536,25 +535,21 @@ void timer_irq(int irq, struct pt_regs *regs) } clear_softint(clr_mask); - old_regs = set_irq_regs(regs); irq_enter(); kstat_this_cpu.irqs[0]++; - timer_interrupt(irq, NULL); + timer_interrupt(irq, NULL, regs); irq_exit(); - set_irq_regs(old_regs); } #endif void handler_irq(int irq, struct pt_regs *regs) { struct ino_bucket *bucket; - struct pt_regs *old_regs; clear_softint(1 << irq); - old_regs = set_irq_regs(regs); irq_enter(); /* Sliiiick... */ @@ -563,13 +558,12 @@ void handler_irq(int irq, struct pt_regs *regs) struct ino_bucket *next = __bucket(bucket->irq_chain); bucket->irq_chain = 0; - __do_IRQ(bucket->virt_irq); + __do_IRQ(bucket->virt_irq, regs); bucket = next; } irq_exit(); - set_irq_regs(old_regs); } struct sun5_timer { diff --git a/trunk/arch/sparc64/kernel/isa.c b/trunk/arch/sparc64/kernel/isa.c index f028e68b23f2..0f3aec72ef5f 100644 --- a/trunk/arch/sparc64/kernel/isa.c +++ b/trunk/arch/sparc64/kernel/isa.c @@ -115,12 +115,12 @@ static void __init isa_fill_devices(struct sparc_isa_bridge *isa_br) isa_dev->ofdev.node = dp; isa_dev->ofdev.dev.parent = &isa_br->ofdev.dev; isa_dev->ofdev.dev.bus = &isa_bus_type; - sprintf(isa_dev->ofdev.dev.bus_id, "isa[%08x]", dp->node); + strcpy(isa_dev->ofdev.dev.bus_id, dp->path_component_name); /* Register with core */ if (of_device_register(&isa_dev->ofdev) != 0) { printk(KERN_DEBUG "isa: device registration error for %s!\n", - dp->path_component_name); + isa_dev->ofdev.dev.bus_id); kfree(isa_dev); goto next_sibling; } @@ -191,12 +191,12 @@ void __init isa_init(void) isa_br->ofdev.node = dp; isa_br->ofdev.dev.parent = &pdev->dev; isa_br->ofdev.dev.bus = &isa_bus_type; - sprintf(isa_br->ofdev.dev.bus_id, "isa%d", index); + strcpy(isa_br->ofdev.dev.bus_id, dp->path_component_name); /* Register with core */ if (of_device_register(&isa_br->ofdev) != 0) { printk(KERN_DEBUG "isa: device registration error for %s!\n", - dp->path_component_name); + isa_br->ofdev.dev.bus_id); kfree(isa_br); return; } diff --git a/trunk/arch/sparc64/kernel/of_device.c b/trunk/arch/sparc64/kernel/of_device.c index 8cc14fc6b6f1..7f9204535770 100644 --- a/trunk/arch/sparc64/kernel/of_device.c +++ b/trunk/arch/sparc64/kernel/of_device.c @@ -131,13 +131,8 @@ static int of_device_resume(struct device * dev) void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name) { unsigned long ret = res->start + offset; - struct resource *r; - if (res->flags & IORESOURCE_MEM) - r = request_mem_region(ret, size, name); - else - r = request_region(ret, size, name); - if (!r) + if (!request_region(ret, size, name)) ret = 0; return (void __iomem *) ret; @@ -402,22 +397,16 @@ static void of_bus_sbus_count_cells(struct device_node *child, *sizec = 1; } -/* - * FHC/Central bus specific translator. - * - * This is just needed to hard-code the address and size cell - * counts. 'fhc' and 'central' nodes lack the #address-cells and - * #size-cells properties, and if you walk to the root on such - * Enterprise boxes all you'll get is a #size-cells of 2 which is - * not what we want to use. - */ -static int of_bus_fhc_match(struct device_node *np) +static int of_bus_sbus_map(u32 *addr, const u32 *range, int na, int ns, int pna) { - return !strcmp(np->name, "fhc") || - !strcmp(np->name, "central"); + return of_bus_default_map(addr, range, na, ns, pna); +} + +static unsigned int of_bus_sbus_get_flags(u32 *addr) +{ + return IORESOURCE_MEM; } -#define of_bus_fhc_count_cells of_bus_sbus_count_cells /* * Array of bus specific translators @@ -439,17 +428,8 @@ static struct of_bus of_busses[] = { .addr_prop_name = "reg", .match = of_bus_sbus_match, .count_cells = of_bus_sbus_count_cells, - .map = of_bus_default_map, - .get_flags = of_bus_default_get_flags, - }, - /* FHC */ - { - .name = "fhc", - .addr_prop_name = "reg", - .match = of_bus_fhc_match, - .count_cells = of_bus_fhc_count_cells, - .map = of_bus_default_map, - .get_flags = of_bus_default_get_flags, + .map = of_bus_sbus_map, + .get_flags = of_bus_sbus_get_flags, }, /* Default */ { @@ -861,7 +841,7 @@ static struct of_device * __init scan_one_device(struct device_node *dp, if (!parent) strcpy(op->dev.bus_id, "root"); else - sprintf(op->dev.bus_id, "%08x", dp->node); + strcpy(op->dev.bus_id, dp->path_component_name); if (of_device_register(op)) { printk("%s: Could not register of device.\n", diff --git a/trunk/arch/sparc64/kernel/pci.c b/trunk/arch/sparc64/kernel/pci.c index dfc41cd4bb5d..e02f01b644af 100644 --- a/trunk/arch/sparc64/kernel/pci.c +++ b/trunk/arch/sparc64/kernel/pci.c @@ -646,4 +646,13 @@ int pci_domain_nr(struct pci_bus *pbus) } EXPORT_SYMBOL(pci_domain_nr); +int pcibios_prep_mwi(struct pci_dev *dev) +{ + /* We set correct PCI_CACHE_LINE_SIZE register values for every + * device probed on this platform. So there is nothing to check + * and this always succeeds. + */ + return 0; +} + #endif /* !(CONFIG_PCI) */ diff --git a/trunk/arch/sparc64/kernel/pci_common.c b/trunk/arch/sparc64/kernel/pci_common.c index 827ae30aa497..7a59cc72c844 100644 --- a/trunk/arch/sparc64/kernel/pci_common.c +++ b/trunk/arch/sparc64/kernel/pci_common.c @@ -330,6 +330,19 @@ __init get_device_resource(struct linux_prom_pci_registers *ap, return res; } +static int __init pdev_resource_collisions_expected(struct pci_dev *pdev) +{ + if (pdev->vendor != PCI_VENDOR_ID_SUN) + return 0; + + if (pdev->device == PCI_DEVICE_ID_SUN_RIO_EBUS || + pdev->device == PCI_DEVICE_ID_SUN_RIO_1394 || + pdev->device == PCI_DEVICE_ID_SUN_RIO_USB) + return 1; + + return 0; +} + static void __init pdev_record_assignments(struct pci_pbm_info *pbm, struct pci_dev *pdev) { @@ -387,23 +400,19 @@ static void __init pdev_record_assignments(struct pci_pbm_info *pbm, pbm->parent->resource_adjust(pdev, res, root); if (request_resource(root, res) < 0) { - int rnum; - /* OK, there is some conflict. But this is fine * since we'll reassign it in the fixup pass. * - * Do not print the warning for ROM resources - * as such a conflict is quite common and - * harmless as the ROM bar is disabled. + * We notify the user that OBP made an error if it + * is a case we don't expect. */ - rnum = (res - &pdev->resource[0]); - if (rnum != PCI_ROM_RESOURCE) - printk(KERN_ERR "PCI: Resource collision, " - "region %d " + if (!pdev_resource_collisions_expected(pdev)) { + printk(KERN_ERR "PCI: Address space collision on region %ld " "[%016lx:%016lx] of device %s\n", - rnum, + (res - &pdev->resource[0]), res->start, res->end, pci_name(pdev)); + } } } } diff --git a/trunk/arch/sparc64/kernel/pci_iommu.c b/trunk/arch/sparc64/kernel/pci_iommu.c index 2e7f1427088a..82e5455134c6 100644 --- a/trunk/arch/sparc64/kernel/pci_iommu.c +++ b/trunk/arch/sparc64/kernel/pci_iommu.c @@ -281,7 +281,7 @@ static void pci_4u_free_consistent(struct pci_dev *pdev, size_t size, void *cpu, spin_lock_irqsave(&iommu->lock, flags); - free_npages(iommu, dvma - iommu->page_table_map_base, npages); + free_npages(iommu, dvma, npages); spin_unlock_irqrestore(&iommu->lock, flags); diff --git a/trunk/arch/sparc64/kernel/pci_psycho.c b/trunk/arch/sparc64/kernel/pci_psycho.c index fda5db223d96..1ec0aab68c08 100644 --- a/trunk/arch/sparc64/kernel/pci_psycho.c +++ b/trunk/arch/sparc64/kernel/pci_psycho.c @@ -533,7 +533,7 @@ static void psycho_check_iommu_error(struct pci_controller_info *p, #define PSYCHO_UEAFSR_RESV2 0x00000000007fffffUL /* Reserved */ #define PSYCHO_UE_AFAR 0x0038UL -static irqreturn_t psycho_ue_intr(int irq, void *dev_id) +static irqreturn_t psycho_ue_intr(int irq, void *dev_id, struct pt_regs *regs) { struct pci_controller_info *p = dev_id; unsigned long afsr_reg = p->pbm_A.controller_regs + PSYCHO_UE_AFSR; @@ -610,7 +610,7 @@ static irqreturn_t psycho_ue_intr(int irq, void *dev_id) #define PSYCHO_CEAFSR_RESV2 0x00000000007fffffUL /* Reserved */ #define PSYCHO_CE_AFAR 0x0040UL -static irqreturn_t psycho_ce_intr(int irq, void *dev_id) +static irqreturn_t psycho_ce_intr(int irq, void *dev_id, struct pt_regs *regs) { struct pci_controller_info *p = dev_id; unsigned long afsr_reg = p->pbm_A.controller_regs + PSYCHO_CE_AFSR; @@ -735,7 +735,7 @@ static irqreturn_t psycho_pcierr_intr_other(struct pci_pbm_info *pbm, int is_pbm return ret; } -static irqreturn_t psycho_pcierr_intr(int irq, void *dev_id) +static irqreturn_t psycho_pcierr_intr(int irq, void *dev_id, struct pt_regs *regs) { struct pci_pbm_info *pbm = dev_id; struct pci_controller_info *p = pbm->parent; diff --git a/trunk/arch/sparc64/kernel/pci_sabre.c b/trunk/arch/sparc64/kernel/pci_sabre.c index 94bb681f2323..45891850b90d 100644 --- a/trunk/arch/sparc64/kernel/pci_sabre.c +++ b/trunk/arch/sparc64/kernel/pci_sabre.c @@ -574,7 +574,7 @@ static void sabre_check_iommu_error(struct pci_controller_info *p, spin_unlock_irqrestore(&iommu->lock, flags); } -static irqreturn_t sabre_ue_intr(int irq, void *dev_id) +static irqreturn_t sabre_ue_intr(int irq, void *dev_id, struct pt_regs *regs) { struct pci_controller_info *p = dev_id; unsigned long afsr_reg = p->pbm_A.controller_regs + SABRE_UE_AFSR; @@ -634,7 +634,7 @@ static irqreturn_t sabre_ue_intr(int irq, void *dev_id) return IRQ_HANDLED; } -static irqreturn_t sabre_ce_intr(int irq, void *dev_id) +static irqreturn_t sabre_ce_intr(int irq, void *dev_id, struct pt_regs *regs) { struct pci_controller_info *p = dev_id; unsigned long afsr_reg = p->pbm_A.controller_regs + SABRE_CE_AFSR; @@ -726,7 +726,7 @@ static irqreturn_t sabre_pcierr_intr_other(struct pci_controller_info *p) return ret; } -static irqreturn_t sabre_pcierr_intr(int irq, void *dev_id) +static irqreturn_t sabre_pcierr_intr(int irq, void *dev_id, struct pt_regs *regs) { struct pci_controller_info *p = dev_id; unsigned long afsr_reg, afar_reg; @@ -1196,7 +1196,7 @@ static void pbm_register_toplevel_resources(struct pci_controller_info *p, &pbm->mem_space); } -static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp, u32 dma_start, u32 dma_end) +static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp, u32 dma_begin) { struct pci_pbm_info *pbm; struct device_node *node; @@ -1261,8 +1261,6 @@ static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp node = node->sibling; } if (simbas_found == 0) { - struct resource *rp; - /* No APBs underneath, probably this is a hummingbird * system. */ @@ -1304,10 +1302,8 @@ static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp pbm->io_space.end = pbm->io_space.start + (1UL << 24) - 1UL; pbm->io_space.flags = IORESOURCE_IO; - pbm->mem_space.start = - (p->pbm_A.controller_regs + SABRE_MEMSPACE); - pbm->mem_space.end = - (pbm->mem_space.start + ((1UL << 32UL) - 1UL)); + pbm->mem_space.start = p->pbm_A.controller_regs + SABRE_MEMSPACE; + pbm->mem_space.end = pbm->mem_space.start + (unsigned long)dma_begin - 1UL; pbm->mem_space.flags = IORESOURCE_MEM; if (request_resource(&ioport_resource, &pbm->io_space) < 0) { @@ -1319,17 +1315,6 @@ static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp prom_halt(); } - rp = kmalloc(sizeof(*rp), GFP_KERNEL); - if (!rp) { - prom_printf("Cannot allocate IOMMU resource.\n"); - prom_halt(); - } - rp->name = "IOMMU"; - rp->start = pbm->mem_space.start + (unsigned long) dma_start; - rp->end = pbm->mem_space.start + (unsigned long) dma_end - 1UL; - rp->flags = IORESOURCE_BUSY; - request_resource(&pbm->mem_space, rp); - pci_register_legacy_regions(&pbm->io_space, &pbm->mem_space); } @@ -1465,5 +1450,5 @@ void sabre_init(struct device_node *dp, char *model_name) /* * Look for APB underneath. */ - sabre_pbm_init(p, dp, vdma[0], vdma[0] + vdma[1]); + sabre_pbm_init(p, dp, vdma[0]); } diff --git a/trunk/arch/sparc64/kernel/pci_schizo.c b/trunk/arch/sparc64/kernel/pci_schizo.c index 66911b126aed..75ade83ecc65 100644 --- a/trunk/arch/sparc64/kernel/pci_schizo.c +++ b/trunk/arch/sparc64/kernel/pci_schizo.c @@ -515,7 +515,7 @@ static void schizo_check_iommu_error(struct pci_controller_info *p, #define SCHIZO_UEAFSR_MTAG 0x000000000000e000UL /* Safari */ #define SCHIZO_UEAFSR_ECCSYND 0x00000000000001ffUL /* Safari */ -static irqreturn_t schizo_ue_intr(int irq, void *dev_id) +static irqreturn_t schizo_ue_intr(int irq, void *dev_id, struct pt_regs *regs) { struct pci_controller_info *p = dev_id; unsigned long afsr_reg = p->pbm_B.controller_regs + SCHIZO_UE_AFSR; @@ -603,7 +603,7 @@ static irqreturn_t schizo_ue_intr(int irq, void *dev_id) #define SCHIZO_CEAFSR_MTAG 0x000000000000e000UL #define SCHIZO_CEAFSR_ECCSYND 0x00000000000001ffUL -static irqreturn_t schizo_ce_intr(int irq, void *dev_id) +static irqreturn_t schizo_ce_intr(int irq, void *dev_id, struct pt_regs *regs) { struct pci_controller_info *p = dev_id; unsigned long afsr_reg = p->pbm_B.controller_regs + SCHIZO_CE_AFSR; @@ -778,7 +778,7 @@ static irqreturn_t schizo_pcierr_intr_other(struct pci_pbm_info *pbm) return ret; } -static irqreturn_t schizo_pcierr_intr(int irq, void *dev_id) +static irqreturn_t schizo_pcierr_intr(int irq, void *dev_id, struct pt_regs *regs) { struct pci_pbm_info *pbm = dev_id; struct pci_controller_info *p = pbm->parent; @@ -933,7 +933,7 @@ static irqreturn_t schizo_pcierr_intr(int irq, void *dev_id) /* We only expect UNMAP errors here. The rest of the Safari errors * are marked fatal and thus cause a system reset. */ -static irqreturn_t schizo_safarierr_intr(int irq, void *dev_id) +static irqreturn_t schizo_safarierr_intr(int irq, void *dev_id, struct pt_regs *regs) { struct pci_controller_info *p = dev_id; u64 errlog; diff --git a/trunk/arch/sparc64/kernel/power.c b/trunk/arch/sparc64/kernel/power.c index 699b24b890df..0b9c70627ce4 100644 --- a/trunk/arch/sparc64/kernel/power.c +++ b/trunk/arch/sparc64/kernel/power.c @@ -35,7 +35,7 @@ static void __iomem *power_reg; static DECLARE_WAIT_QUEUE_HEAD(powerd_wait); static int button_pressed; -static irqreturn_t power_handler(int irq, void *dev_id) +static irqreturn_t power_handler(int irq, void *dev_id, struct pt_regs *regs) { if (button_pressed == 0) { button_pressed = 1; diff --git a/trunk/arch/sparc64/kernel/prom.c b/trunk/arch/sparc64/kernel/prom.c index 0917c24c4f08..e21cd6afa709 100644 --- a/trunk/arch/sparc64/kernel/prom.c +++ b/trunk/arch/sparc64/kernel/prom.c @@ -793,7 +793,7 @@ static unsigned int schizo_irq_build(struct device_node *dp, return virt_irq; } -static void __schizo_irq_trans_init(struct device_node *dp, int is_tomatillo) +static void schizo_irq_trans_init(struct device_node *dp) { struct linux_prom64_registers *regs; struct schizo_irq_data *irq_data; @@ -807,24 +807,11 @@ static void __schizo_irq_trans_init(struct device_node *dp, int is_tomatillo) dp->irq_trans->data = irq_data; irq_data->pbm_regs = regs[0].phys_addr; - if (is_tomatillo) - irq_data->sync_reg = regs[3].phys_addr + 0x1a18UL; - else - irq_data->sync_reg = 0UL; + irq_data->sync_reg = regs[3].phys_addr + 0x1a18UL; irq_data->portid = of_getintprop_default(dp, "portid", 0); irq_data->chip_version = of_getintprop_default(dp, "version#", 0); } -static void schizo_irq_trans_init(struct device_node *dp) -{ - __schizo_irq_trans_init(dp, 0); -} - -static void tomatillo_irq_trans_init(struct device_node *dp) -{ - __schizo_irq_trans_init(dp, 1); -} - static unsigned int pci_sun4v_irq_build(struct device_node *dp, unsigned int devino, void *_data) @@ -1063,8 +1050,8 @@ static struct irq_trans pci_irq_trans_table[] = { { "pci108e,8001", schizo_irq_trans_init }, { "SUNW,schizo+", schizo_irq_trans_init }, { "pci108e,8002", schizo_irq_trans_init }, - { "SUNW,tomatillo", tomatillo_irq_trans_init }, - { "pci108e,a801", tomatillo_irq_trans_init }, + { "SUNW,tomatillo", schizo_irq_trans_init }, + { "pci108e,a801", schizo_irq_trans_init }, { "SUNW,sun4v-pci", pci_sun4v_irq_trans_init }, }; #endif @@ -1092,22 +1079,23 @@ static void sun4v_vdev_irq_trans_init(struct device_node *dp) static void irq_trans_init(struct device_node *dp) { -#ifdef CONFIG_PCI const char *model; +#ifdef CONFIG_PCI int i; #endif -#ifdef CONFIG_PCI model = of_get_property(dp, "model", NULL); if (!model) model = of_get_property(dp, "compatible", NULL); - if (model) { - for (i = 0; i < ARRAY_SIZE(pci_irq_trans_table); i++) { - struct irq_trans *t = &pci_irq_trans_table[i]; + if (!model) + return; - if (!strcmp(model, t->name)) - return t->init(dp); - } +#ifdef CONFIG_PCI + for (i = 0; i < ARRAY_SIZE(pci_irq_trans_table); i++) { + struct irq_trans *t = &pci_irq_trans_table[i]; + + if (!strcmp(model, t->name)) + return t->init(dp); } #endif #ifdef CONFIG_SBUS @@ -1115,9 +1103,8 @@ static void irq_trans_init(struct device_node *dp) !strcmp(dp->name, "sbi")) return sbus_irq_trans_init(dp); #endif - if (!strcmp(dp->name, "fhc") && - !strcmp(dp->parent->name, "central")) - return central_irq_trans_init(dp); + if (!strcmp(dp->name, "central")) + return central_irq_trans_init(dp->child); if (!strcmp(dp->name, "virtual-devices")) return sun4v_vdev_irq_trans_init(dp); } @@ -1529,7 +1516,7 @@ static char * __init get_one_property(phandle node, const char *name) return buf; } -static struct device_node * __init create_node(phandle node, struct device_node *parent) +static struct device_node * __init create_node(phandle node) { struct device_node *dp; @@ -1538,7 +1525,6 @@ static struct device_node * __init create_node(phandle node, struct device_node dp = prom_early_alloc(sizeof(*dp)); dp->unique_id = unique_id++; - dp->parent = parent; kref_init(&dp->kref); @@ -1557,11 +1543,12 @@ static struct device_node * __init build_tree(struct device_node *parent, phandl { struct device_node *dp; - dp = create_node(node, parent); + dp = create_node(node); if (dp) { *(*nextp) = dp; *nextp = &dp->allnext; + dp->parent = parent; dp->path_component_name = build_path_component(dp); dp->full_name = build_full_name(dp); @@ -1577,7 +1564,7 @@ void __init prom_build_devicetree(void) { struct device_node **nextp; - allnodes = create_node(prom_root_node, NULL); + allnodes = create_node(prom_root_node); allnodes->path_component_name = ""; allnodes->full_name = "/"; diff --git a/trunk/arch/sparc64/kernel/sbus.c b/trunk/arch/sparc64/kernel/sbus.c index 01d6d869ea2b..c49a57795743 100644 --- a/trunk/arch/sparc64/kernel/sbus.c +++ b/trunk/arch/sparc64/kernel/sbus.c @@ -839,7 +839,7 @@ unsigned int sbus_build_irq(void *buscookie, unsigned int ino) #define SYSIO_UEAFSR_SIZE 0x00001c0000000000UL /* Bad transfer size 2^SIZE */ #define SYSIO_UEAFSR_MID 0x000003e000000000UL /* UPA MID causing the fault */ #define SYSIO_UEAFSR_RESV2 0x0000001fffffffffUL /* Reserved */ -static irqreturn_t sysio_ue_handler(int irq, void *dev_id) +static irqreturn_t sysio_ue_handler(int irq, void *dev_id, struct pt_regs *regs) { struct sbus_bus *sbus = dev_id; struct sbus_iommu *iommu = sbus->iommu; @@ -911,7 +911,7 @@ static irqreturn_t sysio_ue_handler(int irq, void *dev_id) #define SYSIO_CEAFSR_SIZE 0x00001c0000000000UL /* Bad transfer size 2^SIZE */ #define SYSIO_CEAFSR_MID 0x000003e000000000UL /* UPA MID causing the fault */ #define SYSIO_CEAFSR_RESV2 0x0000001fffffffffUL /* Reserved */ -static irqreturn_t sysio_ce_handler(int irq, void *dev_id) +static irqreturn_t sysio_ce_handler(int irq, void *dev_id, struct pt_regs *regs) { struct sbus_bus *sbus = dev_id; struct sbus_iommu *iommu = sbus->iommu; @@ -988,7 +988,7 @@ static irqreturn_t sysio_ce_handler(int irq, void *dev_id) #define SYSIO_SBAFSR_SIZE 0x00001c0000000000UL /* Size of transfer */ #define SYSIO_SBAFSR_MID 0x000003e000000000UL /* MID causing the error */ #define SYSIO_SBAFSR_RESV3 0x0000001fffffffffUL /* Reserved */ -static irqreturn_t sysio_sbus_error_handler(int irq, void *dev_id) +static irqreturn_t sysio_sbus_error_handler(int irq, void *dev_id, struct pt_regs *regs) { struct sbus_bus *sbus = dev_id; struct sbus_iommu *iommu = sbus->iommu; diff --git a/trunk/arch/sparc64/kernel/setup.c b/trunk/arch/sparc64/kernel/setup.c index bf033b31d437..958287448cfe 100644 --- a/trunk/arch/sparc64/kernel/setup.c +++ b/trunk/arch/sparc64/kernel/setup.c @@ -74,6 +74,7 @@ prom_console_write(struct console *con, const char *s, unsigned n) unsigned int boot_flags = 0; #define BOOTME_DEBUG 0x1 +#define BOOTME_SINGLE 0x2 /* Exported for mm/init.c:paging_init. */ unsigned long cmdline_memory_size = 0; @@ -90,6 +91,16 @@ void kernel_enter_debugger(void) { } +int obp_system_intr(void) +{ + if (boot_flags & BOOTME_DEBUG) { + printk("OBP: system interrupted\n"); + prom_halt(); + return 1; + } + return 0; +} + /* * Process kernel command line switches that are specific to the * SPARC or that require special low-level processing. @@ -101,6 +112,7 @@ static void __init process_switch(char c) boot_flags |= BOOTME_DEBUG; break; case 's': + boot_flags |= BOOTME_SINGLE; break; case 'h': prom_printf("boot_flags_init: Halt!\n"); diff --git a/trunk/arch/sparc64/kernel/smp.c b/trunk/arch/sparc64/kernel/smp.c index cc09d8266414..f62bf3a2de1a 100644 --- a/trunk/arch/sparc64/kernel/smp.c +++ b/trunk/arch/sparc64/kernel/smp.c @@ -31,7 +31,6 @@ #include #include -#include #include #include #include @@ -1188,7 +1187,6 @@ void smp_percpu_timer_interrupt(struct pt_regs *regs) unsigned long compare, tick, pstate; int cpu = smp_processor_id(); int user = user_mode(regs); - struct pt_regs *old_regs; /* * Check for level 14 softint. @@ -1205,9 +1203,8 @@ void smp_percpu_timer_interrupt(struct pt_regs *regs) clear_softint(tick_mask); } - old_regs = set_irq_regs(regs); do { - profile_tick(CPU_PROFILING); + profile_tick(CPU_PROFILING, regs); if (!--prof_counter(cpu)) { irq_enter(); @@ -1239,7 +1236,6 @@ void smp_percpu_timer_interrupt(struct pt_regs *regs) : /* no outputs */ : "r" (pstate)); } while (time_after_eq(tick, compare)); - set_irq_regs(old_regs); } static void __init smp_setup_percpu_timer(void) diff --git a/trunk/arch/sparc64/kernel/systbls.S b/trunk/arch/sparc64/kernel/systbls.S index 9a8026797ac0..419a63fca172 100644 --- a/trunk/arch/sparc64/kernel/systbls.S +++ b/trunk/arch/sparc64/kernel/systbls.S @@ -79,7 +79,7 @@ sys_call_table32: .word sys_mkdirat, sys_mknodat, sys_fchownat, compat_sys_futimesat, compat_sys_fstatat64 /*290*/ .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat .word sys_fchmodat, sys_faccessat, compat_sys_pselect6, compat_sys_ppoll, sys_unshare -/*300*/ .word compat_sys_set_robust_list, compat_sys_get_robust_list, compat_sys_migrate_pages +/*300*/ .word compat_sys_set_robust_list, compat_sys_get_robust_list #endif /* CONFIG_COMPAT */ @@ -149,7 +149,7 @@ sys_call_table: .word sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, sys_fstatat64 /*290*/ .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat .word sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare -/*300*/ .word sys_set_robust_list, sys_get_robust_list, sys_migrate_pages +/*300*/ .word sys_set_robust_list, sys_get_robust_list #if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \ defined(CONFIG_SOLARIS_EMUL_MODULE) @@ -262,7 +262,5 @@ sunos_sys_table: /*290*/ .word sunos_nosys, sunos_nosys, sunos_nosys .word sunos_nosys, sunos_nosys, sunos_nosys .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_nosys -/*300*/ .word sunos_nosys, sunos_nosys, sunos_nosys - + .word sunos_nosys, sunos_nosys, sunos_nosys #endif diff --git a/trunk/arch/sparc64/kernel/time.c b/trunk/arch/sparc64/kernel/time.c index 061e1b1fa583..00f6fc4aaaff 100644 --- a/trunk/arch/sparc64/kernel/time.c +++ b/trunk/arch/sparc64/kernel/time.c @@ -45,7 +45,6 @@ #include #include #include -#include DEFINE_SPINLOCK(mostek_lock); DEFINE_SPINLOCK(rtc_lock); @@ -453,7 +452,7 @@ static inline void timer_check_rtc(void) } } -irqreturn_t timer_interrupt(int irq, void *dev_id) +irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs * regs) { unsigned long ticks, compare, pstate; @@ -461,8 +460,8 @@ irqreturn_t timer_interrupt(int irq, void *dev_id) do { #ifndef CONFIG_SMP - profile_tick(CPU_PROFILING); - update_process_times(user_mode(get_irq_regs())); + profile_tick(CPU_PROFILING, regs); + update_process_times(user_mode(regs)); #endif do_timer(1); diff --git a/trunk/arch/sparc64/kernel/traps.c b/trunk/arch/sparc64/kernel/traps.c index fe1796c939c3..68420e2dad0e 100644 --- a/trunk/arch/sparc64/kernel/traps.c +++ b/trunk/arch/sparc64/kernel/traps.c @@ -87,7 +87,6 @@ static void dump_tl1_traplog(struct tl1_traplog *p) i + 1, p->trapstack[i].tstate, p->trapstack[i].tpc, p->trapstack[i].tnpc, p->trapstack[i].tt); - print_symbol("TRAPLOG: TPC<%s>\n", p->trapstack[i].tpc); } } @@ -1135,9 +1134,6 @@ static void cheetah_log_errors(struct pt_regs *regs, struct cheetah_err_info *in printk("%s" "ERROR(%d): TPC[%lx] TNPC[%lx] O7[%lx] TSTATE[%lx]\n", (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(), regs->tpc, regs->tnpc, regs->u_regs[UREG_I7], regs->tstate); - printk("%s" "ERROR(%d): ", - (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id()); - print_symbol("TPC<%s>\n", regs->tpc); printk("%s" "ERROR(%d): M_SYND(%lx), E_SYND(%lx)%s%s\n", (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(), (afsr & CHAFSR_M_SYNDROME) >> CHAFSR_M_SYNDROME_SHIFT, @@ -1745,7 +1741,6 @@ void cheetah_plus_parity_error(int type, struct pt_regs *regs) smp_processor_id(), (type & 0x1) ? 'I' : 'D', regs->tpc); - print_symbol(KERN_EMERG "TPC<%s>\n", regs->tpc); panic("Irrecoverable Cheetah+ parity error."); } @@ -1753,7 +1748,6 @@ void cheetah_plus_parity_error(int type, struct pt_regs *regs) smp_processor_id(), (type & 0x1) ? 'I' : 'D', regs->tpc); - print_symbol(KERN_WARNING "TPC<%s>\n", regs->tpc); } struct sun4v_error_entry { @@ -1952,7 +1946,6 @@ void sun4v_itlb_error_report(struct pt_regs *regs, int tl) printk(KERN_EMERG "SUN4V-ITLB: Error at TPC[%lx], tl %d\n", regs->tpc, tl); - print_symbol(KERN_EMERG "SUN4V-ITLB: TPC<%s>\n", regs->tpc); printk(KERN_EMERG "SUN4V-ITLB: vaddr[%lx] ctx[%lx] " "pte[%lx] error[%lx]\n", sun4v_err_itlb_vaddr, sun4v_err_itlb_ctx, @@ -1973,7 +1966,6 @@ void sun4v_dtlb_error_report(struct pt_regs *regs, int tl) printk(KERN_EMERG "SUN4V-DTLB: Error at TPC[%lx], tl %d\n", regs->tpc, tl); - print_symbol(KERN_EMERG "SUN4V-DTLB: TPC<%s>\n", regs->tpc); printk(KERN_EMERG "SUN4V-DTLB: vaddr[%lx] ctx[%lx] " "pte[%lx] error[%lx]\n", sun4v_err_dtlb_vaddr, sun4v_err_dtlb_ctx, diff --git a/trunk/arch/sparc64/kernel/vmlinux.lds.S b/trunk/arch/sparc64/kernel/vmlinux.lds.S index bd9de8c2a2aa..b097379a49a8 100644 --- a/trunk/arch/sparc64/kernel/vmlinux.lds.S +++ b/trunk/arch/sparc64/kernel/vmlinux.lds.S @@ -57,7 +57,13 @@ SECTIONS __setup_end = .; __initcall_start = .; .initcall.init : { - INITCALLS + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) } __initcall_end = .; __con_initcall_start = .; diff --git a/trunk/arch/um/Kconfig b/trunk/arch/um/Kconfig index 5ac1f2963ae3..d75307589d74 100644 --- a/trunk/arch/um/Kconfig +++ b/trunk/arch/um/Kconfig @@ -1,8 +1,3 @@ -config DEFCONFIG_LIST - string - option defconfig_list - default "arch/$ARCH/defconfig" - # UML uses the generic IRQ sugsystem config GENERIC_HARDIRQS bool @@ -30,19 +25,6 @@ config PCI config PCMCIA bool -# Yet to do! -config TRACE_IRQFLAGS_SUPPORT - bool - default n - -config LOCKDEP_SUPPORT - bool - default y - -config STACKTRACE_SUPPORT - bool - default y - config GENERIC_CALIBRATE_DELAY bool default y @@ -55,16 +37,13 @@ config IRQ_RELEASE_METHOD menu "UML-specific options" config MODE_TT - bool "Tracing thread support (DEPRECATED)" + bool "Tracing thread support" default n - depends on BROKEN help This option controls whether tracing thread support is compiled - into UML. This option is largely obsolete, given that skas0 provides + into UML. This option is largely obsolete, given that skas0 provides skas security and performance without needing to patch the host. - It is safe to say 'N' here; saying 'Y' may cause additional problems - with the resulting binary even if you run UML in SKAS mode, and running - in TT mode is strongly *NOT RECOMMENDED*. + It is safe to say 'N' here. config STATIC_LINK bool "Force a static link" @@ -77,9 +56,6 @@ config STATIC_LINK for use in a chroot jail. So, if you intend to run UML inside a chroot, and you disable CONFIG_MODE_TT, you probably want to say Y here. - Additionally, this option enables using higher memory spaces (up to - 2.75G) for UML - disabling CONFIG_MODE_TT and enabling this option leads - to best results for this. config KERNEL_HALF_GIGS int "Kernel address space size (in .5G units)" @@ -96,13 +72,10 @@ config MODE_SKAS default y help This option controls whether skas (separate kernel address space) - support is compiled in. - Unless you have specific needs to use TT mode (which applies almost only - to developers), you should say Y here. - SKAS mode will make use of the SKAS3 patch if it is applied on the host - (and your UML will run in SKAS3 mode), but if no SKAS patch is applied - on the host it will run in SKAS0 mode, which is anyway faster than TT - mode. + support is compiled in. If you have applied the skas patch to the + host, then you certainly want to say Y here (and consider saying N + to CONFIG_MODE_TT). Otherwise, it is safe to say Y. Disabling this + option will shrink the UML binary slightly. source "arch/um/Kconfig.arch" source "mm/Kconfig" diff --git a/trunk/arch/um/Kconfig.char b/trunk/arch/um/Kconfig.char index e03e40c7aac3..62d87b71179b 100644 --- a/trunk/arch/um/Kconfig.char +++ b/trunk/arch/um/Kconfig.char @@ -190,11 +190,6 @@ config HOSTAUDIO tristate default UML_SOUND -#It is selected elsewhere, so kconfig would warn without this. -config HW_RANDOM - tristate - default n - config UML_RANDOM tristate "Hardware random number generator" help diff --git a/trunk/arch/um/Kconfig.i386 b/trunk/arch/um/Kconfig.i386 index f191a550a079..f6eb72d117b9 100644 --- a/trunk/arch/um/Kconfig.i386 +++ b/trunk/arch/um/Kconfig.i386 @@ -16,42 +16,23 @@ config SEMAPHORE_SLEEPERS bool default y -choice - prompt "Host memory split" - default HOST_VMSPLIT_3G - ---help--- - This is needed when the host kernel on which you run has a non-default - (like 2G/2G) memory split, instead of the customary 3G/1G. If you did - not recompile your own kernel but use the default distro's one, you can - safely accept the "Default split" option. - - It can be enabled on recent (>=2.6.16-rc2) vanilla kernels via - CONFIG_VM_SPLIT_*, or on previous kernels with special patches (-ck - patchset by Con Kolivas, or other ones) - option names match closely the - host CONFIG_VM_SPLIT_* ones. - - A lower setting (where 1G/3G is lowest and 3G/1G is higher) will - tolerate even more "normal" host kernels, but an higher setting will be - stricter. - - So, if you do not know what to do here, say 'Default split'. - - config HOST_VMSPLIT_3G - bool "Default split (3G/1G user/kernel host split)" - config HOST_VMSPLIT_3G_OPT - bool "3G/1G user/kernel host split (for full 1G low memory)" - config HOST_VMSPLIT_2G - bool "2G/2G user/kernel host split" - config HOST_VMSPLIT_1G - bool "1G/3G user/kernel host split" -endchoice +config HOST_2G_2G + bool "2G/2G host address space split" + default n + help + This is needed when the host on which you run has a 2G/2G memory + split, instead of the customary 3G/1G. + + Note that to enable such a host + configuration, which makes sense only in some cases, you need special + host patches. + + So, if you do not know what to do here, say 'N'. config TOP_ADDR - hex - default 0xB0000000 if HOST_VMSPLIT_3G_OPT - default 0x78000000 if HOST_VMSPLIT_2G - default 0x40000000 if HOST_VMSPLIT_1G - default 0xC0000000 + hex + default 0xc0000000 if !HOST_2G_2G + default 0x80000000 if HOST_2G_2G config 3_LEVEL_PGTABLES bool "Three-level pagetables (EXPERIMENTAL)" diff --git a/trunk/arch/um/Makefile b/trunk/arch/um/Makefile index 5d5ed726faa0..c8016a98483b 100644 --- a/trunk/arch/um/Makefile +++ b/trunk/arch/um/Makefile @@ -64,14 +64,9 @@ CFLAGS += $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \ AFLAGS += $(ARCH_INCLUDE) -USER_CFLAGS = $(patsubst $(KERNEL_DEFINES),,$(patsubst -D__KERNEL__,,\ - $(patsubst -I%,,$(CFLAGS)))) $(ARCH_INCLUDE) $(MODE_INCLUDE) \ - -D_FILE_OFFSET_BITS=64 - -include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH) - -#This will adjust *FLAGS accordingly to the platform. -include $(srctree)/$(ARCH_DIR)/Makefile-os-$(OS) +USER_CFLAGS := $(patsubst -I%,,$(CFLAGS)) +USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) $(ARCH_INCLUDE) \ + $(MODE_INCLUDE) -D_FILE_OFFSET_BITS=64 # -Derrno=kernel_errno - This turns all kernel references to errno into # kernel_errno to separate them from the libc errno. This allows -fno-common @@ -79,11 +74,15 @@ include $(srctree)/$(ARCH_DIR)/Makefile-os-$(OS) # errnos. # These apply to kernelspace only. -KERNEL_DEFINES = -Derrno=kernel_errno -Dsigprocmask=kernel_sigprocmask \ - -Dmktime=kernel_mktime $(ARCH_KERNEL_DEFINES) -CFLAGS += $(KERNEL_DEFINES) +CFLAGS += -Derrno=kernel_errno -Dsigprocmask=kernel_sigprocmask \ + -Dmktime=kernel_mktime CFLAGS += $(call cc-option,-fno-unit-at-a-time,) +include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH) + +#This will adjust *FLAGS accordingly to the platform. +include $(srctree)/$(ARCH_DIR)/Makefile-os-$(OS) + # These are needed for clean and mrproper, since in that case .config is not # included; the values here are meaningless diff --git a/trunk/arch/um/Makefile-i386 b/trunk/arch/um/Makefile-i386 index c9f1c5b24c9a..b65ca115ef77 100644 --- a/trunk/arch/um/Makefile-i386 +++ b/trunk/arch/um/Makefile-i386 @@ -16,6 +16,7 @@ OBJCOPYFLAGS := -O binary -R .note -R .comment -S ifeq ("$(origin SUBARCH)", "command line") ifneq ("$(shell uname -m | sed -e s/i.86/i386/)", "$(SUBARCH)") CFLAGS += $(call cc-option,-m32) +USER_CFLAGS += $(call cc-option,-m32) AFLAGS += $(call cc-option,-m32) LINK-y += $(call cc-option,-m32) UML_OBJCOPYFLAGS += -F $(ELF_FORMAT) @@ -24,7 +25,7 @@ export LDFLAGS HOSTCFLAGS HOSTLDFLAGS UML_OBJCOPYFLAGS endif endif -ARCH_KERNEL_DEFINES += -U__$(SUBARCH)__ -U$(SUBARCH) +CFLAGS += -U__$(SUBARCH)__ -U$(SUBARCH) # First of all, tune CFLAGS for the specific CPU. This actually sets cflags-y. include $(srctree)/arch/i386/Makefile.cpu @@ -37,3 +38,4 @@ cflags-y += $(call cc-option,-mpreferred-stack-boundary=2) cflags-y += -ffreestanding CFLAGS += $(cflags-y) +USER_CFLAGS += $(cflags-y) diff --git a/trunk/arch/um/Makefile-x86_64 b/trunk/arch/um/Makefile-x86_64 index 69ecea63fdae..11154b6773ec 100644 --- a/trunk/arch/um/Makefile-x86_64 +++ b/trunk/arch/um/Makefile-x86_64 @@ -1,15 +1,15 @@ # Copyright 2003 - 2004 Pathscale, Inc # Released under the GPL -core-y += arch/um/sys-x86_64/ arch/x86_64/crypto/ +core-y += arch/um/sys-x86_64/ START := 0x60000000 -_extra_flags_ = -fno-builtin -m64 +_extra_flags_ = -fno-builtin -m64 -mcmodel=kernel #We #undef __x86_64__ for kernelspace, not for userspace where #it's needed for headers to work! -ARCH_KERNEL_DEFINES = -U__$(SUBARCH)__ -CFLAGS += $(_extra_flags_) +CFLAGS += -U__$(SUBARCH)__ $(_extra_flags_) +USER_CFLAGS += $(_extra_flags_) CHECKFLAGS += -m64 AFLAGS += -m64 diff --git a/trunk/arch/um/drivers/chan_user.c b/trunk/arch/um/drivers/chan_user.c index 0cad3546cb89..2f880cb167a5 100644 --- a/trunk/arch/um/drivers/chan_user.c +++ b/trunk/arch/um/drivers/chan_user.c @@ -120,7 +120,7 @@ static int winch_thread(void *arg) /* These are synchronization calls between various UML threads on the * host - since they are not different kernel threads, we cannot use * kernel semaphores. We don't use SysV semaphores because they are - * persistent. */ + * persistant. */ count = os_read_file(pipe_fd, &c, sizeof(c)); if(count != sizeof(c)) printk("winch_thread : failed to read synchronization byte, " diff --git a/trunk/arch/um/drivers/cow_sys.h b/trunk/arch/um/drivers/cow_sys.h index c6a308464acb..7a5b4afde692 100644 --- a/trunk/arch/um/drivers/cow_sys.h +++ b/trunk/arch/um/drivers/cow_sys.h @@ -5,7 +5,6 @@ #include "user_util.h" #include "os.h" #include "user.h" -#include "um_malloc.h" static inline void *cow_malloc(int size) { diff --git a/trunk/arch/um/drivers/daemon_user.c b/trunk/arch/um/drivers/daemon_user.c index 310af0f1e49e..77954ea77043 100644 --- a/trunk/arch/um/drivers/daemon_user.c +++ b/trunk/arch/um/drivers/daemon_user.c @@ -17,7 +17,6 @@ #include "user_util.h" #include "user.h" #include "os.h" -#include "um_malloc.h" #define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER) diff --git a/trunk/arch/um/drivers/fd.c b/trunk/arch/um/drivers/fd.c index 218aa0e9b792..108b7dafbd0e 100644 --- a/trunk/arch/um/drivers/fd.c +++ b/trunk/arch/um/drivers/fd.c @@ -12,7 +12,6 @@ #include "user_util.h" #include "chan_user.h" #include "os.h" -#include "um_malloc.h" struct fd_chan { int fd; diff --git a/trunk/arch/um/drivers/line.c b/trunk/arch/um/drivers/line.c index 426633e5d6e3..cfd9f01fd464 100644 --- a/trunk/arch/um/drivers/line.c +++ b/trunk/arch/um/drivers/line.c @@ -20,7 +20,7 @@ #define LINE_BUFSIZE 4096 -static irqreturn_t line_interrupt(int irq, void *data) +static irqreturn_t line_interrupt(int irq, void *data, struct pt_regs *unused) { struct chan *chan = data; struct line *line = chan->line; @@ -364,7 +364,8 @@ void line_unthrottle(struct tty_struct *tty) reactivate_chan(&line->chan_list, line->driver->read_irq); } -static irqreturn_t line_write_interrupt(int irq, void *data) +static irqreturn_t line_write_interrupt(int irq, void *data, + struct pt_regs *unused) { struct chan *chan = data; struct line *line = chan->line; @@ -711,7 +712,7 @@ struct winch { struct tty_struct *tty; }; -static irqreturn_t winch_interrupt(int irq, void *data) +static irqreturn_t winch_interrupt(int irq, void *data, struct pt_regs *unused) { struct winch *winch = data; struct tty_struct *tty; diff --git a/trunk/arch/um/drivers/mcast_user.c b/trunk/arch/um/drivers/mcast_user.c index 8138f5ea1bf7..4d2bd39a85bc 100644 --- a/trunk/arch/um/drivers/mcast_user.c +++ b/trunk/arch/um/drivers/mcast_user.c @@ -23,7 +23,6 @@ #include "user_util.h" #include "user.h" #include "os.h" -#include "um_malloc.h" #define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER) diff --git a/trunk/arch/um/drivers/mconsole_kern.c b/trunk/arch/um/drivers/mconsole_kern.c index 7b172160fe04..a67dcbd78de4 100644 --- a/trunk/arch/um/drivers/mconsole_kern.c +++ b/trunk/arch/um/drivers/mconsole_kern.c @@ -74,12 +74,13 @@ static void mc_work_proc(void *unused) static DECLARE_WORK(mconsole_work, mc_work_proc, NULL); -static irqreturn_t mconsole_interrupt(int irq, void *dev_id) +static irqreturn_t mconsole_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { /* long to avoid size mismatch warnings from gcc */ long fd; struct mconsole_entry *new; - static struct mc_request req; /* that's OK */ + struct mc_request req; fd = (long) dev_id; while (mconsole_get_request(fd, &req)){ @@ -91,7 +92,6 @@ static irqreturn_t mconsole_interrupt(int irq, void *dev_id) mconsole_reply(&req, "Out of memory", 1, 0); else { new->request = req; - new->request.regs = get_irq_regs()->regs; list_add(&new->list, &mc_requests); } } @@ -315,21 +315,9 @@ void mconsole_stop(struct mc_request *req) { deactivate_fd(req->originating_fd, MCONSOLE_IRQ); os_set_fd_block(req->originating_fd, 1); - mconsole_reply(req, "stopped", 0, 0); - while (mconsole_get_request(req->originating_fd, req)) { - if (req->cmd->handler == mconsole_go) - break; - if (req->cmd->handler == mconsole_stop) { - mconsole_reply(req, "Already stopped", 1, 0); - continue; - } - if (req->cmd->handler == mconsole_sysrq) { - struct pt_regs *old_regs; - old_regs = set_irq_regs((struct pt_regs *)&req->regs); - mconsole_sysrq(req); - set_irq_regs(old_regs); - continue; - } + mconsole_reply(req, "", 0, 0); + while(mconsole_get_request(req->originating_fd, req)){ + if(req->cmd->handler == mconsole_go) break; (*req->cmd->handler)(req); } os_set_fd_block(req->originating_fd, 0); @@ -686,7 +674,8 @@ static void with_console(struct mc_request *req, void (*proc)(void *), static void sysrq_proc(void *arg) { char *op = arg; - handle_sysrq(*op, NULL); + + handle_sysrq(*op, ¤t->thread.regs, NULL); } void mconsole_sysrq(struct mc_request *req) diff --git a/trunk/arch/um/drivers/mconsole_user.c b/trunk/arch/um/drivers/mconsole_user.c index 75aef6f7ef6e..17068eb746c0 100644 --- a/trunk/arch/um/drivers/mconsole_user.c +++ b/trunk/arch/um/drivers/mconsole_user.c @@ -14,7 +14,6 @@ #include #include #include "user.h" -#include "sysdep/ptrace.h" #include "mconsole.h" #include "umid.h" #include "user_util.h" diff --git a/trunk/arch/um/drivers/mmapper_kern.c b/trunk/arch/um/drivers/mmapper_kern.c index df3516e47d4d..9a3b5daf6250 100644 --- a/trunk/arch/um/drivers/mmapper_kern.c +++ b/trunk/arch/um/drivers/mmapper_kern.c @@ -95,8 +95,7 @@ static const struct file_operations mmapper_fops = { .release = mmapper_release, }; -/* No locking needed - only used (and modified) by below initcall and exitcall. */ -static struct miscdevice mmapper_dev = { +static const struct miscdevice mmapper_dev = { .minor = MISC_DYNAMIC_MINOR, .name = "mmapper", .fops = &mmapper_fops diff --git a/trunk/arch/um/drivers/net_kern.c b/trunk/arch/um/drivers/net_kern.c index ec9eb8bd9432..c1c5604752fb 100644 --- a/trunk/arch/um/drivers/net_kern.c +++ b/trunk/arch/um/drivers/net_kern.c @@ -77,7 +77,7 @@ static void uml_dev_close(void* dev) dev_close( (struct net_device *) dev); } -irqreturn_t uml_net_interrupt(int irq, void *dev_id) +irqreturn_t uml_net_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; struct uml_net_private *lp = dev->priv; diff --git a/trunk/arch/um/drivers/net_user.c b/trunk/arch/um/drivers/net_user.c index 0ffd7ac295d4..f3a3f8a29c7a 100644 --- a/trunk/arch/um/drivers/net_user.c +++ b/trunk/arch/um/drivers/net_user.c @@ -18,7 +18,6 @@ #include "kern_util.h" #include "net_user.h" #include "os.h" -#include "um_malloc.h" int tap_open_common(void *dev, char *gate_addr) { diff --git a/trunk/arch/um/drivers/pcap_user.c b/trunk/arch/um/drivers/pcap_user.c index 11921a7baa7b..2ef641ded960 100644 --- a/trunk/arch/um/drivers/pcap_user.c +++ b/trunk/arch/um/drivers/pcap_user.c @@ -12,7 +12,6 @@ #include "net_user.h" #include "pcap_user.h" #include "user.h" -#include "um_malloc.h" #define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER) diff --git a/trunk/arch/um/drivers/pcap_user.h b/trunk/arch/um/drivers/pcap_user.h index 96b80b565eeb..58f9f6a1420f 100644 --- a/trunk/arch/um/drivers/pcap_user.h +++ b/trunk/arch/um/drivers/pcap_user.h @@ -15,7 +15,7 @@ struct pcap_data { void *dev; }; -extern const struct net_user_info pcap_user_info; +extern struct net_user_info pcap_user_info; extern int pcap_user_read(int fd, void *buf, int len, struct pcap_data *pri); diff --git a/trunk/arch/um/drivers/port_kern.c b/trunk/arch/um/drivers/port_kern.c index ce9f3733f73e..73755f37a8a8 100644 --- a/trunk/arch/um/drivers/port_kern.c +++ b/trunk/arch/um/drivers/port_kern.c @@ -47,7 +47,7 @@ struct connection { struct port_list *port; }; -static irqreturn_t pipe_interrupt(int irq, void *data) +static irqreturn_t pipe_interrupt(int irq, void *data, struct pt_regs *regs) { struct connection *conn = data; int fd; @@ -152,7 +152,7 @@ void port_work_proc(void *unused) DECLARE_WORK(port_work, port_work_proc, NULL); -static irqreturn_t port_interrupt(int irq, void *data) +static irqreturn_t port_interrupt(int irq, void *data, struct pt_regs *regs) { struct port_list *port = data; diff --git a/trunk/arch/um/drivers/port_user.c b/trunk/arch/um/drivers/port_user.c index bc6afaf74c1a..f2e8fc42ecc2 100644 --- a/trunk/arch/um/drivers/port_user.c +++ b/trunk/arch/um/drivers/port_user.c @@ -19,7 +19,6 @@ #include "chan_user.h" #include "port.h" #include "os.h" -#include "um_malloc.h" struct port_chan { int raw; diff --git a/trunk/arch/um/drivers/pty.c b/trunk/arch/um/drivers/pty.c index 829a5eca8c07..abec620e8380 100644 --- a/trunk/arch/um/drivers/pty.c +++ b/trunk/arch/um/drivers/pty.c @@ -13,7 +13,6 @@ #include "user_util.h" #include "kern_util.h" #include "os.h" -#include "um_malloc.h" struct pty_chan { void (*announce)(char *dev_name, int dev); diff --git a/trunk/arch/um/drivers/slip_user.c b/trunk/arch/um/drivers/slip_user.c index 7eddacc53b6e..8460285c69a5 100644 --- a/trunk/arch/um/drivers/slip_user.c +++ b/trunk/arch/um/drivers/slip_user.c @@ -15,7 +15,6 @@ #include "slip.h" #include "slip_common.h" #include "os.h" -#include "um_malloc.h" void slip_user_init(void *data, void *dev) { diff --git a/trunk/arch/um/drivers/tty.c b/trunk/arch/um/drivers/tty.c index d95d64309eaf..11de3ac1eb5c 100644 --- a/trunk/arch/um/drivers/tty.c +++ b/trunk/arch/um/drivers/tty.c @@ -11,7 +11,6 @@ #include "user_util.h" #include "user.h" #include "os.h" -#include "um_malloc.h" struct tty_chan { char *dev; diff --git a/trunk/arch/um/drivers/ubd_kern.c b/trunk/arch/um/drivers/ubd_kern.c index 49c047b75cc5..f0b0668458b7 100644 --- a/trunk/arch/um/drivers/ubd_kern.c +++ b/trunk/arch/um/drivers/ubd_kern.c @@ -106,15 +106,10 @@ static inline void ubd_set_bit(__u64 bit, unsigned char *data) #define DRIVER_NAME "uml-blkdev" -/* Can be taken in interrupt context, and is passed to the block layer to lock - * the request queue. Kernel side code knows that. */ static DEFINE_SPINLOCK(ubd_io_lock); +static DEFINE_SPINLOCK(ubd_lock); -static DEFINE_MUTEX(ubd_lock); - -/* XXX - this made sense in 2.4 days, now it's only used as a boolean, and - * probably it doesn't make sense even for that. */ -static int do_ubd; +static void (*do_ubd)(void); static int ubd_open(struct inode * inode, struct file * filp); static int ubd_release(struct inode * inode, struct file * file); @@ -122,7 +117,7 @@ static int ubd_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg); static int ubd_getgeo(struct block_device *bdev, struct hd_geometry *geo); -#define MAX_DEV (16) +#define MAX_DEV (8) static struct block_device_operations ubd_blops = { .owner = THIS_MODULE, @@ -155,9 +150,8 @@ static struct gendisk *fake_gendisk[MAX_DEV]; static struct openflags global_openflags = OPEN_FLAGS; struct cow { - /* backing file name */ + /* This is the backing file, actually */ char *file; - /* backing file fd */ int fd; unsigned long *bitmap; unsigned long bitmap_len; @@ -166,16 +160,14 @@ struct cow { }; struct ubd { - /* name (and fd, below) of the file opened for writing, either the - * backing or the cow file. */ char *file; int count; int fd; __u64 size; struct openflags boot_openflags; struct openflags openflags; - unsigned shared:1; - unsigned no_cow:1; + int shared; + int no_cow; struct cow cow; struct platform_device pdev; }; @@ -200,7 +192,18 @@ struct ubd { .cow = DEFAULT_COW, \ } -struct ubd ubd_devs[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_UBD }; +struct ubd ubd_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_UBD }; + +static int ubd0_init(void) +{ + struct ubd *dev = &ubd_dev[0]; + + if(dev->file == NULL) + dev->file = "root_fs"; + return(0); +} + +__initcall(ubd0_init); /* Only changed by fake_ide_setup which is a setup */ static int fake_ide = 0; @@ -274,7 +277,7 @@ static int parse_unit(char **ptr) return(-1); *ptr = end; } - else if (('a' <= *str) && (*str <= 'z')) { + else if (('a' <= *str) && (*str <= 'h')) { n = *str - 'a'; str++; *ptr = str; @@ -282,13 +285,9 @@ static int parse_unit(char **ptr) return(n); } -/* If *index_out == -1 at exit, the passed option was a general one; - * otherwise, the str pointer is used (and owned) inside ubd_devs array, so it - * should not be freed on exit. - */ static int ubd_setup_common(char *str, int *index_out) { - struct ubd *ubd_dev; + struct ubd *dev; struct openflags flags = global_openflags; char *backing_file; int n, err, i; @@ -312,7 +311,7 @@ static int ubd_setup_common(char *str, int *index_out) } err = 1; - mutex_lock(&ubd_lock); + spin_lock(&ubd_lock); if(fake_major != MAJOR_NR){ printk(KERN_ERR "Can't assign a fake major twice\n"); goto out1; @@ -324,7 +323,7 @@ static int ubd_setup_common(char *str, int *index_out) major); err = 0; out1: - mutex_unlock(&ubd_lock); + spin_unlock(&ubd_lock); return(err); } @@ -341,10 +340,10 @@ static int ubd_setup_common(char *str, int *index_out) } err = 1; - mutex_lock(&ubd_lock); + spin_lock(&ubd_lock); - ubd_dev = &ubd_devs[n]; - if(ubd_dev->file != NULL){ + dev = &ubd_dev[n]; + if(dev->file != NULL){ printk(KERN_ERR "ubd_setup : device already configured\n"); goto out; } @@ -361,10 +360,10 @@ static int ubd_setup_common(char *str, int *index_out) flags.s = 1; break; case 'd': - ubd_dev->no_cow = 1; + dev->no_cow = 1; break; case 'c': - ubd_dev->shared = 1; + dev->shared = 1; break; case '=': str++; @@ -391,7 +390,7 @@ static int ubd_setup_common(char *str, int *index_out) } if(backing_file){ - if(ubd_dev->no_cow) + if(dev->no_cow) printk(KERN_ERR "Can't specify both 'd' and a " "cow file\n"); else { @@ -399,11 +398,11 @@ static int ubd_setup_common(char *str, int *index_out) backing_file++; } } - ubd_dev->file = str; - ubd_dev->cow.file = backing_file; - ubd_dev->boot_openflags = flags; + dev->file = str; + dev->cow.file = backing_file; + dev->boot_openflags = flags; out: - mutex_unlock(&ubd_lock); + spin_unlock(&ubd_lock); return(err); } @@ -473,9 +472,8 @@ int thread_fd = -1; /* Changed by ubd_handler, which is serialized because interrupts only * happen on CPU 0. - * XXX: currently unused. */ -static int intr_count = 0; +int intr_count = 0; /* call ubd_finish if you need to serialize */ static void __ubd_finish(struct request *req, int error) @@ -495,8 +493,6 @@ static void __ubd_finish(struct request *req, int error) end_request(req, 1); } -/* Callable only from interrupt context - otherwise you need to do - * spin_lock_irq()/spin_lock_irqsave() */ static inline void ubd_finish(struct request *req, int error) { spin_lock(&ubd_io_lock); @@ -504,15 +500,14 @@ static inline void ubd_finish(struct request *req, int error) spin_unlock(&ubd_io_lock); } -/* XXX - move this inside ubd_intr. */ -/* Called without ubd_io_lock held, and only in interrupt context. */ +/* Called without ubd_io_lock held */ static void ubd_handler(void) { struct io_thread_req req; struct request *rq = elv_next_request(ubd_queue); int n; - do_ubd = 0; + do_ubd = NULL; intr_count++; n = os_read_file(thread_fd, &req, sizeof(req)); if(n != sizeof(req)){ @@ -526,12 +521,10 @@ static void ubd_handler(void) ubd_finish(rq, req.error); reactivate_fd(thread_fd, UBD_IRQ); - spin_lock(&ubd_io_lock); do_ubd_request(ubd_queue); - spin_unlock(&ubd_io_lock); } -static irqreturn_t ubd_intr(int irq, void *dev) +static irqreturn_t ubd_intr(int irq, void *dev, struct pt_regs *unused) { ubd_handler(); return(IRQ_HANDLED); @@ -548,90 +541,87 @@ void kill_io_thread(void) __uml_exitcall(kill_io_thread); -static inline int ubd_file_size(struct ubd *ubd_dev, __u64 *size_out) +static int ubd_file_size(struct ubd *dev, __u64 *size_out) { char *file; - file = ubd_dev->cow.file ? ubd_dev->cow.file : ubd_dev->file; + file = dev->cow.file ? dev->cow.file : dev->file; return(os_file_size(file, size_out)); } -static void ubd_close_dev(struct ubd *ubd_dev) +static void ubd_close(struct ubd *dev) { - os_close_file(ubd_dev->fd); - if(ubd_dev->cow.file == NULL) + os_close_file(dev->fd); + if(dev->cow.file == NULL) return; - os_close_file(ubd_dev->cow.fd); - vfree(ubd_dev->cow.bitmap); - ubd_dev->cow.bitmap = NULL; + os_close_file(dev->cow.fd); + vfree(dev->cow.bitmap); + dev->cow.bitmap = NULL; } -static int ubd_open_dev(struct ubd *ubd_dev) +static int ubd_open_dev(struct ubd *dev) { struct openflags flags; char **back_ptr; int err, create_cow, *create_ptr; - int fd; - ubd_dev->openflags = ubd_dev->boot_openflags; + dev->openflags = dev->boot_openflags; create_cow = 0; - create_ptr = (ubd_dev->cow.file != NULL) ? &create_cow : NULL; - back_ptr = ubd_dev->no_cow ? NULL : &ubd_dev->cow.file; - - fd = open_ubd_file(ubd_dev->file, &ubd_dev->openflags, ubd_dev->shared, - back_ptr, &ubd_dev->cow.bitmap_offset, - &ubd_dev->cow.bitmap_len, &ubd_dev->cow.data_offset, + create_ptr = (dev->cow.file != NULL) ? &create_cow : NULL; + back_ptr = dev->no_cow ? NULL : &dev->cow.file; + dev->fd = open_ubd_file(dev->file, &dev->openflags, dev->shared, + back_ptr, &dev->cow.bitmap_offset, + &dev->cow.bitmap_len, &dev->cow.data_offset, create_ptr); - if((fd == -ENOENT) && create_cow){ - fd = create_cow_file(ubd_dev->file, ubd_dev->cow.file, - ubd_dev->openflags, 1 << 9, PAGE_SIZE, - &ubd_dev->cow.bitmap_offset, - &ubd_dev->cow.bitmap_len, - &ubd_dev->cow.data_offset); - if(fd >= 0){ + if((dev->fd == -ENOENT) && create_cow){ + dev->fd = create_cow_file(dev->file, dev->cow.file, + dev->openflags, 1 << 9, PAGE_SIZE, + &dev->cow.bitmap_offset, + &dev->cow.bitmap_len, + &dev->cow.data_offset); + if(dev->fd >= 0){ printk(KERN_INFO "Creating \"%s\" as COW file for " - "\"%s\"\n", ubd_dev->file, ubd_dev->cow.file); + "\"%s\"\n", dev->file, dev->cow.file); } } - if(fd < 0){ - printk("Failed to open '%s', errno = %d\n", ubd_dev->file, - -fd); - return fd; + if(dev->fd < 0){ + printk("Failed to open '%s', errno = %d\n", dev->file, + -dev->fd); + return(dev->fd); } - ubd_dev->fd = fd; - if(ubd_dev->cow.file != NULL){ + if(dev->cow.file != NULL){ err = -ENOMEM; - ubd_dev->cow.bitmap = (void *) vmalloc(ubd_dev->cow.bitmap_len); - if(ubd_dev->cow.bitmap == NULL){ + dev->cow.bitmap = (void *) vmalloc(dev->cow.bitmap_len); + if(dev->cow.bitmap == NULL){ printk(KERN_ERR "Failed to vmalloc COW bitmap\n"); goto error; } flush_tlb_kernel_vm(); - err = read_cow_bitmap(ubd_dev->fd, ubd_dev->cow.bitmap, - ubd_dev->cow.bitmap_offset, - ubd_dev->cow.bitmap_len); + err = read_cow_bitmap(dev->fd, dev->cow.bitmap, + dev->cow.bitmap_offset, + dev->cow.bitmap_len); if(err < 0) goto error; - flags = ubd_dev->openflags; + flags = dev->openflags; flags.w = 0; - err = open_ubd_file(ubd_dev->cow.file, &flags, ubd_dev->shared, NULL, + err = open_ubd_file(dev->cow.file, &flags, dev->shared, NULL, NULL, NULL, NULL, NULL); if(err < 0) goto error; - ubd_dev->cow.fd = err; + dev->cow.fd = err; } return(0); error: - os_close_file(ubd_dev->fd); + os_close_file(dev->fd); return(err); } -static int ubd_disk_register(int major, u64 size, int unit, +static int ubd_new_disk(int major, u64 size, int unit, struct gendisk **disk_out) { @@ -652,13 +642,13 @@ static int ubd_disk_register(int major, u64 size, int unit, /* sysfs register (not for ide fake devices) */ if (major == MAJOR_NR) { - ubd_devs[unit].pdev.id = unit; - ubd_devs[unit].pdev.name = DRIVER_NAME; - platform_device_register(&ubd_devs[unit].pdev); - disk->driverfs_dev = &ubd_devs[unit].pdev.dev; + ubd_dev[unit].pdev.id = unit; + ubd_dev[unit].pdev.name = DRIVER_NAME; + platform_device_register(&ubd_dev[unit].pdev); + disk->driverfs_dev = &ubd_dev[unit].pdev.dev; } - disk->private_data = &ubd_devs[unit]; + disk->private_data = &ubd_dev[unit]; disk->queue = ubd_queue; add_disk(disk); @@ -670,25 +660,25 @@ static int ubd_disk_register(int major, u64 size, int unit, static int ubd_add(int n) { - struct ubd *ubd_dev = &ubd_devs[n]; + struct ubd *dev = &ubd_dev[n]; int err; err = -ENODEV; - if(ubd_dev->file == NULL) + if(dev->file == NULL) goto out; - err = ubd_file_size(ubd_dev, &ubd_dev->size); + err = ubd_file_size(dev, &dev->size); if(err < 0) goto out; - ubd_dev->size = ROUND_BLOCK(ubd_dev->size); + dev->size = ROUND_BLOCK(dev->size); - err = ubd_disk_register(MAJOR_NR, ubd_dev->size, n, &ubd_gendisk[n]); + err = ubd_new_disk(MAJOR_NR, dev->size, n, &ubd_gendisk[n]); if(err) goto out; if(fake_major != MAJOR_NR) - ubd_disk_register(fake_major, ubd_dev->size, n, + ubd_new_disk(fake_major, dev->size, n, &fake_gendisk[n]); /* perhaps this should also be under the "if (fake_major)" above */ @@ -703,41 +693,32 @@ static int ubd_add(int n) static int ubd_config(char *str) { - int n, ret; + int n, err; str = kstrdup(str, GFP_KERNEL); - if (str == NULL) { + if(str == NULL){ printk(KERN_ERR "ubd_config failed to strdup string\n"); - ret = 1; - goto out; - } - ret = ubd_setup_common(str, &n); - if (ret) { - ret = -1; - goto err_free; + return(1); } - if (n == -1) { - ret = 0; - goto err_free; + err = ubd_setup_common(str, &n); + if(err){ + kfree(str); + return(-1); } + if(n == -1) return(0); - mutex_lock(&ubd_lock); - ret = ubd_add(n); - if (ret) - ubd_devs[n].file = NULL; - mutex_unlock(&ubd_lock); - -out: - return ret; + spin_lock(&ubd_lock); + err = ubd_add(n); + if(err) + ubd_dev[n].file = NULL; + spin_unlock(&ubd_lock); -err_free: - kfree(str); - goto out; + return(err); } static int ubd_get_config(char *name, char *str, int size, char **error_out) { - struct ubd *ubd_dev; + struct ubd *dev; int n, len = 0; n = parse_unit(&name); @@ -746,24 +727,24 @@ static int ubd_get_config(char *name, char *str, int size, char **error_out) return(-1); } - ubd_dev = &ubd_devs[n]; - mutex_lock(&ubd_lock); + dev = &ubd_dev[n]; + spin_lock(&ubd_lock); - if(ubd_dev->file == NULL){ + if(dev->file == NULL){ CONFIG_CHUNK(str, size, len, "", 1); goto out; } - CONFIG_CHUNK(str, size, len, ubd_dev->file, 0); + CONFIG_CHUNK(str, size, len, dev->file, 0); - if(ubd_dev->cow.file != NULL){ + if(dev->cow.file != NULL){ CONFIG_CHUNK(str, size, len, ",", 0); - CONFIG_CHUNK(str, size, len, ubd_dev->cow.file, 1); + CONFIG_CHUNK(str, size, len, dev->cow.file, 1); } else CONFIG_CHUNK(str, size, len, "", 1); out: - mutex_unlock(&ubd_lock); + spin_unlock(&ubd_lock); return(len); } @@ -779,22 +760,22 @@ static int ubd_id(char **str, int *start_out, int *end_out) static int ubd_remove(int n) { - struct ubd *ubd_dev; + struct ubd *dev; int err = -ENODEV; - mutex_lock(&ubd_lock); + spin_lock(&ubd_lock); if(ubd_gendisk[n] == NULL) goto out; - ubd_dev = &ubd_devs[n]; + dev = &ubd_dev[n]; - if(ubd_dev->file == NULL) + if(dev->file == NULL) goto out; /* you cannot remove a open disk */ err = -EBUSY; - if(ubd_dev->count > 0) + if(dev->count > 0) goto out; del_gendisk(ubd_gendisk[n]); @@ -807,15 +788,14 @@ static int ubd_remove(int n) fake_gendisk[n] = NULL; } - platform_device_unregister(&ubd_dev->pdev); - *ubd_dev = ((struct ubd) DEFAULT_UBD); + platform_device_unregister(&dev->pdev); + *dev = ((struct ubd) DEFAULT_UBD); err = 0; out: - mutex_unlock(&ubd_lock); + spin_unlock(&ubd_lock); return err; } -/* All these are called by mconsole in process context and without ubd-specific locks. */ static struct mc_device ubd_mc = { .name = "ubd", .config = ubd_config, @@ -824,7 +804,7 @@ static struct mc_device ubd_mc = { .remove = ubd_remove, }; -static int __init ubd_mc_init(void) +static int ubd_mc_init(void) { mconsole_register_dev(&ubd_mc); return 0; @@ -832,24 +812,13 @@ static int __init ubd_mc_init(void) __initcall(ubd_mc_init); -static int __init ubd0_init(void) -{ - struct ubd *ubd_dev = &ubd_devs[0]; - - if(ubd_dev->file == NULL) - ubd_dev->file = "root_fs"; - return(0); -} - -__initcall(ubd0_init); - static struct platform_driver ubd_driver = { .driver = { .name = DRIVER_NAME, }, }; -static int __init ubd_init(void) +int ubd_init(void) { int i; @@ -877,7 +846,7 @@ static int __init ubd_init(void) late_initcall(ubd_init); -static int __init ubd_driver_init(void){ +int ubd_driver_init(void){ unsigned long stack; int err; @@ -898,7 +867,7 @@ static int __init ubd_driver_init(void){ return(0); } err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr, - IRQF_DISABLED, "ubd", ubd_devs); + IRQF_DISABLED, "ubd", ubd_dev); if(err != 0) printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err); return 0; @@ -909,24 +878,24 @@ device_initcall(ubd_driver_init); static int ubd_open(struct inode *inode, struct file *filp) { struct gendisk *disk = inode->i_bdev->bd_disk; - struct ubd *ubd_dev = disk->private_data; + struct ubd *dev = disk->private_data; int err = 0; - if(ubd_dev->count == 0){ - err = ubd_open_dev(ubd_dev); + if(dev->count == 0){ + err = ubd_open_dev(dev); if(err){ printk(KERN_ERR "%s: Can't open \"%s\": errno = %d\n", - disk->disk_name, ubd_dev->file, -err); + disk->disk_name, dev->file, -err); goto out; } } - ubd_dev->count++; - set_disk_ro(disk, !ubd_dev->openflags.w); + dev->count++; + set_disk_ro(disk, !dev->openflags.w); /* This should no more be needed. And it didn't work anyway to exclude * read-write remounting of filesystems.*/ - /*if((filp->f_mode & FMODE_WRITE) && !ubd_dev->openflags.w){ - if(--ubd_dev->count == 0) ubd_close_dev(ubd_dev); + /*if((filp->f_mode & FMODE_WRITE) && !dev->openflags.w){ + if(--dev->count == 0) ubd_close(dev); err = -EROFS; }*/ out: @@ -936,10 +905,10 @@ static int ubd_open(struct inode *inode, struct file *filp) static int ubd_release(struct inode * inode, struct file * file) { struct gendisk *disk = inode->i_bdev->bd_disk; - struct ubd *ubd_dev = disk->private_data; + struct ubd *dev = disk->private_data; - if(--ubd_dev->count == 0) - ubd_close_dev(ubd_dev); + if(--dev->count == 0) + ubd_close(dev); return(0); } @@ -1007,12 +976,12 @@ static void cowify_req(struct io_thread_req *req, unsigned long *bitmap, static int prepare_request(struct request *req, struct io_thread_req *io_req) { struct gendisk *disk = req->rq_disk; - struct ubd *ubd_dev = disk->private_data; + struct ubd *dev = disk->private_data; __u64 offset; int len; /* This should be impossible now */ - if((rq_data_dir(req) == WRITE) && !ubd_dev->openflags.w){ + if((rq_data_dir(req) == WRITE) && !dev->openflags.w){ printk("Write attempted on readonly ubd device %s\n", disk->disk_name); end_request(req, 0); @@ -1022,8 +991,8 @@ static int prepare_request(struct request *req, struct io_thread_req *io_req) offset = ((__u64) req->sector) << 9; len = req->current_nr_sectors << 9; - io_req->fds[0] = (ubd_dev->cow.file != NULL) ? ubd_dev->cow.fd : ubd_dev->fd; - io_req->fds[1] = ubd_dev->fd; + io_req->fds[0] = (dev->cow.file != NULL) ? dev->cow.fd : dev->fd; + io_req->fds[1] = dev->fd; io_req->cow_offset = -1; io_req->offset = offset; io_req->length = len; @@ -1032,13 +1001,13 @@ static int prepare_request(struct request *req, struct io_thread_req *io_req) io_req->op = (rq_data_dir(req) == READ) ? UBD_READ : UBD_WRITE; io_req->offsets[0] = 0; - io_req->offsets[1] = ubd_dev->cow.data_offset; + io_req->offsets[1] = dev->cow.data_offset; io_req->buffer = req->buffer; io_req->sectorsize = 1 << 9; - if(ubd_dev->cow.file != NULL) - cowify_req(io_req, ubd_dev->cow.bitmap, ubd_dev->cow.bitmap_offset, - ubd_dev->cow.bitmap_len); + if(dev->cow.file != NULL) + cowify_req(io_req, dev->cow.bitmap, dev->cow.bitmap_offset, + dev->cow.bitmap_len); return(0); } @@ -1064,7 +1033,7 @@ static void do_ubd_request(request_queue_t *q) return; err = prepare_request(req, &io_req); if(!err){ - do_ubd = 1; + do_ubd = ubd_handler; n = os_write_file(thread_fd, (char *) &io_req, sizeof(io_req)); if(n != sizeof(io_req)) @@ -1076,18 +1045,18 @@ static void do_ubd_request(request_queue_t *q) static int ubd_getgeo(struct block_device *bdev, struct hd_geometry *geo) { - struct ubd *ubd_dev = bdev->bd_disk->private_data; + struct ubd *dev = bdev->bd_disk->private_data; geo->heads = 128; geo->sectors = 32; - geo->cylinders = ubd_dev->size / (128 * 32 * 512); + geo->cylinders = dev->size / (128 * 32 * 512); return 0; } static int ubd_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg) { - struct ubd *ubd_dev = inode->i_bdev->bd_disk->private_data; + struct ubd *dev = inode->i_bdev->bd_disk->private_data; struct hd_driveid ubd_id = { .cyls = 0, .heads = 128, @@ -1097,7 +1066,7 @@ static int ubd_ioctl(struct inode * inode, struct file * file, switch (cmd) { struct cdrom_volctrl volume; case HDIO_GET_IDENTITY: - ubd_id.cyls = ubd_dev->size / (128 * 32 * 512); + ubd_id.cyls = dev->size / (128 * 32 * 512); if(copy_to_user((char __user *) arg, (char *) &ubd_id, sizeof(ubd_id))) return(-EFAULT); @@ -1384,8 +1353,8 @@ void do_io(struct io_thread_req *req) */ int kernel_fd = -1; -/* Only changed by the io thread. XXX: currently unused. */ -static int io_count = 0; +/* Only changed by the io thread */ +int io_count = 0; int io_thread(void *arg) { diff --git a/trunk/arch/um/drivers/xterm.c b/trunk/arch/um/drivers/xterm.c index 850221d9b4c9..386f8b952982 100644 --- a/trunk/arch/um/drivers/xterm.c +++ b/trunk/arch/um/drivers/xterm.c @@ -136,6 +136,8 @@ int xterm_open(int input, int output, int primary, void *d, return(pid); } + if(data->stack == 0) free_stack(stack, 0); + if (data->direct_rcv) { new = os_rcv_fd(fd, &data->helper_pid); } else { diff --git a/trunk/arch/um/drivers/xterm_kern.c b/trunk/arch/um/drivers/xterm_kern.c index a4ce7058e10e..6036ec85895a 100644 --- a/trunk/arch/um/drivers/xterm_kern.c +++ b/trunk/arch/um/drivers/xterm_kern.c @@ -21,7 +21,7 @@ struct xterm_wait { int new_fd; }; -static irqreturn_t xterm_interrupt(int irq, void *data) +static irqreturn_t xterm_interrupt(int irq, void *data, struct pt_regs *regs) { struct xterm_wait *xterm = data; int fd; diff --git a/trunk/arch/um/include/common-offsets.h b/trunk/arch/um/include/common-offsets.h index 461175f8b1d9..356390d1f8b9 100644 --- a/trunk/arch/um/include/common-offsets.h +++ b/trunk/arch/um/include/common-offsets.h @@ -1,16 +1,9 @@ /* for use by sys-$SUBARCH/kernel-offsets.c */ -DEFINE(KERNEL_MADV_REMOVE, MADV_REMOVE); -#ifdef CONFIG_MODE_TT -OFFSET(HOST_TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid); -#endif - OFFSET(HOST_TASK_REGS, task_struct, thread.regs); OFFSET(HOST_TASK_PID, task_struct, pid); - DEFINE(UM_KERN_PAGE_SIZE, PAGE_SIZE); DEFINE(UM_NSEC_PER_SEC, NSEC_PER_SEC); - DEFINE_STR(UM_KERN_EMERG, KERN_EMERG); DEFINE_STR(UM_KERN_ALERT, KERN_ALERT); DEFINE_STR(UM_KERN_CRIT, KERN_CRIT); @@ -19,10 +12,6 @@ DEFINE_STR(UM_KERN_WARNING, KERN_WARNING); DEFINE_STR(UM_KERN_NOTICE, KERN_NOTICE); DEFINE_STR(UM_KERN_INFO, KERN_INFO); DEFINE_STR(UM_KERN_DEBUG, KERN_DEBUG); - DEFINE(UM_ELF_CLASS, ELF_CLASS); DEFINE(UM_ELFCLASS32, ELFCLASS32); DEFINE(UM_ELFCLASS64, ELFCLASS64); - -/* For crypto assembler code. */ -DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx)); diff --git a/trunk/arch/um/include/irq_kern.h b/trunk/arch/um/include/irq_kern.h index 4f775597fd5f..c222d56b1494 100644 --- a/trunk/arch/um/include/irq_kern.h +++ b/trunk/arch/um/include/irq_kern.h @@ -10,11 +10,12 @@ #include "asm/ptrace.h" extern int um_request_irq(unsigned int irq, int fd, int type, - irq_handler_t handler, + irqreturn_t (*handler)(int, void *, + struct pt_regs *), unsigned long irqflags, const char * devname, void *dev_id); extern int init_aio_irq(int irq, char *name, - irq_handler_t handler); + irqreturn_t (*handler)(int, void *, struct pt_regs *)); #endif diff --git a/trunk/arch/um/include/kern_util.h b/trunk/arch/um/include/kern_util.h index cec9fcc57bf5..59cfa9e0cad0 100644 --- a/trunk/arch/um/include/kern_util.h +++ b/trunk/arch/um/include/kern_util.h @@ -6,6 +6,7 @@ #ifndef __KERN_UTIL_H__ #define __KERN_UTIL_H__ +#include "linux/threads.h" #include "sysdep/ptrace.h" #include "sysdep/faultinfo.h" diff --git a/trunk/arch/um/include/longjmp.h b/trunk/arch/um/include/longjmp.h index e860bc5848e0..e93c6d3e893b 100644 --- a/trunk/arch/um/include/longjmp.h +++ b/trunk/arch/um/include/longjmp.h @@ -12,8 +12,7 @@ extern void longjmp(jmp_buf, int); } while(0) #define UML_SETJMP(buf) ({ \ - int n; \ - volatile int enable; \ + int n, enable; \ enable = get_signals(); \ n = setjmp(*buf); \ if(n != 0) \ diff --git a/trunk/arch/um/include/mconsole.h b/trunk/arch/um/include/mconsole.h index 2666815b6af5..58f67d391105 100644 --- a/trunk/arch/um/include/mconsole.h +++ b/trunk/arch/um/include/mconsole.h @@ -61,7 +61,6 @@ struct mc_request struct mconsole_request request; struct mconsole_command *cmd; - union uml_pt_regs regs; }; extern char mconsole_socket_name[]; diff --git a/trunk/arch/um/include/mconsole_kern.h b/trunk/arch/um/include/mconsole_kern.h index 1ea6d928e1cd..d0b690197fd7 100644 --- a/trunk/arch/um/include/mconsole_kern.h +++ b/trunk/arch/um/include/mconsole_kern.h @@ -14,7 +14,6 @@ struct mconsole_entry { struct mc_request request; }; -/* All these methods are called in process context. */ struct mc_device { struct list_head list; char *name; diff --git a/trunk/arch/um/include/os.h b/trunk/arch/um/include/os.h index 13a86bd383d3..120ca21a513a 100644 --- a/trunk/arch/um/include/os.h +++ b/trunk/arch/um/include/os.h @@ -201,7 +201,6 @@ extern int os_getpgrp(void); #ifdef UML_CONFIG_MODE_TT extern void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int)); -extern void stop(void); #endif extern void init_new_thread_signals(void); extern int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr); @@ -233,8 +232,6 @@ extern unsigned long __do_user_copy(void *to, const void *from, int n, void (*op)(void *to, const void *from, int n), int *faulted_out); -/* execvp.c */ -extern int execvp_noalloc(char *buf, const char *file, char *const argv[]); /* helper.c */ extern int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv, unsigned long *stack_out); diff --git a/trunk/arch/um/include/sysdep-i386/barrier.h b/trunk/arch/um/include/sysdep-i386/barrier.h deleted file mode 100644 index b58d52c5b2f4..000000000000 --- a/trunk/arch/um/include/sysdep-i386/barrier.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __SYSDEP_I386_BARRIER_H -#define __SYSDEP_I386_BARRIER_H - -/* Copied from include/asm-i386 for use by userspace. i386 has the option - * of using mfence, but I'm just using this, which works everywhere, for now. - */ -#define mb() asm volatile("lock; addl $0,0(%esp)") - -#endif diff --git a/trunk/arch/um/include/sysdep-i386/kernel-offsets.h b/trunk/arch/um/include/sysdep-i386/kernel-offsets.h index 97ec9d894d75..2c13de321f2f 100644 --- a/trunk/arch/um/include/sysdep-i386/kernel-offsets.h +++ b/trunk/arch/um/include/sysdep-i386/kernel-offsets.h @@ -1,7 +1,6 @@ #include #include #include -#include #include #define DEFINE(sym, val) \ @@ -18,5 +17,9 @@ void foo(void) { OFFSET(HOST_TASK_DEBUGREGS, task_struct, thread.arch.debugregs); + DEFINE(KERNEL_MADV_REMOVE, MADV_REMOVE); +#ifdef CONFIG_MODE_TT + OFFSET(HOST_TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid); +#endif #include } diff --git a/trunk/arch/um/include/sysdep-x86_64/barrier.h b/trunk/arch/um/include/sysdep-x86_64/barrier.h deleted file mode 100644 index 7b610befdc8f..000000000000 --- a/trunk/arch/um/include/sysdep-x86_64/barrier.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __SYSDEP_X86_64_BARRIER_H -#define __SYSDEP_X86_64_BARRIER_H - -/* Copied from include/asm-x86_64 for use by userspace. */ -#define mb() asm volatile("mfence":::"memory") - -#endif diff --git a/trunk/arch/um/include/sysdep-x86_64/kernel-offsets.h b/trunk/arch/um/include/sysdep-x86_64/kernel-offsets.h index a307237b7964..91d129fb3930 100644 --- a/trunk/arch/um/include/sysdep-x86_64/kernel-offsets.h +++ b/trunk/arch/um/include/sysdep-x86_64/kernel-offsets.h @@ -2,7 +2,6 @@ #include #include #include -#include #include #include @@ -19,5 +18,9 @@ void foo(void) { + DEFINE(KERNEL_MADV_REMOVE, MADV_REMOVE); +#ifdef CONFIG_MODE_TT + OFFSET(HOST_TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid); +#endif #include } diff --git a/trunk/arch/um/include/um_malloc.h b/trunk/arch/um/include/um_malloc.h deleted file mode 100644 index 0363a9b53f8d..000000000000 --- a/trunk/arch/um/include/um_malloc.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (C) 2005 Paolo 'Blaisorblade' Giarrusso - * Licensed under the GPL - */ - -#ifndef __UM_MALLOC_H__ -#define __UM_MALLOC_H__ - -extern void *um_kmalloc(int size); -extern void *um_kmalloc_atomic(int size); -extern void kfree(const void *ptr); - -extern void *um_vmalloc(int size); -extern void *um_vmalloc_atomic(int size); -extern void vfree(void *ptr); - -#endif /* __UM_MALLOC_H__ */ diff --git a/trunk/arch/um/include/user.h b/trunk/arch/um/include/user.h index acadce3f271f..39f8c8801076 100644 --- a/trunk/arch/um/include/user.h +++ b/trunk/arch/um/include/user.h @@ -11,11 +11,17 @@ extern void panic(const char *fmt, ...) extern int printk(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); extern void schedule(void); +extern void *um_kmalloc(int size); +extern void *um_kmalloc_atomic(int size); +extern void kfree(void *ptr); extern int in_aton(char *str); extern int open_gdb_chan(void); /* These use size_t, however unsigned long is correct on both i386 and x86_64. */ extern unsigned long strlcpy(char *, const char *, unsigned long); extern unsigned long strlcat(char *, const char *, unsigned long); +extern void *um_vmalloc(int size); +extern void *um_vmalloc_atomic(int size); +extern void vfree(void *ptr); #endif diff --git a/trunk/arch/um/include/user_util.h b/trunk/arch/um/include/user_util.h index 06625fefef33..802d7842514d 100644 --- a/trunk/arch/um/include/user_util.h +++ b/trunk/arch/um/include/user_util.h @@ -52,6 +52,7 @@ extern int linux_main(int argc, char **argv); extern void set_cmdline(char *cmd); extern void input_cb(void (*proc)(void *), void *arg, int arg_len); extern int get_pty(void); +extern void *um_kmalloc(int size); extern int switcheroo(int fd, int prot, void *from, void *to, int size); extern void do_exec(int old_pid, int new_pid); extern void tracer_panic(char *msg, ...) diff --git a/trunk/arch/um/kernel/dyn.lds.S b/trunk/arch/um/kernel/dyn.lds.S index e36f92b463ce..68ed24df5c8f 100644 --- a/trunk/arch/um/kernel/dyn.lds.S +++ b/trunk/arch/um/kernel/dyn.lds.S @@ -14,7 +14,6 @@ SECTIONS * is remapped.*/ __binary_start = .; . = ALIGN(4096); /* Init code and data */ - _text = .; _stext = .; __init_begin = .; .init.text : { diff --git a/trunk/arch/um/kernel/irq.c b/trunk/arch/um/kernel/irq.c index 5c1e611f628d..eee97bb81ba5 100644 --- a/trunk/arch/um/kernel/irq.c +++ b/trunk/arch/um/kernel/irq.c @@ -31,7 +31,6 @@ #include "irq_kern.h" #include "os.h" #include "sigio.h" -#include "um_malloc.h" #include "misc_constants.h" /* @@ -356,16 +355,14 @@ void forward_interrupts(int pid) */ unsigned int do_IRQ(int irq, union uml_pt_regs *regs) { - struct pt_regs *old_regs = set_irq_regs((struct pt_regs *)regs); - irq_enter(); - __do_IRQ(irq); - irq_exit(); - set_irq_regs(old_regs); - return 1; + irq_enter(); + __do_IRQ(irq, (struct pt_regs *)regs); + irq_exit(); + return 1; } int um_request_irq(unsigned int irq, int fd, int type, - irq_handler_t handler, + irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long irqflags, const char * devname, void *dev_id) { @@ -426,7 +423,8 @@ void __init init_IRQ(void) } } -int init_aio_irq(int irq, char *name, irq_handler_t handler) +int init_aio_irq(int irq, char *name, irqreturn_t (*handler)(int, void *, + struct pt_regs *)) { int fds[2], err; diff --git a/trunk/arch/um/kernel/process.c b/trunk/arch/um/kernel/process.c index 348b272bb766..fe6c64abda5b 100644 --- a/trunk/arch/um/kernel/process.c +++ b/trunk/arch/um/kernel/process.c @@ -46,7 +46,6 @@ #include "mode.h" #include "mode_kern.h" #include "choose-mode.h" -#include "um_malloc.h" /* This is a per-cpu array. A processor only modifies its entry and it only * cares about its entry, so it's OK if another processor is modifying its diff --git a/trunk/arch/um/kernel/sigio.c b/trunk/arch/um/kernel/sigio.c index 2b0ab438301c..0ad755ceb212 100644 --- a/trunk/arch/um/kernel/sigio.c +++ b/trunk/arch/um/kernel/sigio.c @@ -17,7 +17,7 @@ /* Protected by sigio_lock() called from write_sigio_workaround */ static int sigio_irq_fd = -1; -static irqreturn_t sigio_interrupt(int irq, void *data) +static irqreturn_t sigio_interrupt(int irq, void *data, struct pt_regs *unused) { char c; diff --git a/trunk/arch/um/kernel/skas/mmu.c b/trunk/arch/um/kernel/skas/mmu.c index 2c6d090a2e87..c17eddcf89b3 100644 --- a/trunk/arch/um/kernel/skas/mmu.c +++ b/trunk/arch/um/kernel/skas/mmu.c @@ -60,7 +60,10 @@ static int init_stub_pte(struct mm_struct *mm, unsigned long proc, #endif *pte = mk_pte(virt_to_page(kernel), __pgprot(_PAGE_PRESENT)); - *pte = pte_mkread(*pte); + /* This is wrong for the code page, but it doesn't matter since the + * stub is mapped by hand with the correct permissions. + */ + *pte = pte_mkwrite(*pte); return(0); out_pmd: diff --git a/trunk/arch/um/kernel/time.c b/trunk/arch/um/kernel/time.c index 2e354b3ca060..a92965f8f9cd 100644 --- a/trunk/arch/um/kernel/time.c +++ b/trunk/arch/um/kernel/time.c @@ -86,7 +86,7 @@ static inline unsigned long long get_time(void) return nsecs; } -irqreturn_t um_timer(int irq, void *dev) +irqreturn_t um_timer(int irq, void *dev, struct pt_regs *regs) { unsigned long long nsecs; unsigned long flags; diff --git a/trunk/arch/um/kernel/tt/tracer.c b/trunk/arch/um/kernel/tt/tracer.c index b9195355075a..9882342206ec 100644 --- a/trunk/arch/um/kernel/tt/tracer.c +++ b/trunk/arch/um/kernel/tt/tracer.c @@ -176,6 +176,7 @@ struct { int signal_index[32]; int nsignals = 0; int debug_trace = 0; +extern int io_nsignals, io_count, intr_count; extern void signal_usr1(int sig); diff --git a/trunk/arch/um/kernel/tt/uaccess_user.c b/trunk/arch/um/kernel/tt/uaccess_user.c index ed1abcf4d057..6c92bbccb49c 100644 --- a/trunk/arch/um/kernel/tt/uaccess_user.c +++ b/trunk/arch/um/kernel/tt/uaccess_user.c @@ -4,13 +4,13 @@ * Licensed under the GPL */ +#include #include #include "user_util.h" #include "uml_uaccess.h" #include "task.h" #include "kern_util.h" #include "os.h" -#include "longjmp.h" int __do_copy_from_user(void *to, const void *from, int n, void **fault_addr, void **fault_catcher) @@ -80,10 +80,10 @@ int __do_strnlen_user(const char *str, unsigned long n, struct tt_regs save = TASK_REGS(get_current())->tt; int ret; unsigned long *faddrp = (unsigned long *)fault_addr; - jmp_buf jbuf; + sigjmp_buf jbuf; *fault_catcher = &jbuf; - if(UML_SETJMP(&jbuf) == 0) + if(sigsetjmp(jbuf, 1) == 0) ret = strlen(str) + 1; else ret = *faddrp - (unsigned long) str; diff --git a/trunk/arch/um/kernel/uml.lds.S b/trunk/arch/um/kernel/uml.lds.S index f6301274cf3c..8eca47a6ff08 100644 --- a/trunk/arch/um/kernel/uml.lds.S +++ b/trunk/arch/um/kernel/uml.lds.S @@ -25,7 +25,6 @@ SECTIONS . = ALIGN(4096); /* Init code and data */ #endif - _text = .; _stext = .; __init_begin = .; .init.text : { diff --git a/trunk/arch/um/os-Linux/Makefile b/trunk/arch/um/os-Linux/Makefile index 2f8c79464015..b4183929b32c 100644 --- a/trunk/arch/um/os-Linux/Makefile +++ b/trunk/arch/um/os-Linux/Makefile @@ -3,8 +3,8 @@ # Licensed under the GPL # -obj-y = aio.o elf_aux.o execvp.o file.o helper.o irq.o main.o mem.o process.o \ - sigio.o signal.o start_up.o time.o trap.o tty.o uaccess.o umid.o tls.o \ +obj-y = aio.o elf_aux.o file.o helper.o irq.o main.o mem.o process.o sigio.o \ + signal.o start_up.o time.o trap.o tty.o uaccess.o umid.o tls.o \ user_syms.o util.o drivers/ sys-$(SUBARCH)/ obj-$(CONFIG_MODE_SKAS) += skas/ @@ -15,9 +15,9 @@ user-objs-$(CONFIG_MODE_TT) += tt.o obj-$(CONFIG_TTY_LOG) += tty_log.o user-objs-$(CONFIG_TTY_LOG) += tty_log.o -USER_OBJS := $(user-objs-y) aio.o elf_aux.o execvp.o file.o helper.o irq.o \ - main.o mem.o process.o sigio.o signal.o start_up.o time.o trap.o tty.o \ - tls.o uaccess.o umid.o util.o +USER_OBJS := $(user-objs-y) aio.o elf_aux.o file.o helper.o irq.o main.o mem.o \ + process.o sigio.o signal.o start_up.o time.o trap.o tty.o tls.o \ + uaccess.o umid.o util.o CFLAGS_user_syms.o += -DSUBARCH_$(SUBARCH) diff --git a/trunk/arch/um/os-Linux/drivers/ethertap_user.c b/trunk/arch/um/os-Linux/drivers/ethertap_user.c index 863981ba1468..f559bdf746e6 100644 --- a/trunk/arch/um/os-Linux/drivers/ethertap_user.c +++ b/trunk/arch/um/os-Linux/drivers/ethertap_user.c @@ -20,7 +20,6 @@ #include "net_user.h" #include "etap.h" #include "os.h" -#include "um_malloc.h" #define MAX_PACKET ETH_MAX_PACKET diff --git a/trunk/arch/um/os-Linux/execvp.c b/trunk/arch/um/os-Linux/execvp.c deleted file mode 100644 index 66e583a4031b..000000000000 --- a/trunk/arch/um/os-Linux/execvp.c +++ /dev/null @@ -1,149 +0,0 @@ -/* Copyright (C) 2006 by Paolo Giarrusso - modified from glibc' execvp.c. - Original copyright notice follows: - - Copyright (C) 1991,92,1995-99,2002,2004 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ -#include - -#include -#include -#include -#include -#include - -#ifndef TEST -#include "um_malloc.h" -#else -#include -#define um_kmalloc malloc -#endif -#include "os.h" - -/* Execute FILE, searching in the `PATH' environment variable if it contains - no slashes, with arguments ARGV and environment from `environ'. */ -int execvp_noalloc(char *buf, const char *file, char *const argv[]) -{ - if (*file == '\0') { - return -ENOENT; - } - - if (strchr (file, '/') != NULL) { - /* Don't search when it contains a slash. */ - execv(file, argv); - } else { - int got_eacces; - size_t len, pathlen; - char *name, *p; - char *path = getenv("PATH"); - if (path == NULL) - path = ":/bin:/usr/bin"; - - len = strlen(file) + 1; - pathlen = strlen(path); - /* Copy the file name at the top. */ - name = memcpy(buf + pathlen + 1, file, len); - /* And add the slash. */ - *--name = '/'; - - got_eacces = 0; - p = path; - do { - char *startp; - - path = p; - //Let's avoid this GNU extension. - //p = strchrnul (path, ':'); - p = strchr(path, ':'); - if (!p) - p = strchr(path, '\0'); - - if (p == path) - /* Two adjacent colons, or a colon at the beginning or the end - of `PATH' means to search the current directory. */ - startp = name + 1; - else - startp = memcpy(name - (p - path), path, p - path); - - /* Try to execute this name. If it works, execv will not return. */ - execv(startp, argv); - - /* - if (errno == ENOEXEC) { - } - */ - - switch (errno) { - case EACCES: - /* Record the we got a `Permission denied' error. If we end - up finding no executable we can use, we want to diagnose - that we did find one but were denied access. */ - got_eacces = 1; - case ENOENT: - case ESTALE: - case ENOTDIR: - /* Those errors indicate the file is missing or not executable - by us, in which case we want to just try the next path - directory. */ - case ENODEV: - case ETIMEDOUT: - /* Some strange filesystems like AFS return even - stranger error numbers. They cannot reasonably mean - anything else so ignore those, too. */ - case ENOEXEC: - /* We won't go searching for the shell - * if it is not executable - the Linux - * kernel already handles this enough, - * for us. */ - break; - - default: - /* Some other error means we found an executable file, but - something went wrong executing it; return the error to our - caller. */ - return -errno; - } - } while (*p++ != '\0'); - - /* We tried every element and none of them worked. */ - if (got_eacces) - /* At least one failure was due to permissions, so report that - error. */ - return -EACCES; - } - - /* Return the error from the last attempt (probably ENOENT). */ - return -errno; -} -#ifdef TEST -int main(int argc, char**argv) -{ - char buf[PATH_MAX]; - int ret; - argc--; - if (!argc) { - fprintf(stderr, "Not enough arguments\n"); - return 1; - } - argv++; - if (ret = execvp_noalloc(buf, argv[0], argv)) { - errno = -ret; - perror("execvp_noalloc"); - } - return 0; -} -#endif diff --git a/trunk/arch/um/os-Linux/helper.c b/trunk/arch/um/os-Linux/helper.c index c7ad6306e22f..cd15b9df5b5c 100644 --- a/trunk/arch/um/os-Linux/helper.c +++ b/trunk/arch/um/os-Linux/helper.c @@ -8,21 +8,18 @@ #include #include #include -#include #include #include #include "user.h" #include "kern_util.h" #include "user_util.h" #include "os.h" -#include "um_malloc.h" struct helper_data { void (*pre_exec)(void*); void *pre_data; char **argv; int fd; - char *buf; }; /* Debugging aid, changed only from gdb */ @@ -38,22 +35,22 @@ static int helper_child(void *arg) char **argv = data->argv; int errval; - if (helper_pause){ + if(helper_pause){ signal(SIGHUP, helper_hup); pause(); } - if (data->pre_exec != NULL) + if(data->pre_exec != NULL) (*data->pre_exec)(data->pre_data); - errval = execvp_noalloc(data->buf, argv[0], argv); - printk("helper_child - execvp of '%s' failed - errno = %d\n", argv[0], -errval); + execvp(argv[0], argv); + errval = -errno; + printk("helper_child - execve of '%s' failed - errno = %d\n", argv[0], errno); os_write_file(data->fd, &errval, sizeof(errval)); kill(os_getpid(), SIGKILL); - return 0; + return(0); } /* Returns either the pid of the child process we run or -E* on failure. - * XXX The alloc_stack here breaks if this is called in the tracing thread, so - * we need to receive a preallocated stack (a local buffer is ok). */ + * XXX The alloc_stack here breaks if this is called in the tracing thread */ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv, unsigned long *stack_out) { @@ -61,21 +58,20 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv, unsigned long stack, sp; int pid, fds[2], ret, n; - if ((stack_out != NULL) && (*stack_out != 0)) + if((stack_out != NULL) && (*stack_out != 0)) stack = *stack_out; - else - stack = alloc_stack(0, __cant_sleep()); - if (stack == 0) + else stack = alloc_stack(0, __cant_sleep()); + if(stack == 0) return -ENOMEM; ret = os_pipe(fds, 1, 0); - if (ret < 0) { + if(ret < 0){ printk("run_helper : pipe failed, ret = %d\n", -ret); goto out_free; } ret = os_set_exec_close(fds[1], 1); - if (ret < 0) { + if(ret < 0){ printk("run_helper : setting FD_CLOEXEC failed, ret = %d\n", -ret); goto out_close; @@ -86,13 +82,11 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv, data.pre_data = pre_data; data.argv = argv; data.fd = fds[1]; - data.buf = __cant_sleep() ? um_kmalloc_atomic(PATH_MAX) : - um_kmalloc(PATH_MAX); pid = clone(helper_child, (void *) sp, CLONE_VM | SIGCHLD, &data); - if (pid < 0) { + if(pid < 0){ ret = -errno; printk("run_helper : clone failed, errno = %d\n", errno); - goto out_free2; + goto out_close; } close(fds[1]); @@ -101,10 +95,10 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv, /* Read the errno value from the child, if the exec failed, or get 0 if * the exec succeeded because the pipe fd was set as close-on-exec. */ n = os_read_file(fds[0], &ret, sizeof(ret)); - if (n == 0) { + if(n == 0) ret = pid; - } else { - if (n < 0) { + else { + if(n < 0){ printk("run_helper : read on pipe failed, ret = %d\n", -n); ret = n; @@ -113,16 +107,15 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv, CATCH_EINTR(waitpid(pid, NULL, 0)); } -out_free2: - kfree(data.buf); out_close: if (fds[1] != -1) close(fds[1]); close(fds[0]); out_free: - if ((stack_out == NULL) || (*stack_out == 0)) + if(stack_out == NULL) free_stack(stack, 0); - return ret; + else *stack_out = stack; + return(ret); } int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags, @@ -132,32 +125,31 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags, int pid, status, err; stack = alloc_stack(stack_order, __cant_sleep()); - if (stack == 0) - return -ENOMEM; + if(stack == 0) return(-ENOMEM); sp = stack + (page_size() << stack_order) - sizeof(void *); pid = clone(proc, (void *) sp, flags | SIGCHLD, arg); - if (pid < 0) { + if(pid < 0){ err = -errno; printk("run_helper_thread : clone failed, errno = %d\n", errno); return err; } - if (stack_out == NULL) { + if(stack_out == NULL){ CATCH_EINTR(pid = waitpid(pid, &status, 0)); - if (pid < 0) { + if(pid < 0){ err = -errno; printk("run_helper_thread - wait failed, errno = %d\n", errno); pid = err; } - if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0)) + if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)) printk("run_helper_thread - thread returned status " "0x%x\n", status); free_stack(stack, stack_order); - } else - *stack_out = stack; - return pid; + } + else *stack_out = stack; + return(pid); } int helper_wait(int pid) @@ -165,9 +157,9 @@ int helper_wait(int pid) int ret; CATCH_EINTR(ret = waitpid(pid, NULL, WNOHANG)); - if (ret < 0) { + if(ret < 0){ ret = -errno; printk("helper_wait : waitpid failed, errno = %d\n", errno); } - return ret; + return(ret); } diff --git a/trunk/arch/um/os-Linux/irq.c b/trunk/arch/um/os-Linux/irq.c index d46b818c1311..a97206df5b52 100644 --- a/trunk/arch/um/os-Linux/irq.c +++ b/trunk/arch/um/os-Linux/irq.c @@ -18,7 +18,6 @@ #include "sigio.h" #include "irq_user.h" #include "os.h" -#include "um_malloc.h" static struct pollfd *pollfds = NULL; static int pollfds_num = 0; diff --git a/trunk/arch/um/os-Linux/main.c b/trunk/arch/um/os-Linux/main.c index 685feaab65d2..d1c5670787dc 100644 --- a/trunk/arch/um/os-Linux/main.c +++ b/trunk/arch/um/os-Linux/main.c @@ -23,7 +23,6 @@ #include "choose-mode.h" #include "uml-config.h" #include "os.h" -#include "um_malloc.h" /* Set in set_stklim, which is called from main and __wrap_malloc. * __wrap_malloc only calls it if main hasn't started. diff --git a/trunk/arch/um/os-Linux/process.c b/trunk/arch/um/os-Linux/process.c index c692a192957a..51f0893640a6 100644 --- a/trunk/arch/um/os-Linux/process.c +++ b/trunk/arch/um/os-Linux/process.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/um/os-Linux/sigio.c b/trunk/arch/um/os-Linux/sigio.c index 925a65240cfe..f6457765b17d 100644 --- a/trunk/arch/um/os-Linux/sigio.c +++ b/trunk/arch/um/os-Linux/sigio.c @@ -19,7 +19,6 @@ #include "user_util.h" #include "sigio.h" #include "os.h" -#include "um_malloc.h" /* Protected by sigio_lock(), also used by sigio_cleanup, which is an * exitcall. diff --git a/trunk/arch/um/os-Linux/signal.c b/trunk/arch/um/os-Linux/signal.c index b897e8592d77..6b81739279d1 100644 --- a/trunk/arch/um/os-Linux/signal.c +++ b/trunk/arch/um/os-Linux/signal.c @@ -15,7 +15,6 @@ #include "user.h" #include "signal_kern.h" #include "sysdep/sigcontext.h" -#include "sysdep/barrier.h" #include "sigcontext.h" #include "mode.h" #include "os.h" @@ -35,12 +34,8 @@ #define SIGALRM_BIT 2 #define SIGALRM_MASK (1 << SIGALRM_BIT) -/* These are used by both the signal handlers and - * block/unblock_signals. I don't want modifications cached in a - * register - they must go straight to memory. - */ -static volatile int signals_enabled = 1; -static volatile int pending = 0; +static int signals_enabled = 1; +static int pending = 0; void sig_handler(int sig, struct sigcontext *sc) { @@ -157,12 +152,6 @@ int change_sig(int signal, int on) void block_signals(void) { signals_enabled = 0; - /* This must return with signals disabled, so this barrier - * ensures that writes are flushed out before the return. - * This might matter if gcc figures out how to inline this and - * decides to shuffle this code into the caller. - */ - mb(); } void unblock_signals(void) @@ -182,23 +171,9 @@ void unblock_signals(void) */ signals_enabled = 1; - /* Setting signals_enabled and reading pending must - * happen in this order. - */ - mb(); - save_pending = pending; - if(save_pending == 0){ - /* This must return with signals enabled, so - * this barrier ensures that writes are - * flushed out before the return. This might - * matter if gcc figures out how to inline - * this (unlikely, given its size) and decides - * to shuffle this code into the caller. - */ - mb(); + if(save_pending == 0) return; - } pending = 0; diff --git a/trunk/arch/um/os-Linux/skas/process.c b/trunk/arch/um/os-Linux/skas/process.c index 9b34fe65949a..cb9ab54146cc 100644 --- a/trunk/arch/um/os-Linux/skas/process.c +++ b/trunk/arch/um/os-Linux/skas/process.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include "user.h" #include "sysdep/ptrace.h" diff --git a/trunk/arch/um/os-Linux/sys-i386/tls.c b/trunk/arch/um/os-Linux/sys-i386/tls.c index 256532034c62..6e945ab45843 100644 --- a/trunk/arch/um/os-Linux/sys-i386/tls.c +++ b/trunk/arch/um/os-Linux/sys-i386/tls.c @@ -1,9 +1,6 @@ #include #include - #include -#include - #include "sysdep/tls.h" #include "user_util.h" diff --git a/trunk/arch/um/os-Linux/time.c b/trunk/arch/um/os-Linux/time.c index 2115b8beb541..38be096e750f 100644 --- a/trunk/arch/um/os-Linux/time.c +++ b/trunk/arch/um/os-Linux/time.c @@ -16,7 +16,6 @@ #include "process.h" #include "kern_constants.h" #include "os.h" -#include "uml-config.h" int set_interval(int is_virtual) { @@ -31,7 +30,7 @@ int set_interval(int is_virtual) return 0; } -#ifdef UML_CONFIG_MODE_TT +#ifdef CONFIG_MODE_TT void enable_timer(void) { set_interval(1); diff --git a/trunk/arch/um/os-Linux/tls.c b/trunk/arch/um/os-Linux/tls.c index 16215b990804..a2de2580b8af 100644 --- a/trunk/arch/um/os-Linux/tls.c +++ b/trunk/arch/um/os-Linux/tls.c @@ -1,5 +1,4 @@ #include -#include #include #include #include diff --git a/trunk/arch/um/os-Linux/tt.c b/trunk/arch/um/os-Linux/tt.c index 3dc3a02d6263..5461a065bbb9 100644 --- a/trunk/arch/um/os-Linux/tt.c +++ b/trunk/arch/um/os-Linux/tt.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/um/os-Linux/util.c b/trunk/arch/um/os-Linux/util.c index 56b8a50e8bc2..3f5b1514e8a7 100644 --- a/trunk/arch/um/os-Linux/util.c +++ b/trunk/arch/um/os-Linux/util.c @@ -80,18 +80,11 @@ void setup_machinename(char *machine_out) struct utsname host; uname(&host); -#ifdef UML_CONFIG_UML_X86 -# ifndef UML_CONFIG_64BIT +#if defined(UML_CONFIG_UML_X86) && !defined(UML_CONFIG_64BIT) if (!strcmp(host.machine, "x86_64")) { strcpy(machine_out, "i686"); return; } -# else - if (!strcmp(host.machine, "i686")) { - strcpy(machine_out, "x86_64"); - return; - } -# endif #endif strcpy(machine_out, host.machine); } diff --git a/trunk/arch/um/sys-i386/unmap.c b/trunk/arch/um/sys-i386/unmap.c index 1b0ad0e4adcd..8e55cd5d3d07 100644 --- a/trunk/arch/um/sys-i386/unmap.c +++ b/trunk/arch/um/sys-i386/unmap.c @@ -5,20 +5,17 @@ #include #include +#include -static int errno; - -static inline _syscall2(int,munmap,void *,start,size_t,len) -static inline _syscall6(void *,mmap2,void *,addr,size_t,len,int,prot,int,flags,int,fd,off_t,offset) int switcheroo(int fd, int prot, void *from, void *to, int size) { - if(munmap(to, size) < 0){ + if (syscall(__NR_munmap, to, size) < 0){ return(-1); } - if(mmap2(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1 ){ + if (syscall(__NR_mmap2, to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1 ){ return(-1); } - if(munmap(from, size) < 0){ + if (syscall(__NR_munmap, from, size) < 0){ return(-1); } return(0); diff --git a/trunk/arch/um/sys-x86_64/ksyms.c b/trunk/arch/um/sys-x86_64/ksyms.c index 12c593607c59..859273808203 100644 --- a/trunk/arch/um/sys-x86_64/ksyms.c +++ b/trunk/arch/um/sys-x86_64/ksyms.c @@ -14,3 +14,6 @@ EXPORT_SYMBOL(__up_wakeup); /*XXX: we need them because they would be exported by x86_64 */ EXPORT_SYMBOL(__memcpy); + +/* Networking helper routines. */ +EXPORT_SYMBOL(ip_compute_csum); diff --git a/trunk/arch/um/sys-x86_64/stub_segv.c b/trunk/arch/um/sys-x86_64/stub_segv.c index 652fa34c2cd3..1c967026c957 100644 --- a/trunk/arch/um/sys-x86_64/stub_segv.c +++ b/trunk/arch/um/sys-x86_64/stub_segv.c @@ -5,6 +5,7 @@ #include #include +#include #include #include "uml-config.h" #include "sysdep/sigcontext.h" diff --git a/trunk/arch/um/sys-x86_64/unmap.c b/trunk/arch/um/sys-x86_64/unmap.c index f4a4bffd8a18..57c9286a701b 100644 --- a/trunk/arch/um/sys-x86_64/unmap.c +++ b/trunk/arch/um/sys-x86_64/unmap.c @@ -5,20 +5,17 @@ #include #include +#include -static int errno; - -static inline _syscall2(int,munmap,void *,start,size_t,len) -static inline _syscall6(void *,mmap,void *,addr,size_t,len,int,prot,int,flags,int,fd,off_t,offset) int switcheroo(int fd, int prot, void *from, void *to, int size) { - if(munmap(to, size) < 0){ + if (syscall(__NR_munmap, to, size) < 0){ return(-1); } - if(mmap(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1){ + if (syscall(__NR_mmap, to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1){ return(-1); } - if(munmap(from, size) < 0){ + if (syscall(__NR_munmap, from, size) < 0){ return(-1); } return(0); diff --git a/trunk/arch/v850/kernel/vmlinux.lds.S b/trunk/arch/v850/kernel/vmlinux.lds.S index 88d087f527c9..63399219cd9f 100644 --- a/trunk/arch/v850/kernel/vmlinux.lds.S +++ b/trunk/arch/v850/kernel/vmlinux.lds.S @@ -140,7 +140,13 @@ ___setup_end = . ; \ ___initcall_start = . ; \ *(.initcall.init) \ - INITCALLS \ + *(.initcall1.init) \ + *(.initcall2.init) \ + *(.initcall3.init) \ + *(.initcall4.init) \ + *(.initcall5.init) \ + *(.initcall6.init) \ + *(.initcall7.init) \ . = ALIGN (4) ; \ ___initcall_end = . ; \ ___con_initcall_start = .; \ diff --git a/trunk/arch/x86_64/Makefile b/trunk/arch/x86_64/Makefile index 6e38d4daeed7..1c0f18d4f887 100644 --- a/trunk/arch/x86_64/Makefile +++ b/trunk/arch/x86_64/Makefile @@ -54,10 +54,6 @@ endif cflags-y += $(call cc-option,-funit-at-a-time) # prevent gcc from generating any FP code by mistake cflags-y += $(call cc-option,-mno-sse -mno-mmx -mno-sse2 -mno-3dnow,) -# this works around some issues with generating unwind tables in older gccs -# newer gccs do it by default -cflags-y += -maccumulate-outgoing-args - # do binutils support CFI? cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) @@ -66,8 +62,8 @@ AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) cflags-y += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,) AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,) -cflags-$(CONFIG_CC_STACKPROTECTOR) += $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-x86_64-has-stack-protector.sh "$(CC)" -fstack-protector ) -cflags-$(CONFIG_CC_STACKPROTECTOR_ALL) += $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-x86_64-has-stack-protector.sh "$(CC)" -fstack-protector-all ) +cflags-$(CONFIG_CC_STACKPROTECTOR) += $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-x86_64-has-stack-protector.sh $(CC) -fstack-protector ) +cflags-$(CONFIG_CC_STACKPROTECTOR_ALL) += $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-x86_64-has-stack-protector.sh $(CC) -fstack-protector-all ) CFLAGS += $(cflags-y) CFLAGS_KERNEL += $(cflags-kernel-y) diff --git a/trunk/arch/x86_64/boot/setup.S b/trunk/arch/x86_64/boot/setup.S index 770940cc0108..c3bfd223ab49 100644 --- a/trunk/arch/x86_64/boot/setup.S +++ b/trunk/arch/x86_64/boot/setup.S @@ -836,12 +836,13 @@ gdt: .word 0x9200 # data read/write .word 0x00CF # granularity = 4096, 386 # (+5th nibble of limit) -gdt_end: idt_48: .word 0 # idt limit = 0 .word 0, 0 # idt base = 0L gdt_48: - .word gdt_end-gdt-1 # gdt limit + .word 0x8000 # gdt limit=2048, + # 256 GDT entries + .word 0, 0 # gdt base (filled in later) # Include video setup & detection code diff --git a/trunk/arch/x86_64/defconfig b/trunk/arch/x86_64/defconfig index 0f5d44e86be5..4844b543bed0 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-rc2-git4 -# Sat Oct 21 03:38:52 2006 +# Linux kernel version: 2.6.18-git7 +# Wed Sep 27 21:53:10 2006 # CONFIG_X86_64=y CONFIG_64BIT=y @@ -19,7 +19,6 @@ CONFIG_EARLY_PRINTK=y CONFIG_GENERIC_ISA_DMA=y CONFIG_GENERIC_IOMAP=y CONFIG_ARCH_MAY_HAVE_PC_FDC=y -CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_DMI=y CONFIG_AUDIT_ARCH=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" @@ -38,11 +37,9 @@ CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set CONFIG_POSIX_MQUEUE=y # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y @@ -50,10 +47,9 @@ CONFIG_IKCONFIG_PROC=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 is not set +CONFIG_SYSCTL=y CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y # CONFIG_KALLSYMS_EXTRA_PASS is not set @@ -86,7 +82,6 @@ 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 @@ -257,11 +252,9 @@ CONFIG_PCI=y CONFIG_PCI_DIRECT=y CONFIG_PCI_MMCONFIG=y CONFIG_PCIEPORTBUS=y -CONFIG_PCIEAER=y CONFIG_PCI_MSI=y # CONFIG_PCI_MULTITHREAD_PROBE is not set # CONFIG_PCI_DEBUG is not set -# CONFIG_HT_IRQ is not set # # PCCARD (PCMCIA/CardBus) support @@ -316,7 +309,6 @@ CONFIG_IP_PNP_DHCP=y # CONFIG_INET_TUNNEL is not set # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set @@ -333,10 +325,9 @@ CONFIG_IPV6=y # CONFIG_INET6_TUNNEL is not set # CONFIG_INET6_XFRM_MODE_TRANSPORT is not set # CONFIG_INET6_XFRM_MODE_TUNNEL is not set -# CONFIG_INET6_XFRM_MODE_BEET is not set # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set -CONFIG_IPV6_SIT=y # CONFIG_IPV6_TUNNEL is not set +# CONFIG_IPV6_SUBTREES is not set # CONFIG_IPV6_MULTIPLE_TABLES is not set # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set @@ -437,13 +428,6 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set -# -# Misc devices -# -# CONFIG_IBM_ASM is not set -# CONFIG_SGI_IOC4 is not set -# CONFIG_TIFM_CORE is not set - # # ATA/ATAPI/MFM/RLL support # @@ -489,7 +473,6 @@ CONFIG_BLK_DEV_ATIIXP=y # CONFIG_BLK_DEV_CS5530 is not set # CONFIG_BLK_DEV_HPT34X is not set # CONFIG_BLK_DEV_HPT366 is not set -# CONFIG_BLK_DEV_JMICRON is not set # CONFIG_BLK_DEV_SC1200 is not set CONFIG_BLK_DEV_PIIX=y # CONFIG_BLK_DEV_IT821X is not set @@ -581,7 +564,6 @@ CONFIG_MEGARAID_SAS=y # CONFIG_SCSI_IPR is not set # CONFIG_SCSI_QLOGIC_1280 is not set # CONFIG_SCSI_QLA_FC is not set -# CONFIG_SCSI_QLA_ISCSI is not set # CONFIG_SCSI_LPFC is not set # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set @@ -623,6 +605,7 @@ CONFIG_SATA_INTEL_COMBINED=y # CONFIG_PATA_HPT3X3 is not set # CONFIG_PATA_IT821X is not set # CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_LEGACY is not set # CONFIG_PATA_TRIFLEX is not set # CONFIG_PATA_MPIIX is not set # CONFIG_PATA_OLDPIIX is not set @@ -631,6 +614,7 @@ CONFIG_SATA_INTEL_COMBINED=y # CONFIG_PATA_OPTI is not set # CONFIG_PATA_OPTIDMA is not set # CONFIG_PATA_PDC_OLD is not set +# CONFIG_PATA_QDI is not set # CONFIG_PATA_RADISYS is not set # CONFIG_PATA_RZ1000 is not set # CONFIG_PATA_SC1200 is not set @@ -647,7 +631,6 @@ CONFIG_SATA_INTEL_COMBINED=y CONFIG_MD=y # CONFIG_BLK_DEV_MD is not set CONFIG_BLK_DEV_DM=y -# CONFIG_DM_DEBUG is not set # CONFIG_DM_CRYPT is not set # CONFIG_DM_SNAPSHOT is not set # CONFIG_DM_MIRROR is not set @@ -836,7 +819,6 @@ CONFIG_NET_POLL_CONTROLLER=y # Input device support # CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set # # Userland interfaces @@ -859,7 +841,6 @@ CONFIG_KEYBOARD_ATKBD=y # CONFIG_KEYBOARD_LKKBD is not set # CONFIG_KEYBOARD_XTKBD is not set # CONFIG_KEYBOARD_NEWTON is not set -# CONFIG_KEYBOARD_STOWAWAY is not set CONFIG_INPUT_MOUSE=y CONFIG_MOUSE_PS2=y # CONFIG_MOUSE_SERIAL is not set @@ -1015,7 +996,6 @@ CONFIG_I2C_ISA=m # # Dallas's 1-wire bus # -# CONFIG_W1 is not set # # Hardware Monitoring support @@ -1028,7 +1008,6 @@ CONFIG_HWMON=y # CONFIG_SENSORS_ADM1026 is not set # CONFIG_SENSORS_ADM1031 is not set # CONFIG_SENSORS_ADM9240 is not set -# CONFIG_SENSORS_K8TEMP is not set # CONFIG_SENSORS_ASB100 is not set # CONFIG_SENSORS_ATXP1 is not set # CONFIG_SENSORS_DS1621 is not set @@ -1055,7 +1034,6 @@ CONFIG_HWMON=y # CONFIG_SENSORS_SMSC47M192 is not set CONFIG_SENSORS_SMSC47B397=m # CONFIG_SENSORS_VIA686A is not set -# CONFIG_SENSORS_VT1211 is not set # CONFIG_SENSORS_VT8231 is not set # CONFIG_SENSORS_W83781D is not set # CONFIG_SENSORS_W83791D is not set @@ -1066,10 +1044,16 @@ CONFIG_SENSORS_SMSC47B397=m # CONFIG_SENSORS_HDAPS is not set # CONFIG_HWMON_DEBUG_CHIP is not set +# +# Misc devices +# +# CONFIG_IBM_ASM is not set + # # Multimedia devices # # CONFIG_VIDEO_DEV is not set +CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices @@ -1175,7 +1159,6 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_STORAGE_SDDR55 is not set # CONFIG_USB_STORAGE_JUMPSHOT is not set # CONFIG_USB_STORAGE_ALAUDA is not set -# CONFIG_USB_STORAGE_KARMA is not set # CONFIG_USB_LIBUSUAL is not set # @@ -1229,7 +1212,6 @@ CONFIG_USB_MON=y # # CONFIG_USB_EMI62 is not set # CONFIG_USB_EMI26 is not set -# CONFIG_USB_ADUTUX is not set # CONFIG_USB_AUERSWALD is not set # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set @@ -1237,13 +1219,12 @@ CONFIG_USB_MON=y # CONFIG_USB_LED is not set # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set -# CONFIG_USB_PHIDGET is not set +# CONFIG_USB_PHIDGETKIT is not set +# CONFIG_USB_PHIDGETSERVO is not set # CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_FTDI_ELAN is not set # CONFIG_USB_APPLEDISPLAY is not set # CONFIG_USB_SISUSBVGA is not set # CONFIG_USB_LD is not set -# CONFIG_USB_TRANCEVIBRATOR is not set # CONFIG_USB_TEST is not set # @@ -1320,7 +1301,6 @@ CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y CONFIG_EXT3_FS_POSIX_ACL=y # CONFIG_EXT3_FS_SECURITY is not set -# CONFIG_EXT4DEV_FS is not set CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set CONFIG_FS_MBCACHE=y @@ -1333,7 +1313,6 @@ CONFIG_REISERFS_FS_POSIX_ACL=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set @@ -1344,7 +1323,6 @@ CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set CONFIG_AUTOFS4_FS=y # CONFIG_FUSE_FS is not set -CONFIG_GENERIC_ACL=y # # CD-ROM/DVD Filesystems @@ -1369,10 +1347,8 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" # CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y -CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y CONFIG_TMPFS=y -CONFIG_TMPFS_POSIX_ACL=y CONFIG_HUGETLBFS=y CONFIG_HUGETLB_PAGE=y CONFIG_RAMFS=y @@ -1506,14 +1482,11 @@ CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_DEBUG_INFO is not set CONFIG_DEBUG_FS=y # CONFIG_DEBUG_VM is not set -# CONFIG_DEBUG_LIST is not set # CONFIG_FRAME_POINTER is not set CONFIG_UNWIND_INFO=y CONFIG_STACK_UNWIND=y # CONFIG_FORCED_INLINING is not set -# CONFIG_HEADERS_CHECK is not set # CONFIG_RCU_TORTURE_TEST is not set -# CONFIG_LKDTM is not set # CONFIG_DEBUG_RODATA is not set # CONFIG_IOMMU_DEBUG is not set CONFIG_DEBUG_STACKOVERFLOW=y diff --git a/trunk/arch/x86_64/ia32/ia32_signal.c b/trunk/arch/x86_64/ia32/ia32_signal.c index 0e0a266d976f..a6ba9951e86c 100644 --- a/trunk/arch/x86_64/ia32/ia32_signal.c +++ b/trunk/arch/x86_64/ia32/ia32_signal.c @@ -579,11 +579,6 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, regs->rsp = (unsigned long) frame; regs->rip = (unsigned long) ka->sa.sa_handler; - /* 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/ptrace32.c b/trunk/arch/x86_64/ia32/ptrace32.c index 04566fe5de49..d18198ed636b 100644 --- a/trunk/arch/x86_64/ia32/ptrace32.c +++ b/trunk/arch/x86_64/ia32/ptrace32.c @@ -205,9 +205,9 @@ static int getreg32(struct task_struct *child, unsigned regno, u32 *val) static long ptrace32_siginfo(unsigned request, u32 pid, u32 addr, u32 data) { int ret; - compat_siginfo_t __user *si32 = compat_ptr(data); + compat_siginfo_t *si32 = (compat_siginfo_t *)compat_ptr(data); siginfo_t ssi; - siginfo_t __user *si = compat_alloc_user_space(sizeof(siginfo_t)); + siginfo_t *si = compat_alloc_user_space(sizeof(siginfo_t)); if (request == PTRACE_SETSIGINFO) { memset(&ssi, 0, sizeof(siginfo_t)); ret = copy_siginfo_from_user32(&ssi, si32); @@ -244,8 +244,6 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data) case PTRACE_DETACH: case PTRACE_SYSCALL: case PTRACE_SETOPTIONS: - case PTRACE_SET_THREAD_AREA: - case PTRACE_GET_THREAD_AREA: return sys_ptrace(request, pid, addr, data); default: diff --git a/trunk/arch/x86_64/kernel/apic.c b/trunk/arch/x86_64/kernel/apic.c index 4d9d5ed942b2..6472e321cad7 100644 --- a/trunk/arch/x86_64/kernel/apic.c +++ b/trunk/arch/x86_64/kernel/apic.c @@ -885,14 +885,14 @@ void setup_APIC_extened_lvt(unsigned char lvt_off, unsigned char vector, * value into /proc/profile. */ -void smp_local_timer_interrupt(void) +void smp_local_timer_interrupt(struct pt_regs *regs) { - profile_tick(CPU_PROFILING); + profile_tick(CPU_PROFILING, regs); #ifdef CONFIG_SMP - update_process_times(user_mode(get_irq_regs())); + update_process_times(user_mode(regs)); #endif if (apic_runs_main_timer > 1 && smp_processor_id() == boot_cpu_id) - main_timer_handler(); + main_timer_handler(regs); /* * We take the 'long' return path, and there every subsystem * grabs the appropriate locks (kernel lock/ irq lock). @@ -915,8 +915,6 @@ void smp_local_timer_interrupt(void) */ void smp_apic_timer_interrupt(struct pt_regs *regs) { - struct pt_regs *old_regs = set_irq_regs(regs); - /* * the NMI deadlock-detector uses this. */ @@ -934,9 +932,8 @@ void smp_apic_timer_interrupt(struct pt_regs *regs) */ exit_idle(); irq_enter(); - smp_local_timer_interrupt(); + smp_local_timer_interrupt(regs); irq_exit(); - set_irq_regs(old_regs); } /* diff --git a/trunk/arch/x86_64/kernel/e820.c b/trunk/arch/x86_64/kernel/e820.c index 6fe191c58084..b3f0908668ec 100644 --- a/trunk/arch/x86_64/kernel/e820.c +++ b/trunk/arch/x86_64/kernel/e820.c @@ -54,13 +54,13 @@ static inline int bad_addr(unsigned long *addrp, unsigned long size) /* various gunk below that needed for SMP startup */ if (addr < 0x8000) { - *addrp = PAGE_ALIGN(0x8000); + *addrp = 0x8000; return 1; } /* direct mapping tables of the kernel */ if (last >= table_start<= INITRD_START && addr < INITRD_START+INITRD_SIZE) { - *addrp = PAGE_ALIGN(INITRD_START + INITRD_SIZE); + *addrp = INITRD_START + INITRD_SIZE; return 1; } #endif /* kernel code */ - if (last >= __pa_symbol(&_text) && addr < __pa_symbol(&_end)) { - *addrp = PAGE_ALIGN(__pa_symbol(&_end)); + if (last >= __pa_symbol(&_text) && last < __pa_symbol(&_end)) { + *addrp = __pa_symbol(&_end); return 1; } if (last >= ebda_addr && addr < ebda_addr + ebda_size) { - *addrp = PAGE_ALIGN(ebda_addr + ebda_size); + *addrp = ebda_addr + ebda_size; return 1; } @@ -152,7 +152,7 @@ unsigned long __init find_e820_area(unsigned long start, unsigned long end, unsi continue; while (bad_addr(&addr, size) && addr+size <= ei->addr+ei->size) ; - last = PAGE_ALIGN(addr) + size; + last = addr + size; if (last > ei->addr + ei->size) continue; if (last > end) @@ -278,7 +278,7 @@ e820_register_active_regions(int nid, unsigned long start_pfn, >> PAGE_SHIFT; /* Skip map entries smaller than a page */ - if (ei_startpfn >= ei_endpfn) + if (ei_startpfn > ei_endpfn) continue; /* Check if end_pfn_map should be updated */ @@ -594,9 +594,7 @@ static int __init parse_memmap_opt(char *p) * size before original memory map is * reset. */ - e820_register_active_regions(0, 0, -1UL); saved_max_pfn = e820_end_of_ram(); - remove_all_active_ranges(); #endif end_pfn_map = 0; e820.nr_map = 0; diff --git a/trunk/arch/x86_64/kernel/early-quirks.c b/trunk/arch/x86_64/kernel/early-quirks.c index 68273bff58cc..208e38a372c1 100644 --- a/trunk/arch/x86_64/kernel/early-quirks.c +++ b/trunk/arch/x86_64/kernel/early-quirks.c @@ -45,13 +45,7 @@ static void nvidia_bugs(void) /* * All timer overrides on Nvidia are * wrong unless HPET is enabled. - * Unfortunately that's not true on many Asus boards. - * We don't know yet how to detect this automatically, but - * at least allow a command line override. */ - if (acpi_use_timer_override) - return; - nvidia_hpet_detected = 0; acpi_table_parse(ACPI_HPET, nvidia_hpet_check); if (nvidia_hpet_detected == 0) { @@ -59,8 +53,6 @@ static void nvidia_bugs(void) printk(KERN_INFO "Nvidia board " "detected. Ignoring ACPI " "timer override.\n"); - printk(KERN_INFO "If you got timer trouble " - "try acpi_use_timer_override\n"); } #endif /* RED-PEN skip them on mptables too? */ @@ -69,11 +61,10 @@ static void nvidia_bugs(void) static void ati_bugs(void) { - if (timer_over_8254 == 1) { - timer_over_8254 = 0; - printk(KERN_INFO - "ATI board detected. Disabling timer routing over 8254.\n"); - } +#if 1 /* for testing */ + printk("ATI board detected\n"); +#endif + /* No bugs right now */ } struct chipset { diff --git a/trunk/arch/x86_64/kernel/early_printk.c b/trunk/arch/x86_64/kernel/early_printk.c index 47b6d90349da..e22ecd54870d 100644 --- a/trunk/arch/x86_64/kernel/early_printk.c +++ b/trunk/arch/x86_64/kernel/early_printk.c @@ -224,7 +224,7 @@ static int __init setup_early_printk(char *buf) return 0; early_console_initialized = 1; - if (strstr(buf, "keep")) + if (!strcmp(buf,"keep")) keep_early = 1; if (!strncmp(buf, "serial", 6)) { diff --git a/trunk/arch/x86_64/kernel/entry.S b/trunk/arch/x86_64/kernel/entry.S index 7d401b00d822..b8285cf1a9c3 100644 --- a/trunk/arch/x86_64/kernel/entry.S +++ b/trunk/arch/x86_64/kernel/entry.S @@ -315,8 +315,6 @@ tracesys: LOAD_ARGS ARGOFFSET /* reload args from stack in case ptrace changed it */ RESTORE_REST cmpq $__NR_syscall_max,%rax - movq $-ENOSYS,%rcx - cmova %rcx,%rax ja 1f movq %r10,%rcx /* fixup for C */ call *sys_call_table(,%rax,8) diff --git a/trunk/arch/x86_64/kernel/genapic_cluster.c b/trunk/arch/x86_64/kernel/genapic_cluster.c index 73d76308b955..cdb90e671b88 100644 --- a/trunk/arch/x86_64/kernel/genapic_cluster.c +++ b/trunk/arch/x86_64/kernel/genapic_cluster.c @@ -63,13 +63,6 @@ static cpumask_t cluster_target_cpus(void) return cpumask_of_cpu(0); } -static cpumask_t cluster_vector_allocation_domain(int cpu) -{ - cpumask_t domain = CPU_MASK_NONE; - cpu_set(cpu, domain); - return domain; -} - static void cluster_send_IPI_mask(cpumask_t mask, int vector) { send_IPI_mask_sequence(mask, vector); @@ -126,7 +119,6 @@ struct genapic apic_cluster = { .int_delivery_mode = dest_Fixed, .int_dest_mode = (APIC_DEST_PHYSICAL != 0), .target_cpus = cluster_target_cpus, - .vector_allocation_domain = cluster_vector_allocation_domain, .apic_id_registered = cluster_apic_id_registered, .init_apic_ldr = cluster_init_apic_ldr, .send_IPI_all = cluster_send_IPI_all, diff --git a/trunk/arch/x86_64/kernel/genapic_flat.c b/trunk/arch/x86_64/kernel/genapic_flat.c index 7c01db8fa9d1..50ad153eaac4 100644 --- a/trunk/arch/x86_64/kernel/genapic_flat.c +++ b/trunk/arch/x86_64/kernel/genapic_flat.c @@ -22,20 +22,6 @@ static cpumask_t flat_target_cpus(void) return cpu_online_map; } -static cpumask_t flat_vector_allocation_domain(int cpu) -{ - /* Careful. Some cpus do not strictly honor the set of cpus - * specified in the interrupt destination when using lowest - * priority interrupt delivery mode. - * - * In particular there was a hyperthreading cpu observed to - * deliver interrupts to the wrong hyperthread when only one - * hyperthread was specified in the interrupt desitination. - */ - cpumask_t domain = { { [0] = APIC_ALL_CPUS, } }; - return domain; -} - /* * Set up the logical destination ID. * @@ -135,7 +121,6 @@ struct genapic apic_flat = { .int_delivery_mode = dest_LowestPrio, .int_dest_mode = (APIC_DEST_LOGICAL != 0), .target_cpus = flat_target_cpus, - .vector_allocation_domain = flat_vector_allocation_domain, .apic_id_registered = flat_apic_id_registered, .init_apic_ldr = flat_init_apic_ldr, .send_IPI_all = flat_send_IPI_all, @@ -153,17 +138,9 @@ struct genapic apic_flat = { static cpumask_t physflat_target_cpus(void) { - return cpu_online_map; + return cpumask_of_cpu(0); } -static cpumask_t physflat_vector_allocation_domain(int cpu) -{ - cpumask_t domain = CPU_MASK_NONE; - cpu_set(cpu, domain); - return domain; -} - - static void physflat_send_IPI_mask(cpumask_t cpumask, int vector) { send_IPI_mask_sequence(cpumask, vector); @@ -202,7 +179,6 @@ struct genapic apic_physflat = { .int_delivery_mode = dest_Fixed, .int_dest_mode = (APIC_DEST_PHYSICAL != 0), .target_cpus = physflat_target_cpus, - .vector_allocation_domain = physflat_vector_allocation_domain, .apic_id_registered = flat_apic_id_registered, .init_apic_ldr = flat_init_apic_ldr,/*not needed, but shouldn't hurt*/ .send_IPI_all = physflat_send_IPI_all, diff --git a/trunk/arch/x86_64/kernel/i8259.c b/trunk/arch/x86_64/kernel/i8259.c index c4ef801b765b..0612a33bb896 100644 --- a/trunk/arch/x86_64/kernel/i8259.c +++ b/trunk/arch/x86_64/kernel/i8259.c @@ -178,8 +178,7 @@ void make_8259A_irq(unsigned int irq) { disable_irq_nosync(irq); io_apic_irqs &= ~(1< #include -static int assign_irq_vector(int irq, cpumask_t mask, cpumask_t *result); +static int assign_irq_vector(int irq, cpumask_t mask); #define __apicdebuginit __init @@ -57,13 +57,13 @@ static int no_timer_check; static int disable_timer_pin_1 __initdata; -int timer_over_8254 __initdata = 1; +int timer_over_8254 __initdata = 0; /* Where if anywhere is the i8259 connect in external int mode */ static struct { int pin, apic; } ioapic_i8259 = { -1, -1 }; static DEFINE_SPINLOCK(ioapic_lock); -DEFINE_SPINLOCK(vector_lock); +static DEFINE_SPINLOCK(vector_lock); /* * # of IRQ routing registers @@ -88,52 +88,6 @@ static struct irq_pin_list { short apic, pin, next; } irq_2_pin[PIN_MAP_SIZE]; -struct io_apic { - unsigned int index; - unsigned int unused[3]; - unsigned int data; -}; - -static __attribute_const__ struct io_apic __iomem *io_apic_base(int idx) -{ - return (void __iomem *) __fix_to_virt(FIX_IO_APIC_BASE_0 + idx) - + (mp_ioapics[idx].mpc_apicaddr & ~PAGE_MASK); -} - -static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg) -{ - struct io_apic __iomem *io_apic = io_apic_base(apic); - writel(reg, &io_apic->index); - return readl(&io_apic->data); -} - -static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned int value) -{ - struct io_apic __iomem *io_apic = io_apic_base(apic); - writel(reg, &io_apic->index); - writel(value, &io_apic->data); -} - -/* - * Re-write a value: to be used for read-modify-write - * cycles where the read already set up the index register. - */ -static inline void io_apic_modify(unsigned int apic, unsigned int value) -{ - struct io_apic __iomem *io_apic = io_apic_base(apic); - writel(value, &io_apic->data); -} - -/* - * Synchronize the IO-APIC and the CPU by doing - * a dummy read from the IO-APIC - */ -static inline void io_apic_sync(unsigned int apic) -{ - struct io_apic __iomem *io_apic = io_apic_base(apic); - readl(&io_apic->data); -} - #define __DO_ACTION(R, ACTION, FINAL) \ \ { \ @@ -172,33 +126,11 @@ static struct IO_APIC_route_entry ioapic_read_entry(int apic, int pin) return eu.entry; } -/* - * When we write a new IO APIC routing entry, we need to write the high - * word first! If the mask bit in the low word is clear, we will enable - * 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) { 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); - spin_unlock_irqrestore(&ioapic_lock, flags); -} - -/* - * When we mask an IO APIC routing entry, we need to write the low - * word first, in order to set the mask bit before we change the - * high bits! - */ -static void ioapic_mask_entry(int apic, int pin) -{ - unsigned long flags; - union entry_union eu = { .entry.mask = 1 }; - spin_lock_irqsave(&ioapic_lock, flags); io_apic_write(apic, 0x10 + 2*pin, eu.w1); io_apic_write(apic, 0x11 + 2*pin, eu.w2); @@ -242,10 +174,12 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t mask) cpus_and(mask, tmp, CPU_MASK_ALL); - vector = assign_irq_vector(irq, mask, &tmp); + vector = assign_irq_vector(irq, mask); if (vector < 0) return; + cpus_clear(tmp); + cpu_set(vector >> 8, tmp); dest = cpu_mask_to_apicid(tmp); /* @@ -254,7 +188,7 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t mask) dest = SET_APIC_LOGICAL_ID(dest); spin_lock_irqsave(&ioapic_lock, flags); - __target_IO_APIC_irq(irq, dest, vector); + __target_IO_APIC_irq(irq, dest, vector & 0xff); set_native_irq_info(irq, mask); spin_unlock_irqrestore(&ioapic_lock, flags); } @@ -324,7 +258,9 @@ static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin) /* * Disable it in the IO-APIC irq-routing table: */ - ioapic_mask_entry(apic, pin); + memset(&entry, 0, sizeof(entry)); + entry.mask = 1; + ioapic_write_entry(apic, pin, entry); } static void clear_IO_APIC (void) @@ -627,45 +563,9 @@ 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 = { - [0] = FIRST_EXTERNAL_VECTOR + 0, - [1] = FIRST_EXTERNAL_VECTOR + 1, - [2] = FIRST_EXTERNAL_VECTOR + 2, - [3] = FIRST_EXTERNAL_VECTOR + 3, - [4] = FIRST_EXTERNAL_VECTOR + 4, - [5] = FIRST_EXTERNAL_VECTOR + 5, - [6] = FIRST_EXTERNAL_VECTOR + 6, - [7] = FIRST_EXTERNAL_VECTOR + 7, - [8] = FIRST_EXTERNAL_VECTOR + 8, - [9] = FIRST_EXTERNAL_VECTOR + 9, - [10] = FIRST_EXTERNAL_VECTOR + 10, - [11] = FIRST_EXTERNAL_VECTOR + 11, - [12] = FIRST_EXTERNAL_VECTOR + 12, - [13] = FIRST_EXTERNAL_VECTOR + 13, - [14] = FIRST_EXTERNAL_VECTOR + 14, - [15] = FIRST_EXTERNAL_VECTOR + 15, -}; - -static cpumask_t irq_domain[NR_IRQ_VECTORS] __read_mostly = { - [0] = CPU_MASK_ALL, - [1] = CPU_MASK_ALL, - [2] = CPU_MASK_ALL, - [3] = CPU_MASK_ALL, - [4] = CPU_MASK_ALL, - [5] = CPU_MASK_ALL, - [6] = CPU_MASK_ALL, - [7] = CPU_MASK_ALL, - [8] = CPU_MASK_ALL, - [9] = CPU_MASK_ALL, - [10] = CPU_MASK_ALL, - [11] = CPU_MASK_ALL, - [12] = CPU_MASK_ALL, - [13] = CPU_MASK_ALL, - [14] = CPU_MASK_ALL, - [15] = CPU_MASK_ALL, -}; +unsigned int irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_EXTERNAL_VECTOR, 0 }; -static int __assign_irq_vector(int irq, cpumask_t mask, cpumask_t *result) +static int __assign_irq_vector(int irq, cpumask_t mask) { /* * NOTE! The local APIC isn't very good at handling @@ -678,33 +578,25 @@ static int __assign_irq_vector(int irq, cpumask_t mask, cpumask_t *result) * Also, we've got to be careful not to trash gate * 0x80, because int 0x80 is hm, kind of importantish. ;) */ - static int current_vector = FIRST_DEVICE_VECTOR, current_offset = 0; + static struct { + int vector; + int offset; + } pos[NR_CPUS] = { [ 0 ... NR_CPUS - 1] = {FIRST_DEVICE_VECTOR, 0} }; int old_vector = -1; int cpu; BUG_ON((unsigned)irq >= NR_IRQ_VECTORS); - /* Only try and allocate irqs on cpus that are present */ - cpus_and(mask, mask, cpu_online_map); - - if (irq_vector[irq] > 0) - old_vector = irq_vector[irq]; - if (old_vector > 0) { - cpus_and(*result, irq_domain[irq], mask); - if (!cpus_empty(*result)) - return old_vector; + if (IO_APIC_VECTOR(irq) > 0) + old_vector = IO_APIC_VECTOR(irq); + if ((old_vector > 0) && cpu_isset(old_vector >> 8, mask)) { + return old_vector; } for_each_cpu_mask(cpu, mask) { - cpumask_t domain, new_mask; - int new_cpu; int vector, offset; - - domain = vector_allocation_domain(cpu); - cpus_and(new_mask, domain, cpu_online_map); - - vector = current_vector; - offset = current_offset; + vector = pos[cpu].vector; + offset = pos[cpu].offset; next: vector += 8; if (vector >= FIRST_SYSTEM_VECTOR) { @@ -712,68 +604,39 @@ static int __assign_irq_vector(int irq, cpumask_t mask, cpumask_t *result) offset = (offset + 1) % 8; vector = FIRST_DEVICE_VECTOR + offset; } - if (unlikely(current_vector == vector)) + if (unlikely(pos[cpu].vector == vector)) continue; if (vector == IA32_SYSCALL_VECTOR) goto next; - for_each_cpu_mask(new_cpu, new_mask) - if (per_cpu(vector_irq, new_cpu)[vector] != -1) - goto next; + if (per_cpu(vector_irq, cpu)[vector] != -1) + goto next; /* Found one! */ - current_vector = vector; - current_offset = offset; + pos[cpu].vector = vector; + pos[cpu].offset = offset; if (old_vector >= 0) { - cpumask_t old_mask; - int old_cpu; - cpus_and(old_mask, irq_domain[irq], cpu_online_map); - for_each_cpu_mask(old_cpu, old_mask) - per_cpu(vector_irq, old_cpu)[old_vector] = -1; + int old_cpu = old_vector >> 8; + old_vector &= 0xff; + per_cpu(vector_irq, old_cpu)[old_vector] = -1; } - for_each_cpu_mask(new_cpu, new_mask) - per_cpu(vector_irq, new_cpu)[vector] = irq; - irq_vector[irq] = vector; - irq_domain[irq] = domain; - cpus_and(*result, domain, mask); + per_cpu(vector_irq, cpu)[vector] = irq; + vector |= cpu << 8; + IO_APIC_VECTOR(irq) = vector; return vector; } return -ENOSPC; } -static int assign_irq_vector(int irq, cpumask_t mask, cpumask_t *result) +static int assign_irq_vector(int irq, cpumask_t mask) { int vector; unsigned long flags; spin_lock_irqsave(&vector_lock, flags); - vector = __assign_irq_vector(irq, mask, result); + vector = __assign_irq_vector(irq, mask); spin_unlock_irqrestore(&vector_lock, flags); return vector; } -void __setup_vector_irq(int cpu) -{ - /* Initialize vector_irq on a new cpu */ - /* This function must be called with vector_lock held */ - int irq, vector; - - /* Mark the inuse vectors */ - for (irq = 0; irq < NR_IRQ_VECTORS; ++irq) { - if (!cpu_isset(cpu, irq_domain[irq])) - continue; - vector = irq_vector[irq]; - per_cpu(vector_irq, cpu)[vector] = irq; - } - /* Mark the free vectors */ - for (vector = 0; vector < NR_VECTORS; ++vector) { - irq = per_cpu(vector_irq, cpu)[vector]; - if (irq < 0) - continue; - if (!cpu_isset(cpu, irq_domain[irq])) - per_cpu(vector_irq, cpu)[vector] = -1; - } -} - - extern void (*interrupt[NR_IRQS])(void); static struct irq_chip ioapic_chip; @@ -786,13 +649,11 @@ static void ioapic_register_intr(int irq, int vector, unsigned long trigger) { if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || trigger == IOAPIC_LEVEL) - set_irq_chip_and_handler_name(irq, &ioapic_chip, - handle_fasteoi_irq, "fasteoi"); - else { - irq_desc[irq].status |= IRQ_DELAYED_DISABLE; - set_irq_chip_and_handler_name(irq, &ioapic_chip, - handle_edge_irq, "edge"); - } + set_irq_chip_and_handler(irq, &ioapic_chip, + handle_fasteoi_irq); + else + set_irq_chip_and_handler(irq, &ioapic_chip, + handle_edge_irq); } static void __init setup_IO_APIC_irqs(void) @@ -843,12 +704,14 @@ static void __init setup_IO_APIC_irqs(void) if (IO_APIC_IRQ(irq)) { cpumask_t mask; - vector = assign_irq_vector(irq, TARGET_CPUS, &mask); + vector = assign_irq_vector(irq, TARGET_CPUS); if (vector < 0) continue; + cpus_clear(mask); + cpu_set(vector >> 8, mask); entry.dest.logical.logical_dest = cpu_mask_to_apicid(mask); - entry.vector = vector; + entry.vector = vector & 0xff; ioapic_register_intr(irq, vector, IOAPIC_AUTO); if (!apic && (irq < 16)) @@ -898,7 +761,7 @@ static void __init setup_ExtINT_IRQ0_pin(unsigned int apic, unsigned int pin, in * The timer IRQ doesn't have to know that behind the * scene we have a 8259A-master in AEOI mode ... */ - set_irq_chip_and_handler_name(0, &ioapic_chip, handle_edge_irq, "edge"); + set_irq_chip_and_handler(0, &ioapic_chip, handle_edge_irq); /* * Add it to the IO-APIC irq-routing table: @@ -1347,15 +1210,12 @@ static int ioapic_retrigger_irq(unsigned int irq) { cpumask_t mask; unsigned vector; - unsigned long flags; - spin_lock_irqsave(&vector_lock, flags); vector = irq_vector[irq]; cpus_clear(mask); - cpu_set(first_cpu(irq_domain[irq]), mask); + cpu_set(vector >> 8, mask); - send_IPI_mask(mask, vector); - spin_unlock_irqrestore(&vector_lock, flags); + send_IPI_mask(mask, vector & 0xff); return 1; } @@ -1429,7 +1289,7 @@ static inline void init_IO_APIC_traps(void) */ for (irq = 0; irq < NR_IRQS ; irq++) { int tmp = irq; - if (IO_APIC_IRQ(tmp) && !irq_vector[tmp]) { + if (IO_APIC_IRQ(tmp) && !IO_APIC_VECTOR(tmp)) { /* * Hmm.. We don't have an entry for this, * so default to an old-fashioned 8259 @@ -1570,13 +1430,12 @@ static inline void check_timer(void) { int apic1, pin1, apic2, pin2; int vector; - cpumask_t mask; /* * get/set the timer IRQ vector: */ disable_8259A_irq(0); - vector = assign_irq_vector(0, TARGET_CPUS, &mask); + vector = assign_irq_vector(0, TARGET_CPUS); /* * Subtle, code in do_timer_interrupt() expects an AEOI @@ -1808,7 +1667,6 @@ int create_irq(void) int new; int vector = 0; unsigned long flags; - cpumask_t mask; irq = -ENOSPC; spin_lock_irqsave(&vector_lock, flags); @@ -1817,7 +1675,7 @@ int create_irq(void) continue; if (irq_vector[new] != 0) continue; - vector = __assign_irq_vector(new, TARGET_CPUS, &mask); + vector = __assign_irq_vector(new, TARGET_CPUS); if (likely(vector > 0)) irq = new; break; @@ -1849,10 +1707,13 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_ms { int vector; unsigned dest; - cpumask_t tmp; - vector = assign_irq_vector(irq, TARGET_CPUS, &tmp); + vector = assign_irq_vector(irq, TARGET_CPUS); if (vector >= 0) { + cpumask_t tmp; + + cpus_clear(tmp); + cpu_set(vector >> 8, tmp); dest = cpu_mask_to_apicid(tmp); msg->address_hi = MSI_ADDR_BASE_HI; @@ -1891,10 +1752,12 @@ static void set_msi_irq_affinity(unsigned int irq, cpumask_t mask) cpus_and(mask, tmp, CPU_MASK_ALL); - vector = assign_irq_vector(irq, mask, &tmp); + vector = assign_irq_vector(irq, mask); if (vector < 0) return; + cpus_clear(tmp); + cpu_set(vector >> 8, tmp); dest = cpu_mask_to_apicid(tmp); read_msi_msg(irq, &msg); @@ -1934,7 +1797,7 @@ int arch_setup_msi_irq(unsigned int irq, struct pci_dev *dev) write_msi_msg(irq, &msg); - set_irq_chip_and_handler_name(irq, &msi_chip, handle_edge_irq, "edge"); + set_irq_chip_and_handler(irq, &msi_chip, handle_edge_irq); return 0; } @@ -1955,16 +1818,18 @@ void arch_teardown_msi_irq(unsigned int irq) static void target_ht_irq(unsigned int irq, unsigned int dest, u8 vector) { - struct ht_irq_msg msg; - fetch_ht_irq_msg(irq, &msg); + u32 low, high; + low = read_ht_irq_low(irq); + high = read_ht_irq_high(irq); - msg.address_lo &= ~(HT_IRQ_LOW_VECTOR_MASK | HT_IRQ_LOW_DEST_ID_MASK); - msg.address_hi &= ~(HT_IRQ_HIGH_DEST_ID_MASK); + low &= ~(HT_IRQ_LOW_VECTOR_MASK | HT_IRQ_LOW_DEST_ID_MASK); + high &= ~(HT_IRQ_HIGH_DEST_ID_MASK); - msg.address_lo |= HT_IRQ_LOW_VECTOR(vector) | HT_IRQ_LOW_DEST_ID(dest); - msg.address_hi |= HT_IRQ_HIGH_DEST_ID(dest); + low |= HT_IRQ_LOW_VECTOR(vector) | HT_IRQ_LOW_DEST_ID(dest); + high |= HT_IRQ_HIGH_DEST_ID(dest); - write_ht_irq_msg(irq, &msg); + write_ht_irq_low(irq, low); + write_ht_irq_high(irq, high); } static void set_ht_irq_affinity(unsigned int irq, cpumask_t mask) @@ -1979,18 +1844,20 @@ static void set_ht_irq_affinity(unsigned int irq, cpumask_t mask) cpus_and(mask, tmp, CPU_MASK_ALL); - vector = assign_irq_vector(irq, mask, &tmp); + vector = assign_irq_vector(irq, mask); if (vector < 0) return; + cpus_clear(tmp); + cpu_set(vector >> 8, tmp); dest = cpu_mask_to_apicid(tmp); - target_ht_irq(irq, dest, vector); + target_ht_irq(irq, dest, vector & 0xff); set_native_irq_info(irq, mask); } #endif -static struct irq_chip ht_irq_chip = { +static struct hw_interrupt_type ht_irq_chip = { .name = "PCI-HT", .mask = mask_ht_irq, .unmask = unmask_ht_irq, @@ -2004,19 +1871,20 @@ static struct irq_chip ht_irq_chip = { int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev) { int vector; - cpumask_t tmp; - vector = assign_irq_vector(irq, TARGET_CPUS, &tmp); + vector = assign_irq_vector(irq, TARGET_CPUS); if (vector >= 0) { - struct ht_irq_msg msg; + u32 low, high; unsigned dest; + cpumask_t tmp; + cpus_clear(tmp); + cpu_set(vector >> 8, tmp); dest = cpu_mask_to_apicid(tmp); - msg.address_hi = HT_IRQ_HIGH_DEST_ID(dest); + high = HT_IRQ_HIGH_DEST_ID(dest); - msg.address_lo = - HT_IRQ_LOW_BASE | + low = HT_IRQ_LOW_BASE | HT_IRQ_LOW_DEST_ID(dest) | HT_IRQ_LOW_VECTOR(vector) | ((INT_DEST_MODE == 0) ? @@ -2025,13 +1893,12 @@ int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev) HT_IRQ_LOW_RQEOI_EDGE | ((INT_DELIVERY_MODE != dest_LowestPrio) ? HT_IRQ_LOW_MT_FIXED : - HT_IRQ_LOW_MT_ARBITRATED) | - HT_IRQ_LOW_IRQ_MASKED; + HT_IRQ_LOW_MT_ARBITRATED); - write_ht_irq_msg(irq, &msg); + write_ht_irq_low(irq, low); + write_ht_irq_high(irq, high); - set_irq_chip_and_handler_name(irq, &ht_irq_chip, - handle_edge_irq, "edge"); + set_irq_chip_and_handler(irq, &ht_irq_chip, handle_edge_irq); } return vector; } @@ -2078,10 +1945,13 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int triggering, int p add_pin_to_irq(irq, ioapic, pin); - vector = assign_irq_vector(irq, TARGET_CPUS, &mask); + vector = assign_irq_vector(irq, TARGET_CPUS); if (vector < 0) return vector; + cpus_clear(mask); + cpu_set(vector >> 8, mask); + /* * Generate a PCI IRQ routing entry and program the IOAPIC accordingly. * Note that we mask (disable) IRQs now -- these get enabled when the diff --git a/trunk/arch/x86_64/kernel/irq.c b/trunk/arch/x86_64/kernel/irq.c index e46c55856d40..506f27c85ca5 100644 --- a/trunk/arch/x86_64/kernel/irq.c +++ b/trunk/arch/x86_64/kernel/irq.c @@ -75,7 +75,7 @@ int show_interrupts(struct seq_file *p, void *v) seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); #endif seq_printf(p, " %8s", irq_desc[i].chip->name); - seq_printf(p, "-%-8s", irq_desc[i].name); + seq_printf(p, "-%s", handle_irq_name(irq_desc[i].handle_irq)); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) @@ -103,9 +103,7 @@ int show_interrupts(struct seq_file *p, void *v) * handlers). */ asmlinkage unsigned int do_IRQ(struct pt_regs *regs) -{ - struct pt_regs *old_regs = set_irq_regs(regs); - +{ /* high bit used in ret_from_ code */ unsigned vector = ~regs->orig_rax; unsigned irq; @@ -114,19 +112,18 @@ asmlinkage unsigned int do_IRQ(struct pt_regs *regs) irq_enter(); irq = __get_cpu_var(vector_irq)[vector]; + if (unlikely(irq >= NR_IRQS)) { + printk(KERN_EMERG "%s: cannot handle IRQ %d\n", + __FUNCTION__, irq); + BUG(); + } + #ifdef CONFIG_DEBUG_STACKOVERFLOW stack_overflow_check(regs); #endif - - if (likely(irq < NR_IRQS)) - generic_handle_irq(irq); - else - printk(KERN_EMERG "%s: %d.%d No irq handler for vector\n", - __func__, smp_processor_id(), vector); - + generic_handle_irq(irq, regs); irq_exit(); - set_irq_regs(old_regs); return 1; } diff --git a/trunk/arch/x86_64/kernel/pci-calgary.c b/trunk/arch/x86_64/kernel/pci-calgary.c index 37a770859e71..f760045d6d35 100644 --- a/trunk/arch/x86_64/kernel/pci-calgary.c +++ b/trunk/arch/x86_64/kernel/pci-calgary.c @@ -2,9 +2,8 @@ * Derived from arch/powerpc/kernel/iommu.c * * Copyright (C) IBM Corporation, 2006 - * Copyright (C) 2006 Jon Mason * - * Author: Jon Mason + * Author: Jon Mason * Author: Muli Ben-Yehuda * This program is free software; you can redistribute it and/or modify @@ -52,8 +51,7 @@ #define ONE_BASED_CHASSIS_NUM 1 /* register offsets inside the host bridge space */ -#define CALGARY_CONFIG_REG 0x0108 -#define PHB_CSR_OFFSET 0x0110 /* Channel Status */ +#define PHB_CSR_OFFSET 0x0110 #define PHB_PLSSR_OFFSET 0x0120 #define PHB_CONFIG_RW_OFFSET 0x0160 #define PHB_IOBASE_BAR_LOW 0x0170 @@ -84,8 +82,6 @@ #define TAR_VALID 0x0000000000000008UL /* CSR (Channel/DMA Status Register) */ #define CSR_AGENT_MASK 0xffe0ffff -/* CCR (Calgary Configuration Register) */ -#define CCR_2SEC_TIMEOUT 0x000000000000000EUL #define MAX_NUM_OF_PHBS 8 /* how many PHBs in total? */ #define MAX_NUM_CHASSIS 8 /* max number of chassis */ @@ -718,7 +714,7 @@ static void calgary_watchdog(unsigned long data) /* If no error, the agent ID in the CSR is not valid */ if (val32 & CSR_AGENT_MASK) { - printk(KERN_EMERG "calgary_watchdog: DMA error on PHB %#x, " + printk(KERN_EMERG "calgary_watchdog: DMA error on bus %d, " "CSR = %#x\n", dev->bus->number, val32); writel(0, target); @@ -735,38 +731,6 @@ static void calgary_watchdog(unsigned long data) } } -static void __init calgary_increase_split_completion_timeout(void __iomem *bbar, - unsigned char busnum) -{ - u64 val64; - void __iomem *target; - unsigned long phb_shift = -1; - u64 mask; - - switch (busno_to_phbid(busnum)) { - case 0: phb_shift = (63 - 19); - break; - case 1: phb_shift = (63 - 23); - break; - case 2: phb_shift = (63 - 27); - break; - case 3: phb_shift = (63 - 35); - break; - default: - BUG_ON(busno_to_phbid(busnum)); - } - - target = calgary_reg(bbar, CALGARY_CONFIG_REG); - val64 = be64_to_cpu(readq(target)); - - /* zero out this PHB's timer bits */ - mask = ~(0xFUL << phb_shift); - val64 &= mask; - val64 |= (CCR_2SEC_TIMEOUT << phb_shift); - writeq(cpu_to_be64(val64), target); - readq(target); /* flush */ -} - static void __init calgary_enable_translation(struct pci_dev *dev) { u32 val32; @@ -784,20 +748,13 @@ static void __init calgary_enable_translation(struct pci_dev *dev) val32 = be32_to_cpu(readl(target)); val32 |= PHB_TCE_ENABLE | PHB_DAC_DISABLE | PHB_MCSR_ENABLE; - printk(KERN_INFO "Calgary: enabling translation on PHB %#x\n", busnum); + printk(KERN_INFO "Calgary: enabling translation on PHB %d\n", busnum); printk(KERN_INFO "Calgary: errant DMAs will now be prevented on this " "bus.\n"); writel(cpu_to_be32(val32), target); readl(target); /* flush */ - /* - * Give split completion a longer timeout on bus 1 for aic94xx - * http://bugzilla.kernel.org/show_bug.cgi?id=7180 - */ - if (busnum == 1) - calgary_increase_split_completion_timeout(bbar, busnum); - init_timer(&tbl->watchdog_timer); tbl->watchdog_timer.function = &calgary_watchdog; tbl->watchdog_timer.data = (unsigned long)dev; @@ -821,7 +778,7 @@ static void __init calgary_disable_translation(struct pci_dev *dev) val32 = be32_to_cpu(readl(target)); val32 &= ~(PHB_TCE_ENABLE | PHB_DAC_DISABLE | PHB_MCSR_ENABLE); - printk(KERN_INFO "Calgary: disabling translation on PHB %#x!\n", busnum); + printk(KERN_INFO "Calgary: disabling translation on PHB %d!\n", busnum); writel(cpu_to_be32(val32), target); readl(target); /* flush */ @@ -833,16 +790,7 @@ 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; + rionodeid = (dev->bus->number % 15 > 4) ? 3 : 2; /* * register space address calculation as follows: * FE0MB-8MB*OneBasedChassisNumber+1MB*(RioNodeId-ChassisBase) @@ -850,7 +798,7 @@ static inline unsigned int __init locate_register_space(struct pci_dev *dev) * RioNodeId is 2 for first Calgary, 3 for second Calgary */ address = START_ADDRESS - - (0x800000 * (ONE_BASED_CHASSIS_NUM + dev->bus->number / 14)) + + (0x800000 * (ONE_BASED_CHASSIS_NUM + dev->bus->number / 15)) + (0x100000) * (rionodeid - CHASSIS_BASE); return address; } @@ -868,8 +816,6 @@ static int __init calgary_init_one(struct pci_dev *dev) void __iomem *bbar; int ret; - BUG_ON(dev->bus->number >= MAX_PHB_BUS_NUM); - address = locate_register_space(dev); /* map entire 1MB of Calgary config space */ bbar = ioremap_nocache(address, 1024 * 1024); @@ -896,10 +842,10 @@ static int __init calgary_init_one(struct pci_dev *dev) static int __init calgary_init(void) { - int ret = -ENODEV; + int i, ret = -ENODEV; struct pci_dev *dev = NULL; - do { + for (i = 0; i < MAX_PHB_BUS_NUM; i++) { dev = pci_get_device(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CALGARY, dev); @@ -915,12 +861,12 @@ static int __init calgary_init(void) ret = calgary_init_one(dev); if (ret) goto error; - } while (1); + } return ret; error: - do { + for (i--; i >= 0; i--) { dev = pci_find_device_reverse(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CALGARY, dev); @@ -936,7 +882,7 @@ static int __init calgary_init(void) calgary_disable_translation(dev); calgary_free_bus(dev); pci_dev_put(dev); /* Undo calgary_init_one()'s pci_dev_get() */ - } while (1); + } return ret; } @@ -1106,7 +1052,7 @@ static int __init calgary_parse_options(char *p) if (bridge < MAX_PHB_BUS_NUM) { printk(KERN_INFO "Calgary: disabling " - "translation for PHB %#x\n", bridge); + "translation for PHB 0x%x\n", bridge); bus_info[bridge].translation_disabled = 1; } } diff --git a/trunk/arch/x86_64/kernel/process.c b/trunk/arch/x86_64/kernel/process.c index 7451a4c43c16..de10cb8a2c97 100644 --- a/trunk/arch/x86_64/kernel/process.c +++ b/trunk/arch/x86_64/kernel/process.c @@ -88,8 +88,9 @@ void enter_idle(void) static void __exit_idle(void) { - if (test_and_clear_bit_pda(0, isidle) == 0) + if (read_pda(isidle) == 0) return; + write_pda(isidle, 0); atomic_notifier_call_chain(&idle_notifier, IDLE_END, NULL); } @@ -144,7 +145,7 @@ static void poll_idle (void) void cpu_idle_wait(void) { unsigned int cpu, this_cpu = get_cpu(); - cpumask_t map, tmp = current->cpus_allowed; + cpumask_t map; set_cpus_allowed(current, cpumask_of_cpu(this_cpu)); put_cpu(); @@ -167,8 +168,6 @@ void cpu_idle_wait(void) } cpus_and(map, map, cpu_online_map); } while (!cpus_empty(map)); - - set_cpus_allowed(current, tmp); } EXPORT_SYMBOL_GPL(cpu_idle_wait); @@ -239,28 +238,20 @@ void cpu_idle (void) * We execute MONITOR against need_resched and enter optimized wait state * through MWAIT. Whenever someone changes need_resched, we would be woken * up from MWAIT (without an IPI). - * - * New with Core Duo processors, MWAIT can take some hints based on CPU - * capability. */ -void mwait_idle_with_hints(unsigned long eax, unsigned long ecx) +static void mwait_idle(void) { - if (!need_resched()) { + local_irq_enable(); + + while (!need_resched()) { __monitor((void *)¤t_thread_info()->flags, 0, 0); smp_mb(); - if (!need_resched()) - __mwait(eax, ecx); + if (need_resched()) + break; + __mwait(0, 0); } } -/* Default MONITOR/MWAIT with no hints, used for default C1 state */ -static void mwait_idle(void) -{ - local_irq_enable(); - while (!need_resched()) - mwait_idle_with_hints(0,0); -} - void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c) { static int printed; @@ -624,9 +615,6 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) prev->gsindex = gsindex; } - /* Must be after DS reload */ - unlazy_fpu(prev_p); - /* * Switch the PDA and FPU contexts. */ @@ -634,6 +622,10 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) write_pda(oldrsp, next->userrsp); write_pda(pcurrent, next_p); + /* This must be here to ensure both math_state_restore() and + kernel_fpu_begin() work consistently. + And the AMD workaround requires it to be after DS reload. */ + unlazy_fpu(prev_p); write_pda(kernelstack, (unsigned long)task_stack_page(next_p) + THREAD_SIZE - PDA_STACKOFFSET); #ifdef CONFIG_CC_STACKPROTECTOR diff --git a/trunk/arch/x86_64/kernel/smp.c b/trunk/arch/x86_64/kernel/smp.c index 9f74c883568c..4f67697f5036 100644 --- a/trunk/arch/x86_64/kernel/smp.c +++ b/trunk/arch/x86_64/kernel/smp.c @@ -376,8 +376,9 @@ int smp_call_function_single (int cpu, void (*func) (void *info), void *info, /* prevent preemption and reschedule on another processor */ int me = get_cpu(); if (cpu == me) { + WARN_ON(1); put_cpu(); - return 0; + return -EBUSY; } spin_lock_bh(&call_lock); __smp_call_function_single(cpu, func, info, nonatomic, wait); diff --git a/trunk/arch/x86_64/kernel/smpboot.c b/trunk/arch/x86_64/kernel/smpboot.c index 62c2e747af58..7b7a6870288a 100644 --- a/trunk/arch/x86_64/kernel/smpboot.c +++ b/trunk/arch/x86_64/kernel/smpboot.c @@ -581,16 +581,12 @@ void __cpuinit start_secondary(void) * smp_call_function(). */ lock_ipi_call_lock(); - spin_lock(&vector_lock); - /* Setup the per cpu irq handling data structures */ - __setup_vector_irq(smp_processor_id()); /* * Allow the master to continue. */ cpu_set(smp_processor_id(), cpu_online_map); per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE; - spin_unlock(&vector_lock); unlock_ipi_call_lock(); cpu_idle(); @@ -803,6 +799,7 @@ static int __cpuinit do_boot_cpu(int cpu, int apicid) cpu, node); } + alternatives_smp_switch(1); c_idle.idle = get_idle_for_cpu(cpu); @@ -1249,10 +1246,8 @@ int __cpu_disable(void) local_irq_disable(); remove_siblinginfo(cpu); - spin_lock(&vector_lock); /* It's now safe to remove this processor from the online map */ cpu_clear(cpu, cpu_online_map); - spin_unlock(&vector_lock); remove_cpu_from_maps(); fixup_irqs(cpu_online_map); return 0; diff --git a/trunk/arch/x86_64/kernel/time.c b/trunk/arch/x86_64/kernel/time.c index e3ef544d2cfb..557e92af7bea 100644 --- a/trunk/arch/x86_64/kernel/time.c +++ b/trunk/arch/x86_64/kernel/time.c @@ -302,20 +302,20 @@ unsigned long long monotonic_clock(void) } EXPORT_SYMBOL(monotonic_clock); -static noinline void handle_lost_ticks(int lost) +static noinline void handle_lost_ticks(int lost, struct pt_regs *regs) { static long lost_count; static int warned; if (report_lost_ticks) { printk(KERN_WARNING "time.c: Lost %d timer tick(s)! ", lost); - print_symbol("rip %s)\n", get_irq_regs()->rip); + print_symbol("rip %s)\n", regs->rip); } if (lost_count == 1000 && !warned) { printk(KERN_WARNING "warning: many lost ticks.\n" KERN_WARNING "Your time source seems to be instable or " "some driver is hogging interupts\n"); - print_symbol("rip %s\n", get_irq_regs()->rip); + print_symbol("rip %s\n", regs->rip); if (vxtime.mode == VXTIME_TSC && vxtime.hpet_address) { printk(KERN_WARNING "Falling back to HPET\n"); if (hpet_use_timer) @@ -339,7 +339,7 @@ static noinline void handle_lost_ticks(int lost) #endif } -void main_timer_handler(void) +void main_timer_handler(struct pt_regs *regs) { static unsigned long rtc_update = 0; unsigned long tsc; @@ -411,7 +411,7 @@ void main_timer_handler(void) } if (lost > 0) - handle_lost_ticks(lost); + handle_lost_ticks(lost, regs); else lost = 0; @@ -421,7 +421,7 @@ void main_timer_handler(void) do_timer(lost + 1); #ifndef CONFIG_SMP - update_process_times(user_mode(get_irq_regs())); + update_process_times(user_mode(regs)); #endif /* @@ -431,7 +431,7 @@ void main_timer_handler(void) */ if (!using_apic_timer) - smp_local_timer_interrupt(); + smp_local_timer_interrupt(regs); /* * If we have an externally synchronized Linux clock, then update CMOS clock @@ -450,11 +450,11 @@ void main_timer_handler(void) write_sequnlock(&xtime_lock); } -static irqreturn_t timer_interrupt(int irq, void *dev_id) +static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { if (apic_runs_main_timer > 1) return IRQ_HANDLED; - main_timer_handler(); + main_timer_handler(regs); if (using_apic_timer) smp_send_timer_broadcast_ipi(); return IRQ_HANDLED; @@ -876,6 +876,15 @@ static struct irqaction irq0 = { timer_interrupt, IRQF_DISABLED, CPU_MASK_NONE, "timer", NULL, NULL }; +static int __cpuinit +time_cpu_notifier(struct notifier_block *nb, unsigned long action, void *hcpu) +{ + unsigned cpu = (unsigned long) hcpu; + if (action == CPU_ONLINE) + vsyscall_set_cpu(cpu); + return NOTIFY_DONE; +} + void __init time_init(void) { if (nohpet) @@ -916,6 +925,8 @@ void __init time_init(void) vxtime.last_tsc = get_cycles_sync(); set_cyc2ns_scale(cpu_khz); setup_irq(0, &irq0); + hotcpu_notifier(time_cpu_notifier, 0); + time_cpu_notifier(NULL, CPU_ONLINE, (void *)(long)smp_processor_id()); #ifndef CONFIG_SMP time_init_gtod(); @@ -937,7 +948,7 @@ __cpuinit int unsynchronized_tsc(void) if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) { #ifdef CONFIG_ACPI /* But TSC doesn't tick in C3 so don't use it there */ - if (acpi_fadt.length > 0 && acpi_fadt.plvl3_lat < 1000) + if (acpi_fadt.length > 0 && acpi_fadt.plvl3_lat < 100) return 1; #endif return 0; @@ -1326,7 +1337,7 @@ irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs) } if (call_rtc_interrupt) { rtc_int_flag |= (RTC_IRQF | (RTC_NUM_INTS << 8)); - rtc_interrupt(rtc_int_flag, dev_id); + rtc_interrupt(rtc_int_flag, dev_id, regs); } return IRQ_HANDLED; } diff --git a/trunk/arch/x86_64/kernel/traps.c b/trunk/arch/x86_64/kernel/traps.c index 0d65b22f229c..01f2a8d254c2 100644 --- a/trunk/arch/x86_64/kernel/traps.c +++ b/trunk/arch/x86_64/kernel/traps.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -116,6 +115,7 @@ static int call_trace = 1; #endif #ifdef CONFIG_KALLSYMS +# include void printk_address(unsigned long address) { unsigned long offset = 0, symsize; @@ -242,19 +242,12 @@ static int dump_trace_unwind(struct unwind_frame_info *info, void *context) * severe exception (double fault, nmi, stack fault, debug, mce) hardware stack */ -static inline int valid_stack_ptr(struct thread_info *tinfo, void *p) -{ - void *t = (void *)tinfo; - return p > t && p < t + THREAD_SIZE - 3; -} - void dump_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * stack, struct stacktrace_ops *ops, void *data) { const unsigned cpu = smp_processor_id(); unsigned long *irqstack_end = (unsigned long *)cpu_pda(cpu)->irqstackptr; unsigned used = 0; - struct thread_info *tinfo; if (!tsk) tsk = current; @@ -297,12 +290,6 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * s 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 @@ -377,8 +364,7 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * s /* * This handles the process stack: */ - tinfo = current_thread_info(); - HANDLE_STACK (valid_stack_ptr(tinfo, stack)); + HANDLE_STACK (((long) stack & (THREAD_SIZE-1)) != 0); #undef HANDLE_STACK } EXPORT_SYMBOL(dump_trace); diff --git a/trunk/arch/x86_64/kernel/vmlinux.lds.S b/trunk/arch/x86_64/kernel/vmlinux.lds.S index d9534e750d4f..b9df2ab6529f 100644 --- a/trunk/arch/x86_64/kernel/vmlinux.lds.S +++ b/trunk/arch/x86_64/kernel/vmlinux.lds.S @@ -17,7 +17,6 @@ PHDRS { text PT_LOAD FLAGS(5); /* R_E */ data PT_LOAD FLAGS(7); /* RWE */ user PT_LOAD FLAGS(7); /* RWE */ - data.init PT_LOAD FLAGS(7); /* RWE */ note PT_NOTE FLAGS(4); /* R__ */ } SECTIONS @@ -60,7 +59,6 @@ SECTIONS } #endif - . = ALIGN(PAGE_SIZE); /* Align data segment to page size boundary */ /* Data */ .data : AT(ADDR(.data) - LOAD_OFFSET) { *(.data) @@ -133,7 +131,7 @@ SECTIONS . = ALIGN(8192); /* init_task */ .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) { *(.data.init_task) - }:data.init + } :data . = ALIGN(4096); .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) { @@ -176,7 +174,13 @@ SECTIONS __setup_end = .; __initcall_start = .; .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) { - INITCALLS + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) } __initcall_end = .; __con_initcall_start = .; diff --git a/trunk/arch/x86_64/kernel/vsmp.c b/trunk/arch/x86_64/kernel/vsmp.c index 414caf0c5f9a..044e852bd25e 100644 --- a/trunk/arch/x86_64/kernel/vsmp.c +++ b/trunk/arch/x86_64/kernel/vsmp.c @@ -14,7 +14,6 @@ #include #include #include -#include static int __init vsmp_init(void) { diff --git a/trunk/arch/x86_64/kernel/vsyscall.c b/trunk/arch/x86_64/kernel/vsyscall.c index 92546c1526f1..a98b460af6a1 100644 --- a/trunk/arch/x86_64/kernel/vsyscall.c +++ b/trunk/arch/x86_64/kernel/vsyscall.c @@ -27,9 +27,6 @@ #include #include #include -#include -#include -#include #include #include @@ -246,17 +243,32 @@ static ctl_table kernel_root_table2[] = { #endif -/* Assume __initcall executes before all user space. Hopefully kmod - doesn't violate that. We'll find out if it does. */ -static void __cpuinit vsyscall_set_cpu(int cpu) +static void __cpuinit write_rdtscp_cb(void *info) +{ + write_rdtscp_aux((unsigned long)info); +} + +void __cpuinit vsyscall_set_cpu(int cpu) { unsigned long *d; unsigned long node = 0; #ifdef CONFIG_NUMA node = cpu_to_node[cpu]; #endif - if (cpu_has(&cpu_data[cpu], X86_FEATURE_RDTSCP)) - write_rdtscp_aux((node << 12) | cpu); + if (cpu_has(&cpu_data[cpu], X86_FEATURE_RDTSCP)) { + void *info = (void *)((node << 12) | cpu); + /* Can happen on preemptive kernel */ + if (get_cpu() == cpu) + write_rdtscp_cb(info); +#ifdef CONFIG_SMP + else { + /* the notifier is unfortunately not executed on the + target CPU */ + smp_call_function_single(cpu,write_rdtscp_cb,info,0,1); + } +#endif + put_cpu(); + } /* Store cpu number in limit so that it can be loaded quickly in user space in vgetcpu. @@ -268,23 +280,6 @@ static void __cpuinit vsyscall_set_cpu(int cpu) *d |= (node >> 4) << 48; } -static void __cpuinit cpu_vsyscall_init(void *arg) -{ - /* preemption should be already off */ - 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) -{ - long cpu = (long)arg; - if (action == CPU_ONLINE) - 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; @@ -304,8 +299,6 @@ static int __init vsyscall_init(void) #ifdef CONFIG_SYSCTL register_sysctl_table(kernel_root_table2, 0); #endif - on_each_cpu(cpu_vsyscall_init, NULL, 0, 1); - hotcpu_notifier(cpu_vsyscall_notifier, 0); return 0; } diff --git a/trunk/arch/x86_64/mm/init.c b/trunk/arch/x86_64/mm/init.c index 4c0c00ef3ca7..19c72520a868 100644 --- a/trunk/arch/x86_64/mm/init.c +++ b/trunk/arch/x86_64/mm/init.c @@ -406,12 +406,9 @@ void __cpuinit zap_low_mappings(int cpu) #ifndef CONFIG_NUMA void __init paging_init(void) { - unsigned long max_zone_pfns[MAX_NR_ZONES]; - memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); - max_zone_pfns[ZONE_DMA] = MAX_DMA_PFN; - max_zone_pfns[ZONE_DMA32] = MAX_DMA32_PFN; - max_zone_pfns[ZONE_NORMAL] = end_pfn; - + unsigned long max_zone_pfns[MAX_NR_ZONES] = {MAX_DMA_PFN, + MAX_DMA32_PFN, + end_pfn}; memory_present(0, 0, end_pfn); sparse_init(); free_area_init_nodes(max_zone_pfns); @@ -496,7 +493,7 @@ int remove_memory(u64 start, u64 size) } EXPORT_SYMBOL_GPL(remove_memory); -#if !defined(CONFIG_ACPI_NUMA) && defined(CONFIG_NUMA) +#ifndef CONFIG_ACPI_NUMA int memory_add_physaddr_to_nid(u64 start) { return 0; @@ -504,6 +501,13 @@ int memory_add_physaddr_to_nid(u64 start) EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid); #endif +#ifndef CONFIG_ACPI_NUMA +int memory_add_physaddr_to_nid(u64 start) +{ + return 0; +} +#endif + #endif /* CONFIG_MEMORY_HOTPLUG */ #ifdef CONFIG_MEMORY_HOTPLUG_RESERVE @@ -648,22 +652,9 @@ void free_initrd_mem(unsigned long start, unsigned long end) void __init reserve_bootmem_generic(unsigned long phys, unsigned len) { + /* Should check here against the e820 map to avoid double free */ #ifdef CONFIG_NUMA int nid = phys_to_nid(phys); -#endif - unsigned long pfn = phys >> PAGE_SHIFT; - if (pfn >= end_pfn) { - /* This can happen with kdump kernels when accessing firmware - tables. */ - if (pfn < end_pfn_map) - return; - printk(KERN_ERR "reserve_bootmem: illegal reserve %lx %u\n", - phys, len); - return; - } - - /* Should check here against the e820 map to avoid double free */ -#ifdef CONFIG_NUMA reserve_bootmem_node(NODE_DATA(nid), phys, len); #else reserve_bootmem(phys, len); diff --git a/trunk/arch/x86_64/mm/numa.c b/trunk/arch/x86_64/mm/numa.c index 2ee2e003606c..829a008bd39b 100644 --- a/trunk/arch/x86_64/mm/numa.c +++ b/trunk/arch/x86_64/mm/numa.c @@ -338,11 +338,9 @@ static void __init arch_sparse_init(void) void __init paging_init(void) { int i; - unsigned long max_zone_pfns[MAX_NR_ZONES]; - memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); - max_zone_pfns[ZONE_DMA] = MAX_DMA_PFN; - max_zone_pfns[ZONE_DMA32] = MAX_DMA32_PFN; - max_zone_pfns[ZONE_NORMAL] = end_pfn; + unsigned long max_zone_pfns[MAX_NR_ZONES] = { MAX_DMA_PFN, + MAX_DMA32_PFN, + end_pfn}; arch_sparse_init(); diff --git a/trunk/arch/x86_64/mm/srat.c b/trunk/arch/x86_64/mm/srat.c index 1087e150a218..3cc0544e25f5 100644 --- a/trunk/arch/x86_64/mm/srat.c +++ b/trunk/arch/x86_64/mm/srat.c @@ -207,7 +207,7 @@ static inline int save_add_info(void) return hotadd_percent > 0; } #else -int update_end_of_memory(unsigned long end) {return -1;} +int update_end_of_memory(unsigned long end) {return 0;} static int hotadd_enough_memory(struct bootnode *nd) {return 1;} #ifdef CONFIG_MEMORY_HOTPLUG_SPARSE static inline int save_add_info(void) {return 1;} @@ -337,7 +337,7 @@ acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma) push_node_boundaries(node, nd->start >> PAGE_SHIFT, nd->end >> PAGE_SHIFT); - if (ma->flags.hot_pluggable && (reserve_hotadd(node, start, end) < 0)) { + if (ma->flags.hot_pluggable && !reserve_hotadd(node, start, end) < 0) { /* Ignore hotadd region. Undo damage */ printk(KERN_NOTICE "SRAT: Hotplug region ignored\n"); *nd = oldnode; diff --git a/trunk/arch/x86_64/pci/Makefile b/trunk/arch/x86_64/pci/Makefile index 149aba05a5b8..1eb18f421edf 100644 --- a/trunk/arch/x86_64/pci/Makefile +++ b/trunk/arch/x86_64/pci/Makefile @@ -3,7 +3,7 @@ # # Reuse the i386 PCI subsystem # -EXTRA_CFLAGS += -Iarch/i386/pci +CFLAGS += -Iarch/i386/pci obj-y := i386.o obj-$(CONFIG_PCI_DIRECT)+= direct.o diff --git a/trunk/arch/x86_64/pci/mmconfig.c b/trunk/arch/x86_64/pci/mmconfig.c index f8b6b2800a62..7732f4254d21 100644 --- a/trunk/arch/x86_64/pci/mmconfig.c +++ b/trunk/arch/x86_64/pci/mmconfig.c @@ -163,6 +163,37 @@ static __init void unreachable_devices(void) } } +static __init void pci_mmcfg_insert_resources(void) +{ +#define PCI_MMCFG_RESOURCE_NAME_LEN 19 + int i; + struct resource *res; + char *names; + unsigned num_buses; + + res = kcalloc(PCI_MMCFG_RESOURCE_NAME_LEN + sizeof(*res), + pci_mmcfg_config_num, GFP_KERNEL); + + if (!res) { + printk(KERN_ERR "PCI: Unable to allocate MMCONFIG resources\n"); + return; + } + + names = (void *)&res[pci_mmcfg_config_num]; + for (i = 0; i < pci_mmcfg_config_num; i++, res++) { + num_buses = pci_mmcfg_config[i].end_bus_number - + pci_mmcfg_config[i].start_bus_number + 1; + res->name = names; + snprintf(names, PCI_MMCFG_RESOURCE_NAME_LEN, "PCI MMCONFIG %u", + pci_mmcfg_config[i].pci_segment_group_number); + res->start = pci_mmcfg_config[i].base_address; + res->end = res->start + (num_buses << 20) - 1; + res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; + insert_resource(&iomem_resource, res); + names += PCI_MMCFG_RESOURCE_NAME_LEN; + } +} + void __init pci_mmcfg_init(int type) { int i; @@ -189,7 +220,7 @@ void __init pci_mmcfg_init(int type) pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num, GFP_KERNEL); if (pci_mmcfg_virt == NULL) { - printk(KERN_ERR "PCI: Can not allocate memory for mmconfig structures\n"); + printk("PCI: Can not allocate memory for mmconfig structures\n"); return; } for (i = 0; i < pci_mmcfg_config_num; ++i) { @@ -197,8 +228,7 @@ void __init pci_mmcfg_init(int type) pci_mmcfg_virt[i].virt = ioremap_nocache(pci_mmcfg_config[i].base_address, MMCONFIG_APER_MAX); if (!pci_mmcfg_virt[i].virt) { - printk(KERN_ERR "PCI: Cannot map mmconfig aperture for " - "segment %d\n", + printk("PCI: Cannot map mmconfig aperture for segment %d\n", pci_mmcfg_config[i].pci_segment_group_number); return; } @@ -206,6 +236,7 @@ void __init pci_mmcfg_init(int type) } unreachable_devices(); + pci_mmcfg_insert_resources(); raw_pci_ops = &pci_mmcfg; pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; diff --git a/trunk/arch/xtensa/kernel/vmlinux.lds.S b/trunk/arch/xtensa/kernel/vmlinux.lds.S index cfe75f528725..ab6cdbd5eb68 100644 --- a/trunk/arch/xtensa/kernel/vmlinux.lds.S +++ b/trunk/arch/xtensa/kernel/vmlinux.lds.S @@ -184,7 +184,13 @@ SECTIONS __initcall_start = .; .initcall.init : { - INITCALLS + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) } __initcall_end = .; diff --git a/trunk/block/as-iosched.c b/trunk/block/as-iosched.c index 00242111a457..50b95e4c1425 100644 --- a/trunk/block/as-iosched.c +++ b/trunk/block/as-iosched.c @@ -1317,7 +1317,7 @@ static void as_exit_queue(elevator_t *e) /* * initialize elevator private data (as_data). */ -static void *as_init_queue(request_queue_t *q) +static void *as_init_queue(request_queue_t *q, elevator_t *e) { struct as_data *ad; diff --git a/trunk/block/blktrace.c b/trunk/block/blktrace.c index 562ca7cbf858..135593c8e45b 100644 --- a/trunk/block/blktrace.c +++ b/trunk/block/blktrace.c @@ -22,61 +22,30 @@ #include #include #include -#include #include static DEFINE_PER_CPU(unsigned long long, blk_trace_cpu_offset) = { 0, }; static unsigned int blktrace_seq __read_mostly = 1; -/* - * Send out a notify message. - */ -static inline unsigned int trace_note(struct blk_trace *bt, - pid_t pid, int action, - const void *data, size_t len) -{ - struct blk_io_trace *t; - int cpu = smp_processor_id(); - - t = relay_reserve(bt->rchan, sizeof(*t) + len); - if (t == NULL) - return 0; - - t->magic = BLK_IO_TRACE_MAGIC | BLK_IO_TRACE_VERSION; - t->time = sched_clock() - per_cpu(blk_trace_cpu_offset, cpu); - t->device = bt->dev; - t->action = action; - t->pid = pid; - t->cpu = cpu; - t->pdu_len = len; - memcpy((void *) t + sizeof(*t), data, len); - return blktrace_seq; -} - /* * Send out a notify for this process, if we haven't done so since a trace * started */ static void trace_note_tsk(struct blk_trace *bt, struct task_struct *tsk) { - tsk->btrace_seq = trace_note(bt, tsk->pid, - BLK_TN_PROCESS, - tsk->comm, sizeof(tsk->comm)); -} - -static void trace_note_time(struct blk_trace *bt) -{ - struct timespec now; - unsigned long flags; - u32 words[2]; - - getnstimeofday(&now); - words[0] = now.tv_sec; - words[1] = now.tv_nsec; + struct blk_io_trace *t; - local_irq_save(flags); - trace_note(bt, 0, BLK_TN_TIMESTAMP, words, sizeof(words)); - local_irq_restore(flags); + t = relay_reserve(bt->rchan, sizeof(*t) + sizeof(tsk->comm)); + if (t) { + t->magic = BLK_IO_TRACE_MAGIC | BLK_IO_TRACE_VERSION; + t->device = bt->dev; + t->action = BLK_TC_ACT(BLK_TC_NOTIFY); + t->pid = tsk->pid; + t->cpu = smp_processor_id(); + t->pdu_len = sizeof(tsk->comm); + memcpy((void *) t + sizeof(*t), tsk->comm, t->pdu_len); + tsk->btrace_seq = blktrace_seq; + } } static int act_log_check(struct blk_trace *bt, u32 what, sector_t sector, @@ -425,8 +394,6 @@ static int blk_trace_startstop(request_queue_t *q, int start) blktrace_seq++; smp_mb(); bt->trace_state = Blktrace_running; - - trace_note_time(bt); ret = 0; } } else { diff --git a/trunk/block/cfq-iosched.c b/trunk/block/cfq-iosched.c index e9019ed39b73..d3d76136f53a 100644 --- a/trunk/block/cfq-iosched.c +++ b/trunk/block/cfq-iosched.c @@ -456,9 +456,6 @@ static void cfq_add_rq_rb(struct request *rq) */ while ((__alias = elv_rb_add(&cfqq->sort_list, rq)) != NULL) cfq_dispatch_insert(cfqd->queue, __alias); - - if (!cfq_cfqq_on_rr(cfqq)) - cfq_add_cfqq_rr(cfqd, cfqq); } static inline void @@ -1218,12 +1215,11 @@ static inline void changed_ioprio(struct cfq_io_context *cic) { struct cfq_data *cfqd = cic->key; struct cfq_queue *cfqq; - unsigned long flags; if (unlikely(!cfqd)) return; - spin_lock_irqsave(cfqd->queue->queue_lock, flags); + spin_lock(cfqd->queue->queue_lock); cfqq = cic->cfqq[ASYNC]; if (cfqq) { @@ -1240,7 +1236,7 @@ static inline void changed_ioprio(struct cfq_io_context *cic) if (cfqq) cfq_mark_cfqq_prio_changed(cfqq); - spin_unlock_irqrestore(cfqd->queue->queue_lock, flags); + spin_unlock(cfqd->queue->queue_lock); } static void cfq_ioc_set_ioprio(struct io_context *ioc) @@ -1366,7 +1362,6 @@ cfq_cic_link(struct cfq_data *cfqd, struct io_context *ioc, struct rb_node **p; struct rb_node *parent; struct cfq_io_context *__cic; - unsigned long flags; void *k; cic->ioc = ioc; @@ -1396,9 +1391,9 @@ cfq_cic_link(struct cfq_data *cfqd, struct io_context *ioc, rb_link_node(&cic->rb_node, parent, p); rb_insert_color(&cic->rb_node, &ioc->cic_root); - spin_lock_irqsave(cfqd->queue->queue_lock, flags); + spin_lock_irq(cfqd->queue->queue_lock); list_add(&cic->queue_list, &cfqd->cic_list); - spin_unlock_irqrestore(cfqd->queue->queue_lock, flags); + spin_unlock_irq(cfqd->queue->queue_lock); } /* @@ -1464,7 +1459,8 @@ cfq_update_io_thinktime(struct cfq_data *cfqd, struct cfq_io_context *cic) } static void -cfq_update_io_seektime(struct cfq_io_context *cic, struct request *rq) +cfq_update_io_seektime(struct cfq_data *cfqd, struct cfq_io_context *cic, + struct request *rq) { sector_t sdist; u64 total; @@ -1616,7 +1612,7 @@ cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq, } cfq_update_io_thinktime(cfqd, cic); - cfq_update_io_seektime(cic, rq); + cfq_update_io_seektime(cfqd, cic, rq); cfq_update_idle_window(cfqd, cfqq, cic); cic->last_queue = jiffies; @@ -1654,6 +1650,9 @@ static void cfq_insert_request(request_queue_t *q, struct request *rq) cfq_add_rq_rb(rq); + if (!cfq_cfqq_on_rr(cfqq)) + cfq_add_cfqq_rr(cfqd, cfqq); + list_add_tail(&rq->queuelist, &cfqq->fifo); cfq_rq_enqueued(cfqd, cfqq, rq); @@ -1769,7 +1768,7 @@ static int cfq_may_queue(request_queue_t *q, int rw) /* * queue lock held here */ -static void cfq_put_request(struct request *rq) +static void cfq_put_request(request_queue_t *q, struct request *rq) { struct cfq_queue *cfqq = RQ_CFQQ(rq); @@ -1950,7 +1949,7 @@ static void cfq_exit_queue(elevator_t *e) kfree(cfqd); } -static void *cfq_init_queue(request_queue_t *q) +static void *cfq_init_queue(request_queue_t *q, elevator_t *e) { struct cfq_data *cfqd; int i; diff --git a/trunk/block/deadline-iosched.c b/trunk/block/deadline-iosched.c index 6d673e938d3e..b7c5b34cb7b4 100644 --- a/trunk/block/deadline-iosched.c +++ b/trunk/block/deadline-iosched.c @@ -356,7 +356,7 @@ static void deadline_exit_queue(elevator_t *e) /* * initialize elevator private data (deadline_data). */ -static void *deadline_init_queue(request_queue_t *q) +static void *deadline_init_queue(request_queue_t *q, elevator_t *e) { struct deadline_data *dd; diff --git a/trunk/block/elevator.c b/trunk/block/elevator.c index c0063f345c5d..487dd3da8853 100644 --- a/trunk/block/elevator.c +++ b/trunk/block/elevator.c @@ -93,18 +93,21 @@ static inline int elv_try_merge(struct request *__rq, struct bio *bio) static struct elevator_type *elevator_find(const char *name) { - struct elevator_type *e; + struct elevator_type *e = NULL; struct list_head *entry; list_for_each(entry, &elv_list) { + struct elevator_type *__e; - e = list_entry(entry, struct elevator_type, list); + __e = list_entry(entry, struct elevator_type, list); - if (!strcmp(e->elevator_name, name)) - return e; + if (!strcmp(__e->elevator_name, name)) { + e = __e; + break; + } } - return NULL; + return e; } static void elevator_put(struct elevator_type *e) @@ -129,7 +132,7 @@ static struct elevator_type *elevator_get(const char *name) static void *elevator_init_queue(request_queue_t *q, struct elevator_queue *eq) { - return eq->ops->elevator_init_fn(q); + return eq->ops->elevator_init_fn(q, eq); } static void elevator_attach(request_queue_t *q, struct elevator_queue *eq, @@ -810,7 +813,7 @@ void elv_put_request(request_queue_t *q, struct request *rq) elevator_t *e = q->elevator; if (e->ops->elevator_put_req_fn) - e->ops->elevator_put_req_fn(rq); + e->ops->elevator_put_req_fn(q, rq); } int elv_may_queue(request_queue_t *q, int rw) @@ -1085,7 +1088,7 @@ ssize_t elv_iosched_show(request_queue_t *q, char *name) struct list_head *entry; int len = 0; - spin_lock_irq(&elv_list_lock); + spin_lock_irq(q->queue_lock); list_for_each(entry, &elv_list) { struct elevator_type *__e; @@ -1095,7 +1098,7 @@ ssize_t elv_iosched_show(request_queue_t *q, char *name) else len += sprintf(name+len, "%s ", __e->elevator_name); } - spin_unlock_irq(&elv_list_lock); + spin_unlock_irq(q->queue_lock); len += sprintf(len+name, "\n"); return len; diff --git a/trunk/block/ll_rw_blk.c b/trunk/block/ll_rw_blk.c index 0f82e12f7b67..c847e17e5caa 100644 --- a/trunk/block/ll_rw_blk.c +++ b/trunk/block/ll_rw_blk.c @@ -56,6 +56,11 @@ static kmem_cache_t *requestq_cachep; */ static kmem_cache_t *iocontext_cachep; +static wait_queue_head_t congestion_wqh[2] = { + __WAIT_QUEUE_HEAD_INITIALIZER(congestion_wqh[0]), + __WAIT_QUEUE_HEAD_INITIALIZER(congestion_wqh[1]) + }; + /* * Controlling structure to kblockd */ @@ -107,6 +112,35 @@ static void blk_queue_congestion_threshold(struct request_queue *q) q->nr_congestion_off = nr; } +/* + * A queue has just exitted congestion. Note this in the global counter of + * congested queues, and wake up anyone who was waiting for requests to be + * put back. + */ +static void clear_queue_congested(request_queue_t *q, int rw) +{ + enum bdi_state bit; + wait_queue_head_t *wqh = &congestion_wqh[rw]; + + bit = (rw == WRITE) ? BDI_write_congested : BDI_read_congested; + clear_bit(bit, &q->backing_dev_info.state); + smp_mb__after_clear_bit(); + if (waitqueue_active(wqh)) + wake_up(wqh); +} + +/* + * A queue has just entered congestion. Flag that in the queue's VM-visible + * state flags and increment the global gounter of congested queues. + */ +static void set_queue_congested(request_queue_t *q, int rw) +{ + enum bdi_state bit; + + bit = (rw == WRITE) ? BDI_write_congested : BDI_read_congested; + set_bit(bit, &q->backing_dev_info.state); +} + /** * blk_get_backing_dev_info - get the address of a queue's backing_dev_info * @bdev: device @@ -125,6 +159,7 @@ struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev) ret = &q->backing_dev_info; return ret; } + EXPORT_SYMBOL(blk_get_backing_dev_info); void blk_queue_activity_fn(request_queue_t *q, activity_fn *fn, void *data) @@ -132,6 +167,7 @@ void blk_queue_activity_fn(request_queue_t *q, activity_fn *fn, void *data) q->activity_fn = fn; q->activity_data = data; } + EXPORT_SYMBOL(blk_queue_activity_fn); /** @@ -2031,7 +2067,7 @@ static void __freed_request(request_queue_t *q, int rw) struct request_list *rl = &q->rq; if (rl->count[rw] < queue_congestion_off_threshold(q)) - blk_clear_queue_congested(q, rw); + clear_queue_congested(q, rw); if (rl->count[rw] + 1 <= q->nr_requests) { if (waitqueue_active(&rl->wait[rw])) @@ -2101,7 +2137,7 @@ static struct request *get_request(request_queue_t *q, int rw, struct bio *bio, } } } - blk_set_queue_congested(q, rw); + set_queue_congested(q, rw); } /* @@ -2322,84 +2358,6 @@ void blk_insert_request(request_queue_t *q, struct request *rq, EXPORT_SYMBOL(blk_insert_request); -static int __blk_rq_unmap_user(struct bio *bio) -{ - int ret = 0; - - if (bio) { - if (bio_flagged(bio, BIO_USER_MAPPED)) - bio_unmap_user(bio); - else - ret = bio_uncopy_user(bio); - } - - return ret; -} - -static int __blk_rq_map_user(request_queue_t *q, struct request *rq, - void __user *ubuf, unsigned int len) -{ - unsigned long uaddr; - struct bio *bio, *orig_bio; - int reading, ret; - - reading = rq_data_dir(rq) == READ; - - /* - * if alignment requirement is satisfied, map in user pages for - * direct dma. else, set up kernel bounce buffers - */ - uaddr = (unsigned long) ubuf; - if (!(uaddr & queue_dma_alignment(q)) && !(len & queue_dma_alignment(q))) - bio = bio_map_user(q, NULL, uaddr, len, reading); - else - bio = bio_copy_user(q, uaddr, len, reading); - - if (IS_ERR(bio)) { - return PTR_ERR(bio); - } - - orig_bio = bio; - blk_queue_bounce(q, &bio); - /* - * We link the bounce buffer in and could have to traverse it - * later so we have to get a ref to prevent it from being freed - */ - bio_get(bio); - - /* - * for most (all? don't know of any) queues we could - * skip grabbing the queue lock here. only drivers with - * funky private ->back_merge_fn() function could be - * problematic. - */ - spin_lock_irq(q->queue_lock); - if (!rq->bio) - blk_rq_bio_prep(q, rq, bio); - else if (!q->back_merge_fn(q, rq, bio)) { - ret = -EINVAL; - spin_unlock_irq(q->queue_lock); - goto unmap_bio; - } else { - rq->biotail->bi_next = bio; - rq->biotail = bio; - - rq->nr_sectors += bio_sectors(bio); - rq->hard_nr_sectors = rq->nr_sectors; - rq->data_len += bio->bi_size; - } - spin_unlock_irq(q->queue_lock); - - return bio->bi_size; - -unmap_bio: - /* if it was boucned we must call the end io function */ - bio_endio(bio, bio->bi_size, 0); - __blk_rq_unmap_user(orig_bio); - bio_put(bio); - return ret; -} - /** * blk_rq_map_user - map user data to a request, for REQ_BLOCK_PC usage * @q: request queue where request should be inserted @@ -2421,44 +2379,42 @@ static int __blk_rq_map_user(request_queue_t *q, struct request *rq, * unmapping. */ int blk_rq_map_user(request_queue_t *q, struct request *rq, void __user *ubuf, - unsigned long len) + unsigned int len) { - unsigned long bytes_read = 0; - int ret; + unsigned long uaddr; + struct bio *bio; + int reading; if (len > (q->max_hw_sectors << 9)) return -EINVAL; if (!len || !ubuf) return -EINVAL; - while (bytes_read != len) { - unsigned long map_len, end, start; + reading = rq_data_dir(rq) == READ; - map_len = min_t(unsigned long, len - bytes_read, BIO_MAX_SIZE); - end = ((unsigned long)ubuf + map_len + PAGE_SIZE - 1) - >> PAGE_SHIFT; - start = (unsigned long)ubuf >> PAGE_SHIFT; + /* + * if alignment requirement is satisfied, map in user pages for + * direct dma. else, set up kernel bounce buffers + */ + uaddr = (unsigned long) ubuf; + if (!(uaddr & queue_dma_alignment(q)) && !(len & queue_dma_alignment(q))) + bio = bio_map_user(q, NULL, uaddr, len, reading); + else + bio = bio_copy_user(q, uaddr, len, reading); - /* - * A bad offset could cause us to require BIO_MAX_PAGES + 1 - * pages. If this happens we just lower the requested - * mapping len by a page so that we can fit - */ - if (end - start > BIO_MAX_PAGES) - map_len -= PAGE_SIZE; + if (!IS_ERR(bio)) { + rq->bio = rq->biotail = bio; + blk_rq_bio_prep(q, rq, bio); - ret = __blk_rq_map_user(q, rq, ubuf, map_len); - if (ret < 0) - goto unmap_rq; - bytes_read += ret; - ubuf += ret; + rq->buffer = rq->data = NULL; + rq->data_len = len; + return 0; } - rq->buffer = rq->data = NULL; - return 0; -unmap_rq: - blk_rq_unmap_user(rq); - return ret; + /* + * bio is the err-ptr + */ + return PTR_ERR(bio); } EXPORT_SYMBOL(blk_rq_map_user); @@ -2484,7 +2440,7 @@ EXPORT_SYMBOL(blk_rq_map_user); * unmapping. */ int blk_rq_map_user_iov(request_queue_t *q, struct request *rq, - struct sg_iovec *iov, int iov_count, unsigned int len) + struct sg_iovec *iov, int iov_count) { struct bio *bio; @@ -2498,15 +2454,10 @@ int blk_rq_map_user_iov(request_queue_t *q, struct request *rq, if (IS_ERR(bio)) return PTR_ERR(bio); - if (bio->bi_size != len) { - bio_endio(bio, bio->bi_size, 0); - bio_unmap_user(bio); - return -EINVAL; - } - - bio_get(bio); + rq->bio = rq->biotail = bio; blk_rq_bio_prep(q, rq, bio); rq->buffer = rq->data = NULL; + rq->data_len = bio->bi_size; return 0; } @@ -2514,26 +2465,23 @@ EXPORT_SYMBOL(blk_rq_map_user_iov); /** * blk_rq_unmap_user - unmap a request with user data - * @rq: rq to be unmapped + * @bio: bio to be unmapped + * @ulen: length of user buffer * * Description: - * Unmap a rq previously mapped by blk_rq_map_user(). - * rq->bio must be set to the original head of the request. + * Unmap a bio previously mapped by blk_rq_map_user(). */ -int blk_rq_unmap_user(struct request *rq) +int blk_rq_unmap_user(struct bio *bio, unsigned int ulen) { - struct bio *bio, *mapped_bio; + int ret = 0; - while ((bio = rq->bio)) { - if (bio_flagged(bio, BIO_BOUNCED)) - mapped_bio = bio->bi_private; + if (bio) { + if (bio_flagged(bio, BIO_USER_MAPPED)) + bio_unmap_user(bio); else - mapped_bio = bio; - - __blk_rq_unmap_user(mapped_bio); - rq->bio = bio->bi_next; - bio_put(bio); + ret = bio_uncopy_user(bio); } + return 0; } @@ -2564,8 +2512,11 @@ int blk_rq_map_kern(request_queue_t *q, struct request *rq, void *kbuf, if (rq_data_dir(rq) == WRITE) bio->bi_rw |= (1 << BIO_RW); + rq->bio = rq->biotail = bio; blk_rq_bio_prep(q, rq, bio); + rq->buffer = rq->data = NULL; + rq->data_len = len; return 0; } @@ -2804,6 +2755,41 @@ void blk_end_sync_rq(struct request *rq, int error) } EXPORT_SYMBOL(blk_end_sync_rq); +/** + * blk_congestion_wait - wait for a queue to become uncongested + * @rw: READ or WRITE + * @timeout: timeout in jiffies + * + * Waits for up to @timeout jiffies for a queue (any queue) to exit congestion. + * If no queues are congested then just wait for the next request to be + * returned. + */ +long blk_congestion_wait(int rw, long timeout) +{ + long ret; + DEFINE_WAIT(wait); + wait_queue_head_t *wqh = &congestion_wqh[rw]; + + prepare_to_wait(wqh, &wait, TASK_UNINTERRUPTIBLE); + ret = io_schedule_timeout(timeout); + finish_wait(wqh, &wait); + return ret; +} + +EXPORT_SYMBOL(blk_congestion_wait); + +/** + * blk_congestion_end - wake up sleepers on a congestion queue + * @rw: READ or WRITE + */ +void blk_congestion_end(int rw) +{ + wait_queue_head_t *wqh = &congestion_wqh[rw]; + + if (waitqueue_active(wqh)) + wake_up(wqh); +} + /* * Has to be called with the request spinlock acquired */ @@ -3084,7 +3070,6 @@ void generic_make_request(struct bio *bio) { request_queue_t *q; sector_t maxsector; - sector_t old_sector; int ret, nr_sectors = bio_sectors(bio); dev_t old_dev; @@ -3113,7 +3098,7 @@ void generic_make_request(struct bio *bio) * NOTE: we don't repeat the blk_size check for each new device. * Stacking drivers are expected to know what they are doing. */ - old_sector = -1; + maxsector = -1; old_dev = 0; do { char b[BDEVNAME_SIZE]; @@ -3147,31 +3132,15 @@ void generic_make_request(struct bio *bio) */ blk_partition_remap(bio); - if (old_sector != -1) + if (maxsector != -1) blk_add_trace_remap(q, bio, old_dev, bio->bi_sector, - old_sector); + maxsector); blk_add_trace_bio(q, bio, BLK_TA_QUEUE); - old_sector = bio->bi_sector; + maxsector = bio->bi_sector; old_dev = bio->bi_bdev->bd_dev; - maxsector = bio->bi_bdev->bd_inode->i_size >> 9; - if (maxsector) { - sector_t sector = bio->bi_sector; - - if (maxsector < nr_sectors || - maxsector - nr_sectors < sector) { - /* - * This may well happen - partitions are not - * checked to make sure they are within the size - * of the whole device. - */ - handle_bad_sector(bio); - goto end_io; - } - } - ret = q->make_request_fn(q, bio); } while (ret); } @@ -3580,7 +3549,6 @@ void blk_rq_bio_prep(request_queue_t *q, struct request *rq, struct bio *bio) rq->hard_cur_sectors = rq->current_nr_sectors; rq->hard_nr_sectors = rq->nr_sectors = bio_sectors(bio); rq->buffer = bio_data(bio); - rq->data_len = bio->bi_size; rq->bio = rq->biotail = bio; } @@ -3797,14 +3765,14 @@ queue_requests_store(struct request_queue *q, const char *page, size_t count) blk_queue_congestion_threshold(q); if (rl->count[READ] >= queue_congestion_on_threshold(q)) - blk_set_queue_congested(q, READ); + set_queue_congested(q, READ); else if (rl->count[READ] < queue_congestion_off_threshold(q)) - blk_clear_queue_congested(q, READ); + clear_queue_congested(q, READ); if (rl->count[WRITE] >= queue_congestion_on_threshold(q)) - blk_set_queue_congested(q, WRITE); + set_queue_congested(q, WRITE); else if (rl->count[WRITE] < queue_congestion_off_threshold(q)) - blk_clear_queue_congested(q, WRITE); + clear_queue_congested(q, WRITE); if (rl->count[READ] >= q->nr_requests) { blk_set_queue_full(q, READ); diff --git a/trunk/block/noop-iosched.c b/trunk/block/noop-iosched.c index 1c3de2b9a6b5..79af43179421 100644 --- a/trunk/block/noop-iosched.c +++ b/trunk/block/noop-iosched.c @@ -65,7 +65,7 @@ noop_latter_request(request_queue_t *q, struct request *rq) return list_entry(rq->queuelist.next, struct request, queuelist); } -static void *noop_init_queue(request_queue_t *q) +static void *noop_init_queue(request_queue_t *q, elevator_t *e) { struct noop_data *nd; diff --git a/trunk/block/scsi_ioctl.c b/trunk/block/scsi_ioctl.c index 5493c2fbbab1..2dc326421a24 100644 --- a/trunk/block/scsi_ioctl.c +++ b/trunk/block/scsi_ioctl.c @@ -226,6 +226,7 @@ static int sg_io(struct file *file, request_queue_t *q, unsigned long start_time; int writing = 0, ret = 0; struct request *rq; + struct bio *bio; char sense[SCSI_SENSE_BUFFERSIZE]; unsigned char cmd[BLK_MAX_CDB]; @@ -245,10 +246,10 @@ static int sg_io(struct file *file, request_queue_t *q, switch (hdr->dxfer_direction) { default: return -EINVAL; + case SG_DXFER_TO_FROM_DEV: case SG_DXFER_TO_DEV: writing = 1; break; - case SG_DXFER_TO_FROM_DEV: case SG_DXFER_FROM_DEV: break; } @@ -257,18 +258,44 @@ static int sg_io(struct file *file, request_queue_t *q, if (!rq) return -ENOMEM; + if (hdr->iovec_count) { + const int size = sizeof(struct sg_iovec) * hdr->iovec_count; + struct sg_iovec *iov; + + iov = kmalloc(size, GFP_KERNEL); + if (!iov) { + ret = -ENOMEM; + goto out; + } + + if (copy_from_user(iov, hdr->dxferp, size)) { + kfree(iov); + ret = -EFAULT; + goto out; + } + + ret = blk_rq_map_user_iov(q, rq, iov, hdr->iovec_count); + kfree(iov); + } else if (hdr->dxfer_len) + ret = blk_rq_map_user(q, rq, hdr->dxferp, hdr->dxfer_len); + + if (ret) + goto out; + /* * fill in request structure */ rq->cmd_len = hdr->cmd_len; - memset(rq->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */ memcpy(rq->cmd, cmd, hdr->cmd_len); + if (sizeof(rq->cmd) != hdr->cmd_len) + memset(rq->cmd + hdr->cmd_len, 0, sizeof(rq->cmd) - hdr->cmd_len); memset(sense, 0, sizeof(sense)); rq->sense = sense; rq->sense_len = 0; rq->cmd_type = REQ_TYPE_BLOCK_PC; + bio = rq->bio; /* * bounce this after holding a reference to the original bio, it's @@ -283,31 +310,6 @@ static int sg_io(struct file *file, request_queue_t *q, if (!rq->timeout) rq->timeout = BLK_DEFAULT_TIMEOUT; - if (hdr->iovec_count) { - const int size = sizeof(struct sg_iovec) * hdr->iovec_count; - struct sg_iovec *iov; - - iov = kmalloc(size, GFP_KERNEL); - if (!iov) { - ret = -ENOMEM; - goto out; - } - - if (copy_from_user(iov, hdr->dxferp, size)) { - kfree(iov); - ret = -EFAULT; - goto out; - } - - ret = blk_rq_map_user_iov(q, rq, iov, hdr->iovec_count, - hdr->dxfer_len); - kfree(iov); - } else if (hdr->dxfer_len) - ret = blk_rq_map_user(q, rq, hdr->dxferp, hdr->dxfer_len); - - if (ret) - goto out; - rq->retries = 0; start_time = jiffies; @@ -338,7 +340,7 @@ static int sg_io(struct file *file, request_queue_t *q, hdr->sb_len_wr = len; } - if (blk_rq_unmap_user(rq)) + if (blk_rq_unmap_user(bio, hdr->dxfer_len)) ret = -EFAULT; /* may not have succeeded, but output values written to control diff --git a/trunk/crypto/Kconfig b/trunk/crypto/Kconfig index cbae8392ce11..1e2f39c21180 100644 --- a/trunk/crypto/Kconfig +++ b/trunk/crypto/Kconfig @@ -27,6 +27,7 @@ config CRYPTO_HASH config CRYPTO_MANAGER tristate "Cryptographic algorithm manager" select CRYPTO_ALGAPI + default m help Create default cryptographic template instantiations such as cbc(aes). @@ -34,7 +35,6 @@ config CRYPTO_MANAGER config CRYPTO_HMAC tristate "HMAC support" select CRYPTO_HASH - select CRYPTO_MANAGER help HMAC: Keyed-Hashing for Message Authentication (RFC2104). This is required for IPSec. @@ -131,7 +131,6 @@ config CRYPTO_TGR192 config CRYPTO_ECB tristate "ECB support" select CRYPTO_BLKCIPHER - select CRYPTO_MANAGER default m help ECB: Electronic CodeBook mode @@ -141,7 +140,6 @@ config CRYPTO_ECB config CRYPTO_CBC tristate "CBC support" select CRYPTO_BLKCIPHER - select CRYPTO_MANAGER default m help CBC: Cipher Block Chaining mode diff --git a/trunk/crypto/api.c b/trunk/crypto/api.c index 4fb7fa45cb0d..2e84d4b54790 100644 --- a/trunk/crypto/api.c +++ b/trunk/crypto/api.c @@ -331,7 +331,7 @@ struct crypto_tfm *__crypto_alloc_tfm(struct crypto_alg *alg, u32 flags) tfm_size = sizeof(*tfm) + crypto_ctxsize(alg, flags); tfm = kzalloc(tfm_size, GFP_KERNEL); if (tfm == NULL) - goto out_err; + goto out; tfm->__crt_alg = alg; @@ -355,7 +355,6 @@ struct crypto_tfm *__crypto_alloc_tfm(struct crypto_alg *alg, u32 flags) crypto_exit_ops(tfm); out_free_tfm: kfree(tfm); -out_err: tfm = ERR_PTR(err); out: return tfm; @@ -415,14 +414,14 @@ struct crypto_tfm *crypto_alloc_base(const char *alg_name, u32 type, u32 mask) struct crypto_alg *alg; alg = crypto_alg_mod_lookup(alg_name, type, mask); - if (IS_ERR(alg)) { - err = PTR_ERR(alg); + err = PTR_ERR(alg); + tfm = ERR_PTR(err); + if (IS_ERR(alg)) goto err; - } tfm = __crypto_alloc_tfm(alg, 0); if (!IS_ERR(tfm)) - return tfm; + break; crypto_mod_put(alg); err = PTR_ERR(tfm); @@ -434,9 +433,9 @@ struct crypto_tfm *crypto_alloc_base(const char *alg_name, u32 type, u32 mask) err = -EINTR; break; } - } + }; - return ERR_PTR(err); + return tfm; } EXPORT_SYMBOL_GPL(crypto_alloc_base); diff --git a/trunk/crypto/serpent.c b/trunk/crypto/serpent.c index 2b0a19a44ec5..465d091cd3ec 100644 --- a/trunk/crypto/serpent.c +++ b/trunk/crypto/serpent.c @@ -364,10 +364,10 @@ static void serpent_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) { struct serpent_ctx *ctx = crypto_tfm_ctx(tfm); const u32 - *k = ctx->expkey; - const __le32 *s = (const __le32 *)src; - __le32 *d = (__le32 *)dst; - u32 r0, r1, r2, r3, r4; + *k = ctx->expkey, + *s = (const u32 *)src; + u32 *d = (u32 *)dst, + r0, r1, r2, r3, r4; /* * Note: The conversions between u8* and u32* might cause trouble @@ -423,10 +423,10 @@ static void serpent_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) { struct serpent_ctx *ctx = crypto_tfm_ctx(tfm); const u32 - *k = ((struct serpent_ctx *)ctx)->expkey; - const __le32 *s = (const __le32 *)src; - __le32 *d = (__le32 *)dst; - u32 r0, r1, r2, r3, r4; + *k = ((struct serpent_ctx *)ctx)->expkey, + *s = (const u32 *)src; + u32 *d = (u32 *)dst, + r0, r1, r2, r3, r4; r0 = le32_to_cpu(s[0]); r1 = le32_to_cpu(s[1]); diff --git a/trunk/drivers/Kconfig b/trunk/drivers/Kconfig index f39463418904..263e86ddc1a4 100644 --- a/trunk/drivers/Kconfig +++ b/trunk/drivers/Kconfig @@ -14,10 +14,6 @@ source "drivers/pnp/Kconfig" source "drivers/block/Kconfig" -# misc before ide - BLK_DEV_SGIIOC4 depends on SGI_IOC4 - -source "drivers/misc/Kconfig" - source "drivers/ide/Kconfig" source "drivers/scsi/Kconfig" @@ -56,6 +52,8 @@ source "drivers/w1/Kconfig" source "drivers/hwmon/Kconfig" +source "drivers/misc/Kconfig" + source "drivers/mfd/Kconfig" source "drivers/media/Kconfig" diff --git a/trunk/drivers/acorn/block/mfmhd.c b/trunk/drivers/acorn/block/mfmhd.c index 7fde8f4daebf..1bace29f4b6a 100644 --- a/trunk/drivers/acorn/block/mfmhd.c +++ b/trunk/drivers/acorn/block/mfmhd.c @@ -938,7 +938,7 @@ static void do_mfm_request(request_queue_t *q) mfm_request(); } -static void mfm_interrupt_handler(int unused, void *dev_id) +static void mfm_interrupt_handler(int unused, void *dev_id, struct pt_regs *regs) { void (*handler) (void) = do_mfm; diff --git a/trunk/drivers/acpi/acpi_memhotplug.c b/trunk/drivers/acpi/acpi_memhotplug.c index 6bcd9e8e7bcb..98099de59b45 100644 --- a/trunk/drivers/acpi/acpi_memhotplug.c +++ b/trunk/drivers/acpi/acpi_memhotplug.c @@ -85,8 +85,6 @@ struct acpi_memory_device { struct list_head res_list; }; -static int acpi_hotmem_initialized; - static acpi_status acpi_memory_get_resource(struct acpi_resource *resource, void *context) { @@ -416,7 +414,7 @@ static int acpi_memory_device_add(struct acpi_device *device) /* Set the device state */ mem_device->state = MEMORY_POWER_ON_STATE; - printk(KERN_DEBUG "%s \n", acpi_device_name(device)); + printk(KERN_INFO "%s \n", acpi_device_name(device)); return result; } @@ -440,15 +438,6 @@ static int acpi_memory_device_start (struct acpi_device *device) struct acpi_memory_device *mem_device; int result = 0; - /* - * Early boot code has recognized memory area by EFI/E820. - * If DSDT shows these memory devices on boot, hotplug is not necessary - * for them. So, it just returns until completion of this driver's - * start up. - */ - if (!acpi_hotmem_initialized) - return 0; - mem_device = acpi_driver_data(device); if (!acpi_memory_check_device(mem_device)) { @@ -548,7 +537,6 @@ static int __init acpi_memory_device_init(void) return -ENODEV; } - acpi_hotmem_initialized = 1; return 0; } diff --git a/trunk/drivers/acpi/asus_acpi.c b/trunk/drivers/acpi/asus_acpi.c index c7ac9297a204..e9ee4c52a5f6 100644 --- a/trunk/drivers/acpi/asus_acpi.c +++ b/trunk/drivers/acpi/asus_acpi.c @@ -138,7 +138,6 @@ struct asus_hotk { S2x, //S200 (J1 reported), Victor MP-XP7210 W1N, //W1000N W5A, //W5A - W3V, //W3030V xxN, //M2400N, M3700N, M5200N, M6800N, S1300N, S5200N //(Centrino) END_MODEL @@ -377,17 +376,6 @@ static struct model_data model_conf[END_MODEL] = { .display_get = "\\ADVG"}, { - .name = "W3V", - .mt_mled = "MLED", - .mt_wled = "WLED", - .mt_lcd_switch = xxN_PREFIX "_Q10", - .lcd_status = "\\BKLT", - .brightness_set = "SPLV", - .brightness_get = "GPLV", - .display_set = "SDSP", - .display_get = "\\INFB"}, - - { .name = "xxN", .mt_mled = "MLED", /* WLED present, but not controlled by ACPI */ @@ -567,11 +555,11 @@ static int write_led(const char __user * buffer, unsigned long count, char *ledname, int ledmask, int invert) { - int rv, value; + int value; int led_out = 0; - rv = parse_arg(buffer, count, &value); - if (rv > 0) + count = parse_arg(buffer, count, &value); + if (count > 0) led_out = value ? 1 : 0; hotk->status = @@ -584,7 +572,7 @@ write_led(const char __user * buffer, unsigned long count, printk(KERN_WARNING "Asus ACPI: LED (%s) write failed\n", ledname); - return rv; + return count; } /* @@ -619,18 +607,20 @@ static int proc_write_ledd(struct file *file, const char __user * buffer, unsigned long count, void *data) { - int rv, value; + int value; - rv = parse_arg(buffer, count, &value); - if (rv > 0) { + count = parse_arg(buffer, count, &value); + if (count > 0) { if (!write_acpi_int (hotk->handle, hotk->methods->mt_ledd, value, NULL)) printk(KERN_WARNING "Asus ACPI: LED display write failed\n"); else hotk->ledd_status = (u32) value; - } - return rv; + } else if (count < 0) + printk(KERN_WARNING "Asus ACPI: Error reading user input\n"); + + return count; } /* @@ -771,12 +761,12 @@ static int proc_write_lcd(struct file *file, const char __user * buffer, unsigned long count, void *data) { - int rv, value; + int value; - rv = parse_arg(buffer, count, &value); - if (rv > 0) + count = parse_arg(buffer, count, &value); + if (count > 0) set_lcd_state(value); - return rv; + return count; } static int read_brightness(void) @@ -840,15 +830,18 @@ static int proc_write_brn(struct file *file, const char __user * buffer, unsigned long count, void *data) { - int rv, value; + int value; - rv = parse_arg(buffer, count, &value); - if (rv > 0) { + count = parse_arg(buffer, count, &value); + if (count > 0) { value = (0 < value) ? ((15 < value) ? 15 : value) : 0; /* 0 <= value <= 15 */ set_brightness(value); + } else if (count < 0) { + printk(KERN_WARNING "Asus ACPI: Error reading user input\n"); } - return rv; + + return count; } static void set_display(int value) @@ -887,12 +880,15 @@ static int proc_write_disp(struct file *file, const char __user * buffer, unsigned long count, void *data) { - int rv, value; + int value; - rv = parse_arg(buffer, count, &value); - if (rv > 0) + count = parse_arg(buffer, count, &value); + if (count > 0) set_display(value); - return rv; + else if (count < 0) + printk(KERN_WARNING "Asus ACPI: Error reading user input\n"); + + return count; } typedef int (proc_readfunc) (char *page, char **start, off_t off, int count, @@ -1101,8 +1097,6 @@ static int asus_model_match(char *model) return A4G; else if (strncmp(model, "W1N", 3) == 0) return W1N; - else if (strncmp(model, "W3V", 3) == 0) - return W3V; else if (strncmp(model, "W5A", 3) == 0) return W5A; else @@ -1206,10 +1200,9 @@ static int asus_hotk_get_info(void) hotk->methods->mt_wled = NULL; /* L5D's WLED is not controlled by ACPI */ else if (strncmp(string, "M2N", 3) == 0 || - strncmp(string, "W3V", 3) == 0 || strncmp(string, "S1N", 3) == 0) hotk->methods->mt_wled = "WLED"; - /* M2N, S1N and W3V have a usable WLED */ + /* M2N and S1N have a usable WLED */ else if (asus_info) { if (strncmp(asus_info->oem_table_id, "L1", 2) == 0) hotk->methods->mled_status = NULL; diff --git a/trunk/drivers/acpi/battery.c b/trunk/drivers/acpi/battery.c index 026e40755cdd..9810e2a55d0a 100644 --- a/trunk/drivers/acpi/battery.c +++ b/trunk/drivers/acpi/battery.c @@ -64,7 +64,6 @@ extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir); static int acpi_battery_add(struct acpi_device *device); static int acpi_battery_remove(struct acpi_device *device, int type); -static int acpi_battery_resume(struct acpi_device *device, int status); static struct acpi_driver acpi_battery_driver = { .name = ACPI_BATTERY_DRIVER_NAME, @@ -72,7 +71,6 @@ static struct acpi_driver acpi_battery_driver = { .ids = ACPI_BATTERY_HID, .ops = { .add = acpi_battery_add, - .resume = acpi_battery_resume, .remove = acpi_battery_remove, }, }; @@ -755,18 +753,6 @@ static int acpi_battery_remove(struct acpi_device *device, int type) return 0; } -/* this is needed to learn about changes made in suspended state */ -static int acpi_battery_resume(struct acpi_device *device, int state) -{ - struct acpi_battery *battery; - - if (!device) - return -EINVAL; - - battery = device->driver_data; - return acpi_battery_check(battery); -} - static int __init acpi_battery_init(void) { int result; diff --git a/trunk/drivers/acpi/cm_sbs.c b/trunk/drivers/acpi/cm_sbs.c index 4a9b7bf6f44e..a01ce6700bfe 100644 --- a/trunk/drivers/acpi/cm_sbs.c +++ b/trunk/drivers/acpi/cm_sbs.c @@ -67,7 +67,7 @@ void acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir_param) lock_ac_dir_cnt--; if (lock_ac_dir_cnt == 0 && acpi_ac_dir_param && acpi_ac_dir) { remove_proc_entry(ACPI_AC_CLASS, acpi_root_dir); - acpi_ac_dir = NULL; + acpi_ac_dir = 0; } mutex_unlock(&cm_sbs_mutex); } @@ -99,7 +99,7 @@ void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir_param) if (lock_battery_dir_cnt == 0 && acpi_battery_dir_param && acpi_battery_dir) { remove_proc_entry(ACPI_BATTERY_CLASS, acpi_root_dir); - acpi_battery_dir = NULL; + acpi_battery_dir = 0; } mutex_unlock(&cm_sbs_mutex); return; diff --git a/trunk/drivers/acpi/ec.c b/trunk/drivers/acpi/ec.c index e6d4b084dca2..e5d796362854 100644 --- a/trunk/drivers/acpi/ec.c +++ b/trunk/drivers/acpi/ec.c @@ -45,143 +45,206 @@ ACPI_MODULE_NAME("acpi_ec") #define ACPI_EC_DRIVER_NAME "ACPI Embedded Controller Driver" #define ACPI_EC_DEVICE_NAME "Embedded Controller" #define ACPI_EC_FILE_INFO "info" - -/* EC status register */ #define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */ #define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */ #define ACPI_EC_FLAG_BURST 0x10 /* burst mode */ #define ACPI_EC_FLAG_SCI 0x20 /* EC-SCI occurred */ - -/* EC commands */ +#define ACPI_EC_EVENT_OBF 0x01 /* Output buffer full */ +#define ACPI_EC_EVENT_IBE 0x02 /* Input buffer empty */ +#define ACPI_EC_DELAY 50 /* Wait 50ms max. during EC ops */ +#define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ +#define ACPI_EC_UDELAY 100 /* Poll @ 100us increments */ +#define ACPI_EC_UDELAY_COUNT 1000 /* Wait 10ms max. during EC ops */ #define ACPI_EC_COMMAND_READ 0x80 #define ACPI_EC_COMMAND_WRITE 0x81 #define ACPI_EC_BURST_ENABLE 0x82 #define ACPI_EC_BURST_DISABLE 0x83 #define ACPI_EC_COMMAND_QUERY 0x84 - -/* EC events */ -enum { - ACPI_EC_EVENT_OBF_1 = 1, /* Output buffer full */ - ACPI_EC_EVENT_IBF_0, /* Input buffer empty */ -}; - -#define ACPI_EC_DELAY 50 /* Wait 50ms max. during EC ops */ -#define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ -#define ACPI_EC_UDELAY 100 /* Poll @ 100us increments */ -#define ACPI_EC_UDELAY_COUNT 1000 /* Wait 10ms max. during EC ops */ - -enum { - EC_INTR = 1, /* Output buffer full */ - EC_POLL, /* Input buffer empty */ -}; - +#define EC_POLL 0xFF +#define EC_INTR 0x00 static int acpi_ec_remove(struct acpi_device *device, int type); static int acpi_ec_start(struct acpi_device *device); static int acpi_ec_stop(struct acpi_device *device, int type); -static int acpi_ec_add(struct acpi_device *device); +static int acpi_ec_intr_add(struct acpi_device *device); +static int acpi_ec_poll_add(struct acpi_device *device); static struct acpi_driver acpi_ec_driver = { .name = ACPI_EC_DRIVER_NAME, .class = ACPI_EC_CLASS, .ids = ACPI_EC_HID, .ops = { - .add = acpi_ec_add, + .add = acpi_ec_intr_add, .remove = acpi_ec_remove, .start = acpi_ec_start, .stop = acpi_ec_stop, }, }; +union acpi_ec { + struct { + u32 mode; + acpi_handle handle; + unsigned long uid; + unsigned long gpe_bit; + struct acpi_generic_address status_addr; + struct acpi_generic_address command_addr; + struct acpi_generic_address data_addr; + unsigned long global_lock; + } common; + + struct { + u32 mode; + acpi_handle handle; + unsigned long uid; + unsigned long gpe_bit; + struct acpi_generic_address status_addr; + struct acpi_generic_address command_addr; + struct acpi_generic_address data_addr; + unsigned long global_lock; + unsigned int expect_event; + atomic_t leaving_burst; /* 0 : No, 1 : Yes, 2: abort */ + atomic_t pending_gpe; + struct semaphore sem; + wait_queue_head_t wait; + } intr; + + struct { + u32 mode; + acpi_handle handle; + unsigned long uid; + unsigned long gpe_bit; + struct acpi_generic_address status_addr; + struct acpi_generic_address command_addr; + struct acpi_generic_address data_addr; + unsigned long global_lock; + struct semaphore sem; + } poll; +}; +static int acpi_ec_poll_wait(union acpi_ec *ec, u8 event); +static int acpi_ec_intr_wait(union acpi_ec *ec, unsigned int event); +static int acpi_ec_poll_read(union acpi_ec *ec, u8 address, u32 * data); +static int acpi_ec_intr_read(union acpi_ec *ec, u8 address, u32 * data); +static int acpi_ec_poll_write(union acpi_ec *ec, u8 address, u8 data); +static int acpi_ec_intr_write(union acpi_ec *ec, u8 address, u8 data); +static int acpi_ec_poll_query(union acpi_ec *ec, u32 * data); +static int acpi_ec_intr_query(union acpi_ec *ec, u32 * data); +static void acpi_ec_gpe_poll_query(void *ec_cxt); +static void acpi_ec_gpe_intr_query(void *ec_cxt); +static u32 acpi_ec_gpe_poll_handler(void *data); +static u32 acpi_ec_gpe_intr_handler(void *data); +static acpi_status __init +acpi_fake_ecdt_poll_callback(acpi_handle handle, + u32 Level, void *context, void **retval); + +static acpi_status __init +acpi_fake_ecdt_intr_callback(acpi_handle handle, + u32 Level, void *context, void **retval); + +static int __init acpi_ec_poll_get_real_ecdt(void); +static int __init acpi_ec_intr_get_real_ecdt(void); /* If we find an EC via the ECDT, we need to keep a ptr to its context */ -struct acpi_ec { - acpi_handle handle; - unsigned long uid; - unsigned long gpe_bit; - unsigned long command_addr; - unsigned long data_addr; - unsigned long global_lock; - struct semaphore sem; - unsigned int expect_event; - atomic_t leaving_burst; /* 0 : No, 1 : Yes, 2: abort */ - wait_queue_head_t wait; -} *ec_ecdt; +static union acpi_ec *ec_ecdt; /* External interfaces use first EC only, so remember */ static struct acpi_device *first_ec; -static int acpi_ec_mode = EC_INTR; +static int acpi_ec_poll_mode = EC_INTR; /* -------------------------------------------------------------------------- Transaction Management -------------------------------------------------------------------------- */ -static inline u8 acpi_ec_read_status(struct acpi_ec *ec) +static u32 acpi_ec_read_status(union acpi_ec *ec) { - return inb(ec->command_addr); -} + u32 status = 0; -static inline u8 acpi_ec_read_data(struct acpi_ec *ec) -{ - return inb(ec->data_addr); + acpi_hw_low_level_read(8, &status, &ec->common.status_addr); + return status; } -static inline void acpi_ec_write_cmd(struct acpi_ec *ec, u8 command) +static int acpi_ec_wait(union acpi_ec *ec, u8 event) { - outb(command, ec->command_addr); + if (acpi_ec_poll_mode) + return acpi_ec_poll_wait(ec, event); + else + return acpi_ec_intr_wait(ec, event); } -static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data) +static int acpi_ec_poll_wait(union acpi_ec *ec, u8 event) { - outb(data, ec->data_addr); -} + u32 acpi_ec_status = 0; + u32 i = ACPI_EC_UDELAY_COUNT; -static int acpi_ec_check_status(u8 status, u8 event) -{ + if (!ec) + return -EINVAL; + + /* Poll the EC status register waiting for the event to occur. */ switch (event) { - case ACPI_EC_EVENT_OBF_1: - if (status & ACPI_EC_FLAG_OBF) - return 1; + case ACPI_EC_EVENT_OBF: + do { + acpi_hw_low_level_read(8, &acpi_ec_status, + &ec->common.status_addr); + if (acpi_ec_status & ACPI_EC_FLAG_OBF) + return 0; + udelay(ACPI_EC_UDELAY); + } while (--i > 0); break; - case ACPI_EC_EVENT_IBF_0: - if (!(status & ACPI_EC_FLAG_IBF)) - return 1; + case ACPI_EC_EVENT_IBE: + do { + acpi_hw_low_level_read(8, &acpi_ec_status, + &ec->common.status_addr); + if (!(acpi_ec_status & ACPI_EC_FLAG_IBF)) + return 0; + udelay(ACPI_EC_UDELAY); + } while (--i > 0); break; default: - break; + return -EINVAL; } - return 0; + return -ETIME; } - -static int acpi_ec_wait(struct acpi_ec *ec, u8 event) +static int acpi_ec_intr_wait(union acpi_ec *ec, unsigned int event) { - int i = (acpi_ec_mode == EC_POLL) ? ACPI_EC_UDELAY_COUNT : 0; - long time_left; + int result = 0; - ec->expect_event = event; - if (acpi_ec_check_status(acpi_ec_read_status(ec), event)) { - ec->expect_event = 0; - return 0; + + ec->intr.expect_event = event; + smp_mb(); + + switch (event) { + case ACPI_EC_EVENT_IBE: + if (~acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) { + ec->intr.expect_event = 0; + return 0; + } + break; + default: + break; } - do { - if (acpi_ec_mode == EC_POLL) { - udelay(ACPI_EC_UDELAY); - } else { - time_left = wait_event_timeout(ec->wait, - !ec->expect_event, + result = wait_event_timeout(ec->intr.wait, + !ec->intr.expect_event, msecs_to_jiffies(ACPI_EC_DELAY)); - if (time_left > 0) { - ec->expect_event = 0; - return 0; - } - } - if (acpi_ec_check_status(acpi_ec_read_status(ec), event)) { - ec->expect_event = 0; + + ec->intr.expect_event = 0; + smp_mb(); + + /* + * Verify that the event in question has actually happened by + * querying EC status. Do the check even if operation timed-out + * to make sure that we did not miss interrupt. + */ + switch (event) { + case ACPI_EC_EVENT_OBF: + if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_OBF) return 0; - } - } while (--i > 0); + break; - ec->expect_event = 0; + case ACPI_EC_EVENT_IBE: + if (~acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) + return 0; + break; + } return -ETIME; } @@ -191,150 +254,272 @@ static int acpi_ec_wait(struct acpi_ec *ec, u8 event) * Note: samsung nv5000 doesn't work with ec burst mode. * http://bugzilla.kernel.org/show_bug.cgi?id=4980 */ -int acpi_ec_enter_burst_mode(struct acpi_ec *ec) +int acpi_ec_enter_burst_mode(union acpi_ec *ec) { - u8 tmp = 0; - u8 status = 0; + u32 tmp = 0; + int status = 0; status = acpi_ec_read_status(ec); if (status != -EINVAL && !(status & ACPI_EC_FLAG_BURST)) { - status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); + status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); if (status) goto end; - acpi_ec_write_cmd(ec, ACPI_EC_BURST_ENABLE); - status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1); - tmp = acpi_ec_read_data(ec); + acpi_hw_low_level_write(8, ACPI_EC_BURST_ENABLE, + &ec->common.command_addr); + status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); + acpi_hw_low_level_read(8, &tmp, &ec->common.data_addr); if (tmp != 0x90) { /* Burst ACK byte */ return -EINVAL; } } - atomic_set(&ec->leaving_burst, 0); + atomic_set(&ec->intr.leaving_burst, 0); return 0; - end: - ACPI_EXCEPTION((AE_INFO, status, "EC wait, burst mode")); + end: + ACPI_EXCEPTION ((AE_INFO, status, "EC wait, burst mode"); return -1; } -int acpi_ec_leave_burst_mode(struct acpi_ec *ec) +int acpi_ec_leave_burst_mode(union acpi_ec *ec) { - u8 status = 0; + int status = 0; status = acpi_ec_read_status(ec); if (status != -EINVAL && (status & ACPI_EC_FLAG_BURST)){ - status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); + status = acpi_ec_wait(ec, ACPI_EC_FLAG_IBF); if(status) goto end; - acpi_ec_write_cmd(ec, ACPI_EC_BURST_DISABLE); - acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); - } - atomic_set(&ec->leaving_burst, 1); + acpi_hw_low_level_write(8, ACPI_EC_BURST_DISABLE, &ec->common.command_addr); + acpi_ec_wait(ec, ACPI_EC_FLAG_IBF); + } + atomic_set(&ec->intr.leaving_burst, 1); return 0; - end: - ACPI_EXCEPTION((AE_INFO, status, "EC leave burst mode")); +end: + ACPI_EXCEPTION((AE_INFO, status, "EC leave burst mode"); return -1; } #endif /* ACPI_FUTURE_USAGE */ -static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command, - const u8 *wdata, unsigned wdata_len, - u8 *rdata, unsigned rdata_len) +static int acpi_ec_read(union acpi_ec *ec, u8 address, u32 * data) +{ + if (acpi_ec_poll_mode) + return acpi_ec_poll_read(ec, address, data); + else + return acpi_ec_intr_read(ec, address, data); +} +static int acpi_ec_write(union acpi_ec *ec, u8 address, u8 data) +{ + if (acpi_ec_poll_mode) + return acpi_ec_poll_write(ec, address, data); + else + return acpi_ec_intr_write(ec, address, data); +} +static int acpi_ec_poll_read(union acpi_ec *ec, u8 address, u32 * data) { - int result; + acpi_status status = AE_OK; + int result = 0; + u32 glk = 0; - acpi_ec_write_cmd(ec, command); - for (; wdata_len > 0; wdata_len --) { - result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); - if (result) - return result; - acpi_ec_write_data(ec, *(wdata++)); + if (!ec || !data) + return -EINVAL; + + *data = 0; + + if (ec->common.global_lock) { + status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); + if (ACPI_FAILURE(status)) + return -ENODEV; } - if (command == ACPI_EC_COMMAND_WRITE) { - result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); - if (result) - return result; + if (down_interruptible(&ec->poll.sem)) { + result = -ERESTARTSYS; + goto end_nosem; } + + acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, + &ec->common.command_addr); + result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); + if (result) + goto end; + + acpi_hw_low_level_write(8, address, &ec->common.data_addr); + result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); + if (result) + goto end; + + acpi_hw_low_level_read(8, data, &ec->common.data_addr); + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n", + *data, address)); + + end: + up(&ec->poll.sem); +end_nosem: + if (ec->common.global_lock) + acpi_release_global_lock(glk); + + return result; +} + +static int acpi_ec_poll_write(union acpi_ec *ec, u8 address, u8 data) +{ + int result = 0; + acpi_status status = AE_OK; + u32 glk = 0; - for (; rdata_len > 0; rdata_len --) { - result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1); - if (result) - return result; - *(rdata++) = acpi_ec_read_data(ec); + if (!ec) + return -EINVAL; + + if (ec->common.global_lock) { + status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); + if (ACPI_FAILURE(status)) + return -ENODEV; + } + + if (down_interruptible(&ec->poll.sem)) { + result = -ERESTARTSYS; + goto end_nosem; } + + acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, + &ec->common.command_addr); + result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); + if (result) + goto end; - return 0; + acpi_hw_low_level_write(8, address, &ec->common.data_addr); + result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); + if (result) + goto end; + + acpi_hw_low_level_write(8, data, &ec->common.data_addr); + result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); + if (result) + goto end; + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Wrote [%02x] to address [%02x]\n", + data, address)); + + end: + up(&ec->poll.sem); +end_nosem: + if (ec->common.global_lock) + acpi_release_global_lock(glk); + + return result; } -static int acpi_ec_transaction(struct acpi_ec *ec, u8 command, - const u8 *wdata, unsigned wdata_len, - u8 *rdata, unsigned rdata_len) +static int acpi_ec_intr_read(union acpi_ec *ec, u8 address, u32 * data) { - int status; + int status = 0; u32 glk; - if (!ec || (wdata_len && !wdata) || (rdata_len && !rdata)) + + if (!ec || !data) return -EINVAL; - if (rdata) - memset(rdata, 0, rdata_len); + *data = 0; - if (ec->global_lock) { + if (ec->common.global_lock) { status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); if (ACPI_FAILURE(status)) return -ENODEV; } - down(&ec->sem); - status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); + WARN_ON(in_interrupt()); + down(&ec->intr.sem); + + status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); if (status) { printk(KERN_DEBUG PREFIX "read EC, IB not empty\n"); goto end; } + acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, + &ec->common.command_addr); + status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); + if (status) { + printk(KERN_DEBUG PREFIX "read EC, IB not empty\n"); + } - status = acpi_ec_transaction_unlocked(ec, command, - wdata, wdata_len, - rdata, rdata_len); + acpi_hw_low_level_write(8, address, &ec->common.data_addr); + status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); + if (status) { + printk(KERN_DEBUG PREFIX "read EC, OB not full\n"); + goto end; + } + acpi_hw_low_level_read(8, data, &ec->common.data_addr); + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n", + *data, address)); -end: - up(&ec->sem); + end: + up(&ec->intr.sem); - if (ec->global_lock) + if (ec->common.global_lock) acpi_release_global_lock(glk); return status; } -static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 *data) +static int acpi_ec_intr_write(union acpi_ec *ec, u8 address, u8 data) { - int result; - u8 d; + int status = 0; + u32 glk; - result = acpi_ec_transaction(ec, ACPI_EC_COMMAND_READ, - &address, 1, &d, 1); - *data = d; - return result; -} -static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data) -{ - u8 wdata[2] = { address, data }; - return acpi_ec_transaction(ec, ACPI_EC_COMMAND_WRITE, - wdata, 2, NULL, 0); + if (!ec) + return -EINVAL; + + if (ec->common.global_lock) { + status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); + if (ACPI_FAILURE(status)) + return -ENODEV; + } + + WARN_ON(in_interrupt()); + down(&ec->intr.sem); + + status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); + if (status) { + printk(KERN_DEBUG PREFIX "write EC, IB not empty\n"); + } + acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, + &ec->common.command_addr); + status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); + if (status) { + printk(KERN_DEBUG PREFIX "write EC, IB not empty\n"); + } + + acpi_hw_low_level_write(8, address, &ec->common.data_addr); + status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); + if (status) { + printk(KERN_DEBUG PREFIX "write EC, IB not empty\n"); + } + + acpi_hw_low_level_write(8, data, &ec->common.data_addr); + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Wrote [%02x] to address [%02x]\n", + data, address)); + + up(&ec->intr.sem); + + if (ec->common.global_lock) + acpi_release_global_lock(glk); + + return status; } /* * Externally callable EC access functions. For now, assume 1 EC only */ -int ec_read(u8 addr, u8 *val) +int ec_read(u8 addr, u8 * val) { - struct acpi_ec *ec; + union acpi_ec *ec; int err; - u8 temp_data; + u32 temp_data; if (!first_ec) return -ENODEV; @@ -354,7 +539,7 @@ EXPORT_SYMBOL(ec_read); int ec_write(u8 addr, u8 val) { - struct acpi_ec *ec; + union acpi_ec *ec; int err; if (!first_ec) @@ -369,106 +554,255 @@ int ec_write(u8 addr, u8 val) EXPORT_SYMBOL(ec_write); -extern int ec_transaction(u8 command, - const u8 *wdata, unsigned wdata_len, - u8 *rdata, unsigned rdata_len) +static int acpi_ec_query(union acpi_ec *ec, u32 * data) +{ + if (acpi_ec_poll_mode) + return acpi_ec_poll_query(ec, data); + else + return acpi_ec_intr_query(ec, data); +} +static int acpi_ec_poll_query(union acpi_ec *ec, u32 * data) { - struct acpi_ec *ec; + int result = 0; + acpi_status status = AE_OK; + u32 glk = 0; - if (!first_ec) - return -ENODEV; - ec = acpi_driver_data(first_ec); + if (!ec || !data) + return -EINVAL; - return acpi_ec_transaction(ec, command, wdata, - wdata_len, rdata, rdata_len); -} + *data = 0; + + if (ec->common.global_lock) { + status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); + if (ACPI_FAILURE(status)) + return -ENODEV; + } -EXPORT_SYMBOL(ec_transaction); + /* + * Query the EC to find out which _Qxx method we need to evaluate. + * Note that successful completion of the query causes the ACPI_EC_SCI + * bit to be cleared (and thus clearing the interrupt source). + */ + if (down_interruptible(&ec->poll.sem)) { + result = -ERESTARTSYS; + goto end_nosem; + } + + acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, + &ec->common.command_addr); + result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); + if (result) + goto end; + + acpi_hw_low_level_read(8, data, &ec->common.data_addr); + if (!*data) + result = -ENODATA; + + end: + up(&ec->poll.sem); +end_nosem: + if (ec->common.global_lock) + acpi_release_global_lock(glk); -static int acpi_ec_query(struct acpi_ec *ec, u8 *data) + return result; +} +static int acpi_ec_intr_query(union acpi_ec *ec, u32 * data) { - int result; - u8 d; + int status = 0; + u32 glk; + + + if (!ec || !data) + return -EINVAL; + *data = 0; + + if (ec->common.global_lock) { + status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); + if (ACPI_FAILURE(status)) + return -ENODEV; + } - if (!ec || !data) - return -EINVAL; + down(&ec->intr.sem); - /* - * Query the EC to find out which _Qxx method we need to evaluate. - * Note that successful completion of the query causes the ACPI_EC_SCI - * bit to be cleared (and thus clearing the interrupt source). - */ + status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); + if (status) { + printk(KERN_DEBUG PREFIX "query EC, IB not empty\n"); + goto end; + } + /* + * Query the EC to find out which _Qxx method we need to evaluate. + * Note that successful completion of the query causes the ACPI_EC_SCI + * bit to be cleared (and thus clearing the interrupt source). + */ + acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, + &ec->common.command_addr); + status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); + if (status) { + printk(KERN_DEBUG PREFIX "query EC, OB not full\n"); + goto end; + } - result = acpi_ec_transaction(ec, ACPI_EC_COMMAND_QUERY, NULL, 0, &d, 1); - if (result) - return result; + acpi_hw_low_level_read(8, data, &ec->common.data_addr); + if (!*data) + status = -ENODATA; - if (!d) - return -ENODATA; + end: + up(&ec->intr.sem); + + if (ec->common.global_lock) + acpi_release_global_lock(glk); - *data = d; - return 0; + return status; } /* -------------------------------------------------------------------------- Event Management -------------------------------------------------------------------------- */ -struct acpi_ec_query_data { +union acpi_ec_query_data { acpi_handle handle; u8 data; }; static void acpi_ec_gpe_query(void *ec_cxt) { - struct acpi_ec *ec = (struct acpi_ec *)ec_cxt; - u8 value = 0; - static char object_name[8]; + if (acpi_ec_poll_mode) + acpi_ec_gpe_poll_query(ec_cxt); + else + acpi_ec_gpe_intr_query(ec_cxt); +} - if (!ec) - goto end; +static void acpi_ec_gpe_poll_query(void *ec_cxt) +{ + union acpi_ec *ec = (union acpi_ec *)ec_cxt; + u32 value = 0; + static char object_name[5] = { '_', 'Q', '0', '0', '\0' }; + const char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' + }; - value = acpi_ec_read_status(ec); + if (!ec_cxt) + goto end; + + if (down_interruptible (&ec->poll.sem)) { + return; + } + acpi_hw_low_level_read(8, &value, &ec->common.command_addr); + up(&ec->poll.sem); + + /* TBD: Implement asynch events! + * NOTE: All we care about are EC-SCI's. Other EC events are + * handled via polling (yuck!). This is because some systems + * treat EC-SCIs as level (versus EDGE!) triggered, preventing + * a purely interrupt-driven approach (grumble, grumble). + */ if (!(value & ACPI_EC_FLAG_SCI)) goto end; if (acpi_ec_query(ec, &value)) goto end; - snprintf(object_name, 8, "_Q%2.2X", value); + object_name[2] = hex[((value >> 4) & 0x0F)]; + object_name[3] = hex[(value & 0x0F)]; + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s\n", object_name)); - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s", object_name)); + acpi_evaluate_object(ec->common.handle, object_name, NULL, NULL); - acpi_evaluate_object(ec->handle, object_name, NULL, NULL); + end: + acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); +} +static void acpi_ec_gpe_intr_query(void *ec_cxt) +{ + union acpi_ec *ec = (union acpi_ec *)ec_cxt; + u32 value; + int result = -ENODATA; + static char object_name[5] = { '_', 'Q', '0', '0', '\0' }; + const char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' + }; + + if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_SCI) + result = acpi_ec_query(ec, &value); + + if (result) + goto end; + + object_name[2] = hex[((value >> 4) & 0x0F)]; + object_name[3] = hex[(value & 0x0F)]; + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s\n", object_name)); + + acpi_evaluate_object(ec->common.handle, object_name, NULL, NULL); end: - acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); + atomic_dec(&ec->intr.pending_gpe); + return; } static u32 acpi_ec_gpe_handler(void *data) +{ + if (acpi_ec_poll_mode) + return acpi_ec_gpe_poll_handler(data); + else + return acpi_ec_gpe_intr_handler(data); +} +static u32 acpi_ec_gpe_poll_handler(void *data) { acpi_status status = AE_OK; - u8 value; - struct acpi_ec *ec = (struct acpi_ec *)data; + union acpi_ec *ec = (union acpi_ec *)data; + + if (!ec) + return ACPI_INTERRUPT_NOT_HANDLED; + + acpi_disable_gpe(NULL, ec->common.gpe_bit, ACPI_ISR); + + status = acpi_os_execute(OSL_EC_POLL_HANDLER, acpi_ec_gpe_query, ec); + + if (status == AE_OK) + return ACPI_INTERRUPT_HANDLED; + else + return ACPI_INTERRUPT_NOT_HANDLED; +} +static u32 acpi_ec_gpe_intr_handler(void *data) +{ + acpi_status status = AE_OK; + u32 value; + union acpi_ec *ec = (union acpi_ec *)data; + + if (!ec) + return ACPI_INTERRUPT_NOT_HANDLED; - acpi_clear_gpe(NULL, ec->gpe_bit, ACPI_ISR); + acpi_clear_gpe(NULL, ec->common.gpe_bit, ACPI_ISR); value = acpi_ec_read_status(ec); - if (acpi_ec_mode == EC_INTR) { - if (acpi_ec_check_status(value, ec->expect_event)) { - ec->expect_event = 0; - wake_up(&ec->wait); - } + switch (ec->intr.expect_event) { + case ACPI_EC_EVENT_OBF: + if (!(value & ACPI_EC_FLAG_OBF)) + break; + ec->intr.expect_event = 0; + wake_up(&ec->intr.wait); + break; + case ACPI_EC_EVENT_IBE: + if ((value & ACPI_EC_FLAG_IBF)) + break; + ec->intr.expect_event = 0; + wake_up(&ec->intr.wait); + break; + default: + break; } if (value & ACPI_EC_FLAG_SCI) { - status = acpi_os_execute(OSL_EC_BURST_HANDLER, acpi_ec_gpe_query, ec); + atomic_add(1, &ec->intr.pending_gpe); + status = acpi_os_execute(OSL_EC_BURST_HANDLER, + acpi_ec_gpe_query, ec); return status == AE_OK ? ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED; } - acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_ISR); + acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_ISR); return status == AE_OK ? ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED; } @@ -499,7 +833,7 @@ acpi_ec_space_handler(u32 function, void *handler_context, void *region_context) { int result = 0; - struct acpi_ec *ec = NULL; + union acpi_ec *ec = NULL; u64 temp = *value; acpi_integer f_v = 0; int i = 0; @@ -509,16 +843,18 @@ acpi_ec_space_handler(u32 function, return AE_BAD_PARAMETER; if (bit_width != 8 && acpi_strict) { + printk(KERN_WARNING PREFIX + "acpi_ec_space_handler: bit_width should be 8\n"); return AE_BAD_PARAMETER; } - ec = (struct acpi_ec *)handler_context; + ec = (union acpi_ec *)handler_context; next_byte: switch (function) { case ACPI_READ: temp = 0; - result = acpi_ec_read(ec, (u8) address, (u8 *) &temp); + result = acpi_ec_read(ec, (u8) address, (u32 *) & temp); break; case ACPI_WRITE: result = acpi_ec_write(ec, (u8) address, (u8) temp); @@ -569,20 +905,20 @@ static struct proc_dir_entry *acpi_ec_dir; static int acpi_ec_read_info(struct seq_file *seq, void *offset) { - struct acpi_ec *ec = (struct acpi_ec *)seq->private; + union acpi_ec *ec = (union acpi_ec *)seq->private; if (!ec) goto end; seq_printf(seq, "gpe bit: 0x%02x\n", - (u32) ec->gpe_bit); + (u32) ec->common.gpe_bit); seq_printf(seq, "ports: 0x%02x, 0x%02x\n", - (u32) ec->command_addr, - (u32) ec->data_addr); + (u32) ec->common.status_addr.address, + (u32) ec->common.data_addr.address); seq_printf(seq, "use global lock: %s\n", - ec->global_lock ? "yes" : "no"); - acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); + ec->common.global_lock ? "yes" : "no"); + acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); end: return 0; @@ -593,7 +929,7 @@ static int acpi_ec_info_open_fs(struct inode *inode, struct file *file) return single_open(file, acpi_ec_read_info, PDE(inode)->data); } -static struct file_operations acpi_ec_info_ops = { +static const struct file_operations acpi_ec_info_ops = { .open = acpi_ec_info_open_fs, .read = seq_read, .llseek = seq_lseek, @@ -642,35 +978,101 @@ static int acpi_ec_remove_fs(struct acpi_device *device) Driver Interface -------------------------------------------------------------------------- */ -static int acpi_ec_add(struct acpi_device *device) +static int acpi_ec_poll_add(struct acpi_device *device) { int result = 0; acpi_status status = AE_OK; - struct acpi_ec *ec = NULL; + union acpi_ec *ec = NULL; if (!device) return -EINVAL; - ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL); + ec = kmalloc(sizeof(union acpi_ec), GFP_KERNEL); if (!ec) return -ENOMEM; - memset(ec, 0, sizeof(struct acpi_ec)); - - ec->handle = device->handle; - ec->uid = -1; - init_MUTEX(&ec->sem); - if (acpi_ec_mode == EC_INTR) { - atomic_set(&ec->leaving_burst, 1); - init_waitqueue_head(&ec->wait); + memset(ec, 0, sizeof(union acpi_ec)); + + ec->common.handle = device->handle; + ec->common.uid = -1; + init_MUTEX(&ec->poll.sem); + strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME); + strcpy(acpi_device_class(device), ACPI_EC_CLASS); + acpi_driver_data(device) = ec; + + /* Use the global lock for all EC transactions? */ + acpi_evaluate_integer(ec->common.handle, "_GLK", NULL, + &ec->common.global_lock); + + /* XXX we don't test uids, because on some boxes ecdt uid = 0, see: + http://bugzilla.kernel.org/show_bug.cgi?id=6111 */ + if (ec_ecdt) { + acpi_remove_address_space_handler(ACPI_ROOT_OBJECT, + ACPI_ADR_SPACE_EC, + &acpi_ec_space_handler); + + acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit, + &acpi_ec_gpe_handler); + + kfree(ec_ecdt); } + + /* Get GPE bit assignment (EC events). */ + /* TODO: Add support for _GPE returning a package */ + status = + acpi_evaluate_integer(ec->common.handle, "_GPE", NULL, + &ec->common.gpe_bit); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, "Obtaining GPE bit")); + result = -ENODEV; + goto end; + } + + result = acpi_ec_add_fs(device); + if (result) + goto end; + + printk(KERN_INFO PREFIX "%s [%s] (gpe %d) polling mode.\n", + acpi_device_name(device), acpi_device_bid(device), + (u32) ec->common.gpe_bit); + + if (!first_ec) + first_ec = device; + + end: + if (result) + kfree(ec); + + return result; +} +static int acpi_ec_intr_add(struct acpi_device *device) +{ + int result = 0; + acpi_status status = AE_OK; + union acpi_ec *ec = NULL; + + + if (!device) + return -EINVAL; + + ec = kmalloc(sizeof(union acpi_ec), GFP_KERNEL); + if (!ec) + return -ENOMEM; + memset(ec, 0, sizeof(union acpi_ec)); + + ec->common.handle = device->handle; + ec->common.uid = -1; + atomic_set(&ec->intr.pending_gpe, 0); + atomic_set(&ec->intr.leaving_burst, 1); + init_MUTEX(&ec->intr.sem); + init_waitqueue_head(&ec->intr.wait); strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME); strcpy(acpi_device_class(device), ACPI_EC_CLASS); acpi_driver_data(device) = ec; /* Use the global lock for all EC transactions? */ - acpi_evaluate_integer(ec->handle, "_GLK", NULL, - &ec->global_lock); + acpi_evaluate_integer(ec->common.handle, "_GLK", NULL, + &ec->common.global_lock); /* XXX we don't test uids, because on some boxes ecdt uid = 0, see: http://bugzilla.kernel.org/show_bug.cgi?id=6111 */ @@ -679,7 +1081,7 @@ static int acpi_ec_add(struct acpi_device *device) ACPI_ADR_SPACE_EC, &acpi_ec_space_handler); - acpi_remove_gpe_handler(NULL, ec_ecdt->gpe_bit, + acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit, &acpi_ec_gpe_handler); kfree(ec_ecdt); @@ -688,10 +1090,10 @@ static int acpi_ec_add(struct acpi_device *device) /* Get GPE bit assignment (EC events). */ /* TODO: Add support for _GPE returning a package */ status = - acpi_evaluate_integer(ec->handle, "_GPE", NULL, - &ec->gpe_bit); + acpi_evaluate_integer(ec->common.handle, "_GPE", NULL, + &ec->common.gpe_bit); if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, "Obtaining GPE bit assignment")); + printk(KERN_ERR PREFIX "Obtaining GPE bit assignment\n"); result = -ENODEV; goto end; } @@ -700,14 +1102,14 @@ static int acpi_ec_add(struct acpi_device *device) if (result) goto end; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s [%s] (gpe %d) interrupt mode.", + printk(KERN_INFO PREFIX "%s [%s] (gpe %d) interrupt mode.\n", acpi_device_name(device), acpi_device_bid(device), - (u32) ec->gpe_bit)); + (u32) ec->common.gpe_bit); if (!first_ec) first_ec = device; - end: + end: if (result) kfree(ec); @@ -716,7 +1118,7 @@ static int acpi_ec_add(struct acpi_device *device) static int acpi_ec_remove(struct acpi_device *device, int type) { - struct acpi_ec *ec = NULL; + union acpi_ec *ec = NULL; if (!device) @@ -734,7 +1136,8 @@ static int acpi_ec_remove(struct acpi_device *device, int type) static acpi_status acpi_ec_io_ports(struct acpi_resource *resource, void *context) { - struct acpi_ec *ec = (struct acpi_ec *)context; + union acpi_ec *ec = (union acpi_ec *)context; + struct acpi_generic_address *addr; if (resource->type != ACPI_RESOURCE_TYPE_IO) { return AE_OK; @@ -745,21 +1148,26 @@ acpi_ec_io_ports(struct acpi_resource *resource, void *context) * the second address region returned is the status/command * port. */ - if (ec->data_addr == 0) { - ec->data_addr = resource->data.io.minimum; - } else if (ec->command_addr == 0) { - ec->command_addr = resource->data.io.minimum; + if (ec->common.data_addr.register_bit_width == 0) { + addr = &ec->common.data_addr; + } else if (ec->common.command_addr.register_bit_width == 0) { + addr = &ec->common.command_addr; } else { return AE_CTRL_TERMINATE; } + addr->address_space_id = ACPI_ADR_SPACE_SYSTEM_IO; + addr->register_bit_width = 8; + addr->register_bit_offset = 0; + addr->address = resource->data.io.minimum; + return AE_OK; } static int acpi_ec_start(struct acpi_device *device) { acpi_status status = AE_OK; - struct acpi_ec *ec = NULL; + union acpi_ec *ec = NULL; if (!device) @@ -773,35 +1181,39 @@ static int acpi_ec_start(struct acpi_device *device) /* * Get I/O port addresses. Convert to GAS format. */ - status = acpi_walk_resources(ec->handle, METHOD_NAME__CRS, + status = acpi_walk_resources(ec->common.handle, METHOD_NAME__CRS, acpi_ec_io_ports, ec); - if (ACPI_FAILURE(status) || ec->command_addr == 0) { - ACPI_EXCEPTION((AE_INFO, status, - "Error getting I/O port addresses")); + if (ACPI_FAILURE(status) + || ec->common.command_addr.register_bit_width == 0) { + printk(KERN_ERR PREFIX "Error getting I/O port addresses\n"); return -ENODEV; } - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02lx, ports=0x%2lx,0x%2lx", - ec->gpe_bit, ec->command_addr, ec->data_addr)); + ec->common.status_addr = ec->common.command_addr; + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02x, ports=0x%2x,0x%2x\n", + (u32) ec->common.gpe_bit, + (u32) ec->common.command_addr.address, + (u32) ec->common.data_addr.address)); /* * Install GPE handler */ - status = acpi_install_gpe_handler(NULL, ec->gpe_bit, + status = acpi_install_gpe_handler(NULL, ec->common.gpe_bit, ACPI_GPE_EDGE_TRIGGERED, &acpi_ec_gpe_handler, ec); if (ACPI_FAILURE(status)) { return -ENODEV; } - acpi_set_gpe_type(NULL, ec->gpe_bit, ACPI_GPE_TYPE_RUNTIME); - acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); + acpi_set_gpe_type(NULL, ec->common.gpe_bit, ACPI_GPE_TYPE_RUNTIME); + acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); - status = acpi_install_address_space_handler(ec->handle, + status = acpi_install_address_space_handler(ec->common.handle, ACPI_ADR_SPACE_EC, &acpi_ec_space_handler, &acpi_ec_space_setup, ec); if (ACPI_FAILURE(status)) { - acpi_remove_gpe_handler(NULL, ec->gpe_bit, + acpi_remove_gpe_handler(NULL, ec->common.gpe_bit, &acpi_ec_gpe_handler); return -ENODEV; } @@ -812,7 +1224,7 @@ static int acpi_ec_start(struct acpi_device *device) static int acpi_ec_stop(struct acpi_device *device, int type) { acpi_status status = AE_OK; - struct acpi_ec *ec = NULL; + union acpi_ec *ec = NULL; if (!device) @@ -820,14 +1232,14 @@ static int acpi_ec_stop(struct acpi_device *device, int type) ec = acpi_driver_data(device); - status = acpi_remove_address_space_handler(ec->handle, + status = acpi_remove_address_space_handler(ec->common.handle, ACPI_ADR_SPACE_EC, &acpi_ec_space_handler); if (ACPI_FAILURE(status)) return -ENODEV; status = - acpi_remove_gpe_handler(NULL, ec->gpe_bit, + acpi_remove_gpe_handler(NULL, ec->common.gpe_bit, &acpi_ec_gpe_handler); if (ACPI_FAILURE(status)) return -ENODEV; @@ -839,30 +1251,76 @@ static acpi_status __init acpi_fake_ecdt_callback(acpi_handle handle, u32 Level, void *context, void **retval) { + + if (acpi_ec_poll_mode) + return acpi_fake_ecdt_poll_callback(handle, + Level, context, retval); + else + return acpi_fake_ecdt_intr_callback(handle, + Level, context, retval); +} + +static acpi_status __init +acpi_fake_ecdt_poll_callback(acpi_handle handle, + u32 Level, void *context, void **retval) +{ acpi_status status; - init_MUTEX(&ec_ecdt->sem); - if (acpi_ec_mode == EC_INTR) { - init_waitqueue_head(&ec_ecdt->wait); - } status = acpi_walk_resources(handle, METHOD_NAME__CRS, acpi_ec_io_ports, ec_ecdt); if (ACPI_FAILURE(status)) return status; + ec_ecdt->common.status_addr = ec_ecdt->common.command_addr; + + ec_ecdt->common.uid = -1; + acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->common.uid); + + status = + acpi_evaluate_integer(handle, "_GPE", NULL, + &ec_ecdt->common.gpe_bit); + if (ACPI_FAILURE(status)) + return status; + init_MUTEX(&ec_ecdt->poll.sem); + ec_ecdt->common.global_lock = TRUE; + ec_ecdt->common.handle = handle; + + printk(KERN_INFO PREFIX "GPE=0x%02x, ports=0x%2x, 0x%2x\n", + (u32) ec_ecdt->common.gpe_bit, + (u32) ec_ecdt->common.command_addr.address, + (u32) ec_ecdt->common.data_addr.address); + + return AE_CTRL_TERMINATE; +} + +static acpi_status __init +acpi_fake_ecdt_intr_callback(acpi_handle handle, + u32 Level, void *context, void **retval) +{ + acpi_status status; + + init_MUTEX(&ec_ecdt->intr.sem); + init_waitqueue_head(&ec_ecdt->intr.wait); + status = acpi_walk_resources(handle, METHOD_NAME__CRS, + acpi_ec_io_ports, ec_ecdt); + if (ACPI_FAILURE(status)) + return status; + ec_ecdt->common.status_addr = ec_ecdt->common.command_addr; - ec_ecdt->uid = -1; - acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->uid); + ec_ecdt->common.uid = -1; + acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->common.uid); status = acpi_evaluate_integer(handle, "_GPE", NULL, - &ec_ecdt->gpe_bit); + &ec_ecdt->common.gpe_bit); if (ACPI_FAILURE(status)) return status; - ec_ecdt->global_lock = TRUE; - ec_ecdt->handle = handle; + ec_ecdt->common.global_lock = TRUE; + ec_ecdt->common.handle = handle; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "GPE=0x%02lx, ports=0x%2lx, 0x%2lx", - ec_ecdt->gpe_bit, ec_ecdt->command_addr, ec_ecdt->data_addr)); + printk(KERN_INFO PREFIX "GPE=0x%02x, ports=0x%2x, 0x%2x\n", + (u32) ec_ecdt->common.gpe_bit, + (u32) ec_ecdt->common.command_addr.address, + (u32) ec_ecdt->common.data_addr.address); return AE_CTRL_TERMINATE; } @@ -882,14 +1340,14 @@ static int __init acpi_ec_fake_ecdt(void) acpi_status status; int ret = 0; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Try to make an fake ECDT")); + printk(KERN_INFO PREFIX "Try to make an fake ECDT\n"); - ec_ecdt = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL); + ec_ecdt = kmalloc(sizeof(union acpi_ec), GFP_KERNEL); if (!ec_ecdt) { ret = -ENOMEM; goto error; } - memset(ec_ecdt, 0, sizeof(struct acpi_ec)); + memset(ec_ecdt, 0, sizeof(union acpi_ec)); status = acpi_get_devices(ACPI_EC_HID, acpi_fake_ecdt_callback, NULL, NULL); @@ -897,15 +1355,23 @@ static int __init acpi_ec_fake_ecdt(void) kfree(ec_ecdt); ec_ecdt = NULL; ret = -ENODEV; - ACPI_EXCEPTION((AE_INFO, status, "Can't make an fake ECDT")); goto error; } return 0; - error: + error: + printk(KERN_ERR PREFIX "Can't make an fake ECDT\n"); return ret; } static int __init acpi_ec_get_real_ecdt(void) +{ + if (acpi_ec_poll_mode) + return acpi_ec_poll_get_real_ecdt(); + else + return acpi_ec_intr_get_real_ecdt(); +} + +static int __init acpi_ec_poll_get_real_ecdt(void) { acpi_status status; struct acpi_table_ecdt *ecdt_ptr; @@ -916,36 +1382,80 @@ static int __init acpi_ec_get_real_ecdt(void) if (ACPI_FAILURE(status)) return -ENODEV; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found ECDT")); + printk(KERN_INFO PREFIX "Found ECDT\n"); /* * Generate a temporary ec context to use until the namespace is scanned */ - ec_ecdt = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL); + ec_ecdt = kmalloc(sizeof(union acpi_ec), GFP_KERNEL); if (!ec_ecdt) return -ENOMEM; - memset(ec_ecdt, 0, sizeof(struct acpi_ec)); + memset(ec_ecdt, 0, sizeof(union acpi_ec)); + + ec_ecdt->common.command_addr = ecdt_ptr->ec_control; + ec_ecdt->common.status_addr = ecdt_ptr->ec_control; + ec_ecdt->common.data_addr = ecdt_ptr->ec_data; + ec_ecdt->common.gpe_bit = ecdt_ptr->gpe_bit; + init_MUTEX(&ec_ecdt->poll.sem); + /* use the GL just to be safe */ + ec_ecdt->common.global_lock = TRUE; + ec_ecdt->common.uid = ecdt_ptr->uid; - init_MUTEX(&ec_ecdt->sem); - if (acpi_ec_mode == EC_INTR) { - init_waitqueue_head(&ec_ecdt->wait); + status = + acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->common.handle); + if (ACPI_FAILURE(status)) { + goto error; } - ec_ecdt->command_addr = ecdt_ptr->ec_control.address; - ec_ecdt->data_addr = ecdt_ptr->ec_data.address; - ec_ecdt->gpe_bit = ecdt_ptr->gpe_bit; + + return 0; + error: + printk(KERN_ERR PREFIX "Could not use ECDT\n"); + kfree(ec_ecdt); + ec_ecdt = NULL; + + return -ENODEV; +} + +static int __init acpi_ec_intr_get_real_ecdt(void) +{ + acpi_status status; + struct acpi_table_ecdt *ecdt_ptr; + + status = acpi_get_firmware_table("ECDT", 1, ACPI_LOGICAL_ADDRESSING, + (struct acpi_table_header **) + &ecdt_ptr); + if (ACPI_FAILURE(status)) + return -ENODEV; + + printk(KERN_INFO PREFIX "Found ECDT\n"); + + /* + * Generate a temporary ec context to use until the namespace is scanned + */ + ec_ecdt = kmalloc(sizeof(union acpi_ec), GFP_KERNEL); + if (!ec_ecdt) + return -ENOMEM; + memset(ec_ecdt, 0, sizeof(union acpi_ec)); + + init_MUTEX(&ec_ecdt->intr.sem); + init_waitqueue_head(&ec_ecdt->intr.wait); + ec_ecdt->common.command_addr = ecdt_ptr->ec_control; + ec_ecdt->common.status_addr = ecdt_ptr->ec_control; + ec_ecdt->common.data_addr = ecdt_ptr->ec_data; + ec_ecdt->common.gpe_bit = ecdt_ptr->gpe_bit; /* use the GL just to be safe */ - ec_ecdt->global_lock = TRUE; - ec_ecdt->uid = ecdt_ptr->uid; + ec_ecdt->common.global_lock = TRUE; + ec_ecdt->common.uid = ecdt_ptr->uid; status = - acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->handle); + acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->common.handle); if (ACPI_FAILURE(status)) { goto error; } return 0; - error: - ACPI_EXCEPTION((AE_INFO, status, "Could not use ECDT")); + error: + printk(KERN_ERR PREFIX "Could not use ECDT\n"); kfree(ec_ecdt); ec_ecdt = NULL; @@ -970,14 +1480,14 @@ int __init acpi_ec_ecdt_probe(void) /* * Install GPE handler */ - status = acpi_install_gpe_handler(NULL, ec_ecdt->gpe_bit, + status = acpi_install_gpe_handler(NULL, ec_ecdt->common.gpe_bit, ACPI_GPE_EDGE_TRIGGERED, &acpi_ec_gpe_handler, ec_ecdt); if (ACPI_FAILURE(status)) { goto error; } - acpi_set_gpe_type(NULL, ec_ecdt->gpe_bit, ACPI_GPE_TYPE_RUNTIME); - acpi_enable_gpe(NULL, ec_ecdt->gpe_bit, ACPI_NOT_ISR); + acpi_set_gpe_type(NULL, ec_ecdt->common.gpe_bit, ACPI_GPE_TYPE_RUNTIME); + acpi_enable_gpe(NULL, ec_ecdt->common.gpe_bit, ACPI_NOT_ISR); status = acpi_install_address_space_handler(ACPI_ROOT_OBJECT, ACPI_ADR_SPACE_EC, @@ -985,7 +1495,7 @@ int __init acpi_ec_ecdt_probe(void) &acpi_ec_space_setup, ec_ecdt); if (ACPI_FAILURE(status)) { - acpi_remove_gpe_handler(NULL, ec_ecdt->gpe_bit, + acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit, &acpi_ec_gpe_handler); goto error; } @@ -993,7 +1503,7 @@ int __init acpi_ec_ecdt_probe(void) return 0; error: - ACPI_EXCEPTION((AE_INFO, status, "Could not use ECDT")); + printk(KERN_ERR PREFIX "Could not use ECDT\n"); kfree(ec_ecdt); ec_ecdt = NULL; @@ -1052,13 +1562,13 @@ static int __init acpi_ec_set_intr_mode(char *str) return 0; if (intr) { - acpi_ec_mode = EC_INTR; + acpi_ec_poll_mode = EC_INTR; + acpi_ec_driver.ops.add = acpi_ec_intr_add; } else { - acpi_ec_mode = EC_POLL; + acpi_ec_poll_mode = EC_POLL; + acpi_ec_driver.ops.add = acpi_ec_poll_add; } - acpi_ec_driver.ops.add = acpi_ec_add; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "EC %s mode.\n", intr ? "interrupt" : "polling")); - + printk(KERN_INFO PREFIX "EC %s mode.\n", intr ? "interrupt" : "polling"); return 1; } diff --git a/trunk/drivers/acpi/events/evmisc.c b/trunk/drivers/acpi/events/evmisc.c index ee2a10bf9077..6eef4efddcf6 100644 --- a/trunk/drivers/acpi/events/evmisc.c +++ b/trunk/drivers/acpi/events/evmisc.c @@ -342,8 +342,20 @@ static u32 acpi_ev_global_lock_handler(void *context) if (acquired) { /* Got the lock, now wake all threads waiting for it */ + acpi_gbl_global_lock_acquired = TRUE; - acpi_ev_global_lock_thread(context); + + /* Run the Global Lock thread which will signal all waiting threads */ + + status = + acpi_os_execute(OSL_GLOBAL_LOCK_HANDLER, + acpi_ev_global_lock_thread, context); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, + "Could not queue Global Lock thread")); + + return (ACPI_INTERRUPT_NOT_HANDLED); + } } return (ACPI_INTERRUPT_HANDLED); diff --git a/trunk/drivers/acpi/events/evrgnini.c b/trunk/drivers/acpi/events/evrgnini.c index 203d1359190a..5b3c7a85eb9a 100644 --- a/trunk/drivers/acpi/events/evrgnini.c +++ b/trunk/drivers/acpi/events/evrgnini.c @@ -225,12 +225,13 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, if (! (ACPI_STRNCMP (object_hID.value, PCI_ROOT_HID_STRING, - sizeof(PCI_ROOT_HID_STRING))) - || - !(ACPI_STRNCMP - (object_hID.value, - PCI_EXPRESS_ROOT_HID_STRING, - sizeof(PCI_EXPRESS_ROOT_HID_STRING)))) { + sizeof(PCI_ROOT_HID_STRING)) + || + !(ACPI_STRNCMP + (object_hID.value, + PCI_EXPRESS_ROOT_HID_STRING, + sizeof(PCI_EXPRESS_ROOT_HID_STRING))))) + { /* Install a handler for this PCI root bridge */ diff --git a/trunk/drivers/acpi/glue.c b/trunk/drivers/acpi/glue.c index a2f46d587d55..10f160dc75b1 100644 --- a/trunk/drivers/acpi/glue.c +++ b/trunk/drivers/acpi/glue.c @@ -267,9 +267,9 @@ static int acpi_bind_one(struct device *dev, acpi_handle handle) { acpi_status status; - if (dev->archdata.acpi_handle) { + if (dev->firmware_data) { printk(KERN_WARNING PREFIX - "Drivers changed 'acpi_handle' for %s\n", dev->bus_id); + "Drivers changed 'firmware_data' for %s\n", dev->bus_id); return -EINVAL; } get_device(dev); @@ -278,26 +278,25 @@ static int acpi_bind_one(struct device *dev, acpi_handle handle) put_device(dev); return -EINVAL; } - dev->archdata.acpi_handle = handle; + dev->firmware_data = handle; return 0; } static int acpi_unbind_one(struct device *dev) { - if (!dev->archdata.acpi_handle) + if (!dev->firmware_data) return 0; - if (dev == acpi_get_physical_device(dev->archdata.acpi_handle)) { + if (dev == acpi_get_physical_device(dev->firmware_data)) { /* acpi_get_physical_device increase refcnt by one */ put_device(dev); - acpi_detach_data(dev->archdata.acpi_handle, - acpi_glue_data_handler); - dev->archdata.acpi_handle = NULL; + acpi_detach_data(dev->firmware_data, acpi_glue_data_handler); + dev->firmware_data = NULL; /* acpi_bind_one increase refcnt by one */ put_device(dev); } else { printk(KERN_ERR PREFIX - "Oops, 'acpi_handle' corrupt for %s\n", dev->bus_id); + "Oops, 'firmware_data' corrupt for %s\n", dev->bus_id); } return 0; } @@ -329,8 +328,7 @@ static int acpi_platform_notify(struct device *dev) if (!ret) { struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; - acpi_get_name(dev->archdata.acpi_handle, - ACPI_FULL_PATHNAME, &buffer); + acpi_get_name(dev->firmware_data, ACPI_FULL_PATHNAME, &buffer); DBG("Device %s -> %s\n", dev->bus_id, (char *)buffer.pointer); kfree(buffer.pointer); } else diff --git a/trunk/drivers/acpi/hardware/hwregs.c b/trunk/drivers/acpi/hardware/hwregs.c index fa58c1edce1e..3143f36fcec9 100644 --- a/trunk/drivers/acpi/hardware/hwregs.c +++ b/trunk/drivers/acpi/hardware/hwregs.c @@ -665,6 +665,8 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value) /* * Perform a read first to preserve certain bits (per ACPI spec) + * + * Note: This includes SCI_EN, we never want to change this bit */ status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_CONTROL, diff --git a/trunk/drivers/acpi/ibm_acpi.c b/trunk/drivers/acpi/ibm_acpi.c index 003a9876c968..15fc12482ba0 100644 --- a/trunk/drivers/acpi/ibm_acpi.c +++ b/trunk/drivers/acpi/ibm_acpi.c @@ -1702,11 +1702,13 @@ static struct ibm_struct ibms[] = { .name = "brightness", .read = brightness_read, .write = brightness_write, + .experimental = 1, }, { .name = "volume", .read = volume_read, .write = volume_write, + .experimental = 1, }, { .name = "fan", diff --git a/trunk/drivers/acpi/motherboard.c b/trunk/drivers/acpi/motherboard.c index 2e17ec75af03..ec6b7f9ede34 100644 --- a/trunk/drivers/acpi/motherboard.c +++ b/trunk/drivers/acpi/motherboard.c @@ -48,12 +48,6 @@ ACPI_MODULE_NAME("acpi_motherboard") * the io ports if they really know they can use it, while * still preventing hotplug PCI devices from using it. */ - -/* - * When CONFIG_PNP is enabled, pnp/system.c binds to PNP0C01 - * and PNP0C02, redundant with acpi_reserve_io_ranges(). - * But acpi_reserve_io_ranges() is necessary for !CONFIG_PNP. - */ static acpi_status acpi_reserve_io_ranges(struct acpi_resource *res, void *data) { struct resource *requested_res = NULL; diff --git a/trunk/drivers/acpi/osl.c b/trunk/drivers/acpi/osl.c index 068fe4f100b0..20beea778ea2 100644 --- a/trunk/drivers/acpi/osl.c +++ b/trunk/drivers/acpi/osl.c @@ -237,7 +237,7 @@ acpi_os_table_override(struct acpi_table_header * existing_table, return AE_OK; } -static irqreturn_t acpi_irq(int irq, void *dev_id) +static irqreturn_t acpi_irq(int irq, void *dev_id, struct pt_regs *regs) { return (*acpi_irq_handler) (acpi_irq_context) ? IRQ_HANDLED : IRQ_NONE; } diff --git a/trunk/drivers/acpi/pci_link.c b/trunk/drivers/acpi/pci_link.c index d53bd9878ca2..7f3e7e77e794 100644 --- a/trunk/drivers/acpi/pci_link.c +++ b/trunk/drivers/acpi/pci_link.c @@ -307,7 +307,7 @@ static int acpi_pci_link_set(struct acpi_pci_link *link, int irq) if (!link || !irq) return -EINVAL; - resource = kmalloc(sizeof(*resource) + 1, irqs_disabled() ? GFP_ATOMIC: GFP_KERNEL); + resource = kmalloc(sizeof(*resource) + 1, GFP_ATOMIC); if (!resource) return -ENOMEM; diff --git a/trunk/drivers/acpi/power.c b/trunk/drivers/acpi/power.c index fe67a8af520e..fec225d1b6b7 100644 --- a/trunk/drivers/acpi/power.c +++ b/trunk/drivers/acpi/power.c @@ -216,8 +216,10 @@ static int acpi_power_off_device(acpi_handle handle) { int result = 0; acpi_status status = AE_OK; + struct acpi_device *device = NULL; struct acpi_power_resource *resource = NULL; + result = acpi_power_get_context(handle, &resource); if (result) return result; @@ -228,13 +230,13 @@ static int acpi_power_off_device(acpi_handle handle) if (resource->references) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] is still in use, dereferencing\n", - resource->device->pnp.bus_id)); + device->pnp.bus_id)); return 0; } if (resource->state == ACPI_POWER_RESOURCE_STATE_OFF) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] already off\n", - resource->device->pnp.bus_id)); + device->pnp.bus_id)); return 0; } @@ -249,7 +251,8 @@ static int acpi_power_off_device(acpi_handle handle) return -ENOEXEC; /* Update the power resource's _device_ power state */ - resource->device->power.state = ACPI_STATE_D3; + device = resource->device; + device->power.state = ACPI_STATE_D3; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] turned off\n", resource->name)); diff --git a/trunk/drivers/acpi/processor_core.c b/trunk/drivers/acpi/processor_core.c index 1908e0d20222..b13d64415b7a 100644 --- a/trunk/drivers/acpi/processor_core.c +++ b/trunk/drivers/acpi/processor_core.c @@ -519,7 +519,7 @@ static int acpi_processor_get_info(struct acpi_processor *pr) static void *processor_device_array[NR_CPUS]; -static int __cpuinit acpi_processor_start(struct acpi_device *device) +static int acpi_processor_start(struct acpi_device *device) { int result = 0; acpi_status status = AE_OK; diff --git a/trunk/drivers/acpi/processor_idle.c b/trunk/drivers/acpi/processor_idle.c index 65b3f056ad89..0a395fca843b 100644 --- a/trunk/drivers/acpi/processor_idle.c +++ b/trunk/drivers/acpi/processor_idle.c @@ -219,23 +219,6 @@ static void acpi_safe_halt(void) static atomic_t c3_cpu_count; -/* Common C-state entry for C2, C3, .. */ -static void acpi_cstate_enter(struct acpi_processor_cx *cstate) -{ - if (cstate->space_id == ACPI_CSTATE_FFH) { - /* Call into architectural FFH based C-state */ - acpi_processor_ffh_cstate_enter(cstate); - } else { - int unused; - /* IO port based C-state */ - inb(cstate->address); - /* Dummy wait op - must do something useless after P_LVL2 read - because chipsets cannot guarantee that STPCLK# signal - gets asserted in time to freeze execution properly. */ - unused = inl(acpi_fadt.xpm_tmr_blk.address); - } -} - static void acpi_processor_idle(void) { struct acpi_processor *pr = NULL; @@ -378,7 +361,11 @@ static void acpi_processor_idle(void) /* Get start time (ticks) */ t1 = inl(acpi_fadt.xpm_tmr_blk.address); /* Invoke C2 */ - acpi_cstate_enter(cx); + inb(cx->address); + /* Dummy wait op - must do something useless after P_LVL2 read + because chipsets cannot guarantee that STPCLK# signal + gets asserted in time to freeze execution properly. */ + t2 = inl(acpi_fadt.xpm_tmr_blk.address); /* Get end time (ticks) */ t2 = inl(acpi_fadt.xpm_tmr_blk.address); @@ -414,7 +401,9 @@ static void acpi_processor_idle(void) /* Get start time (ticks) */ t1 = inl(acpi_fadt.xpm_tmr_blk.address); /* Invoke C3 */ - acpi_cstate_enter(cx); + inb(cx->address); + /* Dummy wait op (see above) */ + t2 = inl(acpi_fadt.xpm_tmr_blk.address); /* Get end time (ticks) */ t2 = inl(acpi_fadt.xpm_tmr_blk.address); if (pr->flags.bm_check) { @@ -639,16 +628,20 @@ static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr) return 0; } -static int acpi_processor_get_power_info_default(struct acpi_processor *pr) +static int acpi_processor_get_power_info_default_c1(struct acpi_processor *pr) { - if (!pr->power.states[ACPI_STATE_C1].valid) { - /* set the first C-State to C1 */ - /* all processors need to support C1 */ - pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1; - pr->power.states[ACPI_STATE_C1].valid = 1; - } - /* the C0 state only exists as a filler in our array */ + + /* Zero initialize all the C-states info. */ + memset(pr->power.states, 0, sizeof(pr->power.states)); + + /* set the first C-State to C1 */ + pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1; + + /* the C0 state only exists as a filler in our array, + * and all processors need to support C1 */ pr->power.states[ACPI_STATE_C0].valid = 1; + pr->power.states[ACPI_STATE_C1].valid = 1; + return 0; } @@ -665,7 +658,12 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) if (nocst) return -ENODEV; - current_count = 0; + current_count = 1; + + /* Zero initialize C2 onwards and prepare for fresh CST lookup */ + for (i = 2; i < ACPI_PROCESSOR_MAX_POWER; i++) + memset(&(pr->power.states[i]), 0, + sizeof(struct acpi_processor_cx)); status = acpi_evaluate_object(pr->handle, "_CST", NULL, &buffer); if (ACPI_FAILURE(status)) { @@ -720,39 +718,22 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) (reg->space_id != ACPI_ADR_SPACE_FIXED_HARDWARE)) continue; + cx.address = (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) ? + 0 : reg->address; + /* There should be an easy way to extract an integer... */ obj = (union acpi_object *)&(element->package.elements[1]); if (obj->type != ACPI_TYPE_INTEGER) continue; cx.type = obj->integer.value; - /* - * Some buggy BIOSes won't list C1 in _CST - - * Let acpi_processor_get_power_info_default() handle them later - */ - if (i == 1 && cx.type != ACPI_STATE_C1) - current_count++; - - cx.address = reg->address; - cx.index = current_count + 1; - - cx.space_id = ACPI_CSTATE_SYSTEMIO; - if (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) { - if (acpi_processor_ffh_cstate_probe - (pr->id, &cx, reg) == 0) { - cx.space_id = ACPI_CSTATE_FFH; - } else if (cx.type != ACPI_STATE_C1) { - /* - * C1 is a special case where FIXED_HARDWARE - * can be handled in non-MWAIT way as well. - * In that case, save this _CST entry info. - * That is, we retain space_id of SYSTEM_IO for - * halt based C1. - * Otherwise, ignore this info and continue. - */ - continue; - } - } + + if ((cx.type != ACPI_STATE_C1) && + (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO)) + continue; + + if ((cx.type < ACPI_STATE_C2) || (cx.type > ACPI_STATE_C3)) + continue; obj = (union acpi_object *)&(element->package.elements[2]); if (obj->type != ACPI_TYPE_INTEGER) @@ -957,17 +938,11 @@ static int acpi_processor_get_power_info(struct acpi_processor *pr) /* NOTE: the idle thread may not be running while calling * this function */ - /* Zero initialize all the C-states info. */ - memset(pr->power.states, 0, sizeof(pr->power.states)); - + /* Adding C1 state */ + acpi_processor_get_power_info_default_c1(pr); result = acpi_processor_get_power_info_cst(pr); if (result == -ENODEV) - result = acpi_processor_get_power_info_fadt(pr); - - if (result) - return result; - - acpi_processor_get_power_info_default(pr); + acpi_processor_get_power_info_fadt(pr); pr->power.count = acpi_processor_power_verify(pr); @@ -1108,7 +1083,6 @@ static const struct file_operations acpi_processor_power_fops = { .release = single_release, }; -#ifdef CONFIG_SMP static void smp_callback(void *v) { /* we already woke the CPU up, nothing more to do */ @@ -1130,9 +1104,8 @@ static int acpi_processor_latency_notify(struct notifier_block *b, static struct notifier_block acpi_processor_latency_notifier = { .notifier_call = acpi_processor_latency_notify, }; -#endif -int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, +int acpi_processor_power_init(struct acpi_processor *pr, struct acpi_device *device) { acpi_status status = 0; @@ -1148,9 +1121,7 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, "ACPI: processor limited to max C-state %d\n", max_cstate); first_run++; -#ifdef CONFIG_SMP register_latency_notifier(&acpi_processor_latency_notifier); -#endif } if (!pr) @@ -1222,9 +1193,7 @@ int acpi_processor_power_exit(struct acpi_processor *pr, * copies of pm_idle before proceeding. */ cpu_idle_wait(); -#ifdef CONFIG_SMP unregister_latency_notifier(&acpi_processor_latency_notifier); -#endif } return 0; diff --git a/trunk/drivers/acpi/processor_perflib.c b/trunk/drivers/acpi/processor_perflib.c index 6fd174a37149..7ba5e49ab302 100644 --- a/trunk/drivers/acpi/processor_perflib.c +++ b/trunk/drivers/acpi/processor_perflib.c @@ -83,8 +83,10 @@ static int acpi_processor_ppc_notifier(struct notifier_block *nb, goto out; ppc = (unsigned int)pr->performance_platform_limit; + if (!ppc) + goto out; - if (ppc >= pr->performance->state_count) + if (ppc > pr->performance->state_count) goto out; cpufreq_verify_within_limits(policy, 0, diff --git a/trunk/drivers/acpi/sbs.c b/trunk/drivers/acpi/sbs.c index 8908a975e575..62bef0b3b614 100644 --- a/trunk/drivers/acpi/sbs.c +++ b/trunk/drivers/acpi/sbs.c @@ -98,11 +98,11 @@ static int update_info_mode = UPDATE_INFO_MODE; static int update_time = UPDATE_TIME; static int update_time2 = UPDATE_TIME2; -module_param(capacity_mode, int, 0); -module_param(update_mode, int, 0); -module_param(update_info_mode, int, 0); -module_param(update_time, int, 0); -module_param(update_time2, int, 0); +module_param(capacity_mode, int, CAPACITY_UNIT); +module_param(update_mode, int, UPDATE_MODE); +module_param(update_info_mode, int, UPDATE_INFO_MODE); +module_param(update_time, int, UPDATE_TIME); +module_param(update_time2, int, UPDATE_TIME2); static int acpi_sbs_add(struct acpi_device *device); static int acpi_sbs_remove(struct acpi_device *device, int type); @@ -1685,16 +1685,10 @@ static int acpi_sbs_add(struct acpi_device *device) int acpi_sbs_remove(struct acpi_device *device, int type) { - struct acpi_sbs *sbs = NULL; + struct acpi_sbs *sbs = (struct acpi_sbs *)acpi_driver_data(device); int id; - if (!device) { - return -EINVAL; - } - - sbs = (struct acpi_sbs *)acpi_driver_data(device); - - if (!sbs) { + if (!device || !sbs) { return -EINVAL; } diff --git a/trunk/drivers/acpi/tables/tbget.c b/trunk/drivers/acpi/tables/tbget.c index 11e2d4454e05..7856db759af0 100644 --- a/trunk/drivers/acpi/tables/tbget.c +++ b/trunk/drivers/acpi/tables/tbget.c @@ -324,7 +324,7 @@ acpi_tb_get_this_table(struct acpi_pointer *address, if (header->length < sizeof(struct acpi_table_header)) { ACPI_ERROR((AE_INFO, - "Table length (%X) is smaller than minimum (%zX)", + "Table length (%X) is smaller than minimum (%X)", header->length, sizeof(struct acpi_table_header))); return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH); diff --git a/trunk/drivers/acpi/tables/tbrsdt.c b/trunk/drivers/acpi/tables/tbrsdt.c index 86a5fca9b739..0ad3dbb9ebca 100644 --- a/trunk/drivers/acpi/tables/tbrsdt.c +++ b/trunk/drivers/acpi/tables/tbrsdt.c @@ -187,7 +187,7 @@ acpi_status acpi_tb_validate_rsdt(struct acpi_table_header *table_ptr) if (table_ptr->length < sizeof(struct acpi_table_header)) { ACPI_ERROR((AE_INFO, - "RSDT/XSDT length (%X) is smaller than minimum (%zX)", + "RSDT/XSDT length (%X) is smaller than minimum (%X)", table_ptr->length, sizeof(struct acpi_table_header))); diff --git a/trunk/drivers/ata/Kconfig b/trunk/drivers/ata/Kconfig index 03f6338acc8f..3f4aa0c99ee4 100644 --- a/trunk/drivers/ata/Kconfig +++ b/trunk/drivers/ata/Kconfig @@ -6,7 +6,6 @@ menu "Serial ATA (prod) and Parallel ATA (experimental) drivers" config ATA tristate "ATA device support" - depends on BLOCK depends on !(M32R || M68K) || BROKEN depends on !SUN4 || BROKEN select SCSI diff --git a/trunk/drivers/ata/ahci.c b/trunk/drivers/ata/ahci.c index bddb14e91d3c..54e1f38ce301 100644 --- a/trunk/drivers/ata/ahci.c +++ b/trunk/drivers/ata/ahci.c @@ -78,7 +78,6 @@ enum { board_ahci = 0, board_ahci_vt8251 = 1, - board_ahci_ign_iferr = 2, /* global controller registers */ HOST_CAP = 0x00, /* host capabilities */ @@ -169,7 +168,6 @@ enum { /* ap->flags bits */ AHCI_FLAG_RESET_NEEDS_CLO = (1 << 24), AHCI_FLAG_NO_NCQ = (1 << 25), - AHCI_FLAG_IGN_IRQ_IF_ERR = (1 << 26), /* ignore IRQ_IF_ERR */ }; struct ahci_cmd_hdr { @@ -206,7 +204,7 @@ static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg); static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc); -static irqreturn_t ahci_interrupt (int irq, void *dev_instance); +static irqreturn_t ahci_interrupt (int irq, void *dev_instance, struct pt_regs *regs); static void ahci_irq_clear(struct ata_port *ap); static int ahci_port_start(struct ata_port *ap); static void ahci_port_stop(struct ata_port *ap); @@ -297,17 +295,6 @@ static const struct ata_port_info ahci_port_info[] = { .udma_mask = 0x7f, /* udma0-6 ; FIXME */ .port_ops = &ahci_ops, }, - /* board_ahci_ign_iferr */ - { - .sht = &ahci_sht, - .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | - ATA_FLAG_SKIP_D2H_BSY | - AHCI_FLAG_IGN_IRQ_IF_ERR, - .pio_mask = 0x1f, /* pio0-4 */ - .udma_mask = 0x7f, /* udma0-6 ; FIXME */ - .port_ops = &ahci_ops, - }, }; static const struct pci_device_id ahci_pci_tbl[] = { @@ -327,24 +314,13 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(INTEL, 0x2824), board_ahci }, /* ICH8 */ { PCI_VDEVICE(INTEL, 0x2829), board_ahci }, /* ICH8M */ { PCI_VDEVICE(INTEL, 0x282a), board_ahci }, /* ICH8M */ - { PCI_VDEVICE(INTEL, 0x2922), board_ahci }, /* ICH9 */ - { PCI_VDEVICE(INTEL, 0x2923), board_ahci }, /* ICH9 */ - { PCI_VDEVICE(INTEL, 0x2924), board_ahci }, /* ICH9 */ - { PCI_VDEVICE(INTEL, 0x2925), board_ahci }, /* ICH9 */ - { PCI_VDEVICE(INTEL, 0x2927), board_ahci }, /* ICH9 */ - { PCI_VDEVICE(INTEL, 0x2929), board_ahci }, /* ICH9M */ - { PCI_VDEVICE(INTEL, 0x292a), board_ahci }, /* ICH9M */ - { PCI_VDEVICE(INTEL, 0x292b), board_ahci }, /* ICH9M */ - { PCI_VDEVICE(INTEL, 0x292f), board_ahci }, /* ICH9M */ - { PCI_VDEVICE(INTEL, 0x294d), board_ahci }, /* ICH9 */ - { PCI_VDEVICE(INTEL, 0x294e), board_ahci }, /* ICH9M */ /* JMicron */ - { PCI_VDEVICE(JMICRON, 0x2360), board_ahci_ign_iferr }, /* JMB360 */ - { PCI_VDEVICE(JMICRON, 0x2361), board_ahci_ign_iferr }, /* JMB361 */ - { PCI_VDEVICE(JMICRON, 0x2363), board_ahci_ign_iferr }, /* JMB363 */ - { PCI_VDEVICE(JMICRON, 0x2365), board_ahci_ign_iferr }, /* JMB365 */ - { PCI_VDEVICE(JMICRON, 0x2366), board_ahci_ign_iferr }, /* JMB366 */ + { PCI_VDEVICE(JMICRON, 0x2360), board_ahci }, /* JMicron JMB360 */ + { PCI_VDEVICE(JMICRON, 0x2361), board_ahci }, /* JMicron JMB361 */ + { PCI_VDEVICE(JMICRON, 0x2363), board_ahci }, /* JMicron JMB363 */ + { PCI_VDEVICE(JMICRON, 0x2365), board_ahci }, /* JMicron JMB365 */ + { PCI_VDEVICE(JMICRON, 0x2366), board_ahci }, /* JMicron JMB366 */ /* ATI */ { PCI_VDEVICE(ATI, 0x4380), board_ahci }, /* ATI SB600 non-raid */ @@ -358,14 +334,6 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(NVIDIA, 0x044d), board_ahci }, /* MCP65 */ { PCI_VDEVICE(NVIDIA, 0x044e), board_ahci }, /* MCP65 */ { PCI_VDEVICE(NVIDIA, 0x044f), board_ahci }, /* MCP65 */ - { PCI_VDEVICE(NVIDIA, 0x0554), board_ahci }, /* MCP67 */ - { PCI_VDEVICE(NVIDIA, 0x0555), board_ahci }, /* MCP67 */ - { PCI_VDEVICE(NVIDIA, 0x0556), board_ahci }, /* MCP67 */ - { PCI_VDEVICE(NVIDIA, 0x0557), board_ahci }, /* MCP67 */ - { PCI_VDEVICE(NVIDIA, 0x0558), board_ahci }, /* MCP67 */ - { PCI_VDEVICE(NVIDIA, 0x0559), board_ahci }, /* MCP67 */ - { PCI_VDEVICE(NVIDIA, 0x055a), board_ahci }, /* MCP67 */ - { PCI_VDEVICE(NVIDIA, 0x055b), board_ahci }, /* MCP67 */ /* SiS */ { PCI_VDEVICE(SI, 0x1184), board_ahci }, /* SiS 966 */ @@ -768,7 +736,8 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class) } /* check BUSY/DRQ, perform Command List Override if necessary */ - if (ahci_check_status(ap) & (ATA_BUSY | ATA_DRQ)) { + ahci_tf_read(ap, &tf); + if (tf.command & (ATA_BUSY | ATA_DRQ)) { rc = ahci_clo(ap); if (rc == -EOPNOTSUPP) { @@ -993,10 +962,6 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat) /* analyze @irq_stat */ ata_ehi_push_desc(ehi, "irq_stat 0x%08x", irq_stat); - /* some controllers set IRQ_IF_ERR on device errors, ignore it */ - if (ap->flags & AHCI_FLAG_IGN_IRQ_IF_ERR) - irq_stat &= ~PORT_IRQ_IF_ERR; - if (irq_stat & PORT_IRQ_TF_ERR) err_mask |= AC_ERR_DEV; @@ -1076,7 +1041,7 @@ static void ahci_host_intr(struct ata_port *ap) /* hmmm... a spurious interupt */ /* some devices send D2H reg with I bit set during NCQ command phase */ - if (ap->sactive && (status & PORT_IRQ_D2H_REG_FIS)) + if (ap->sactive && status & PORT_IRQ_D2H_REG_FIS) return; /* ignore interim PIO setup fis interrupts */ @@ -1094,7 +1059,7 @@ static void ahci_irq_clear(struct ata_port *ap) /* TODO */ } -static irqreturn_t ahci_interrupt(int irq, void *dev_instance) +static irqreturn_t ahci_interrupt(int irq, void *dev_instance, struct pt_regs *regs) { struct ata_host *host = dev_instance; struct ahci_host_priv *hpriv; diff --git a/trunk/drivers/ata/ata_generic.c b/trunk/drivers/ata/ata_generic.c index 4a80ff9312b8..377425e71391 100644 --- a/trunk/drivers/ata/ata_generic.c +++ b/trunk/drivers/ata/ata_generic.c @@ -116,7 +116,6 @@ static struct scsi_host_template generic_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; diff --git a/trunk/drivers/ata/ata_piix.c b/trunk/drivers/ata/ata_piix.c index 720174d628fa..5719704eb0ee 100644 --- a/trunk/drivers/ata/ata_piix.c +++ b/trunk/drivers/ata/ata_piix.c @@ -126,7 +126,8 @@ enum { ich6_sata = 7, ich6_sata_ahci = 8, ich6m_sata_ahci = 9, - ich8_sata_ahci = 10, + ich7m_sata_ahci = 10, + ich8_sata_ahci = 11, /* constants for mapping table */ P0 = 0, /* port 0 */ @@ -226,7 +227,7 @@ static const struct pci_device_id piix_pci_tbl[] = { /* 82801GB/GR/GH (ICH7, identical to ICH6) */ { 0x8086, 0x27c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci }, /* 2801GBM/GHM (ICH7M, identical to ICH6M) */ - { 0x8086, 0x27c4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6m_sata_ahci }, + { 0x8086, 0x27c4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich7m_sata_ahci }, /* Enterprise Southbridge 2 (where's the datasheet?) */ { 0x8086, 0x2680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci }, /* SATA Controller 1 IDE (ICH8, no datasheet yet) */ @@ -398,10 +399,23 @@ static const struct piix_map_db ich6m_map_db = { .mask = 0x3, .port_enable = 0x5, .present_shift = 4, + .map = { + /* PM PS SM SS MAP */ + { P0, P2, RV, RV }, /* 00b */ + { RV, RV, RV, RV }, + { P0, P2, IDE, IDE }, /* 10b */ + { RV, RV, RV, RV }, + }, +}; + +static const struct piix_map_db ich7m_map_db = { + .mask = 0x3, + .port_enable = 0x5, + .present_shift = 4, /* Map 01b isn't specified in the doc but some notebooks use - * it anyway. MAP 01b have been spotted on both ICH6M and - * ICH7M. + * it anyway. ATM, the only case spotted carries subsystem ID + * 1025:0107. This is the only difference from ich6m. */ .map = { /* PM PS SM SS MAP */ @@ -418,9 +432,9 @@ static const struct piix_map_db ich8_map_db = { .present_shift = 8, .map = { /* PM PS SM SS MAP */ - { P0, P2, P1, P3 }, /* 00b (hardwired when in AHCI) */ + { P0, NA, P1, NA }, /* 00b (hardwired) */ { RV, RV, RV, RV }, - { IDE, IDE, NA, NA }, /* 10b (IDE mode) */ + { RV, RV, RV, RV }, /* 10b (never) */ { RV, RV, RV, RV }, }, }; @@ -431,6 +445,7 @@ static const struct piix_map_db *piix_map_db_table[] = { [ich6_sata] = &ich6_map_db, [ich6_sata_ahci] = &ich6_map_db, [ich6m_sata_ahci] = &ich6m_map_db, + [ich7m_sata_ahci] = &ich7m_map_db, [ich8_sata_ahci] = &ich8_map_db, }; @@ -541,7 +556,19 @@ static struct ata_port_info piix_port_info[] = { .port_ops = &piix_sata_ops, }, - /* ich8_sata_ahci: 10 */ + /* ich7m_sata_ahci: 10 */ + { + .sht = &piix_sht, + .flags = ATA_FLAG_SATA | + PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR | + PIIX_FLAG_AHCI, + .pio_mask = 0x1f, /* pio0-4 */ + .mwdma_mask = 0x07, /* mwdma0-2 */ + .udma_mask = 0x7f, /* udma0-6 */ + .port_ops = &piix_sata_ops, + }, + + /* ich8_sata_ahci: 11 */ { .sht = &piix_sht, .flags = ATA_FLAG_SATA | diff --git a/trunk/drivers/ata/libata-core.c b/trunk/drivers/ata/libata-core.c index 915a55a6cc14..dce65651d858 100644 --- a/trunk/drivers/ata/libata-core.c +++ b/trunk/drivers/ata/libata-core.c @@ -870,11 +870,7 @@ static unsigned int ata_id_xfermask(const u16 *id) * the PIO timing number for the maximum. Turn it into * a mask. */ - u8 mode = id[ATA_ID_OLD_PIO_MODES] & 0xFF; - if (mode < 5) /* Valid PIO range */ - pio_mask = (2 << mode) - 1; - else - pio_mask = 1; + pio_mask = (2 << (id[ATA_ID_OLD_PIO_MODES] & 0xFF)) - 1 ; /* But wait.. there's more. Design your standards by * committee and you too can get a free iordy field to @@ -4861,6 +4857,7 @@ inline unsigned int ata_host_intr (struct ata_port *ap, * ata_interrupt - Default ATA host interrupt handler * @irq: irq line (unused) * @dev_instance: pointer to our ata_host information structure + * @regs: unused * * Default interrupt handler for PCI IDE devices. Calls * ata_host_intr() for each port that is not disabled. @@ -4872,7 +4869,7 @@ inline unsigned int ata_host_intr (struct ata_port *ap, * IRQ_NONE or IRQ_HANDLED. */ -irqreturn_t ata_interrupt (int irq, void *dev_instance) +irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs) { struct ata_host *host = dev_instance; unsigned int i; @@ -5957,7 +5954,7 @@ static void __exit ata_exit(void) destroy_workqueue(ata_aux_wq); } -subsys_initcall(ata_init); +module_init(ata_init); module_exit(ata_exit); static unsigned long ratelimit_time; @@ -6122,6 +6119,7 @@ EXPORT_SYMBOL_GPL(ata_std_prereset); EXPORT_SYMBOL_GPL(ata_std_softreset); EXPORT_SYMBOL_GPL(sata_std_hardreset); EXPORT_SYMBOL_GPL(ata_std_postreset); +EXPORT_SYMBOL_GPL(ata_dev_revalidate); EXPORT_SYMBOL_GPL(ata_dev_classify); EXPORT_SYMBOL_GPL(ata_dev_pair); EXPORT_SYMBOL_GPL(ata_port_disable); diff --git a/trunk/drivers/ata/libata-scsi.c b/trunk/drivers/ata/libata-scsi.c index 47ea111d5ace..b0d0cc41f3e8 100644 --- a/trunk/drivers/ata/libata-scsi.c +++ b/trunk/drivers/ata/libata-scsi.c @@ -164,10 +164,10 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg) { int rc = 0; u8 scsi_cmd[MAX_COMMAND_SIZE]; - u8 args[4], *argbuf = NULL, *sensebuf = NULL; + u8 args[4], *argbuf = NULL; int argsize = 0; + struct scsi_sense_hdr sshdr; enum dma_data_direction data_dir; - int cmd_result; if (arg == NULL) return -EINVAL; @@ -175,10 +175,6 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg) if (copy_from_user(args, arg, sizeof(args))) return -EFAULT; - sensebuf = kzalloc(SCSI_SENSE_BUFFERSIZE, GFP_NOIO); - if (!sensebuf) - return -ENOMEM; - memset(scsi_cmd, 0, sizeof(scsi_cmd)); if (args[3]) { @@ -195,7 +191,7 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg) data_dir = DMA_FROM_DEVICE; } else { scsi_cmd[1] = (3 << 1); /* Non-data */ - scsi_cmd[2] = 0x20; /* cc but no off.line or data xfer */ + /* scsi_cmd[2] is already 0 -- no off.line, cc, or data xfer */ data_dir = DMA_NONE; } @@ -214,46 +210,18 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg) /* Good values for timeout and retries? Values below from scsi_ioctl_send_command() for default case... */ - cmd_result = scsi_execute(scsidev, scsi_cmd, data_dir, argbuf, argsize, - sensebuf, (10*HZ), 5, 0); - - if (driver_byte(cmd_result) == DRIVER_SENSE) {/* sense data available */ - u8 *desc = sensebuf + 8; - cmd_result &= ~(0xFF<<24); /* DRIVER_SENSE is not an error */ - - /* If we set cc then ATA pass-through will cause a - * check condition even if no error. Filter that. */ - if (cmd_result & SAM_STAT_CHECK_CONDITION) { - struct scsi_sense_hdr sshdr; - scsi_normalize_sense(sensebuf, SCSI_SENSE_BUFFERSIZE, - &sshdr); - if (sshdr.sense_key==0 && - sshdr.asc==0 && sshdr.ascq==0) - cmd_result &= ~SAM_STAT_CHECK_CONDITION; - } - - /* Send userspace a few ATA registers (same as drivers/ide) */ - if (sensebuf[0] == 0x72 && /* format is "descriptor" */ - desc[0] == 0x09 ) { /* code is "ATA Descriptor" */ - args[0] = desc[13]; /* status */ - args[1] = desc[3]; /* error */ - args[2] = desc[5]; /* sector count (0:7) */ - if (copy_to_user(arg, args, sizeof(args))) - rc = -EFAULT; - } - } - - - if (cmd_result) { + if (scsi_execute_req(scsidev, scsi_cmd, data_dir, argbuf, argsize, + &sshdr, (10*HZ), 5)) { rc = -EIO; goto error; } + /* Need code to retrieve data from check condition? */ + if ((argbuf) && copy_to_user(arg + sizeof(args), argbuf, argsize)) rc = -EFAULT; error: - kfree(sensebuf); kfree(argbuf); return rc; } @@ -1451,7 +1419,6 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm static void ata_scsi_qc_complete(struct ata_queued_cmd *qc) { - struct ata_port *ap = qc->ap; struct scsi_cmnd *cmd = qc->scsicmd; u8 *cdb = cmd->cmnd; int need_sense = (qc->err_mask != 0); @@ -1460,12 +1427,11 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc) * schedule EH_REVALIDATE operation to update the IDENTIFY DEVICE * cache */ - if (ap->ops->error_handler && - !need_sense && (qc->tf.command == ATA_CMD_SET_FEATURES) && + if (!need_sense && (qc->tf.command == ATA_CMD_SET_FEATURES) && ((qc->tf.feature == SETFEATURES_WC_ON) || (qc->tf.feature == SETFEATURES_WC_OFF))) { - ap->eh_info.action |= ATA_EH_REVALIDATE; - ata_port_schedule_eh(ap); + qc->ap->eh_info.action |= ATA_EH_REVALIDATE; + ata_port_schedule_eh(qc->ap); } /* For ATA pass thru (SAT) commands, generate a sense block if @@ -1492,8 +1458,8 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc) } } - if (need_sense && !ap->ops->error_handler) - ata_dump_status(ap->id, &qc->result_tf); + if (need_sense && !qc->ap->ops->error_handler) + ata_dump_status(qc->ap->id, &qc->result_tf); qc->scsidone(cmd); @@ -1614,9 +1580,9 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd, err_did: ata_qc_free(qc); +err_mem: cmd->result = (DID_ERROR << 16); done(cmd); -err_mem: DPRINTK("EXIT - internal\n"); return 0; @@ -3347,23 +3313,20 @@ EXPORT_SYMBOL_GPL(ata_sas_slave_configure); * @ap: ATA port to which the command is being sent * * RETURNS: - * Return value from __ata_scsi_queuecmd() if @cmd can be queued, - * 0 otherwise. + * Zero. */ int ata_sas_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *), struct ata_port *ap) { - int rc = 0; - ata_scsi_dump_cdb(ap, cmd); if (likely(ata_scsi_dev_enabled(ap->device))) - rc = __ata_scsi_queuecmd(cmd, done, ap->device); + __ata_scsi_queuecmd(cmd, done, ap->device); else { cmd->result = (DID_BAD_TARGET << 16); done(cmd); } - return rc; + return 0; } EXPORT_SYMBOL_GPL(ata_sas_queuecmd); diff --git a/trunk/drivers/ata/libata-sff.c b/trunk/drivers/ata/libata-sff.c index 7645f2b30ccf..06daaa3736a2 100644 --- a/trunk/drivers/ata/libata-sff.c +++ b/trunk/drivers/ata/libata-sff.c @@ -981,15 +981,6 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, mask = (1 << 2) | (1 << 0); if ((tmp8 & mask) != mask) legacy_mode = (1 << 3); -#if defined(CONFIG_NO_ATA_LEGACY) - /* Some platforms with PCI limits cannot address compat - port space. In that case we punt if their firmware has - left a device in compatibility mode */ - if (legacy_mode) { - printk(KERN_ERR "ata: Compatibility mode ATA is not supported on this platform, skipping.\n"); - return -EOPNOTSUPP; - } -#endif } rc = pci_request_regions(pdev, DRV_NAME); diff --git a/trunk/drivers/ata/libata.h b/trunk/drivers/ata/libata.h index 0ed263be652a..a5ecb71390a9 100644 --- a/trunk/drivers/ata/libata.h +++ b/trunk/drivers/ata/libata.h @@ -53,7 +53,6 @@ extern unsigned ata_exec_internal(struct ata_device *dev, extern unsigned int ata_do_simple_cmd(struct ata_device *dev, u8 cmd); extern int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, int post_reset, u16 *id); -extern int ata_dev_revalidate(struct ata_device *dev, int post_reset); extern int ata_dev_configure(struct ata_device *dev, int print_info); extern int sata_down_spd_limit(struct ata_port *ap); extern int sata_set_spd_needed(struct ata_port *ap); diff --git a/trunk/drivers/ata/pata_ali.c b/trunk/drivers/ata/pata_ali.c index 64eed99f6814..1d695df5860a 100644 --- a/trunk/drivers/ata/pata_ali.c +++ b/trunk/drivers/ata/pata_ali.c @@ -346,7 +346,6 @@ static struct scsi_host_template ali_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; diff --git a/trunk/drivers/ata/pata_amd.c b/trunk/drivers/ata/pata_amd.c index 8be46a63af74..29234c897118 100644 --- a/trunk/drivers/ata/pata_amd.c +++ b/trunk/drivers/ata/pata_amd.c @@ -333,7 +333,6 @@ static struct scsi_host_template amd_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; @@ -678,8 +677,6 @@ static const struct pci_device_id amd[] = { { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE), 8 }, { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE), 8 }, { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE), 8 }, - { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE), 8 }, - { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE), 8 }, { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_CS5536_IDE), 9 }, { }, diff --git a/trunk/drivers/ata/pata_artop.c b/trunk/drivers/ata/pata_artop.c index 2cd30761ca1f..690828eb5226 100644 --- a/trunk/drivers/ata/pata_artop.c +++ b/trunk/drivers/ata/pata_artop.c @@ -92,7 +92,7 @@ static int artop6260_pre_reset(struct ata_port *ap) return -ENOENT; pci_read_config_byte(pdev, 0x49, &tmp); - if (tmp & (1 << ap->port_no)) + if (tmp & (1 >> ap->port_no)) ap->cbl = ATA_CBL_PATA40; else ap->cbl = ATA_CBL_PATA80; @@ -314,7 +314,6 @@ static struct scsi_host_template artop_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; diff --git a/trunk/drivers/ata/pata_atiixp.c b/trunk/drivers/ata/pata_atiixp.c index 4e1d3b59adbb..1ce28d2125f4 100644 --- a/trunk/drivers/ata/pata_atiixp.c +++ b/trunk/drivers/ata/pata_atiixp.c @@ -216,7 +216,6 @@ static struct scsi_host_template atiixp_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; diff --git a/trunk/drivers/ata/pata_cmd64x.c b/trunk/drivers/ata/pata_cmd64x.c index 29a60df465da..b9bbd1d454bf 100644 --- a/trunk/drivers/ata/pata_cmd64x.c +++ b/trunk/drivers/ata/pata_cmd64x.c @@ -275,7 +275,6 @@ static struct scsi_host_template cmd64x_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; diff --git a/trunk/drivers/ata/pata_cs5520.c b/trunk/drivers/ata/pata_cs5520.c index 33d2b88f9c79..2cd3c0ff76df 100644 --- a/trunk/drivers/ata/pata_cs5520.c +++ b/trunk/drivers/ata/pata_cs5520.c @@ -166,7 +166,6 @@ static struct scsi_host_template cs5520_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; diff --git a/trunk/drivers/ata/pata_cs5530.c b/trunk/drivers/ata/pata_cs5530.c index 981f49223469..a07cc81ef791 100644 --- a/trunk/drivers/ata/pata_cs5530.c +++ b/trunk/drivers/ata/pata_cs5530.c @@ -180,7 +180,6 @@ static struct scsi_host_template cs5530_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; diff --git a/trunk/drivers/ata/pata_cs5535.c b/trunk/drivers/ata/pata_cs5535.c index 8dafa4a49fdc..f8def3f9c618 100644 --- a/trunk/drivers/ata/pata_cs5535.c +++ b/trunk/drivers/ata/pata_cs5535.c @@ -184,7 +184,6 @@ static struct scsi_host_template cs5535_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; diff --git a/trunk/drivers/ata/pata_cypress.c b/trunk/drivers/ata/pata_cypress.c index 5a0b811907ee..247b43608b14 100644 --- a/trunk/drivers/ata/pata_cypress.c +++ b/trunk/drivers/ata/pata_cypress.c @@ -135,7 +135,6 @@ static struct scsi_host_template cy82c693_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; diff --git a/trunk/drivers/ata/pata_efar.c b/trunk/drivers/ata/pata_efar.c index 755f79279de3..ef18c60fe140 100644 --- a/trunk/drivers/ata/pata_efar.c +++ b/trunk/drivers/ata/pata_efar.c @@ -233,7 +233,6 @@ static struct scsi_host_template efar_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; diff --git a/trunk/drivers/ata/pata_hpt366.c b/trunk/drivers/ata/pata_hpt366.c index c0e150a9586b..6d3e4c0f15fe 100644 --- a/trunk/drivers/ata/pata_hpt366.c +++ b/trunk/drivers/ata/pata_hpt366.c @@ -329,7 +329,6 @@ static struct scsi_host_template hpt36x_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; diff --git a/trunk/drivers/ata/pata_hpt37x.c b/trunk/drivers/ata/pata_hpt37x.c index 1eeb16f0fb02..7350443948c1 100644 --- a/trunk/drivers/ata/pata_hpt37x.c +++ b/trunk/drivers/ata/pata_hpt37x.c @@ -25,7 +25,7 @@ #include #define DRV_NAME "pata_hpt37x" -#define DRV_VERSION "0.5.1" +#define DRV_VERSION "0.5" struct hpt_clock { u8 xfer_speed; @@ -453,13 +453,7 @@ static int hpt37x_pre_reset(struct ata_port *ap) { u8 scr2, ata66; struct pci_dev *pdev = to_pci_dev(ap->host->dev); - static const struct pci_bits hpt37x_enable_bits[] = { - { 0x50, 1, 0x04, 0x04 }, - { 0x54, 1, 0x04, 0x04 } - }; - if (!pci_test_config_bits(pdev, &hpt37x_enable_bits[ap->port_no])) - return -ENOENT; - + pci_read_config_byte(pdev, 0x5B, &scr2); pci_write_config_byte(pdev, 0x5B, scr2 & ~0x01); /* Cable register now active */ @@ -494,17 +488,10 @@ static void hpt37x_error_handler(struct ata_port *ap) static int hpt374_pre_reset(struct ata_port *ap) { - static const struct pci_bits hpt37x_enable_bits[] = { - { 0x50, 1, 0x04, 0x04 }, - { 0x54, 1, 0x04, 0x04 } - }; u16 mcr3, mcr6; u8 ata66; - struct pci_dev *pdev = to_pci_dev(ap->host->dev); - if (!pci_test_config_bits(pdev, &hpt37x_enable_bits[ap->port_no])) - return -ENOENT; - + struct pci_dev *pdev = to_pci_dev(ap->host->dev); /* Do the extra channel work */ pci_read_config_word(pdev, 0x52, &mcr3); pci_read_config_word(pdev, 0x56, &mcr6); @@ -775,7 +762,6 @@ static struct scsi_host_template hpt37x_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; diff --git a/trunk/drivers/ata/pata_hpt3x2n.c b/trunk/drivers/ata/pata_hpt3x2n.c index 47d7664e9eee..58cfb2bc8098 100644 --- a/trunk/drivers/ata/pata_hpt3x2n.c +++ b/trunk/drivers/ata/pata_hpt3x2n.c @@ -341,7 +341,6 @@ static struct scsi_host_template hpt3x2n_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; diff --git a/trunk/drivers/ata/pata_hpt3x3.c b/trunk/drivers/ata/pata_hpt3x3.c index d216cc564b56..3334d72e251b 100644 --- a/trunk/drivers/ata/pata_hpt3x3.c +++ b/trunk/drivers/ata/pata_hpt3x3.c @@ -118,7 +118,6 @@ static struct scsi_host_template hpt3x3_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; diff --git a/trunk/drivers/ata/pata_isapnp.c b/trunk/drivers/ata/pata_isapnp.c index 40ca2b82b7fc..640b8b0954f5 100644 --- a/trunk/drivers/ata/pata_isapnp.c +++ b/trunk/drivers/ata/pata_isapnp.c @@ -34,7 +34,6 @@ static struct scsi_host_template isapnp_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; diff --git a/trunk/drivers/ata/pata_it821x.c b/trunk/drivers/ata/pata_it821x.c index 7f68f14be6fd..18ff3e59a89b 100644 --- a/trunk/drivers/ata/pata_it821x.c +++ b/trunk/drivers/ata/pata_it821x.c @@ -675,7 +675,6 @@ static struct scsi_host_template it821x_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; diff --git a/trunk/drivers/ata/pata_jmicron.c b/trunk/drivers/ata/pata_jmicron.c index 0210b10d49cd..52a2bdf3c38d 100644 --- a/trunk/drivers/ata/pata_jmicron.c +++ b/trunk/drivers/ata/pata_jmicron.c @@ -136,7 +136,6 @@ static struct scsi_host_template jmicron_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, /* Use standard CHS mapping rules */ .bios_param = ata_std_bios_param, }; diff --git a/trunk/drivers/ata/pata_legacy.c b/trunk/drivers/ata/pata_legacy.c index b39078b2a47b..10231ef731d1 100644 --- a/trunk/drivers/ata/pata_legacy.c +++ b/trunk/drivers/ata/pata_legacy.c @@ -135,7 +135,6 @@ static struct scsi_host_template legacy_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; diff --git a/trunk/drivers/ata/pata_mpiix.c b/trunk/drivers/ata/pata_mpiix.c index e00d406bfdf5..9dfe3e9abea3 100644 --- a/trunk/drivers/ata/pata_mpiix.c +++ b/trunk/drivers/ata/pata_mpiix.c @@ -166,7 +166,6 @@ static struct scsi_host_template mpiix_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; diff --git a/trunk/drivers/ata/pata_netcell.c b/trunk/drivers/ata/pata_netcell.c index 1963a4d35873..f5672de99c22 100644 --- a/trunk/drivers/ata/pata_netcell.c +++ b/trunk/drivers/ata/pata_netcell.c @@ -62,7 +62,6 @@ static struct scsi_host_template netcell_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, /* Use standard CHS mapping rules */ .bios_param = ata_std_bios_param, }; diff --git a/trunk/drivers/ata/pata_ns87410.c b/trunk/drivers/ata/pata_ns87410.c index 7ec800f00ec8..2a3dbeed89b4 100644 --- a/trunk/drivers/ata/pata_ns87410.c +++ b/trunk/drivers/ata/pata_ns87410.c @@ -156,7 +156,6 @@ static struct scsi_host_template ns87410_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; diff --git a/trunk/drivers/ata/pata_oldpiix.c b/trunk/drivers/ata/pata_oldpiix.c index 8837256632e9..fc947dfecd73 100644 --- a/trunk/drivers/ata/pata_oldpiix.c +++ b/trunk/drivers/ata/pata_oldpiix.c @@ -231,7 +231,6 @@ static struct scsi_host_template oldpiix_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; diff --git a/trunk/drivers/ata/pata_opti.c b/trunk/drivers/ata/pata_opti.c index c6319cf50de4..a7320ba15575 100644 --- a/trunk/drivers/ata/pata_opti.c +++ b/trunk/drivers/ata/pata_opti.c @@ -202,7 +202,6 @@ static struct scsi_host_template opti_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; diff --git a/trunk/drivers/ata/pata_optidma.c b/trunk/drivers/ata/pata_optidma.c index 2f4770cce04e..c6906b4215de 100644 --- a/trunk/drivers/ata/pata_optidma.c +++ b/trunk/drivers/ata/pata_optidma.c @@ -359,7 +359,6 @@ static struct scsi_host_template optidma_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; diff --git a/trunk/drivers/ata/pata_pcmcia.c b/trunk/drivers/ata/pata_pcmcia.c index 999922de476e..e93ea2702c73 100644 --- a/trunk/drivers/ata/pata_pcmcia.c +++ b/trunk/drivers/ata/pata_pcmcia.c @@ -69,7 +69,6 @@ static struct scsi_host_template pcmcia_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; diff --git a/trunk/drivers/ata/pata_pdc2027x.c b/trunk/drivers/ata/pata_pdc2027x.c index beb6d10a234b..d894d9918b1d 100644 --- a/trunk/drivers/ata/pata_pdc2027x.c +++ b/trunk/drivers/ata/pata_pdc2027x.c @@ -141,7 +141,6 @@ static struct scsi_host_template pdc2027x_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; diff --git a/trunk/drivers/ata/pata_pdc202xx_old.c b/trunk/drivers/ata/pata_pdc202xx_old.c index 6baf51b2fda1..5ba9eb20a6c2 100644 --- a/trunk/drivers/ata/pata_pdc202xx_old.c +++ b/trunk/drivers/ata/pata_pdc202xx_old.c @@ -269,7 +269,6 @@ static struct scsi_host_template pdc_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; diff --git a/trunk/drivers/ata/pata_qdi.c b/trunk/drivers/ata/pata_qdi.c index 314938dea1fc..7977f471d5e9 100644 --- a/trunk/drivers/ata/pata_qdi.c +++ b/trunk/drivers/ata/pata_qdi.c @@ -141,7 +141,7 @@ static void qdi_data_xfer(struct ata_device *adev, unsigned char *buf, unsigned memcpy(&pad, buf + buflen - slop, slop); outl(le32_to_cpu(pad), ap->ioaddr.data_addr); } else { - pad = cpu_to_le32(inl(ap->ioaddr.data_addr)); + pad = cpu_to_le16(inl(ap->ioaddr.data_addr)); memcpy(buf + buflen - slop, &pad, slop); } } @@ -164,7 +164,6 @@ static struct scsi_host_template qdi_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; diff --git a/trunk/drivers/ata/pata_radisys.c b/trunk/drivers/ata/pata_radisys.c index 048c2bb21ef1..1af83d7694d5 100644 --- a/trunk/drivers/ata/pata_radisys.c +++ b/trunk/drivers/ata/pata_radisys.c @@ -227,7 +227,6 @@ static struct scsi_host_template radisys_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; diff --git a/trunk/drivers/ata/pata_rz1000.c b/trunk/drivers/ata/pata_rz1000.c index e4e5ea423fef..4533b6357d99 100644 --- a/trunk/drivers/ata/pata_rz1000.c +++ b/trunk/drivers/ata/pata_rz1000.c @@ -90,7 +90,6 @@ static struct scsi_host_template rz1000_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; diff --git a/trunk/drivers/ata/pata_sc1200.c b/trunk/drivers/ata/pata_sc1200.c index 0c75dae74764..067d9d223e35 100644 --- a/trunk/drivers/ata/pata_sc1200.c +++ b/trunk/drivers/ata/pata_sc1200.c @@ -193,7 +193,6 @@ static struct scsi_host_template sc1200_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; diff --git a/trunk/drivers/ata/pata_serverworks.c b/trunk/drivers/ata/pata_serverworks.c index be7f60efcb61..5bbf76ec14a4 100644 --- a/trunk/drivers/ata/pata_serverworks.c +++ b/trunk/drivers/ata/pata_serverworks.c @@ -325,7 +325,6 @@ static struct scsi_host_template serverworks_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; diff --git a/trunk/drivers/ata/pata_sil680.c b/trunk/drivers/ata/pata_sil680.c index 11942fd03b55..4a2b72b4be8a 100644 --- a/trunk/drivers/ata/pata_sil680.c +++ b/trunk/drivers/ata/pata_sil680.c @@ -225,7 +225,6 @@ static struct scsi_host_template sil680_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; diff --git a/trunk/drivers/ata/pata_sis.c b/trunk/drivers/ata/pata_sis.c index 91e85f90941d..b9ffafb4198c 100644 --- a/trunk/drivers/ata/pata_sis.c +++ b/trunk/drivers/ata/pata_sis.c @@ -545,7 +545,6 @@ static struct scsi_host_template sis_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; diff --git a/trunk/drivers/ata/pata_sl82c105.c b/trunk/drivers/ata/pata_sl82c105.c index dc1cfc6d805b..08a6dc88676f 100644 --- a/trunk/drivers/ata/pata_sl82c105.c +++ b/trunk/drivers/ata/pata_sl82c105.c @@ -237,7 +237,6 @@ static struct scsi_host_template sl82c105_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; diff --git a/trunk/drivers/ata/pata_triflex.c b/trunk/drivers/ata/pata_triflex.c index bfda1f7e760a..9640f80e8b0d 100644 --- a/trunk/drivers/ata/pata_triflex.c +++ b/trunk/drivers/ata/pata_triflex.c @@ -192,7 +192,6 @@ static struct scsi_host_template triflex_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; diff --git a/trunk/drivers/ata/pata_via.c b/trunk/drivers/ata/pata_via.c index c5f1616d224d..1e7be9eee9c3 100644 --- a/trunk/drivers/ata/pata_via.c +++ b/trunk/drivers/ata/pata_via.c @@ -295,7 +295,6 @@ static struct scsi_host_template via_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; diff --git a/trunk/drivers/ata/pdc_adma.c b/trunk/drivers/ata/pdc_adma.c index 9021e34d2096..81f3d219e70e 100644 --- a/trunk/drivers/ata/pdc_adma.c +++ b/trunk/drivers/ata/pdc_adma.c @@ -124,7 +124,8 @@ struct adma_port_priv { static int adma_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); -static irqreturn_t adma_intr (int irq, void *dev_instance); +static irqreturn_t adma_intr (int irq, void *dev_instance, + struct pt_regs *regs); static int adma_port_start(struct ata_port *ap); static void adma_host_stop(struct ata_host *host); static void adma_port_stop(struct ata_port *ap); @@ -507,7 +508,7 @@ static inline unsigned int adma_intr_mmio(struct ata_host *host) return handled; } -static irqreturn_t adma_intr(int irq, void *dev_instance) +static irqreturn_t adma_intr(int irq, void *dev_instance, struct pt_regs *regs) { struct ata_host *host = dev_instance; unsigned int handled = 0; diff --git a/trunk/drivers/ata/sata_mv.c b/trunk/drivers/ata/sata_mv.c index 1b8e0eb9e032..e6aa1a86d5cf 100644 --- a/trunk/drivers/ata/sata_mv.c +++ b/trunk/drivers/ata/sata_mv.c @@ -348,7 +348,8 @@ static void mv_port_stop(struct ata_port *ap); static void mv_qc_prep(struct ata_queued_cmd *qc); static void mv_qc_prep_iie(struct ata_queued_cmd *qc); static unsigned int mv_qc_issue(struct ata_queued_cmd *qc); -static irqreturn_t mv_interrupt(int irq, void *dev_instance); +static irqreturn_t mv_interrupt(int irq, void *dev_instance, + struct pt_regs *regs); static void mv_eng_timeout(struct ata_port *ap); static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); @@ -1447,7 +1448,8 @@ static void mv_host_intr(struct ata_host *host, u32 relevant, unsigned int hc) * This routine holds the host lock while processing pending * interrupts. */ -static irqreturn_t mv_interrupt(int irq, void *dev_instance) +static irqreturn_t mv_interrupt(int irq, void *dev_instance, + struct pt_regs *regs) { struct ata_host *host = dev_instance; unsigned int hc, handled = 0, n_hcs; diff --git a/trunk/drivers/ata/sata_nv.c b/trunk/drivers/ata/sata_nv.c index d65ebfd7c7b2..d09d20a17790 100644 --- a/trunk/drivers/ata/sata_nv.c +++ b/trunk/drivers/ata/sata_nv.c @@ -82,9 +82,12 @@ enum { static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); static void nv_ck804_host_stop(struct ata_host *host); -static irqreturn_t nv_generic_interrupt(int irq, void *dev_instance); -static irqreturn_t nv_nf2_interrupt(int irq, void *dev_instance); -static irqreturn_t nv_ck804_interrupt(int irq, void *dev_instance); +static irqreturn_t nv_generic_interrupt(int irq, void *dev_instance, + struct pt_regs *regs); +static irqreturn_t nv_nf2_interrupt(int irq, void *dev_instance, + struct pt_regs *regs); +static irqreturn_t nv_ck804_interrupt(int irq, void *dev_instance, + struct pt_regs *regs); static u32 nv_scr_read (struct ata_port *ap, unsigned int sc_reg); static void nv_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); @@ -117,14 +120,10 @@ static const struct pci_device_id nv_pci_tbl[] = { { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA), GENERIC }, { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA2), GENERIC }, { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3), GENERIC }, - { PCI_VDEVICE(NVIDIA, 0x045c), GENERIC }, /* MCP65 */ - { PCI_VDEVICE(NVIDIA, 0x045d), GENERIC }, /* MCP65 */ - { PCI_VDEVICE(NVIDIA, 0x045e), GENERIC }, /* MCP65 */ - { PCI_VDEVICE(NVIDIA, 0x045f), GENERIC }, /* MCP65 */ - { PCI_VDEVICE(NVIDIA, 0x0550), GENERIC }, /* MCP67 */ - { PCI_VDEVICE(NVIDIA, 0x0551), GENERIC }, /* MCP67 */ - { PCI_VDEVICE(NVIDIA, 0x0552), GENERIC }, /* MCP67 */ - { PCI_VDEVICE(NVIDIA, 0x0553), GENERIC }, /* MCP67 */ + { PCI_VDEVICE(NVIDIA, 0x045c), GENERIC }, + { PCI_VDEVICE(NVIDIA, 0x045d), GENERIC }, + { PCI_VDEVICE(NVIDIA, 0x045e), GENERIC }, + { PCI_VDEVICE(NVIDIA, 0x045f), GENERIC }, { PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE<<8, 0xffff00, GENERIC }, @@ -277,7 +276,8 @@ MODULE_LICENSE("GPL"); MODULE_DEVICE_TABLE(pci, nv_pci_tbl); MODULE_VERSION(DRV_VERSION); -static irqreturn_t nv_generic_interrupt(int irq, void *dev_instance) +static irqreturn_t nv_generic_interrupt(int irq, void *dev_instance, + struct pt_regs *regs) { struct ata_host *host = dev_instance; unsigned int i; @@ -357,7 +357,8 @@ static irqreturn_t nv_do_interrupt(struct ata_host *host, u8 irq_stat) return IRQ_RETVAL(handled); } -static irqreturn_t nv_nf2_interrupt(int irq, void *dev_instance) +static irqreturn_t nv_nf2_interrupt(int irq, void *dev_instance, + struct pt_regs *regs) { struct ata_host *host = dev_instance; u8 irq_stat; @@ -371,7 +372,8 @@ static irqreturn_t nv_nf2_interrupt(int irq, void *dev_instance) return ret; } -static irqreturn_t nv_ck804_interrupt(int irq, void *dev_instance) +static irqreturn_t nv_ck804_interrupt(int irq, void *dev_instance, + struct pt_regs *regs) { struct ata_host *host = dev_instance; u8 irq_stat; diff --git a/trunk/drivers/ata/sata_promise.c b/trunk/drivers/ata/sata_promise.c index 72eda5160fad..15c9437710fc 100644 --- a/trunk/drivers/ata/sata_promise.c +++ b/trunk/drivers/ata/sata_promise.c @@ -93,7 +93,7 @@ struct pdc_host_priv { static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg); static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); -static irqreturn_t pdc_interrupt (int irq, void *dev_instance); +static irqreturn_t pdc_interrupt (int irq, void *dev_instance, struct pt_regs *regs); static void pdc_eng_timeout(struct ata_port *ap); static int pdc_port_start(struct ata_port *ap); static void pdc_port_stop(struct ata_port *ap); @@ -260,7 +260,6 @@ static const struct pci_device_id pdc_ata_pci_tbl[] = { #if 0 { PCI_VDEVICE(PROMISE, 0x3570), board_20771 }, #endif - { PCI_VDEVICE(PROMISE, 0x3577), board_20771 }, { } /* terminate list */ }; @@ -361,7 +360,7 @@ static void pdc_sata_phy_reset(struct ata_port *ap) static void pdc_pata_cbl_detect(struct ata_port *ap) { u8 tmp; - void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr + PDC_CTLSTAT + 0x03; + void __iomem *mmio = (void *) ap->ioaddr.cmd_addr + PDC_CTLSTAT + 0x03; tmp = readb(mmio); @@ -499,7 +498,7 @@ static void pdc_irq_clear(struct ata_port *ap) readl(mmio + PDC_INT_SEQMASK); } -static irqreturn_t pdc_interrupt (int irq, void *dev_instance) +static irqreturn_t pdc_interrupt (int irq, void *dev_instance, struct pt_regs *regs) { struct ata_host *host = dev_instance; struct ata_port *ap; diff --git a/trunk/drivers/ata/sata_qstor.c b/trunk/drivers/ata/sata_qstor.c index 710909df4eaf..7f6cc3c07de5 100644 --- a/trunk/drivers/ata/sata_qstor.c +++ b/trunk/drivers/ata/sata_qstor.c @@ -114,7 +114,7 @@ struct qs_port_priv { static u32 qs_scr_read (struct ata_port *ap, unsigned int sc_reg); static void qs_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); static int qs_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); -static irqreturn_t qs_intr (int irq, void *dev_instance); +static irqreturn_t qs_intr (int irq, void *dev_instance, struct pt_regs *regs); static int qs_port_start(struct ata_port *ap); static void qs_host_stop(struct ata_host *host); static void qs_port_stop(struct ata_port *ap); @@ -454,7 +454,7 @@ static inline unsigned int qs_intr_mmio(struct ata_host *host) return handled; } -static irqreturn_t qs_intr(int irq, void *dev_instance) +static irqreturn_t qs_intr(int irq, void *dev_instance, struct pt_regs *regs) { struct ata_host *host = dev_instance; unsigned int handled = 0; diff --git a/trunk/drivers/ata/sata_sil.c b/trunk/drivers/ata/sata_sil.c index ca8d99312472..3d9fa1cc834d 100644 --- a/trunk/drivers/ata/sata_sil.c +++ b/trunk/drivers/ata/sata_sil.c @@ -116,7 +116,8 @@ static void sil_dev_config(struct ata_port *ap, struct ata_device *dev); static u32 sil_scr_read (struct ata_port *ap, unsigned int sc_reg); static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); static void sil_post_set_mode (struct ata_port *ap); -static irqreturn_t sil_interrupt(int irq, void *dev_instance); +static irqreturn_t sil_interrupt(int irq, void *dev_instance, + struct pt_regs *regs); static void sil_freeze(struct ata_port *ap); static void sil_thaw(struct ata_port *ap); @@ -349,7 +350,7 @@ static u32 sil_scr_read (struct ata_port *ap, unsigned int sc_reg) static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) { - void __iomem *mmio = (void __iomem *) sil_scr_addr(ap, sc_reg); + void *mmio = (void __iomem *) sil_scr_addr(ap, sc_reg); if (mmio) writel(val, mmio); } @@ -436,7 +437,8 @@ static void sil_host_intr(struct ata_port *ap, u32 bmdma2) ata_port_freeze(ap); } -static irqreturn_t sil_interrupt(int irq, void *dev_instance) +static irqreturn_t sil_interrupt(int irq, void *dev_instance, + struct pt_regs *regs) { struct ata_host *host = dev_instance; void __iomem *mmio_base = host->mmio_base; diff --git a/trunk/drivers/ata/sata_sil24.c b/trunk/drivers/ata/sata_sil24.c index 169e200a6a71..a951f40c2f21 100644 --- a/trunk/drivers/ata/sata_sil24.c +++ b/trunk/drivers/ata/sata_sil24.c @@ -330,7 +330,7 @@ static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf); static void sil24_qc_prep(struct ata_queued_cmd *qc); static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc); static void sil24_irq_clear(struct ata_port *ap); -static irqreturn_t sil24_interrupt(int irq, void *dev_instance); +static irqreturn_t sil24_interrupt(int irq, void *dev_instance, struct pt_regs *regs); static void sil24_freeze(struct ata_port *ap); static void sil24_thaw(struct ata_port *ap); static void sil24_error_handler(struct ata_port *ap); @@ -870,7 +870,7 @@ static inline void sil24_host_intr(struct ata_port *ap) slot_stat, ap->active_tag, ap->sactive); } -static irqreturn_t sil24_interrupt(int irq, void *dev_instance) +static irqreturn_t sil24_interrupt(int irq, void *dev_instance, struct pt_regs *regs) { struct ata_host *host = dev_instance; struct sil24_host_priv *hpriv = host->private_data; diff --git a/trunk/drivers/ata/sata_sis.c b/trunk/drivers/ata/sata_sis.c index 9d1235ba06b1..0738f52463a9 100644 --- a/trunk/drivers/ata/sata_sis.c +++ b/trunk/drivers/ata/sata_sis.c @@ -240,7 +240,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) struct ata_probe_ent *probe_ent = NULL; int rc; u32 genctl; - struct ata_port_info pi = sis_port_info, *ppi[2] = { &pi, &pi }; + struct ata_port_info *ppi[2]; int pci_dev_busy = 0; u8 pmr; u8 port2_start; @@ -265,20 +265,27 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) if (rc) goto err_out_regions; + ppi[0] = ppi[1] = &sis_port_info; + probe_ent = ata_pci_init_native_mode(pdev, ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY); + if (!probe_ent) { + rc = -ENOMEM; + goto err_out_regions; + } + /* check and see if the SCRs are in IO space or PCI cfg space */ pci_read_config_dword(pdev, SIS_GENCTL, &genctl); if ((genctl & GENCTL_IOMAPPED_SCR) == 0) - pi.flags |= SIS_FLAG_CFGSCR; + probe_ent->port_flags |= SIS_FLAG_CFGSCR; /* if hardware thinks SCRs are in IO space, but there are * no IO resources assigned, change to PCI cfg space. */ - if ((!(pi.flags & SIS_FLAG_CFGSCR)) && + if ((!(probe_ent->port_flags & SIS_FLAG_CFGSCR)) && ((pci_resource_start(pdev, SIS_SCR_PCI_BAR) == 0) || (pci_resource_len(pdev, SIS_SCR_PCI_BAR) < 128))) { genctl &= ~GENCTL_IOMAPPED_SCR; pci_write_config_dword(pdev, SIS_GENCTL, genctl); - pi.flags |= SIS_FLAG_CFGSCR; + probe_ent->port_flags |= SIS_FLAG_CFGSCR; } pci_read_config_byte(pdev, SIS_PMR, &pmr); @@ -299,12 +306,6 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) port2_start = 0x20; } - probe_ent = ata_pci_init_native_mode(pdev, ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY); - if (!probe_ent) { - rc = -ENOMEM; - goto err_out_regions; - } - if (!(probe_ent->port_flags & SIS_FLAG_CFGSCR)) { probe_ent->port[0].scr_addr = pci_resource_start(pdev, SIS_SCR_PCI_BAR); diff --git a/trunk/drivers/ata/sata_svw.c b/trunk/drivers/ata/sata_svw.c index db32d15b7fa1..84025a2fd5be 100644 --- a/trunk/drivers/ata/sata_svw.c +++ b/trunk/drivers/ata/sata_svw.c @@ -177,7 +177,7 @@ static void k2_bmdma_setup_mmio (struct ata_queued_cmd *qc) struct ata_port *ap = qc->ap; unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE); u8 dmactl; - void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr; + void *mmio = (void *) ap->ioaddr.bmdma_addr; /* load PRD table addr. */ mb(); /* make sure PRD table writes are visible to controller */ writel(ap->prd_dma, mmio + ATA_DMA_TABLE_OFS); @@ -205,7 +205,7 @@ static void k2_bmdma_setup_mmio (struct ata_queued_cmd *qc) static void k2_bmdma_start_mmio (struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; - void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr; + void *mmio = (void *) ap->ioaddr.bmdma_addr; u8 dmactl; /* start host DMA transaction */ diff --git a/trunk/drivers/ata/sata_sx4.c b/trunk/drivers/ata/sata_sx4.c index ae7992de4b08..8c74f2ff4344 100644 --- a/trunk/drivers/ata/sata_sx4.c +++ b/trunk/drivers/ata/sata_sx4.c @@ -152,7 +152,7 @@ struct pdc_host_priv { static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); -static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance); +static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance, struct pt_regs *regs); static void pdc_eng_timeout(struct ata_port *ap); static void pdc_20621_phy_reset (struct ata_port *ap); static int pdc_port_start(struct ata_port *ap); @@ -788,7 +788,7 @@ static void pdc20621_irq_clear(struct ata_port *ap) readl(mmio + PDC_20621_SEQMASK); } -static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance) +static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance, struct pt_regs *regs) { struct ata_host *host = dev_instance; struct ata_port *ap; diff --git a/trunk/drivers/ata/sata_via.c b/trunk/drivers/ata/sata_via.c index 1c7f19aecc25..f4455a1efe2d 100644 --- a/trunk/drivers/ata/sata_via.c +++ b/trunk/drivers/ata/sata_via.c @@ -230,7 +230,7 @@ static int vt6420_prereset(struct ata_port *ap) int online; /* don't do any SCR stuff if we're not loading */ - if (!(ap->pflags & ATA_PFLAG_LOADING)) + if (!ATA_PFLAG_LOADING) goto skip_scr; /* Resume phy. This is the old resume sequence from diff --git a/trunk/drivers/ata/sata_vsc.c b/trunk/drivers/ata/sata_vsc.c index e654b990b905..273d88fcf980 100644 --- a/trunk/drivers/ata/sata_vsc.c +++ b/trunk/drivers/ata/sata_vsc.c @@ -203,7 +203,8 @@ static void vsc_sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf) * * Read the interrupt register and process for the devices that have them pending. */ -static irqreturn_t vsc_sata_interrupt (int irq, void *dev_instance) +static irqreturn_t vsc_sata_interrupt (int irq, void *dev_instance, + struct pt_regs *regs) { struct ata_host *host = dev_instance; unsigned int i; diff --git a/trunk/drivers/atm/ambassador.c b/trunk/drivers/atm/ambassador.c index 9fffa7af6db1..da599e6e9d34 100644 --- a/trunk/drivers/atm/ambassador.c +++ b/trunk/drivers/atm/ambassador.c @@ -861,11 +861,18 @@ static inline void interrupts_off (amb_dev * dev) { /********** interrupt handling **********/ -static irqreturn_t interrupt_handler(int irq, void *dev_id) { - amb_dev * dev = dev_id; +static irqreturn_t interrupt_handler(int irq, void *dev_id, + struct pt_regs *pt_regs) { + amb_dev * dev = (amb_dev *) dev_id; + (void) pt_regs; PRINTD (DBG_IRQ|DBG_FLOW, "interrupt_handler: %p", dev_id); + if (!dev_id) { + PRINTD (DBG_IRQ|DBG_ERR, "irq with NULL dev_id: %d", irq); + return IRQ_NONE; + } + { u32 interrupt = rd_plain (dev, offsetof(amb_mem, interrupt)); @@ -2452,8 +2459,8 @@ static int __init amb_module_init (void) static void __exit amb_module_exit (void) { PRINTD (DBG_FLOW|DBG_INIT, "cleanup_module"); - - pci_unregister_driver(&amb_driver); + + return pci_unregister_driver(&amb_driver); } module_init(amb_module_init); diff --git a/trunk/drivers/atm/eni.c b/trunk/drivers/atm/eni.c index bc1b13c8f5d7..df359a6c14f6 100644 --- a/trunk/drivers/atm/eni.c +++ b/trunk/drivers/atm/eni.c @@ -1488,7 +1488,7 @@ static void bug_int(struct atm_dev *dev,unsigned long reason) } -static irqreturn_t eni_int(int irq,void *dev_id) +static irqreturn_t eni_int(int irq,void *dev_id,struct pt_regs *regs) { struct atm_dev *dev; struct eni_dev *eni_dev; diff --git a/trunk/drivers/atm/firestream.c b/trunk/drivers/atm/firestream.c index 697ad82f6634..5f25e5efefcd 100644 --- a/trunk/drivers/atm/firestream.c +++ b/trunk/drivers/atm/firestream.c @@ -1002,10 +1002,6 @@ static int fs_open(struct atm_vcc *atm_vcc) r = ROUND_UP; } error = make_rate (pcr, r, &tmc0, NULL); - if (error) { - kfree(tc); - return error; - } } fs_dprintk (FS_DEBUG_OPEN, "pcr = %d.\n", pcr); } @@ -1550,7 +1546,7 @@ static void __devexit free_freepool (struct fs_dev *dev, struct freepool *fp) -static irqreturn_t fs_irq (int irq, void *dev_id) +static irqreturn_t fs_irq (int irq, void *dev_id, struct pt_regs * pt_regs) { int i; u32 status; diff --git a/trunk/drivers/atm/fore200e.c b/trunk/drivers/atm/fore200e.c index 3a7b21ff30a5..98622130de5b 100644 --- a/trunk/drivers/atm/fore200e.c +++ b/trunk/drivers/atm/fore200e.c @@ -1328,7 +1328,7 @@ fore200e_irq(struct fore200e* fore200e) static irqreturn_t -fore200e_interrupt(int irq, void* dev) +fore200e_interrupt(int irq, void* dev, struct pt_regs* regs) { struct fore200e* fore200e = FORE200E_DEV((struct atm_dev*)dev); diff --git a/trunk/drivers/atm/he.c b/trunk/drivers/atm/he.c index c7314a79da0f..b22a9142b240 100644 --- a/trunk/drivers/atm/he.c +++ b/trunk/drivers/atm/he.c @@ -109,7 +109,7 @@ static int he_open(struct atm_vcc *vcc); static void he_close(struct atm_vcc *vcc); static int he_send(struct atm_vcc *vcc, struct sk_buff *skb); static int he_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg); -static irqreturn_t he_irq_handler(int irq, void *dev_id); +static irqreturn_t he_irq_handler(int irq, void *dev_id, struct pt_regs *regs); static void he_tasklet(unsigned long data); static int he_proc_read(struct atm_dev *dev,loff_t *pos,char *page); static int he_start(struct atm_dev *dev); @@ -2216,7 +2216,7 @@ he_tasklet(unsigned long data) } static irqreturn_t -he_irq_handler(int irq, void *dev_id) +he_irq_handler(int irq, void *dev_id, struct pt_regs *regs) { unsigned long flags; struct he_dev *he_dev = (struct he_dev * )dev_id; diff --git a/trunk/drivers/atm/horizon.c b/trunk/drivers/atm/horizon.c index 4dc10105d610..209dba1c70da 100644 --- a/trunk/drivers/atm/horizon.c +++ b/trunk/drivers/atm/horizon.c @@ -1382,13 +1382,24 @@ static inline void rx_data_av_handler (hrz_dev * dev) { /********** interrupt handler **********/ -static irqreturn_t interrupt_handler(int irq, void *dev_id) { +static irqreturn_t interrupt_handler(int irq, void *dev_id, + struct pt_regs *pt_regs) { hrz_dev * dev = (hrz_dev *) dev_id; u32 int_source; unsigned int irq_ok; + (void) pt_regs; PRINTD (DBG_FLOW, "interrupt_handler: %p", dev_id); + if (!dev_id) { + PRINTD (DBG_IRQ|DBG_ERR, "irq with NULL dev_id: %d", irq); + return IRQ_NONE; + } + if (irq != dev->irq) { + PRINTD (DBG_IRQ|DBG_ERR, "irq mismatch: %d", irq); + return IRQ_NONE; + } + // definitely for us irq_ok = 0; while ((int_source = rd_regl (dev, INT_SOURCE_REG_OFF) @@ -1789,7 +1800,7 @@ static inline void CLOCK_IT (const hrz_dev *dev, u32 ctrl) WRITE_IT_WAIT(dev, ctrl | SEEPROM_SK); } -static u16 __devinit read_bia (const hrz_dev * dev, u16 addr) +static u16 __init read_bia (const hrz_dev * dev, u16 addr) { u32 ctrl = rd_regl (dev, CONTROL_0_REG); @@ -2932,8 +2943,8 @@ static int __init hrz_module_init (void) { static void __exit hrz_module_exit (void) { PRINTD (DBG_FLOW, "cleanup_module"); - - pci_unregister_driver(&hrz_driver); + + return pci_unregister_driver(&hrz_driver); } module_init(hrz_module_init); diff --git a/trunk/drivers/atm/idt77252.c b/trunk/drivers/atm/idt77252.c index 87b17c33b3f9..7487f0ad68e9 100644 --- a/trunk/drivers/atm/idt77252.c +++ b/trunk/drivers/atm/idt77252.c @@ -2774,7 +2774,7 @@ idt77252_collect_stat(struct idt77252_dev *card) } static irqreturn_t -idt77252_interrupt(int irq, void *dev_id) +idt77252_interrupt(int irq, void *dev_id, struct pt_regs *ptregs) { struct idt77252_dev *card = dev_id; u32 stat; diff --git a/trunk/drivers/atm/iphase.c b/trunk/drivers/atm/iphase.c index bb7ef570514c..f20b0b2c06c6 100644 --- a/trunk/drivers/atm/iphase.c +++ b/trunk/drivers/atm/iphase.c @@ -305,7 +305,7 @@ static void clear_lockup (struct atm_vcc *vcc, IADEV *dev) { ** | R | NZ | 5-bit exponent | 9-bit mantissa | ** +----+----+------------------+-------------------------------+ ** -** R = reserved (written as 0) +** R = reserverd (written as 0) ** NZ = 0 if 0 cells/sec; 1 otherwise ** ** if NZ = 1, rate = 1.mmmmmmmmm x 2^(eeeee) cells/sec @@ -2195,7 +2195,7 @@ static int tx_init(struct atm_dev *dev) return -ENOMEM; } -static irqreturn_t ia_int(int irq, void *dev_id) +static irqreturn_t ia_int(int irq, void *dev_id, struct pt_regs *regs) { struct atm_dev *dev; IADEV *iadev; diff --git a/trunk/drivers/atm/lanai.c b/trunk/drivers/atm/lanai.c index 267825501dfe..b9568e10965a 100644 --- a/trunk/drivers/atm/lanai.c +++ b/trunk/drivers/atm/lanai.c @@ -1890,11 +1890,13 @@ static inline void lanai_int_1(struct lanai_dev *lanai, u32 reason) reg_write(lanai, ack, IntAck_Reg); } -static irqreturn_t lanai_int(int irq, void *devid) +static irqreturn_t lanai_int(int irq, void *devid, struct pt_regs *regs) { - struct lanai_dev *lanai = devid; + struct lanai_dev *lanai = (struct lanai_dev *) devid; u32 reason; + (void) irq; (void) regs; /* unused variables */ + #ifdef USE_POWERDOWN /* * If we're powered down we shouldn't be generating any interrupts - diff --git a/trunk/drivers/atm/nicstar.c b/trunk/drivers/atm/nicstar.c index bd0904594805..b8036899e56f 100644 --- a/trunk/drivers/atm/nicstar.c +++ b/trunk/drivers/atm/nicstar.c @@ -214,7 +214,7 @@ static void __devinit ns_init_card_error(ns_dev *card, int error); static scq_info *get_scq(int size, u32 scd); static void free_scq(scq_info *scq, struct atm_vcc *vcc); static void push_rxbufs(ns_dev *, struct sk_buff *); -static irqreturn_t ns_irq_handler(int irq, void *dev_id); +static irqreturn_t ns_irq_handler(int irq, void *dev_id, struct pt_regs *regs); static int ns_open(struct atm_vcc *vcc); static void ns_close(struct atm_vcc *vcc); static void fill_tst(ns_dev *card, int n, vc_map *vc); @@ -1194,7 +1194,7 @@ static void push_rxbufs(ns_dev *card, struct sk_buff *skb) -static irqreturn_t ns_irq_handler(int irq, void *dev_id) +static irqreturn_t ns_irq_handler(int irq, void *dev_id, struct pt_regs *regs) { u32 stat_r; ns_dev *card; @@ -2759,7 +2759,7 @@ static int ns_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg) { ns_dev *card; pool_levels pl; - long btype; + int btype; unsigned long flags; card = dev->dev_data; @@ -2859,7 +2859,7 @@ static int ns_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg) case NS_ADJBUFLEV: if (!capable(CAP_NET_ADMIN)) return -EPERM; - btype = (long) arg; /* a long is the same size as a pointer or bigger */ + btype = (int) arg; /* an int is the same size as a pointer */ switch (btype) { case NS_BUFTYPE_SMALL: diff --git a/trunk/drivers/atm/zatm.c b/trunk/drivers/atm/zatm.c index 7df0f373188e..083c5d3f2e18 100644 --- a/trunk/drivers/atm/zatm.c +++ b/trunk/drivers/atm/zatm.c @@ -1012,7 +1012,7 @@ static int start_tx(struct atm_dev *dev) /*------------------------------- interrupts --------------------------------*/ -static irqreturn_t zatm_int(int irq,void *dev_id) +static irqreturn_t zatm_int(int irq,void *dev_id,struct pt_regs *regs) { struct atm_dev *dev; struct zatm_dev *zatm_dev; diff --git a/trunk/drivers/base/Kconfig b/trunk/drivers/base/Kconfig index 1429f3a2629e..0b4e22436935 100644 --- a/trunk/drivers/base/Kconfig +++ b/trunk/drivers/base/Kconfig @@ -37,8 +37,8 @@ config DEBUG_DRIVER If you are unsure about this, say N here. +endmenu + config SYS_HYPERVISOR bool default n - -endmenu diff --git a/trunk/drivers/base/bus.c b/trunk/drivers/base/bus.c index 472810f8e6e7..12173d16bea7 100644 --- a/trunk/drivers/base/bus.c +++ b/trunk/drivers/base/bus.c @@ -355,21 +355,6 @@ static void device_remove_attrs(struct bus_type * bus, struct device * dev) } } -#ifdef CONFIG_SYSFS_DEPRECATED -static int make_deprecated_bus_links(struct device *dev) -{ - return sysfs_create_link(&dev->kobj, - &dev->bus->subsys.kset.kobj, "bus"); -} - -static void remove_deprecated_bus_links(struct device *dev) -{ - sysfs_remove_link(&dev->kobj, "bus"); -} -#else -static inline int make_deprecated_bus_links(struct device *dev) { return 0; } -static inline void remove_deprecated_bus_links(struct device *dev) { } -#endif /** * bus_add_device - add device to bus @@ -387,29 +372,19 @@ int bus_add_device(struct device * dev) pr_debug("bus %s: add device %s\n", bus->name, dev->bus_id); error = device_add_attrs(bus, dev); if (error) - goto out_put; + goto out; error = sysfs_create_link(&bus->devices.kobj, &dev->kobj, dev->bus_id); if (error) - goto out_id; + goto out; error = sysfs_create_link(&dev->kobj, &dev->bus->subsys.kset.kobj, "subsystem"); if (error) - goto out_subsys; - error = make_deprecated_bus_links(dev); - if (error) - goto out_deprecated; + goto out; + error = sysfs_create_link(&dev->kobj, + &dev->bus->subsys.kset.kobj, "bus"); } - return 0; - -out_deprecated: - sysfs_remove_link(&dev->kobj, "subsystem"); -out_subsys: - sysfs_remove_link(&bus->devices.kobj, dev->bus_id); -out_id: - device_remove_attrs(bus, dev); -out_put: - put_bus(dev->bus); +out: return error; } @@ -450,13 +425,11 @@ void bus_remove_device(struct device * dev) { if (dev->bus) { sysfs_remove_link(&dev->kobj, "subsystem"); - remove_deprecated_bus_links(dev); + sysfs_remove_link(&dev->kobj, "bus"); sysfs_remove_link(&dev->bus->devices.kobj, dev->bus_id); device_remove_attrs(dev->bus, dev); - if (dev->is_registered) { - dev->is_registered = 0; - klist_del(&dev->knode_bus); - } + dev->is_registered = 0; + klist_del(&dev->knode_bus); pr_debug("bus %s: remove device %s\n", dev->bus->name, dev->bus_id); device_release_driver(dev); put_bus(dev->bus); @@ -532,36 +505,34 @@ int bus_add_driver(struct device_driver *drv) struct bus_type * bus = get_bus(drv->bus); int error = 0; - if (!bus) - return 0; - - pr_debug("bus %s: add driver %s\n", bus->name, drv->name); - error = kobject_set_name(&drv->kobj, "%s", drv->name); - if (error) - goto out_put_bus; - drv->kobj.kset = &bus->drivers; - if ((error = kobject_register(&drv->kobj))) - goto out_put_bus; - - error = driver_attach(drv); - if (error) - goto out_unregister; - klist_add_tail(&drv->knode_bus, &bus->klist_drivers); - module_add_driver(drv->owner, drv); - - error = driver_add_attrs(bus, drv); - if (error) { - /* How the hell do we get out of this pickle? Give up */ - printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n", - __FUNCTION__, drv->name); - } - error = add_bind_files(drv); - if (error) { - /* Ditto */ - printk(KERN_ERR "%s: add_bind_files(%s) failed\n", - __FUNCTION__, drv->name); - } + if (bus) { + pr_debug("bus %s: add driver %s\n", bus->name, drv->name); + error = kobject_set_name(&drv->kobj, "%s", drv->name); + if (error) + goto out_put_bus; + drv->kobj.kset = &bus->drivers; + if ((error = kobject_register(&drv->kobj))) + goto out_put_bus; + error = driver_attach(drv); + if (error) + goto out_unregister; + klist_add_tail(&drv->knode_bus, &bus->klist_drivers); + module_add_driver(drv->owner, drv); + + error = driver_add_attrs(bus, drv); + if (error) { + /* How the hell do we get out of this pickle? Give up */ + printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n", + __FUNCTION__, drv->name); + } + error = add_bind_files(drv); + if (error) { + /* Ditto */ + printk(KERN_ERR "%s: add_bind_files(%s) failed\n", + __FUNCTION__, drv->name); + } + } return error; out_unregister: kobject_unregister(&drv->kobj); @@ -581,17 +552,16 @@ int bus_add_driver(struct device_driver *drv) void bus_remove_driver(struct device_driver * drv) { - if (!drv->bus) - return; - - remove_bind_files(drv); - driver_remove_attrs(drv->bus, drv); - klist_remove(&drv->knode_bus); - pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name); - driver_detach(drv); - module_remove_driver(drv); - kobject_unregister(&drv->kobj); - put_bus(drv->bus); + if (drv->bus) { + remove_bind_files(drv); + driver_remove_attrs(drv->bus, drv); + klist_remove(&drv->knode_bus); + pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name); + driver_detach(drv); + module_remove_driver(drv); + kobject_unregister(&drv->kobj); + put_bus(drv->bus); + } } @@ -738,8 +708,6 @@ int bus_register(struct bus_type * bus) { int retval; - BLOCKING_INIT_NOTIFIER_HEAD(&bus->bus_notifier); - retval = kobject_set_name(&bus->subsys.kset.kobj, "%s", bus->name); if (retval) goto out; @@ -764,15 +732,11 @@ int bus_register(struct bus_type * bus) klist_init(&bus->klist_devices, klist_devices_get, klist_devices_put); klist_init(&bus->klist_drivers, NULL, NULL); - retval = bus_add_attrs(bus); - if (retval) - goto bus_attrs_fail; + bus_add_attrs(bus); pr_debug("bus type '%s' registered\n", bus->name); return 0; -bus_attrs_fail: - kset_unregister(&bus->drivers); bus_drivers_fail: kset_unregister(&bus->devices); bus_devices_fail: @@ -798,18 +762,6 @@ void bus_unregister(struct bus_type * bus) subsystem_unregister(&bus->subsys); } -int bus_register_notifier(struct bus_type *bus, struct notifier_block *nb) -{ - return blocking_notifier_chain_register(&bus->bus_notifier, nb); -} -EXPORT_SYMBOL_GPL(bus_register_notifier); - -int bus_unregister_notifier(struct bus_type *bus, struct notifier_block *nb) -{ - return blocking_notifier_chain_unregister(&bus->bus_notifier, nb); -} -EXPORT_SYMBOL_GPL(bus_unregister_notifier); - int __init buses_init(void) { return subsystem_register(&bus_subsys); diff --git a/trunk/drivers/base/class.c b/trunk/drivers/base/class.c index f098881f45b2..b32b77ff2dcd 100644 --- a/trunk/drivers/base/class.c +++ b/trunk/drivers/base/class.c @@ -352,92 +352,6 @@ static const char *class_uevent_name(struct kset *kset, struct kobject *kobj) return class_dev->class->name; } -#ifdef CONFIG_SYSFS_DEPRECATED -char *make_class_name(const char *name, struct kobject *kobj) -{ - char *class_name; - int size; - - size = strlen(name) + strlen(kobject_name(kobj)) + 2; - - class_name = kmalloc(size, GFP_KERNEL); - if (!class_name) - return ERR_PTR(-ENOMEM); - - strcpy(class_name, name); - strcat(class_name, ":"); - strcat(class_name, kobject_name(kobj)); - return class_name; -} - -static int deprecated_class_uevent(char **envp, int num_envp, int *cur_index, - char *buffer, int buffer_size, - int *cur_len, - struct class_device *class_dev) -{ - struct device *dev = class_dev->dev; - char *path; - - if (!dev) - return 0; - - /* add device, backing this class device (deprecated) */ - path = kobject_get_path(&dev->kobj, GFP_KERNEL); - - add_uevent_var(envp, num_envp, cur_index, buffer, buffer_size, - cur_len, "PHYSDEVPATH=%s", path); - kfree(path); - - if (dev->bus) - add_uevent_var(envp, num_envp, cur_index, - buffer, buffer_size, cur_len, - "PHYSDEVBUS=%s", dev->bus->name); - - if (dev->driver) - add_uevent_var(envp, num_envp, cur_index, - buffer, buffer_size, cur_len, - "PHYSDEVDRIVER=%s", dev->driver->name); - return 0; -} - -static int make_deprecated_class_device_links(struct class_device *class_dev) -{ - char *class_name; - int error; - - if (!class_dev->dev) - return 0; - - class_name = make_class_name(class_dev->class->name, &class_dev->kobj); - error = sysfs_create_link(&class_dev->dev->kobj, &class_dev->kobj, - class_name); - kfree(class_name); - return error; -} - -static void remove_deprecated_class_device_links(struct class_device *class_dev) -{ - char *class_name; - - if (!class_dev->dev) - return; - - class_name = make_class_name(class_dev->class->name, &class_dev->kobj); - sysfs_remove_link(&class_dev->dev->kobj, class_name); - kfree(class_name); -} -#else -static inline int deprecated_class_uevent(char **envp, int num_envp, - int *cur_index, char *buffer, - int buffer_size, int *cur_len, - struct class_device *class_dev) -{ return 0; } -static inline int make_deprecated_class_device_links(struct class_device *cd) -{ return 0; } -static void remove_deprecated_class_device_links(struct class_device *cd) -{ } -#endif - static int class_uevent(struct kset *kset, struct kobject *kobj, char **envp, int num_envp, char *buffer, int buffer_size) { @@ -448,8 +362,25 @@ static int class_uevent(struct kset *kset, struct kobject *kobj, char **envp, pr_debug("%s - name = %s\n", __FUNCTION__, class_dev->class_id); - deprecated_class_uevent(envp, num_envp, &i, buffer, buffer_size, - &length, class_dev); + if (class_dev->dev) { + /* add device, backing this class device (deprecated) */ + struct device *dev = class_dev->dev; + char *path = kobject_get_path(&dev->kobj, GFP_KERNEL); + + add_uevent_var(envp, num_envp, &i, buffer, buffer_size, + &length, "PHYSDEVPATH=%s", path); + kfree(path); + + if (dev->bus) + add_uevent_var(envp, num_envp, &i, + buffer, buffer_size, &length, + "PHYSDEVBUS=%s", dev->bus->name); + + if (dev->driver) + add_uevent_var(envp, num_envp, &i, + buffer, buffer_size, &length, + "PHYSDEVDRIVER=%s", dev->driver->name); + } if (MAJOR(class_dev->devt)) { add_uevent_var(envp, num_envp, &i, @@ -575,11 +506,29 @@ void class_device_initialize(struct class_device *class_dev) INIT_LIST_HEAD(&class_dev->node); } +char *make_class_name(const char *name, struct kobject *kobj) +{ + char *class_name; + int size; + + size = strlen(name) + strlen(kobject_name(kobj)) + 2; + + class_name = kmalloc(size, GFP_KERNEL); + if (!class_name) + return ERR_PTR(-ENOMEM); + + strcpy(class_name, name); + strcat(class_name, ":"); + strcat(class_name, kobject_name(kobj)); + return class_name; +} + int class_device_add(struct class_device *class_dev) { struct class *parent_class = NULL; struct class_device *parent_class_dev = NULL; struct class_interface *class_intf; + char *class_name = NULL; int error = -EINVAL; class_dev = class_device_get(class_dev); @@ -613,10 +562,7 @@ int class_device_add(struct class_device *class_dev) goto out2; /* add the needed attributes to this device */ - error = sysfs_create_link(&class_dev->kobj, - &parent_class->subsys.kset.kobj, "subsystem"); - if (error) - goto out3; + sysfs_create_link(&class_dev->kobj, &parent_class->subsys.kset.kobj, "subsystem"); class_dev->uevent_attr.attr.name = "uevent"; class_dev->uevent_attr.attr.mode = S_IWUSR; class_dev->uevent_attr.attr.owner = parent_class->owner; @@ -650,17 +596,19 @@ int class_device_add(struct class_device *class_dev) goto out5; if (class_dev->dev) { + class_name = make_class_name(class_dev->class->name, + &class_dev->kobj); error = sysfs_create_link(&class_dev->kobj, &class_dev->dev->kobj, "device"); if (error) goto out6; + error = sysfs_create_link(&class_dev->dev->kobj, &class_dev->kobj, + class_name); + if (error) + goto out7; } error = class_device_add_groups(class_dev); - if (error) - goto out7; - - error = make_deprecated_class_device_links(class_dev); if (error) goto out8; @@ -678,7 +626,8 @@ int class_device_add(struct class_device *class_dev) goto out1; out8: - class_device_remove_groups(class_dev); + if (class_dev->dev) + sysfs_remove_link(&class_dev->kobj, class_name); out7: if (class_dev->dev) sysfs_remove_link(&class_dev->kobj, "device"); @@ -697,6 +646,7 @@ int class_device_add(struct class_device *class_dev) class_put(parent_class); out1: class_device_put(class_dev); + kfree(class_name); return error; } @@ -773,6 +723,7 @@ void class_device_del(struct class_device *class_dev) struct class *parent_class = class_dev->class; struct class_device *parent_device = class_dev->parent; struct class_interface *class_intf; + char *class_name = NULL; if (parent_class) { down(&parent_class->sem); @@ -784,8 +735,10 @@ void class_device_del(struct class_device *class_dev) } if (class_dev->dev) { - remove_deprecated_class_device_links(class_dev); + class_name = make_class_name(class_dev->class->name, + &class_dev->kobj); sysfs_remove_link(&class_dev->kobj, "device"); + sysfs_remove_link(&class_dev->dev->kobj, class_name); } sysfs_remove_link(&class_dev->kobj, "subsystem"); class_device_remove_file(class_dev, &class_dev->uevent_attr); @@ -799,6 +752,7 @@ void class_device_del(struct class_device *class_dev) class_device_put(parent_device); class_put(parent_class); + kfree(class_name); } void class_device_unregister(struct class_device *class_dev) @@ -847,17 +801,14 @@ int class_device_rename(struct class_device *class_dev, char *new_name) pr_debug("CLASS: renaming '%s' to '%s'\n", class_dev->class_id, new_name); -#ifdef CONFIG_SYSFS_DEPRECATED if (class_dev->dev) old_class_name = make_class_name(class_dev->class->name, &class_dev->kobj); -#endif strlcpy(class_dev->class_id, new_name, KOBJ_NAME_LEN); error = kobject_rename(&class_dev->kobj, new_name); -#ifdef CONFIG_SYSFS_DEPRECATED if (class_dev->dev) { new_class_name = make_class_name(class_dev->class->name, &class_dev->kobj); @@ -865,7 +816,6 @@ int class_device_rename(struct class_device *class_dev, char *new_name) new_class_name); sysfs_remove_link(&class_dev->dev->kobj, old_class_name); } -#endif class_device_put(class_dev); kfree(old_class_name); @@ -940,6 +890,23 @@ void class_interface_unregister(struct class_interface *class_intf) class_put(parent); } +int virtual_device_parent(struct device *dev) +{ + if (!dev->class) + return -ENODEV; + + if (!dev->class->virtual_dir) { + static struct kobject *virtual_dir = NULL; + + if (!virtual_dir) + virtual_dir = kobject_add_dir(&devices_subsys.kset.kobj, "virtual"); + dev->class->virtual_dir = kobject_add_dir(virtual_dir, dev->class->name); + } + + dev->kobj.parent = dev->class->virtual_dir; + return 0; +} + int __init classes_init(void) { int retval; diff --git a/trunk/drivers/base/core.c b/trunk/drivers/base/core.c index e4b530ef757d..b224bb43ff63 100644 --- a/trunk/drivers/base/core.c +++ b/trunk/drivers/base/core.c @@ -17,7 +17,6 @@ #include #include #include -#include #include @@ -45,7 +44,7 @@ const char *dev_driver_string(struct device *dev) return dev->driver ? dev->driver->name : (dev->bus ? dev->bus->name : ""); } -EXPORT_SYMBOL(dev_driver_string); +EXPORT_SYMBOL_GPL(dev_driver_string); #define to_dev(obj) container_of(obj, struct device, kobj) #define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr) @@ -154,24 +153,20 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp, "MINOR=%u", MINOR(dev->devt)); } -#ifdef CONFIG_SYSFS_DEPRECATED /* add bus name (same as SUBSYSTEM, deprecated) */ if (dev->bus) add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length, "PHYSDEVBUS=%s", dev->bus->name); -#endif /* add driver name (PHYSDEV* values are deprecated)*/ if (dev->driver) { add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length, "DRIVER=%s", dev->driver->name); -#ifdef CONFIG_SYSFS_DEPRECATED add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length, "PHYSDEVDRIVER=%s", dev->driver->name); -#endif } /* terminate, set to next free slot, shrink available space */ @@ -388,52 +383,6 @@ void device_initialize(struct device *dev) device_init_wakeup(dev, 0); } -#ifdef CONFIG_SYSFS_DEPRECATED -static int setup_parent(struct device *dev, struct device *parent) -{ - /* Set the parent to the class, not the parent device */ - /* this keeps sysfs from having a symlink to make old udevs happy */ - if (dev->class) - dev->kobj.parent = &dev->class->subsys.kset.kobj; - else if (parent) - dev->kobj.parent = &parent->kobj; - - return 0; -} -#else -static int virtual_device_parent(struct device *dev) -{ - if (!dev->class) - return -ENODEV; - - if (!dev->class->virtual_dir) { - static struct kobject *virtual_dir = NULL; - - if (!virtual_dir) - virtual_dir = kobject_add_dir(&devices_subsys.kset.kobj, "virtual"); - dev->class->virtual_dir = kobject_add_dir(virtual_dir, dev->class->name); - } - - dev->kobj.parent = dev->class->virtual_dir; - return 0; -} - -static int setup_parent(struct device *dev, struct device *parent) -{ - int error; - - /* if this is a class device, and has no parent, create one */ - if ((dev->class) && (parent == NULL)) { - error = virtual_device_parent(dev); - if (error) - return error; - } else if (parent) - dev->kobj.parent = &parent->kobj; - - return 0; -} -#endif - /** * device_add - add device to device hierarchy. * @dev: device. @@ -456,44 +405,42 @@ int device_add(struct device *dev) if (!dev || !strlen(dev->bus_id)) goto Error; - pr_debug("DEV: registering device: ID = '%s'\n", dev->bus_id); + /* if this is a class device, and has no parent, create one */ + if ((dev->class) && (dev->parent == NULL)) { + error = virtual_device_parent(dev); + if (error) + goto Error; + } parent = get_device(dev->parent); - error = setup_parent(dev, parent); - if (error) - goto Error; + pr_debug("DEV: registering device: ID = '%s'\n", dev->bus_id); /* first, register with generic layer. */ kobject_set_name(&dev->kobj, "%s", dev->bus_id); - error = kobject_add(&dev->kobj); - if (error) + if (parent) + dev->kobj.parent = &parent->kobj; + + if ((error = kobject_add(&dev->kobj))) goto Error; /* notify platform of device entry */ if (platform_notify) platform_notify(dev); - /* notify clients of device entry (new way) */ - if (dev->bus) - blocking_notifier_call_chain(&dev->bus->bus_notifier, - BUS_NOTIFY_ADD_DEVICE, dev); - dev->uevent_attr.attr.name = "uevent"; dev->uevent_attr.attr.mode = S_IWUSR; if (dev->driver) dev->uevent_attr.attr.owner = dev->driver->owner; dev->uevent_attr.store = store_uevent; - error = device_create_file(dev, &dev->uevent_attr); - if (error) - goto attrError; + device_create_file(dev, &dev->uevent_attr); if (MAJOR(dev->devt)) { struct device_attribute *attr; attr = kzalloc(sizeof(*attr), GFP_KERNEL); if (!attr) { error = -ENOMEM; - goto ueventattrError; + goto PMError; } attr->attr.name = "dev"; attr->attr.mode = S_IRUGO; @@ -503,7 +450,7 @@ int device_add(struct device *dev) error = device_create_file(dev, attr); if (error) { kfree(attr); - goto ueventattrError; + goto attrError; } dev->devt_attr = attr; @@ -512,18 +459,13 @@ int device_add(struct device *dev) if (dev->class) { sysfs_create_link(&dev->kobj, &dev->class->subsys.kset.kobj, "subsystem"); - /* If this is not a "fake" compatible device, then create the - * symlink from the class to the device. */ - if (dev->kobj.parent != &dev->class->subsys.kset.kobj) - sysfs_create_link(&dev->class->subsys.kset.kobj, - &dev->kobj, dev->bus_id); -#ifdef CONFIG_SYSFS_DEPRECATED + sysfs_create_link(&dev->class->subsys.kset.kobj, &dev->kobj, + dev->bus_id); if (parent) { sysfs_create_link(&dev->kobj, &dev->parent->kobj, "device"); class_name = make_class_name(dev->class->name, &dev->kobj); sysfs_create_link(&dev->parent->kobj, &dev->kobj, class_name); } -#endif } if ((error = device_add_attrs(dev))) @@ -535,8 +477,7 @@ int device_add(struct device *dev) if ((error = bus_add_device(dev))) goto BusError; kobject_uevent(&dev->kobj, KOBJ_ADD); - if ((error = bus_attach_device(dev))) - goto AttachError; + bus_attach_device(dev); if (parent) klist_add_tail(&dev->knode_parent, &parent->klist_children); @@ -555,14 +496,9 @@ int device_add(struct device *dev) kfree(class_name); put_device(dev); return error; - AttachError: - bus_remove_device(dev); BusError: device_pm_remove(dev); PMError: - if (dev->bus) - blocking_notifier_call_chain(&dev->bus->bus_notifier, - BUS_NOTIFY_DEL_DEVICE, dev); device_remove_groups(dev); GroupError: device_remove_attrs(dev); @@ -571,8 +507,6 @@ int device_add(struct device *dev) device_remove_file(dev, dev->devt_attr); kfree(dev->devt_attr); } - ueventattrError: - device_remove_file(dev, &dev->uevent_attr); attrError: kobject_uevent(&dev->kobj, KOBJ_REMOVE); kobject_del(&dev->kobj); @@ -645,31 +579,22 @@ void put_device(struct device * dev) void device_del(struct device * dev) { struct device * parent = dev->parent; + char *class_name = NULL; struct class_interface *class_intf; if (parent) klist_del(&dev->knode_parent); - if (dev->devt_attr) { + if (dev->devt_attr) device_remove_file(dev, dev->devt_attr); - kfree(dev->devt_attr); - } if (dev->class) { sysfs_remove_link(&dev->kobj, "subsystem"); - /* If this is not a "fake" compatible device, remove the - * symlink from the class to the device. */ - if (dev->kobj.parent != &dev->class->subsys.kset.kobj) - sysfs_remove_link(&dev->class->subsys.kset.kobj, - dev->bus_id); -#ifdef CONFIG_SYSFS_DEPRECATED + sysfs_remove_link(&dev->class->subsys.kset.kobj, dev->bus_id); + class_name = make_class_name(dev->class->name, &dev->kobj); if (parent) { - char *class_name = make_class_name(dev->class->name, - &dev->kobj); - sysfs_remove_link(&dev->parent->kobj, class_name); - kfree(class_name); sysfs_remove_link(&dev->kobj, "device"); + sysfs_remove_link(&dev->parent->kobj, class_name); } -#endif - + kfree(class_name); down(&dev->class->sem); /* notify any interfaces that the device is now gone */ list_for_each_entry(class_intf, &dev->class->interfaces, node) @@ -682,16 +607,13 @@ void device_del(struct device * dev) device_remove_file(dev, &dev->uevent_attr); device_remove_groups(dev); device_remove_attrs(dev); - bus_remove_device(dev); /* Notify the platform of the removal, in case they * need to do anything... */ if (platform_notify_remove) platform_notify_remove(dev); - if (dev->bus) - blocking_notifier_call_chain(&dev->bus->bus_notifier, - BUS_NOTIFY_DEL_DEVICE, dev); + bus_remove_device(dev); device_pm_remove(dev); kobject_uevent(&dev->kobj, KOBJ_REMOVE); kobject_del(&dev->kobj); @@ -750,45 +672,12 @@ int device_for_each_child(struct device * parent, void * data, return error; } -/** - * device_find_child - device iterator for locating a particular device. - * @parent: parent struct device - * @data: Data to pass to match function - * @match: Callback function to check device - * - * This is similar to the device_for_each_child() function above, but it - * returns a reference to a device that is 'found' for later use, as - * determined by the @match callback. - * - * The callback should return 0 if the device doesn't match and non-zero - * if it does. If the callback returns non-zero and a reference to the - * current device can be obtained, this function will return to the caller - * and not iterate over any more devices. - */ -struct device * device_find_child(struct device *parent, void *data, - int (*match)(struct device *, void *)) -{ - struct klist_iter i; - struct device *child; - - if (!parent) - return NULL; - - klist_iter_init(&parent->klist_children, &i); - while ((child = next_device(&i))) - if (match(child, data) && get_device(child)) - break; - klist_iter_exit(&i); - return child; -} - int __init devices_init(void) { return subsystem_register(&devices_subsys); } EXPORT_SYMBOL_GPL(device_for_each_child); -EXPORT_SYMBOL_GPL(device_find_child); EXPORT_SYMBOL_GPL(device_initialize); EXPORT_SYMBOL_GPL(device_add); @@ -911,17 +800,13 @@ int device_rename(struct device *dev, char *new_name) pr_debug("DEVICE: renaming '%s' to '%s'\n", dev->bus_id, new_name); -#ifdef CONFIG_SYSFS_DEPRECATED if ((dev->class) && (dev->parent)) old_class_name = make_class_name(dev->class->name, &dev->kobj); -#endif if (dev->class) { old_symlink_name = kmalloc(BUS_ID_SIZE, GFP_KERNEL); - if (!old_symlink_name) { - error = -ENOMEM; - goto out_free_old_class; - } + if (!old_symlink_name) + return -ENOMEM; strlcpy(old_symlink_name, dev->bus_id, BUS_ID_SIZE); } @@ -929,7 +814,6 @@ int device_rename(struct device *dev, char *new_name) error = kobject_rename(&dev->kobj, new_name); -#ifdef CONFIG_SYSFS_DEPRECATED if (old_class_name) { new_class_name = make_class_name(dev->class->name, &dev->kobj); if (new_class_name) { @@ -938,8 +822,6 @@ int device_rename(struct device *dev, char *new_name) sysfs_remove_link(&dev->parent->kobj, old_class_name); } } -#endif - if (dev->class) { sysfs_remove_link(&dev->class->subsys.kset.kobj, old_symlink_name); @@ -948,102 +830,9 @@ int device_rename(struct device *dev, char *new_name) } put_device(dev); + kfree(old_class_name); kfree(new_class_name); kfree(old_symlink_name); - out_free_old_class: - kfree(old_class_name); return error; } - - -static int device_move_class_links(struct device *dev, - struct device *old_parent, - struct device *new_parent) -{ -#ifdef CONFIG_SYSFS_DEPRECATED - int error; - char *class_name; - - class_name = make_class_name(dev->class->name, &dev->kobj); - if (!class_name) { - error = PTR_ERR(class_name); - class_name = NULL; - goto out; - } - if (old_parent) { - sysfs_remove_link(&dev->kobj, "device"); - sysfs_remove_link(&old_parent->kobj, class_name); - } - error = sysfs_create_link(&dev->kobj, &new_parent->kobj, "device"); - if (error) - goto out; - error = sysfs_create_link(&new_parent->kobj, &dev->kobj, class_name); - if (error) - sysfs_remove_link(&dev->kobj, "device"); -out: - kfree(class_name); - return error; -#else - return 0; -#endif -} - -/** - * device_move - moves a device to a new parent - * @dev: the pointer to the struct device to be moved - * @new_parent: the new parent of the device - */ -int device_move(struct device *dev, struct device *new_parent) -{ - int error; - struct device *old_parent; - - dev = get_device(dev); - if (!dev) - return -EINVAL; - - if (!device_is_registered(dev)) { - error = -EINVAL; - goto out; - } - new_parent = get_device(new_parent); - if (!new_parent) { - error = -EINVAL; - goto out; - } - pr_debug("DEVICE: moving '%s' to '%s'\n", dev->bus_id, - new_parent->bus_id); - error = kobject_move(&dev->kobj, &new_parent->kobj); - if (error) { - put_device(new_parent); - goto out; - } - old_parent = dev->parent; - dev->parent = new_parent; - if (old_parent) - klist_remove(&dev->knode_parent); - klist_add_tail(&dev->knode_parent, &new_parent->klist_children); - if (!dev->class) - goto out_put; - error = device_move_class_links(dev, old_parent, new_parent); - if (error) { - /* We ignore errors on cleanup since we're hosed anyway... */ - device_move_class_links(dev, new_parent, old_parent); - if (!kobject_move(&dev->kobj, &old_parent->kobj)) { - klist_remove(&dev->knode_parent); - if (old_parent) - klist_add_tail(&dev->knode_parent, - &old_parent->klist_children); - } - put_device(new_parent); - goto out; - } -out_put: - put_device(old_parent); -out: - put_device(dev); - return error; -} - -EXPORT_SYMBOL_GPL(device_move); diff --git a/trunk/drivers/base/dd.c b/trunk/drivers/base/dd.c index 510e7884975f..b5f43c3e44fa 100644 --- a/trunk/drivers/base/dd.c +++ b/trunk/drivers/base/dd.c @@ -18,7 +18,6 @@ #include #include #include -#include #include "base.h" #include "power/power.h" @@ -26,28 +25,33 @@ #define to_drv(node) container_of(node, struct device_driver, kobj.entry) -static void driver_bound(struct device *dev) +/** + * device_bind_driver - bind a driver to one device. + * @dev: device. + * + * Allow manual attachment of a driver to a device. + * Caller must have already set @dev->driver. + * + * Note that this does not modify the bus reference count + * nor take the bus's rwsem. Please verify those are accounted + * for before calling this. (It is ok to call with no other effort + * from a driver's probe() method.) + * + * This function must be called with @dev->sem held. + */ +int device_bind_driver(struct device *dev) { + int ret; + if (klist_node_attached(&dev->knode_driver)) { printk(KERN_WARNING "%s: device %s already bound\n", __FUNCTION__, kobject_name(&dev->kobj)); - return; + return 0; } pr_debug("bound device '%s' to driver '%s'\n", dev->bus_id, dev->driver->name); - - if (dev->bus) - blocking_notifier_call_chain(&dev->bus->bus_notifier, - BUS_NOTIFY_BOUND_DRIVER, dev); - klist_add_tail(&dev->knode_driver, &dev->driver->klist_devices); -} - -static int driver_sysfs_add(struct device *dev) -{ - int ret; - ret = sysfs_create_link(&dev->driver->kobj, &dev->kobj, kobject_name(&dev->kobj)); if (ret == 0) { @@ -60,44 +64,12 @@ static int driver_sysfs_add(struct device *dev) return ret; } -static void driver_sysfs_remove(struct device *dev) -{ - struct device_driver *drv = dev->driver; - - if (drv) { - sysfs_remove_link(&drv->kobj, kobject_name(&dev->kobj)); - sysfs_remove_link(&dev->kobj, "driver"); - } -} - -/** - * device_bind_driver - bind a driver to one device. - * @dev: device. - * - * Allow manual attachment of a driver to a device. - * Caller must have already set @dev->driver. - * - * Note that this does not modify the bus reference count - * nor take the bus's rwsem. Please verify those are accounted - * for before calling this. (It is ok to call with no other effort - * from a driver's probe() method.) - * - * This function must be called with @dev->sem held. - */ -int device_bind_driver(struct device *dev) -{ - driver_bound(dev); - return driver_sysfs_add(dev); -} - struct stupid_thread_structure { struct device_driver *drv; struct device *dev; }; static atomic_t probe_count = ATOMIC_INIT(0); -static DECLARE_WAIT_QUEUE_HEAD(probe_waitqueue); - static int really_probe(void *void_data) { struct stupid_thread_structure *data = void_data; @@ -110,32 +82,30 @@ static int really_probe(void *void_data) drv->bus->name, drv->name, dev->bus_id); dev->driver = drv; - if (driver_sysfs_add(dev)) { - printk(KERN_ERR "%s: driver_sysfs_add(%s) failed\n", - __FUNCTION__, dev->bus_id); - goto probe_failed; - } - if (dev->bus->probe) { ret = dev->bus->probe(dev); - if (ret) + if (ret) { + dev->driver = NULL; goto probe_failed; + } } else if (drv->probe) { ret = drv->probe(dev); - if (ret) + if (ret) { + dev->driver = NULL; goto probe_failed; + } + } + if (device_bind_driver(dev)) { + printk(KERN_ERR "%s: device_bind_driver(%s) failed\n", + __FUNCTION__, dev->bus_id); + /* How does undo a ->probe? We're screwed. */ } - - driver_bound(dev); ret = 1; pr_debug("%s: Bound Device %s to Driver %s\n", drv->bus->name, dev->bus_id, drv->name); goto done; probe_failed: - driver_sysfs_remove(dev); - dev->driver = NULL; - if (ret == -ENODEV || ret == -ENXIO) { /* Driver matched, but didn't support device * or device not found. @@ -151,7 +121,6 @@ static int really_probe(void *void_data) done: kfree(data); atomic_dec(&probe_count); - wake_up(&probe_waitqueue); return ret; } @@ -202,8 +171,6 @@ int driver_probe_device(struct device_driver * drv, struct device * dev) drv->bus->name, dev->bus_id, drv->name); data = kmalloc(sizeof(*data), GFP_KERNEL); - if (!data) - return -ENOMEM; data->drv = drv; data->dev = dev; @@ -211,7 +178,7 @@ int driver_probe_device(struct device_driver * drv, struct device * dev) probe_task = kthread_run(really_probe, data, "probe-%s", dev->bus_id); if (IS_ERR(probe_task)) - ret = really_probe(data); + ret = PTR_ERR(probe_task); } else ret = really_probe(data); @@ -311,15 +278,10 @@ static void __device_release_driver(struct device * dev) drv = dev->driver; if (drv) { get_driver(drv); - driver_sysfs_remove(dev); + sysfs_remove_link(&drv->kobj, kobject_name(&dev->kobj)); sysfs_remove_link(&dev->kobj, "driver"); klist_remove(&dev->knode_driver); - if (dev->bus) - blocking_notifier_call_chain(&dev->bus->bus_notifier, - BUS_NOTIFY_UNBIND_DRIVER, - dev); - if (dev->bus && dev->bus->remove) dev->bus->remove(dev); else if (drv->remove) @@ -373,32 +335,6 @@ void driver_detach(struct device_driver * drv) } } -#ifdef CONFIG_PCI_MULTITHREAD_PROBE -static int __init wait_for_probes(void) -{ - DEFINE_WAIT(wait); - - printk(KERN_INFO "%s: waiting for %d threads\n", __FUNCTION__, - atomic_read(&probe_count)); - if (!atomic_read(&probe_count)) - return 0; - while (atomic_read(&probe_count)) { - prepare_to_wait(&probe_waitqueue, &wait, TASK_UNINTERRUPTIBLE); - if (atomic_read(&probe_count)) - schedule(); - } - finish_wait(&probe_waitqueue, &wait); - return 0; -} - -core_initcall_sync(wait_for_probes); -postcore_initcall_sync(wait_for_probes); -arch_initcall_sync(wait_for_probes); -subsys_initcall_sync(wait_for_probes); -fs_initcall_sync(wait_for_probes); -device_initcall_sync(wait_for_probes); -late_initcall_sync(wait_for_probes); -#endif EXPORT_SYMBOL_GPL(device_bind_driver); EXPORT_SYMBOL_GPL(device_release_driver); diff --git a/trunk/drivers/base/dmapool.c b/trunk/drivers/base/dmapool.c index b2efbd4cf710..33c5cce1560b 100644 --- a/trunk/drivers/base/dmapool.c +++ b/trunk/drivers/base/dmapool.c @@ -141,20 +141,11 @@ dma_pool_create (const char *name, struct device *dev, init_waitqueue_head (&retval->waitq); if (dev) { - int ret; - down (&pools_lock); if (list_empty (&dev->dma_pools)) - ret = device_create_file (dev, &dev_attr_pools); - else - ret = 0; + device_create_file (dev, &dev_attr_pools); /* note: not currently insisting "name" be unique */ - if (!ret) - list_add (&retval->pools, &dev->dma_pools); - else { - kfree(retval); - retval = NULL; - } + list_add (&retval->pools, &dev->dma_pools); up (&pools_lock); } else INIT_LIST_HEAD (&retval->pools); diff --git a/trunk/drivers/base/firmware_class.c b/trunk/drivers/base/firmware_class.c index 4bad2870c485..14615694ae9a 100644 --- a/trunk/drivers/base/firmware_class.c +++ b/trunk/drivers/base/firmware_class.c @@ -21,8 +21,6 @@ #include #include "base.h" -#define to_dev(obj) container_of(obj, struct device, kobj) - MODULE_AUTHOR("Manuel Estrada Sainz "); MODULE_DESCRIPTION("Multi purpose firmware loading support"); MODULE_LICENSE("GPL"); @@ -88,12 +86,12 @@ firmware_timeout_store(struct class *class, const char *buf, size_t count) static CLASS_ATTR(timeout, 0644, firmware_timeout_show, firmware_timeout_store); -static void fw_dev_release(struct device *dev); +static void fw_class_dev_release(struct class_device *class_dev); -static int firmware_uevent(struct device *dev, char **envp, int num_envp, - char *buffer, int buffer_size) +static int firmware_class_uevent(struct class_device *class_dev, char **envp, + int num_envp, char *buffer, int buffer_size) { - struct firmware_priv *fw_priv = dev_get_drvdata(dev); + struct firmware_priv *fw_priv = class_get_devdata(class_dev); int i = 0, len = 0; if (!test_bit(FW_STATUS_READY, &fw_priv->status)) @@ -112,21 +110,21 @@ static int firmware_uevent(struct device *dev, char **envp, int num_envp, static struct class firmware_class = { .name = "firmware", - .dev_uevent = firmware_uevent, - .dev_release = fw_dev_release, + .uevent = firmware_class_uevent, + .release = fw_class_dev_release, }; -static ssize_t firmware_loading_show(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t +firmware_loading_show(struct class_device *class_dev, char *buf) { - struct firmware_priv *fw_priv = dev_get_drvdata(dev); + struct firmware_priv *fw_priv = class_get_devdata(class_dev); int loading = test_bit(FW_STATUS_LOADING, &fw_priv->status); return sprintf(buf, "%d\n", loading); } /** * firmware_loading_store - set value in the 'loading' control file - * @dev: device pointer + * @class_dev: class_device pointer * @buf: buffer to scan for loading control value * @count: number of bytes in @buf * @@ -136,11 +134,11 @@ static ssize_t firmware_loading_show(struct device *dev, * 0: Conclude the load and hand the data to the driver code. * -1: Conclude the load with an error and discard any written data. **/ -static ssize_t firmware_loading_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t +firmware_loading_store(struct class_device *class_dev, + const char *buf, size_t count) { - struct firmware_priv *fw_priv = dev_get_drvdata(dev); + struct firmware_priv *fw_priv = class_get_devdata(class_dev); int loading = simple_strtol(buf, NULL, 10); switch (loading) { @@ -176,14 +174,15 @@ static ssize_t firmware_loading_store(struct device *dev, return count; } -static DEVICE_ATTR(loading, 0644, firmware_loading_show, firmware_loading_store); +static CLASS_DEVICE_ATTR(loading, 0644, + firmware_loading_show, firmware_loading_store); static ssize_t firmware_data_read(struct kobject *kobj, char *buffer, loff_t offset, size_t count) { - struct device *dev = to_dev(kobj); - struct firmware_priv *fw_priv = dev_get_drvdata(dev); + struct class_device *class_dev = to_class_dev(kobj); + struct firmware_priv *fw_priv = class_get_devdata(class_dev); struct firmware *fw; ssize_t ret_count = count; @@ -235,7 +234,7 @@ fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size) /** * firmware_data_write - write method for firmware - * @kobj: kobject for the device + * @kobj: kobject for the class_device * @buffer: buffer being written * @offset: buffer offset for write in total data store area * @count: buffer size @@ -247,8 +246,8 @@ static ssize_t firmware_data_write(struct kobject *kobj, char *buffer, loff_t offset, size_t count) { - struct device *dev = to_dev(kobj); - struct firmware_priv *fw_priv = dev_get_drvdata(dev); + struct class_device *class_dev = to_class_dev(kobj); + struct firmware_priv *fw_priv = class_get_devdata(class_dev); struct firmware *fw; ssize_t retval; @@ -281,12 +280,13 @@ static struct bin_attribute firmware_attr_data_tmpl = { .write = firmware_data_write, }; -static void fw_dev_release(struct device *dev) +static void +fw_class_dev_release(struct class_device *class_dev) { - struct firmware_priv *fw_priv = dev_get_drvdata(dev); + struct firmware_priv *fw_priv = class_get_devdata(class_dev); kfree(fw_priv); - kfree(dev); + kfree(class_dev); module_put(THIS_MODULE); } @@ -298,23 +298,26 @@ firmware_class_timeout(u_long data) fw_load_abort(fw_priv); } -static inline void fw_setup_device_id(struct device *f_dev, struct device *dev) +static inline void +fw_setup_class_device_id(struct class_device *class_dev, struct device *dev) { /* XXX warning we should watch out for name collisions */ - strlcpy(f_dev->bus_id, dev->bus_id, BUS_ID_SIZE); + strlcpy(class_dev->class_id, dev->bus_id, BUS_ID_SIZE); } -static int fw_register_device(struct device **dev_p, const char *fw_name, - struct device *device) +static int +fw_register_class_device(struct class_device **class_dev_p, + const char *fw_name, struct device *device) { int retval; struct firmware_priv *fw_priv = kzalloc(sizeof(*fw_priv), GFP_KERNEL); - struct device *f_dev = kzalloc(sizeof(*f_dev), GFP_KERNEL); + struct class_device *class_dev = kzalloc(sizeof(*class_dev), + GFP_KERNEL); - *dev_p = NULL; + *class_dev_p = NULL; - if (!fw_priv || !f_dev) { + if (!fw_priv || !class_dev) { printk(KERN_ERR "%s: kmalloc failed\n", __FUNCTION__); retval = -ENOMEM; goto error_kfree; @@ -328,54 +331,55 @@ static int fw_register_device(struct device **dev_p, const char *fw_name, fw_priv->timeout.data = (u_long) fw_priv; init_timer(&fw_priv->timeout); - fw_setup_device_id(f_dev, device); - f_dev->parent = device; - f_dev->class = &firmware_class; - dev_set_drvdata(f_dev, fw_priv); - retval = device_register(f_dev); + fw_setup_class_device_id(class_dev, device); + class_dev->dev = device; + class_dev->class = &firmware_class; + class_set_devdata(class_dev, fw_priv); + retval = class_device_register(class_dev); if (retval) { - printk(KERN_ERR "%s: device_register failed\n", + printk(KERN_ERR "%s: class_device_register failed\n", __FUNCTION__); goto error_kfree; } - *dev_p = f_dev; + *class_dev_p = class_dev; return 0; error_kfree: kfree(fw_priv); - kfree(f_dev); + kfree(class_dev); return retval; } -static int fw_setup_device(struct firmware *fw, struct device **dev_p, - const char *fw_name, struct device *device, - int uevent) +static int +fw_setup_class_device(struct firmware *fw, struct class_device **class_dev_p, + const char *fw_name, struct device *device, int uevent) { - struct device *f_dev; + struct class_device *class_dev; struct firmware_priv *fw_priv; int retval; - *dev_p = NULL; - retval = fw_register_device(&f_dev, fw_name, device); + *class_dev_p = NULL; + retval = fw_register_class_device(&class_dev, fw_name, device); if (retval) goto out; /* Need to pin this module until class device is destroyed */ __module_get(THIS_MODULE); - fw_priv = dev_get_drvdata(f_dev); + fw_priv = class_get_devdata(class_dev); fw_priv->fw = fw; - retval = sysfs_create_bin_file(&f_dev->kobj, &fw_priv->attr_data); + retval = sysfs_create_bin_file(&class_dev->kobj, &fw_priv->attr_data); if (retval) { printk(KERN_ERR "%s: sysfs_create_bin_file failed\n", __FUNCTION__); goto error_unreg; } - retval = device_create_file(f_dev, &dev_attr_loading); + retval = class_device_create_file(class_dev, + &class_device_attr_loading); if (retval) { - printk(KERN_ERR "%s: device_create_file failed\n", + printk(KERN_ERR "%s: class_device_create_file failed\n", __FUNCTION__); goto error_unreg; } @@ -384,11 +388,11 @@ static int fw_setup_device(struct firmware *fw, struct device **dev_p, set_bit(FW_STATUS_READY, &fw_priv->status); else set_bit(FW_STATUS_READY_NOHOTPLUG, &fw_priv->status); - *dev_p = f_dev; + *class_dev_p = class_dev; goto out; error_unreg: - device_unregister(f_dev); + class_device_unregister(class_dev); out: return retval; } @@ -397,7 +401,7 @@ static int _request_firmware(const struct firmware **firmware_p, const char *name, struct device *device, int uevent) { - struct device *f_dev; + struct class_device *class_dev; struct firmware_priv *fw_priv; struct firmware *firmware; int retval; @@ -413,11 +417,12 @@ _request_firmware(const struct firmware **firmware_p, const char *name, goto out; } - retval = fw_setup_device(firmware, &f_dev, name, device, uevent); + retval = fw_setup_class_device(firmware, &class_dev, name, device, + uevent); if (retval) goto error_kfree_fw; - fw_priv = dev_get_drvdata(f_dev); + fw_priv = class_get_devdata(class_dev); if (uevent) { if (loading_timeout > 0) { @@ -425,7 +430,7 @@ _request_firmware(const struct firmware **firmware_p, const char *name, add_timer(&fw_priv->timeout); } - kobject_uevent(&f_dev->kobj, KOBJ_ADD); + kobject_uevent(&class_dev->kobj, KOBJ_ADD); wait_for_completion(&fw_priv->completion); set_bit(FW_STATUS_DONE, &fw_priv->status); del_timer_sync(&fw_priv->timeout); @@ -440,7 +445,7 @@ _request_firmware(const struct firmware **firmware_p, const char *name, } fw_priv->fw = NULL; mutex_unlock(&fw_lock); - device_unregister(f_dev); + class_device_unregister(class_dev); goto out; error_kfree_fw: diff --git a/trunk/drivers/base/platform.c b/trunk/drivers/base/platform.c index d1df4a087924..940ce41f1887 100644 --- a/trunk/drivers/base/platform.c +++ b/trunk/drivers/base/platform.c @@ -388,11 +388,6 @@ static int platform_drv_probe(struct device *_dev) return drv->probe(dev); } -static int platform_drv_probe_fail(struct device *_dev) -{ - return -ENXIO; -} - static int platform_drv_remove(struct device *_dev) { struct platform_driver *drv = to_platform_driver(_dev->driver); @@ -456,49 +451,6 @@ void platform_driver_unregister(struct platform_driver *drv) } EXPORT_SYMBOL_GPL(platform_driver_unregister); -/** - * platform_driver_probe - register driver for non-hotpluggable device - * @drv: platform driver structure - * @probe: the driver probe routine, probably from an __init section - * - * Use this instead of platform_driver_register() when you know the device - * is not hotpluggable and has already been registered, and you want to - * remove its run-once probe() infrastructure from memory after the driver - * has bound to the device. - * - * One typical use for this would be with drivers for controllers integrated - * into system-on-chip processors, where the controller devices have been - * configured as part of board setup. - * - * Returns zero if the driver registered and bound to a device, else returns - * a negative error code and with the driver not registered. - */ -int platform_driver_probe(struct platform_driver *drv, - int (*probe)(struct platform_device *)) -{ - int retval, code; - - /* temporary section violation during probe() */ - drv->probe = probe; - retval = code = platform_driver_register(drv); - - /* Fixup that section violation, being paranoid about code scanning - * the list of drivers in order to probe new devices. Check to see - * if the probe was successful, and make sure any forced probes of - * new devices fail. - */ - spin_lock(&platform_bus_type.klist_drivers.k_lock); - drv->probe = NULL; - if (code == 0 && list_empty(&drv->driver.klist_devices.k_list)) - retval = -ENODEV; - drv->driver.probe = platform_drv_probe_fail; - spin_unlock(&platform_bus_type.klist_drivers.k_lock); - - if (code != retval) - platform_driver_unregister(drv); - return retval; -} -EXPORT_SYMBOL_GPL(platform_driver_probe); /* modalias support enables more hands-off userspace setup: * (a) environment variable lets new-style hotplug events work once system is diff --git a/trunk/drivers/base/topology.c b/trunk/drivers/base/topology.c index 3d12b85b0962..3ef9d514b916 100644 --- a/trunk/drivers/base/topology.c +++ b/trunk/drivers/base/topology.c @@ -94,63 +94,55 @@ static struct attribute_group topology_attr_group = { .name = "topology" }; -static cpumask_t topology_dev_map = CPU_MASK_NONE; - /* Add/Remove cpu_topology interface for CPU device */ -static int __cpuinit topology_add_dev(unsigned int cpu) +static int __cpuinit topology_add_dev(struct sys_device * sys_dev) { - int rc; - struct sys_device *sys_dev = get_cpu_sysdev(cpu); - - rc = sysfs_create_group(&sys_dev->kobj, &topology_attr_group); - if (!rc) - cpu_set(cpu, topology_dev_map); - return rc; + sysfs_create_group(&sys_dev->kobj, &topology_attr_group); + return 0; } -#ifdef CONFIG_HOTPLUG_CPU -static void __cpuinit topology_remove_dev(unsigned int cpu) +static int __cpuinit topology_remove_dev(struct sys_device * sys_dev) { - struct sys_device *sys_dev = get_cpu_sysdev(cpu); - - if (!cpu_isset(cpu, topology_dev_map)) - return; - cpu_clear(cpu, topology_dev_map); sysfs_remove_group(&sys_dev->kobj, &topology_attr_group); + return 0; } static int __cpuinit topology_cpu_callback(struct notifier_block *nfb, - unsigned long action, void *hcpu) + unsigned long action, void *hcpu) { unsigned int cpu = (unsigned long)hcpu; - int rc = 0; + struct sys_device *sys_dev; + sys_dev = get_cpu_sysdev(cpu); switch (action) { - case CPU_UP_PREPARE: - rc = topology_add_dev(cpu); + case CPU_ONLINE: + topology_add_dev(sys_dev); break; - case CPU_UP_CANCELED: case CPU_DEAD: - topology_remove_dev(cpu); + topology_remove_dev(sys_dev); break; } - return rc ? NOTIFY_BAD : NOTIFY_OK; + return NOTIFY_OK; } -#endif + +static struct notifier_block __cpuinitdata topology_cpu_notifier = +{ + .notifier_call = topology_cpu_callback, +}; static int __cpuinit topology_sysfs_init(void) { - int cpu; - int rc; + int i; - for_each_online_cpu(cpu) { - rc = topology_add_dev(cpu); - if (rc) - return rc; + for_each_online_cpu(i) { + topology_cpu_callback(&topology_cpu_notifier, CPU_ONLINE, + (void *)(long)i); } - hotcpu_notifier(topology_cpu_callback, 0); + + register_hotcpu_notifier(&topology_cpu_notifier); return 0; } device_initcall(topology_sysfs_init); + diff --git a/trunk/drivers/block/DAC960.c b/trunk/drivers/block/DAC960.c index 742d07403101..b3f639fbf220 100644 --- a/trunk/drivers/block/DAC960.c +++ b/trunk/drivers/block/DAC960.c @@ -2698,7 +2698,8 @@ DAC960_DetectController(struct pci_dev *PCI_Device, { struct DAC960_privdata *privdata = (struct DAC960_privdata *)entry->driver_data; - irq_handler_t InterruptHandler = privdata->InterruptHandler; + irqreturn_t (*InterruptHandler)(int, void *, struct pt_regs *) = + privdata->InterruptHandler; unsigned int MemoryWindowSize = privdata->MemoryWindowSize; DAC960_Controller_T *Controller = NULL; unsigned char DeviceFunction = PCI_Device->devfn; @@ -5252,9 +5253,10 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command) */ static irqreturn_t DAC960_GEM_InterruptHandler(int IRQ_Channel, - void *DeviceIdentifier) + void *DeviceIdentifier, + struct pt_regs *InterruptRegisters) { - DAC960_Controller_T *Controller = DeviceIdentifier; + DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier; void __iomem *ControllerBaseAddress = Controller->BaseAddress; DAC960_V2_StatusMailbox_T *NextStatusMailbox; unsigned long flags; @@ -5293,9 +5295,10 @@ static irqreturn_t DAC960_GEM_InterruptHandler(int IRQ_Channel, */ static irqreturn_t DAC960_BA_InterruptHandler(int IRQ_Channel, - void *DeviceIdentifier) + void *DeviceIdentifier, + struct pt_regs *InterruptRegisters) { - DAC960_Controller_T *Controller = DeviceIdentifier; + DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier; void __iomem *ControllerBaseAddress = Controller->BaseAddress; DAC960_V2_StatusMailbox_T *NextStatusMailbox; unsigned long flags; @@ -5335,9 +5338,10 @@ static irqreturn_t DAC960_BA_InterruptHandler(int IRQ_Channel, */ static irqreturn_t DAC960_LP_InterruptHandler(int IRQ_Channel, - void *DeviceIdentifier) + void *DeviceIdentifier, + struct pt_regs *InterruptRegisters) { - DAC960_Controller_T *Controller = DeviceIdentifier; + DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier; void __iomem *ControllerBaseAddress = Controller->BaseAddress; DAC960_V2_StatusMailbox_T *NextStatusMailbox; unsigned long flags; @@ -5377,9 +5381,10 @@ static irqreturn_t DAC960_LP_InterruptHandler(int IRQ_Channel, */ static irqreturn_t DAC960_LA_InterruptHandler(int IRQ_Channel, - void *DeviceIdentifier) + void *DeviceIdentifier, + struct pt_regs *InterruptRegisters) { - DAC960_Controller_T *Controller = DeviceIdentifier; + DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier; void __iomem *ControllerBaseAddress = Controller->BaseAddress; DAC960_V1_StatusMailbox_T *NextStatusMailbox; unsigned long flags; @@ -5415,9 +5420,10 @@ static irqreturn_t DAC960_LA_InterruptHandler(int IRQ_Channel, */ static irqreturn_t DAC960_PG_InterruptHandler(int IRQ_Channel, - void *DeviceIdentifier) + void *DeviceIdentifier, + struct pt_regs *InterruptRegisters) { - DAC960_Controller_T *Controller = DeviceIdentifier; + DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier; void __iomem *ControllerBaseAddress = Controller->BaseAddress; DAC960_V1_StatusMailbox_T *NextStatusMailbox; unsigned long flags; @@ -5453,9 +5459,10 @@ static irqreturn_t DAC960_PG_InterruptHandler(int IRQ_Channel, */ static irqreturn_t DAC960_PD_InterruptHandler(int IRQ_Channel, - void *DeviceIdentifier) + void *DeviceIdentifier, + struct pt_regs *InterruptRegisters) { - DAC960_Controller_T *Controller = DeviceIdentifier; + DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier; void __iomem *ControllerBaseAddress = Controller->BaseAddress; unsigned long flags; @@ -5491,9 +5498,10 @@ static irqreturn_t DAC960_PD_InterruptHandler(int IRQ_Channel, */ static irqreturn_t DAC960_P_InterruptHandler(int IRQ_Channel, - void *DeviceIdentifier) + void *DeviceIdentifier, + struct pt_regs *InterruptRegisters) { - DAC960_Controller_T *Controller = DeviceIdentifier; + DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier; void __iomem *ControllerBaseAddress = Controller->BaseAddress; unsigned long flags; diff --git a/trunk/drivers/block/DAC960.h b/trunk/drivers/block/DAC960.h index 6148073532b2..f9217c34bc2b 100644 --- a/trunk/drivers/block/DAC960.h +++ b/trunk/drivers/block/DAC960.h @@ -2175,7 +2175,7 @@ static char struct DAC960_privdata { DAC960_HardwareType_T HardwareType; DAC960_FirmwareType_T FirmwareType; - irq_handler_t InterruptHandler; + irqreturn_t (*InterruptHandler)(int, void *, struct pt_regs *); unsigned int MemoryWindowSize; }; @@ -4379,8 +4379,8 @@ static inline void DAC960_P_To_PD_TranslateEnquiry(void *Enquiry) static inline void DAC960_P_To_PD_TranslateDeviceState(void *DeviceState) { memcpy(DeviceState + 2, DeviceState + 3, 1); - memmove(DeviceState + 4, DeviceState + 5, 2); - memmove(DeviceState + 6, DeviceState + 8, 4); + memcpy(DeviceState + 4, DeviceState + 5, 2); + memcpy(DeviceState + 6, DeviceState + 8, 4); } static inline @@ -4412,12 +4412,12 @@ static void DAC960_FinalizeController(DAC960_Controller_T *); static void DAC960_V1_QueueReadWriteCommand(DAC960_Command_T *); static void DAC960_V2_QueueReadWriteCommand(DAC960_Command_T *); static void DAC960_RequestFunction(struct request_queue *); -static irqreturn_t DAC960_BA_InterruptHandler(int, void *); -static irqreturn_t DAC960_LP_InterruptHandler(int, void *); -static irqreturn_t DAC960_LA_InterruptHandler(int, void *); -static irqreturn_t DAC960_PG_InterruptHandler(int, void *); -static irqreturn_t DAC960_PD_InterruptHandler(int, void *); -static irqreturn_t DAC960_P_InterruptHandler(int, void *); +static irqreturn_t DAC960_BA_InterruptHandler(int, void *, struct pt_regs *); +static irqreturn_t DAC960_LP_InterruptHandler(int, void *, struct pt_regs *); +static irqreturn_t DAC960_LA_InterruptHandler(int, void *, struct pt_regs *); +static irqreturn_t DAC960_PG_InterruptHandler(int, void *, struct pt_regs *); +static irqreturn_t DAC960_PD_InterruptHandler(int, void *, struct pt_regs *); +static irqreturn_t DAC960_P_InterruptHandler(int, void *, struct pt_regs *); static void DAC960_V1_QueueMonitoringCommand(DAC960_Command_T *); static void DAC960_V2_QueueMonitoringCommand(DAC960_Command_T *); static void DAC960_MonitoringTimerFunction(unsigned long); diff --git a/trunk/drivers/block/acsi.c b/trunk/drivers/block/acsi.c index 706cdc6a69ec..0b80fbb8dbfd 100644 --- a/trunk/drivers/block/acsi.c +++ b/trunk/drivers/block/acsi.c @@ -346,7 +346,7 @@ static int acsicmd_dma( const char *cmd, char *buffer, int blocks, int rwflag, int enable); static int acsi_reqsense( char *buffer, int targ, int lun); static void acsi_print_error(const unsigned char *errblk, struct acsi_info_struct *aip); -static irqreturn_t acsi_interrupt (int irq, void *data); +static irqreturn_t acsi_interrupt (int irq, void *data, struct pt_regs *fp); static void unexpected_acsi_interrupt( void ); static void bad_rw_intr( void ); static void read_intr( void ); @@ -726,7 +726,7 @@ static void acsi_print_error(const unsigned char *errblk, struct acsi_info_struc * *******************************************************************/ -static irqreturn_t acsi_interrupt(int irq, void *data ) +static irqreturn_t acsi_interrupt(int irq, void *data, struct pt_regs *fp ) { void (*acsi_irq_handler)(void) = do_acsi; diff --git a/trunk/drivers/block/acsi_slm.c b/trunk/drivers/block/acsi_slm.c index 8e41c87b026e..4030a8fd1187 100644 --- a/trunk/drivers/block/acsi_slm.c +++ b/trunk/drivers/block/acsi_slm.c @@ -246,7 +246,7 @@ static int slm_getstats( char *buffer, int device ); static ssize_t slm_read( struct file* file, char *buf, size_t count, loff_t *ppos ); static void start_print( int device ); -static irqreturn_t slm_interrupt(int irc, void *data); +static irqreturn_t slm_interrupt(int irc, void *data, struct pt_regs *fp); static void slm_test_ready( unsigned long dummy ); static void set_dma_addr( unsigned long paddr ); static unsigned long get_dma_addr( void ); @@ -452,7 +452,7 @@ static void start_print( int device ) /* Only called when an error happened or at the end of a page */ -static irqreturn_t slm_interrupt(int irc, void *data) +static irqreturn_t slm_interrupt(int irc, void *data, struct pt_regs *fp) { unsigned long addr; int stat; diff --git a/trunk/drivers/block/amiflop.c b/trunk/drivers/block/amiflop.c index 5d6562171533..2641597c6549 100644 --- a/trunk/drivers/block/amiflop.c +++ b/trunk/drivers/block/amiflop.c @@ -209,7 +209,7 @@ static int fd_device[4] = { 0, 0, 0, 0 }; /* Milliseconds timer */ -static irqreturn_t ms_isr(int irq, void *dummy) +static irqreturn_t ms_isr(int irq, void *dummy, struct pt_regs *fp) { ms_busy = -1; wake_up(&ms_wait); @@ -560,7 +560,7 @@ static unsigned long fd_get_drive_id(int drive) return (id); } -static irqreturn_t fd_block_done(int irq, void *dummy) +static irqreturn_t fd_block_done(int irq, void *dummy, struct pt_regs *fp) { if (block_flag) custom.dsklen = 0x4000; @@ -1709,13 +1709,10 @@ static struct kobject *floppy_find(dev_t dev, int *part, void *data) return get_disk(unit[drive].gendisk); } -static int __init amiga_floppy_init(void) +int __init amiga_floppy_init(void) { int i, ret; - if (!MACH_IS_AMIGA) - return -ENXIO; - if (!AMIGAHW_PRESENT(AMI_FLOPPY)) return -ENXIO; @@ -1812,9 +1809,15 @@ static int __init amiga_floppy_init(void) return ret; } -module_init(amiga_floppy_init); #ifdef MODULE +int init_module(void) +{ + if (!MACH_IS_AMIGA) + return -ENXIO; + return amiga_floppy_init(); +} + #if 0 /* not safe to unload */ void cleanup_module(void) { diff --git a/trunk/drivers/block/aoe/aoe.h b/trunk/drivers/block/aoe/aoe.h index 6d111228cfac..6eebcb7be97e 100644 --- a/trunk/drivers/block/aoe/aoe.h +++ b/trunk/drivers/block/aoe/aoe.h @@ -1,5 +1,5 @@ -/* Copyright (c) 2006 Coraid, Inc. See COPYING for GPL terms. */ -#define VERSION "32" +/* Copyright (c) 2004 Coraid, Inc. See COPYING for GPL terms. */ +#define VERSION "22" #define AOE_MAJOR 152 #define DEVICE_NAME "aoe" @@ -65,7 +65,7 @@ struct aoe_atahdr { struct aoe_cfghdr { __be16 bufcnt; __be16 fwver; - unsigned char scnt; + unsigned char res; unsigned char aoeccmd; unsigned char cslen[2]; }; @@ -78,14 +78,12 @@ enum { DEVFL_GDALLOC = (1<<4), /* need to alloc gendisk */ DEVFL_PAUSE = (1<<5), DEVFL_NEWSIZE = (1<<6), /* need to update dev size in block layer */ - DEVFL_MAXBCNT = (1<<7), /* d->maxbcnt is not changeable */ - DEVFL_KICKME = (1<<8), BUFFL_FAIL = 1, }; enum { - DEFAULTBCNT = 2 * 512, /* 2 sectors */ + MAXATADATA = 1024, NPERSHELF = 16, /* number of slots per shelf address */ FREETAG = -1, MIN_BUFS = 8, @@ -109,9 +107,11 @@ struct frame { ulong waited; struct buf *buf; char *bufaddr; - ulong bcnt; - sector_t lba; - struct sk_buff *skb; + int writedatalen; + int ndata; + + /* largest possible */ + unsigned char data[sizeof(struct aoe_hdr) + sizeof(struct aoe_atahdr)]; }; struct aoedev { @@ -121,12 +121,9 @@ struct aoedev { ulong sysminor; ulong aoemajor; ulong aoeminor; - u16 nopen; /* (bd_openers isn't available without sleeping) */ - u16 lasttag; /* last tag sent */ - u16 rttavg; /* round trip average of requests/responses */ - u16 mintimer; + ulong nopen; /* (bd_openers isn't available without sleeping) */ + ulong rttavg; /* round trip average of requests/responses */ u16 fw_ver; /* version of blade's firmware */ - u16 maxbcnt; struct work_struct work;/* disk create work struct */ struct gendisk *gd; request_queue_t blkq; @@ -140,8 +137,8 @@ struct aoedev { mempool_t *bufpool; /* for deadlock-free Buf allocation */ struct list_head bufq; /* queue of bios to work on */ struct buf *inprocess; /* the one we're currently working on */ - ushort lostjumbo; - ushort nframes; /* number of frames below */ + ulong lasttag; /* last tag sent */ + ulong nframes; /* number of frames below */ struct frame *frames; }; @@ -160,7 +157,6 @@ void aoecmd_cfg(ushort aoemajor, unsigned char aoeminor); void aoecmd_ata_rsp(struct sk_buff *); void aoecmd_cfg_rsp(struct sk_buff *); void aoecmd_sleepwork(void *vp); -struct sk_buff *new_skb(ulong); int aoedev_init(void); void aoedev_exit(void); diff --git a/trunk/drivers/block/aoe/aoeblk.c b/trunk/drivers/block/aoe/aoeblk.c index aa25f8b09fe3..393b86a3dbf8 100644 --- a/trunk/drivers/block/aoe/aoeblk.c +++ b/trunk/drivers/block/aoe/aoeblk.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2006 Coraid, Inc. See COPYING for GPL terms. */ +/* Copyright (c) 2004 Coraid, Inc. See COPYING for GPL terms. */ /* * aoeblk.c * block device routines @@ -14,6 +14,7 @@ static kmem_cache_t *buf_pool_cache; +/* add attributes for our block devices in sysfs */ static ssize_t aoedisk_show_state(struct gendisk * disk, char *page) { struct aoedev *d = disk->private_data; @@ -63,27 +64,21 @@ static struct disk_attribute disk_attr_fwver = { .show = aoedisk_show_fwver }; -static struct attribute *aoe_attrs[] = { - &disk_attr_state.attr, - &disk_attr_mac.attr, - &disk_attr_netif.attr, - &disk_attr_fwver.attr, - NULL -}; - -static const struct attribute_group attr_group = { - .attrs = aoe_attrs, -}; - -static int +static void aoedisk_add_sysfs(struct aoedev *d) { - return sysfs_create_group(&d->gd->kobj, &attr_group); + sysfs_create_file(&d->gd->kobj, &disk_attr_state.attr); + sysfs_create_file(&d->gd->kobj, &disk_attr_mac.attr); + sysfs_create_file(&d->gd->kobj, &disk_attr_netif.attr); + sysfs_create_file(&d->gd->kobj, &disk_attr_fwver.attr); } void aoedisk_rm_sysfs(struct aoedev *d) { - sysfs_remove_group(&d->gd->kobj, &attr_group); + sysfs_remove_link(&d->gd->kobj, "state"); + sysfs_remove_link(&d->gd->kobj, "mac"); + sysfs_remove_link(&d->gd->kobj, "netif"); + sysfs_remove_link(&d->gd->kobj, "firmware-version"); } static int @@ -137,7 +132,8 @@ aoeblk_make_request(request_queue_t *q, struct bio *bio) d = bio->bi_bdev->bd_disk->private_data; buf = mempool_alloc(d->bufpool, GFP_NOIO); if (buf == NULL) { - printk(KERN_INFO "aoe: buf allocation failure\n"); + printk(KERN_INFO "aoe: aoeblk_make_request: buf allocation " + "failure\n"); bio_endio(bio, bio->bi_size, -ENOMEM); return 0; } @@ -147,15 +143,14 @@ aoeblk_make_request(request_queue_t *q, struct bio *bio) buf->bio = bio; buf->resid = bio->bi_size; buf->sector = bio->bi_sector; - buf->bv = &bio->bi_io_vec[bio->bi_idx]; - WARN_ON(buf->bv->bv_len == 0); + buf->bv = buf->bio->bi_io_vec; buf->bv_resid = buf->bv->bv_len; buf->bufaddr = page_address(buf->bv->bv_page) + buf->bv->bv_offset; spin_lock_irqsave(&d->lock, flags); if ((d->flags & DEVFL_UP) == 0) { - printk(KERN_INFO "aoe: device %ld.%ld is not up\n", + printk(KERN_INFO "aoe: aoeblk_make_request: device %ld.%ld is not up\n", d->aoemajor, d->aoeminor); spin_unlock_irqrestore(&d->lock, flags); mempool_free(buf, d->bufpool); @@ -181,7 +176,7 @@ aoeblk_getgeo(struct block_device *bdev, struct hd_geometry *geo) struct aoedev *d = bdev->bd_disk->private_data; if ((d->flags & DEVFL_UP) == 0) { - printk(KERN_ERR "aoe: disk not up\n"); + printk(KERN_ERR "aoe: aoeblk_ioctl: disk not up\n"); return -ENODEV; } @@ -208,8 +203,8 @@ aoeblk_gdalloc(void *vp) gd = alloc_disk(AOE_PARTITIONS); if (gd == NULL) { - printk(KERN_ERR "aoe: cannot allocate disk structure for %ld.%ld\n", - d->aoemajor, d->aoeminor); + printk(KERN_ERR "aoe: aoeblk_gdalloc: cannot allocate disk " + "structure for %ld.%ld\n", d->aoemajor, d->aoeminor); spin_lock_irqsave(&d->lock, flags); d->flags &= ~DEVFL_GDALLOC; spin_unlock_irqrestore(&d->lock, flags); @@ -218,8 +213,8 @@ aoeblk_gdalloc(void *vp) d->bufpool = mempool_create_slab_pool(MIN_BUFS, buf_pool_cache); if (d->bufpool == NULL) { - printk(KERN_ERR "aoe: cannot allocate bufpool for %ld.%ld\n", - d->aoemajor, d->aoeminor); + printk(KERN_ERR "aoe: aoeblk_gdalloc: cannot allocate bufpool " + "for %ld.%ld\n", d->aoemajor, d->aoeminor); put_disk(gd); spin_lock_irqsave(&d->lock, flags); d->flags &= ~DEVFL_GDALLOC; diff --git a/trunk/drivers/block/aoe/aoechr.c b/trunk/drivers/block/aoe/aoechr.c index e22b4c9520a9..1bc1cf9603f1 100644 --- a/trunk/drivers/block/aoe/aoechr.c +++ b/trunk/drivers/block/aoe/aoechr.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2006 Coraid, Inc. See COPYING for GPL terms. */ +/* Copyright (c) 2004 Coraid, Inc. See COPYING for GPL terms. */ /* * aoechr.c * AoE character device driver @@ -15,6 +15,7 @@ enum { MINOR_INTERFACES, MINOR_REVALIDATE, MSGSZ = 2048, + NARGS = 10, NMSG = 100, /* message backlog to retain */ }; @@ -55,8 +56,9 @@ static int interfaces(const char __user *str, size_t size) { if (set_aoe_iflist(str, size)) { - printk(KERN_ERR - "aoe: could not set interface list: too many interfaces\n"); + printk(KERN_CRIT + "%s: could not set interface list: %s\n", + __FUNCTION__, "too many interfaces"); return -EINVAL; } return 0; @@ -79,7 +81,8 @@ revalidate(const char __user *str, size_t size) /* should be e%d.%d format */ n = sscanf(buf, "e%d.%d", &major, &minor); if (n != 2) { - printk(KERN_ERR "aoe: invalid device specification\n"); + printk(KERN_ERR "aoe: %s: invalid device specification\n", + __FUNCTION__); return -EINVAL; } d = aoedev_by_aoeaddr(major, minor); @@ -87,7 +90,6 @@ revalidate(const char __user *str, size_t size) return -EINVAL; spin_lock_irqsave(&d->lock, flags); - d->flags &= ~DEVFL_MAXBCNT; d->flags |= DEVFL_PAUSE; spin_unlock_irqrestore(&d->lock, flags); aoecmd_cfg(major, minor); @@ -114,7 +116,7 @@ bail: spin_unlock_irqrestore(&emsgs_lock, flags); mp = kmalloc(n, GFP_ATOMIC); if (mp == NULL) { - printk(KERN_ERR "aoe: allocation failure, len=%ld\n", n); + printk(KERN_CRIT "aoe: aoechr_error: allocation failure, len=%ld\n", n); goto bail; } @@ -139,7 +141,7 @@ aoechr_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offp switch ((unsigned long) filp->private_data) { default: - printk(KERN_INFO "aoe: can't write to that file.\n"); + printk(KERN_INFO "aoe: aoechr_write: can't write to that file.\n"); break; case MINOR_DISCOVER: ret = discover(); @@ -248,7 +250,7 @@ aoechr_init(void) n = register_chrdev(AOE_MAJOR, "aoechr", &aoe_fops); if (n < 0) { - printk(KERN_ERR "aoe: can't register char device\n"); + printk(KERN_ERR "aoe: aoechr_init: can't register char device\n"); return n; } sema_init(&emsgs_sema, 0); diff --git a/trunk/drivers/block/aoe/aoecmd.c b/trunk/drivers/block/aoe/aoecmd.c index 8a13b1af8bab..39da28d344fe 100644 --- a/trunk/drivers/block/aoe/aoecmd.c +++ b/trunk/drivers/block/aoe/aoecmd.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2006 Coraid, Inc. See COPYING for GPL terms. */ +/* Copyright (c) 2004 Coraid, Inc. See COPYING for GPL terms. */ /* * aoecmd.c * Filesystem request handling methods @@ -15,19 +15,17 @@ #define TIMERTICK (HZ / 10) #define MINTIMER (2 * TIMERTICK) #define MAXTIMER (HZ << 1) +#define MAXWAIT (60 * 3) /* After MAXWAIT seconds, give up and fail dev */ -static int aoe_deadsecs = 60 * 3; -module_param(aoe_deadsecs, int, 0644); -MODULE_PARM_DESC(aoe_deadsecs, "After aoe_deadsecs seconds, give up and fail dev."); - -struct sk_buff * -new_skb(ulong len) +static struct sk_buff * +new_skb(struct net_device *if_dev, ulong len) { struct sk_buff *skb; skb = alloc_skb(len, GFP_ATOMIC); if (skb) { skb->nh.raw = skb->mac.raw = skb->data; + skb->dev = if_dev; skb->protocol = __constant_htons(ETH_P_AOE); skb->priority = 0; skb_put(skb, len); @@ -42,6 +40,29 @@ new_skb(ulong len) return skb; } +static struct sk_buff * +skb_prepare(struct aoedev *d, struct frame *f) +{ + struct sk_buff *skb; + char *p; + + skb = new_skb(d->ifp, f->ndata + f->writedatalen); + if (!skb) { + printk(KERN_INFO "aoe: skb_prepare: failure to allocate skb\n"); + return NULL; + } + + p = skb->mac.raw; + memcpy(p, f->data, f->ndata); + + if (f->writedatalen) { + p += sizeof(struct aoe_hdr) + sizeof(struct aoe_atahdr); + memcpy(p, f->bufaddr, f->writedatalen); + } + + return skb; +} + static struct frame * getframe(struct aoedev *d, int tag) { @@ -86,17 +107,6 @@ aoehdr_atainit(struct aoedev *d, struct aoe_hdr *h) return host_tag; } -static inline void -put_lba(struct aoe_atahdr *ah, sector_t lba) -{ - ah->lba0 = lba; - ah->lba1 = lba >>= 8; - ah->lba2 = lba >>= 8; - ah->lba3 = lba >>= 8; - ah->lba4 = lba >>= 8; - ah->lba5 = lba >>= 8; -} - static void aoecmd_ata_rw(struct aoedev *d, struct frame *f) { @@ -115,27 +125,29 @@ aoecmd_ata_rw(struct aoedev *d, struct frame *f) sector = buf->sector; bcnt = buf->bv_resid; - if (bcnt > d->maxbcnt) - bcnt = d->maxbcnt; + if (bcnt > MAXATADATA) + bcnt = MAXATADATA; /* initialize the headers & frame */ - skb = f->skb; - h = (struct aoe_hdr *) skb->mac.raw; + h = (struct aoe_hdr *) f->data; ah = (struct aoe_atahdr *) (h+1); - skb->len = sizeof *h + sizeof *ah; - memset(h, 0, ETH_ZLEN); + f->ndata = sizeof *h + sizeof *ah; + memset(h, 0, f->ndata); f->tag = aoehdr_atainit(d, h); f->waited = 0; f->buf = buf; f->bufaddr = buf->bufaddr; - f->bcnt = bcnt; - f->lba = sector; /* set up ata header */ ah->scnt = bcnt >> 9; - put_lba(ah, sector); + ah->lba0 = sector; + ah->lba1 = sector >>= 8; + ah->lba2 = sector >>= 8; + ah->lba3 = sector >>= 8; if (d->flags & DEVFL_EXT) { ah->aflags |= AOEAFL_EXT; + ah->lba4 = sector >>= 8; + ah->lba5 = sector >>= 8; } else { extbit = 0; ah->lba3 &= 0x0f; @@ -143,14 +155,11 @@ aoecmd_ata_rw(struct aoedev *d, struct frame *f) } if (bio_data_dir(buf->bio) == WRITE) { - skb_fill_page_desc(skb, 0, virt_to_page(f->bufaddr), - offset_in_page(f->bufaddr), bcnt); ah->aflags |= AOEAFL_WRITE; - skb->len += bcnt; - skb->data_len = bcnt; + f->writedatalen = bcnt; } else { - skb->len = ETH_ZLEN; writebit = 0; + f->writedatalen = 0; } ah->cmdstat = WIN_READ | writebit | extbit; @@ -159,27 +168,26 @@ aoecmd_ata_rw(struct aoedev *d, struct frame *f) buf->nframesout += 1; buf->bufaddr += bcnt; buf->bv_resid -= bcnt; -/* printk(KERN_DEBUG "aoe: bv_resid=%ld\n", buf->bv_resid); */ +/* printk(KERN_INFO "aoe: bv_resid=%ld\n", buf->bv_resid); */ buf->resid -= bcnt; buf->sector += bcnt >> 9; if (buf->resid == 0) { d->inprocess = NULL; } else if (buf->bv_resid == 0) { buf->bv++; - WARN_ON(buf->bv->bv_len == 0); buf->bv_resid = buf->bv->bv_len; buf->bufaddr = page_address(buf->bv->bv_page) + buf->bv->bv_offset; } - skb->dev = d->ifp; - skb = skb_clone(skb, GFP_ATOMIC); - if (skb == NULL) - return; - if (d->sendq_hd) - d->sendq_tl->next = skb; - else - d->sendq_hd = skb; - d->sendq_tl = skb; + skb = skb_prepare(d, f); + if (skb) { + skb->next = NULL; + if (d->sendq_hd) + d->sendq_tl->next = skb; + else + d->sendq_hd = skb; + d->sendq_tl = skb; + } } /* some callers cannot sleep, and they can call this function, @@ -201,12 +209,11 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail) if (!is_aoe_netif(ifp)) continue; - skb = new_skb(sizeof *h + sizeof *ch); + skb = new_skb(ifp, sizeof *h + sizeof *ch); if (skb == NULL) { - printk(KERN_INFO "aoe: skb alloc failure\n"); + printk(KERN_INFO "aoe: aoecmd_cfg: skb alloc failure\n"); continue; } - skb->dev = ifp; if (sl_tail == NULL) sl_tail = skb; h = (struct aoe_hdr *) skb->mac.raw; @@ -230,29 +237,6 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail) return sl; } -static struct frame * -freeframe(struct aoedev *d) -{ - struct frame *f, *e; - int n = 0; - - f = d->frames; - e = f + d->nframes; - for (; ftag != FREETAG) - continue; - if (atomic_read(&skb_shinfo(f->skb)->dataref) == 1) { - skb_shinfo(f->skb)->nr_frags = f->skb->data_len = 0; - return f; - } - n++; - } - if (n == d->nframes) /* wait for network layer */ - d->flags |= DEVFL_KICKME; - - return NULL; -} - /* enters with d->lock held */ void aoecmd_work(struct aoedev *d) @@ -268,7 +252,7 @@ aoecmd_work(struct aoedev *d) } loop: - f = freeframe(d); + f = getframe(d, FREETAG); if (f == NULL) return; if (d->inprocess == NULL) { @@ -276,7 +260,7 @@ aoecmd_work(struct aoedev *d) return; buf = container_of(d->bufq.next, struct buf, bufs); list_del(d->bufq.next); -/*printk(KERN_DEBUG "aoe: bi_size=%ld\n", buf->bio->bi_size); */ +/*printk(KERN_INFO "aoecmd_work: bi_size=%ld\n", buf->bio->bi_size); */ d->inprocess = buf; } aoecmd_ata_rw(d, f); @@ -288,7 +272,6 @@ rexmit(struct aoedev *d, struct frame *f) { struct sk_buff *skb; struct aoe_hdr *h; - struct aoe_atahdr *ah; char buf[128]; u32 n; @@ -300,41 +283,21 @@ rexmit(struct aoedev *d, struct frame *f) d->aoemajor, d->aoeminor, f->tag, jiffies, n); aoechr_error(buf); - skb = f->skb; - h = (struct aoe_hdr *) skb->mac.raw; - ah = (struct aoe_atahdr *) (h+1); + h = (struct aoe_hdr *) f->data; f->tag = n; h->tag = cpu_to_be32(n); memcpy(h->dst, d->addr, sizeof h->dst); memcpy(h->src, d->ifp->dev_addr, sizeof h->src); - n = DEFAULTBCNT / 512; - if (ah->scnt > n) { - ah->scnt = n; - if (ah->aflags & AOEAFL_WRITE) { - skb_fill_page_desc(skb, 0, virt_to_page(f->bufaddr), - offset_in_page(f->bufaddr), DEFAULTBCNT); - skb->len = sizeof *h + sizeof *ah + DEFAULTBCNT; - skb->data_len = DEFAULTBCNT; - } - if (++d->lostjumbo > (d->nframes << 1)) - if (d->maxbcnt != DEFAULTBCNT) { - printk(KERN_INFO "aoe: e%ld.%ld: too many lost jumbo on %s - using 1KB frames.\n", - d->aoemajor, d->aoeminor, d->ifp->name); - d->maxbcnt = DEFAULTBCNT; - d->flags |= DEVFL_MAXBCNT; - } + skb = skb_prepare(d, f); + if (skb) { + skb->next = NULL; + if (d->sendq_hd) + d->sendq_tl->next = skb; + else + d->sendq_hd = skb; + d->sendq_tl = skb; } - - skb->dev = d->ifp; - skb = skb_clone(skb, GFP_ATOMIC); - if (skb == NULL) - return; - if (d->sendq_hd) - d->sendq_tl->next = skb; - else - d->sendq_hd = skb; - d->sendq_tl = skb; } static int @@ -377,17 +340,13 @@ rexmit_timer(ulong vp) if (f->tag != FREETAG && tsince(f->tag) >= timeout) { n = f->waited += timeout; n /= HZ; - if (n > aoe_deadsecs) { /* waited too long for response */ + if (n > MAXWAIT) { /* waited too long. device failure. */ aoedev_downdev(d); break; } rexmit(d, f); } } - if (d->flags & DEVFL_KICKME) { - d->flags &= ~DEVFL_KICKME; - aoecmd_work(d); - } sl = d->sendq_hd; d->sendq_hd = d->sendq_tl = NULL; @@ -472,8 +431,8 @@ ataid_complete(struct aoedev *d, unsigned char *id) } if (d->ssize != ssize) - printk(KERN_INFO "aoe: %012llx e%lu.%lu v%04x has %llu sectors\n", - (unsigned long long)mac_addr(d->addr), + printk(KERN_INFO "aoe: %012llx e%lu.%lu v%04x has %llu " + "sectors\n", (unsigned long long)mac_addr(d->addr), d->aoemajor, d->aoeminor, d->fw_ver, (long long)ssize); d->ssize = ssize; @@ -483,9 +442,11 @@ ataid_complete(struct aoedev *d, unsigned char *id) d->flags |= DEVFL_NEWSIZE; } else { if (d->flags & DEVFL_GDALLOC) { - printk(KERN_ERR "aoe: can't schedule work for e%lu.%lu, %s\n", + printk(KERN_INFO "aoe: %s: %s e%lu.%lu, %s\n", + __FUNCTION__, + "can't schedule work for", d->aoemajor, d->aoeminor, - "it's already on! This shouldn't happen.\n"); + "it's already on! (This really shouldn't happen).\n"); return; } d->flags |= DEVFL_GDALLOC; @@ -499,15 +460,8 @@ calc_rttavg(struct aoedev *d, int rtt) register long n; n = rtt; - if (n < 0) { - n = -rtt; - if (n < MINTIMER) - n = MINTIMER; - else if (n > MAXTIMER) - n = MAXTIMER; - d->mintimer += (n - d->mintimer) >> 1; - } else if (n < d->mintimer) - n = d->mintimer; + if (n < MINTIMER) + n = MINTIMER; else if (n > MAXTIMER) n = MAXTIMER; @@ -520,7 +474,7 @@ void aoecmd_ata_rsp(struct sk_buff *skb) { struct aoedev *d; - struct aoe_hdr *hin, *hout; + struct aoe_hdr *hin; struct aoe_atahdr *ahin, *ahout; struct frame *f; struct buf *buf; @@ -543,10 +497,8 @@ aoecmd_ata_rsp(struct sk_buff *skb) spin_lock_irqsave(&d->lock, flags); - n = be32_to_cpu(hin->tag); - f = getframe(d, n); + f = getframe(d, be32_to_cpu(hin->tag)); if (f == NULL) { - calc_rttavg(d, -tsince(n)); spin_unlock_irqrestore(&d->lock, flags); snprintf(ebuf, sizeof ebuf, "%15s e%d.%d tag=%08x@%08lx\n", @@ -562,27 +514,26 @@ aoecmd_ata_rsp(struct sk_buff *skb) calc_rttavg(d, tsince(f->tag)); ahin = (struct aoe_atahdr *) (hin+1); - hout = (struct aoe_hdr *) f->skb->mac.raw; - ahout = (struct aoe_atahdr *) (hout+1); + ahout = (struct aoe_atahdr *) (f->data + sizeof(struct aoe_hdr)); buf = f->buf; if (ahout->cmdstat == WIN_IDENTIFY) d->flags &= ~DEVFL_PAUSE; if (ahin->cmdstat & 0xa9) { /* these bits cleared on success */ - printk(KERN_ERR - "aoe: ata error cmd=%2.2Xh stat=%2.2Xh from e%ld.%ld\n", + printk(KERN_CRIT "aoe: aoecmd_ata_rsp: ata error cmd=%2.2Xh " + "stat=%2.2Xh from e%ld.%ld\n", ahout->cmdstat, ahin->cmdstat, d->aoemajor, d->aoeminor); if (buf) buf->flags |= BUFFL_FAIL; } else { - n = ahout->scnt << 9; switch (ahout->cmdstat) { case WIN_READ: case WIN_READ_EXT: + n = ahout->scnt << 9; if (skb->len - sizeof *hin - sizeof *ahin < n) { - printk(KERN_ERR - "aoe: runt data size in read. skb->len=%d\n", + printk(KERN_CRIT "aoe: aoecmd_ata_rsp: runt " + "ata data size in read. skb->len=%d\n", skb->len); /* fail frame f? just returning will rexmit. */ spin_unlock_irqrestore(&d->lock, flags); @@ -591,49 +542,22 @@ aoecmd_ata_rsp(struct sk_buff *skb) memcpy(f->bufaddr, ahin+1, n); case WIN_WRITE: case WIN_WRITE_EXT: - if (f->bcnt -= n) { - skb = f->skb; - f->bufaddr += n; - put_lba(ahout, f->lba += ahout->scnt); - n = f->bcnt; - if (n > DEFAULTBCNT) - n = DEFAULTBCNT; - ahout->scnt = n >> 9; - if (ahout->aflags & AOEAFL_WRITE) { - skb_fill_page_desc(skb, 0, - virt_to_page(f->bufaddr), - offset_in_page(f->bufaddr), n); - skb->len = sizeof *hout + sizeof *ahout + n; - skb->data_len = n; - } - f->tag = newtag(d); - hout->tag = cpu_to_be32(f->tag); - skb->dev = d->ifp; - skb = skb_clone(skb, GFP_ATOMIC); - spin_unlock_irqrestore(&d->lock, flags); - if (skb) - aoenet_xmit(skb); - return; - } - if (n > DEFAULTBCNT) - d->lostjumbo = 0; break; case WIN_IDENTIFY: if (skb->len - sizeof *hin - sizeof *ahin < 512) { - printk(KERN_INFO - "aoe: runt data size in ataid. skb->len=%d\n", - skb->len); + printk(KERN_INFO "aoe: aoecmd_ata_rsp: runt data size " + "in ataid. skb->len=%d\n", skb->len); spin_unlock_irqrestore(&d->lock, flags); return; } ataid_complete(d, (char *) (ahin+1)); break; default: - printk(KERN_INFO - "aoe: unrecognized ata command %2.2Xh for %d.%d\n", - ahout->cmdstat, - be16_to_cpu(hin->major), - hin->minor); + printk(KERN_INFO "aoe: aoecmd_ata_rsp: unrecognized " + "outbound ata command %2.2Xh for %d.%d\n", + ahout->cmdstat, + be16_to_cpu(hin->major), + hin->minor); } } @@ -688,32 +612,33 @@ aoecmd_ata_id(struct aoedev *d) struct frame *f; struct sk_buff *skb; - f = freeframe(d); + f = getframe(d, FREETAG); if (f == NULL) { - printk(KERN_ERR "aoe: can't get a frame. This shouldn't happen.\n"); + printk(KERN_CRIT "aoe: aoecmd_ata_id: can't get a frame. " + "This shouldn't happen.\n"); return NULL; } /* initialize the headers & frame */ - skb = f->skb; - h = (struct aoe_hdr *) skb->mac.raw; + h = (struct aoe_hdr *) f->data; ah = (struct aoe_atahdr *) (h+1); - skb->len = ETH_ZLEN; - memset(h, 0, ETH_ZLEN); + f->ndata = sizeof *h + sizeof *ah; + memset(h, 0, f->ndata); f->tag = aoehdr_atainit(d, h); f->waited = 0; + f->writedatalen = 0; /* set up ata header */ ah->scnt = 1; ah->cmdstat = WIN_IDENTIFY; ah->lba3 = 0xa0; - skb->dev = d->ifp; + skb = skb_prepare(d, f); d->rttavg = MAXTIMER; d->timer.function = rexmit_timer; - return skb_clone(skb, GFP_ATOMIC); + return skb; } void @@ -723,9 +648,9 @@ aoecmd_cfg_rsp(struct sk_buff *skb) struct aoe_hdr *h; struct aoe_cfghdr *ch; ulong flags, sysminor, aoemajor; + u16 bufcnt; struct sk_buff *sl; enum { MAXFRAMES = 16 }; - u16 n; h = (struct aoe_hdr *) skb->mac.raw; ch = (struct aoe_cfghdr *) (h+1); @@ -736,25 +661,26 @@ aoecmd_cfg_rsp(struct sk_buff *skb) */ aoemajor = be16_to_cpu(h->major); if (aoemajor == 0xfff) { - printk(KERN_ERR "aoe: Warning: shelf address is all ones. " - "Check shelf dip switches.\n"); + printk(KERN_CRIT "aoe: aoecmd_cfg_rsp: Warning: shelf " + "address is all ones. Check shelf dip switches\n"); return; } sysminor = SYSMINOR(aoemajor, h->minor); if (sysminor * AOE_PARTITIONS + AOE_PARTITIONS > MINORMASK) { - printk(KERN_INFO "aoe: e%ld.%d: minor number too large\n", + printk(KERN_INFO + "aoe: e%ld.%d: minor number too large\n", aoemajor, (int) h->minor); return; } - n = be16_to_cpu(ch->bufcnt); - if (n > MAXFRAMES) /* keep it reasonable */ - n = MAXFRAMES; + bufcnt = be16_to_cpu(ch->bufcnt); + if (bufcnt > MAXFRAMES) /* keep it reasonable */ + bufcnt = MAXFRAMES; - d = aoedev_by_sysminor_m(sysminor, n); + d = aoedev_by_sysminor_m(sysminor, bufcnt); if (d == NULL) { - printk(KERN_INFO "aoe: device sysminor_m failure\n"); + printk(KERN_INFO "aoe: aoecmd_cfg_rsp: device sysminor_m failure\n"); return; } @@ -763,20 +689,6 @@ aoecmd_cfg_rsp(struct sk_buff *skb) /* permit device to migrate mac and network interface */ d->ifp = skb->dev; memcpy(d->addr, h->src, sizeof d->addr); - if (!(d->flags & DEVFL_MAXBCNT)) { - n = d->ifp->mtu; - n -= sizeof (struct aoe_hdr) + sizeof (struct aoe_atahdr); - n /= 512; - if (n > ch->scnt) - n = ch->scnt; - n = n ? n * 512 : DEFAULTBCNT; - if (n != d->maxbcnt) { - printk(KERN_INFO - "aoe: e%ld.%ld: setting %d byte data frames on %s\n", - d->aoemajor, d->aoeminor, n, d->ifp->name); - d->maxbcnt = n; - } - } /* don't change users' perspective */ if (d->nopen && !(d->flags & DEVFL_PAUSE)) { @@ -784,7 +696,6 @@ aoecmd_cfg_rsp(struct sk_buff *skb) return; } d->flags |= DEVFL_PAUSE; /* force pause */ - d->mintimer = MINTIMER; d->fw_ver = be16_to_cpu(ch->fwver); /* check for already outstanding ataid */ diff --git a/trunk/drivers/block/aoe/aoedev.c b/trunk/drivers/block/aoe/aoedev.c index 6125921bbec4..ed4258a62df5 100644 --- a/trunk/drivers/block/aoe/aoedev.c +++ b/trunk/drivers/block/aoe/aoedev.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2006 Coraid, Inc. See COPYING for GPL terms. */ +/* Copyright (c) 2004 Coraid, Inc. See COPYING for GPL terms. */ /* * aoedev.c * AoE device utility functions; maintains device list. @@ -20,8 +20,11 @@ aoedev_isbusy(struct aoedev *d) f = d->frames; e = f + d->nframes; do { - if (f->tag != FREETAG) + if (f->tag != FREETAG) { + printk(KERN_DEBUG "aoe: %ld.%ld isbusy\n", + d->aoemajor, d->aoeminor); return 1; + } } while (++f < e); return 0; @@ -63,32 +66,22 @@ aoedev_newdev(ulong nframes) struct frame *f, *e; d = kzalloc(sizeof *d, GFP_ATOMIC); + if (d == NULL) + return NULL; f = kcalloc(nframes, sizeof *f, GFP_ATOMIC); - switch (!d || !f) { - case 0: - d->nframes = nframes; - d->frames = f; - e = f + nframes; - for (; ftag = FREETAG; - f->skb = new_skb(ETH_ZLEN); - if (!f->skb) - break; - } - if (f == e) - break; - while (f > d->frames) { - f--; - dev_kfree_skb(f->skb); - } - default: - if (f) - kfree(f); - if (d) - kfree(d); + if (f == NULL) { + kfree(d); return NULL; } + INIT_WORK(&d->work, aoecmd_sleepwork, d); + + d->nframes = nframes; + d->frames = f; + e = f + nframes; + for (; ftag = FREETAG; + spin_lock_init(&d->lock); init_timer(&d->timer); d->timer.data = (ulong) d; @@ -121,7 +114,6 @@ aoedev_downdev(struct aoedev *d) mempool_free(buf, d->bufpool); bio_endio(bio, bio->bi_size, -EIO); } - skb_shinfo(f->skb)->nr_frags = f->skb->data_len = 0; } d->inprocess = NULL; @@ -156,7 +148,7 @@ aoedev_by_sysminor_m(ulong sysminor, ulong bufcnt) d = aoedev_newdev(bufcnt); if (d == NULL) { spin_unlock_irqrestore(&devlist_lock, flags); - printk(KERN_INFO "aoe: aoedev_newdev failure.\n"); + printk(KERN_INFO "aoe: aoedev_set: aoedev_newdev failure.\n"); return NULL; } d->sysminor = sysminor; @@ -171,19 +163,11 @@ aoedev_by_sysminor_m(ulong sysminor, ulong bufcnt) static void aoedev_freedev(struct aoedev *d) { - struct frame *f, *e; - if (d->gd) { aoedisk_rm_sysfs(d); del_gendisk(d->gd); put_disk(d->gd); } - f = d->frames; - e = f + d->nframes; - for (; fskb)->nr_frags = 0; - dev_kfree_skb(f->skb); - } kfree(d->frames); if (d->bufpool) mempool_destroy(d->bufpool); diff --git a/trunk/drivers/block/aoe/aoemain.c b/trunk/drivers/block/aoe/aoemain.c index a04b7d613299..de08491ebe66 100644 --- a/trunk/drivers/block/aoe/aoemain.c +++ b/trunk/drivers/block/aoe/aoemain.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2006 Coraid, Inc. See COPYING for GPL terms. */ +/* Copyright (c) 2004 Coraid, Inc. See COPYING for GPL terms. */ /* * aoemain.c * Module initialization routines, discover timer @@ -84,11 +84,13 @@ aoe_init(void) goto net_fail; ret = register_blkdev(AOE_MAJOR, DEVICE_NAME); if (ret < 0) { - printk(KERN_ERR "aoe: can't register major\n"); + printk(KERN_ERR "aoe: aoeblk_init: can't register major\n"); goto blkreg_fail; } - printk(KERN_INFO "aoe: AoE v%s initialised.\n", VERSION); + printk(KERN_INFO + "aoe: aoe_init: AoE v%s initialised.\n", + VERSION); discover_timer(TINIT); return 0; @@ -101,7 +103,7 @@ aoe_init(void) chr_fail: aoedev_exit(); - printk(KERN_INFO "aoe: initialisation failure.\n"); + printk(KERN_INFO "aoe: aoe_init: initialisation failure.\n"); return ret; } diff --git a/trunk/drivers/block/aoe/aoenet.c b/trunk/drivers/block/aoe/aoenet.c index 9626e0f5da9d..c1434ed11880 100644 --- a/trunk/drivers/block/aoe/aoenet.c +++ b/trunk/drivers/block/aoe/aoenet.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2006 Coraid, Inc. See COPYING for GPL terms. */ +/* Copyright (c) 2004 Coraid, Inc. See COPYING for GPL terms. */ /* * aoenet.c * Ethernet portion of AoE driver @@ -74,7 +74,7 @@ set_aoe_iflist(const char __user *user_str, size_t size) return -EINVAL; if (copy_from_user(aoe_iflist, user_str, size)) { - printk(KERN_INFO "aoe: copy from user failed\n"); + printk(KERN_INFO "aoe: %s: copy from user failed\n", __FUNCTION__); return -EFAULT; } aoe_iflist[size] = 0x00; @@ -132,7 +132,8 @@ aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt, if (n > NECODES) n = 0; if (net_ratelimit()) - printk(KERN_ERR "aoe: error packet from %d.%d; ecode=%d '%s'\n", + printk(KERN_ERR "aoe: aoenet_rcv: error packet from %d.%d; " + "ecode=%d '%s'\n", be16_to_cpu(h->major), h->minor, h->err, aoe_errlist[n]); goto exit; @@ -146,7 +147,7 @@ aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt, aoecmd_cfg_rsp(skb); break; default: - printk(KERN_INFO "aoe: unknown cmd %d\n", h->cmd); + printk(KERN_INFO "aoe: aoenet_rcv: unknown cmd %d\n", h->cmd); } exit: dev_kfree_skb(skb); diff --git a/trunk/drivers/block/ataflop.c b/trunk/drivers/block/ataflop.c index 14d6b9492750..c39650920bdf 100644 --- a/trunk/drivers/block/ataflop.c +++ b/trunk/drivers/block/ataflop.c @@ -342,7 +342,7 @@ static void fd_select_drive( int drive ); static void fd_deselect( void ); static void fd_motor_off_timer( unsigned long dummy ); static void check_change( unsigned long dummy ); -static irqreturn_t floppy_irq (int irq, void *dummy); +static irqreturn_t floppy_irq (int irq, void *dummy, struct pt_regs *fp); static void fd_error( void ); static int do_format(int drive, int type, struct atari_format_descr *desc); static void do_fd_action( int drive ); @@ -573,7 +573,7 @@ static inline void copy_buffer(void *from, void *to) static void (*FloppyIRQHandler)( int status ) = NULL; -static irqreturn_t floppy_irq (int irq, void *dummy) +static irqreturn_t floppy_irq (int irq, void *dummy, struct pt_regs *fp) { unsigned char status; void (*handler)( int ); diff --git a/trunk/drivers/block/cciss.c b/trunk/drivers/block/cciss.c index 4105c3bf3476..36b88f6c5f82 100644 --- a/trunk/drivers/block/cciss.c +++ b/trunk/drivers/block/cciss.c @@ -130,7 +130,7 @@ static struct board_type products[] = { static ctlr_info_t *hba[MAX_CTLR]; static void do_cciss_request(request_queue_t *q); -static irqreturn_t do_cciss_intr(int irq, void *dev_id); +static irqreturn_t do_cciss_intr(int irq, void *dev_id, struct pt_regs *regs); static int cciss_open(struct inode *inode, struct file *filep); static int cciss_release(struct inode *inode, struct file *filep); static int cciss_ioctl(struct inode *inode, struct file *filep, @@ -1300,12 +1300,6 @@ static void cciss_softirq_done(struct request *rq) complete_buffers(rq->bio, rq->errors); - if (blk_fs_request(rq)) { - const int rw = rq_data_dir(rq); - - disk_stat_add(rq->rq_disk, sectors[rw], rq->nr_sectors); - } - #ifdef CCISS_DEBUG printk("Done with %p\n", rq); #endif /* CCISS_DEBUG */ @@ -1929,6 +1923,7 @@ static void cciss_geometry_inquiry(int ctlr, int logvol, { int return_code; unsigned long t; + unsigned long rem; memset(inq_buff, 0, sizeof(InquiryData_struct)); if (withirq) @@ -1944,23 +1939,26 @@ static void cciss_geometry_inquiry(int ctlr, int logvol, printk(KERN_WARNING "cciss: reading geometry failed, volume " "does not support reading geometry\n"); + drv->block_size = block_size; + drv->nr_blocks = total_size; drv->heads = 255; drv->sectors = 32; // Sectors per track + t = drv->heads * drv->sectors; + drv->cylinders = total_size; + rem = do_div(drv->cylinders, t); } else { + drv->block_size = block_size; + drv->nr_blocks = total_size; drv->heads = inq_buff->data_byte[6]; drv->sectors = inq_buff->data_byte[7]; drv->cylinders = (inq_buff->data_byte[4] & 0xff) << 8; drv->cylinders += inq_buff->data_byte[5]; drv->raid_level = inq_buff->data_byte[8]; - } - drv->block_size = block_size; - drv->nr_blocks = total_size; - t = drv->heads * drv->sectors; - if (t > 1) { - unsigned rem = sector_div(total_size, t); - if (rem) - total_size++; - drv->cylinders = total_size; + t = drv->heads * drv->sectors; + if (t > 1) { + drv->cylinders = total_size; + rem = do_div(drv->cylinders, t); + } } } else { /* Get geometry failed */ printk(KERN_WARNING "cciss: reading geometry failed\n"); @@ -1998,8 +1996,8 @@ cciss_read_capacity(int ctlr, int logvol, int withirq, sector_t *total_size, *block_size = BLOCK_SIZE; } if (*total_size != (__u32) 0) - printk(KERN_INFO " blocks= %llu block_size= %d\n", - (unsigned long long)*total_size, *block_size); + printk(KERN_INFO " blocks= %lld block_size= %d\n", + *total_size, *block_size); kfree(buf); return; } @@ -2033,8 +2031,8 @@ cciss_read_capacity_16(int ctlr, int logvol, int withirq, sector_t *total_size, *total_size = 0; *block_size = BLOCK_SIZE; } - printk(KERN_INFO " blocks= %llu block_size= %d\n", - (unsigned long long)*total_size, *block_size); + printk(KERN_INFO " blocks= %lld block_size= %d\n", + *total_size, *block_size); kfree(buf); return; } @@ -2302,7 +2300,7 @@ static int sendcmd(__u8 cmd, int ctlr, void *buff, size_t size, unsigned int use #ifdef CONFIG_CISS_SCSI_TAPE /* if we saved some commands for later, process them now. */ if (info_p->scsi_rejects.ncompletions > 0) - do_cciss_intr(0, info_p); + do_cciss_intr(0, info_p, NULL); #endif cmd_free(info_p, c, 1); return status; @@ -2654,7 +2652,7 @@ static inline long interrupt_not_for_us(ctlr_info_t *h) #endif } -static irqreturn_t do_cciss_intr(int irq, void *dev_id) +static irqreturn_t do_cciss_intr(int irq, void *dev_id, struct pt_regs *regs) { ctlr_info_t *h = dev_id; CommandList_struct *c; diff --git a/trunk/drivers/block/cpqarray.c b/trunk/drivers/block/cpqarray.c index d5f519ebbc08..ada68e65b5ff 100644 --- a/trunk/drivers/block/cpqarray.c +++ b/trunk/drivers/block/cpqarray.c @@ -169,7 +169,7 @@ static inline cmdlist_t *removeQ(cmdlist_t **Qptr, cmdlist_t *c); static inline void complete_buffers(struct bio *bio, int ok); static inline void complete_command(cmdlist_t *cmd, int timeout); -static irqreturn_t do_ida_intr(int irq, void *dev_id); +static irqreturn_t do_ida_intr(int irq, void *dev_id, struct pt_regs * regs); static void ida_timer(unsigned long tdata); static int ida_revalidate(struct gendisk *disk); static int revalidate_allvol(ctlr_info_t *host); @@ -998,7 +998,6 @@ static inline void complete_buffers(struct bio *bio, int ok) */ static inline void complete_command(cmdlist_t *cmd, int timeout) { - struct request *rq = cmd->rq; int ok=1; int i, ddir; @@ -1030,18 +1029,12 @@ static inline void complete_command(cmdlist_t *cmd, int timeout) pci_unmap_page(hba[cmd->ctlr]->pci_dev, cmd->req.sg[i].addr, cmd->req.sg[i].size, ddir); - complete_buffers(rq->bio, ok); + complete_buffers(cmd->rq->bio, ok); - if (blk_fs_request(rq)) { - const int rw = rq_data_dir(rq); + add_disk_randomness(cmd->rq->rq_disk); - disk_stat_add(rq->rq_disk, sectors[rw], rq->nr_sectors); - } - - add_disk_randomness(rq->rq_disk); - - DBGPX(printk("Done with %p\n", rq);); - end_that_request_last(rq, ok ? 1 : -EIO); + DBGPX(printk("Done with %p\n", cmd->rq);); + end_that_request_last(cmd->rq, ok ? 1 : -EIO); } /* @@ -1049,7 +1042,7 @@ static inline void complete_command(cmdlist_t *cmd, int timeout) * Find the command on the completion queue, remove it, tell the OS and * try to queue up more IO */ -static irqreturn_t do_ida_intr(int irq, void *dev_id) +static irqreturn_t do_ida_intr(int irq, void *dev_id, struct pt_regs *regs) { ctlr_info_t *h = dev_id; cmdlist_t *c; diff --git a/trunk/drivers/block/floppy.c b/trunk/drivers/block/floppy.c index 9e6d3a87cbe3..629c5769d994 100644 --- a/trunk/drivers/block/floppy.c +++ b/trunk/drivers/block/floppy.c @@ -221,7 +221,7 @@ static DEFINE_SPINLOCK(floppy_lock); static struct completion device_release; static unsigned short virtual_dma_port = 0x3f0; -irqreturn_t floppy_interrupt(int irq, void *dev_id); +irqreturn_t floppy_interrupt(int irq, void *dev_id, struct pt_regs *regs); static int set_dor(int fdc, char mask, char data); #define K_64 0x10000 /* 64KB */ @@ -1726,7 +1726,7 @@ static void print_result(char *message, int inr) } /* interrupt handler. Note that this can be called externally on the Sparc */ -irqreturn_t floppy_interrupt(int irq, void *dev_id) +irqreturn_t floppy_interrupt(int irq, void *dev_id, struct pt_regs *regs) { void (*handler) (void) = do_floppy; int do_print; diff --git a/trunk/drivers/block/loop.c b/trunk/drivers/block/loop.c index beab6d2643cb..d6bb8da955a2 100644 --- a/trunk/drivers/block/loop.c +++ b/trunk/drivers/block/loop.c @@ -295,7 +295,7 @@ static int do_lo_send_aops(struct loop_device *lo, struct bio_vec *bvec, * and do_lo_send_write(). */ static int __do_lo_send_write(struct file *file, - u8 *buf, const int len, loff_t pos) + u8 __user *buf, const int len, loff_t pos) { ssize_t bw; mm_segment_t old_fs = get_fs(); @@ -324,7 +324,7 @@ static int do_lo_send_direct_write(struct loop_device *lo, struct bio_vec *bvec, int bsize, loff_t pos, struct page *page) { ssize_t bw = __do_lo_send_write(lo->lo_backing_file, - kmap(bvec->bv_page) + bvec->bv_offset, + (u8 __user *)kmap(bvec->bv_page) + bvec->bv_offset, bvec->bv_len, pos); kunmap(bvec->bv_page); cond_resched(); @@ -351,7 +351,7 @@ static int do_lo_send_write(struct loop_device *lo, struct bio_vec *bvec, bvec->bv_offset, bvec->bv_len, pos >> 9); if (likely(!ret)) return __do_lo_send_write(lo->lo_backing_file, - page_address(page), bvec->bv_len, + (u8 __user *)page_address(page), bvec->bv_len, pos); printk(KERN_ERR "loop: Transfer error at byte offset %llu, " "length %i.\n", (unsigned long long)pos, bvec->bv_len); @@ -1187,7 +1187,7 @@ struct compat_loop_info { * - noinlined to reduce stack space usage in main part of driver */ static noinline int -loop_info64_from_compat(const struct compat_loop_info __user *arg, +loop_info64_from_compat(const struct compat_loop_info *arg, struct loop_info64 *info64) { struct compat_loop_info info; diff --git a/trunk/drivers/block/ps2esdi.c b/trunk/drivers/block/ps2esdi.c index 688a4fb0dc99..5537974fb242 100644 --- a/trunk/drivers/block/ps2esdi.c +++ b/trunk/drivers/block/ps2esdi.c @@ -75,7 +75,8 @@ static int ps2esdi_out_cmd_blk(u_short * cmd_blk); static void ps2esdi_prep_dma(char *buffer, u_short length, u_char dma_xmode); -static irqreturn_t ps2esdi_interrupt_handler(int irq, void *dev_id); +static irqreturn_t ps2esdi_interrupt_handler(int irq, void *dev_id, + struct pt_regs *regs); static void (*current_int_handler) (u_int) = NULL; static void ps2esdi_normal_interrupt_handler(u_int); static void ps2esdi_initial_reset_int_handler(u_int); @@ -686,7 +687,8 @@ static void ps2esdi_prep_dma(char *buffer, u_short length, u_char dma_xmode) -static irqreturn_t ps2esdi_interrupt_handler(int irq, void *dev_id) +static irqreturn_t ps2esdi_interrupt_handler(int irq, void *dev_id, + struct pt_regs *regs) { u_int int_ret_code; diff --git a/trunk/drivers/block/rd.c b/trunk/drivers/block/rd.c index 485aa87e9bcd..a3f64bfe6b58 100644 --- a/trunk/drivers/block/rd.c +++ b/trunk/drivers/block/rd.c @@ -432,12 +432,6 @@ static int __init rd_init(void) rd_disks[i] = alloc_disk(1); if (!rd_disks[i]) goto out; - - rd_queue[i] = blk_alloc_queue(GFP_KERNEL); - if (!rd_queue[i]) { - put_disk(rd_disks[i]); - goto out; - } } if (register_blkdev(RAMDISK_MAJOR, "ramdisk")) { @@ -448,6 +442,10 @@ static int __init rd_init(void) for (i = 0; i < CONFIG_BLK_DEV_RAM_COUNT; i++) { struct gendisk *disk = rd_disks[i]; + rd_queue[i] = blk_alloc_queue(GFP_KERNEL); + if (!rd_queue[i]) + goto out_queue; + blk_queue_make_request(rd_queue[i], &rd_make_request); blk_queue_hardsect_size(rd_queue[i], rd_blocksize); @@ -468,6 +466,8 @@ static int __init rd_init(void) CONFIG_BLK_DEV_RAM_COUNT, rd_size, rd_blocksize); return 0; +out_queue: + unregister_blkdev(RAMDISK_MAJOR, "ramdisk"); out: while (i--) { put_disk(rd_disks[i]); diff --git a/trunk/drivers/block/swim3.c b/trunk/drivers/block/swim3.c index 1a65979f1f0f..fdc8f892eb86 100644 --- a/trunk/drivers/block/swim3.c +++ b/trunk/drivers/block/swim3.c @@ -238,8 +238,8 @@ static void scan_timeout(unsigned long data); static void seek_timeout(unsigned long data); static void settle_timeout(unsigned long data); static void xfer_timeout(unsigned long data); -static irqreturn_t swim3_interrupt(int irq, void *dev_id); -/*static void fd_dma_interrupt(int irq, void *dev_id);*/ +static irqreturn_t swim3_interrupt(int irq, void *dev_id, struct pt_regs *regs); +/*static void fd_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs);*/ static int grab_drive(struct floppy_state *fs, enum swim_state state, int interruptible); static void release_drive(struct floppy_state *fs); @@ -624,7 +624,7 @@ static void xfer_timeout(unsigned long data) start_request(fs); } -static irqreturn_t swim3_interrupt(int irq, void *dev_id) +static irqreturn_t swim3_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct floppy_state *fs = (struct floppy_state *) dev_id; struct swim3 __iomem *sw = fs->swim3; @@ -777,7 +777,7 @@ static irqreturn_t swim3_interrupt(int irq, void *dev_id) } /* -static void fd_dma_interrupt(int irq, void *dev_id) +static void fd_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs) { } */ diff --git a/trunk/drivers/block/swim_iop.c b/trunk/drivers/block/swim_iop.c index ed7b06cf3e68..dfda796eba56 100644 --- a/trunk/drivers/block/swim_iop.c +++ b/trunk/drivers/block/swim_iop.c @@ -94,7 +94,7 @@ static char *drive_names[7] = { int swimiop_init(void); static void swimiop_init_request(struct swim_iop_req *); static int swimiop_send_request(struct swim_iop_req *); -static void swimiop_receive(struct iop_msg *); +static void swimiop_receive(struct iop_msg *, struct pt_regs *); static void swimiop_status_update(int, struct swim_drvstatus *); static int swimiop_eject(struct floppy_state *fs); @@ -257,7 +257,7 @@ static int swimiop_send_request(struct swim_iop_req *req) * 2. An unsolicited message was received from the IOP. */ -void swimiop_receive(struct iop_msg *msg) +void swimiop_receive(struct iop_msg *msg, struct pt_regs *regs) { struct swim_iop_req *req; struct swimmsg_status *sm; diff --git a/trunk/drivers/block/sx8.c b/trunk/drivers/block/sx8.c index 47d6975268ff..c6beee18a07c 100644 --- a/trunk/drivers/block/sx8.c +++ b/trunk/drivers/block/sx8.c @@ -1200,7 +1200,7 @@ static inline void carm_handle_responses(struct carm_host *host) host->resp_idx += work; } -static irqreturn_t carm_interrupt(int irq, void *__host) +static irqreturn_t carm_interrupt(int irq, void *__host, struct pt_regs *regs) { struct carm_host *host = __host; void __iomem *mmio; diff --git a/trunk/drivers/block/ub.c b/trunk/drivers/block/ub.c index 0d5c73f07265..45a8f402b07b 100644 --- a/trunk/drivers/block/ub.c +++ b/trunk/drivers/block/ub.c @@ -362,7 +362,7 @@ static void ub_end_rq(struct request *rq, unsigned int status); static int ub_rw_cmd_retry(struct ub_dev *sc, struct ub_lun *lun, struct ub_request *urq, struct ub_scsi_cmd *cmd); static int ub_submit_scsi(struct ub_dev *sc, struct ub_scsi_cmd *cmd); -static void ub_urb_complete(struct urb *urb); +static void ub_urb_complete(struct urb *urb, struct pt_regs *pt); static void ub_scsi_action(unsigned long _dev); static void ub_scsi_dispatch(struct ub_dev *sc); static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd); @@ -959,7 +959,7 @@ static void ub_urb_timeout(unsigned long arg) * the sc->lock taken) and from an interrupt (while we do NOT have * the sc->lock taken). Therefore, bounce this off to a tasklet. */ -static void ub_urb_complete(struct urb *urb) +static void ub_urb_complete(struct urb *urb, struct pt_regs *pt) { struct ub_dev *sc = urb->context; @@ -1923,7 +1923,7 @@ static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun, /* */ -static void ub_probe_urb_complete(struct urb *urb) +static void ub_probe_urb_complete(struct urb *urb, struct pt_regs *pt) { struct completion *cop = urb->context; complete(cop); diff --git a/trunk/drivers/block/umem.c b/trunk/drivers/block/umem.c index 30f16bd83650..cbb9d0f21acc 100644 --- a/trunk/drivers/block/umem.c +++ b/trunk/drivers/block/umem.c @@ -571,7 +571,7 @@ static int mm_make_request(request_queue_t *q, struct bio *bio) -- mm_interrupt ----------------------------------------------------------------------------------- */ -static irqreturn_t mm_interrupt(int irq, void *__card) +static irqreturn_t mm_interrupt(int irq, void *__card, struct pt_regs *regs) { struct cardinfo *card = (struct cardinfo *) __card; unsigned int dma_status; diff --git a/trunk/drivers/block/xd.c b/trunk/drivers/block/xd.c index 0d97b7eb818a..ebf3025721d1 100644 --- a/trunk/drivers/block/xd.c +++ b/trunk/drivers/block/xd.c @@ -48,9 +48,9 @@ #include #include #include -#include #include +#include #include #include @@ -462,7 +462,8 @@ static void xd_recalibrate (u_char drive) } /* xd_interrupt_handler: interrupt service routine */ -static irqreturn_t xd_interrupt_handler(int irq, void *dev_id) +static irqreturn_t xd_interrupt_handler(int irq, void *dev_id, + struct pt_regs *regs) { if (inb(XD_STATUS) & STAT_INTERRUPT) { /* check if it was our device */ #ifdef DEBUG_OTHER diff --git a/trunk/drivers/block/xd.h b/trunk/drivers/block/xd.h index 82e090fea957..71ac2e3dffc8 100644 --- a/trunk/drivers/block/xd.h +++ b/trunk/drivers/block/xd.h @@ -109,7 +109,8 @@ static int xd_ioctl (struct inode *inode,struct file *file,unsigned int cmd,unsi static int xd_readwrite (u_char operation,XD_INFO *disk,char *buffer,u_int block,u_int count); static void xd_recalibrate (u_char drive); -static irqreturn_t xd_interrupt_handler(int irq, void *dev_id); +static irqreturn_t xd_interrupt_handler(int irq, void *dev_id, + struct pt_regs *regs); static u_char xd_setup_dma (u_char opcode,u_char *buffer,u_int count); static u_char *xd_build (u_char *cmdblk,u_char command,u_char drive,u_char head,u_short cylinder,u_char sector,u_char count,u_char control); static void xd_watchdog (unsigned long unused); diff --git a/trunk/drivers/block/z2ram.c b/trunk/drivers/block/z2ram.c index 7cc2685ca84a..82ddbdd7bd4b 100644 --- a/trunk/drivers/block/z2ram.c +++ b/trunk/drivers/block/z2ram.c @@ -329,7 +329,7 @@ static struct kobject *z2_find(dev_t dev, int *part, void *data) static struct request_queue *z2_queue; -static int __init +int __init z2_init(void) { int ret; @@ -370,7 +370,26 @@ z2_init(void) return ret; } -static void __exit z2_exit(void) +#if defined(MODULE) + +MODULE_LICENSE("GPL"); + +int +init_module( void ) +{ + int error; + + error = z2_init(); + if ( error == 0 ) + { + printk( KERN_INFO DEVICE_NAME ": loaded as module\n" ); + } + + return error; +} + +void +cleanup_module( void ) { int i, j; blk_unregister_region(MKDEV(Z2RAM_MAJOR, 0), 256); @@ -406,7 +425,4 @@ static void __exit z2_exit(void) return; } - -module_init(z2_init); -module_exit(z2_exit); -MODULE_LICENSE("GPL"); +#endif diff --git a/trunk/drivers/bluetooth/bcm203x.c b/trunk/drivers/bluetooth/bcm203x.c index 516751754aa9..13ba729cdd57 100644 --- a/trunk/drivers/bluetooth/bcm203x.c +++ b/trunk/drivers/bluetooth/bcm203x.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -42,7 +43,7 @@ #define BT_DBG(D...) #endif -#define VERSION "1.1" +#define VERSION "1.0" static int ignore = 0; @@ -71,7 +72,7 @@ struct bcm203x_data { unsigned long state; - struct work_struct work; + struct timer_list timer; struct urb *urb; unsigned char *buffer; @@ -81,7 +82,7 @@ struct bcm203x_data { unsigned int fw_sent; }; -static void bcm203x_complete(struct urb *urb) +static void bcm203x_complete(struct urb *urb, struct pt_regs *regs) { struct bcm203x_data *data = urb->context; struct usb_device *udev = urb->dev; @@ -104,7 +105,7 @@ static void bcm203x_complete(struct urb *urb) data->state = BCM203X_SELECT_MEMORY; - schedule_work(&data->work); + mod_timer(&data->timer, jiffies + (HZ / 10)); break; case BCM203X_SELECT_MEMORY: @@ -157,9 +158,9 @@ static void bcm203x_complete(struct urb *urb) } } -static void bcm203x_work(void *user_data) +static void bcm203x_timer(unsigned long user_data) { - struct bcm203x_data *data = user_data; + struct bcm203x_data *data = (struct bcm203x_data *) user_data; if (usb_submit_urb(data->urb, GFP_ATOMIC) < 0) BT_ERR("Can't submit URB"); @@ -246,11 +247,13 @@ static int bcm203x_probe(struct usb_interface *intf, const struct usb_device_id release_firmware(firmware); - INIT_WORK(&data->work, bcm203x_work, (void *) data); + init_timer(&data->timer); + data->timer.function = bcm203x_timer; + data->timer.data = (unsigned long) data; usb_set_intfdata(intf, data); - schedule_work(&data->work); + mod_timer(&data->timer, jiffies + HZ); return 0; } diff --git a/trunk/drivers/bluetooth/bfusb.c b/trunk/drivers/bluetooth/bfusb.c index 31ade991aa91..efcc28ec9d9a 100644 --- a/trunk/drivers/bluetooth/bfusb.c +++ b/trunk/drivers/bluetooth/bfusb.c @@ -95,8 +95,8 @@ struct bfusb_data_scb { struct urb *urb; }; -static void bfusb_tx_complete(struct urb *urb); -static void bfusb_rx_complete(struct urb *urb); +static void bfusb_tx_complete(struct urb *urb, struct pt_regs *regs); +static void bfusb_rx_complete(struct urb *urb, struct pt_regs *regs); static struct urb *bfusb_get_completed(struct bfusb_data *data) { @@ -190,7 +190,7 @@ static void bfusb_tx_wakeup(struct bfusb_data *data) clear_bit(BFUSB_TX_PROCESS, &data->state); } -static void bfusb_tx_complete(struct urb *urb) +static void bfusb_tx_complete(struct urb *urb, struct pt_regs *regs) { struct sk_buff *skb = (struct sk_buff *) urb->context; struct bfusb_data *data = (struct bfusb_data *) skb->dev; @@ -349,7 +349,7 @@ static inline int bfusb_recv_block(struct bfusb_data *data, int hdr, unsigned ch return 0; } -static void bfusb_rx_complete(struct urb *urb) +static void bfusb_rx_complete(struct urb *urb, struct pt_regs *regs) { struct sk_buff *skb = (struct sk_buff *) urb->context; struct bfusb_data *data = (struct bfusb_data *) skb->dev; diff --git a/trunk/drivers/bluetooth/bluecard_cs.c b/trunk/drivers/bluetooth/bluecard_cs.c index cbc07250b898..8eebf9ca3786 100644 --- a/trunk/drivers/bluetooth/bluecard_cs.c +++ b/trunk/drivers/bluetooth/bluecard_cs.c @@ -282,7 +282,7 @@ static void bluecard_write_wakeup(bluecard_info_t *info) clear_bit(ready_bit, &(info->tx_state)); if (bt_cb(skb)->pkt_type & 0x80) { - DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq); + DECLARE_WAIT_QUEUE_HEAD(wq); DEFINE_WAIT(wait); unsigned char baud_reg; @@ -497,7 +497,7 @@ static void bluecard_receive(bluecard_info_t *info, unsigned int offset) } -static irqreturn_t bluecard_interrupt(int irq, void *dev_inst) +static irqreturn_t bluecard_interrupt(int irq, void *dev_inst, struct pt_regs *regs) { bluecard_info_t *info = dev_inst; unsigned int iobase; diff --git a/trunk/drivers/bluetooth/bpa10x.c b/trunk/drivers/bluetooth/bpa10x.c index 9fca6513562d..e0231dc2cb1a 100644 --- a/trunk/drivers/bluetooth/bpa10x.c +++ b/trunk/drivers/bluetooth/bpa10x.c @@ -263,7 +263,7 @@ static void bpa10x_wakeup(struct bpa10x_data *data) } } -static void bpa10x_complete(struct urb *urb) +static void bpa10x_complete(struct urb *urb, struct pt_regs *regs) { struct bpa10x_data *data = urb->context; unsigned char *buf = urb->transfer_buffer; diff --git a/trunk/drivers/bluetooth/bt3c_cs.c b/trunk/drivers/bluetooth/bt3c_cs.c index 3a96a0babc6a..df7bb016df49 100644 --- a/trunk/drivers/bluetooth/bt3c_cs.c +++ b/trunk/drivers/bluetooth/bt3c_cs.c @@ -338,7 +338,7 @@ static void bt3c_receive(bt3c_info_t *info) } -static irqreturn_t bt3c_interrupt(int irq, void *dev_inst) +static irqreturn_t bt3c_interrupt(int irq, void *dev_inst, struct pt_regs *regs) { bt3c_info_t *info = dev_inst; unsigned int iobase; diff --git a/trunk/drivers/bluetooth/btuart_cs.c b/trunk/drivers/bluetooth/btuart_cs.c index 3b29086b7c3f..746ccca97f6f 100644 --- a/trunk/drivers/bluetooth/btuart_cs.c +++ b/trunk/drivers/bluetooth/btuart_cs.c @@ -288,7 +288,7 @@ static void btuart_receive(btuart_info_t *info) } -static irqreturn_t btuart_interrupt(int irq, void *dev_inst) +static irqreturn_t btuart_interrupt(int irq, void *dev_inst, struct pt_regs *regs) { btuart_info_t *info = dev_inst; unsigned int iobase; diff --git a/trunk/drivers/bluetooth/dtl1_cs.c b/trunk/drivers/bluetooth/dtl1_cs.c index 07eafbc5dc3a..0e99def8a1e3 100644 --- a/trunk/drivers/bluetooth/dtl1_cs.c +++ b/trunk/drivers/bluetooth/dtl1_cs.c @@ -291,7 +291,7 @@ static void dtl1_receive(dtl1_info_t *info) } -static irqreturn_t dtl1_interrupt(int irq, void *dev_inst) +static irqreturn_t dtl1_interrupt(int irq, void *dev_inst, struct pt_regs *regs) { dtl1_info_t *info = dev_inst; unsigned int iobase; @@ -711,7 +711,6 @@ static void dtl1_release(struct pcmcia_device *link) static struct pcmcia_device_id dtl1_ids[] = { PCMCIA_DEVICE_PROD_ID12("Nokia Mobile Phones", "DTL-1", 0xe1bfdd64, 0xe168480d), - PCMCIA_DEVICE_PROD_ID12("Nokia Mobile Phones", "DTL-4", 0xe1bfdd64, 0x9102bc82), PCMCIA_DEVICE_PROD_ID12("Socket", "CF", 0xb38bcc2e, 0x44ebf863), PCMCIA_DEVICE_PROD_ID12("Socket", "CF+ Personal Network Card", 0xb38bcc2e, 0xe732bae3), PCMCIA_DEVICE_NULL diff --git a/trunk/drivers/bluetooth/hci_usb.c b/trunk/drivers/bluetooth/hci_usb.c index fdea58ae16b2..0801af4ad2b9 100644 --- a/trunk/drivers/bluetooth/hci_usb.c +++ b/trunk/drivers/bluetooth/hci_usb.c @@ -118,9 +118,6 @@ static struct usb_device_id blacklist_ids[] = { /* IBM/Lenovo ThinkPad with Broadcom chip */ { USB_DEVICE(0x0a5c, 0x201e), .driver_info = HCI_WRONG_SCO_MTU }, - /* ANYCOM Bluetooth USB-200 and USB-250 */ - { USB_DEVICE(0x0a5c, 0x2111), .driver_info = HCI_RESET }, - /* Microsoft Wireless Transceiver for Bluetooth 2.0 */ { USB_DEVICE(0x045e, 0x009c), .driver_info = HCI_RESET }, @@ -179,8 +176,8 @@ static struct _urb *_urb_dequeue(struct _urb_queue *q) return _urb; } -static void hci_usb_rx_complete(struct urb *urb); -static void hci_usb_tx_complete(struct urb *urb); +static void hci_usb_rx_complete(struct urb *urb, struct pt_regs *regs); +static void hci_usb_tx_complete(struct urb *urb, struct pt_regs *regs); #define __pending_tx(husb, type) (&husb->pending_tx[type-1]) #define __pending_q(husb, type) (&husb->pending_q[type-1]) @@ -735,7 +732,7 @@ static inline int __recv_frame(struct hci_usb *husb, int type, void *data, int c return 0; } -static void hci_usb_rx_complete(struct urb *urb) +static void hci_usb_rx_complete(struct urb *urb, struct pt_regs *regs) { struct _urb *_urb = container_of(urb, struct _urb, urb); struct hci_usb *husb = (void *) urb->context; @@ -789,7 +786,7 @@ static void hci_usb_rx_complete(struct urb *urb) read_unlock(&husb->completion_lock); } -static void hci_usb_tx_complete(struct urb *urb) +static void hci_usb_tx_complete(struct urb *urb, struct pt_regs *regs) { struct _urb *_urb = container_of(urb, struct _urb, urb); struct hci_usb *husb = (void *) urb->context; diff --git a/trunk/drivers/cdrom/cdrom.c b/trunk/drivers/cdrom/cdrom.c index 2df5cf4ec743..2a0c50d84fc5 100644 --- a/trunk/drivers/cdrom/cdrom.c +++ b/trunk/drivers/cdrom/cdrom.c @@ -703,7 +703,7 @@ static int cdrom_has_defect_mgt(struct cdrom_device_info *cdi) { struct packet_command cgc; char buffer[16]; - __be16 *feature_code; + __u16 *feature_code; int ret; init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ); @@ -716,7 +716,7 @@ static int cdrom_has_defect_mgt(struct cdrom_device_info *cdi) if ((ret = cdi->ops->generic_packet(cdi, &cgc))) return ret; - feature_code = (__be16 *) &buffer[sizeof(struct feature_header)]; + feature_code = (__u16 *) &buffer[sizeof(struct feature_header)]; if (be16_to_cpu(*feature_code) == CDF_HWDM) return 0; @@ -2133,14 +2133,16 @@ static int cdrom_read_cdda_bpc(struct cdrom_device_info *cdi, __u8 __user *ubuf, rq->timeout = 60 * HZ; bio = rq->bio; + if (rq->bio) + blk_queue_bounce(q, &rq->bio); + if (blk_execute_rq(q, cdi->disk, rq, 0)) { struct request_sense *s = rq->sense; ret = -EIO; cdi->last_sense = s->sense_key; } - rq->bio = bio; - if (blk_rq_unmap_user(rq)) + if (blk_rq_unmap_user(bio, len)) ret = -EFAULT; if (ret) @@ -2961,7 +2963,7 @@ static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, how much data is available for transfer. buffer[1] is unfortunately ambigious and the only reliable way seem to be to simply skip over the block descriptor... */ - offset = 8 + be16_to_cpu(*(__be16 *)(buffer+6)); + offset = 8 + be16_to_cpu(*(unsigned short *)(buffer+6)); if (offset + 16 > sizeof(buffer)) return -E2BIG; diff --git a/trunk/drivers/cdrom/cdu31a.c b/trunk/drivers/cdrom/cdu31a.c index 2157c58755e0..ccd91c1a84bd 100644 --- a/trunk/drivers/cdrom/cdu31a.c +++ b/trunk/drivers/cdrom/cdu31a.c @@ -513,7 +513,7 @@ static inline void write_cmd(unsigned char cmd) outb(cmd, sony_cd_cmd_reg); } -static irqreturn_t cdu31a_interrupt(int irq, void *dev_id) +static irqreturn_t cdu31a_interrupt(int irq, void *dev_id, struct pt_regs *regs) { unsigned char val; diff --git a/trunk/drivers/cdrom/cm206.c b/trunk/drivers/cdrom/cm206.c index e6d8e9ededea..9b05ddd23141 100644 --- a/trunk/drivers/cdrom/cm206.c +++ b/trunk/drivers/cdrom/cm206.c @@ -359,7 +359,7 @@ static struct tasklet_struct cm206_tasklet; as there seems so reason for this to happen. */ -static irqreturn_t cm206_interrupt(int sig, void *dev_id) +static irqreturn_t cm206_interrupt(int sig, void *dev_id, struct pt_regs *regs) { volatile ush fool; cd->intr_ds = inw(r_data_status); /* resets data_ready, data_error, diff --git a/trunk/drivers/cdrom/mcdx.c b/trunk/drivers/cdrom/mcdx.c index f574962f4288..dcd1ab684f3e 100644 --- a/trunk/drivers/cdrom/mcdx.c +++ b/trunk/drivers/cdrom/mcdx.c @@ -845,11 +845,15 @@ static void mcdx_delay(struct s_drive_stuff *stuff, long jifs) } } -static irqreturn_t mcdx_intr(int irq, void *dev_id) +static irqreturn_t mcdx_intr(int irq, void *dev_id, struct pt_regs *regs) { struct s_drive_stuff *stuffp = dev_id; unsigned char b; + if (stuffp == NULL) { + xwarn("mcdx: no device for intr %d\n", irq); + return IRQ_NONE; + } #ifdef AK2 if (!stuffp->busy && stuffp->pending) stuffp->int_err = 1; diff --git a/trunk/drivers/cdrom/sonycd535.c b/trunk/drivers/cdrom/sonycd535.c index f77ada933ea0..30ab56258a92 100644 --- a/trunk/drivers/cdrom/sonycd535.c +++ b/trunk/drivers/cdrom/sonycd535.c @@ -322,7 +322,7 @@ disable_interrupts(void) } static irqreturn_t -cdu535_interrupt(int irq, void *dev_id) +cdu535_interrupt(int irq, void *dev_id, struct pt_regs *regs) { disable_interrupts(); if (waitqueue_active(&cdu535_irq_wait)) { diff --git a/trunk/drivers/char/Kconfig b/trunk/drivers/char/Kconfig index ad8b537ad47b..0e6f35fcc2eb 100644 --- a/trunk/drivers/char/Kconfig +++ b/trunk/drivers/char/Kconfig @@ -409,6 +409,14 @@ config SGI_MBCS If you have an SGI Altix with an attached SABrick say Y or M here, otherwise say N. +config MSPEC + tristate "Memory special operations driver" + depends on IA64 + help + If you have an ia64 and you want to enable memory special + operations support (formerly known as fetchop), say Y here, + otherwise say N. + source "drivers/serial/Kconfig" config UNIX98_PTYS @@ -994,7 +1002,7 @@ config HPET help If you say Y here, you will have a miscdevice named "/dev/hpet/". Each open selects one of the timers supported by the HPET. The timers are - non-periodic and/or periodic. + non-periodioc and/or periodic. config HPET_RTC_IRQ bool "HPET Control RTC IRQ" if !HPET_EMULATE_RTC @@ -1038,7 +1046,7 @@ source "drivers/char/tpm/Kconfig" config TELCLOCK tristate "Telecom clock driver for MPBL0010 ATCA SBC" - depends on EXPERIMENTAL && X86 + depends on EXPERIMENTAL default n help The telecom clock device is specific to the MPBL0010 ATCA computer and diff --git a/trunk/drivers/char/agp/generic.c b/trunk/drivers/char/agp/generic.c index 5ff457b41efb..c39200161688 100644 --- a/trunk/drivers/char/agp/generic.c +++ b/trunk/drivers/char/agp/generic.c @@ -1054,7 +1054,7 @@ void *agp_generic_alloc_page(struct agp_bridge_data *bridge) { struct page * page; - page = alloc_page(GFP_KERNEL | GFP_DMA32); + page = alloc_page(GFP_KERNEL); if (page == NULL) return NULL; diff --git a/trunk/drivers/char/agp/intel-agp.c b/trunk/drivers/char/agp/intel-agp.c index 555b3a8ab49c..d1ede7db5a12 100644 --- a/trunk/drivers/char/agp/intel-agp.c +++ b/trunk/drivers/char/agp/intel-agp.c @@ -169,7 +169,7 @@ static void *i8xx_alloc_pages(void) { struct page * page; - page = alloc_pages(GFP_KERNEL | GFP_DMA32, 2); + page = alloc_pages(GFP_KERNEL, 2); if (page == NULL) return NULL; @@ -387,7 +387,11 @@ static void intel_i830_init_gtt_entries(void) /* We obtain the size of the GTT, which is also stored (for some * reason) at the top of stolen memory. Then we add 4KB to that * for the video BIOS popup, which is also stored in there. */ - size = agp_bridge->driver->fetch_size() + 4; + + if (IS_I965) + size = 512 + 4; + else + size = agp_bridge->driver->fetch_size() + 4; if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82830_HB || agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82845G_HB) { @@ -801,26 +805,6 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge) return 0; } - -/* - * The i965 supports 36-bit physical addresses, but to keep - * the format of the GTT the same, the bits that don't fit - * in a 32-bit word are shifted down to bits 4..7. - * - * Gcc is smart enough to notice that "(addr >> 28) & 0xf0" - * is always zero on 32-bit architectures, so no need to make - * this conditional. - */ -static unsigned long intel_i965_mask_memory(struct agp_bridge_data *bridge, - unsigned long addr, int type) -{ - /* Shift high bits down */ - addr |= (addr >> 28) & 0xf0; - - /* Type checking must be done elsewhere */ - return addr | bridge->driver->masks[type].mask; -} - static int intel_i965_fetch_size(void) { struct aper_size_info_fixed *values; @@ -848,8 +832,7 @@ static int intel_i965_fetch_size(void) agp_bridge->previous_size = agp_bridge->current_size = (void *)(values + offset); - /* The i965 GTT is always sized as if it had a 512kB aperture size */ - return 512; + return values[offset].size; } /* The intel i965 automatically initializes the agp aperture during POST. @@ -1601,7 +1584,7 @@ static struct agp_bridge_driver intel_i965_driver = { .fetch_size = intel_i965_fetch_size, .cleanup = intel_i915_cleanup, .tlb_flush = intel_i810_tlbflush, - .mask_memory = intel_i965_mask_memory, + .mask_memory = intel_i810_mask_memory, .masks = intel_i810_masks, .agp_enable = intel_i810_agp_enable, .cache_flush = global_cache_flush, diff --git a/trunk/drivers/char/agp/uninorth-agp.c b/trunk/drivers/char/agp/uninorth-agp.c index dffc19382f7e..91b71e750ee1 100644 --- a/trunk/drivers/char/agp/uninorth-agp.c +++ b/trunk/drivers/char/agp/uninorth-agp.c @@ -27,42 +27,32 @@ static int uninorth_rev; static int is_u3; -static char __devinitdata *aperture = NULL; static int uninorth_fetch_size(void) { - int i, size = 0; - struct aper_size_info_32 *values = - A_SIZE_32(agp_bridge->driver->aperture_sizes); - - if (aperture) { - char *save = aperture; - - size = memparse(aperture, &aperture) >> 20; - aperture = save; - - for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) - if (size == values[i].size) - break; - - if (i == agp_bridge->driver->num_aperture_sizes) { - printk(KERN_ERR PFX "Invalid aperture size, using" - " default\n"); - size = 0; - aperture = NULL; + int i; + u32 temp; + struct aper_size_info_32 *values; + + pci_read_config_dword(agp_bridge->dev, UNI_N_CFG_GART_BASE, &temp); + temp &= ~(0xfffff000); + values = A_SIZE_32(agp_bridge->driver->aperture_sizes); + + for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) { + if (temp == values[i].size_value) { + agp_bridge->previous_size = + agp_bridge->current_size = (void *) (values + i); + agp_bridge->aperture_size_idx = i; + return values[i].size; } } - if (!size) { - for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) - if (values[i].size == 32) - break; - } - agp_bridge->previous_size = - agp_bridge->current_size = (void *)(values + i); - agp_bridge->aperture_size_idx = i; - return values[i].size; + agp_bridge->current_size = (void *) (values + 1); + agp_bridge->aperture_size_idx = 1; + return values[1].size; + + return 0; } static void uninorth_tlbflush(struct agp_memory *mem) @@ -693,11 +683,5 @@ static void __exit agp_uninorth_cleanup(void) module_init(agp_uninorth_init); module_exit(agp_uninorth_cleanup); -module_param(aperture, charp, 0); -MODULE_PARM_DESC(aperture, - "Aperture size, must be power of two between 4MB and an\n" - "\t\tupper limit specific to the UniNorth revision.\n" - "\t\tDefault: 32M"); - MODULE_AUTHOR("Ben Herrenschmidt & Paul Mackerras"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/char/amiserial.c b/trunk/drivers/char/amiserial.c index 66086fa2d59a..486f97c3f4e5 100644 --- a/trunk/drivers/char/amiserial.c +++ b/trunk/drivers/char/amiserial.c @@ -447,7 +447,7 @@ static void check_modem_status(struct async_struct *info) } } -static irqreturn_t ser_vbl_int( int irq, void *data) +static irqreturn_t ser_vbl_int( int irq, void *data, struct pt_regs *regs) { /* vbl is just a periodic interrupt we tie into to update modem status */ struct async_struct * info = IRQ_ports; @@ -460,7 +460,7 @@ static irqreturn_t ser_vbl_int( int irq, void *data) return IRQ_HANDLED; } -static irqreturn_t ser_rx_int(int irq, void *dev_id) +static irqreturn_t ser_rx_int(int irq, void *dev_id, struct pt_regs * regs) { struct async_struct * info; @@ -480,7 +480,7 @@ static irqreturn_t ser_rx_int(int irq, void *dev_id) return IRQ_HANDLED; } -static irqreturn_t ser_tx_int(int irq, void *dev_id) +static irqreturn_t ser_tx_int(int irq, void *dev_id, struct pt_regs * regs) { struct async_struct * info; diff --git a/trunk/drivers/char/applicom.c b/trunk/drivers/char/applicom.c index 1f0b752e5de1..10a389dafd60 100644 --- a/trunk/drivers/char/applicom.c +++ b/trunk/drivers/char/applicom.c @@ -110,7 +110,7 @@ static ssize_t ac_read (struct file *, char __user *, size_t, loff_t *); static ssize_t ac_write (struct file *, const char __user *, size_t, loff_t *); static int ac_ioctl(struct inode *, struct file *, unsigned int, unsigned long); -static irqreturn_t ac_interrupt(int, void *); +static irqreturn_t ac_interrupt(int, void *, struct pt_regs *); static const struct file_operations ac_fops = { .owner = THIS_MODULE, @@ -617,7 +617,7 @@ static ssize_t ac_read (struct file *filp, char __user *buf, size_t count, loff_ } } -static irqreturn_t ac_interrupt(int vec, void *dev_instance) +static irqreturn_t ac_interrupt(int vec, void *dev_instance, struct pt_regs *regs) { unsigned int i; unsigned int FlagInt; diff --git a/trunk/drivers/char/cyclades.c b/trunk/drivers/char/cyclades.c index e608dadece2f..87b2fb510871 100644 --- a/trunk/drivers/char/cyclades.c +++ b/trunk/drivers/char/cyclades.c @@ -1057,7 +1057,7 @@ detect_isa_irq(void __iomem *address) received, out buffer empty, modem change, etc. */ static irqreturn_t -cyy_interrupt(int irq, void *dev_id) +cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct tty_struct *tty; int status; @@ -1802,7 +1802,7 @@ cyz_handle_cmd(struct cyclades_card *cinfo) #ifdef CONFIG_CYZ_INTR static irqreturn_t -cyz_interrupt(int irq, void *dev_id) +cyz_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct cyclades_card *cinfo; diff --git a/trunk/drivers/char/drm/drm_bufs.c b/trunk/drivers/char/drm/drm_bufs.c index 6eafff13dab6..029baea33b62 100644 --- a/trunk/drivers/char/drm/drm_bufs.c +++ b/trunk/drivers/char/drm/drm_bufs.c @@ -237,8 +237,6 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset, list = drm_alloc(sizeof(*list), DRM_MEM_MAPS); if (!list) { - if (map->type == _DRM_REGISTERS) - drm_ioremapfree(map->handle, map->size, dev); drm_free(map, sizeof(*map), DRM_MEM_MAPS); return -EINVAL; } @@ -254,8 +252,6 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset, map->offset; ret = drm_map_handle(dev, &list->hash, user_token, 0); if (ret) { - if (map->type == _DRM_REGISTERS) - drm_ioremapfree(map->handle, map->size, dev); drm_free(map, sizeof(*map), DRM_MEM_MAPS); drm_free(list, sizeof(*list), DRM_MEM_MAPS); mutex_unlock(&dev->struct_mutex); diff --git a/trunk/drivers/char/drm/drm_os_linux.h b/trunk/drivers/char/drm/drm_os_linux.h index 2908b72daa6e..695115d70382 100644 --- a/trunk/drivers/char/drm/drm_os_linux.h +++ b/trunk/drivers/char/drm/drm_os_linux.h @@ -38,7 +38,7 @@ drm_device_t *dev = priv->head->dev /** IRQ handler arguments and return type and values */ -#define DRM_IRQ_ARGS int irq, void *arg +#define DRM_IRQ_ARGS int irq, void *arg, struct pt_regs *regs /** AGP types */ #if __OS_HAS_AGP diff --git a/trunk/drivers/char/drm/drm_sysfs.c b/trunk/drivers/char/drm/drm_sysfs.c index ba4b8de83cf0..51ad98c685c3 100644 --- a/trunk/drivers/char/drm/drm_sysfs.c +++ b/trunk/drivers/char/drm/drm_sysfs.c @@ -42,24 +42,13 @@ static CLASS_ATTR(version, S_IRUGO, version_show, NULL); struct class *drm_sysfs_create(struct module *owner, char *name) { struct class *class; - int err; class = class_create(owner, name); - if (!class) { - err = -ENOMEM; - goto err_out; - } - - err = class_create_file(class, &class_attr_version); - if (err) - goto err_out_class; + if (!class) + return class; + class_create_file(class, &class_attr_version); return class; - -err_out_class: - class_destroy(class); -err_out: - return ERR_PTR(err); } /** @@ -107,36 +96,20 @@ static struct class_device_attribute class_device_attrs[] = { struct class_device *drm_sysfs_device_add(struct class *cs, drm_head_t *head) { struct class_device *class_dev; - int i, j, err; + int i; class_dev = class_device_create(cs, NULL, MKDEV(DRM_MAJOR, head->minor), &(head->dev->pdev)->dev, "card%d", head->minor); - if (!class_dev) { - err = -ENOMEM; - goto err_out; - } + if (!class_dev) + return NULL; class_set_devdata(class_dev, head); - for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) { - err = class_device_create_file(class_dev, - &class_device_attrs[i]); - if (err) - goto err_out_files; - } - + for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) + class_device_create_file(class_dev, &class_device_attrs[i]); return class_dev; - -err_out_files: - if (i > 0) - for (j = 0; j < i; j++) - class_device_remove_file(class_dev, - &class_device_attrs[i]); - class_device_unregister(class_dev); -err_out: - return ERR_PTR(err); } /** diff --git a/trunk/drivers/char/drm/mga_drv.c b/trunk/drivers/char/drm/mga_drv.c index be49dbb9ec3f..e30f556b79f1 100644 --- a/trunk/drivers/char/drm/mga_drv.c +++ b/trunk/drivers/char/drm/mga_drv.c @@ -47,7 +47,6 @@ static struct drm_driver driver = { DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL, - .dev_priv_size = sizeof(drm_mga_buf_priv_t), .load = mga_driver_load, .unload = mga_driver_unload, .lastclose = mga_driver_lastclose, diff --git a/trunk/drivers/char/drm/r300_cmdbuf.c b/trunk/drivers/char/drm/r300_cmdbuf.c index d14477ba3679..26bdf2ca59d7 100644 --- a/trunk/drivers/char/drm/r300_cmdbuf.c +++ b/trunk/drivers/char/drm/r300_cmdbuf.c @@ -538,36 +538,6 @@ static __inline__ int r300_emit_bitblt_multi(drm_radeon_private_t *dev_priv, return 0; } -static __inline__ int r300_emit_indx_buffer(drm_radeon_private_t *dev_priv, - drm_radeon_kcmd_buffer_t *cmdbuf) -{ - u32 *cmd = (u32 *) cmdbuf->buf; - int count, ret; - RING_LOCALS; - - count=(cmd[0]>>16) & 0x3fff; - - if ((cmd[1] & 0x8000ffff) != 0x80000810) { - DRM_ERROR("Invalid indx_buffer reg address %08X\n", cmd[1]); - return DRM_ERR(EINVAL); - } - ret = r300_check_offset(dev_priv, cmd[2]); - if (ret) { - DRM_ERROR("Invalid indx_buffer offset is %08X\n", cmd[2]); - return DRM_ERR(EINVAL); - } - - BEGIN_RING(count+2); - OUT_RING(cmd[0]); - OUT_RING_TABLE((int *)(cmdbuf->buf + 4), count + 1); - ADVANCE_RING(); - - cmdbuf->buf += (count+2)*4; - cmdbuf->bufsz -= (count+2)*4; - - return 0; -} - static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t *dev_priv, drm_radeon_kcmd_buffer_t *cmdbuf) { @@ -608,11 +578,10 @@ static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t *dev_priv, case RADEON_CNTL_BITBLT_MULTI: return r300_emit_bitblt_multi(dev_priv, cmdbuf); - case RADEON_CP_INDX_BUFFER: /* DRAW_INDX_2 without INDX_BUFFER seems to lock up the gpu */ - return r300_emit_indx_buffer(dev_priv, cmdbuf); case RADEON_CP_3D_DRAW_IMMD_2: /* triggers drawing using in-packet vertex data */ case RADEON_CP_3D_DRAW_VBUF_2: /* triggers drawing of vertex buffers setup elsewhere */ case RADEON_CP_3D_DRAW_INDX_2: /* triggers drawing using indices to vertex buffer */ + case RADEON_CP_INDX_BUFFER: /* DRAW_INDX_2 without INDX_BUFFER seems to lock up the gpu */ case RADEON_WAIT_FOR_IDLE: case RADEON_CP_NOP: /* these packets are safe */ diff --git a/trunk/drivers/char/drm/radeon_state.c b/trunk/drivers/char/drm/radeon_state.c index 6e04fdd732ac..feac5f005d47 100644 --- a/trunk/drivers/char/drm/radeon_state.c +++ b/trunk/drivers/char/drm/radeon_state.c @@ -275,8 +275,6 @@ static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t * unsigned int *cmdsz) { u32 *cmd = (u32 *) cmdbuf->buf; - u32 offset, narrays; - int count, i, k; *cmdsz = 2 + ((cmd[0] & RADEON_CP_PACKET_COUNT_MASK) >> 16); @@ -290,106 +288,10 @@ static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t * return DRM_ERR(EINVAL); } - switch(cmd[0] & 0xff00) { - /* XXX Are there old drivers needing other packets? */ + /* Check client state and fix it up if necessary */ + if (cmd[0] & 0x8000) { /* MSB of opcode: next DWORD GUI_CNTL */ + u32 offset; - case RADEON_3D_DRAW_IMMD: - case RADEON_3D_DRAW_VBUF: - case RADEON_3D_DRAW_INDX: - case RADEON_WAIT_FOR_IDLE: - case RADEON_CP_NOP: - case RADEON_3D_CLEAR_ZMASK: -/* case RADEON_CP_NEXT_CHAR: - case RADEON_CP_PLY_NEXTSCAN: - case RADEON_CP_SET_SCISSORS: */ /* probably safe but will never need them? */ - /* these packets are safe */ - break; - - case RADEON_CP_3D_DRAW_IMMD_2: - case RADEON_CP_3D_DRAW_VBUF_2: - case RADEON_CP_3D_DRAW_INDX_2: - case RADEON_3D_CLEAR_HIZ: - /* safe but r200 only */ - if (dev_priv->microcode_version != UCODE_R200) { - DRM_ERROR("Invalid 3d packet for r100-class chip\n"); - return DRM_ERR(EINVAL); - } - break; - - case RADEON_3D_LOAD_VBPNTR: - count = (cmd[0] >> 16) & 0x3fff; - - if (count > 18) { /* 12 arrays max */ - DRM_ERROR("Too large payload in 3D_LOAD_VBPNTR (count=%d)\n", - count); - return DRM_ERR(EINVAL); - } - - /* carefully check packet contents */ - narrays = cmd[1] & ~0xc000; - k = 0; - i = 2; - while ((k < narrays) && (i < (count + 2))) { - i++; /* skip attribute field */ - if (radeon_check_and_fixup_offset(dev_priv, filp_priv, &cmd[i])) { - DRM_ERROR - ("Invalid offset (k=%d i=%d) in 3D_LOAD_VBPNTR packet.\n", - k, i); - return DRM_ERR(EINVAL); - } - k++; - i++; - if (k == narrays) - break; - /* have one more to process, they come in pairs */ - if (radeon_check_and_fixup_offset(dev_priv, filp_priv, &cmd[i])) { - DRM_ERROR - ("Invalid offset (k=%d i=%d) in 3D_LOAD_VBPNTR packet.\n", - k, i); - return DRM_ERR(EINVAL); - } - k++; - i++; - } - /* do the counts match what we expect ? */ - if ((k != narrays) || (i != (count + 2))) { - DRM_ERROR - ("Malformed 3D_LOAD_VBPNTR packet (k=%d i=%d narrays=%d count+1=%d).\n", - k, i, narrays, count + 1); - return DRM_ERR(EINVAL); - } - break; - - case RADEON_3D_RNDR_GEN_INDX_PRIM: - if (dev_priv->microcode_version != UCODE_R100) { - DRM_ERROR("Invalid 3d packet for r200-class chip\n"); - return DRM_ERR(EINVAL); - } - if (radeon_check_and_fixup_offset(dev_priv, filp_priv, &cmd[1])) { - DRM_ERROR("Invalid rndr_gen_indx offset\n"); - return DRM_ERR(EINVAL); - } - break; - - case RADEON_CP_INDX_BUFFER: - if (dev_priv->microcode_version != UCODE_R200) { - DRM_ERROR("Invalid 3d packet for r100-class chip\n"); - return DRM_ERR(EINVAL); - } - if ((cmd[1] & 0x8000ffff) != 0x80000810) { - DRM_ERROR("Invalid indx_buffer reg address %08X\n", cmd[1]); - return DRM_ERR(EINVAL); - } - if (radeon_check_and_fixup_offset(dev_priv, filp_priv, &cmd[2])) { - DRM_ERROR("Invalid indx_buffer offset is %08X\n", cmd[2]); - return DRM_ERR(EINVAL); - } - break; - - case RADEON_CNTL_HOSTDATA_BLT: - case RADEON_CNTL_PAINT_MULTI: - case RADEON_CNTL_BITBLT_MULTI: - /* MSB of opcode: next DWORD GUI_CNTL */ if (cmd[1] & (RADEON_GMC_SRC_PITCH_OFFSET_CNTL | RADEON_GMC_DST_PITCH_OFFSET_CNTL)) { offset = cmd[2] << 10; @@ -411,11 +313,6 @@ static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t * } cmd[3] = (cmd[3] & 0xffc00000) | offset >> 10; } - break; - - default: - DRM_ERROR("Invalid packet type %x\n", cmd[0] & 0xff00); - return DRM_ERR(EINVAL); } return 0; diff --git a/trunk/drivers/char/drm/savage_bci.c b/trunk/drivers/char/drm/savage_bci.c index a9a84f88df5e..59c7520bf9a2 100644 --- a/trunk/drivers/char/drm/savage_bci.c +++ b/trunk/drivers/char/drm/savage_bci.c @@ -728,7 +728,6 @@ static int savage_do_init_bci(drm_device_t * dev, drm_savage_init_t * init) dev_priv->status = NULL; } if (dev_priv->dma_type == SAVAGE_DMA_AGP && init->buffers_offset) { - dev->agp_buffer_token = init->buffers_offset; dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset); if (!dev->agp_buffer_map) { diff --git a/trunk/drivers/char/drm/savage_state.c b/trunk/drivers/char/drm/savage_state.c index 1ca1e9cb5a33..ef2581d16146 100644 --- a/trunk/drivers/char/drm/savage_state.c +++ b/trunk/drivers/char/drm/savage_state.c @@ -994,7 +994,7 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS) if (cmdbuf.size) { kcmd_addr = drm_alloc(cmdbuf.size * 8, DRM_MEM_DRIVER); if (kcmd_addr == NULL) - return DRM_ERR(ENOMEM); + return ENOMEM; if (DRM_COPY_FROM_USER(kcmd_addr, cmdbuf.cmd_addr, cmdbuf.size * 8)) diff --git a/trunk/drivers/char/ec3104_keyb.c b/trunk/drivers/char/ec3104_keyb.c index 77f58ed6d59a..abac18b1871c 100644 --- a/trunk/drivers/char/ec3104_keyb.c +++ b/trunk/drivers/char/ec3104_keyb.c @@ -370,7 +370,7 @@ static void e5_receive(struct e5_struct *k) } } -static void ec3104_keyb_interrupt(int irq, void *data) +static void ec3104_keyb_interrupt(int irq, void *data, struct pt_regs *regs) { struct e5_struct *k = &ec3104_keyb; u8 msr, lsr; diff --git a/trunk/drivers/char/epca.c b/trunk/drivers/char/epca.c index 706733c0b36a..c3f95583a120 100644 --- a/trunk/drivers/char/epca.c +++ b/trunk/drivers/char/epca.c @@ -1157,7 +1157,6 @@ static int __init pc_init(void) int crd; struct board_info *bd; unsigned char board_id = 0; - int err = -ENOMEM; int pci_boards_found, pci_count; @@ -1165,11 +1164,13 @@ static int __init pc_init(void) pc_driver = alloc_tty_driver(MAX_ALLOC); if (!pc_driver) - goto out1; + return -ENOMEM; pc_info = alloc_tty_driver(MAX_ALLOC); - if (!pc_info) - goto out2; + if (!pc_info) { + put_tty_driver(pc_driver); + return -ENOMEM; + } /* ----------------------------------------------------------------------- If epca_setup has not been ran by LILO set num_cards to defaults; copy @@ -1369,17 +1370,11 @@ static int __init pc_init(void) } /* End for each card */ - err = tty_register_driver(pc_driver); - if (err) { - printk(KERN_ERR "Couldn't register Digi PC/ driver"); - goto out3; - } + if (tty_register_driver(pc_driver)) + panic("Couldn't register Digi PC/ driver"); - err = tty_register_driver(pc_info); - if (err) { - printk(KERN_ERR "Couldn't register Digi PC/ info "); - goto out4; - } + if (tty_register_driver(pc_info)) + panic("Couldn't register Digi PC/ info "); /* ------------------------------------------------------------------- Start up the poller to check for events on all enabled boards @@ -1390,15 +1385,6 @@ static int __init pc_init(void) mod_timer(&epca_timer, jiffies + HZ/25); return 0; -out4: - tty_unregister_driver(pc_driver); -out3: - put_tty_driver(pc_info); -out2: - put_tty_driver(pc_driver); -out1: - return err; - } /* End pc_init */ /* ------------------ Begin post_fep_init ---------------------- */ diff --git a/trunk/drivers/char/esp.c b/trunk/drivers/char/esp.c index 15a4ea896328..05788c75d7fc 100644 --- a/trunk/drivers/char/esp.c +++ b/trunk/drivers/char/esp.c @@ -615,7 +615,8 @@ static inline void check_modem_status(struct esp_struct *info) /* * This is the serial driver's interrupt routine */ -static irqreturn_t rs_interrupt_single(int irq, void *dev_id) +static irqreturn_t rs_interrupt_single(int irq, void *dev_id, + struct pt_regs *regs) { struct esp_struct * info; unsigned err_status; diff --git a/trunk/drivers/char/ftape/lowlevel/fdc-io.c b/trunk/drivers/char/ftape/lowlevel/fdc-io.c index bbcf918f056f..216532445652 100644 --- a/trunk/drivers/char/ftape/lowlevel/fdc-io.c +++ b/trunk/drivers/char/ftape/lowlevel/fdc-io.c @@ -1243,7 +1243,7 @@ static int fdc_config(void) TRACE_EXIT 0; } -static irqreturn_t ftape_interrupt(int irq, void *dev_id) +static irqreturn_t ftape_interrupt(int irq, void *dev_id, struct pt_regs *regs) { void (*handler) (void) = *fdc.hook; int handled = 0; diff --git a/trunk/drivers/char/ftape/zftape/zftape-buffers.c b/trunk/drivers/char/ftape/zftape/zftape-buffers.c index 7ebce2ec7897..da06f138334e 100644 --- a/trunk/drivers/char/ftape/zftape/zftape-buffers.c +++ b/trunk/drivers/char/ftape/zftape/zftape-buffers.c @@ -85,7 +85,7 @@ int zft_vmalloc_once(void *new, size_t size) peak_memory = used_memory; } TRACE_ABORT(0, ft_t_noise, - "allocated buffer @ %p, %zd bytes", *(void **)new, size); + "allocated buffer @ %p, %d bytes", *(void **)new, size); } int zft_vmalloc_always(void *new, size_t size) { @@ -101,7 +101,7 @@ void zft_vfree(void *old, size_t size) if (*(void **)old) { vfree(*(void **)old); used_memory -= size; - TRACE(ft_t_noise, "released buffer @ %p, %zd bytes", + TRACE(ft_t_noise, "released buffer @ %p, %d bytes", *(void **)old, size); *(void **)old = NULL; } diff --git a/trunk/drivers/char/hangcheck-timer.c b/trunk/drivers/char/hangcheck-timer.c index 1aa93a752a9c..d69f2ad9a67d 100644 --- a/trunk/drivers/char/hangcheck-timer.c +++ b/trunk/drivers/char/hangcheck-timer.c @@ -159,7 +159,7 @@ static void hangcheck_fire(unsigned long data) if (hangcheck_dump_tasks) { printk(KERN_CRIT "Hangcheck: Task state:\n"); #ifdef CONFIG_MAGIC_SYSRQ - handle_sysrq('t', NULL); + handle_sysrq('t', NULL, NULL); #endif /* CONFIG_MAGIC_SYSRQ */ } if (hangcheck_reboot) { diff --git a/trunk/drivers/char/hpet.c b/trunk/drivers/char/hpet.c index 091a11cd878c..58b0eb581114 100644 --- a/trunk/drivers/char/hpet.c +++ b/trunk/drivers/char/hpet.c @@ -116,7 +116,7 @@ static inline void writeq(unsigned long long v, void __iomem *addr) } #endif -static irqreturn_t hpet_interrupt(int irq, void *data) +static irqreturn_t hpet_interrupt(int irq, void *data, struct pt_regs *regs) { struct hpet_dev *devp; unsigned long isr; diff --git a/trunk/drivers/char/hvc_console.c b/trunk/drivers/char/hvc_console.c index 9902ffad3b12..4053d1cd393f 100644 --- a/trunk/drivers/char/hvc_console.c +++ b/trunk/drivers/char/hvc_console.c @@ -294,7 +294,7 @@ static int hvc_poll(struct hvc_struct *hp); * NOTE: This API isn't used if the console adapter doesn't support interrupts. * In this case the console is poll driven. */ -static irqreturn_t hvc_handle_interrupt(int irq, void *dev_instance) +static irqreturn_t hvc_handle_interrupt(int irq, void *dev_instance, struct pt_regs *regs) { /* if hvc_poll request a repoll, then kick the hvcd thread */ if (hvc_poll(dev_instance)) @@ -621,7 +621,7 @@ static int hvc_poll(struct hvc_struct *hp) sysrq_pressed = 1; continue; } else if (sysrq_pressed) { - handle_sysrq(buf[i], tty); + handle_sysrq(buf[i], NULL, tty); sysrq_pressed = 0; continue; } diff --git a/trunk/drivers/char/hvcs.c b/trunk/drivers/char/hvcs.c index 8728255c9463..0b89bcde8c52 100644 --- a/trunk/drivers/char/hvcs.c +++ b/trunk/drivers/char/hvcs.c @@ -313,7 +313,8 @@ static DEFINE_SPINLOCK(hvcs_structs_lock); static void hvcs_unthrottle(struct tty_struct *tty); static void hvcs_throttle(struct tty_struct *tty); -static irqreturn_t hvcs_handle_interrupt(int irq, void *dev_instance); +static irqreturn_t hvcs_handle_interrupt(int irq, void *dev_instance, + struct pt_regs *regs); static int hvcs_write(struct tty_struct *tty, const unsigned char *buf, int count); @@ -386,7 +387,8 @@ static void hvcs_throttle(struct tty_struct *tty) * handler taking any further interrupts because they are disabled which means * the hvcs_struct will always be valid in this handler. */ -static irqreturn_t hvcs_handle_interrupt(int irq, void *dev_instance) +static irqreturn_t hvcs_handle_interrupt(int irq, void *dev_instance, + struct pt_regs *regs) { struct hvcs_struct *hvcsd = dev_instance; diff --git a/trunk/drivers/char/hvsi.c b/trunk/drivers/char/hvsi.c index 2cf63e7305a3..c07dc58d5c1d 100644 --- a/trunk/drivers/char/hvsi.c +++ b/trunk/drivers/char/hvsi.c @@ -406,7 +406,7 @@ static void hvsi_insert_chars(struct hvsi_struct *hp, const char *buf, int len) hp->sysrq = 1; continue; } else if (hp->sysrq) { - handle_sysrq(c, hp->tty); + handle_sysrq(c, NULL, hp->tty); hp->sysrq = 0; continue; } @@ -555,7 +555,7 @@ static void hvsi_send_overflow(struct hvsi_struct *hp) * must get all pending data because we only get an irq on empty->non-empty * transition */ -static irqreturn_t hvsi_interrupt(int irq, void *arg) +static irqreturn_t hvsi_interrupt(int irq, void *arg, struct pt_regs *regs) { struct hvsi_struct *hp = (struct hvsi_struct *)arg; struct tty_struct *flip; @@ -616,7 +616,7 @@ static int __init poll_for_state(struct hvsi_struct *hp, int state) unsigned long end_jiffies = jiffies + HVSI_TIMEOUT; for (;;) { - hvsi_interrupt(hp->virq, (void *)hp); /* get pending data */ + hvsi_interrupt(hp->virq, (void *)hp, NULL); /* get pending data */ if (hp->state == state) return 0; diff --git a/trunk/drivers/char/hw_random/core.c b/trunk/drivers/char/hw_random/core.c index ebace201bec6..154a81d328c1 100644 --- a/trunk/drivers/char/hw_random/core.c +++ b/trunk/drivers/char/hw_random/core.c @@ -162,8 +162,7 @@ static struct miscdevice rng_miscdev = { }; -static ssize_t hwrng_attr_current_store(struct device *dev, - struct device_attribute *attr, +static ssize_t hwrng_attr_current_store(struct class_device *class, const char *buf, size_t len) { int err; @@ -193,8 +192,7 @@ static ssize_t hwrng_attr_current_store(struct device *dev, return err ? : len; } -static ssize_t hwrng_attr_current_show(struct device *dev, - struct device_attribute *attr, +static ssize_t hwrng_attr_current_show(struct class_device *class, char *buf) { int err; @@ -212,8 +210,7 @@ static ssize_t hwrng_attr_current_show(struct device *dev, return ret; } -static ssize_t hwrng_attr_available_show(struct device *dev, - struct device_attribute *attr, +static ssize_t hwrng_attr_available_show(struct class_device *class, char *buf) { int err; @@ -237,18 +234,20 @@ static ssize_t hwrng_attr_available_show(struct device *dev, return ret; } -static DEVICE_ATTR(rng_current, S_IRUGO | S_IWUSR, - hwrng_attr_current_show, - hwrng_attr_current_store); -static DEVICE_ATTR(rng_available, S_IRUGO, - hwrng_attr_available_show, - NULL); +static CLASS_DEVICE_ATTR(rng_current, S_IRUGO | S_IWUSR, + hwrng_attr_current_show, + hwrng_attr_current_store); +static CLASS_DEVICE_ATTR(rng_available, S_IRUGO, + hwrng_attr_available_show, + NULL); static void unregister_miscdev(void) { - device_remove_file(rng_miscdev.this_device, &dev_attr_rng_available); - device_remove_file(rng_miscdev.this_device, &dev_attr_rng_current); + class_device_remove_file(rng_miscdev.class, + &class_device_attr_rng_available); + class_device_remove_file(rng_miscdev.class, + &class_device_attr_rng_current); misc_deregister(&rng_miscdev); } @@ -259,19 +258,20 @@ static int register_miscdev(void) err = misc_register(&rng_miscdev); if (err) goto out; - err = device_create_file(rng_miscdev.this_device, - &dev_attr_rng_current); + err = class_device_create_file(rng_miscdev.class, + &class_device_attr_rng_current); if (err) goto err_misc_dereg; - err = device_create_file(rng_miscdev.this_device, - &dev_attr_rng_available); + err = class_device_create_file(rng_miscdev.class, + &class_device_attr_rng_available); if (err) goto err_remove_current; out: return err; err_remove_current: - device_remove_file(rng_miscdev.this_device, &dev_attr_rng_current); + class_device_remove_file(rng_miscdev.class, + &class_device_attr_rng_current); err_misc_dereg: misc_deregister(&rng_miscdev); goto out; diff --git a/trunk/drivers/char/ip2/i2lib.c b/trunk/drivers/char/ip2/i2lib.c index 54d93f0345e8..fc944d375be7 100644 --- a/trunk/drivers/char/ip2/i2lib.c +++ b/trunk/drivers/char/ip2/i2lib.c @@ -1007,7 +1007,7 @@ i2InputAvailable(i2ChanStrPtr pCh) // applications that one cannot break out of. //****************************************************************************** static int -i2Output(i2ChanStrPtr pCh, const char *pSource, int count) +i2Output(i2ChanStrPtr pCh, const char *pSource, int count, int user ) { i2eBordStrPtr pB; unsigned char *pInsert; @@ -1020,7 +1020,7 @@ i2Output(i2ChanStrPtr pCh, const char *pSource, int count) int bailout = 10; - ip2trace (CHANN, ITRC_OUTPUT, ITRC_ENTER, 2, count, 0 ); + ip2trace (CHANN, ITRC_OUTPUT, ITRC_ENTER, 2, count, user ); // Ensure channel structure seems real if ( !i2Validate ( pCh ) ) @@ -1087,7 +1087,12 @@ i2Output(i2ChanStrPtr pCh, const char *pSource, int count) DATA_COUNT_OF(pInsert) = amountToMove; // Move the data - memcpy( (char*)(DATA_OF(pInsert)), pSource, amountToMove ); + if ( user ) { + rc = copy_from_user((char*)(DATA_OF(pInsert)), pSource, + amountToMove ); + } else { + memcpy( (char*)(DATA_OF(pInsert)), pSource, amountToMove ); + } // Adjust pointers and indices pSource += amountToMove; pCh->Obuf_char_count += amountToMove; diff --git a/trunk/drivers/char/ip2/i2lib.h b/trunk/drivers/char/ip2/i2lib.h index e559e9bac06d..952e113ccd8a 100644 --- a/trunk/drivers/char/ip2/i2lib.h +++ b/trunk/drivers/char/ip2/i2lib.h @@ -332,7 +332,7 @@ static int i2QueueCommands(int, i2ChanStrPtr, int, int, cmdSyntaxPtr,...); static int i2GetStatus(i2ChanStrPtr, int); static int i2Input(i2ChanStrPtr); static int i2InputFlush(i2ChanStrPtr); -static int i2Output(i2ChanStrPtr, const char *, int); +static int i2Output(i2ChanStrPtr, const char *, int, int); static int i2OutputFree(i2ChanStrPtr); static int i2ServiceBoard(i2eBordStrPtr); static void i2DrainOutput(i2ChanStrPtr, int); diff --git a/trunk/drivers/char/ip2/ip2main.c b/trunk/drivers/char/ip2/ip2main.c index a3f32d46d2f8..62ef511d143b 100644 --- a/trunk/drivers/char/ip2/ip2main.c +++ b/trunk/drivers/char/ip2/ip2main.c @@ -190,7 +190,7 @@ static int ip2_tiocmset(struct tty_struct *tty, struct file *file, static void set_irq(int, int); static void ip2_interrupt_bh(i2eBordStrPtr pB); -static irqreturn_t ip2_interrupt(int irq, void *dev_id); +static irqreturn_t ip2_interrupt(int irq, void *dev_id, struct pt_regs * regs); static void ip2_poll(unsigned long arg); static inline void service_all_boards(void); static void do_input(void *p); @@ -1154,9 +1154,10 @@ ip2_interrupt_bh(i2eBordStrPtr pB) /******************************************************************************/ -/* Function: ip2_interrupt(int irq, void *dev_id) */ +/* Function: ip2_interrupt(int irq, void *dev_id, struct pt_regs * regs) */ /* Parameters: irq - interrupt number */ /* pointer to optional device ID structure */ +/* pointer to register structure */ /* Returns: Nothing */ /* */ /* Description: */ @@ -1172,7 +1173,7 @@ ip2_interrupt_bh(i2eBordStrPtr pB) /* */ /******************************************************************************/ static irqreturn_t -ip2_interrupt(int irq, void *dev_id) +ip2_interrupt(int irq, void *dev_id, struct pt_regs * regs) { int i; i2eBordStrPtr pB; @@ -1236,7 +1237,7 @@ ip2_poll(unsigned long arg) // Just polled boards, IRQ = 0 will hit all non-interrupt boards. // It will NOT poll boards handled by hard interrupts. // The issue of queued BH interrups is handled in ip2_interrupt(). - ip2_interrupt(0, NULL); + ip2_interrupt(0, NULL, NULL); PollTimer.expires = POLL_TIMEOUT; add_timer( &PollTimer ); @@ -1704,7 +1705,7 @@ ip2_write( PTTY tty, const unsigned char *pData, int count) /* This is the actual move bit. Make sure it does what we need!!!!! */ WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags); - bytesSent = i2Output( pCh, pData, count); + bytesSent = i2Output( pCh, pData, count, 0 ); WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags); ip2trace (CHANN, ITRC_WRITE, ITRC_RETURN, 1, bytesSent ); @@ -1764,7 +1765,7 @@ ip2_flush_chars( PTTY tty ) // // We may need to restart i2Output if it does not fullfill this request // - strip = i2Output( pCh, pCh->Pbuf, pCh->Pbuf_stuff); + strip = i2Output( pCh, pCh->Pbuf, pCh->Pbuf_stuff, 0 ); if ( strip != pCh->Pbuf_stuff ) { memmove( pCh->Pbuf, &pCh->Pbuf[strip], pCh->Pbuf_stuff - strip ); } diff --git a/trunk/drivers/char/ipmi/ipmi_msghandler.c b/trunk/drivers/char/ipmi/ipmi_msghandler.c index c47add8e47df..2455e8d478ac 100644 --- a/trunk/drivers/char/ipmi/ipmi_msghandler.c +++ b/trunk/drivers/char/ipmi/ipmi_msghandler.c @@ -376,23 +376,13 @@ static void free_recv_msg_list(struct list_head *q) } } -static void free_smi_msg_list(struct list_head *q) -{ - struct ipmi_smi_msg *msg, *msg2; - - list_for_each_entry_safe(msg, msg2, q, link) { - list_del(&msg->link); - ipmi_free_smi_msg(msg); - } -} - static void clean_up_interface_data(ipmi_smi_t intf) { int i; struct cmd_rcvr *rcvr, *rcvr2; struct list_head list; - free_smi_msg_list(&intf->waiting_msgs); + free_recv_msg_list(&intf->waiting_msgs); free_recv_msg_list(&intf->waiting_events); /* Wholesale remove all the entries from the list in the @@ -1854,7 +1844,7 @@ static ssize_t provides_dev_sdrs_show(struct device *dev, struct bmc_device *bmc = dev_get_drvdata(dev); return snprintf(buf, 10, "%u\n", - (bmc->id.device_revision & 0x80) >> 7); + bmc->id.device_revision && 0x80 >> 7); } static ssize_t revision_show(struct device *dev, struct device_attribute *attr, @@ -1863,7 +1853,7 @@ static ssize_t revision_show(struct device *dev, struct device_attribute *attr, struct bmc_device *bmc = dev_get_drvdata(dev); return snprintf(buf, 20, "%u\n", - bmc->id.device_revision & 0x0F); + bmc->id.device_revision && 0x0F); } static ssize_t firmware_rev_show(struct device *dev, @@ -1938,8 +1928,13 @@ static ssize_t guid_show(struct device *dev, struct device_attribute *attr, (long long) bmc->guid[8]); } -static void remove_files(struct bmc_device *bmc) +static void +cleanup_bmc_device(struct kref *ref) { + struct bmc_device *bmc; + + bmc = container_of(ref, struct bmc_device, refcount); + device_remove_file(&bmc->dev->dev, &bmc->device_id_attr); device_remove_file(&bmc->dev->dev, @@ -1956,23 +1951,12 @@ static void remove_files(struct bmc_device *bmc) &bmc->manufacturer_id_attr); device_remove_file(&bmc->dev->dev, &bmc->product_id_attr); - if (bmc->id.aux_firmware_revision_set) device_remove_file(&bmc->dev->dev, &bmc->aux_firmware_rev_attr); if (bmc->guid_set) device_remove_file(&bmc->dev->dev, &bmc->guid_attr); -} - -static void -cleanup_bmc_device(struct kref *ref) -{ - struct bmc_device *bmc; - - bmc = container_of(ref, struct bmc_device, refcount); - - remove_files(bmc); platform_device_unregister(bmc->dev); kfree(bmc); } @@ -1993,79 +1977,6 @@ static void ipmi_bmc_unregister(ipmi_smi_t intf) mutex_unlock(&ipmidriver_mutex); } -static int create_files(struct bmc_device *bmc) -{ - int err; - - err = device_create_file(&bmc->dev->dev, - &bmc->device_id_attr); - if (err) goto out; - err = device_create_file(&bmc->dev->dev, - &bmc->provides_dev_sdrs_attr); - if (err) goto out_devid; - err = device_create_file(&bmc->dev->dev, - &bmc->revision_attr); - if (err) goto out_sdrs; - err = device_create_file(&bmc->dev->dev, - &bmc->firmware_rev_attr); - if (err) goto out_rev; - err = device_create_file(&bmc->dev->dev, - &bmc->version_attr); - if (err) goto out_firm; - err = device_create_file(&bmc->dev->dev, - &bmc->add_dev_support_attr); - if (err) goto out_version; - err = device_create_file(&bmc->dev->dev, - &bmc->manufacturer_id_attr); - if (err) goto out_add_dev; - err = device_create_file(&bmc->dev->dev, - &bmc->product_id_attr); - if (err) goto out_manu; - if (bmc->id.aux_firmware_revision_set) { - err = device_create_file(&bmc->dev->dev, - &bmc->aux_firmware_rev_attr); - if (err) goto out_prod_id; - } - if (bmc->guid_set) { - err = device_create_file(&bmc->dev->dev, - &bmc->guid_attr); - if (err) goto out_aux_firm; - } - - return 0; - -out_aux_firm: - if (bmc->id.aux_firmware_revision_set) - device_remove_file(&bmc->dev->dev, - &bmc->aux_firmware_rev_attr); -out_prod_id: - device_remove_file(&bmc->dev->dev, - &bmc->product_id_attr); -out_manu: - device_remove_file(&bmc->dev->dev, - &bmc->manufacturer_id_attr); -out_add_dev: - device_remove_file(&bmc->dev->dev, - &bmc->add_dev_support_attr); -out_version: - device_remove_file(&bmc->dev->dev, - &bmc->version_attr); -out_firm: - device_remove_file(&bmc->dev->dev, - &bmc->firmware_rev_attr); -out_rev: - device_remove_file(&bmc->dev->dev, - &bmc->revision_attr); -out_sdrs: - device_remove_file(&bmc->dev->dev, - &bmc->provides_dev_sdrs_attr); -out_devid: - device_remove_file(&bmc->dev->dev, - &bmc->device_id_attr); -out: - return err; -} - static int ipmi_bmc_register(ipmi_smi_t intf) { int rv; @@ -2118,7 +2029,7 @@ static int ipmi_bmc_register(ipmi_smi_t intf) dev_set_drvdata(&bmc->dev->dev, bmc); kref_init(&bmc->refcount); - rv = platform_device_add(bmc->dev); + rv = platform_device_register(bmc->dev); mutex_unlock(&ipmidriver_mutex); if (rv) { printk(KERN_ERR @@ -2140,6 +2051,7 @@ static int ipmi_bmc_register(ipmi_smi_t intf) 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; @@ -2181,14 +2093,28 @@ static int ipmi_bmc_register(ipmi_smi_t intf) 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); - platform_device_unregister(bmc->dev); - mutex_unlock(&ipmidriver_mutex); - - return rv; - } + device_create_file(&bmc->dev->dev, + &bmc->device_id_attr); + device_create_file(&bmc->dev->dev, + &bmc->provides_dev_sdrs_attr); + device_create_file(&bmc->dev->dev, + &bmc->revision_attr); + device_create_file(&bmc->dev->dev, + &bmc->firmware_rev_attr); + device_create_file(&bmc->dev->dev, + &bmc->version_attr); + device_create_file(&bmc->dev->dev, + &bmc->add_dev_support_attr); + device_create_file(&bmc->dev->dev, + &bmc->manufacturer_id_attr); + device_create_file(&bmc->dev->dev, + &bmc->product_id_attr); + if (bmc->id.aux_firmware_revision_set) + device_create_file(&bmc->dev->dev, + &bmc->aux_firmware_rev_attr); + if (bmc->guid_set) + device_create_file(&bmc->dev->dev, + &bmc->guid_attr); printk(KERN_INFO "ipmi: Found new BMC (man_id: 0x%6.6x, " @@ -3242,9 +3168,7 @@ void ipmi_smi_msg_received(ipmi_smi_t intf, report the error immediately. */ if ((msg->rsp_size >= 3) && (msg->rsp[2] != 0) && (msg->rsp[2] != IPMI_NODE_BUSY_ERR) - && (msg->rsp[2] != IPMI_LOST_ARBITRATION_ERR) - && (msg->rsp[2] != IPMI_BUS_ERR) - && (msg->rsp[2] != IPMI_NAK_ON_WRITE_ERR)) + && (msg->rsp[2] != IPMI_LOST_ARBITRATION_ERR)) { int chan = msg->rsp[3] & 0xf; diff --git a/trunk/drivers/char/ipmi/ipmi_si_intf.c b/trunk/drivers/char/ipmi/ipmi_si_intf.c index bb1fac104fda..b106c45abfc9 100644 --- a/trunk/drivers/char/ipmi/ipmi_si_intf.c +++ b/trunk/drivers/char/ipmi/ipmi_si_intf.c @@ -872,7 +872,7 @@ static void smi_timeout(unsigned long data) add_timer(&(smi_info->si_timer)); } -static irqreturn_t si_irq_handler(int irq, void *data) +static irqreturn_t si_irq_handler(int irq, void *data, struct pt_regs *regs) { struct smi_info *smi_info = data; unsigned long flags; @@ -899,14 +899,14 @@ static irqreturn_t si_irq_handler(int irq, void *data) return IRQ_HANDLED; } -static irqreturn_t si_bt_irq_handler(int irq, void *data) +static irqreturn_t si_bt_irq_handler(int irq, void *data, struct pt_regs *regs) { struct smi_info *smi_info = data; /* We need to clear the IRQ flag for the BT interface. */ smi_info->io.outputb(&smi_info->io, IPMI_BT_INTMASK_REG, IPMI_BT_INTMASK_CLEAR_IRQ_BIT | IPMI_BT_INTMASK_ENABLE_IRQ_BIT); - return si_irq_handler(irq, data); + return si_irq_handler(irq, data, regs); } static int smi_start_processing(void *send_info, @@ -1211,7 +1211,7 @@ static void intf_mem_outb(struct si_sm_io *io, unsigned int offset, static unsigned char intf_mem_inw(struct si_sm_io *io, unsigned int offset) { return (readw((io->addr)+(offset * io->regspacing)) >> io->regshift) - & 0xff; + && 0xff; } static void intf_mem_outw(struct si_sm_io *io, unsigned int offset, @@ -1223,7 +1223,7 @@ static void intf_mem_outw(struct si_sm_io *io, unsigned int offset, static unsigned char intf_mem_inl(struct si_sm_io *io, unsigned int offset) { return (readl((io->addr)+(offset * io->regspacing)) >> io->regshift) - & 0xff; + && 0xff; } static void intf_mem_outl(struct si_sm_io *io, unsigned int offset, @@ -1236,7 +1236,7 @@ static void intf_mem_outl(struct si_sm_io *io, unsigned int offset, static unsigned char mem_inq(struct si_sm_io *io, unsigned int offset) { return (readq((io->addr)+(offset * io->regspacing)) >> io->regshift) - & 0xff; + && 0xff; } static void mem_outq(struct si_sm_io *io, unsigned int offset, @@ -1789,7 +1789,7 @@ static int __devinit ipmi_pci_probe(struct pci_dev *pdev, info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) - return -ENOMEM; + return ENOMEM; info->addr_source = "PCI"; @@ -1810,7 +1810,7 @@ static int __devinit ipmi_pci_probe(struct pci_dev *pdev, kfree(info); printk(KERN_INFO "ipmi_si: %s: Unknown IPMI type: %d\n", pci_name(pdev), class_type); - return -ENOMEM; + return ENOMEM; } rv = pci_enable_device(pdev); @@ -1867,7 +1867,7 @@ static int ipmi_pci_resume(struct pci_dev *pdev) static struct pci_device_id ipmi_pci_devices[] = { { PCI_DEVICE(PCI_HP_VENDOR_ID, PCI_MMC_DEVICE_ID) }, - { PCI_DEVICE_CLASS(PCI_ERMC_CLASSCODE, PCI_ERMC_CLASSCODE_MASK) } + { PCI_DEVICE_CLASS(PCI_ERMC_CLASSCODE, PCI_ERMC_CLASSCODE) } }; MODULE_DEVICE_TABLE(pci, ipmi_pci_devices); @@ -2346,7 +2346,7 @@ static int try_smi_init(struct smi_info *new_smi) new_smi->dev = &new_smi->pdev->dev; new_smi->dev->driver = &ipmi_driver; - rv = platform_device_add(new_smi->pdev); + rv = platform_device_register(new_smi->pdev); if (rv) { printk(KERN_ERR "ipmi_si_intf:" diff --git a/trunk/drivers/char/ipmi/ipmi_watchdog.c b/trunk/drivers/char/ipmi/ipmi_watchdog.c index 73f759eaa5a6..accaaf1a6b69 100644 --- a/trunk/drivers/char/ipmi/ipmi_watchdog.c +++ b/trunk/drivers/char/ipmi/ipmi_watchdog.c @@ -903,7 +903,7 @@ static void ipmi_register_watchdog(int ipmi_intf) #ifdef HAVE_NMI_HANDLER static int -ipmi_nmi(void *dev_id, int cpu, int handled) +ipmi_nmi(void *dev_id, struct pt_regs *regs, int cpu, int handled) { /* If we are not expecting a timeout, ignore it. */ if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) diff --git a/trunk/drivers/char/isicom.c b/trunk/drivers/char/isicom.c index 58c955e390b3..ea2bbf80ad33 100644 --- a/trunk/drivers/char/isicom.c +++ b/trunk/drivers/char/isicom.c @@ -546,7 +546,7 @@ static void isicom_bottomhalf(void *data) * Main interrupt handler routine */ -static irqreturn_t isicom_interrupt(int irq, void *dev_id) +static irqreturn_t isicom_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct isi_board *card = dev_id; struct isi_port *port; @@ -1062,12 +1062,11 @@ static void isicom_shutdown_port(struct isi_port *port) static void isicom_close(struct tty_struct *tty, struct file *filp) { struct isi_port *port = tty->driver_data; - struct isi_board *card; + struct isi_board *card = port->card; unsigned long flags; if (!port) return; - card = port->card; if (isicom_paranoia_check(port, tty->name, "isicom_close")) return; diff --git a/trunk/drivers/char/istallion.c b/trunk/drivers/char/istallion.c index ffdf9df1a67a..d6e031542c6b 100644 --- a/trunk/drivers/char/istallion.c +++ b/trunk/drivers/char/istallion.c @@ -686,37 +686,37 @@ static stlibrd_t *stli_allocbrd(void); static void stli_ecpinit(stlibrd_t *brdp); static void stli_ecpenable(stlibrd_t *brdp); static void stli_ecpdisable(stlibrd_t *brdp); -static void __iomem *stli_ecpgetmemptr(stlibrd_t *brdp, unsigned long offset, int line); +static char *stli_ecpgetmemptr(stlibrd_t *brdp, unsigned long offset, int line); static void stli_ecpreset(stlibrd_t *brdp); static void stli_ecpintr(stlibrd_t *brdp); static void stli_ecpeiinit(stlibrd_t *brdp); static void stli_ecpeienable(stlibrd_t *brdp); static void stli_ecpeidisable(stlibrd_t *brdp); -static void __iomem *stli_ecpeigetmemptr(stlibrd_t *brdp, unsigned long offset, int line); +static char *stli_ecpeigetmemptr(stlibrd_t *brdp, unsigned long offset, int line); static void stli_ecpeireset(stlibrd_t *brdp); static void stli_ecpmcenable(stlibrd_t *brdp); static void stli_ecpmcdisable(stlibrd_t *brdp); -static void __iomem *stli_ecpmcgetmemptr(stlibrd_t *brdp, unsigned long offset, int line); +static char *stli_ecpmcgetmemptr(stlibrd_t *brdp, unsigned long offset, int line); static void stli_ecpmcreset(stlibrd_t *brdp); static void stli_ecppciinit(stlibrd_t *brdp); -static void __iomem *stli_ecppcigetmemptr(stlibrd_t *brdp, unsigned long offset, int line); +static char *stli_ecppcigetmemptr(stlibrd_t *brdp, unsigned long offset, int line); static void stli_ecppcireset(stlibrd_t *brdp); static void stli_onbinit(stlibrd_t *brdp); static void stli_onbenable(stlibrd_t *brdp); static void stli_onbdisable(stlibrd_t *brdp); -static void __iomem *stli_onbgetmemptr(stlibrd_t *brdp, unsigned long offset, int line); +static char *stli_onbgetmemptr(stlibrd_t *brdp, unsigned long offset, int line); static void stli_onbreset(stlibrd_t *brdp); static void stli_onbeinit(stlibrd_t *brdp); static void stli_onbeenable(stlibrd_t *brdp); static void stli_onbedisable(stlibrd_t *brdp); -static void __iomem *stli_onbegetmemptr(stlibrd_t *brdp, unsigned long offset, int line); +static char *stli_onbegetmemptr(stlibrd_t *brdp, unsigned long offset, int line); static void stli_onbereset(stlibrd_t *brdp); static void stli_bbyinit(stlibrd_t *brdp); -static void __iomem *stli_bbygetmemptr(stlibrd_t *brdp, unsigned long offset, int line); +static char *stli_bbygetmemptr(stlibrd_t *brdp, unsigned long offset, int line); static void stli_bbyreset(stlibrd_t *brdp); static void stli_stalinit(stlibrd_t *brdp); -static void __iomem *stli_stalgetmemptr(stlibrd_t *brdp, unsigned long offset, int line); +static char *stli_stalgetmemptr(stlibrd_t *brdp, unsigned long offset, int line); static void stli_stalreset(stlibrd_t *brdp); static stliport_t *stli_getport(int brdnr, int panelnr, int portnr); @@ -1566,7 +1566,7 @@ static void stli_flushchars(struct tty_struct *tty) len = MIN(len, cooksize); count = 0; - shbuf = EBRDGETMEMPTR(brdp, portp->txoffset); + shbuf = (char *) EBRDGETMEMPTR(brdp, portp->txoffset); buf = stli_txcookbuf; while (len > 0) { @@ -2948,9 +2948,9 @@ static void stli_ecpdisable(stlibrd_t *brdp) /*****************************************************************************/ -static void __iomem *stli_ecpgetmemptr(stlibrd_t *brdp, unsigned long offset, int line) +static char *stli_ecpgetmemptr(stlibrd_t *brdp, unsigned long offset, int line) { - void __iomem *ptr; + void *ptr; unsigned char val; if (offset > brdp->memsize) { @@ -3022,9 +3022,9 @@ static void stli_ecpeidisable(stlibrd_t *brdp) /*****************************************************************************/ -static void __iomem *stli_ecpeigetmemptr(stlibrd_t *brdp, unsigned long offset, int line) +static char *stli_ecpeigetmemptr(stlibrd_t *brdp, unsigned long offset, int line) { - void __iomem *ptr; + void *ptr; unsigned char val; if (offset > brdp->memsize) { @@ -3074,9 +3074,9 @@ static void stli_ecpmcdisable(stlibrd_t *brdp) /*****************************************************************************/ -static void __iomem *stli_ecpmcgetmemptr(stlibrd_t *brdp, unsigned long offset, int line) +static char *stli_ecpmcgetmemptr(stlibrd_t *brdp, unsigned long offset, int line) { - void __iomem *ptr; + void *ptr; unsigned char val; if (offset > brdp->memsize) { @@ -3119,9 +3119,9 @@ static void stli_ecppciinit(stlibrd_t *brdp) /*****************************************************************************/ -static void __iomem *stli_ecppcigetmemptr(stlibrd_t *brdp, unsigned long offset, int line) +static char *stli_ecppcigetmemptr(stlibrd_t *brdp, unsigned long offset, int line) { - void __iomem *ptr; + void *ptr; unsigned char val; if (offset > brdp->memsize) { @@ -3185,9 +3185,9 @@ static void stli_onbdisable(stlibrd_t *brdp) /*****************************************************************************/ -static void __iomem *stli_onbgetmemptr(stlibrd_t *brdp, unsigned long offset, int line) +static char *stli_onbgetmemptr(stlibrd_t *brdp, unsigned long offset, int line) { - void __iomem *ptr; + void *ptr; if (offset > brdp->memsize) { printk(KERN_ERR "STALLION: shared memory pointer=%x out of " @@ -3250,9 +3250,9 @@ static void stli_onbedisable(stlibrd_t *brdp) /*****************************************************************************/ -static void __iomem *stli_onbegetmemptr(stlibrd_t *brdp, unsigned long offset, int line) +static char *stli_onbegetmemptr(stlibrd_t *brdp, unsigned long offset, int line) { - void __iomem *ptr; + void *ptr; unsigned char val; if (offset > brdp->memsize) { @@ -3300,9 +3300,9 @@ static void stli_bbyinit(stlibrd_t *brdp) /*****************************************************************************/ -static void __iomem *stli_bbygetmemptr(stlibrd_t *brdp, unsigned long offset, int line) +static char *stli_bbygetmemptr(stlibrd_t *brdp, unsigned long offset, int line) { - void __iomem *ptr; + void *ptr; unsigned char val; BUG_ON(offset > brdp->memsize); @@ -3337,7 +3337,7 @@ static void stli_stalinit(stlibrd_t *brdp) /*****************************************************************************/ -static void __iomem *stli_stalgetmemptr(stlibrd_t *brdp, unsigned long offset, int line) +static char *stli_stalgetmemptr(stlibrd_t *brdp, unsigned long offset, int line) { BUG_ON(offset > brdp->memsize); return brdp->membase + (offset % STAL_PAGESIZE); @@ -3876,7 +3876,7 @@ static int stli_eisamemprobe(stlibrd_t *brdp) continue; if (brdp->brdtype == BRD_ECPE) { - ecpsigp = stli_ecpeigetmemptr(brdp, + ecpsigp = (cdkecpsig_t __iomem *) stli_ecpeigetmemptr(brdp, CDK_SIGADDR, __LINE__); memcpy_fromio(&ecpsig, ecpsigp, sizeof(cdkecpsig_t)); if (ecpsig.magic == cpu_to_le32(ECP_MAGIC)) @@ -4184,7 +4184,7 @@ static int stli_initbrds(void) static ssize_t stli_memread(struct file *fp, char __user *buf, size_t count, loff_t *offp) { unsigned long flags; - void __iomem *memptr; + void *memptr; stlibrd_t *brdp; int brdnr, size, n; void *p; @@ -4214,7 +4214,7 @@ static ssize_t stli_memread(struct file *fp, char __user *buf, size_t count, lof while (size > 0) { spin_lock_irqsave(&brd_lock, flags); EBRDENABLE(brdp); - memptr = EBRDGETMEMPTR(brdp, off); + memptr = (void *) EBRDGETMEMPTR(brdp, off); n = MIN(size, (brdp->pagesize - (((unsigned long) off) % brdp->pagesize))); n = MIN(n, PAGE_SIZE); memcpy_fromio(p, memptr, n); @@ -4247,7 +4247,7 @@ static ssize_t stli_memread(struct file *fp, char __user *buf, size_t count, lof static ssize_t stli_memwrite(struct file *fp, const char __user *buf, size_t count, loff_t *offp) { unsigned long flags; - void __iomem *memptr; + void *memptr; stlibrd_t *brdp; char __user *chbuf; int brdnr, size, n; @@ -4287,7 +4287,7 @@ static ssize_t stli_memwrite(struct file *fp, const char __user *buf, size_t cou } spin_lock_irqsave(&brd_lock, flags); EBRDENABLE(brdp); - memptr = EBRDGETMEMPTR(brdp, off); + memptr = (void *) EBRDGETMEMPTR(brdp, off); memcpy_toio(memptr, p, n); EBRDDISABLE(brdp); spin_unlock_irqrestore(&brd_lock, flags); diff --git a/trunk/drivers/char/keyboard.c b/trunk/drivers/char/keyboard.c index 20b6c8b30248..e2011669c7bb 100644 --- a/trunk/drivers/char/keyboard.c +++ b/trunk/drivers/char/keyboard.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include @@ -78,7 +77,7 @@ void compute_shiftstate(void); k_slock, k_dead2, k_brl, k_ignore typedef void (k_handler_fn)(struct vc_data *vc, unsigned char value, - char up_flag); + char up_flag, struct pt_regs *regs); static k_handler_fn K_HANDLERS; static k_handler_fn *k_handler[16] = { K_HANDLERS }; @@ -89,7 +88,7 @@ static k_handler_fn *k_handler[16] = { K_HANDLERS }; fn_boot_it, fn_caps_on, fn_compose, fn_SAK,\ fn_dec_console, fn_inc_console, fn_spawn_con, fn_bare_num -typedef void (fn_handler_fn)(struct vc_data *vc); +typedef void (fn_handler_fn)(struct vc_data *vc, struct pt_regs *regs); static fn_handler_fn FN_HANDLERS; static fn_handler_fn *fn_handler[] = { FN_HANDLERS }; @@ -429,7 +428,7 @@ static unsigned int handle_diacr(struct vc_data *vc, unsigned int ch) /* * Special function handlers */ -static void fn_enter(struct vc_data *vc) +static void fn_enter(struct vc_data *vc, struct pt_regs *regs) { if (diacr) { if (kbd->kbdmode == VC_UNICODE) @@ -443,28 +442,27 @@ static void fn_enter(struct vc_data *vc) put_queue(vc, 10); } -static void fn_caps_toggle(struct vc_data *vc) +static void fn_caps_toggle(struct vc_data *vc, struct pt_regs *regs) { if (rep) return; chg_vc_kbd_led(kbd, VC_CAPSLOCK); } -static void fn_caps_on(struct vc_data *vc) +static void fn_caps_on(struct vc_data *vc, struct pt_regs *regs) { if (rep) return; set_vc_kbd_led(kbd, VC_CAPSLOCK); } -static void fn_show_ptregs(struct vc_data *vc) +static void fn_show_ptregs(struct vc_data *vc, struct pt_regs *regs) { - struct pt_regs *regs = get_irq_regs(); if (regs) show_regs(regs); } -static void fn_hold(struct vc_data *vc) +static void fn_hold(struct vc_data *vc, struct pt_regs *regs) { struct tty_struct *tty = vc->vc_tty; @@ -482,12 +480,12 @@ static void fn_hold(struct vc_data *vc) stop_tty(tty); } -static void fn_num(struct vc_data *vc) +static void fn_num(struct vc_data *vc, struct pt_regs *regs) { if (vc_kbd_mode(kbd,VC_APPLIC)) applkey(vc, 'P', 1); else - fn_bare_num(vc); + fn_bare_num(vc, regs); } /* @@ -496,19 +494,19 @@ static void fn_num(struct vc_data *vc) * Bind this to NumLock if you prefer that the NumLock key always * changes the NumLock flag. */ -static void fn_bare_num(struct vc_data *vc) +static void fn_bare_num(struct vc_data *vc, struct pt_regs *regs) { if (!rep) chg_vc_kbd_led(kbd, VC_NUMLOCK); } -static void fn_lastcons(struct vc_data *vc) +static void fn_lastcons(struct vc_data *vc, struct pt_regs *regs) { /* switch to the last used console, ChN */ set_console(last_console); } -static void fn_dec_console(struct vc_data *vc) +static void fn_dec_console(struct vc_data *vc, struct pt_regs *regs) { int i, cur = fg_console; @@ -525,7 +523,7 @@ static void fn_dec_console(struct vc_data *vc) set_console(i); } -static void fn_inc_console(struct vc_data *vc) +static void fn_inc_console(struct vc_data *vc, struct pt_regs *regs) { int i, cur = fg_console; @@ -542,7 +540,7 @@ static void fn_inc_console(struct vc_data *vc) set_console(i); } -static void fn_send_intr(struct vc_data *vc) +static void fn_send_intr(struct vc_data *vc, struct pt_regs *regs) { struct tty_struct *tty = vc->vc_tty; @@ -552,37 +550,37 @@ static void fn_send_intr(struct vc_data *vc) con_schedule_flip(tty); } -static void fn_scroll_forw(struct vc_data *vc) +static void fn_scroll_forw(struct vc_data *vc, struct pt_regs *regs) { scrollfront(vc, 0); } -static void fn_scroll_back(struct vc_data *vc) +static void fn_scroll_back(struct vc_data *vc, struct pt_regs *regs) { scrollback(vc, 0); } -static void fn_show_mem(struct vc_data *vc) +static void fn_show_mem(struct vc_data *vc, struct pt_regs *regs) { show_mem(); } -static void fn_show_state(struct vc_data *vc) +static void fn_show_state(struct vc_data *vc, struct pt_regs *regs) { show_state(); } -static void fn_boot_it(struct vc_data *vc) +static void fn_boot_it(struct vc_data *vc, struct pt_regs *regs) { ctrl_alt_del(); } -static void fn_compose(struct vc_data *vc) +static void fn_compose(struct vc_data *vc, struct pt_regs *regs) { dead_key_next = 1; } -static void fn_spawn_con(struct vc_data *vc) +static void fn_spawn_con(struct vc_data *vc, struct pt_regs *regs) { spin_lock(&vt_spawn_con.lock); if (vt_spawn_con.pid) @@ -593,7 +591,7 @@ static void fn_spawn_con(struct vc_data *vc) spin_unlock(&vt_spawn_con.lock); } -static void fn_SAK(struct vc_data *vc) +static void fn_SAK(struct vc_data *vc, struct pt_regs *regs) { struct tty_struct *tty = vc->vc_tty; @@ -606,7 +604,7 @@ static void fn_SAK(struct vc_data *vc) reset_vc(vc); } -static void fn_null(struct vc_data *vc) +static void fn_null(struct vc_data *vc, struct pt_regs *regs) { compute_shiftstate(); } @@ -614,11 +612,11 @@ static void fn_null(struct vc_data *vc) /* * Special key handlers */ -static void k_ignore(struct vc_data *vc, unsigned char value, char up_flag) +static void k_ignore(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) { } -static void k_spec(struct vc_data *vc, unsigned char value, char up_flag) +static void k_spec(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) { if (up_flag) return; @@ -628,15 +626,15 @@ static void k_spec(struct vc_data *vc, unsigned char value, char up_flag) kbd->kbdmode == VC_MEDIUMRAW) && value != KVAL(K_SAK)) return; /* SAK is allowed even in raw mode */ - fn_handler[value](vc); + fn_handler[value](vc, regs); } -static void k_lowercase(struct vc_data *vc, unsigned char value, char up_flag) +static void k_lowercase(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) { printk(KERN_ERR "keyboard.c: k_lowercase was called - impossible\n"); } -static void k_unicode(struct vc_data *vc, unsigned int value, char up_flag) +static void k_unicode(struct vc_data *vc, unsigned int value, char up_flag, struct pt_regs *regs) { if (up_flag) return; /* no action, if this is a key release */ @@ -660,41 +658,41 @@ static void k_unicode(struct vc_data *vc, unsigned int value, char up_flag) * dead keys modifying the same character. Very useful * for Vietnamese. */ -static void k_deadunicode(struct vc_data *vc, unsigned int value, char up_flag) +static void k_deadunicode(struct vc_data *vc, unsigned int value, char up_flag, struct pt_regs *regs) { if (up_flag) return; diacr = (diacr ? handle_diacr(vc, value) : value); } -static void k_self(struct vc_data *vc, unsigned char value, char up_flag) +static void k_self(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) { - k_unicode(vc, value, up_flag); + k_unicode(vc, value, up_flag, regs); } -static void k_dead2(struct vc_data *vc, unsigned char value, char up_flag) +static void k_dead2(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) { - k_deadunicode(vc, value, up_flag); + k_deadunicode(vc, value, up_flag, regs); } /* * Obsolete - for backwards compatibility only */ -static void k_dead(struct vc_data *vc, unsigned char value, char up_flag) +static void k_dead(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) { static const unsigned char ret_diacr[NR_DEAD] = {'`', '\'', '^', '~', '"', ',' }; value = ret_diacr[value]; - k_deadunicode(vc, value, up_flag); + k_deadunicode(vc, value, up_flag, regs); } -static void k_cons(struct vc_data *vc, unsigned char value, char up_flag) +static void k_cons(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) { if (up_flag) return; set_console(value); } -static void k_fn(struct vc_data *vc, unsigned char value, char up_flag) +static void k_fn(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) { unsigned v; @@ -708,7 +706,7 @@ static void k_fn(struct vc_data *vc, unsigned char value, char up_flag) printk(KERN_ERR "k_fn called with value=%d\n", value); } -static void k_cur(struct vc_data *vc, unsigned char value, char up_flag) +static void k_cur(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) { static const char *cur_chars = "BDCA"; @@ -717,7 +715,7 @@ static void k_cur(struct vc_data *vc, unsigned char value, char up_flag) applkey(vc, cur_chars[value], vc_kbd_mode(kbd, VC_CKMODE)); } -static void k_pad(struct vc_data *vc, unsigned char value, char up_flag) +static void k_pad(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) { static const char pad_chars[] = "0123456789+-*/\015,.?()#"; static const char app_map[] = "pqrstuvwxylSRQMnnmPQS"; @@ -735,34 +733,34 @@ static void k_pad(struct vc_data *vc, unsigned char value, char up_flag) switch (value) { case KVAL(K_PCOMMA): case KVAL(K_PDOT): - k_fn(vc, KVAL(K_REMOVE), 0); + k_fn(vc, KVAL(K_REMOVE), 0, regs); return; case KVAL(K_P0): - k_fn(vc, KVAL(K_INSERT), 0); + k_fn(vc, KVAL(K_INSERT), 0, regs); return; case KVAL(K_P1): - k_fn(vc, KVAL(K_SELECT), 0); + k_fn(vc, KVAL(K_SELECT), 0, regs); return; case KVAL(K_P2): - k_cur(vc, KVAL(K_DOWN), 0); + k_cur(vc, KVAL(K_DOWN), 0, regs); return; case KVAL(K_P3): - k_fn(vc, KVAL(K_PGDN), 0); + k_fn(vc, KVAL(K_PGDN), 0, regs); return; case KVAL(K_P4): - k_cur(vc, KVAL(K_LEFT), 0); + k_cur(vc, KVAL(K_LEFT), 0, regs); return; case KVAL(K_P6): - k_cur(vc, KVAL(K_RIGHT), 0); + k_cur(vc, KVAL(K_RIGHT), 0, regs); return; case KVAL(K_P7): - k_fn(vc, KVAL(K_FIND), 0); + k_fn(vc, KVAL(K_FIND), 0, regs); return; case KVAL(K_P8): - k_cur(vc, KVAL(K_UP), 0); + k_cur(vc, KVAL(K_UP), 0, regs); return; case KVAL(K_P9): - k_fn(vc, KVAL(K_PGUP), 0); + k_fn(vc, KVAL(K_PGUP), 0, regs); return; case KVAL(K_P5): applkey(vc, 'G', vc_kbd_mode(kbd, VC_APPLIC)); @@ -774,7 +772,7 @@ static void k_pad(struct vc_data *vc, unsigned char value, char up_flag) put_queue(vc, 10); } -static void k_shift(struct vc_data *vc, unsigned char value, char up_flag) +static void k_shift(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) { int old_state = shift_state; @@ -815,7 +813,7 @@ static void k_shift(struct vc_data *vc, unsigned char value, char up_flag) } } -static void k_meta(struct vc_data *vc, unsigned char value, char up_flag) +static void k_meta(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) { if (up_flag) return; @@ -827,7 +825,7 @@ static void k_meta(struct vc_data *vc, unsigned char value, char up_flag) put_queue(vc, value | 0x80); } -static void k_ascii(struct vc_data *vc, unsigned char value, char up_flag) +static void k_ascii(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) { int base; @@ -849,16 +847,16 @@ static void k_ascii(struct vc_data *vc, unsigned char value, char up_flag) npadch = npadch * base + value; } -static void k_lock(struct vc_data *vc, unsigned char value, char up_flag) +static void k_lock(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) { if (up_flag || rep) return; chg_vc_kbd_lock(kbd, value); } -static void k_slock(struct vc_data *vc, unsigned char value, char up_flag) +static void k_slock(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) { - k_shift(vc, value, up_flag); + k_shift(vc, value, up_flag, regs); if (up_flag || rep) return; chg_vc_kbd_slock(kbd, value); @@ -878,25 +876,25 @@ static unsigned brl_nbchords = 1; MODULE_PARM_DESC(brl_nbchords, "Number of chords that produce a braille pattern (0 for dead chords)"); module_param(brl_nbchords, uint, 0644); -static void k_brlcommit(struct vc_data *vc, unsigned int pattern, char up_flag) +static void k_brlcommit(struct vc_data *vc, unsigned int pattern, char up_flag, struct pt_regs *regs) { static unsigned long chords; static unsigned committed; if (!brl_nbchords) - k_deadunicode(vc, BRL_UC_ROW | pattern, up_flag); + k_deadunicode(vc, BRL_UC_ROW | pattern, up_flag, regs); else { committed |= pattern; chords++; if (chords == brl_nbchords) { - k_unicode(vc, BRL_UC_ROW | committed, up_flag); + k_unicode(vc, BRL_UC_ROW | committed, up_flag, regs); chords = 0; committed = 0; } } } -static void k_brl(struct vc_data *vc, unsigned char value, char up_flag) +static void k_brl(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) { static unsigned pressed,committing; static unsigned long releasestart; @@ -908,7 +906,7 @@ static void k_brl(struct vc_data *vc, unsigned char value, char up_flag) } if (!value) { - k_unicode(vc, BRL_UC_ROW, up_flag); + k_unicode(vc, BRL_UC_ROW, up_flag, regs); return; } @@ -925,13 +923,13 @@ static void k_brl(struct vc_data *vc, unsigned char value, char up_flag) pressed &= ~(1 << (value - 1)); if (!pressed) { if (committing) { - k_brlcommit(vc, committing, 0); + k_brlcommit(vc, committing, 0, regs); committing = 0; } } } else { if (committing) { - k_brlcommit(vc, committing, 0); + k_brlcommit(vc, committing, 0, regs); committing = 0; } pressed &= ~(1 << (value - 1)); @@ -1135,7 +1133,8 @@ static void kbd_rawcode(unsigned char data) put_queue(vc, data); } -static void kbd_keycode(unsigned int keycode, int down, int hw_raw) +static void kbd_keycode(unsigned int keycode, int down, + int hw_raw, struct pt_regs *regs) { struct vc_data *vc = vc_cons[fg_console].d; unsigned short keysym, *key_map; @@ -1182,7 +1181,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) if (sysrq_down && !down && keycode == sysrq_alt_use) sysrq_down = 0; if (sysrq_down && down && !rep) { - handle_sysrq(kbd_sysrq_xlate[keycode], tty); + handle_sysrq(kbd_sysrq_xlate[keycode], regs, tty); return; } #endif @@ -1268,7 +1267,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) } } - (*k_handler[type])(vc, keysym & 0xff, !down); + (*k_handler[type])(vc, keysym & 0xff, !down, regs); if (type != KT_SLOCK) kbd->slockstate = 0; @@ -1280,7 +1279,7 @@ static void kbd_event(struct input_handle *handle, unsigned int event_type, if (event_type == EV_MSC && event_code == MSC_RAW && HW_RAW(handle->dev)) kbd_rawcode(value); if (event_type == EV_KEY) - kbd_keycode(event_code, value, HW_RAW(handle->dev)); + kbd_keycode(event_code, value, HW_RAW(handle->dev), handle->dev->regs); tasklet_schedule(&keyboard_tasklet); do_poke_blanked_console = 1; schedule_console_callback(); diff --git a/trunk/drivers/char/mbcs.c b/trunk/drivers/char/mbcs.c index 0afb7ba999cf..636354722658 100644 --- a/trunk/drivers/char/mbcs.c +++ b/trunk/drivers/char/mbcs.c @@ -516,10 +516,11 @@ int mbcs_gscr_mmap(struct file *fp, struct vm_area_struct *vma) * mbcs_completion_intr_handler - Primary completion handler. * @irq: irq * @arg: soft struct for device + * @ep: regs * */ static irqreturn_t -mbcs_completion_intr_handler(int irq, void *arg) +mbcs_completion_intr_handler(int irq, void *arg, struct pt_regs *ep) { struct mbcs_soft *soft = (struct mbcs_soft *)arg; void *mmr_base; diff --git a/trunk/drivers/char/mem.c b/trunk/drivers/char/mem.c index e67eef4867ba..6511012cbdcd 100644 --- a/trunk/drivers/char/mem.c +++ b/trunk/drivers/char/mem.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include @@ -293,8 +292,8 @@ static int mmap_kmem(struct file * file, struct vm_area_struct * vma) { unsigned long pfn; - /* Turn a pfn offset into an absolute pfn */ - pfn = PFN_DOWN(virt_to_phys((void *)PAGE_OFFSET)) + vma->vm_pgoff; + /* Turn a kernel-virtual address into a physical page frame */ + pfn = __pa((u64)vma->vm_pgoff << PAGE_SHIFT) >> PAGE_SHIFT; /* * RED-PEN: on some architectures there is more mapped memory @@ -980,10 +979,10 @@ static int __init chr_dev_init(void) mem_class = class_create(THIS_MODULE, "mem"); for (i = 0; i < ARRAY_SIZE(devlist); i++) - device_create(mem_class, NULL, - MKDEV(MEM_MAJOR, devlist[i].minor), - devlist[i].name); - + class_device_create(mem_class, NULL, + MKDEV(MEM_MAJOR, devlist[i].minor), + NULL, devlist[i].name); + return 0; } diff --git a/trunk/drivers/char/misc.c b/trunk/drivers/char/misc.c index 7a484fc7cb9e..62ebe09656e3 100644 --- a/trunk/drivers/char/misc.c +++ b/trunk/drivers/char/misc.c @@ -169,6 +169,11 @@ static int misc_open(struct inode * inode, struct file * file) return err; } +/* + * TODO for 2.7: + * - add a struct kref to struct miscdevice and make all usages of + * them dynamic. + */ static struct class *misc_class; static const struct file_operations misc_fops = { @@ -223,10 +228,10 @@ int misc_register(struct miscdevice * misc) misc_minors[misc->minor >> 3] |= 1 << (misc->minor & 7); dev = MKDEV(MISC_MAJOR, misc->minor); - misc->this_device = device_create(misc_class, misc->parent, dev, + misc->class = class_device_create(misc_class, NULL, dev, misc->dev, "%s", misc->name); - if (IS_ERR(misc->this_device)) { - err = PTR_ERR(misc->this_device); + if (IS_ERR(misc->class)) { + err = PTR_ERR(misc->class); goto out; } @@ -259,7 +264,7 @@ int misc_deregister(struct miscdevice * misc) down(&misc_sem); list_del(&misc->list); - device_destroy(misc_class, MKDEV(MISC_MAJOR, misc->minor)); + class_device_destroy(misc_class, MKDEV(MISC_MAJOR, misc->minor)); if (i < DYNAMIC_MINORS && i>0) { misc_minors[i>>3] &= ~(1 << (misc->minor & 7)); } diff --git a/trunk/drivers/char/mmtimer.c b/trunk/drivers/char/mmtimer.c index 22b9905c1e52..1f0f2b6dae26 100644 --- a/trunk/drivers/char/mmtimer.c +++ b/trunk/drivers/char/mmtimer.c @@ -422,6 +422,7 @@ static int inline reschedule_periodic_timer(mmtimer_t *x) * mmtimer_interrupt - timer interrupt handler * @irq: irq received * @dev_id: device the irq came from + * @regs: register state upon receipt of the interrupt * * Called when one of the comarators matches the counter, This * routine will send signals to processes that have requested @@ -432,7 +433,7 @@ static int inline reschedule_periodic_timer(mmtimer_t *x) * registers. */ static irqreturn_t -mmtimer_interrupt(int irq, void *dev_id) +mmtimer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { int i; unsigned long expires = 0; diff --git a/trunk/drivers/char/moxa.c b/trunk/drivers/char/moxa.c index 96cb1f07332b..b401383808c2 100644 --- a/trunk/drivers/char/moxa.c +++ b/trunk/drivers/char/moxa.c @@ -130,7 +130,6 @@ static moxa_isa_board_conf moxa_isa_boards[] = typedef struct _moxa_pci_devinfo { ushort busNum; ushort devNum; - struct pci_dev *pdev; } moxa_pci_devinfo; typedef struct _moxa_board_conf { @@ -325,9 +324,6 @@ static int moxa_get_PCI_conf(struct pci_dev *p, int board_type, moxa_board_conf board->busType = MOXA_BUS_TYPE_PCI; board->pciInfo.busNum = p->bus->number; board->pciInfo.devNum = p->devfn >> 3; - board->pciInfo.pdev = p; - /* don't lose the reference in the next pci_get_device iteration */ - pci_dev_get(p); return (0); } @@ -497,11 +493,6 @@ static void __exit moxa_exit(void) if (tty_unregister_driver(moxaDriver)) printk("Couldn't unregister MOXA Intellio family serial driver\n"); put_tty_driver(moxaDriver); - - 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/mspec.c b/trunk/drivers/char/mspec.c index 235e89226112..5c0dec39cf6c 100644 --- a/trunk/drivers/char/mspec.c +++ b/trunk/drivers/char/mspec.c @@ -72,11 +72,7 @@ enum { MSPEC_UNCACHED }; -#ifdef CONFIG_SGI_SN static int is_sn2; -#else -#define is_sn2 0 -#endif /* * One of these structures is allocated when an mspec region is mmaped. The @@ -215,7 +211,7 @@ mspec_nopfn(struct vm_area_struct *vma, unsigned long address) if (vdata->type == MSPEC_FETCHOP) paddr = TO_AMO(maddr); else - paddr = maddr & ~__IA64_UNCACHED_OFFSET; + paddr = __pa(TO_CAC(maddr)); pfn = paddr >> PAGE_SHIFT; @@ -339,7 +335,6 @@ mspec_init(void) * The fetchop device only works on SN2 hardware, uncached and cached * memory drivers should both be valid on all ia64 hardware */ -#ifdef CONFIG_SGI_SN if (ia64_platform_is("sn2")) { is_sn2 = 1; if (is_shub2()) { @@ -368,7 +363,6 @@ mspec_init(void) goto free_scratch_pages; } } -#endif ret = misc_register(&cached_miscdev); if (ret) { printk(KERN_ERR "%s: failed to register device %i\n", diff --git a/trunk/drivers/char/mwave/tp3780i.c b/trunk/drivers/char/mwave/tp3780i.c index f282976daaac..cc3e54dd7234 100644 --- a/trunk/drivers/char/mwave/tp3780i.c +++ b/trunk/drivers/char/mwave/tp3780i.c @@ -95,14 +95,14 @@ static void EnableSRAM(THINKPAD_BD_DATA * pBDData) } -static irqreturn_t UartInterrupt(int irq, void *dev_id) +static irqreturn_t UartInterrupt(int irq, void *dev_id, struct pt_regs *regs) { PRINTK_3(TRACE_TP3780I, "tp3780i::UartInterrupt entry irq %x dev_id %p\n", irq, dev_id); return IRQ_HANDLED; } -static irqreturn_t DspInterrupt(int irq, void *dev_id) +static irqreturn_t DspInterrupt(int irq, void *dev_id, struct pt_regs *regs) { pMWAVE_DEVICE_DATA pDrvData = &mwave_s_mdd; DSP_3780I_CONFIG_SETTINGS *pSettings = &pDrvData->rBDData.rDspSettings; diff --git a/trunk/drivers/char/mxser.c b/trunk/drivers/char/mxser.c index 048d91142c17..8253fca8efd5 100644 --- a/trunk/drivers/char/mxser.c +++ b/trunk/drivers/char/mxser.c @@ -407,7 +407,7 @@ static void mxser_stop(struct tty_struct *); static void mxser_start(struct tty_struct *); static void mxser_hangup(struct tty_struct *); static void mxser_rs_break(struct tty_struct *, int); -static irqreturn_t mxser_interrupt(int, void *); +static irqreturn_t mxser_interrupt(int, void *, struct pt_regs *); static void mxser_receive_chars(struct mxser_struct *, int *); static void mxser_transmit_chars(struct mxser_struct *); static void mxser_check_modem_status(struct mxser_struct *, int); @@ -1916,7 +1916,7 @@ static void mxser_rs_break(struct tty_struct *tty, int break_state) /* * This is the serial driver's generic interrupt routine */ -static irqreturn_t mxser_interrupt(int irq, void *dev_id) +static irqreturn_t mxser_interrupt(int irq, void *dev_id, struct pt_regs *regs) { int status, iir, i; struct mxser_struct *info; diff --git a/trunk/drivers/char/nwbutton.c b/trunk/drivers/char/nwbutton.c index 2d264971d839..ea1aa7764f8e 100644 --- a/trunk/drivers/char/nwbutton.c +++ b/trunk/drivers/char/nwbutton.c @@ -144,7 +144,7 @@ static void button_sequence_finished (unsigned long parameters) * increments the counter. */ -static irqreturn_t button_handler (int irq, void *dev_id) +static irqreturn_t button_handler (int irq, void *dev_id, struct pt_regs *regs) { if (button_press_count) { del_timer (&button_timer); diff --git a/trunk/drivers/char/nwbutton.h b/trunk/drivers/char/nwbutton.h index c3ebc16ce8a7..ddb7b928dcbb 100644 --- a/trunk/drivers/char/nwbutton.h +++ b/trunk/drivers/char/nwbutton.h @@ -25,7 +25,7 @@ struct button_callback { /* Function prototypes: */ static void button_sequence_finished (unsigned long parameters); -static irqreturn_t button_handler (int irq, void *dev_id); +static irqreturn_t button_handler (int irq, void *dev_id, struct pt_regs *regs); int button_init (void); int button_add_callback (void (*callback) (void), int count); int button_del_callback (void (*callback) (void)); diff --git a/trunk/drivers/char/pcmcia/synclink_cs.c b/trunk/drivers/char/pcmcia/synclink_cs.c index 1a0bc30b79d1..73e324209913 100644 --- a/trunk/drivers/char/pcmcia/synclink_cs.c +++ b/trunk/drivers/char/pcmcia/synclink_cs.c @@ -416,7 +416,7 @@ static void rx_reset_buffers(MGSLPC_INFO *info); static int rx_alloc_buffers(MGSLPC_INFO *info); static void rx_free_buffers(MGSLPC_INFO *info); -static irqreturn_t mgslpc_isr(int irq, void *dev_id); +static irqreturn_t mgslpc_isr(int irq, void *dev_id, struct pt_regs * regs); /* * Bottom half interrupt handlers @@ -1234,8 +1234,9 @@ static void ri_change(MGSLPC_INFO *info) * * irq interrupt number that caused interrupt * dev_id device ID supplied during interrupt registration + * regs interrupted processor context */ -static irqreturn_t mgslpc_isr(int irq, void *dev_id) +static irqreturn_t mgslpc_isr(int irq, void *dev_id, struct pt_regs * regs) { MGSLPC_INFO * info = (MGSLPC_INFO *)dev_id; unsigned short isr; diff --git a/trunk/drivers/char/ppdev.c b/trunk/drivers/char/ppdev.c index c1e3dd837fc8..520d2cf82bc0 100644 --- a/trunk/drivers/char/ppdev.c +++ b/trunk/drivers/char/ppdev.c @@ -269,7 +269,7 @@ static ssize_t pp_write (struct file * file, const char __user * buf, return bytes_written; } -static void pp_irq (int irq, void * private) +static void pp_irq (int irq, void * private, struct pt_regs * unused) { struct pp_struct * pp = (struct pp_struct *) private; @@ -752,13 +752,13 @@ static const struct file_operations pp_fops = { static void pp_attach(struct parport *port) { - device_create(ppdev_class, NULL, MKDEV(PP_MAJOR, port->number), - "parport%d", port->number); + class_device_create(ppdev_class, NULL, MKDEV(PP_MAJOR, port->number), + NULL, "parport%d", port->number); } static void pp_detach(struct parport *port) { - device_destroy(ppdev_class, MKDEV(PP_MAJOR, port->number)); + class_device_destroy(ppdev_class, MKDEV(PP_MAJOR, port->number)); } static struct parport_driver pp_driver = { diff --git a/trunk/drivers/char/qtronix.c b/trunk/drivers/char/qtronix.c new file mode 100644 index 000000000000..9d134e98d2a0 --- /dev/null +++ b/trunk/drivers/char/qtronix.c @@ -0,0 +1,605 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * Qtronix 990P infrared keyboard driver. + * + * + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * + * The bottom portion of this driver was take from + * pc_keyb.c Please see that file for copyrights. + * + * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +/* + * NOTE: + * + * This driver has only been tested with the Consumer IR + * port of the ITE 8172 system controller. + * + * You do not need this driver if you are using the ps/2 or + * USB adapter that the keyboard ships with. You only need + * this driver if your board has a IR port and the keyboard + * data is being sent directly to the IR. In that case, + * you also need some low-level IR support. See it8172_cir.c. + * + */ + +#ifdef CONFIG_QTRONIX_KEYBOARD + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define leading1 0 +#define leading2 0xF + +#define KBD_CIR_PORT 0 +#define AUX_RECONNECT 170 /* scancode when ps2 device is plugged (back) in */ + +static int data_index; +struct cir_port *cir; +static unsigned char kbdbytes[5]; +static unsigned char cir_data[32]; /* we only need 16 chars */ + +static void kbd_int_handler(int irq, void *dev_id, struct pt_regs *regs); +static int handle_data(unsigned char *p_data); +static inline void handle_mouse_event(unsigned char scancode); +static inline void handle_keyboard_event(unsigned char scancode, int down); +static int __init psaux_init(void); + +static struct aux_queue *queue; /* Mouse data buffer. */ +static int aux_count = 0; + +/* + * Keys accessed through the 'Fn' key + * The Fn key does not produce a key-up sequence. So, the first + * time the user presses it, it will be key-down event. The key + * stays down until the user presses it again. + */ +#define NUM_FN_KEYS 56 +static unsigned char fn_keys[NUM_FN_KEYS] = { + 0,0,0,0,0,0,0,0, /* 0 7 */ + 8,9,10,93,0,0,0,0, /* 8 15 */ + 0,0,0,0,0,0,0,5, /* 16 23 */ + 6,7,91,0,0,0,0,0, /* 24 31 */ + 0,0,0,0,0,2,3,4, /* 32 39 */ + 92,0,0,0,0,0,0,0, /* 40 47 */ + 0,0,0,0,11,0,94,95 /* 48 55 */ + +}; + +void __init init_qtronix_990P_kbd(void) +{ + int retval; + + cir = (struct cir_port *)kmalloc(sizeof(struct cir_port), GFP_KERNEL); + if (!cir) { + printk("Unable to initialize Qtronix keyboard\n"); + return; + } + + /* + * revisit + * this should be programmable, somehow by the, by the user. + */ + cir->port = KBD_CIR_PORT; + cir->baud_rate = 0x1d; + cir->rdwos = 0; + cir->rxdcr = 0x3; + cir->hcfs = 0; + cir->fifo_tl = 0; + cir->cfq = 0x1d; + cir_port_init(cir); + + retval = request_irq(IT8172_CIR0_IRQ, kbd_int_handler, + (unsigned long )(IRQF_DISABLED|IRQF_SHARED), + (const char *)"Qtronix IR Keyboard", (void *)cir); + + if (retval) { + printk("unable to allocate cir %d irq %d\n", + cir->port, IT8172_CIR0_IRQ); + } +#ifdef CONFIG_PSMOUSE + psaux_init(); +#endif +} + +static inline unsigned char BitReverse(unsigned short key) +{ + unsigned char rkey = 0; + rkey |= (key & 0x1) << 7; + rkey |= (key & 0x2) << 5; + rkey |= (key & 0x4) << 3; + rkey |= (key & 0x8) << 1; + rkey |= (key & 0x10) >> 1; + rkey |= (key & 0x20) >> 3; + rkey |= (key & 0x40) >> 5; + rkey |= (key & 0x80) >> 7; + return rkey; + +} + + +static inline u_int8_t UpperByte(u_int8_t data) +{ + return (data >> 4); +} + + +static inline u_int8_t LowerByte(u_int8_t data) +{ + return (data & 0xF); +} + + +int CheckSumOk(u_int8_t byte1, u_int8_t byte2, + u_int8_t byte3, u_int8_t byte4, u_int8_t byte5) +{ + u_int8_t CheckSum; + + CheckSum = (byte1 & 0x0F) + byte2 + byte3 + byte4 + byte5; + if ( LowerByte(UpperByte(CheckSum) + LowerByte(CheckSum)) != UpperByte(byte1) ) + return 0; + else + return 1; +} + + +static void kbd_int_handler(int irq, void *dev_id, struct pt_regs *regs) +{ + struct cir_port *cir; + int j; + unsigned char int_status; + + cir = (struct cir_port *)dev_id; + int_status = get_int_status(cir); + if (int_status & 0x4) { + clear_fifo(cir); + return; + } + + while (cir_get_rx_count(cir)) { + + cir_data[data_index] = cir_read_data(cir); + + if (data_index == 0) {/* expecting first byte */ + if (cir_data[data_index] != leading1) { + //printk("!leading byte %x\n", cir_data[data_index]); + set_rx_active(cir); + clear_fifo(cir); + continue; + } + } + if (data_index == 1) { + if ((cir_data[data_index] & 0xf) != leading2) { + set_rx_active(cir); + data_index = 0; /* start over */ + clear_fifo(cir); + continue; + } + } + + if ( (cir_data[data_index] == 0xff)) { /* last byte */ + //printk("data_index %d\n", data_index); + set_rx_active(cir); +#if 0 + for (j=0; j<=data_index; j++) { + printk("rx_data %d: %x\n", j, cir_data[j]); + } +#endif + data_index = 0; + handle_data(cir_data); + return; + } + else if (data_index>16) { + set_rx_active(cir); +#if 0 + printk("warning: data_index %d\n", data_index); + for (j=0; j<=data_index; j++) { + printk("rx_data %d: %x\n", j, cir_data[j]); + } +#endif + data_index = 0; + clear_fifo(cir); + return; + } + data_index++; + } +} + + +#define NUM_KBD_BYTES 5 +static int handle_data(unsigned char *p_data) +{ + u_int32_t bit_bucket; + u_int32_t i, j; + u_int32_t got_bits, next_byte; + int down = 0; + + /* Reorganize the bit stream */ + for (i=0; i<16; i++) + p_data[i] = BitReverse(~p_data[i]); + + /* + * We've already previously checked that p_data[0] + * is equal to leading1 and that (p_data[1] & 0xf) + * is equal to leading2. These twelve bits are the + * leader code. We can now throw them away (the 12 + * bits) and continue parsing the stream. + */ + bit_bucket = p_data[1] << 12; + got_bits = 4; + next_byte = 2; + + /* + * Process four bits at a time + */ + for (i=0; i> 1); + got_bits -= 4; + bit_bucket = bit_bucket << 4; + } + else if ((bit_bucket & 0xC000) == 0x8000) { + /* Convert 10b to 0 */ + kbdbytes[i] = kbdbytes[i] >> 1; + got_bits -= 2; + bit_bucket = bit_bucket << 2; + } + else { + /* bad serial stream */ + return 1; + } + + if (next_byte > 16) { + //printk("error: too many bytes\n"); + return 1; + } + } + } + + + if (!CheckSumOk(kbdbytes[0], kbdbytes[1], + kbdbytes[2], kbdbytes[3], kbdbytes[4])) { + //printk("checksum failed\n"); + return 1; + } + + if (kbdbytes[1] & 0x08) { + //printk("m: %x %x %x\n", kbdbytes[1], kbdbytes[2], kbdbytes[3]); + handle_mouse_event(kbdbytes[1]); + handle_mouse_event(kbdbytes[2]); + handle_mouse_event(kbdbytes[3]); + } + else { + if (kbdbytes[2] == 0) down = 1; +#if 0 + if (down) + printk("down %d\n", kbdbytes[3]); + else + printk("up %d\n", kbdbytes[3]); +#endif + handle_keyboard_event(kbdbytes[3], down); + } + return 0; +} + + +DEFINE_SPINLOCK(kbd_controller_lock); +static unsigned char handle_kbd_event(void); + + +int kbd_setkeycode(unsigned int scancode, unsigned int keycode) +{ + printk("kbd_setkeycode scancode %x keycode %x\n", scancode, keycode); + return 0; +} + +int kbd_getkeycode(unsigned int scancode) +{ + return scancode; +} + + +int kbd_translate(unsigned char scancode, unsigned char *keycode, + char raw_mode) +{ + static int prev_scancode = 0; + + if (scancode == 0x00 || scancode == 0xff) { + prev_scancode = 0; + return 0; + } + + /* todo */ + if (!prev_scancode && scancode == 160) { /* Fn key down */ + //printk("Fn key down\n"); + prev_scancode = 160; + return 0; + } + else if (prev_scancode && scancode == 160) { /* Fn key up */ + //printk("Fn key up\n"); + prev_scancode = 0; + return 0; + } + + /* todo */ + if (prev_scancode == 160) { + if (scancode <= NUM_FN_KEYS) { + *keycode = fn_keys[scancode]; + //printk("fn keycode %d\n", *keycode); + } + else + return 0; + } + else if (scancode <= 127) { + *keycode = scancode; + } + else + return 0; + + + return 1; +} + +char kbd_unexpected_up(unsigned char keycode) +{ + //printk("kbd_unexpected_up\n"); + return 0; +} + +static unsigned char kbd_exists = 1; + +static inline void handle_keyboard_event(unsigned char scancode, int down) +{ + kbd_exists = 1; + handle_scancode(scancode, down); + tasklet_schedule(&keyboard_tasklet); +} + + +void kbd_leds(unsigned char leds) +{ +} + +/* dummy */ +void kbd_init_hw(void) +{ +} + + + +static inline void handle_mouse_event(unsigned char scancode) +{ + if(scancode == AUX_RECONNECT){ + queue->head = queue->tail = 0; /* Flush input queue */ + // __aux_write_ack(AUX_ENABLE_DEV); /* ping the mouse :) */ + return; + } + + if (aux_count) { + int head = queue->head; + + queue->buf[head] = scancode; + head = (head + 1) & (AUX_BUF_SIZE-1); + if (head != queue->tail) { + queue->head = head; + kill_fasync(&queue->fasync, SIGIO, POLL_IN); + wake_up_interruptible(&queue->proc_list); + } + } +} + +static unsigned char get_from_queue(void) +{ + unsigned char result; + unsigned long flags; + + spin_lock_irqsave(&kbd_controller_lock, flags); + result = queue->buf[queue->tail]; + queue->tail = (queue->tail + 1) & (AUX_BUF_SIZE-1); + spin_unlock_irqrestore(&kbd_controller_lock, flags); + return result; +} + + +static inline int queue_empty(void) +{ + return queue->head == queue->tail; +} + +static int fasync_aux(int fd, struct file *filp, int on) +{ + int retval; + + //printk("fasync_aux\n"); + retval = fasync_helper(fd, filp, on, &queue->fasync); + if (retval < 0) + return retval; + return 0; +} + + +/* + * Random magic cookie for the aux device + */ +#define AUX_DEV ((void *)queue) + +static int release_aux(struct inode * inode, struct file * file) +{ + fasync_aux(-1, file, 0); + aux_count--; + return 0; +} + +static int open_aux(struct inode * inode, struct file * file) +{ + if (aux_count++) { + return 0; + } + queue->head = queue->tail = 0; /* Flush input queue */ + return 0; +} + +/* + * Put bytes from input queue to buffer. + */ + +static ssize_t read_aux(struct file * file, char * buffer, + size_t count, loff_t *ppos) +{ + DECLARE_WAITQUEUE(wait, current); + ssize_t i = count; + unsigned char c; + + if (queue_empty()) { + if (file->f_flags & O_NONBLOCK) + return -EAGAIN; + add_wait_queue(&queue->proc_list, &wait); +repeat: + set_current_state(TASK_INTERRUPTIBLE); + if (queue_empty() && !signal_pending(current)) { + schedule(); + goto repeat; + } + current->state = TASK_RUNNING; + remove_wait_queue(&queue->proc_list, &wait); + } + while (i > 0 && !queue_empty()) { + c = get_from_queue(); + put_user(c, buffer++); + i--; + } + if (count-i) { + struct inode *inode = file->f_dentry->d_inode; + inode->i_atime = current_fs_time(inode->i_sb); + return count-i; + } + if (signal_pending(current)) + return -ERESTARTSYS; + return 0; +} + +/* + * Write to the aux device. + */ + +static ssize_t write_aux(struct file * file, const char * buffer, + size_t count, loff_t *ppos) +{ + /* + * The ITE boards this was tested on did not have the + * transmit wires connected. + */ + return count; +} + +static unsigned int aux_poll(struct file *file, poll_table * wait) +{ + poll_wait(file, &queue->proc_list, wait); + if (!queue_empty()) + return POLLIN | POLLRDNORM; + return 0; +} + +struct file_operations psaux_fops = { + .read = read_aux, + .write = write_aux, + .poll = aux_poll, + .open = open_aux, + .release = release_aux, + .fasync = fasync_aux, +}; + +/* + * Initialize driver. + */ +static struct miscdevice psaux_mouse = { + PSMOUSE_MINOR, "psaux", &psaux_fops +}; + +static int __init psaux_init(void) +{ + int retval; + + retval = misc_register(&psaux_mouse); + if(retval < 0) + return retval; + + queue = (struct aux_queue *) kmalloc(sizeof(*queue), GFP_KERNEL); + if (!queue) { + misc_deregister(&psaux_mouse); + return -ENOMEM; + } + + memset(queue, 0, sizeof(*queue)); + queue->head = queue->tail = 0; + init_waitqueue_head(&queue->proc_list); + + return 0; +} +module_init(init_qtronix_990P_kbd); +#endif diff --git a/trunk/drivers/char/random.c b/trunk/drivers/char/random.c index eb6b13f4211a..07f47a0208a7 100644 --- a/trunk/drivers/char/random.c +++ b/trunk/drivers/char/random.c @@ -645,7 +645,6 @@ void add_input_randomness(unsigned int type, unsigned int code, add_timer_randomness(&input_timer_state, (type << 4) ^ code ^ (code >> 4) ^ value); } -EXPORT_SYMBOL_GPL(add_input_randomness); void add_interrupt_randomness(int irq) { diff --git a/trunk/drivers/char/raw.c b/trunk/drivers/char/raw.c index 3b32313f6eb4..89b718e326e5 100644 --- a/trunk/drivers/char/raw.c +++ b/trunk/drivers/char/raw.c @@ -127,9 +127,9 @@ raw_ioctl(struct inode *inode, struct file *filp, static void bind_device(struct raw_config_request *rq) { - device_destroy(raw_class, MKDEV(RAW_MAJOR, rq->raw_minor)); - device_create(raw_class, NULL, MKDEV(RAW_MAJOR, rq->raw_minor), - "raw%d", rq->raw_minor); + class_device_destroy(raw_class, MKDEV(RAW_MAJOR, rq->raw_minor)); + class_device_create(raw_class, NULL, MKDEV(RAW_MAJOR, rq->raw_minor), + NULL, "raw%d", rq->raw_minor); } /* @@ -200,7 +200,7 @@ static int raw_ctl_ioctl(struct inode *inode, struct file *filp, if (rq.block_major == 0 && rq.block_minor == 0) { /* unbind */ rawdev->binding = NULL; - device_destroy(raw_class, + class_device_destroy(raw_class, MKDEV(RAW_MAJOR, rq.raw_minor)); } else { rawdev->binding = bdget(dev); @@ -283,7 +283,7 @@ static int __init raw_init(void) ret = PTR_ERR(raw_class); goto error_region; } - device_create(raw_class, NULL, MKDEV(RAW_MAJOR, 0), "rawctl"); + class_device_create(raw_class, NULL, MKDEV(RAW_MAJOR, 0), NULL, "rawctl"); return 0; @@ -295,7 +295,7 @@ static int __init raw_init(void) static void __exit raw_exit(void) { - device_destroy(raw_class, MKDEV(RAW_MAJOR, 0)); + class_device_destroy(raw_class, MKDEV(RAW_MAJOR, 0)); class_destroy(raw_class); cdev_del(&raw_cdev); unregister_chrdev_region(MKDEV(RAW_MAJOR, 0), MAX_RAW_MINORS); diff --git a/trunk/drivers/char/rio/func.h b/trunk/drivers/char/rio/func.h index 9e7283bd81a0..6b039186856d 100644 --- a/trunk/drivers/char/rio/func.h +++ b/trunk/drivers/char/rio/func.h @@ -88,7 +88,7 @@ void RIOHostReset(unsigned int, struct DpRam __iomem *, unsigned int); /* riointr.c */ void RIOTxEnable(char *); -void RIOServiceHost(struct rio_info *, struct Host *); +void RIOServiceHost(struct rio_info *, struct Host *, int); int riotproc(struct rio_info *, struct ttystatics *, int, int); /* rioparam.c */ diff --git a/trunk/drivers/char/rio/host.h b/trunk/drivers/char/rio/host.h index 23d0681fe491..ee2ddea7a63a 100644 --- a/trunk/drivers/char/rio/host.h +++ b/trunk/drivers/char/rio/host.h @@ -44,7 +44,6 @@ ** the host. */ struct Host { - struct pci_dev *pdev; unsigned char Type; /* RIO_EISA, RIO_MCA, ... */ unsigned char Ivec; /* POLLED or ivec number */ unsigned char Mode; /* Control stuff */ diff --git a/trunk/drivers/char/rio/rio_linux.c b/trunk/drivers/char/rio/rio_linux.c index 7ac68cb3bedd..202a3b0945b7 100644 --- a/trunk/drivers/char/rio/rio_linux.c +++ b/trunk/drivers/char/rio/rio_linux.c @@ -363,12 +363,12 @@ static void rio_reset_interrupt(struct Host *HostP) } -static irqreturn_t rio_interrupt(int irq, void *ptr) +static irqreturn_t rio_interrupt(int irq, void *ptr, struct pt_regs *regs) { struct Host *HostP; func_enter(); - HostP = ptr; /* &p->RIOHosts[(long)ptr]; */ + HostP = (struct Host *) ptr; /* &p->RIOHosts[(long)ptr]; */ rio_dprintk(RIO_DEBUG_IFLOW, "rio: enter rio_interrupt (%d/%d)\n", irq, HostP->Ivec); /* AAargh! The order in which to do these things is essential and @@ -402,7 +402,7 @@ static irqreturn_t rio_interrupt(int irq, void *ptr) return IRQ_HANDLED; } - RIOServiceHost(p, HostP); + RIOServiceHost(p, HostP, irq); rio_dprintk(RIO_DEBUG_IFLOW, "riointr() doing host %p type %d\n", ptr, HostP->Type); @@ -417,7 +417,7 @@ static void rio_pollfunc(unsigned long data) { func_enter(); - rio_interrupt(0, &p->RIOHosts[data]); + rio_interrupt(0, &p->RIOHosts[data], NULL); p->RIOHosts[data].timer.expires = jiffies + rio_poll; add_timer(&p->RIOHosts[data].timer); @@ -1017,10 +1017,6 @@ static int __init rio_init(void) rio_dprintk(RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n", p->RIOHosts[p->RIONumHosts].UniqueNum); fix_rio_pci(pdev); - - p->RIOHosts[p->RIONumHosts].pdev = pdev; - pci_dev_get(pdev); - p->RIOLastPCISearch = 0; p->RIONumHosts++; found++; @@ -1070,9 +1066,6 @@ static int __init rio_init(void) ((readb(&p->RIOHosts[p->RIONumHosts].Unique[1]) & 0xFF) << 8) | ((readb(&p->RIOHosts[p->RIONumHosts].Unique[2]) & 0xFF) << 16) | ((readb(&p->RIOHosts[p->RIONumHosts].Unique[3]) & 0xFF) << 24); rio_dprintk(RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n", p->RIOHosts[p->RIONumHosts].UniqueNum); - p->RIOHosts[p->RIONumHosts].pdev = pdev; - pci_dev_get(pdev); - p->RIOLastPCISearch = 0; p->RIONumHosts++; found++; @@ -1188,8 +1181,6 @@ static void __exit rio_exit(void) } /* It is safe/allowed to del_timer a non-active timer */ del_timer(&hp->timer); - if (hp->Type == RIO_PCI) - pci_dev_put(hp->pdev); } if (misc_deregister(&rio_fw_device) < 0) { diff --git a/trunk/drivers/char/rio/riocmd.c b/trunk/drivers/char/rio/riocmd.c index 167ebc84e8d7..4df6ab2206a1 100644 --- a/trunk/drivers/char/rio/riocmd.c +++ b/trunk/drivers/char/rio/riocmd.c @@ -922,7 +922,7 @@ int RIOUnUse(unsigned long iPortP, struct CmdBlk *CmdBlkP) ** ** Packet is an actual packet structure to be filled in with the packet ** information associated with the command. You need to fill in everything, -** as the command processor doesn't process the command packet in any way. +** as the command processore doesn't process the command packet in any way. ** ** The PreFuncP is called before the packet is enqueued on the host rup. ** PreFuncP is called as (*PreFuncP)(PreArg, CmdBlkP);. PreFuncP must diff --git a/trunk/drivers/char/rio/rioctrl.c b/trunk/drivers/char/rio/rioctrl.c index 7ce77619707c..052e8120a471 100644 --- a/trunk/drivers/char/rio/rioctrl.c +++ b/trunk/drivers/char/rio/rioctrl.c @@ -662,7 +662,7 @@ int riocontrol(struct rio_info *p, dev_t dev, int cmd, unsigned long arg, int su p->RIOError.Error = COPYIN_FAILED; return -EFAULT; } - if (portStats.port < 0 || portStats.port >= RIO_PORTS) { + if (portStats.port >= RIO_PORTS) { p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; return -ENXIO; } @@ -702,7 +702,7 @@ int riocontrol(struct rio_info *p, dev_t dev, int cmd, unsigned long arg, int su p->RIOError.Error = COPYIN_FAILED; return -EFAULT; } - if (portStats.port < 0 || portStats.port >= RIO_PORTS) { + if (portStats.port >= RIO_PORTS) { p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; return -ENXIO; } diff --git a/trunk/drivers/char/rio/rioinit.c b/trunk/drivers/char/rio/rioinit.c index 0794844369d6..99f3df02b61c 100644 --- a/trunk/drivers/char/rio/rioinit.c +++ b/trunk/drivers/char/rio/rioinit.c @@ -222,7 +222,7 @@ int RIOBoardTest(unsigned long paddr, void __iomem *caddr, unsigned char type, i ** which value will be written into memory. ** Call with op set to zero means that the RAM will not be read and checked ** before it is written. -** Call with op not zero and the RAM will be read and compared with val[op-1] +** Call with op not zero, and the RAM will be read and compated with val[op-1] ** to check that the data from the previous phase was retained. */ diff --git a/trunk/drivers/char/rio/riointr.c b/trunk/drivers/char/rio/riointr.c index eeda40c5e189..0bd09040a5c0 100644 --- a/trunk/drivers/char/rio/riointr.c +++ b/trunk/drivers/char/rio/riointr.c @@ -181,7 +181,7 @@ static int RupIntr; static int RxIntr; static int TxIntr; -void RIOServiceHost(struct rio_info *p, struct Host *HostP) +void RIOServiceHost(struct rio_info *p, struct Host *HostP, int From) { rio_spin_lock(&HostP->HostLock); if ((HostP->Flags & RUN_STATE) != RC_RUNNING) { diff --git a/trunk/drivers/char/rio/rioparam.c b/trunk/drivers/char/rio/rioparam.c index bb498d24adcc..1066d9760704 100644 --- a/trunk/drivers/char/rio/rioparam.c +++ b/trunk/drivers/char/rio/rioparam.c @@ -87,8 +87,8 @@ static char *_rioparam_c_sccs_ = "@(#)rioparam.c 1.3"; ** command bit set onto the port. The command bit is in the len field, ** and gets ORed in with the actual byte count. ** -** When you send a packet with the command bit set the first -** data byte (data[0]) is interpreted as the command to execute. +** When you send a packet with the command bit set, then the first +** data byte ( data[0] ) is interpretted as the command to execute. ** It also governs what data structure overlay should accompany the packet. ** Commands are defined in cirrus/cirrus.h ** @@ -103,7 +103,7 @@ static char *_rioparam_c_sccs_ = "@(#)rioparam.c 1.3"; ** ** Most commands do not use the remaining bytes in the data array. The ** exceptions are OPEN MOPEN and CONFIG. (NB. As with the SI CONFIG and -** OPEN are currently analogous). With these three commands the following +** OPEN are currently analagous). With these three commands the following ** 11 data bytes are all used to pass config information such as baud rate etc. ** The fields are also defined in cirrus.h. Some contain straightforward ** information such as the transmit XON character. Two contain the transmit and diff --git a/trunk/drivers/char/riscom8.c b/trunk/drivers/char/riscom8.c index 5ab32b38f45a..b0ab3f28cc6a 100644 --- a/trunk/drivers/char/riscom8.c +++ b/trunk/drivers/char/riscom8.c @@ -550,7 +550,7 @@ static inline void rc_check_modem(struct riscom_board const * bp) } /* The main interrupt processing routine */ -static irqreturn_t rc_interrupt(int irq, void * dev_id) +static irqreturn_t rc_interrupt(int irq, void * dev_id, struct pt_regs * regs) { unsigned char status; unsigned char ack; @@ -559,10 +559,11 @@ static irqreturn_t rc_interrupt(int irq, void * dev_id) int handled = 0; bp = IRQ_to_board[irq]; - - if (!(bp->flags & RC_BOARD_ACTIVE)) + + if (!bp || !(bp->flags & RC_BOARD_ACTIVE)) { return IRQ_NONE; - + } + while ((++loop < 16) && ((status = ~(rc_in(bp, RC_BSR))) & (RC_BSR_TOUT | RC_BSR_TINT | RC_BSR_MINT | RC_BSR_RINT))) { diff --git a/trunk/drivers/char/rtc.c b/trunk/drivers/char/rtc.c index 66a7385bc34a..656f8c0ca52e 100644 --- a/trunk/drivers/char/rtc.c +++ b/trunk/drivers/char/rtc.c @@ -35,13 +35,13 @@ * 1.09a Pete Zaitcev: Sun SPARC * 1.09b Jeff Garzik: Modularize, init cleanup * 1.09c Jeff Garzik: SMP cleanup - * 1.10 Paul Barton-Davis: add support for async I/O + * 1.10 Paul Barton-Davis: add support for async I/O * 1.10a Andrea Arcangeli: Alpha updates * 1.10b Andrew Morton: SMP lock fix * 1.10c Cesar Barros: SMP locking fixes and cleanup * 1.10d Paul Gortmaker: delete paranoia check in rtc_exit * 1.10e Maciej W. Rozycki: Handle DECstation's year weirdness. - * 1.11 Takashi Iwai: Kernel access functions + * 1.11 Takashi Iwai: Kernel access functions * rtc_register/rtc_unregister/rtc_control * 1.11a Daniele Bellucci: Audit create_proc_read_entry in rtc_init * 1.12 Venkatesh Pallipadi: Hooks for emulating rtc on HPET base-timer @@ -113,9 +113,9 @@ static int rtc_has_irq = 1; #define hpet_set_rtc_irq_bit(arg) 0 #define hpet_rtc_timer_init() do { } while (0) #define hpet_rtc_dropped_irq() 0 -static inline irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id) {return 0;} +static inline irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs) {return 0;} #else -extern irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id); +extern irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs); #endif /* @@ -229,7 +229,7 @@ static inline unsigned char rtc_is_updating(void) * (See ./arch/XXXX/kernel/time.c for the set_rtc_mmss() function.) */ -irqreturn_t rtc_interrupt(int irq, void *dev_id) +irqreturn_t rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs) { /* * Can be an alarm interrupt, update complete interrupt, @@ -915,7 +915,7 @@ static const struct file_operations rtc_proc_fops = { }; #if defined(RTC_IRQ) && !defined(__sparc__) -static irq_handler_t rtc_int_handler_ptr; +static irqreturn_t (*rtc_int_handler_ptr)(int irq, void *dev_id, struct pt_regs *regs); #endif static int __init rtc_init(void) diff --git a/trunk/drivers/char/ser_a2232.c b/trunk/drivers/char/ser_a2232.c index 4217d38caef9..65c751d0d643 100644 --- a/trunk/drivers/char/ser_a2232.c +++ b/trunk/drivers/char/ser_a2232.c @@ -111,7 +111,7 @@ /***************************** Prototypes ***************************/ /* The interrupt service routine */ -static irqreturn_t a2232_vbl_inter(int irq, void *data); +static irqreturn_t a2232_vbl_inter(int irq, void *data, struct pt_regs *fp); /* Initialize the port structures */ static void a2232_init_portstructs(void); /* Initialize and register TTY drivers. */ @@ -504,7 +504,7 @@ static int a2232_open(struct tty_struct * tty, struct file * filp) } /*** END OF FUNCTIONS EXPECTED BY TTY DRIVER STRUCTS ***/ -static irqreturn_t a2232_vbl_inter(int irq, void *data) +static irqreturn_t a2232_vbl_inter(int irq, void *data, struct pt_regs *fp) { #if A2232_IOBUFLEN != 256 #error "Re-Implement a2232_vbl_inter()!" diff --git a/trunk/drivers/char/serial167.c b/trunk/drivers/char/serial167.c index 3af7f0958c5d..f4809c8183cc 100644 --- a/trunk/drivers/char/serial167.c +++ b/trunk/drivers/char/serial167.c @@ -62,7 +62,6 @@ #include #include #include -#include #include #include @@ -371,7 +370,7 @@ cy_sched_event(struct cyclades_port *info, int event) received, out buffer empty, modem change, etc. */ static irqreturn_t -cd2401_rxerr_interrupt(int irq, void *dev_id) +cd2401_rxerr_interrupt(int irq, void *dev_id, struct pt_regs *fp) { struct tty_struct *tty; struct cyclades_port *info; @@ -428,9 +427,8 @@ cd2401_rxerr_interrupt(int irq, void *dev_id) overflowing, we still loose the next incoming character. */ - if (tty_buffer_request_room(tty, 1) != 0){ - tty_insert_flip_char(tty, data, TTY_FRAME); - } + tty_insert_flip_char(tty, data, TTY_NORMAL); + } /* These two conditions may imply */ /* a normal read should be done. */ /* else if(data & CyTIMEOUT) */ @@ -439,21 +437,21 @@ cd2401_rxerr_interrupt(int irq, void *dev_id) tty_insert_flip_char(tty, 0, TTY_NORMAL); } }else{ - tty_insert_flip_char(tty, data, TTY_NORMAL); + tty_insert_flip_char(tty, data, TTY_NORMAL); } }else{ /* there was a software buffer overrun and nothing could be done about it!!! */ } } - tty_schedule_flip(tty); + schedule_delayed_work(&tty->flip.work, 1); /* end of service */ base_addr[CyREOIR] = rfoc ? 0 : CyNOTRANS; return IRQ_HANDLED; } /* cy_rxerr_interrupt */ static irqreturn_t -cd2401_modem_interrupt(int irq, void *dev_id) +cd2401_modem_interrupt(int irq, void *dev_id, struct pt_regs *fp) { struct cyclades_port *info; volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR; @@ -508,7 +506,7 @@ cd2401_modem_interrupt(int irq, void *dev_id) } /* cy_modem_interrupt */ static irqreturn_t -cd2401_tx_interrupt(int irq, void *dev_id) +cd2401_tx_interrupt(int irq, void *dev_id, struct pt_regs *fp) { struct cyclades_port *info; volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR; @@ -628,7 +626,7 @@ cd2401_tx_interrupt(int irq, void *dev_id) } /* cy_tx_interrupt */ static irqreturn_t -cd2401_rx_interrupt(int irq, void *dev_id) +cd2401_rx_interrupt(int irq, void *dev_id, struct pt_regs *fp) { struct tty_struct *tty; struct cyclades_port *info; @@ -637,7 +635,6 @@ cd2401_rx_interrupt(int irq, void *dev_id) char data; int char_count; int save_cnt; - int len; /* determine the channel and change to that context */ channel = (u_short ) (base_addr[CyLICR] >> 2); @@ -670,15 +667,14 @@ cd2401_rx_interrupt(int irq, void *dev_id) info->mon.char_max = char_count; info->mon.char_last = char_count; #endif - len = tty_buffer_request_room(tty, char_count); - while(len--){ + while(char_count--){ data = base_addr[CyRDR]; tty_insert_flip_char(tty, data, TTY_NORMAL); #ifdef CYCLOM_16Y_HACK udelay(10L); #endif } - tty_schedule_flip(tty); + schedule_delayed_work(&tty->flip.work, 1); } /* end of service */ base_addr[CyREOIR] = save_cnt ? 0 : CyNOTRANS; @@ -839,7 +835,7 @@ shutdown(struct cyclades_port * info) local_irq_save(flags); if (info->xmit_buf){ free_page((unsigned long) info->xmit_buf); - info->xmit_buf = NULL; + info->xmit_buf = 0; } base_addr[CyCAR] = (u_char)channel; @@ -1354,7 +1350,7 @@ cy_unthrottle(struct tty_struct * tty) static int get_serial_info(struct cyclades_port * info, - struct serial_struct __user * retinfo) + struct serial_struct * retinfo) { struct serial_struct tmp; @@ -1376,7 +1372,7 @@ get_serial_info(struct cyclades_port * info, static int set_serial_info(struct cyclades_port * info, - struct serial_struct __user * new_info) + struct serial_struct * new_info) { struct serial_struct new_serial; struct cyclades_port old_info; @@ -1426,6 +1422,7 @@ cy_tiocmget(struct tty_struct *tty, struct file *file) volatile unsigned char *base_addr = (u_char *)BASE_ADDR; unsigned long flags; unsigned char status; + unsigned int result; channel = info->line; @@ -1449,6 +1446,7 @@ cy_tiocmset(struct tty_struct *tty, struct file *file, int channel; volatile unsigned char *base_addr = (u_char *)BASE_ADDR; unsigned long flags; + unsigned int arg; channel = info->line; @@ -1503,7 +1501,7 @@ send_break( struct cyclades_port * info, int duration) } /* send_break */ static int -get_mon_info(struct cyclades_port * info, struct cyclades_monitor __user * mon) +get_mon_info(struct cyclades_port * info, struct cyclades_monitor * mon) { if (copy_to_user(mon, &info->mon, sizeof(struct cyclades_monitor))) @@ -1516,7 +1514,7 @@ get_mon_info(struct cyclades_port * info, struct cyclades_monitor __user * mon) } static int -set_threshold(struct cyclades_port * info, unsigned long __user *arg) +set_threshold(struct cyclades_port * info, unsigned long *arg) { volatile unsigned char *base_addr = (u_char *)BASE_ADDR; unsigned long value; @@ -1533,7 +1531,7 @@ set_threshold(struct cyclades_port * info, unsigned long __user *arg) } static int -get_threshold(struct cyclades_port * info, unsigned long __user *value) +get_threshold(struct cyclades_port * info, unsigned long *value) { volatile unsigned char *base_addr = (u_char *)BASE_ADDR; int channel; @@ -1546,7 +1544,7 @@ get_threshold(struct cyclades_port * info, unsigned long __user *value) } static int -set_default_threshold(struct cyclades_port * info, unsigned long __user *arg) +set_default_threshold(struct cyclades_port * info, unsigned long *arg) { unsigned long value; @@ -1558,13 +1556,13 @@ set_default_threshold(struct cyclades_port * info, unsigned long __user *arg) } static int -get_default_threshold(struct cyclades_port * info, unsigned long __user *value) +get_default_threshold(struct cyclades_port * info, unsigned long *value) { return put_user(info->default_threshold,value); } static int -set_timeout(struct cyclades_port * info, unsigned long __user *arg) +set_timeout(struct cyclades_port * info, unsigned long *arg) { volatile unsigned char *base_addr = (u_char *)BASE_ADDR; int channel; @@ -1581,7 +1579,7 @@ set_timeout(struct cyclades_port * info, unsigned long __user *arg) } static int -get_timeout(struct cyclades_port * info, unsigned long __user *value) +get_timeout(struct cyclades_port * info, unsigned long *value) { volatile unsigned char *base_addr = (u_char *)BASE_ADDR; int channel; @@ -1601,7 +1599,7 @@ set_default_timeout(struct cyclades_port * info, unsigned long value) } static int -get_default_timeout(struct cyclades_port * info, unsigned long __user *value) +get_default_timeout(struct cyclades_port * info, unsigned long *value) { return put_user(info->default_timeout,value); } @@ -1613,7 +1611,6 @@ cy_ioctl(struct tty_struct *tty, struct file * file, unsigned long val; struct cyclades_port * info = (struct cyclades_port *)tty->driver_data; int ret_val = 0; - void __user *argp = (void __user *)arg; #ifdef SERIAL_DEBUG_OTHER printk("cy_ioctl %s, cmd = %x arg = %lx\n", tty->name, cmd, arg); /* */ @@ -1621,28 +1618,28 @@ cy_ioctl(struct tty_struct *tty, struct file * file, switch (cmd) { case CYGETMON: - ret_val = get_mon_info(info, argp); + ret_val = get_mon_info(info, (struct cyclades_monitor *)arg); break; case CYGETTHRESH: - ret_val = get_threshold(info, argp); + ret_val = get_threshold(info, (unsigned long *)arg); break; case CYSETTHRESH: - ret_val = set_threshold(info, argp); + ret_val = set_threshold(info, (unsigned long *)arg); break; case CYGETDEFTHRESH: - ret_val = get_default_threshold(info, argp); + ret_val = get_default_threshold(info, (unsigned long *)arg); break; case CYSETDEFTHRESH: - ret_val = set_default_threshold(info, argp); + ret_val = set_default_threshold(info, (unsigned long *)arg); break; case CYGETTIMEOUT: - ret_val = get_timeout(info, argp); + ret_val = get_timeout(info, (unsigned long *)arg); break; case CYSETTIMEOUT: - ret_val = set_timeout(info, argp); + ret_val = set_timeout(info, (unsigned long *)arg); break; case CYGETDEFTIMEOUT: - ret_val = get_default_timeout(info, argp); + ret_val = get_default_timeout(info, (unsigned long *)arg); break; case CYSETDEFTIMEOUT: ret_val = set_default_timeout(info, (unsigned long)arg); @@ -1665,20 +1662,21 @@ cy_ioctl(struct tty_struct *tty, struct file * file, /* The following commands are incompletely implemented!!! */ case TIOCGSOFTCAR: - ret_val = put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *) argp); + ret_val = put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long *) arg); break; case TIOCSSOFTCAR: - ret_val = get_user(val, (unsigned long __user *) argp); + ret_val = get_user(val, (unsigned long *) arg); if (ret_val) break; tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL) | (val ? CLOCAL : 0)); break; case TIOCGSERIAL: - ret_val = get_serial_info(info, argp); + ret_val = get_serial_info(info, (struct serial_struct *) arg); break; case TIOCSSERIAL: - ret_val = set_serial_info(info, argp); + ret_val = set_serial_info(info, + (struct serial_struct *) arg); break; default: ret_val = -ENOIOCTLCMD; @@ -1773,7 +1771,7 @@ cy_close(struct tty_struct * tty, struct file * filp) tty->driver->flush_buffer(tty); tty_ldisc_flush(tty); info->event = 0; - info->tty = NULL; + info->tty = 0; if (info->blocked_open) { if (info->close_delay) { msleep_interruptible(jiffies_to_msecs(info->close_delay)); @@ -2250,7 +2248,7 @@ scrn[1] = '\0'; info->card = index; info->line = port_num; info->flags = STD_COM_FLAGS; - info->tty = NULL; + info->tty = 0; info->xmit_fifo_size = 12; info->cor1 = CyPARITY_NONE|Cy_8_BITS; info->cor2 = CyETC; diff --git a/trunk/drivers/char/snsc.c b/trunk/drivers/char/snsc.c index 52753e723eaa..07e0b75f2338 100644 --- a/trunk/drivers/char/snsc.c +++ b/trunk/drivers/char/snsc.c @@ -34,7 +34,7 @@ #define SCDRV_TIMEOUT 1000 static irqreturn_t -scdrv_interrupt(int irq, void *subch_data) +scdrv_interrupt(int irq, void *subch_data, struct pt_regs *regs) { struct subch_data_s *sd = subch_data; unsigned long flags; diff --git a/trunk/drivers/char/snsc_event.c b/trunk/drivers/char/snsc_event.c index 2f56e8c54897..864854c58866 100644 --- a/trunk/drivers/char/snsc_event.c +++ b/trunk/drivers/char/snsc_event.c @@ -36,7 +36,7 @@ DECLARE_TASKLET(sn_sysctl_event, scdrv_event, 0); * destination. */ static irqreturn_t -scdrv_event_interrupt(int irq, void *subch_data) +scdrv_event_interrupt(int irq, void *subch_data, struct pt_regs *regs) { struct subch_data_s *sd = subch_data; unsigned long flags; diff --git a/trunk/drivers/char/sonypi.c b/trunk/drivers/char/sonypi.c index c084149153de..d4e434d694b7 100644 --- a/trunk/drivers/char/sonypi.c +++ b/trunk/drivers/char/sonypi.c @@ -826,7 +826,7 @@ static void sonypi_report_input_event(u8 event) } /* Interrupt handler: some event is available */ -static irqreturn_t sonypi_irq(int irq, void *dev_id) +static irqreturn_t sonypi_irq(int irq, void *dev_id, struct pt_regs *regs) { u8 v1, v2, event = 0; int i, j; diff --git a/trunk/drivers/char/specialix.c b/trunk/drivers/char/specialix.c index 7e1bd9562c2a..902c48dca3bc 100644 --- a/trunk/drivers/char/specialix.c +++ b/trunk/drivers/char/specialix.c @@ -183,6 +183,11 @@ static int sx_poll = HZ; static struct tty_driver *specialix_driver; +static unsigned long baud_table[] = { + 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, + 9600, 19200, 38400, 57600, 115200, 0, +}; + static struct specialix_board sx_board[SX_NBOARD] = { { 0, SX_IOBASE1, 9, }, { 0, SX_IOBASE2, 11, }, @@ -195,7 +200,7 @@ static struct specialix_port sx_port[SX_NBOARD * SX_NPORT]; #ifdef SPECIALIX_TIMER static struct timer_list missed_irq_timer; -static irqreturn_t sx_interrupt(int irq, void * dev_id); +static irqreturn_t sx_interrupt(int irq, void * dev_id, struct pt_regs * regs); #endif @@ -892,7 +897,7 @@ static inline void sx_check_modem(struct specialix_board * bp) /* The main interrupt processing routine */ -static irqreturn_t sx_interrupt(int irq, void *dev_id) +static irqreturn_t sx_interrupt(int irq, void *dev_id, struct pt_regs *regs) { unsigned char status; unsigned char ack; @@ -907,7 +912,7 @@ static irqreturn_t sx_interrupt(int irq, void *dev_id) spin_lock_irqsave(&bp->lock, flags); dprintk (SX_DEBUG_FLOW, "enter %s port %d room: %ld\n", __FUNCTION__, port_No(sx_get_port(bp, "INT")), SERIAL_XMIT_SIZE - sx_get_port(bp, "ITN")->xmit_cnt - 1); - if (!(bp->flags & SX_BOARD_ACTIVE)) { + if (!bp || !(bp->flags & SX_BOARD_ACTIVE)) { dprintk (SX_DEBUG_IRQ, "sx: False interrupt. irq %d.\n", irq); spin_unlock_irqrestore(&bp->lock, flags); func_exit(); @@ -1085,9 +1090,9 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p if (baud == 38400) { if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) - baud = 57600; + baud ++; if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) - baud = 115200; + baud += 2; } if (!baud) { @@ -1145,9 +1150,11 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p sx_out(bp, CD186x_RBPRL, tmp & 0xff); sx_out(bp, CD186x_TBPRL, tmp & 0xff); spin_unlock_irqrestore(&bp->lock, flags); - if (port->custom_divisor) + if (port->custom_divisor) { baud = (SX_OSCFREQ + port->custom_divisor/2) / port->custom_divisor; - baud = (baud + 5) / 10; /* Estimated CPS */ + baud = ( baud + 5 ) / 10; + } else + baud = (baud_table[baud] + 5) / 10; /* Estimated CPS */ /* Two timer ticks seems enough to wakeup something like SLIP driver */ tmp = ((baud + HZ/2) / HZ) * 2 - CD186x_NFIFO; diff --git a/trunk/drivers/char/stallion.c b/trunk/drivers/char/stallion.c index 522e88e395cc..bd711537ec4e 100644 --- a/trunk/drivers/char/stallion.c +++ b/trunk/drivers/char/stallion.c @@ -1927,12 +1927,13 @@ static int stl_readproc(char *page, char **start, off_t off, int count, int *eof * calls off to the approrpriate board interrupt handlers. */ -static irqreturn_t stl_intr(int irq, void *dev_id) +static irqreturn_t stl_intr(int irq, void *dev_id, struct pt_regs *regs) { stlbrd_t *brdp = (stlbrd_t *) dev_id; #ifdef DEBUG - printk("stl_intr(brdp=%x,irq=%d)\n", (int) brdp, irq); + printk("stl_intr(brdp=%x,irq=%d,regs=%x)\n", (int) brdp, irq, + (int) regs); #endif return IRQ_RETVAL((* brdp->isr)(brdp)); diff --git a/trunk/drivers/char/sx.c b/trunk/drivers/char/sx.c index cc10af08cb05..8fd71a5fc619 100644 --- a/trunk/drivers/char/sx.c +++ b/trunk/drivers/char/sx.c @@ -1192,7 +1192,7 @@ static inline void sx_check_modem_signals (struct sx_port *port) * Small, elegant, clear. */ -static irqreturn_t sx_interrupt (int irq, void *ptr) +static irqreturn_t sx_interrupt (int irq, void *ptr, struct pt_regs *regs) { struct sx_board *board = ptr; struct sx_port *port; @@ -1300,7 +1300,7 @@ static void sx_pollfunc (unsigned long data) func_enter (); - sx_interrupt (0, board); + sx_interrupt (0, board, NULL); init_timer(&board->timer); @@ -2602,7 +2602,7 @@ static void __exit sx_exit (void) } } if (misc_deregister(&sx_fw_device) < 0) { - printk (KERN_INFO "sx: couldn't deregister firmware loader device\n"); + printk (KERN_INFO "sx: couldn't deregister firmware loader devic\n"); } sx_dprintk (SX_DEBUG_CLEANUP, "Cleaning up drivers (%d)\n", sx_initialized); if (sx_initialized) diff --git a/trunk/drivers/char/synclink.c b/trunk/drivers/char/synclink.c index 06784adcc35c..a4150c4519c4 100644 --- a/trunk/drivers/char/synclink.c +++ b/trunk/drivers/char/synclink.c @@ -133,8 +133,8 @@ static MGSL_PARAMS default_params = { }; #define SHARED_MEM_ADDRESS_SIZE 0x40000 -#define BUFFERLISTSIZE 4096 -#define DMABUFFERSIZE 4096 +#define BUFFERLISTSIZE (PAGE_SIZE) +#define DMABUFFERSIZE (PAGE_SIZE) #define MAXRXFRAMES 7 typedef struct _DMABUFFERENTRY @@ -1698,10 +1698,11 @@ static void mgsl_isr_transmit_dma( struct mgsl_struct *info ) * * irq interrupt number that caused interrupt * dev_id device ID supplied during interrupt registration + * regs interrupted processor context * * Return Value: None */ -static irqreturn_t mgsl_interrupt(int irq, void *dev_id) +static irqreturn_t mgsl_interrupt(int irq, void *dev_id, struct pt_regs * regs) { struct mgsl_struct * info; u16 UscVector; diff --git a/trunk/drivers/char/synclink_gt.c b/trunk/drivers/char/synclink_gt.c index d4334c79f8d4..bdc7cb248b8f 100644 --- a/trunk/drivers/char/synclink_gt.c +++ b/trunk/drivers/char/synclink_gt.c @@ -491,7 +491,7 @@ static void isr_serial(struct slgt_info *info); static void isr_rdma(struct slgt_info *info); static void isr_txeom(struct slgt_info *info, unsigned short status); static void isr_tdma(struct slgt_info *info); -static irqreturn_t slgt_interrupt(int irq, void *dev_id); +static irqreturn_t slgt_interrupt(int irq, void *dev_id, struct pt_regs * regs); static int alloc_dma_bufs(struct slgt_info *info); static void free_dma_bufs(struct slgt_info *info); @@ -2217,8 +2217,9 @@ static void isr_gpio(struct slgt_info *info, unsigned int changed, unsigned int * * irq interrupt number * dev_id device ID supplied during interrupt registration + * regs interrupted processor context */ -static irqreturn_t slgt_interrupt(int irq, void *dev_id) +static irqreturn_t slgt_interrupt(int irq, void *dev_id, struct pt_regs * regs) { struct slgt_info *info; unsigned int gsr; diff --git a/trunk/drivers/char/synclinkmp.c b/trunk/drivers/char/synclinkmp.c index 3e932b681371..6eb75dcd7961 100644 --- a/trunk/drivers/char/synclinkmp.c +++ b/trunk/drivers/char/synclinkmp.c @@ -2596,7 +2596,8 @@ void isr_io_pin( SLMP_INFO *info, u16 status ) * dev_id device ID supplied during interrupt registration * regs interrupted processor context */ -static irqreturn_t synclinkmp_interrupt(int irq, void *dev_id) +static irqreturn_t synclinkmp_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { SLMP_INFO * info; unsigned char status, status0, status1=0; diff --git a/trunk/drivers/char/sysrq.c b/trunk/drivers/char/sysrq.c index 5f49280779fb..6b4d4d1e343d 100644 --- a/trunk/drivers/char/sysrq.c +++ b/trunk/drivers/char/sysrq.c @@ -35,15 +35,14 @@ #include #include #include -#include #include -#include /* Whether we react on sysrq keys or just ignore them */ int sysrq_enabled = 1; -static void sysrq_handle_loglevel(int key, struct tty_struct *tty) +static void sysrq_handle_loglevel(int key, struct pt_regs *pt_regs, + struct tty_struct *tty) { int i; i = key - '0'; @@ -59,7 +58,8 @@ static struct sysrq_key_op sysrq_loglevel_op = { }; #ifdef CONFIG_VT -static void sysrq_handle_SAK(int key, struct tty_struct *tty) +static void sysrq_handle_SAK(int key, struct pt_regs *pt_regs, + struct tty_struct *tty) { if (tty) do_SAK(tty); @@ -76,7 +76,8 @@ static struct sysrq_key_op sysrq_SAK_op = { #endif #ifdef CONFIG_VT -static void sysrq_handle_unraw(int key, struct tty_struct *tty) +static void sysrq_handle_unraw(int key, struct pt_regs *pt_regs, + struct tty_struct *tty) { struct kbd_struct *kbd = &kbd_table[fg_console]; @@ -94,9 +95,10 @@ static struct sysrq_key_op sysrq_unraw_op = { #endif /* CONFIG_VT */ #ifdef CONFIG_KEXEC -static void sysrq_handle_crashdump(int key, struct tty_struct *tty) +static void sysrq_handle_crashdump(int key, struct pt_regs *pt_regs, + struct tty_struct *tty) { - crash_kexec(get_irq_regs()); + crash_kexec(pt_regs); } static struct sysrq_key_op sysrq_crashdump_op = { .handler = sysrq_handle_crashdump, @@ -108,7 +110,8 @@ static struct sysrq_key_op sysrq_crashdump_op = { #define sysrq_crashdump_op (*(struct sysrq_key_op *)0) #endif -static void sysrq_handle_reboot(int key, struct tty_struct *tty) +static void sysrq_handle_reboot(int key, struct pt_regs *pt_regs, + struct tty_struct *tty) { lockdep_off(); local_irq_enable(); @@ -121,7 +124,8 @@ static struct sysrq_key_op sysrq_reboot_op = { .enable_mask = SYSRQ_ENABLE_BOOT, }; -static void sysrq_handle_sync(int key, struct tty_struct *tty) +static void sysrq_handle_sync(int key, struct pt_regs *pt_regs, + struct tty_struct *tty) { emergency_sync(); } @@ -132,7 +136,8 @@ static struct sysrq_key_op sysrq_sync_op = { .enable_mask = SYSRQ_ENABLE_SYNC, }; -static void sysrq_handle_mountro(int key, struct tty_struct *tty) +static void sysrq_handle_mountro(int key, struct pt_regs *pt_regs, + struct tty_struct *tty) { emergency_remount(); } @@ -144,7 +149,8 @@ static struct sysrq_key_op sysrq_mountro_op = { }; #ifdef CONFIG_LOCKDEP -static void sysrq_handle_showlocks(int key, struct tty_struct *tty) +static void sysrq_handle_showlocks(int key, struct pt_regs *pt_regs, + struct tty_struct *tty) { debug_show_all_locks(); } @@ -158,11 +164,11 @@ static struct sysrq_key_op sysrq_showlocks_op = { #define sysrq_showlocks_op (*(struct sysrq_key_op *)0) #endif -static void sysrq_handle_showregs(int key, struct tty_struct *tty) +static void sysrq_handle_showregs(int key, struct pt_regs *pt_regs, + struct tty_struct *tty) { - struct pt_regs *regs = get_irq_regs(); - if (regs) - show_regs(regs); + if (pt_regs) + show_regs(pt_regs); } static struct sysrq_key_op sysrq_showregs_op = { .handler = sysrq_handle_showregs, @@ -171,7 +177,8 @@ static struct sysrq_key_op sysrq_showregs_op = { .enable_mask = SYSRQ_ENABLE_DUMP, }; -static void sysrq_handle_showstate(int key, struct tty_struct *tty) +static void sysrq_handle_showstate(int key, struct pt_regs *pt_regs, + struct tty_struct *tty) { show_state(); } @@ -182,7 +189,8 @@ static struct sysrq_key_op sysrq_showstate_op = { .enable_mask = SYSRQ_ENABLE_DUMP, }; -static void sysrq_handle_showmem(int key, struct tty_struct *tty) +static void sysrq_handle_showmem(int key, struct pt_regs *pt_regs, + struct tty_struct *tty) { show_mem(); } @@ -207,7 +215,8 @@ static void send_sig_all(int sig) } } -static void sysrq_handle_term(int key, struct tty_struct *tty) +static void sysrq_handle_term(int key, struct pt_regs *pt_regs, + struct tty_struct *tty) { send_sig_all(SIGTERM); console_loglevel = 8; @@ -227,7 +236,8 @@ static void moom_callback(void *ignored) static DECLARE_WORK(moom_work, moom_callback, NULL); -static void sysrq_handle_moom(int key, struct tty_struct *tty) +static void sysrq_handle_moom(int key, struct pt_regs *pt_regs, + struct tty_struct *tty) { schedule_work(&moom_work); } @@ -237,7 +247,8 @@ static struct sysrq_key_op sysrq_moom_op = { .action_msg = "Manual OOM execution", }; -static void sysrq_handle_kill(int key, struct tty_struct *tty) +static void sysrq_handle_kill(int key, struct pt_regs *pt_regs, + struct tty_struct *tty) { send_sig_all(SIGKILL); console_loglevel = 8; @@ -249,7 +260,8 @@ static struct sysrq_key_op sysrq_kill_op = { .enable_mask = SYSRQ_ENABLE_SIGNAL, }; -static void sysrq_handle_unrt(int key, struct tty_struct *tty) +static void sysrq_handle_unrt(int key, struct pt_regs *pt_regs, + struct tty_struct *tty) { normalize_rt_tasks(); } @@ -349,7 +361,8 @@ static void __sysrq_put_key_op(int key, struct sysrq_key_op *op_p) * This is the non-locking version of handle_sysrq. It must/can only be called * by sysrq key handlers, as they are inside of the lock */ -void __handle_sysrq(int key, struct tty_struct *tty, int check_mask) +void __handle_sysrq(int key, struct pt_regs *pt_regs, struct tty_struct *tty, + int check_mask) { struct sysrq_key_op *op_p; int orig_log_level; @@ -371,7 +384,7 @@ void __handle_sysrq(int key, struct tty_struct *tty, int check_mask) (sysrq_enabled & op_p->enable_mask)) { printk("%s\n", op_p->action_msg); console_loglevel = orig_log_level; - op_p->handler(key, tty); + op_p->handler(key, pt_regs, tty); } else { printk("This sysrq operation is disabled.\n"); } @@ -400,11 +413,11 @@ void __handle_sysrq(int key, struct tty_struct *tty, int check_mask) * This function is called by the keyboard handler when SysRq is pressed * and any other keycode arrives. */ -void handle_sysrq(int key, struct tty_struct *tty) +void handle_sysrq(int key, struct pt_regs *pt_regs, struct tty_struct *tty) { if (!sysrq_enabled) return; - __handle_sysrq(key, tty, 1); + __handle_sysrq(key, pt_regs, tty, 1); } EXPORT_SYMBOL(handle_sysrq); diff --git a/trunk/drivers/char/tlclk.c b/trunk/drivers/char/tlclk.c index 244d30a03fef..d2c5ba4e83b8 100644 --- a/trunk/drivers/char/tlclk.c +++ b/trunk/drivers/char/tlclk.c @@ -193,7 +193,7 @@ static DEFINE_SPINLOCK(event_lock); static int tlclk_major = TLCLK_MAJOR; -static irqreturn_t tlclk_interrupt(int irq, void *dev_id); +static irqreturn_t tlclk_interrupt(int irq, void *dev_id, struct pt_regs *regs); static DECLARE_WAIT_QUEUE_HEAD(wq); @@ -792,14 +792,15 @@ static int __init tlclk_init(void) ret = misc_register(&tlclk_miscdev); if (ret < 0) { printk(KERN_ERR "tlclk: misc_register returns %d.\n", ret); + ret = -EBUSY; goto out3; } tlclk_device = platform_device_register_simple("telco_clock", -1, NULL, 0); - if (IS_ERR(tlclk_device)) { + if (!tlclk_device) { printk(KERN_ERR "tlclk: platform_device_register failed.\n"); - ret = PTR_ERR(tlclk_device); + ret = -EBUSY; goto out4; } @@ -855,7 +856,7 @@ static void switchover_timeout(unsigned long data) wake_up(&wq); } -static irqreturn_t tlclk_interrupt(int irq, void *dev_id) +static irqreturn_t tlclk_interrupt(int irq, void *dev_id, struct pt_regs *regs) { unsigned long flags; diff --git a/trunk/drivers/char/tpm/tpm.c b/trunk/drivers/char/tpm/tpm.c index 6e1329d404d2..a082a2e34252 100644 --- a/trunk/drivers/char/tpm/tpm.c +++ b/trunk/drivers/char/tpm/tpm.c @@ -1130,7 +1130,7 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vend scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num); chip->vendor.miscdev.name = devname; - chip->vendor.miscdev.parent = dev; + chip->vendor.miscdev.dev = dev; chip->dev = get_device(dev); if (misc_register(&chip->vendor.miscdev)) { @@ -1153,14 +1153,7 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vend spin_unlock(&driver_lock); - if (sysfs_create_group(&dev->kobj, chip->vendor.attr_group)) { - list_del(&chip->list); - put_device(dev); - clear_bit(chip->dev_num, dev_mask); - kfree(chip); - kfree(devname); - return NULL; - } + sysfs_create_group(&dev->kobj, chip->vendor.attr_group); chip->bios_dir = tpm_bios_log_setup(devname); diff --git a/trunk/drivers/char/tpm/tpm_atmel.c b/trunk/drivers/char/tpm/tpm_atmel.c index 1ab0896070be..ad8ffe49256f 100644 --- a/trunk/drivers/char/tpm/tpm_atmel.c +++ b/trunk/drivers/char/tpm/tpm_atmel.c @@ -184,9 +184,7 @@ static int __init init_atmel(void) unsigned long base; struct tpm_chip *chip; - rc = driver_register(&atml_drv); - if (rc) - return rc; + driver_register(&atml_drv); if ((iobase = atmel_get_base_addr(&base, ®ion_size)) == NULL) { rc = -ENODEV; @@ -197,8 +195,10 @@ static int __init init_atmel(void) (atmel_request_region (tpm_atmel.base, region_size, "tpm_atmel0") == NULL) ? 0 : 1; - pdev = platform_device_register_simple("tpm_atmel", -1, NULL, 0); - if (IS_ERR(pdev)) { + + if (IS_ERR + (pdev = + platform_device_register_simple("tpm_atmel", -1, NULL, 0))) { rc = PTR_ERR(pdev); goto err_rel_reg; } diff --git a/trunk/drivers/char/tpm/tpm_nsc.c b/trunk/drivers/char/tpm/tpm_nsc.c index 608f73071bef..26287aace87d 100644 --- a/trunk/drivers/char/tpm/tpm_nsc.c +++ b/trunk/drivers/char/tpm/tpm_nsc.c @@ -284,7 +284,7 @@ static struct device_driver nsc_drv = { static int __init init_nsc(void) { int rc = 0; - int lo, hi, err; + int lo, hi; int nscAddrBase = TPM_ADDR; struct tpm_chip *chip; unsigned long base; @@ -297,9 +297,7 @@ static int __init init_nsc(void) return -ENODEV; } - err = driver_register(&nsc_drv); - if (err) - return err; + driver_register(&nsc_drv); hi = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_HI); lo = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_LO); diff --git a/trunk/drivers/char/tpm/tpm_tis.c b/trunk/drivers/char/tpm/tpm_tis.c index 483f3f60013c..ee7ac6f43c65 100644 --- a/trunk/drivers/char/tpm/tpm_tis.c +++ b/trunk/drivers/char/tpm/tpm_tis.c @@ -377,7 +377,7 @@ static struct tpm_vendor_specific tpm_tis = { .fops = &tis_ops,}, }; -static irqreturn_t tis_int_probe(int irq, void *dev_id) +static irqreturn_t tis_int_probe(int irq, void *dev_id, struct pt_regs *regs) { struct tpm_chip *chip = (struct tpm_chip *) dev_id; u32 interrupt; @@ -397,7 +397,7 @@ static irqreturn_t tis_int_probe(int irq, void *dev_id) return IRQ_HANDLED; } -static irqreturn_t tis_int_handler(int irq, void *dev_id) +static irqreturn_t tis_int_handler(int irq, void *dev_id, struct pt_regs *regs) { struct tpm_chip *chip = (struct tpm_chip *) dev_id; u32 interrupt; diff --git a/trunk/drivers/char/tty_io.c b/trunk/drivers/char/tty_io.c index 50dc49205a23..e90ea39c7c4b 100644 --- a/trunk/drivers/char/tty_io.c +++ b/trunk/drivers/char/tty_io.c @@ -3612,8 +3612,7 @@ static struct class *tty_class; * This field is optional, if there is no known struct device * for this tty device it can be set to NULL safely. * - * Returns a pointer to the struct device for this tty device - * (or ERR_PTR(-EFOO) on error). + * Returns a pointer to the class device (or ERR_PTR(-EFOO) on error). * * This call is required to be made to register an individual tty device * if the tty driver's flags have the TTY_DRIVER_DYNAMIC_DEV bit set. If @@ -3623,8 +3622,8 @@ static struct class *tty_class; * Locking: ?? */ -struct device *tty_register_device(struct tty_driver *driver, unsigned index, - struct device *device) +struct class_device *tty_register_device(struct tty_driver *driver, + unsigned index, struct device *device) { char name[64]; dev_t dev = MKDEV(driver->major, driver->minor_start) + index; @@ -3640,7 +3639,7 @@ struct device *tty_register_device(struct tty_driver *driver, unsigned index, else tty_line_name(driver, index, name); - return device_create(tty_class, device, dev, name); + return class_device_create(tty_class, NULL, dev, device, "%s", name); } /** @@ -3656,7 +3655,7 @@ struct device *tty_register_device(struct tty_driver *driver, unsigned index, void tty_unregister_device(struct tty_driver *driver, unsigned index) { - device_destroy(tty_class, MKDEV(driver->major, driver->minor_start) + index); + class_device_destroy(tty_class, MKDEV(driver->major, driver->minor_start) + index); } EXPORT_SYMBOL(tty_register_device); @@ -3896,20 +3895,20 @@ static int __init tty_init(void) if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) || register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0) panic("Couldn't register /dev/tty driver\n"); - device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), "tty"); + class_device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), NULL, "tty"); cdev_init(&console_cdev, &console_fops); if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) || register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0) panic("Couldn't register /dev/console driver\n"); - device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), "console"); + class_device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), NULL, "console"); #ifdef CONFIG_UNIX98_PTYS cdev_init(&ptmx_cdev, &ptmx_fops); if (cdev_add(&ptmx_cdev, MKDEV(TTYAUX_MAJOR, 2), 1) || register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0) panic("Couldn't register /dev/ptmx driver\n"); - device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 2), "ptmx"); + class_device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx"); #endif #ifdef CONFIG_VT @@ -3917,7 +3916,7 @@ static int __init tty_init(void) if (cdev_add(&vc0_cdev, MKDEV(TTY_MAJOR, 0), 1) || register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0) panic("Couldn't register /dev/tty0 driver\n"); - device_create(tty_class, NULL, MKDEV(TTY_MAJOR, 0), "tty0"); + class_device_create(tty_class, NULL, MKDEV(TTY_MAJOR, 0), NULL, "tty0"); vty_init(); #endif diff --git a/trunk/drivers/char/vc_screen.c b/trunk/drivers/char/vc_screen.c index f442b574b44a..bd7a98c6ea7a 100644 --- a/trunk/drivers/char/vc_screen.c +++ b/trunk/drivers/char/vc_screen.c @@ -476,16 +476,16 @@ static struct class *vc_class; void vcs_make_sysfs(struct tty_struct *tty) { - device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 1), - "vcs%u", tty->index + 1); - device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 129), - "vcsa%u", tty->index + 1); + class_device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 1), + NULL, "vcs%u", tty->index + 1); + class_device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 129), + NULL, "vcsa%u", tty->index + 1); } void vcs_remove_sysfs(struct tty_struct *tty) { - device_destroy(vc_class, MKDEV(VCS_MAJOR, tty->index + 1)); - device_destroy(vc_class, MKDEV(VCS_MAJOR, tty->index + 129)); + class_device_destroy(vc_class, MKDEV(VCS_MAJOR, tty->index + 1)); + class_device_destroy(vc_class, MKDEV(VCS_MAJOR, tty->index + 129)); } int __init vcs_init(void) @@ -494,7 +494,7 @@ int __init vcs_init(void) panic("unable to get major %d for vcs device", VCS_MAJOR); vc_class = class_create(THIS_MODULE, "vc"); - device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 0), "vcs"); - device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 128), "vcsa"); + class_device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 0), NULL, "vcs"); + class_device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 128), NULL, "vcsa"); return 0; } diff --git a/trunk/drivers/char/viocons.c b/trunk/drivers/char/viocons.c index 6d2e314860df..a362ee9c92dd 100644 --- a/trunk/drivers/char/viocons.c +++ b/trunk/drivers/char/viocons.c @@ -947,7 +947,7 @@ static void vioHandleData(struct HvLpEvent *event) */ continue; } else if (vio_sysrq_pressed) { - handle_sysrq(cevent->data[index], tty); + handle_sysrq(cevent->data[index], NULL, tty); vio_sysrq_pressed = 0; /* * continue because we don't want to add diff --git a/trunk/drivers/char/vme_scc.c b/trunk/drivers/char/vme_scc.c index d0b94dd1af6d..c2ca31eb850b 100644 --- a/trunk/drivers/char/vme_scc.c +++ b/trunk/drivers/char/vme_scc.c @@ -81,10 +81,10 @@ static int scc_ioctl(struct tty_struct * tty, struct file * filp, unsigned int cmd, unsigned long arg); static void scc_throttle(struct tty_struct *tty); static void scc_unthrottle(struct tty_struct *tty); -static irqreturn_t scc_tx_int(int irq, void *data); -static irqreturn_t scc_rx_int(int irq, void *data); -static irqreturn_t scc_stat_int(int irq, void *data); -static irqreturn_t scc_spcond_int(int irq, void *data); +static irqreturn_t scc_tx_int(int irq, void *data, struct pt_regs *fp); +static irqreturn_t scc_rx_int(int irq, void *data, struct pt_regs *fp); +static irqreturn_t scc_stat_int(int irq, void *data, struct pt_regs *fp); +static irqreturn_t scc_spcond_int(int irq, void *data, struct pt_regs *fp); static void scc_setsignals(struct scc_port *port, int dtr, int rts); static void scc_break_ctl(struct tty_struct *tty, int break_state); @@ -419,7 +419,7 @@ module_init(vme_scc_init); * Interrupt handlers *--------------------------------------------------------------------------*/ -static irqreturn_t scc_rx_int(int irq, void *data) +static irqreturn_t scc_rx_int(int irq, void *data, struct pt_regs *fp) { unsigned char ch; struct scc_port *port = data; @@ -440,7 +440,7 @@ static irqreturn_t scc_rx_int(int irq, void *data) */ if (SCCread(INT_PENDING_REG) & (port->channel == CHANNEL_A ? IPR_A_RX : IPR_B_RX)) { - scc_spcond_int (irq, data); + scc_spcond_int (irq, data, fp); return IRQ_HANDLED; } @@ -451,7 +451,7 @@ static irqreturn_t scc_rx_int(int irq, void *data) } -static irqreturn_t scc_spcond_int(int irq, void *data) +static irqreturn_t scc_spcond_int(int irq, void *data, struct pt_regs *fp) { struct scc_port *port = data; struct tty_struct *tty = port->gs.tty; @@ -496,7 +496,7 @@ static irqreturn_t scc_spcond_int(int irq, void *data) } -static irqreturn_t scc_tx_int(int irq, void *data) +static irqreturn_t scc_tx_int(int irq, void *data, struct pt_regs *fp) { struct scc_port *port = data; SCC_ACCESS_INIT(port); @@ -538,7 +538,7 @@ static irqreturn_t scc_tx_int(int irq, void *data) } -static irqreturn_t scc_stat_int(int irq, void *data) +static irqreturn_t scc_stat_int(int irq, void *data, struct pt_regs *fp) { struct scc_port *port = data; unsigned channel = port->channel; @@ -593,7 +593,7 @@ static void scc_enable_tx_interrupts(void *ptr) local_irq_save(flags); SCCmod(INT_AND_DMA_REG, 0xff, IDR_TX_INT_ENAB); /* restart the transmitter */ - scc_tx_int (0, port); + scc_tx_int (0, port, 0); local_irq_restore(flags); } diff --git a/trunk/drivers/char/vr41xx_giu.c b/trunk/drivers/char/vr41xx_giu.c index 8e7949305171..8116a47b80f4 100644 --- a/trunk/drivers/char/vr41xx_giu.c +++ b/trunk/drivers/char/vr41xx_giu.c @@ -221,7 +221,7 @@ static struct hw_interrupt_type giuint_high_irq_type = { .end = end_giuint_high_irq, }; -static int giu_get_irq(unsigned int irq) +static int giu_get_irq(unsigned int irq, struct pt_regs *regs) { uint16_t pendl, pendh, maskl, maskh; int i; diff --git a/trunk/drivers/char/vt.c b/trunk/drivers/char/vt.c index 87587b4385ab..8e4413f6fbaf 100644 --- a/trunk/drivers/char/vt.c +++ b/trunk/drivers/char/vt.c @@ -112,7 +112,7 @@ struct con_driver { const struct consw *con; const char *desc; - struct device *dev; + struct class_device *class_dev; int node; int first; int last; @@ -3023,10 +3023,10 @@ static inline int vt_unbind(struct con_driver *con) } #endif /* CONFIG_VT_HW_CONSOLE_BINDING */ -static ssize_t store_bind(struct device *dev, struct device_attribute *attr, +static ssize_t store_bind(struct class_device *class_device, const char *buf, size_t count) { - struct con_driver *con = dev_get_drvdata(dev); + struct con_driver *con = class_get_devdata(class_device); int bind = simple_strtoul(buf, NULL, 0); if (bind) @@ -3037,19 +3037,17 @@ static ssize_t store_bind(struct device *dev, struct device_attribute *attr, return count; } -static ssize_t show_bind(struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t show_bind(struct class_device *class_device, char *buf) { - struct con_driver *con = dev_get_drvdata(dev); + struct con_driver *con = class_get_devdata(class_device); int bind = con_is_bound(con->con); return snprintf(buf, PAGE_SIZE, "%i\n", bind); } -static ssize_t show_name(struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t show_name(struct class_device *class_device, char *buf) { - struct con_driver *con = dev_get_drvdata(dev); + struct con_driver *con = class_get_devdata(class_device); return snprintf(buf, PAGE_SIZE, "%s %s\n", (con->flag & CON_DRIVER_FLAG_MODULE) ? "(M)" : "(S)", @@ -3057,40 +3055,43 @@ static ssize_t show_name(struct device *dev, struct device_attribute *attr, } -static struct device_attribute device_attrs[] = { +static struct class_device_attribute class_device_attrs[] = { __ATTR(bind, S_IRUGO|S_IWUSR, show_bind, store_bind), __ATTR(name, S_IRUGO, show_name, NULL), }; -static int vtconsole_init_device(struct con_driver *con) +static int vtconsole_init_class_device(struct con_driver *con) { int i; int error = 0; con->flag |= CON_DRIVER_FLAG_ATTR; - dev_set_drvdata(con->dev, con); - for (i = 0; i < ARRAY_SIZE(device_attrs); i++) { - error = device_create_file(con->dev, &device_attrs[i]); + class_set_devdata(con->class_dev, con); + for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) { + error = class_device_create_file(con->class_dev, + &class_device_attrs[i]); if (error) break; } if (error) { while (--i >= 0) - device_remove_file(con->dev, &device_attrs[i]); + class_device_remove_file(con->class_dev, + &class_device_attrs[i]); con->flag &= ~CON_DRIVER_FLAG_ATTR; } return error; } -static void vtconsole_deinit_device(struct con_driver *con) +static void vtconsole_deinit_class_device(struct con_driver *con) { int i; if (con->flag & CON_DRIVER_FLAG_ATTR) { - for (i = 0; i < ARRAY_SIZE(device_attrs); i++) - device_remove_file(con->dev, &device_attrs[i]); + for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) + class_device_remove_file(con->class_dev, + &class_device_attrs[i]); con->flag &= ~CON_DRIVER_FLAG_ATTR; } } @@ -3178,17 +3179,18 @@ int register_con_driver(const struct consw *csw, int first, int last) if (retval) goto err; - con_driver->dev = device_create(vtconsole_class, NULL, - MKDEV(0, con_driver->node), - "vtcon%i", con_driver->node); + con_driver->class_dev = class_device_create(vtconsole_class, NULL, + MKDEV(0, con_driver->node), + NULL, "vtcon%i", + con_driver->node); - if (IS_ERR(con_driver->dev)) { - printk(KERN_WARNING "Unable to create device for %s; " + if (IS_ERR(con_driver->class_dev)) { + printk(KERN_WARNING "Unable to create class_device for %s; " "errno = %ld\n", con_driver->desc, - PTR_ERR(con_driver->dev)); - con_driver->dev = NULL; + PTR_ERR(con_driver->class_dev)); + con_driver->class_dev = NULL; } else { - vtconsole_init_device(con_driver); + vtconsole_init_class_device(con_driver); } err: @@ -3224,12 +3226,12 @@ int unregister_con_driver(const struct consw *csw) if (con_driver->con == csw && con_driver->flag & CON_DRIVER_FLAG_MODULE) { - vtconsole_deinit_device(con_driver); - device_destroy(vtconsole_class, - MKDEV(0, con_driver->node)); + vtconsole_deinit_class_device(con_driver); + class_device_destroy(vtconsole_class, + MKDEV(0, con_driver->node)); con_driver->con = NULL; con_driver->desc = NULL; - con_driver->dev = NULL; + con_driver->class_dev = NULL; con_driver->node = 0; con_driver->flag = 0; con_driver->first = 0; @@ -3287,18 +3289,19 @@ static int __init vtconsole_class_init(void) for (i = 0; i < MAX_NR_CON_DRIVER; i++) { struct con_driver *con = ®istered_con_driver[i]; - if (con->con && !con->dev) { - con->dev = device_create(vtconsole_class, NULL, - MKDEV(0, con->node), - "vtcon%i", con->node); + if (con->con && !con->class_dev) { + con->class_dev = + class_device_create(vtconsole_class, NULL, + MKDEV(0, con->node), NULL, + "vtcon%i", con->node); - if (IS_ERR(con->dev)) { + if (IS_ERR(con->class_dev)) { printk(KERN_WARNING "Unable to create " - "device for %s; errno = %ld\n", - con->desc, PTR_ERR(con->dev)); - con->dev = NULL; + "class_device for %s; errno = %ld\n", + con->desc, PTR_ERR(con->class_dev)); + con->class_dev = NULL; } else { - vtconsole_init_device(con); + vtconsole_init_class_device(con); } } } diff --git a/trunk/drivers/char/watchdog/Kconfig b/trunk/drivers/char/watchdog/Kconfig index 0187b1185323..d3e99982b69a 100644 --- a/trunk/drivers/char/watchdog/Kconfig +++ b/trunk/drivers/char/watchdog/Kconfig @@ -363,6 +363,20 @@ config SCx200_WDT If compiled as a module, it will be called scx200_wdt. +config PC87413_WDT + tristate "NS PC87413 watchdog" + depends on WATCHDOG && X86 + ---help--- + This is the driver for the hardware watchdog on the PC87413 chipset + This watchdog simply watches your kernel to make sure it doesn't + freeze, and if it does, it reboots your computer after a certain + amount of time. + + To compile this driver as a module, choose M here: the + module will be called pc87413_wdt. + + Most people will say N. + config 60XX_WDT tristate "SBC-60XX Watchdog Timer" depends on WATCHDOG && X86 diff --git a/trunk/drivers/char/watchdog/Makefile b/trunk/drivers/char/watchdog/Makefile index 36440497047c..e6a9f6f1d4b7 100644 --- a/trunk/drivers/char/watchdog/Makefile +++ b/trunk/drivers/char/watchdog/Makefile @@ -50,6 +50,7 @@ obj-$(CONFIG_I8XX_TCO) += i8xx_tco.o obj-$(CONFIG_ITCO_WDT) += iTCO_wdt.o obj-$(CONFIG_SC1200_WDT) += sc1200wdt.o obj-$(CONFIG_SCx200_WDT) += scx200_wdt.o +obj-$(CONFIG_PC87413_WDT) += pc87413_wdt.o obj-$(CONFIG_60XX_WDT) += sbc60xxwdt.o obj-$(CONFIG_SBC8360_WDT) += sbc8360.o obj-$(CONFIG_CPU5_WDT) += cpu5wdt.o diff --git a/trunk/drivers/char/watchdog/alim7101_wdt.c b/trunk/drivers/char/watchdog/alim7101_wdt.c index bf25d0a55a99..5948863b592b 100644 --- a/trunk/drivers/char/watchdog/alim7101_wdt.c +++ b/trunk/drivers/char/watchdog/alim7101_wdt.c @@ -77,8 +77,7 @@ static struct pci_dev *alim7101_pmu; static int nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, int, 0); -MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __stringify(CONFIG_WATCHDOG_NOWAYOUT) ")"); +MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); /* * Whack the dog @@ -416,16 +415,6 @@ static int __init alim7101_wdt_init(void) module_init(alim7101_wdt_init); module_exit(alim7101_wdt_unload); -static struct pci_device_id alim7101_pci_tbl[] __devinitdata = { - { PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { } -}; - -MODULE_DEVICE_TABLE(pci, alim7101_pci_tbl); - MODULE_AUTHOR("Steve Hill"); MODULE_DESCRIPTION("ALi M7101 PMU Computer Watchdog Timer driver"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/char/watchdog/eurotechwdt.c b/trunk/drivers/char/watchdog/eurotechwdt.c index e228d6e173ce..4f4269754c46 100644 --- a/trunk/drivers/char/watchdog/eurotechwdt.c +++ b/trunk/drivers/char/watchdog/eurotechwdt.c @@ -153,7 +153,7 @@ static void eurwdt_activate_timer(void) * Kernel methods. */ -static irqreturn_t eurwdt_interrupt(int irq, void *dev_id) +static irqreturn_t eurwdt_interrupt(int irq, void *dev_id, struct pt_regs *regs) { printk(KERN_CRIT "timeout WDT timeout\n"); diff --git a/trunk/drivers/char/watchdog/mpcore_wdt.c b/trunk/drivers/char/watchdog/mpcore_wdt.c index 3404a9c67f08..02d336ace504 100644 --- a/trunk/drivers/char/watchdog/mpcore_wdt.c +++ b/trunk/drivers/char/watchdog/mpcore_wdt.c @@ -64,7 +64,7 @@ MODULE_PARM_DESC(mpcore_noboot, "MPcore watchdog action, set to 1 to ignore rebo * This is the interrupt handler. Note that we only use this * in testing mode, so don't actually do a reboot here. */ -static irqreturn_t mpcore_wdt_fire(int irq, void *arg) +static irqreturn_t mpcore_wdt_fire(int irq, void *arg, struct pt_regs *regs) { struct mpcore_wdt *wdt = arg; diff --git a/trunk/drivers/char/watchdog/pc87413_wdt.c b/trunk/drivers/char/watchdog/pc87413_wdt.c new file mode 100644 index 000000000000..a6d42cf385e6 --- /dev/null +++ b/trunk/drivers/char/watchdog/pc87413_wdt.c @@ -0,0 +1,610 @@ +/* + * NS pc87413-wdt Watchdog Timer driver for Linux 2.6.x.x + * + * This code is based on wdt.c with original copyright + * + * (C) Copyright 2006 Marcus Junker, + * and Sven Anders, + * + * 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. + * + * Neither Marcus Junker, Sven Anders nor ANDURAS AG + * admit liability nor provide warranty for any of this software. + * This material is provided "AS-IS" and at no charge. + * + * Release 1.00. + * + */ + + +/* #define DEBUG 1 */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define WATCHDOG_NAME "pc87413 WDT" +#define PFX WATCHDOG_NAME ": " +#define DPFX WATCHDOG_NAME " - DEBUG: " + +#define WDT_INDEX_IO_PORT (io+0) /* */ +#define WDT_DATA_IO_PORT (WDT_INDEX_IO_PORT+1) +#define SWC_LDN 0x04 +#define SIOCFG2 0x22 /* Serial IO register */ +#define WDCTL 0x10 /* Watchdog-Timer-Controll-Register */ +#define WDTO 0x11 /* Watchdog timeout register */ +#define WDCFG 0x12 /* Watchdog config register */ + +#define WD_TIMEOUT 1 /* minutes (1 ... 255) */ + + +static int pc87413_is_open=0; + +/* + * You must set these - there is no sane way to probe for this board. + * You can use pc87413=x to set these now. + */ + + + +/** + * module_params + * + * Setup options. The board isn't really probe-able so we have to + * get the user to tell us the configuration. + */ + +static int io=0x2E; /* Normally used addres on Portwell Boards */ +module_param(io, int, 0); +MODULE_PARM_DESC(wdt_io, WATCHDOG_NAME " io port (default 0x2E)"); + +static int timeout = WD_TIMEOUT; /* in minutes */ +module_param(timeout, int, 0); +MODULE_PARM_DESC(timeout, "Watchdog timeout in minutes. 1<= timeout <=63, default=" __MODULE_STRING(WD_TIMEOUT) "."); + + +/****************************************** + * Helper functions + ******************************************/ + +static void +pc87413_select_wdt_out (void) +{ + + unsigned int cr_data=0; + + /* Select multiple pin,pin55,as WDT output */ + + outb_p(SIOCFG2, WDT_INDEX_IO_PORT); + + cr_data = inb (WDT_DATA_IO_PORT); + + cr_data |= 0x80; /* Set Bit7 to 1*/ + outb_p(SIOCFG2, WDT_INDEX_IO_PORT); + + outb_p(cr_data, WDT_DATA_IO_PORT); + + + #ifdef DEBUG + printk(KERN_INFO DPFX "Select multiple pin,pin55,as WDT output: Bit7 to 1: %d\n", cr_data); + #endif +} + +static void +pc87413_enable_swc(void) +{ + + unsigned int cr_data=0; + + /* Step 2: Enable SWC functions */ + + outb_p(0x07, WDT_INDEX_IO_PORT); /* Point SWC_LDN (LDN=4) */ + outb_p(SWC_LDN, WDT_DATA_IO_PORT); + + outb_p(0x30, WDT_INDEX_IO_PORT); /* Read Index 0x30 First */ + cr_data = inb (WDT_DATA_IO_PORT); + cr_data |= 0x01; /* Set Bit0 to 1 */ + outb_p(0x30, WDT_INDEX_IO_PORT); + outb_p(cr_data, WDT_DATA_IO_PORT); /* Index0x30_bit0P1 */ + + #ifdef DEBUG + printk(KERN_INFO DPFX "pc87413 - Enable SWC functions\n"); + #endif +} + +static unsigned int +pc87413_get_swc_base(void) +{ + unsigned int swc_base_addr = 0; + unsigned char addr_l, addr_h = 0; + + /* Step 3: Read SWC I/O Base Address */ + + outb_p(0x60, WDT_INDEX_IO_PORT); /* Read Index 0x60 */ + addr_h = inb (WDT_DATA_IO_PORT); + + outb_p(0x61, WDT_INDEX_IO_PORT); /* Read Index 0x61 */ + + addr_l = inb (WDT_DATA_IO_PORT); + + + swc_base_addr = (addr_h << 8) + addr_l; + + #ifdef DEBUG + printk(KERN_INFO DPFX "Read SWC I/O Base Address: low %d, high %d, res %d\n", addr_l, addr_h, swc_base_addr); + #endif + + return swc_base_addr; +} + +static void +pc87413_swc_bank3(unsigned int swc_base_addr) +{ + /* Step 4: Select Bank3 of SWC */ + + outb_p (inb (swc_base_addr + 0x0f) | 0x03, swc_base_addr + 0x0f); + + #ifdef DEBUG + printk(KERN_INFO DPFX "Select Bank3 of SWC\n"); + #endif + +} + +static void +pc87413_programm_wdto (unsigned int swc_base_addr, char pc87413_time) +{ + /* Step 5: Programm WDTO, Twd. */ + + outb_p (pc87413_time, swc_base_addr + WDTO); + + #ifdef DEBUG + printk(KERN_INFO DPFX "Set WDTO to %d minutes\n", pc87413_time); + #endif +} + +static void +pc87413_enable_wden (unsigned int swc_base_addr) +{ + /* Step 6: Enable WDEN */ + + outb_p(inb (swc_base_addr + WDCTL) | 0x01, swc_base_addr + WDCTL); + + #ifdef DEBUG + printk(KERN_INFO DPFX "Enable WDEN\n"); + #endif +} + +static void +pc87413_enable_sw_wd_tren (unsigned int swc_base_addr) +{ + /* Enable SW_WD_TREN */ + + outb_p(inb (swc_base_addr + WDCFG) | 0x80, swc_base_addr + WDCFG); + + #ifdef DEBUG + printk(KERN_INFO DPFX "Enable SW_WD_TREN\n"); + #endif +} + +static void +pc87413_disable_sw_wd_tren (unsigned int swc_base_addr) +{ + /* Disable SW_WD_TREN */ + + outb_p(inb (swc_base_addr + WDCFG) & 0x7f, swc_base_addr + WDCFG); + + #ifdef DEBUG + printk(KERN_INFO DPFX "pc87413 - Disable SW_WD_TREN\n"); + #endif +} + + +static void +pc87413_enable_sw_wd_trg (unsigned int swc_base_addr) +{ + + /* Enable SW_WD_TRG */ + + outb_p(inb (swc_base_addr + WDCTL) | 0x80, swc_base_addr + WDCTL); + + #ifdef DEBUG + printk(KERN_INFO DPFX "pc87413 - Enable SW_WD_TRG\n"); + #endif +} + +static void +pc87413_disable_sw_wd_trg (unsigned int swc_base_addr) +{ + + /* Disable SW_WD_TRG */ + + outb_p(inb (swc_base_addr + WDCTL) & 0x7f, swc_base_addr + WDCTL); + + #ifdef DEBUG + printk(KERN_INFO DPFX "Disable SW_WD_TRG\n"); + #endif +} + + + +static void +pc87413_disable(void) +{ + unsigned int swc_base_addr; + + pc87413_select_wdt_out(); + pc87413_enable_swc(); + swc_base_addr = pc87413_get_swc_base(); + pc87413_swc_bank3(swc_base_addr); + pc87413_disable_sw_wd_tren(swc_base_addr); + pc87413_disable_sw_wd_trg(swc_base_addr); + pc87413_programm_wdto(swc_base_addr, 0); +} + + +static void +pc87413_refresh(char pc87413_time) +{ + unsigned int swc_base_addr; + + pc87413_select_wdt_out(); + pc87413_enable_swc(); + swc_base_addr = pc87413_get_swc_base(); + pc87413_swc_bank3(swc_base_addr); + pc87413_disable_sw_wd_tren(swc_base_addr); + pc87413_disable_sw_wd_trg(swc_base_addr); + pc87413_programm_wdto(swc_base_addr, pc87413_time); + pc87413_enable_wden(swc_base_addr); + pc87413_enable_sw_wd_tren(swc_base_addr); + pc87413_enable_sw_wd_trg(swc_base_addr); +} + + +static void +pc87413_enable(char pc87413_time) +{ + unsigned int swc_base_addr; + + pc87413_select_wdt_out(); + pc87413_enable_swc(); + swc_base_addr = pc87413_get_swc_base(); + pc87413_swc_bank3(swc_base_addr); + pc87413_programm_wdto(swc_base_addr, pc87413_time); + pc87413_enable_wden(swc_base_addr); + pc87413_enable_sw_wd_tren(swc_base_addr); + pc87413_enable_sw_wd_trg(swc_base_addr); + +} + + +/******************************************* + * Kernel methods. + *******************************************/ + + +/** + * pc87413_status: + * + * Extract the status information from a WDT watchdog device. There are + * several board variants so we have to know which bits are valid. Some + * bits default to one and some to zero in order to be maximally painful. + * + * we then map the bits onto the status ioctl flags. + */ + +static int pc87413_status(void) +{ + /* Not supported */ + + return 1; +} + +static long long pc87413_llseek(struct file *file, long long offset, int origin) +{ + return -ESPIPE; +} + +/** + * pc87413_write: + * @file: file handle to the watchdog + * @buf: buffer to write (unused as data does not matter here + * @count: count of bytes + * @ppos: pointer to the position to write. No seeks allowed + * + * A write to a watchdog device is defined as a keepalive signal. Any + * write of data will do, as we we don't define content meaning. + */ + +static ssize_t +pc87413_write (struct file *file, const char __user *buf, size_t count, loff_t *ppos) +{ + if (count) { + pc87413_refresh (WD_TIMEOUT); + #ifdef DEBUG + printk(KERN_INFO DPFX "Write\n"); + #endif + } + return count; +} + +/* + * Read reports the temperature in degrees Fahrenheit. + */ +static ssize_t +pc87413_read(struct file *file, char *buf, size_t count, loff_t *ptr) +{ + +// char timeout; +// +// outb_p(0x08, WDT_EFER); /* Select locical device 8 */ +// outb_p(0x0F6, WDT_EFER); /* Select CRF6 */ +// timeout = inb(WDT_EFDR); /* Read Timeout counter from CRF6 */ + + +// if(copy_to_user(buf,&timeout,1)) +// return -EFAULT; + return 1; + + +} + + /** + * pc87413_ioctl: + * @inode: inode of the device + * @file: file handle to the device + * @cmd: watchdog command + * @arg: argument pointer + * + * The watchdog API defines a common set of functions for all watchdogs + * according to their available features. We only actually usefully support + * querying capabilities and current status. + */ + +static int +pc87413_ioctl(struct inode *inode, struct file *file, unsigned int cmd, + unsigned long arg) +{ + static struct watchdog_info ident= + { + .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, + .firmware_version = 1, + .identity = "pc87413(HF/F)" + }; + + ident.options=1; /* Mask down to the card we have */ + + switch(cmd) + { + default: + return -ENOIOCTLCMD; + case WDIOC_GETSUPPORT: + return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))?-EFAULT:0; + case WDIOC_GETSTATUS: + return put_user(pc87413_status(),(int *)arg); + case WDIOC_GETBOOTSTATUS: + return put_user(0, (int *)arg); + case WDIOC_KEEPALIVE: + pc87413_refresh(WD_TIMEOUT); + #ifdef DEBUG + printk(KERN_INFO DPFX "keepalive\n"); + #endif + return 0; + } +} + +/** + * pc87413_open: + * @inode: inode of device + * @file: file handle to device + * + * One of our two misc devices has been opened. The watchdog device is + * single open and on opening we load the counters. Counter zero is a + * 100Hz cascade, into counter 1 which downcounts to reboot. When the + * counter triggers counter 2 downcounts the length of the reset pulse + * which set set to be as long as possible. + */ + +static int +pc87413_open(struct inode *inode, struct file *file) +{ + switch(MINOR(inode->i_rdev)) + { + case WATCHDOG_MINOR: + if(pc87413_is_open) + return -EBUSY; + /* + * Activate + */ + + pc87413_is_open=1; + pc87413_refresh(WD_TIMEOUT); + #ifdef DEBUG + printk(KERN_INFO DPFX "Open\n"); + #endif + return 0; + case TEMP_MINOR: + return 0; + default: + return -ENODEV; + } +} + +/** + * pc87413_close: + * @inode: inode to board + * @file: file handle to board + * + * The watchdog has a configurable API. There is a religious dispute + * between people who want their watchdog to be able to shut down and + * those who want to be sure if the watchdog manager dies the machine + * reboots. In the former case we disable the counters, in the latter + * case you have to open it again very soon. + */ + +static int +pc87413_release(struct inode *inode, struct file *file) +{ + if(MINOR(inode->i_rdev)==WATCHDOG_MINOR) + { +#ifndef CONFIG_WATCHDOG_NOWAYOUT + pc87413_disable(); +#endif + pc87413_is_open=0; + #ifdef DEBUG + printk(KERN_INFO DPFX "Release\n"); + #endif + } + return 0; +} + +/** + * notify_sys: + * @this: our notifier block + * @code: the event being reported + * @unused: unused + * + * Our notifier is called on system shutdowns. We want to turn the card + * off at reboot otherwise the machine will reboot again during memory + * test or worse yet during the following fsck. This would suck, in fact + * trust me - if it happens it does suck. + */ + +static int +pc87413_notify_sys(struct notifier_block *this, unsigned long code, + void *unused) +{ + if(code==SYS_DOWN || code==SYS_HALT) + { + /* Turn the card off */ + pc87413_disable(); + } + return NOTIFY_DONE; +} + + +/***************************************************** + * Kernel Interfaces + *****************************************************/ + + +static struct file_operations pc87413_fops = { + .owner = THIS_MODULE, + .llseek = pc87413_llseek, + .read = pc87413_read, + .write = pc87413_write, + .ioctl = pc87413_ioctl, + .open = pc87413_open, + .release = pc87413_release, +}; + +static struct miscdevice pc87413_miscdev= +{ + .minor = WATCHDOG_MINOR, + .name = "watchdog", + .fops = &pc87413_fops +}; + +/* + * The WDT card needs to learn about soft shutdowns in order to + * turn the timebomb registers off. + */ + +static struct notifier_block pc87413_notifier= +{ + pc87413_notify_sys, + NULL, + 0 +}; + + +/** + * pc87413_exit: + * + * Unload the watchdog. You cannot do this with any file handles open. + * If your watchdog is set to continue ticking on close and you unload + * it, well it keeps ticking. We won't get the interrupt but the board + * will not touch PC memory so all is fine. You just have to load a new + * module in 60 seconds or reboot. + */ + +static void +pc87413_exit(void) +{ + pc87413_disable(); + misc_deregister(&pc87413_miscdev); + unregister_reboot_notifier(&pc87413_notifier); + /* release_region(io,2); */ +} + + +/** + * pc87413_init: + * + * Set up the WDT watchdog board. All we have to do is grab the + * resources we require and bitch if anyone beat us to them. + * The open() function will actually kick the board off. + */ + +static int +pc87413_init(void) +{ + int ret; + + printk(KERN_INFO PFX "Version 1.00 at io 0x%X\n", WDT_INDEX_IO_PORT); + + + /* request_region(io, 2, "pc87413"); */ + + + ret = register_reboot_notifier(&pc87413_notifier); + if (ret != 0) { + printk (KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", + ret); + } + + + + ret = misc_register(&pc87413_miscdev); + + if (ret != 0) { + printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", + WATCHDOG_MINOR, ret); + unregister_reboot_notifier(&pc87413_notifier); + return ret; + } + + printk (KERN_INFO PFX "initialized. timeout=%d min \n", timeout); + + + pc87413_enable(WD_TIMEOUT); + + return 0; +} + + +module_init(pc87413_init); +module_exit(pc87413_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Marcus Junker , Sven Anders "); +MODULE_DESCRIPTION("PC87413 WDT driver"); +MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); + diff --git a/trunk/drivers/char/watchdog/pcwd_usb.c b/trunk/drivers/char/watchdog/pcwd_usb.c index e275dd4a705d..77662cb0ac46 100644 --- a/trunk/drivers/char/watchdog/pcwd_usb.c +++ b/trunk/drivers/char/watchdog/pcwd_usb.c @@ -158,7 +158,7 @@ static struct usb_driver usb_pcwd_driver = { }; -static void usb_pcwd_intr_done(struct urb *urb) +static void usb_pcwd_intr_done(struct urb *urb, struct pt_regs *regs) { struct usb_pcwd_private *usb_pcwd = (struct usb_pcwd_private *)urb->context; unsigned char *data = usb_pcwd->intr_buffer; @@ -561,7 +561,8 @@ static struct notifier_block usb_pcwd_notifier = { */ static inline void usb_pcwd_delete (struct usb_pcwd_private *usb_pcwd) { - usb_free_urb(usb_pcwd->intr_urb); + if (usb_pcwd->intr_urb != NULL) + usb_free_urb (usb_pcwd->intr_urb); if (usb_pcwd->intr_buffer != NULL) usb_buffer_free(usb_pcwd->udev, usb_pcwd->intr_size, usb_pcwd->intr_buffer, usb_pcwd->intr_dma); diff --git a/trunk/drivers/char/watchdog/s3c2410_wdt.c b/trunk/drivers/char/watchdog/s3c2410_wdt.c index 18cb050c3862..d54d0efe0756 100644 --- a/trunk/drivers/char/watchdog/s3c2410_wdt.c +++ b/trunk/drivers/char/watchdog/s3c2410_wdt.c @@ -336,7 +336,8 @@ static struct miscdevice s3c2410wdt_miscdev = { /* interrupt handler code */ -static irqreturn_t s3c2410wdt_irq(int irqno, void *param) +static irqreturn_t s3c2410wdt_irq(int irqno, void *param, + struct pt_regs *regs) { printk(KERN_INFO PFX "Watchdog timer expired!\n"); diff --git a/trunk/drivers/char/watchdog/sc1200wdt.c b/trunk/drivers/char/watchdog/sc1200wdt.c index e3239833e4b0..d8d0f28e0acf 100644 --- a/trunk/drivers/char/watchdog/sc1200wdt.c +++ b/trunk/drivers/char/watchdog/sc1200wdt.c @@ -392,7 +392,7 @@ static int __init sc1200wdt_init(void) if (io == -1) { printk(KERN_ERR PFX "io parameter must be specified\n"); ret = -EINVAL; - goto out_pnp; + goto out_clean; } #if defined CONFIG_PNP @@ -405,7 +405,7 @@ static int __init sc1200wdt_init(void) if (!request_region(io, io_len, SC1200_MODULE_NAME)) { printk(KERN_ERR PFX "Unable to register IO port %#x\n", io); ret = -EBUSY; - goto out_pnp; + goto out_clean; } ret = sc1200wdt_probe(); @@ -435,11 +435,6 @@ static int __init sc1200wdt_init(void) out_io: release_region(io, io_len); -out_pnp: -#if defined CONFIG_PNP - if (isapnp) - pnp_unregister_driver(&scl200wdt_pnp_driver); -#endif goto out_clean; } diff --git a/trunk/drivers/char/watchdog/wdt.c b/trunk/drivers/char/watchdog/wdt.c index 517fbd8643f8..13f23f4a2233 100644 --- a/trunk/drivers/char/watchdog/wdt.c +++ b/trunk/drivers/char/watchdog/wdt.c @@ -225,13 +225,14 @@ static int wdt_get_temperature(int *temperature) * wdt_interrupt: * @irq: Interrupt number * @dev_id: Unused as we don't allow multiple devices. + * @regs: Unused. * * Handle an interrupt from the board. These are raised when the status * map changes in what the board considers an interesting way. That means * a failure condition occurring. */ -static irqreturn_t wdt_interrupt(int irq, void *dev_id) +static irqreturn_t wdt_interrupt(int irq, void *dev_id, struct pt_regs *regs) { /* * Read the status register see what is up and diff --git a/trunk/drivers/char/watchdog/wdt285.c b/trunk/drivers/char/watchdog/wdt285.c index e4cf661dc890..89a249e23fde 100644 --- a/trunk/drivers/char/watchdog/wdt285.c +++ b/trunk/drivers/char/watchdog/wdt285.c @@ -46,7 +46,7 @@ static unsigned long timer_alive; /* * If the timer expires.. */ -static void watchdog_fire(int irq, void *dev_id) +static void watchdog_fire(int irq, void *dev_id, struct pt_regs *regs) { printk(KERN_CRIT "Watchdog: Would Reboot.\n"); *CSR_TIMER4_CNTL = 0; diff --git a/trunk/drivers/char/watchdog/wdt_pci.c b/trunk/drivers/char/watchdog/wdt_pci.c index ce1261c5cbce..74d8cf836e13 100644 --- a/trunk/drivers/char/watchdog/wdt_pci.c +++ b/trunk/drivers/char/watchdog/wdt_pci.c @@ -270,13 +270,14 @@ static int wdtpci_get_temperature(int *temperature) * wdtpci_interrupt: * @irq: Interrupt number * @dev_id: Unused as we don't allow multiple devices. + * @regs: Unused. * * Handle an interrupt from the board. These are raised when the status * map changes in what the board considers an interesting way. That means * a failure condition occurring. */ -static irqreturn_t wdtpci_interrupt(int irq, void *dev_id) +static irqreturn_t wdtpci_interrupt(int irq, void *dev_id, struct pt_regs *regs) { /* * Read the status register see what is up and diff --git a/trunk/drivers/clocksource/acpi_pm.c b/trunk/drivers/clocksource/acpi_pm.c index 7fcb77a9d011..7ad3be8c0f49 100644 --- a/trunk/drivers/clocksource/acpi_pm.c +++ b/trunk/drivers/clocksource/acpi_pm.c @@ -54,8 +54,8 @@ static cycle_t acpi_pm_read_verified(void) v1 = read_pmtmr(); v2 = read_pmtmr(); v3 = read_pmtmr(); - } while (unlikely((v1 > v2 && v1 < v3) || (v2 > v3 && v2 < v1) - || (v3 > v1 && v3 < v2))); + } while ((v1 > v2 && v1 < v3) || (v2 > v3 && v2 < v1) + || (v3 > v1 && v3 < v2)); return (cycle_t)v2; } @@ -138,8 +138,6 @@ static void __devinit acpi_pm_check_graylist(struct pci_dev *dev) } DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, acpi_pm_check_graylist); -DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_LE, - acpi_pm_check_graylist); #endif diff --git a/trunk/drivers/cpufreq/Kconfig b/trunk/drivers/cpufreq/Kconfig index 491779af8d55..2cc71b66231e 100644 --- a/trunk/drivers/cpufreq/Kconfig +++ b/trunk/drivers/cpufreq/Kconfig @@ -107,7 +107,6 @@ config CPU_FREQ_GOV_USERSPACE config CPU_FREQ_GOV_ONDEMAND tristate "'ondemand' cpufreq policy governor" - select CPU_FREQ_TABLE help 'ondemand' - This driver adds a dynamic cpufreq policy governor. The governor does a periodic polling and diff --git a/trunk/drivers/cpufreq/cpufreq.c b/trunk/drivers/cpufreq/cpufreq.c index dd0c2623e27b..86e69b7f9122 100644 --- a/trunk/drivers/cpufreq/cpufreq.c +++ b/trunk/drivers/cpufreq/cpufreq.c @@ -59,7 +59,7 @@ static int __init init_cpufreq_transition_notifier_list(void) srcu_init_notifier_head(&cpufreq_transition_notifier_list); return 0; } -pure_initcall(init_cpufreq_transition_notifier_list); +core_initcall(init_cpufreq_transition_notifier_list); static LIST_HEAD(cpufreq_governor_list); static DEFINE_MUTEX (cpufreq_governor_mutex); diff --git a/trunk/drivers/dma/ioatdma.c b/trunk/drivers/dma/ioatdma.c index 0358419a0e48..dbd4d6c3698e 100644 --- a/trunk/drivers/dma/ioatdma.c +++ b/trunk/drivers/dma/ioatdma.c @@ -80,7 +80,7 @@ static int enumerate_dma_channels(struct ioat_device *device) static struct ioat_desc_sw *ioat_dma_alloc_descriptor( struct ioat_dma_chan *ioat_chan, - gfp_t flags) + int flags) { struct ioat_dma_descriptor *desc; struct ioat_desc_sw *desc_sw; @@ -563,7 +563,7 @@ static struct pci_driver ioat_pci_drv = { .remove = __devexit_p(ioat_remove), }; -static irqreturn_t ioat_do_interrupt(int irq, void *data) +static irqreturn_t ioat_do_interrupt(int irq, void *data, struct pt_regs *regs) { struct ioat_device *instance = data; unsigned long attnstatus; @@ -686,7 +686,7 @@ static int __devinit ioat_probe(struct pci_dev *pdev, { int err; unsigned long mmio_start, mmio_len; - void __iomem *reg_base; + void *reg_base; struct ioat_device *device; err = pci_enable_device(pdev); diff --git a/trunk/drivers/dma/ioatdma.h b/trunk/drivers/dma/ioatdma.h index 62b26a9be4c9..a5d3b3644160 100644 --- a/trunk/drivers/dma/ioatdma.h +++ b/trunk/drivers/dma/ioatdma.h @@ -44,7 +44,7 @@ extern struct list_head dma_client_list; struct ioat_device { struct pci_dev *pdev; - void __iomem *reg_base; + void *reg_base; struct pci_pool *dma_pool; struct pci_pool *completion_pool; @@ -73,7 +73,7 @@ struct ioat_device { struct ioat_dma_chan { - void __iomem *reg_base; + void *reg_base; dma_cookie_t completed_cookie; unsigned long last_completion; diff --git a/trunk/drivers/edac/edac_mc.c b/trunk/drivers/edac/edac_mc.c index 75e9e38330ff..4bde30bb3be7 100644 --- a/trunk/drivers/edac/edac_mc.c +++ b/trunk/drivers/edac/edac_mc.c @@ -230,43 +230,34 @@ static struct kobj_type ktype_memctrl = { */ static int edac_sysfs_memctrl_setup(void) { - int err = 0; + int err=0; debugf1("%s()\n", __func__); /* create the /sys/devices/system/edac directory */ err = sysdev_class_register(&edac_class); - if (err) { - debugf1("%s() error=%d\n", __func__, err); - return err; - } - - /* Init the MC's kobject */ - memset(&edac_memctrl_kobj, 0, sizeof (edac_memctrl_kobj)); - edac_memctrl_kobj.parent = &edac_class.kset.kobj; - edac_memctrl_kobj.ktype = &ktype_memctrl; - - /* generate sysfs "..../edac/mc" */ - err = kobject_set_name(&edac_memctrl_kobj,"mc"); - - if (err) - goto fail; - - /* FIXME: maybe new sysdev_create_subdir() */ - err = kobject_register(&edac_memctrl_kobj); + if (!err) { + /* Init the MC's kobject */ + memset(&edac_memctrl_kobj, 0, sizeof (edac_memctrl_kobj)); + edac_memctrl_kobj.parent = &edac_class.kset.kobj; + edac_memctrl_kobj.ktype = &ktype_memctrl; - if (err) { - debugf1("Failed to register '.../edac/mc'\n"); - goto fail; - } + /* generate sysfs "..../edac/mc" */ + err = kobject_set_name(&edac_memctrl_kobj,"mc"); - debugf1("Registered '.../edac/mc' kobject\n"); + if (!err) { + /* FIXME: maybe new sysdev_create_subdir() */ + err = kobject_register(&edac_memctrl_kobj); - return 0; + if (err) + debugf1("Failed to register '.../edac/mc'\n"); + else + debugf1("Registered '.../edac/mc' kobject\n"); + } + } else + debugf1("%s() error=%d\n", __func__, err); -fail: - sysdev_class_unregister(&edac_class); return err; } diff --git a/trunk/drivers/eisa/eisa-bus.c b/trunk/drivers/eisa/eisa-bus.c index d944647c82c2..3a365e159d89 100644 --- a/trunk/drivers/eisa/eisa-bus.c +++ b/trunk/drivers/eisa/eisa-bus.c @@ -226,26 +226,14 @@ static int __init eisa_init_device (struct eisa_root_device *root, static int __init eisa_register_device (struct eisa_device *edev) { - int rc = device_register (&edev->dev); - if (rc) - return rc; + if (device_register (&edev->dev)) + return -1; - rc = device_create_file (&edev->dev, &dev_attr_signature); - if (rc) goto err_devreg; - rc = device_create_file (&edev->dev, &dev_attr_enabled); - if (rc) goto err_sig; - rc = device_create_file (&edev->dev, &dev_attr_modalias); - if (rc) goto err_enab; + device_create_file (&edev->dev, &dev_attr_signature); + device_create_file (&edev->dev, &dev_attr_enabled); + device_create_file (&edev->dev, &dev_attr_modalias); return 0; - -err_enab: - device_remove_file (&edev->dev, &dev_attr_enabled); -err_sig: - device_remove_file (&edev->dev, &dev_attr_signature); -err_devreg: - device_unregister(&edev->dev); - return rc; } static int __init eisa_request_resources (struct eisa_root_device *root, diff --git a/trunk/drivers/fc4/fc.c b/trunk/drivers/fc4/fc.c index ca4e67a022d0..22d17474755f 100644 --- a/trunk/drivers/fc4/fc.c +++ b/trunk/drivers/fc4/fc.c @@ -70,9 +70,9 @@ #define FCP_CMND(SCpnt) ((fcp_cmnd *)&(SCpnt->SCp)) #define FC_SCMND(SCpnt) ((fc_channel *)(SCpnt->device->host->hostdata[0])) -#define SC_FCMND(fcmnd) ((struct scsi_cmnd *)((long)fcmnd - (long)&(((struct scsi_cmnd *)0)->SCp))) +#define SC_FCMND(fcmnd) ((Scsi_Cmnd *)((long)fcmnd - (long)&(((Scsi_Cmnd *)0)->SCp))) -static int fcp_scsi_queue_it(fc_channel *, struct scsi_cmnd *, fcp_cmnd *, int); +static int fcp_scsi_queue_it(fc_channel *, Scsi_Cmnd *, fcp_cmnd *, int); void fcp_queue_empty(fc_channel *); static void fcp_scsi_insert_queue (fc_channel *fc, fcp_cmnd *fcmd) @@ -378,14 +378,14 @@ void fcp_register(fc_channel *fc, u8 type, int unregister) printk ("FC: %segistering unknown type %02x\n", unregister ? "Unr" : "R", type); } -static void fcp_scsi_done(struct scsi_cmnd *SCpnt); +static void fcp_scsi_done(Scsi_Cmnd *SCpnt); static inline void fcp_scsi_receive(fc_channel *fc, int token, int status, fc_hdr *fch) { fcp_cmnd *fcmd; fcp_rsp *rsp; int host_status; - struct scsi_cmnd *SCpnt; + Scsi_Cmnd *SCpnt; int sense_len; int rsp_status; @@ -757,14 +757,13 @@ void fcp_release(fc_channel *fcchain, int count) /* count must > 0 */ } -static void fcp_scsi_done(struct scsi_cmnd *SCpnt) +static void fcp_scsi_done (Scsi_Cmnd *SCpnt) { if (FCP_CMND(SCpnt)->done) FCP_CMND(SCpnt)->done(SCpnt); } -static int fcp_scsi_queue_it(fc_channel *fc, struct scsi_cmnd *SCpnt, - fcp_cmnd *fcmd, int prepare) +static int fcp_scsi_queue_it(fc_channel *fc, Scsi_Cmnd *SCpnt, fcp_cmnd *fcmd, int prepare) { long i; fcp_cmd *cmd; @@ -838,8 +837,7 @@ static int fcp_scsi_queue_it(fc_channel *fc, struct scsi_cmnd *SCpnt, return 0; } -int fcp_scsi_queuecommand(struct scsi_cmnd *SCpnt, - void (* done)(struct scsi_cmnd *)) +int fcp_scsi_queuecommand(Scsi_Cmnd *SCpnt, void (* done)(Scsi_Cmnd *)) { fcp_cmnd *fcmd = FCP_CMND(SCpnt); fc_channel *fc = FC_SCMND(SCpnt); @@ -875,7 +873,7 @@ void fcp_queue_empty(fc_channel *fc) } } -int fcp_scsi_abort(struct scsi_cmnd *SCpnt) +int fcp_scsi_abort(Scsi_Cmnd *SCpnt) { /* Internal bookkeeping only. Lose 1 cmd_slots slot. */ fcp_cmnd *fcmd = FCP_CMND(SCpnt); @@ -912,7 +910,7 @@ int fcp_scsi_abort(struct scsi_cmnd *SCpnt) } #if 0 -void fcp_scsi_reset_done(struct scsi_cmnd *SCpnt) +void fcp_scsi_reset_done(Scsi_Cmnd *SCpnt) { fc_channel *fc = FC_SCMND(SCpnt); @@ -923,7 +921,7 @@ void fcp_scsi_reset_done(struct scsi_cmnd *SCpnt) #define FCP_RESET_TIMEOUT (2*HZ) -int fcp_scsi_dev_reset(struct scsi_cmnd *SCpnt) +int fcp_scsi_dev_reset(Scsi_Cmnd *SCpnt) { #if 0 /* broken junk, but if davem wants to compile this driver, let him.. */ unsigned long flags; @@ -933,7 +931,7 @@ int fcp_scsi_dev_reset(struct scsi_cmnd *SCpnt) DECLARE_MUTEX_LOCKED(sem); if (!fc->rst_pkt) { - fc->rst_pkt = (struct scsi_cmnd *) kmalloc(sizeof(SCpnt), GFP_KERNEL); + fc->rst_pkt = (Scsi_Cmnd *) kmalloc(sizeof(SCpnt), GFP_KERNEL); if (!fc->rst_pkt) return FAILED; fcmd = FCP_CMND(fc->rst_pkt); @@ -1001,7 +999,7 @@ int fcp_scsi_dev_reset(struct scsi_cmnd *SCpnt) return SUCCESS; } -static int __fcp_scsi_host_reset(struct scsi_cmnd *SCpnt) +static int __fcp_scsi_host_reset(Scsi_Cmnd *SCpnt) { fc_channel *fc = FC_SCMND(SCpnt); fcp_cmnd *fcmd = FCP_CMND(SCpnt); @@ -1022,7 +1020,7 @@ static int __fcp_scsi_host_reset(struct scsi_cmnd *SCpnt) else return FAILED; } -int fcp_scsi_host_reset(struct scsi_cmnd *SCpnt) +int fcp_scsi_host_reset(Scsi_Cmnd *SCpnt) { unsigned long flags; int rc; diff --git a/trunk/drivers/fc4/fcp_impl.h b/trunk/drivers/fc4/fcp_impl.h index 1ac61330592e..c397c84bef63 100644 --- a/trunk/drivers/fc4/fcp_impl.h +++ b/trunk/drivers/fc4/fcp_impl.h @@ -39,7 +39,7 @@ struct _fc_channel; typedef struct fcp_cmnd { struct fcp_cmnd *next; struct fcp_cmnd *prev; - void (*done)(struct scsi_cmnd *); + void (*done)(Scsi_Cmnd *); unsigned short proto; unsigned short token; unsigned int did; @@ -94,14 +94,14 @@ typedef struct _fc_channel { long *scsi_bitmap; long scsi_bitmap_end; int scsi_free; - int (*encode_addr)(struct scsi_cmnd *, u16 *, struct _fc_channel *, fcp_cmnd *); + int (*encode_addr)(Scsi_Cmnd *, u16 *, struct _fc_channel *, fcp_cmnd *); fcp_cmnd *scsi_que; char scsi_name[4]; fcp_cmnd **cmd_slots; int channels; int targets; long *ages; - struct scsi_cmnd *rst_pkt; + Scsi_Cmnd *rst_pkt; fcp_posmap *posmap; /* LOGIN stuff */ fcp_cmnd *login; @@ -155,10 +155,9 @@ int fc_do_prli(fc_channel *, unsigned char); for_each_fc_channel(fc) \ if (fc->state == FC_STATE_ONLINE) -int fcp_scsi_queuecommand(struct scsi_cmnd *, - void (* done) (struct scsi_cmnd *)); -int fcp_scsi_abort(struct scsi_cmnd *); -int fcp_scsi_dev_reset(struct scsi_cmnd *); -int fcp_scsi_host_reset(struct scsi_cmnd *); +int fcp_scsi_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *)); +int fcp_scsi_abort(Scsi_Cmnd *); +int fcp_scsi_dev_reset(Scsi_Cmnd *); +int fcp_scsi_host_reset(Scsi_Cmnd *); #endif /* !(_FCP_SCSI_H) */ diff --git a/trunk/drivers/fc4/soc.c b/trunk/drivers/fc4/soc.c index b09dfc78e5a2..3b07e0ca81cd 100644 --- a/trunk/drivers/fc4/soc.c +++ b/trunk/drivers/fc4/soc.c @@ -334,7 +334,7 @@ static inline void soc_unsolicited (struct soc *s) } } -static irqreturn_t soc_intr(int irq, void *dev_id) +static irqreturn_t soc_intr(int irq, void *dev_id, struct pt_regs *regs) { u32 cmd; unsigned long flags; diff --git a/trunk/drivers/fc4/socal.c b/trunk/drivers/fc4/socal.c index a6b1ae256e16..2b75edc5859d 100644 --- a/trunk/drivers/fc4/socal.c +++ b/trunk/drivers/fc4/socal.c @@ -404,7 +404,7 @@ static inline void socal_unsolicited (struct socal *s, unsigned long qno) } } -static irqreturn_t socal_intr(int irq, void *dev_id) +static irqreturn_t socal_intr(int irq, void *dev_id, struct pt_regs *regs) { u32 cmd; unsigned long flags; diff --git a/trunk/drivers/firmware/dcdbas.c b/trunk/drivers/firmware/dcdbas.c index 1865b56fb141..339f405ff708 100644 --- a/trunk/drivers/firmware/dcdbas.c +++ b/trunk/drivers/firmware/dcdbas.c @@ -8,7 +8,7 @@ * * See Documentation/dcdbas.txt for more information. * - * Copyright (C) 1995-2006 Dell Inc. + * Copyright (C) 1995-2005 Dell Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License v2.0 as published by @@ -40,7 +40,7 @@ #include "dcdbas.h" #define DRIVER_NAME "dcdbas" -#define DRIVER_VERSION "5.6.0-3.2" +#define DRIVER_VERSION "5.6.0-2" #define DRIVER_DESCRIPTION "Dell Systems Management Base Driver" static struct platform_device *dcdbas_pdev; @@ -175,9 +175,6 @@ static ssize_t smi_data_write(struct kobject *kobj, char *buf, loff_t pos, { ssize_t ret; - if ((pos + count) > MAX_SMI_DATA_BUF_SIZE) - return -EINVAL; - mutex_lock(&smi_data_lock); ret = smi_data_buf_realloc(pos + count); @@ -562,7 +559,7 @@ static int __devinit dcdbas_probe(struct platform_device *dev) while (--i >= 0) sysfs_remove_bin_file(&dev->dev.kobj, dcdbas_bin_attrs[i]); - sysfs_remove_group(&dev->dev.kobj, &dcdbas_attr_group); + sysfs_create_group(&dev->dev.kobj, &dcdbas_attr_group); return error; } } diff --git a/trunk/drivers/firmware/dell_rbu.c b/trunk/drivers/firmware/dell_rbu.c index fc702e40bd43..fc17599c905e 100644 --- a/trunk/drivers/firmware/dell_rbu.c +++ b/trunk/drivers/firmware/dell_rbu.c @@ -249,7 +249,7 @@ static int packetize_data(void *data, size_t length) if ((rc = create_packet(temp, packet_length))) return rc; - pr_debug("%p:%td\n", temp, (end - temp)); + pr_debug("%p:%lu\n", temp, (end - temp)); temp += packet_length; } @@ -705,39 +705,27 @@ static struct bin_attribute rbu_packet_size_attr = { static int __init dcdrbu_init(void) { - int rc; + int rc = 0; spin_lock_init(&rbu_data.lock); init_packet_head(); - rbu_device = platform_device_register_simple("dell_rbu", -1, NULL, 0); - if (IS_ERR(rbu_device)) { + rbu_device = + platform_device_register_simple("dell_rbu", -1, NULL, 0); + if (!rbu_device) { printk(KERN_ERR "dell_rbu:%s:platform_device_register_simple " "failed\n", __FUNCTION__); - return PTR_ERR(rbu_device); + return -EIO; } - rc = sysfs_create_bin_file(&rbu_device->dev.kobj, &rbu_data_attr); - if (rc) - goto out_devreg; - rc = sysfs_create_bin_file(&rbu_device->dev.kobj, &rbu_image_type_attr); - if (rc) - goto out_data; - rc = sysfs_create_bin_file(&rbu_device->dev.kobj, + sysfs_create_bin_file(&rbu_device->dev.kobj, &rbu_data_attr); + sysfs_create_bin_file(&rbu_device->dev.kobj, &rbu_image_type_attr); + sysfs_create_bin_file(&rbu_device->dev.kobj, &rbu_packet_size_attr); - if (rc) - goto out_imtype; rbu_data.entry_created = 0; - return 0; - -out_imtype: - sysfs_remove_bin_file(&rbu_device->dev.kobj, &rbu_image_type_attr); -out_data: - sysfs_remove_bin_file(&rbu_device->dev.kobj, &rbu_data_attr); -out_devreg: - platform_device_unregister(rbu_device); return rc; + } static __exit void dcdrbu_exit(void) diff --git a/trunk/drivers/firmware/dmi_scan.c b/trunk/drivers/firmware/dmi_scan.c index 37deee6c0c1c..b8b596d5778d 100644 --- a/trunk/drivers/firmware/dmi_scan.c +++ b/trunk/drivers/firmware/dmi_scan.c @@ -326,26 +326,6 @@ char *dmi_get_system_info(int field) } EXPORT_SYMBOL(dmi_get_system_info); - -/** - * dmi_name_in_vendors - Check if string is anywhere in the DMI vendor information. - * @str: Case sensitive Name - */ -int dmi_name_in_vendors(char *str) -{ - static int fields[] = { DMI_BIOS_VENDOR, DMI_BIOS_VERSION, DMI_SYS_VENDOR, - DMI_PRODUCT_NAME, DMI_PRODUCT_VERSION, DMI_BOARD_VENDOR, - DMI_BOARD_NAME, DMI_BOARD_VERSION, DMI_NONE }; - int i; - for (i = 0; fields[i] != DMI_NONE; i++) { - int f = fields[i]; - if (dmi_ident[f] && strstr(dmi_ident[f], str)) - return 1; - } - return 0; -} -EXPORT_SYMBOL(dmi_name_in_vendors); - /** * dmi_find_device - find onboard device by type/name * @type: device type or %DMI_DEV_TYPE_ANY to match all device types diff --git a/trunk/drivers/firmware/efivars.c b/trunk/drivers/firmware/efivars.c index 5ab5e393b882..8ebce1c03ad7 100644 --- a/trunk/drivers/firmware/efivars.c +++ b/trunk/drivers/firmware/efivars.c @@ -639,12 +639,7 @@ efivar_create_sysfs_entry(unsigned long variable_name_size, kobject_set_name(&new_efivar->kobj, "%s", short_name); kobj_set_kset_s(new_efivar, vars_subsys); - i = kobject_register(&new_efivar->kobj); - if (i) { - kfree(short_name); - kfree(new_efivar); - return 1; - } + kobject_register(&new_efivar->kobj); kfree(short_name); short_name = NULL; diff --git a/trunk/drivers/hwmon/Kconfig b/trunk/drivers/hwmon/Kconfig index e76d91906c99..9b88b25b6edb 100644 --- a/trunk/drivers/hwmon/Kconfig +++ b/trunk/drivers/hwmon/Kconfig @@ -95,13 +95,11 @@ config SENSORS_ADM9240 will be called adm9240. config SENSORS_K8TEMP - tristate "AMD Athlon64/FX or Opteron temperature sensor" + tristate "AMD K8 processor sensor" depends on HWMON && X86 && PCI && EXPERIMENTAL help If you say yes here you get support for the temperature - sensor(s) inside your CPU. Supported is whole AMD K8 - microarchitecture. Please note that you will need at least - lm-sensors 2.10.1 for proper userspace support. + sensor(s) inside your AMD K8 CPU. This driver can also be built as a module. If so, the module will be called k8temp. @@ -371,8 +369,8 @@ config SENSORS_SMSC47M1 help If you say yes here you get support for the integrated fan monitoring and control capabilities of the SMSC LPC47B27x, - LPC47M10x, LPC47M112, LPC47M13x, LPC47M14x, LPC47M15x, - LPC47M192 and LPC47M997 chips. + LPC47M10x, LPC47M13x, LPC47M14x, LPC47M15x, LPC47M192 and + LPC47M997 chips. The temperature and voltage sensor features of the LPC47M192 and LPC47M997 are supported by another driver, select also diff --git a/trunk/drivers/hwmon/adm9240.c b/trunk/drivers/hwmon/adm9240.c index aad594adf0c7..377961c4a41e 100644 --- a/trunk/drivers/hwmon/adm9240.c +++ b/trunk/drivers/hwmon/adm9240.c @@ -5,7 +5,7 @@ * Copyright (C) 1999 Frodo Looijaard * Philip Edelbrock * Copyright (C) 2003 Michiel Rook - * Copyright (C) 2005 Grant Coady with valuable + * Copyright (C) 2005 Grant Coady with valuable * guidance from Jean Delvare * * Driver supports Analog Devices ADM9240 @@ -774,7 +774,7 @@ static void __exit sensors_adm9240_exit(void) } MODULE_AUTHOR("Michiel Rook , " - "Grant Coady and others"); + "Grant Coady and others"); MODULE_DESCRIPTION("ADM9240/DS1780/LM81 driver"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/hwmon/lm78.c b/trunk/drivers/hwmon/lm78.c index 73bc2ffc598d..ac1b746df6d0 100644 --- a/trunk/drivers/hwmon/lm78.c +++ b/trunk/drivers/hwmon/lm78.c @@ -815,18 +815,18 @@ static int __init sm_lm78_init(void) if (res) return res; - /* Don't exit if this one fails, we still want the I2C variants - to work! */ - if (i2c_isa_add_driver(&lm78_isa_driver)) - isa_address = 0; + res = i2c_isa_add_driver(&lm78_isa_driver); + if (res) { + i2c_del_driver(&lm78_driver); + return res; + } return 0; } static void __exit sm_lm78_exit(void) { - if (isa_address) - i2c_isa_del_driver(&lm78_isa_driver); + i2c_isa_del_driver(&lm78_isa_driver); i2c_del_driver(&lm78_driver); } diff --git a/trunk/drivers/hwmon/smsc47m1.c b/trunk/drivers/hwmon/smsc47m1.c index beb881c4b2e8..47132fd26b1b 100644 --- a/trunk/drivers/hwmon/smsc47m1.c +++ b/trunk/drivers/hwmon/smsc47m1.c @@ -2,8 +2,8 @@ smsc47m1.c - Part of lm_sensors, Linux kernel modules for hardware monitoring - Supports the SMSC LPC47B27x, LPC47M10x, LPC47M112, LPC47M13x, - LPC47M14x, LPC47M15x, LPC47M192 and LPC47M997 Super-I/O chips. + Supports the SMSC LPC47B27x, LPC47M10x, LPC47M13x, LPC47M14x, + LPC47M15x, LPC47M192 and LPC47M997 Super-I/O chips. Copyright (C) 2002 Mark D. Studebaker Copyright (C) 2004 Jean Delvare @@ -380,8 +380,8 @@ static int __init smsc47m1_find(unsigned short *addr) val = superio_inb(SUPERIO_REG_DEVID); /* - * SMSC LPC47M10x/LPC47M112/LPC47M13x (device id 0x59), LPC47M14x - * (device id 0x5F) and LPC47B27x (device id 0x51) have fan control. + * SMSC LPC47M10x/LPC47M13x (device id 0x59), LPC47M14x (device id + * 0x5F) and LPC47B27x (device id 0x51) have fan control. * The LPC47M15x and LPC47M192 chips "with hardware monitoring block" * can do much more besides (device id 0x60). * The LPC47M997 is undocumented, but seems to be compatible with @@ -390,8 +390,7 @@ static int __init smsc47m1_find(unsigned short *addr) if (val == 0x51) printk(KERN_INFO "smsc47m1: Found SMSC LPC47B27x\n"); else if (val == 0x59) - printk(KERN_INFO "smsc47m1: Found SMSC " - "LPC47M10x/LPC47M112/LPC47M13x\n"); + printk(KERN_INFO "smsc47m1: Found SMSC LPC47M10x/LPC47M13x\n"); else if (val == 0x5F) printk(KERN_INFO "smsc47m1: Found SMSC LPC47M14x\n"); else if (val == 0x60) diff --git a/trunk/drivers/hwmon/w83627ehf.c b/trunk/drivers/hwmon/w83627ehf.c index 2257806d0102..833faa275ffa 100644 --- a/trunk/drivers/hwmon/w83627ehf.c +++ b/trunk/drivers/hwmon/w83627ehf.c @@ -354,8 +354,6 @@ static void w83627ehf_write_fan_div(struct i2c_client *client, int nr) case 0: reg = (w83627ehf_read_value(client, W83627EHF_REG_FANDIV1) & 0xcf) | ((data->fan_div[0] & 0x03) << 4); - /* fan5 input control bit is write only, compute the value */ - reg |= (data->has_fan & (1 << 4)) ? 1 : 0; w83627ehf_write_value(client, W83627EHF_REG_FANDIV1, reg); reg = (w83627ehf_read_value(client, W83627EHF_REG_VBAT) & 0xdf) | ((data->fan_div[0] & 0x04) << 3); @@ -364,8 +362,6 @@ static void w83627ehf_write_fan_div(struct i2c_client *client, int nr) case 1: reg = (w83627ehf_read_value(client, W83627EHF_REG_FANDIV1) & 0x3f) | ((data->fan_div[1] & 0x03) << 6); - /* fan5 input control bit is write only, compute the value */ - reg |= (data->has_fan & (1 << 4)) ? 1 : 0; w83627ehf_write_value(client, W83627EHF_REG_FANDIV1, reg); reg = (w83627ehf_read_value(client, W83627EHF_REG_VBAT) & 0xbf) | ((data->fan_div[1] & 0x04) << 4); @@ -1220,16 +1216,13 @@ static int w83627ehf_detect(struct i2c_adapter *adapter) superio_exit(); /* It looks like fan4 and fan5 pins can be alternatively used - as fan on/off switches, but fan5 control is write only :/ - We assume that if the serial interface is disabled, designers - connected fan5 as input unless they are emitting log 1, which - is not the default. */ + as fan on/off switches */ data->has_fan = 0x07; /* fan1, fan2 and fan3 */ i = w83627ehf_read_value(client, W83627EHF_REG_FANDIV1); if ((i & (1 << 2)) && (!fan4pin)) data->has_fan |= (1 << 3); - if (!(i & (1 << 1)) && (!fan5pin)) + if ((i & (1 << 0)) && (!fan5pin)) data->has_fan |= (1 << 4); /* Register sysfs hooks */ diff --git a/trunk/drivers/hwmon/w83781d.c b/trunk/drivers/hwmon/w83781d.c index 1232171c3aad..a4584ec69842 100644 --- a/trunk/drivers/hwmon/w83781d.c +++ b/trunk/drivers/hwmon/w83781d.c @@ -1099,8 +1099,7 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) bank. */ if (kind < 0) { if (w83781d_read_value(client, W83781D_REG_CONFIG) & 0x80) { - dev_dbg(&adapter->dev, "Detection of w83781d chip " - "failed at step 3\n"); + dev_dbg(dev, "Detection failed at step 3\n"); err = -ENODEV; goto ERROR2; } @@ -1110,8 +1109,7 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) if ((!(val1 & 0x07)) && (((!(val1 & 0x80)) && (val2 != 0xa3) && (val2 != 0xc3)) || ((val1 & 0x80) && (val2 != 0x5c) && (val2 != 0x12)))) { - dev_dbg(&adapter->dev, "Detection of w83781d chip " - "failed at step 4\n"); + dev_dbg(dev, "Detection failed at step 4\n"); err = -ENODEV; goto ERROR2; } @@ -1121,8 +1119,7 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) ((val1 & 0x80) && (val2 == 0x5c)))) { if (w83781d_read_value (client, W83781D_REG_I2C_ADDR) != address) { - dev_dbg(&adapter->dev, "Detection of w83781d " - "chip failed at step 5\n"); + dev_dbg(dev, "Detection failed at step 5\n"); err = -ENODEV; goto ERROR2; } @@ -1144,8 +1141,8 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) else if (val2 == 0x12) vendid = asus; else { - dev_dbg(&adapter->dev, "w83781d chip vendor is " - "neither Winbond nor Asus\n"); + dev_dbg(dev, "Chip was made by neither " + "Winbond nor Asus?\n"); err = -ENODEV; goto ERROR2; } @@ -1164,9 +1161,10 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) kind = as99127f; else { if (kind == 0) - dev_warn(&adapter->dev, "Ignoring 'force' " + dev_warn(dev, "Ignoring 'force' " "parameter for unknown chip at " - "address 0x%02x\n", address); + "adapter %d, address 0x%02x\n", + i2c_adapter_id(adapter), address); err = -EINVAL; goto ERROR2; } @@ -1687,10 +1685,11 @@ sensors_w83781d_init(void) if (res) return res; - /* Don't exit if this one fails, we still want the I2C variants - to work! */ - if (i2c_isa_add_driver(&w83781d_isa_driver)) - isa_address = 0; + res = i2c_isa_add_driver(&w83781d_isa_driver); + if (res) { + i2c_del_driver(&w83781d_driver); + return res; + } return 0; } @@ -1698,8 +1697,7 @@ sensors_w83781d_init(void) static void __exit sensors_w83781d_exit(void) { - if (isa_address) - i2c_isa_del_driver(&w83781d_isa_driver); + i2c_isa_del_driver(&w83781d_isa_driver); i2c_del_driver(&w83781d_driver); } diff --git a/trunk/drivers/hwmon/w83791d.c b/trunk/drivers/hwmon/w83791d.c index 9e5f885368b4..371ed4f69a97 100644 --- a/trunk/drivers/hwmon/w83791d.c +++ b/trunk/drivers/hwmon/w83791d.c @@ -746,52 +746,6 @@ static ssize_t store_vrm_reg(struct device *dev, static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg); -#define IN_UNIT_ATTRS(X) \ - &sda_in_input[X].dev_attr.attr, \ - &sda_in_min[X].dev_attr.attr, \ - &sda_in_max[X].dev_attr.attr - -#define FAN_UNIT_ATTRS(X) \ - &sda_fan_input[X].dev_attr.attr, \ - &sda_fan_min[X].dev_attr.attr, \ - &sda_fan_div[X].dev_attr.attr - -#define TEMP_UNIT_ATTRS(X) \ - &sda_temp_input[X].dev_attr.attr, \ - &sda_temp_max[X].dev_attr.attr, \ - &sda_temp_max_hyst[X].dev_attr.attr - -static struct attribute *w83791d_attributes[] = { - IN_UNIT_ATTRS(0), - IN_UNIT_ATTRS(1), - IN_UNIT_ATTRS(2), - IN_UNIT_ATTRS(3), - IN_UNIT_ATTRS(4), - IN_UNIT_ATTRS(5), - IN_UNIT_ATTRS(6), - IN_UNIT_ATTRS(7), - IN_UNIT_ATTRS(8), - IN_UNIT_ATTRS(9), - FAN_UNIT_ATTRS(0), - FAN_UNIT_ATTRS(1), - FAN_UNIT_ATTRS(2), - FAN_UNIT_ATTRS(3), - FAN_UNIT_ATTRS(4), - TEMP_UNIT_ATTRS(0), - TEMP_UNIT_ATTRS(1), - TEMP_UNIT_ATTRS(2), - &dev_attr_alarms.attr, - &sda_beep_ctrl[0].dev_attr.attr, - &sda_beep_ctrl[1].dev_attr.attr, - &dev_attr_cpu0_vid.attr, - &dev_attr_vrm.attr, - NULL -}; - -static const struct attribute_group w83791d_group = { - .attrs = w83791d_attributes, -}; - /* This function is called when: * w83791d_driver is inserted (when this module is loaded), for each available adapter @@ -1013,20 +967,41 @@ static int w83791d_detect(struct i2c_adapter *adapter, int address, int kind) } /* Register sysfs hooks */ - if ((err = sysfs_create_group(&client->dev.kobj, &w83791d_group))) - goto error3; - - /* Everything is ready, now register the working device */ data->class_dev = hwmon_device_register(dev); if (IS_ERR(data->class_dev)) { err = PTR_ERR(data->class_dev); - goto error4; + goto error3; } + for (i = 0; i < NUMBER_OF_VIN; i++) { + device_create_file(dev, &sda_in_input[i].dev_attr); + device_create_file(dev, &sda_in_min[i].dev_attr); + device_create_file(dev, &sda_in_max[i].dev_attr); + } + + for (i = 0; i < NUMBER_OF_FANIN; i++) { + device_create_file(dev, &sda_fan_input[i].dev_attr); + device_create_file(dev, &sda_fan_div[i].dev_attr); + device_create_file(dev, &sda_fan_min[i].dev_attr); + } + + for (i = 0; i < NUMBER_OF_TEMPIN; i++) { + device_create_file(dev, &sda_temp_input[i].dev_attr); + device_create_file(dev, &sda_temp_max[i].dev_attr); + device_create_file(dev, &sda_temp_max_hyst[i].dev_attr); + } + + device_create_file(dev, &dev_attr_alarms); + + for (i = 0; i < ARRAY_SIZE(sda_beep_ctrl); i++) { + device_create_file(dev, &sda_beep_ctrl[i].dev_attr); + } + + device_create_file(dev, &dev_attr_cpu0_vid); + device_create_file(dev, &dev_attr_vrm); + return 0; -error4: - sysfs_remove_group(&client->dev.kobj, &w83791d_group); error3: if (data->lm75[0] != NULL) { i2c_detach_client(data->lm75[0]); @@ -1050,10 +1025,8 @@ static int w83791d_detach_client(struct i2c_client *client) int err; /* main client */ - if (data) { + if (data) hwmon_device_unregister(data->class_dev); - sysfs_remove_group(&client->dev.kobj, &w83791d_group); - } if ((err = i2c_detach_client(client))) return err; diff --git a/trunk/drivers/i2c/busses/Kconfig b/trunk/drivers/i2c/busses/Kconfig index 04bee524e31a..510816c16da3 100644 --- a/trunk/drivers/i2c/busses/Kconfig +++ b/trunk/drivers/i2c/busses/Kconfig @@ -125,7 +125,6 @@ config I2C_I801 ICH7 ESB2 ICH8 - ICH9 This driver can also be built as a module. If so, the module will be called i2c-i801. diff --git a/trunk/drivers/i2c/busses/i2c-elektor.c b/trunk/drivers/i2c/busses/i2c-elektor.c index a591fe685f06..caa8e5c8bfbb 100644 --- a/trunk/drivers/i2c/busses/i2c-elektor.c +++ b/trunk/drivers/i2c/busses/i2c-elektor.c @@ -131,7 +131,7 @@ static void pcf_isa_waitforpin(void) { } -static irqreturn_t pcf_isa_handler(int this_irq, void *dev_id) { +static irqreturn_t pcf_isa_handler(int this_irq, void *dev_id, struct pt_regs *regs) { spin_lock(&lock); pcf_pending = 1; spin_unlock(&lock); diff --git a/trunk/drivers/i2c/busses/i2c-i801.c b/trunk/drivers/i2c/busses/i2c-i801.c index c7be2fdbd86b..bbb2fbee836f 100644 --- a/trunk/drivers/i2c/busses/i2c-i801.c +++ b/trunk/drivers/i2c/busses/i2c-i801.c @@ -33,7 +33,6 @@ ICH7 27DA ESB2 269B ICH8 283E - ICH9 2930 This driver supports several versions of Intel's I/O Controller Hubs (ICH). For SMBus support, they are similar to the PIIX4 and are part of Intel's '810' and other chipsets. @@ -458,7 +457,6 @@ static struct pci_device_id i801_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_17) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_17) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_5) }, - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_6) }, { 0, } }; diff --git a/trunk/drivers/i2c/busses/i2c-ibm_iic.c b/trunk/drivers/i2c/busses/i2c-ibm_iic.c index 781a99c1647a..80d4ba1bdfec 100644 --- a/trunk/drivers/i2c/busses/i2c-ibm_iic.c +++ b/trunk/drivers/i2c/busses/i2c-ibm_iic.c @@ -320,7 +320,7 @@ static int iic_smbus_quick(struct ibm_iic_private* dev, const struct i2c_msg* p) /* * IIC interrupt handler */ -static irqreturn_t iic_handler(int irq, void *dev_id) +static irqreturn_t iic_handler(int irq, void *dev_id, struct pt_regs *regs) { struct ibm_iic_private* dev = (struct ibm_iic_private*)dev_id; volatile struct iic_regs __iomem *iic = dev->vaddr; diff --git a/trunk/drivers/i2c/busses/i2c-iop3xx.c b/trunk/drivers/i2c/busses/i2c-iop3xx.c index d108ab4974cc..4436c89be58e 100644 --- a/trunk/drivers/i2c/busses/i2c-iop3xx.c +++ b/trunk/drivers/i2c/busses/i2c-iop3xx.c @@ -120,7 +120,7 @@ iop3xx_i2c_transaction_cleanup(struct i2c_algo_iop3xx_data *iop3xx_adap) * Then it passes the SR flags of interest to BH via adap data */ static irqreturn_t -iop3xx_i2c_irq_handler(int this_irq, void *dev_id) +iop3xx_i2c_irq_handler(int this_irq, void *dev_id, struct pt_regs *regs) { struct i2c_algo_iop3xx_data *iop3xx_adap = dev_id; u32 sr = __raw_readl(iop3xx_adap->ioaddr + SR_OFFSET); diff --git a/trunk/drivers/i2c/busses/i2c-isa.c b/trunk/drivers/i2c/busses/i2c-isa.c index 8ed59a2dff53..4380653748a4 100644 --- a/trunk/drivers/i2c/busses/i2c-isa.c +++ b/trunk/drivers/i2c/busses/i2c-isa.c @@ -91,7 +91,7 @@ int i2c_isa_add_driver(struct i2c_driver *driver) /* Now look for clients */ res = driver->attach_adapter(&isa_adapter); if (res) { - dev_dbg(&isa_adapter.dev, + dev_err(&isa_adapter.dev, "Driver %s failed to attach adapter, unregistering\n", driver->driver.name); driver_unregister(&driver->driver); diff --git a/trunk/drivers/i2c/busses/i2c-ite.c b/trunk/drivers/i2c/busses/i2c-ite.c index f7d71869b3b9..559a62b04ee9 100644 --- a/trunk/drivers/i2c/busses/i2c-ite.c +++ b/trunk/drivers/i2c/busses/i2c-ite.c @@ -140,7 +140,8 @@ static void iic_ite_waitforpin(void) { } -static irqreturn_t iic_ite_handler(int this_irq, void *dev_id) +static irqreturn_t iic_ite_handler(int this_irq, void *dev_id, + struct pt_regs *regs) { spin_lock(&lock); iic_pending = 1; diff --git a/trunk/drivers/i2c/busses/i2c-ixp4xx.c b/trunk/drivers/i2c/busses/i2c-ixp4xx.c index 68fe863f9d54..1ce01fb0ac09 100644 --- a/trunk/drivers/i2c/busses/i2c-ixp4xx.c +++ b/trunk/drivers/i2c/busses/i2c-ixp4xx.c @@ -137,8 +137,7 @@ static int ixp4xx_i2c_probe(struct platform_device *plat_dev) gpio_line_set(gpio->scl_pin, 0); gpio_line_set(gpio->sda_pin, 0); - err = i2c_bit_add_bus(&drv_data->adapter); - if (err) { + if ((err = i2c_bit_add_bus(&drv_data->adapter) != 0)) { printk(KERN_ERR "ERROR: Could not install %s\n", plat_dev->dev.bus_id); kfree(drv_data); diff --git a/trunk/drivers/i2c/busses/i2c-mpc.c b/trunk/drivers/i2c/busses/i2c-mpc.c index ee65aa1be13a..155a986de516 100644 --- a/trunk/drivers/i2c/busses/i2c-mpc.c +++ b/trunk/drivers/i2c/busses/i2c-mpc.c @@ -63,7 +63,7 @@ static __inline__ void writeccr(struct mpc_i2c *i2c, u32 x) writeb(x, i2c->base + MPC_I2C_CR); } -static irqreturn_t mpc_i2c_isr(int irq, void *dev_id) +static irqreturn_t mpc_i2c_isr(int irq, void *dev_id, struct pt_regs *regs) { struct mpc_i2c *i2c = dev_id; if (readb(i2c->base + MPC_I2C_SR) & CSR_MIF) { diff --git a/trunk/drivers/i2c/busses/i2c-mv64xxx.c b/trunk/drivers/i2c/busses/i2c-mv64xxx.c index bbc8e3a7ff55..eacbaf745b64 100644 --- a/trunk/drivers/i2c/busses/i2c-mv64xxx.c +++ b/trunk/drivers/i2c/busses/i2c-mv64xxx.c @@ -278,7 +278,7 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data) } static int -mv64xxx_i2c_intr(int irq, void *dev_id) +mv64xxx_i2c_intr(int irq, void *dev_id, struct pt_regs *regs) { struct mv64xxx_i2c_data *drv_data = dev_id; unsigned long flags; diff --git a/trunk/drivers/i2c/busses/i2c-ocores.c b/trunk/drivers/i2c/busses/i2c-ocores.c index f28a76d1c0af..3e276e958ef7 100644 --- a/trunk/drivers/i2c/busses/i2c-ocores.c +++ b/trunk/drivers/i2c/busses/i2c-ocores.c @@ -143,7 +143,7 @@ static void ocores_process(struct ocores_i2c *i2c) } } -static irqreturn_t ocores_isr(int irq, void *dev_id) +static irqreturn_t ocores_isr(int irq, void *dev_id, struct pt_regs *regs) { struct ocores_i2c *i2c = dev_id; diff --git a/trunk/drivers/i2c/busses/i2c-omap.c b/trunk/drivers/i2c/busses/i2c-omap.c index dec04da0455c..81d87d2c2a2d 100644 --- a/trunk/drivers/i2c/busses/i2c-omap.c +++ b/trunk/drivers/i2c/busses/i2c-omap.c @@ -400,7 +400,7 @@ omap_i2c_ack_stat(struct omap_i2c_dev *dev, u16 stat) } static irqreturn_t -omap_i2c_rev1_isr(int this_irq, void *dev_id) +omap_i2c_rev1_isr(int this_irq, void *dev_id, struct pt_regs *regs) { struct omap_i2c_dev *dev = dev_id; u16 iv, w; @@ -452,7 +452,7 @@ omap_i2c_rev1_isr(int this_irq, void *dev_id) } static irqreturn_t -omap_i2c_isr(int this_irq, void *dev_id) +omap_i2c_isr(int this_irq, void *dev_id, struct pt_regs *regs) { struct omap_i2c_dev *dev = dev_id; u16 bits; diff --git a/trunk/drivers/i2c/busses/i2c-pca-isa.c b/trunk/drivers/i2c/busses/i2c-pca-isa.c index 407840b6a260..d9b4ddbad7e0 100644 --- a/trunk/drivers/i2c/busses/i2c-pca-isa.c +++ b/trunk/drivers/i2c/busses/i2c-pca-isa.c @@ -99,7 +99,7 @@ static int pca_isa_waitforinterrupt(struct i2c_algo_pca_data *adap) return ret; } -static irqreturn_t pca_handler(int this_irq, void *dev_id) { +static irqreturn_t pca_handler(int this_irq, void *dev_id, struct pt_regs *regs) { wake_up_interruptible(&pca_wait); return IRQ_HANDLED; } diff --git a/trunk/drivers/i2c/busses/i2c-powermac.c b/trunk/drivers/i2c/busses/i2c-powermac.c index 648d55533d87..a508cb962d24 100644 --- a/trunk/drivers/i2c/busses/i2c-powermac.c +++ b/trunk/drivers/i2c/busses/i2c-powermac.c @@ -182,9 +182,9 @@ static const struct i2c_algorithm i2c_powermac_algorithm = { }; -static int i2c_powermac_remove(struct platform_device *dev) +static int i2c_powermac_remove(struct device *dev) { - struct i2c_adapter *adapter = platform_get_drvdata(dev); + struct i2c_adapter *adapter = dev_get_drvdata(dev); struct pmac_i2c_bus *bus = i2c_get_adapdata(adapter); int rc; @@ -195,16 +195,16 @@ static int i2c_powermac_remove(struct platform_device *dev) if (rc) printk("i2c-powermac.c: Failed to remove bus %s !\n", adapter->name); - platform_set_drvdata(dev, NULL); + dev_set_drvdata(dev, NULL); kfree(adapter); return 0; } -static int __devexit i2c_powermac_probe(struct platform_device *dev) +static int i2c_powermac_probe(struct device *dev) { - struct pmac_i2c_bus *bus = dev->dev.platform_data; + struct pmac_i2c_bus *bus = dev->platform_data; struct device_node *parent = NULL; struct i2c_adapter *adapter; char name[32]; @@ -246,11 +246,11 @@ static int __devexit i2c_powermac_probe(struct platform_device *dev) printk(KERN_ERR "i2c-powermac: can't allocate inteface !\n"); return -ENOMEM; } - platform_set_drvdata(dev, adapter); + dev_set_drvdata(dev, adapter); strcpy(adapter->name, name); adapter->algo = &i2c_powermac_algorithm; i2c_set_adapdata(adapter, bus); - adapter->dev.parent = &dev->dev; + adapter->dev.parent = dev; pmac_i2c_attach_adapter(bus, adapter); rc = i2c_add_adapter(adapter); if (rc) { @@ -265,25 +265,23 @@ static int __devexit i2c_powermac_probe(struct platform_device *dev) } -static struct platform_driver i2c_powermac_driver = { +static struct device_driver i2c_powermac_driver = { + .name = "i2c-powermac", + .bus = &platform_bus_type, .probe = i2c_powermac_probe, - .remove = __devexit_p(i2c_powermac_remove), - .driver = { - .name = "i2c-powermac", - .bus = &platform_bus_type, - }, + .remove = i2c_powermac_remove, }; static int __init i2c_powermac_init(void) { - platform_driver_register(&i2c_powermac_driver); + driver_register(&i2c_powermac_driver); return 0; } static void __exit i2c_powermac_cleanup(void) { - platform_driver_unregister(&i2c_powermac_driver); + driver_unregister(&i2c_powermac_driver); } module_init(i2c_powermac_init); diff --git a/trunk/drivers/i2c/busses/i2c-pxa.c b/trunk/drivers/i2c/busses/i2c-pxa.c index c95a6c154165..cd4ad98ad517 100644 --- a/trunk/drivers/i2c/busses/i2c-pxa.c +++ b/trunk/drivers/i2c/busses/i2c-pxa.c @@ -272,8 +272,7 @@ static int i2c_pxa_wait_slave(struct pxa_i2c *i2c) dev_dbg(&i2c->adap.dev, "%s: %ld: ISR=%08x, ICR=%08x, IBMR=%02x\n", __func__, (long)jiffies, ISR, ICR, IBMR); - if ((ISR & (ISR_UB|ISR_IBB)) == 0 || - (ISR & ISR_SAD) != 0 || + if ((ISR & (ISR_UB|ISR_IBB|ISR_SAD)) == ISR_SAD || (ICR & ICR_SCLE) == 0) { if (i2c_debug > 1) dev_dbg(&i2c->adap.dev, "%s: done\n", __func__); @@ -493,10 +492,7 @@ static void i2c_pxa_slave_txempty(struct pxa_i2c *i2c, u32 isr) if (isr & ISR_BED) { /* what should we do here? */ } else { - int ret = 0; - - if (i2c->slave != NULL) - ret = i2c->slave->read(i2c->slave->data); + int ret = i2c->slave->read(i2c->slave->data); IDBR = ret; ICR |= ICR_TB; /* allow next byte */ @@ -854,7 +850,7 @@ static void i2c_pxa_irq_rxfull(struct pxa_i2c *i2c, u32 isr) ICR = icr; } -static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id) +static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id, struct pt_regs *regs) { struct pxa_i2c *i2c = dev_id; u32 isr = ISR; diff --git a/trunk/drivers/i2c/busses/i2c-rpx.c b/trunk/drivers/i2c/busses/i2c-rpx.c index 8764df06f51d..0ebec3c1a54e 100644 --- a/trunk/drivers/i2c/busses/i2c-rpx.c +++ b/trunk/drivers/i2c/busses/i2c-rpx.c @@ -55,10 +55,10 @@ rpx_iic_init(struct i2c_algo_8xx_data *data) data->i2c = (i2c8xx_t *)&(((immap_t *)IMAP_ADDR)->im_i2c); } -static int rpx_install_isr(int irq, void (*func)(void *), void *data) +static int rpx_install_isr(int irq, void (*func)(void *, void *), void *data) { /* install interrupt handler */ - cpm_install_handler(irq, func, data); + cpm_install_handler(irq, (void (*)(void *, struct pt_regs *)) func, data); return 0; } diff --git a/trunk/drivers/i2c/busses/i2c-s3c2410.c b/trunk/drivers/i2c/busses/i2c-s3c2410.c index 4ca6de209b8b..9ebe429a0a0f 100644 --- a/trunk/drivers/i2c/busses/i2c-s3c2410.c +++ b/trunk/drivers/i2c/busses/i2c-s3c2410.c @@ -423,7 +423,8 @@ static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat) * top level IRQ servicing routine */ -static irqreturn_t s3c24xx_i2c_irq(int irqno, void *dev_id) +static irqreturn_t s3c24xx_i2c_irq(int irqno, void *dev_id, + struct pt_regs *regs) { struct s3c24xx_i2c *i2c = dev_id; unsigned long status; diff --git a/trunk/drivers/i2c/busses/scx200_acb.c b/trunk/drivers/i2c/busses/scx200_acb.c index 714bae780953..32aab0d34ee9 100644 --- a/trunk/drivers/i2c/busses/scx200_acb.c +++ b/trunk/drivers/i2c/busses/scx200_acb.c @@ -494,12 +494,11 @@ static __init int scx200_create_pci(const char *text, struct pci_dev *pdev, iface->pdev = pdev; iface->bar = bar; - rc = pci_enable_device_bars(iface->pdev, 1 << iface->bar); - if (rc) - goto errout_free; + pci_enable_device_bars(iface->pdev, 1 << iface->bar); rc = pci_request_region(iface->pdev, iface->bar, iface->adapter.name); - if (rc) { + + if (rc != 0) { printk(KERN_ERR NAME ": can't allocate PCI BAR %d\n", iface->bar); goto errout_free; diff --git a/trunk/drivers/i2c/chips/isp1301_omap.c b/trunk/drivers/i2c/chips/isp1301_omap.c index ccdf3e90862b..182f04953466 100644 --- a/trunk/drivers/i2c/chips/isp1301_omap.c +++ b/trunk/drivers/i2c/chips/isp1301_omap.c @@ -669,7 +669,7 @@ static void otg_update_isp(struct isp1301 *isp) dump_regs(isp, "otg->isp1301"); } -static irqreturn_t omap_otg_irq(int irq, void *_isp) +static irqreturn_t omap_otg_irq(int irq, void *_isp, struct pt_regs *regs) { u16 otg_irq = OTG_IRQ_SRC_REG; u32 otg_ctrl; @@ -1181,7 +1181,7 @@ isp1301_work(void *data) isp->working = 0; } -static irqreturn_t isp1301_irq(int irq, void *isp) +static irqreturn_t isp1301_irq(int irq, void *isp, struct pt_regs *regs) { isp1301_defer_work(isp, WORK_UPDATE_OTG); return IRQ_HANDLED; diff --git a/trunk/drivers/i2c/chips/tps65010.c b/trunk/drivers/i2c/chips/tps65010.c index 60bef94cd25f..6a7578217177 100644 --- a/trunk/drivers/i2c/chips/tps65010.c +++ b/trunk/drivers/i2c/chips/tps65010.c @@ -446,7 +446,7 @@ static void tps65010_work(void *_tps) mutex_unlock(&tps->lock); } -static irqreturn_t tps65010_irq(int irq, void *_tps) +static irqreturn_t tps65010_irq(int irq, void *_tps, struct pt_regs *regs) { struct tps65010 *tps = _tps; diff --git a/trunk/drivers/i2c/i2c-dev.c b/trunk/drivers/i2c/i2c-dev.c index 94a4e9a3013c..3f869033ed70 100644 --- a/trunk/drivers/i2c/i2c-dev.c +++ b/trunk/drivers/i2c/i2c-dev.c @@ -42,7 +42,7 @@ static struct i2c_driver i2cdev_driver; struct i2c_dev { struct list_head list; struct i2c_adapter *adap; - struct device *dev; + struct class_device *class_dev; }; #define I2C_MINORS 256 @@ -92,16 +92,15 @@ static void return_i2c_dev(struct i2c_dev *i2c_dev) spin_unlock(&i2c_dev_list_lock); } -static ssize_t show_adapter_name(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t show_adapter_name(struct class_device *class_dev, char *buf) { - struct i2c_dev *i2c_dev = i2c_dev_get_by_minor(MINOR(dev->devt)); + struct i2c_dev *i2c_dev = i2c_dev_get_by_minor(MINOR(class_dev->devt)); if (!i2c_dev) return -ENODEV; return sprintf(buf, "%s\n", i2c_dev->adap->name); } -static DEVICE_ATTR(name, S_IRUGO, show_adapter_name, NULL); +static CLASS_DEVICE_ATTR(name, S_IRUGO, show_adapter_name, NULL); static ssize_t i2cdev_read (struct file *file, char __user *buf, size_t count, loff_t *offset) @@ -414,14 +413,15 @@ static int i2cdev_attach_adapter(struct i2c_adapter *adap) return PTR_ERR(i2c_dev); /* register this i2c device with the driver core */ - i2c_dev->dev = device_create(i2c_dev_class, &adap->dev, - MKDEV(I2C_MAJOR, adap->nr), - "i2c-%d", adap->nr); - if (!i2c_dev->dev) { + i2c_dev->class_dev = class_device_create(i2c_dev_class, NULL, + MKDEV(I2C_MAJOR, adap->nr), + &adap->dev, "i2c-%d", + adap->nr); + if (!i2c_dev->class_dev) { res = -ENODEV; goto error; } - res = device_create_file(i2c_dev->dev, &dev_attr_name); + res = class_device_create_file(i2c_dev->class_dev, &class_device_attr_name); if (res) goto error_destroy; @@ -429,7 +429,7 @@ static int i2cdev_attach_adapter(struct i2c_adapter *adap) adap->name, adap->nr); return 0; error_destroy: - device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, adap->nr)); + class_device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, adap->nr)); error: return_i2c_dev(i2c_dev); kfree(i2c_dev); @@ -444,9 +444,9 @@ static int i2cdev_detach_adapter(struct i2c_adapter *adap) if (!i2c_dev) /* attach_adapter must have failed */ return 0; - device_remove_file(i2c_dev->dev, &dev_attr_name); + class_device_remove_file(i2c_dev->class_dev, &class_device_attr_name); return_i2c_dev(i2c_dev); - device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, adap->nr)); + class_device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, adap->nr)); kfree(i2c_dev); pr_debug("i2c-dev: adapter [%s] unregistered\n", adap->name); diff --git a/trunk/drivers/ide/ide-cd.c b/trunk/drivers/ide/ide-cd.c index 88214943d00a..69bbb6206a00 100644 --- a/trunk/drivers/ide/ide-cd.c +++ b/trunk/drivers/ide/ide-cd.c @@ -597,7 +597,7 @@ static void cdrom_prepare_request(ide_drive_t *drive, struct request *rq) struct cdrom_info *cd = drive->driver_data; ide_init_drive_cmd(rq); - rq->cmd_type = REQ_TYPE_ATA_PC; + rq->cmd_type = REQ_TYPE_BLOCK_PC; rq->rq_disk = cd->disk; } @@ -716,7 +716,7 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) ide_error(drive, "request sense failure", stat); return 1; - } else if (blk_pc_request(rq) || rq->cmd_type == REQ_TYPE_ATA_PC) { + } else if (blk_pc_request(rq)) { /* All other functions, except for READ. */ unsigned long flags; @@ -724,7 +724,7 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) * if we have an error, pass back CHECK_CONDITION as the * scsi status byte */ - if (blk_pc_request(rq) && !rq->errors) + if (!rq->errors) rq->errors = SAM_STAT_CHECK_CONDITION; /* Check for tray open. */ @@ -2023,8 +2023,7 @@ ide_do_rw_cdrom (ide_drive_t *drive, struct request *rq, sector_t block) } info->last_block = block; return action; - } else if (rq->cmd_type == REQ_TYPE_SENSE || - rq->cmd_type == REQ_TYPE_ATA_PC) { + } else if (rq->cmd_type == REQ_TYPE_SENSE) { return cdrom_do_packet_command(drive); } else if (blk_pc_request(rq)) { return cdrom_do_block_pc(drive, rq); diff --git a/trunk/drivers/ide/ide-floppy.c b/trunk/drivers/ide/ide-floppy.c index e3a267622bb6..8ccee9c769f8 100644 --- a/trunk/drivers/ide/ide-floppy.c +++ b/trunk/drivers/ide/ide-floppy.c @@ -1635,7 +1635,7 @@ static int idefloppy_begin_format(ide_drive_t *drive, int __user *arg) /* ** Get ATAPI_FORMAT_UNIT progress indication. ** -** Userland gives a pointer to an int. The int is set to a progress +** Userland gives a pointer to an int. The int is set to a progresss ** indicator 0-65536, with 65536=100%. ** ** If the drive does not support format progress indication, we just check diff --git a/trunk/drivers/ide/ide-io.c b/trunk/drivers/ide/ide-io.c index 2614f41b5074..ba6039b55b41 100644 --- a/trunk/drivers/ide/ide-io.c +++ b/trunk/drivers/ide/ide-io.c @@ -1562,7 +1562,7 @@ static void unexpected_intr (int irq, ide_hwgroup_t *hwgroup) * on the hwgroup and the process begins again. */ -irqreturn_t ide_intr (int irq, void *dev_id) +irqreturn_t ide_intr (int irq, void *dev_id, struct pt_regs *regs) { unsigned long flags; ide_hwgroup_t *hwgroup = (ide_hwgroup_t *)dev_id; diff --git a/trunk/drivers/ide/ide-taskfile.c b/trunk/drivers/ide/ide-taskfile.c index 30175c7688e8..1d0470c1f957 100644 --- a/trunk/drivers/ide/ide-taskfile.c +++ b/trunk/drivers/ide/ide-taskfile.c @@ -524,8 +524,8 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) task_ioreg_t *hobsptr = args.hobRegister; int err = 0; int tasksize = sizeof(struct ide_task_request_s); - unsigned int taskin = 0; - unsigned int taskout = 0; + int taskin = 0; + int taskout = 0; u8 io_32bit = drive->io_32bit; char __user *buf = (char __user *)arg; @@ -538,13 +538,8 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) return -EFAULT; } - taskout = req_task->out_size; - taskin = req_task->in_size; - - if (taskin > 65536 || taskout > 65536) { - err = -EINVAL; - goto abort; - } + taskout = (int) req_task->out_size; + taskin = (int) req_task->in_size; if (taskout) { int outtotal = tasksize; diff --git a/trunk/drivers/ide/legacy/hd.c b/trunk/drivers/ide/legacy/hd.c index 45ed03591cd8..4ab931145673 100644 --- a/trunk/drivers/ide/legacy/hd.c +++ b/trunk/drivers/ide/legacy/hd.c @@ -459,7 +459,7 @@ static void read_intr(void) #ifdef DEBUG printk("%s: read: sector %ld, remaining = %ld, buffer=%p\n", req->rq_disk->disk_name, req->sector, req->nr_sectors, - req->buffer+512); + req->buffer+512)); #endif if (req->current_nr_sectors <= 0) end_request(req, 1); @@ -673,7 +673,7 @@ static int hd_getgeo(struct block_device *bdev, struct hd_geometry *geo) * be forgotten about... */ -static irqreturn_t hd_interrupt(int irq, void *dev_id) +static irqreturn_t hd_interrupt(int irq, void *dev_id, struct pt_regs *regs) { void (*handler)(void) = do_hd; diff --git a/trunk/drivers/ide/legacy/macide.c b/trunk/drivers/ide/legacy/macide.c index b1730d7e414c..d655da749144 100644 --- a/trunk/drivers/ide/legacy/macide.c +++ b/trunk/drivers/ide/legacy/macide.c @@ -78,7 +78,7 @@ int macide_ack_intr(ide_hwif_t* hwif) } #ifdef CONFIG_BLK_DEV_MAC_MEDIABAY -static void macide_mediabay_interrupt(int irq, void *dev_id) +static void macide_mediabay_interrupt(int irq, void *dev_id, struct pt_regs *regs) { int state = baboon->mb_status & 0x04; diff --git a/trunk/drivers/ide/mips/swarm.c b/trunk/drivers/ide/mips/swarm.c index 09c9e7936b0d..66f6064f4640 100644 --- a/trunk/drivers/ide/mips/swarm.c +++ b/trunk/drivers/ide/mips/swarm.c @@ -4,7 +4,6 @@ * Author: Manish Lachwani, mlachwani@mvista.com * Copyright (C) 2004 MIPS Technologies, Inc. All rights reserved. * Author: Maciej W. Rozycki - * Copyright (c) 2006 Maciej W. Rozycki * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -128,7 +127,6 @@ static int __devinit swarm_ide_probe(struct device *dev) memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports)); hwif->irq = hwif->hw.irq; - probe_hwif_init(hwif); dev_set_drvdata(dev, hwif); return 0; diff --git a/trunk/drivers/ide/pci/amd74xx.c b/trunk/drivers/ide/pci/amd74xx.c index 753fe0e21456..2b0ea8b6608d 100644 --- a/trunk/drivers/ide/pci/amd74xx.c +++ b/trunk/drivers/ide/pci/amd74xx.c @@ -75,7 +75,6 @@ static struct amd_ide_chip { { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, 0x50, AMD_UDMA_133 }, { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE, 0x50, AMD_UDMA_133 }, { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE, 0x50, AMD_UDMA_133 }, - { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE, 0x50, AMD_UDMA_133 }, { PCI_DEVICE_ID_AMD_CS5536_IDE, 0x40, AMD_UDMA_100 }, { 0 } }; @@ -492,8 +491,7 @@ static ide_pci_device_t amd74xx_chipsets[] __devinitdata = { /* 16 */ DECLARE_NV_DEV("NFORCE-MCP55"), /* 17 */ DECLARE_NV_DEV("NFORCE-MCP61"), /* 18 */ DECLARE_NV_DEV("NFORCE-MCP65"), - /* 19 */ DECLARE_NV_DEV("NFORCE-MCP67"), - /* 20 */ DECLARE_AMD_DEV("AMD5536"), + /* 19 */ DECLARE_AMD_DEV("AMD5536"), }; static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id) @@ -532,8 +530,7 @@ static struct pci_device_id amd74xx_pci_tbl[] = { { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 16 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 17 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 18 }, - { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 19 }, - { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 20 }, + { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 19 }, { 0, }, }; MODULE_DEVICE_TABLE(pci, amd74xx_pci_tbl); diff --git a/trunk/drivers/ide/pci/generic.c b/trunk/drivers/ide/pci/generic.c index 9f306880491a..965c43659e35 100644 --- a/trunk/drivers/ide/pci/generic.c +++ b/trunk/drivers/ide/pci/generic.c @@ -40,19 +40,6 @@ static int ide_generic_all; /* Set to claim all devices */ -/* - * the module_param_named() was added for the modular case - * the __setup() is left as compatibility for existing setups - */ -#ifndef MODULE -static int __init ide_generic_all_on(char *unused) -{ - ide_generic_all = 1; - printk(KERN_INFO "IDE generic will claim all unknown PCI IDE storage controllers.\n"); - return 1; -} -__setup("all-generic-ide", ide_generic_all_on); -#endif module_param_named(all_generic_ide, ide_generic_all, bool, 0444); MODULE_PARM_DESC(all_generic_ide, "IDE generic will claim all unknown PCI IDE storage controllers."); @@ -247,17 +234,13 @@ static int __devinit generic_init_one(struct pci_dev *dev, const struct pci_devi (!(PCI_FUNC(dev->devfn) & 1))) goto out; - if (dev->vendor == PCI_VENDOR_ID_JMICRON) { - if (dev->device != PCI_DEVICE_ID_JMICRON_JMB368 && PCI_FUNC(dev->devfn) != 1) - goto out; - } + if (dev->vendor == PCI_VENDOR_ID_JMICRON && PCI_FUNC(dev->devfn) != 1) + goto out; - if (dev->vendor != PCI_VENDOR_ID_JMICRON) { - pci_read_config_word(dev, PCI_COMMAND, &command); - if (!(command & PCI_COMMAND_IO)) { - printk(KERN_INFO "Skipping disabled %s IDE controller.\n", d->name); - goto out; - } + pci_read_config_word(dev, PCI_COMMAND, &command); + if (!(command & PCI_COMMAND_IO)) { + printk(KERN_INFO "Skipping disabled %s IDE controller.\n", d->name); + goto out; } ret = ide_setup_pci_device(dev, d); out: diff --git a/trunk/drivers/ide/pci/sgiioc4.c b/trunk/drivers/ide/pci/sgiioc4.c index cfad09accf52..f3fe287fbd89 100644 --- a/trunk/drivers/ide/pci/sgiioc4.c +++ b/trunk/drivers/ide/pci/sgiioc4.c @@ -768,7 +768,14 @@ ioc4_ide_init(void) return ioc4_register_submodule(&ioc4_ide_submodule); } -late_initcall(ioc4_ide_init); /* Call only after IDE init is done */ +static void __devexit +ioc4_ide_exit(void) +{ + ioc4_unregister_submodule(&ioc4_ide_submodule); +} + +module_init(ioc4_ide_init); +module_exit(ioc4_ide_exit); MODULE_AUTHOR("Aniket Malatpure/Jeremy Higdon"); MODULE_DESCRIPTION("IDE PCI driver module for SGI IOC4 Base-IO Card"); diff --git a/trunk/drivers/ieee1394/eth1394.c b/trunk/drivers/ieee1394/eth1394.c index 31e5cc49d61a..8a7b8fab6238 100644 --- a/trunk/drivers/ieee1394/eth1394.c +++ b/trunk/drivers/ieee1394/eth1394.c @@ -64,7 +64,6 @@ #include #include #include -#include #include #include "config_roms.h" @@ -492,7 +491,7 @@ static void ether1394_reset_priv (struct net_device *dev, int set_mtu) int i; struct eth1394_priv *priv = netdev_priv(dev); struct hpsb_host *host = priv->host; - u64 guid = get_unaligned((u64*)&(host->csr.rom->bus_info_data[3])); + u64 guid = *((u64*)&(host->csr.rom->bus_info_data[3])); u16 maxpayload = 1 << (host->csr.max_rec + 1); int max_speed = IEEE1394_SPEED_MAX; @@ -515,8 +514,8 @@ static void ether1394_reset_priv (struct net_device *dev, int set_mtu) ETHER1394_GASP_OVERHEAD))); /* Set our hardware address while we're at it */ - memcpy(dev->dev_addr, &guid, sizeof(u64)); - memset(dev->broadcast, 0xff, sizeof(u64)); + *(u64*)dev->dev_addr = guid; + *(u64*)dev->broadcast = ~0x0ULL; } spin_unlock_irqrestore (&priv->lock, flags); @@ -895,7 +894,6 @@ static inline u16 ether1394_parse_encap(struct sk_buff *skb, u16 maxpayload; struct eth1394_node_ref *node; struct eth1394_node_info *node_info; - __be64 guid; /* Sanity check. MacOSX seems to be sending us 131 in this * field (atleast on my Panther G5). Not sure why. */ @@ -904,9 +902,8 @@ static inline u16 ether1394_parse_encap(struct sk_buff *skb, maxpayload = min(eth1394_speedto_maxpayload[sspd], (u16)(1 << (max_rec + 1))); - guid = get_unaligned(&arp1394->s_uniq_id); node = eth1394_find_node_guid(&priv->ip_node_list, - be64_to_cpu(guid)); + be64_to_cpu(arp1394->s_uniq_id)); if (!node) { return 0; } @@ -934,9 +931,10 @@ static inline u16 ether1394_parse_encap(struct sk_buff *skb, arp_ptr += arp->ar_pln; /* skip over sender IP addr */ if (arp->ar_op == htons(ARPOP_REQUEST)) - memset(arp_ptr, 0, sizeof(u64)); + /* just set ARP req target unique ID to 0 */ + *((u64*)arp_ptr) = 0; else - memcpy(arp_ptr, dev->dev_addr, sizeof(u64)); + *((u64*)arp_ptr) = *((u64*)dev->dev_addr); } /* Now add the ethernet header. */ @@ -1677,10 +1675,8 @@ static int ether1394_tx (struct sk_buff *skb, struct net_device *dev) if (max_payload < dg_size + hdr_type_len[ETH1394_HDR_LF_UF]) priv->bc_dgl++; } else { - __be64 guid = get_unaligned((u64 *)eth->h_dest); - node = eth1394_find_node_guid(&priv->ip_node_list, - be64_to_cpu(guid)); + be64_to_cpu(*(u64*)eth->h_dest)); if (!node) { ret = -EAGAIN; goto fail; diff --git a/trunk/drivers/ieee1394/nodemgr.c b/trunk/drivers/ieee1394/nodemgr.c index 8e7b83f84485..3e7974c57443 100644 --- a/trunk/drivers/ieee1394/nodemgr.c +++ b/trunk/drivers/ieee1394/nodemgr.c @@ -1614,7 +1614,7 @@ static int nodemgr_host_thread(void *__hi) { struct host_info *hi = (struct host_info *)__hi; struct hpsb_host *host = hi->host; - unsigned int g, generation = 0; + unsigned int g, generation = get_hpsb_generation(host) - 1; int i, reset_cycles = 0; /* Setup our device-model entries */ diff --git a/trunk/drivers/ieee1394/ohci1394.c b/trunk/drivers/ieee1394/ohci1394.c index 6e8ea9110c46..8fd0030475ba 100644 --- a/trunk/drivers/ieee1394/ohci1394.c +++ b/trunk/drivers/ieee1394/ohci1394.c @@ -2301,7 +2301,8 @@ static void ohci_schedule_iso_tasklets(struct ti_ohci *ohci, spin_unlock_irqrestore(&ohci->iso_tasklet_list_lock, flags); } -static irqreturn_t ohci_irq_handler(int irq, void *dev_id) +static irqreturn_t ohci_irq_handler(int irq, void *dev_id, + struct pt_regs *regs_are_unused) { quadlet_t event, node_id; struct ti_ohci *ohci = (struct ti_ohci *)dev_id; @@ -3552,21 +3553,12 @@ static int ohci1394_pci_suspend (struct pci_dev *pdev, pm_message_t state) { int err; - printk(KERN_INFO "%s does not fully support suspend and resume yet\n", - OHCI1394_DRIVER_NAME); - err = pci_save_state(pdev); - if (err) { - printk(KERN_ERR "%s: pci_save_state failed with %d\n", - OHCI1394_DRIVER_NAME, err); - return err; - } + if (err) + goto out; err = pci_set_power_state(pdev, pci_choose_state(pdev, state)); -#ifdef OHCI1394_DEBUG if (err) - printk(KERN_DEBUG "%s: pci_set_power_state failed with %d\n", - OHCI1394_DRIVER_NAME, err); -#endif /* OHCI1394_DEBUG */ + goto out; /* PowerMac suspend code comes last */ #ifdef CONFIG_PPC_PMAC @@ -3579,8 +3571,8 @@ static int ohci1394_pci_suspend (struct pci_dev *pdev, pm_message_t state) pmac_call_feature(PMAC_FTR_1394_ENABLE, of_node, 0, 0); } #endif /* CONFIG_PPC_PMAC */ - - return 0; +out: + return err; } #endif /* CONFIG_PM */ diff --git a/trunk/drivers/ieee1394/pcilynx.c b/trunk/drivers/ieee1394/pcilynx.c index 0a7412e27eb4..b4f146f2c951 100644 --- a/trunk/drivers/ieee1394/pcilynx.c +++ b/trunk/drivers/ieee1394/pcilynx.c @@ -839,7 +839,8 @@ static int lynx_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg) ********************************************************/ -static irqreturn_t lynx_irq_handler(int irq, void *dev_id) +static irqreturn_t lynx_irq_handler(int irq, void *dev_id, + struct pt_regs *regs_are_unused) { struct ti_lynx *lynx = (struct ti_lynx *)dev_id; struct hpsb_host *host = lynx->host; diff --git a/trunk/drivers/infiniband/core/addr.c b/trunk/drivers/infiniband/core/addr.c index 7767a11b6890..60d3fbdd216c 100644 --- a/trunk/drivers/infiniband/core/addr.c +++ b/trunk/drivers/infiniband/core/addr.c @@ -47,7 +47,6 @@ struct addr_req { struct sockaddr src_addr; struct sockaddr dst_addr; struct rdma_dev_addr *addr; - struct rdma_addr_client *client; void *context; void (*callback)(int status, struct sockaddr *src_addr, struct rdma_dev_addr *addr, void *context); @@ -62,26 +61,6 @@ static LIST_HEAD(req_list); static DECLARE_WORK(work, process_req, NULL); static struct workqueue_struct *addr_wq; -void rdma_addr_register_client(struct rdma_addr_client *client) -{ - atomic_set(&client->refcount, 1); - init_completion(&client->comp); -} -EXPORT_SYMBOL(rdma_addr_register_client); - -static inline void put_client(struct rdma_addr_client *client) -{ - if (atomic_dec_and_test(&client->refcount)) - complete(&client->comp); -} - -void rdma_addr_unregister_client(struct rdma_addr_client *client) -{ - put_client(client); - wait_for_completion(&client->comp); -} -EXPORT_SYMBOL(rdma_addr_unregister_client); - int rdma_copy_addr(struct rdma_dev_addr *dev_addr, struct net_device *dev, const unsigned char *dst_dev_addr) { @@ -139,7 +118,7 @@ static void queue_req(struct addr_req *req) mutex_lock(&lock); list_for_each_entry_reverse(temp_req, &req_list, list) { - if (time_after_eq(req->timeout, temp_req->timeout)) + if (time_after(req->timeout, temp_req->timeout)) break; } @@ -225,17 +204,19 @@ static void process_req(void *data) mutex_lock(&lock); list_for_each_entry_safe(req, temp_req, &req_list, list) { - if (req->status == -ENODATA) { + if (req->status) { src_in = (struct sockaddr_in *) &req->src_addr; dst_in = (struct sockaddr_in *) &req->dst_addr; req->status = addr_resolve_remote(src_in, dst_in, req->addr); - if (req->status && time_after_eq(jiffies, req->timeout)) - req->status = -ETIMEDOUT; - else if (req->status == -ENODATA) - continue; } - list_move_tail(&req->list, &done_list); + if (req->status && time_after(jiffies, req->timeout)) + req->status = -ETIMEDOUT; + else if (req->status == -ENODATA) + continue; + + list_del(&req->list); + list_add_tail(&req->list, &done_list); } if (!list_empty(&req_list)) { @@ -248,7 +229,6 @@ static void process_req(void *data) list_del(&req->list); req->callback(req->status, &req->src_addr, req->addr, req->context); - put_client(req->client); kfree(req); } } @@ -284,8 +264,7 @@ static int addr_resolve_local(struct sockaddr_in *src_in, return ret; } -int rdma_resolve_ip(struct rdma_addr_client *client, - struct sockaddr *src_addr, struct sockaddr *dst_addr, +int rdma_resolve_ip(struct sockaddr *src_addr, struct sockaddr *dst_addr, struct rdma_dev_addr *addr, int timeout_ms, void (*callback)(int status, struct sockaddr *src_addr, struct rdma_dev_addr *addr, void *context), @@ -306,8 +285,6 @@ int rdma_resolve_ip(struct rdma_addr_client *client, req->addr = addr; req->callback = callback; req->context = context; - req->client = client; - atomic_inc(&client->refcount); src_in = (struct sockaddr_in *) &req->src_addr; dst_in = (struct sockaddr_in *) &req->dst_addr; @@ -328,7 +305,6 @@ int rdma_resolve_ip(struct rdma_addr_client *client, break; default: ret = req->status; - atomic_dec(&client->refcount); kfree(req); break; } @@ -345,7 +321,8 @@ void rdma_addr_cancel(struct rdma_dev_addr *addr) if (req->addr == addr) { req->status = -ECANCELED; req->timeout = jiffies; - list_move(&req->list, &req_list); + list_del(&req->list); + list_add(&req->list, &req_list); set_timeout(req->timeout); break; } diff --git a/trunk/drivers/infiniband/core/cm.c b/trunk/drivers/infiniband/core/cm.c index e5dc4530808a..f35fcc4c0638 100644 --- a/trunk/drivers/infiniband/core/cm.c +++ b/trunk/drivers/infiniband/core/cm.c @@ -75,7 +75,6 @@ static struct ib_cm { struct rb_root remote_sidr_table; struct idr local_id_table; __be32 random_id_operand; - struct list_head timewait_list; struct workqueue_struct *wq; } cm; @@ -113,7 +112,6 @@ struct cm_work { struct cm_timewait_info { struct cm_work work; /* Must be first. */ - struct list_head list; struct rb_node remote_qp_node; struct rb_node remote_id_node; __be64 remote_ca_guid; @@ -147,12 +145,12 @@ struct cm_id_private { __be32 rq_psn; int timeout_ms; enum ib_mtu path_mtu; - __be16 pkey; u8 private_data_len; u8 max_cm_retries; u8 peer_to_peer; u8 responder_resources; u8 initiator_depth; + u8 local_ack_timeout; u8 retry_count; u8 rnr_retry_count; u8 service_timeout; @@ -240,10 +238,11 @@ static void * cm_copy_private_data(const void *private_data, if (!private_data || !private_data_len) return NULL; - data = kmemdup(private_data, private_data_len, GFP_KERNEL); + data = kmalloc(private_data_len, GFP_KERNEL); if (!data) return ERR_PTR(-ENOMEM); + memcpy(data, private_data, private_data_len); return data; } @@ -648,6 +647,13 @@ static inline int cm_convert_to_ms(int iba_time) static void cm_cleanup_timewait(struct cm_timewait_info *timewait_info) { + unsigned long flags; + + if (!timewait_info->inserted_remote_id && + !timewait_info->inserted_remote_qp) + return; + + spin_lock_irqsave(&cm.lock, flags); if (timewait_info->inserted_remote_id) { rb_erase(&timewait_info->remote_id_node, &cm.remote_id_table); timewait_info->inserted_remote_id = 0; @@ -657,6 +663,7 @@ static void cm_cleanup_timewait(struct cm_timewait_info *timewait_info) rb_erase(&timewait_info->remote_qp_node, &cm.remote_qp_table); timewait_info->inserted_remote_qp = 0; } + spin_unlock_irqrestore(&cm.lock, flags); } static struct cm_timewait_info * cm_create_timewait_info(__be32 local_id) @@ -677,12 +684,8 @@ static struct cm_timewait_info * cm_create_timewait_info(__be32 local_id) static void cm_enter_timewait(struct cm_id_private *cm_id_priv) { int wait_time; - unsigned long flags; - spin_lock_irqsave(&cm.lock, flags); cm_cleanup_timewait(cm_id_priv->timewait_info); - list_add_tail(&cm_id_priv->timewait_info->list, &cm.timewait_list); - spin_unlock_irqrestore(&cm.lock, flags); /* * The cm_id could be destroyed by the user before we exit timewait. @@ -690,7 +693,7 @@ static void cm_enter_timewait(struct cm_id_private *cm_id_priv) * timewait before notifying the user that we've exited timewait. */ cm_id_priv->id.state = IB_CM_TIMEWAIT; - wait_time = cm_convert_to_ms(cm_id_priv->av.packet_life_time + 1); + wait_time = cm_convert_to_ms(cm_id_priv->local_ack_timeout); queue_delayed_work(cm.wq, &cm_id_priv->timewait_info->work.work, msecs_to_jiffies(wait_time)); cm_id_priv->timewait_info = NULL; @@ -698,13 +701,9 @@ static void cm_enter_timewait(struct cm_id_private *cm_id_priv) static void cm_reset_to_idle(struct cm_id_private *cm_id_priv) { - unsigned long flags; - cm_id_priv->id.state = IB_CM_IDLE; if (cm_id_priv->timewait_info) { - spin_lock_irqsave(&cm.lock, flags); cm_cleanup_timewait(cm_id_priv->timewait_info); - spin_unlock_irqrestore(&cm.lock, flags); kfree(cm_id_priv->timewait_info); cm_id_priv->timewait_info = NULL; } @@ -1009,7 +1008,6 @@ int ib_send_cm_req(struct ib_cm_id *cm_id, cm_id_priv->responder_resources = param->responder_resources; cm_id_priv->retry_count = param->retry_count; cm_id_priv->path_mtu = param->primary_path->mtu; - cm_id_priv->pkey = param->primary_path->pkey; cm_id_priv->qp_type = param->qp_type; ret = cm_alloc_msg(cm_id_priv, &cm_id_priv->msg); @@ -1024,6 +1022,8 @@ int ib_send_cm_req(struct ib_cm_id *cm_id, cm_id_priv->local_qpn = cm_req_get_local_qpn(req_msg); cm_id_priv->rq_psn = cm_req_get_starting_psn(req_msg); + cm_id_priv->local_ack_timeout = + cm_req_get_primary_local_ack_timeout(req_msg); spin_lock_irqsave(&cm_id_priv->lock, flags); ret = ib_post_send_mad(cm_id_priv->msg, NULL); @@ -1307,7 +1307,6 @@ static struct cm_id_private * cm_match_req(struct cm_work *work, if (timewait_info) { cur_cm_id_priv = cm_get_id(timewait_info->work.local_id, timewait_info->work.remote_id); - cm_cleanup_timewait(cm_id_priv->timewait_info); spin_unlock_irqrestore(&cm.lock, flags); if (cur_cm_id_priv) { cm_dup_req_handler(work, cur_cm_id_priv); @@ -1316,8 +1315,7 @@ static struct cm_id_private * cm_match_req(struct cm_work *work, cm_issue_rej(work->port, work->mad_recv_wc, IB_CM_REJ_STALE_CONN, CM_MSG_RESPONSE_REQ, NULL, 0); - listen_cm_id_priv = NULL; - goto out; + goto error; } /* Find matching listen request. */ @@ -1325,20 +1323,21 @@ static struct cm_id_private * cm_match_req(struct cm_work *work, req_msg->service_id, req_msg->private_data); if (!listen_cm_id_priv) { - cm_cleanup_timewait(cm_id_priv->timewait_info); spin_unlock_irqrestore(&cm.lock, flags); cm_issue_rej(work->port, work->mad_recv_wc, IB_CM_REJ_INVALID_SERVICE_ID, CM_MSG_RESPONSE_REQ, NULL, 0); - goto out; + goto error; } atomic_inc(&listen_cm_id_priv->refcount); atomic_inc(&cm_id_priv->refcount); cm_id_priv->id.state = IB_CM_REQ_RCVD; atomic_inc(&cm_id_priv->work_count); spin_unlock_irqrestore(&cm.lock, flags); -out: return listen_cm_id_priv; + +error: cm_cleanup_timewait(cm_id_priv->timewait_info); + return NULL; } static int cm_req_handler(struct cm_work *work) @@ -1408,8 +1407,9 @@ static int cm_req_handler(struct cm_work *work) cm_id_priv->initiator_depth = cm_req_get_resp_res(req_msg); cm_id_priv->responder_resources = cm_req_get_init_depth(req_msg); cm_id_priv->path_mtu = cm_req_get_path_mtu(req_msg); - cm_id_priv->pkey = req_msg->pkey; cm_id_priv->sq_psn = cm_req_get_starting_psn(req_msg); + cm_id_priv->local_ack_timeout = + cm_req_get_primary_local_ack_timeout(req_msg); cm_id_priv->retry_count = cm_req_get_retry_count(req_msg); cm_id_priv->rnr_retry_count = cm_req_get_rnr_retry_count(req_msg); cm_id_priv->qp_type = cm_req_get_qp_type(req_msg); @@ -1713,7 +1713,7 @@ static int cm_establish_handler(struct cm_work *work) unsigned long flags; int ret; - /* See comment in cm_establish about lookup. */ + /* See comment in ib_cm_establish about lookup. */ cm_id_priv = cm_acquire_id(work->local_id, work->remote_id); if (!cm_id_priv) return -EINVAL; @@ -1899,32 +1899,6 @@ out: spin_unlock_irqrestore(&cm_id_priv->lock, flags); } EXPORT_SYMBOL(ib_send_cm_drep); -static int cm_issue_drep(struct cm_port *port, - struct ib_mad_recv_wc *mad_recv_wc) -{ - struct ib_mad_send_buf *msg = NULL; - struct cm_dreq_msg *dreq_msg; - struct cm_drep_msg *drep_msg; - int ret; - - ret = cm_alloc_response_msg(port, mad_recv_wc, &msg); - if (ret) - return ret; - - dreq_msg = (struct cm_dreq_msg *) mad_recv_wc->recv_buf.mad; - drep_msg = (struct cm_drep_msg *) msg->mad; - - cm_format_mad_hdr(&drep_msg->hdr, CM_DREP_ATTR_ID, dreq_msg->hdr.tid); - drep_msg->remote_comm_id = dreq_msg->local_comm_id; - drep_msg->local_comm_id = dreq_msg->remote_comm_id; - - ret = ib_post_send_mad(msg, NULL); - if (ret) - cm_free_msg(msg); - - return ret; -} - static int cm_dreq_handler(struct cm_work *work) { struct cm_id_private *cm_id_priv; @@ -1936,10 +1910,8 @@ static int cm_dreq_handler(struct cm_work *work) dreq_msg = (struct cm_dreq_msg *)work->mad_recv_wc->recv_buf.mad; cm_id_priv = cm_acquire_id(dreq_msg->remote_comm_id, dreq_msg->local_comm_id); - if (!cm_id_priv) { - cm_issue_drep(work->port, work->mad_recv_wc); + if (!cm_id_priv) return -EINVAL; - } work->cm_event.private_data = &dreq_msg->private_data; @@ -2399,16 +2371,11 @@ int ib_send_cm_lap(struct ib_cm_id *cm_id, cm_id_priv = container_of(cm_id, struct cm_id_private, id); spin_lock_irqsave(&cm_id_priv->lock, flags); if (cm_id->state != IB_CM_ESTABLISHED || - (cm_id->lap_state != IB_CM_LAP_UNINIT && - cm_id->lap_state != IB_CM_LAP_IDLE)) { + cm_id->lap_state != IB_CM_LAP_IDLE) { ret = -EINVAL; goto out; } - ret = cm_init_av_by_path(alternate_path, &cm_id_priv->alt_av); - if (ret) - goto out; - ret = cm_alloc_msg(cm_id_priv, &msg); if (ret) goto out; @@ -2433,8 +2400,7 @@ out: spin_unlock_irqrestore(&cm_id_priv->lock, flags); } EXPORT_SYMBOL(ib_send_cm_lap); -static void cm_format_path_from_lap(struct cm_id_private *cm_id_priv, - struct ib_sa_path_rec *path, +static void cm_format_path_from_lap(struct ib_sa_path_rec *path, struct cm_lap_msg *lap_msg) { memset(path, 0, sizeof *path); @@ -2446,10 +2412,10 @@ static void cm_format_path_from_lap(struct cm_id_private *cm_id_priv, path->hop_limit = lap_msg->alt_hop_limit; path->traffic_class = cm_lap_get_traffic_class(lap_msg); path->reversible = 1; - path->pkey = cm_id_priv->pkey; + /* pkey is same as in REQ */ path->sl = cm_lap_get_sl(lap_msg); path->mtu_selector = IB_SA_EQ; - path->mtu = cm_id_priv->path_mtu; + /* mtu is same as in REQ */ path->rate_selector = IB_SA_EQ; path->rate = cm_lap_get_packet_rate(lap_msg); path->packet_life_time_selector = IB_SA_EQ; @@ -2475,7 +2441,7 @@ static int cm_lap_handler(struct cm_work *work) param = &work->cm_event.param.lap_rcvd; param->alternate_path = &work->path[0]; - cm_format_path_from_lap(cm_id_priv, param->alternate_path, lap_msg); + cm_format_path_from_lap(param->alternate_path, lap_msg); work->cm_event.private_data = &lap_msg->private_data; spin_lock_irqsave(&cm_id_priv->lock, flags); @@ -2483,7 +2449,6 @@ static int cm_lap_handler(struct cm_work *work) goto unlock; switch (cm_id_priv->id.lap_state) { - case IB_CM_LAP_UNINIT: case IB_CM_LAP_IDLE: break; case IB_CM_MRA_LAP_SENT: @@ -2506,10 +2471,6 @@ static int cm_lap_handler(struct cm_work *work) cm_id_priv->id.lap_state = IB_CM_LAP_RCVD; cm_id_priv->tid = lap_msg->hdr.tid; - cm_init_av_for_response(work->port, work->mad_recv_wc->wc, - work->mad_recv_wc->recv_buf.grh, - &cm_id_priv->av); - cm_init_av_by_path(param->alternate_path, &cm_id_priv->alt_av); ret = atomic_inc_and_test(&cm_id_priv->work_count); if (!ret) list_add_tail(&work->list, &cm_id_priv->work_list); @@ -2640,29 +2601,28 @@ static int cm_timewait_handler(struct cm_work *work) { struct cm_timewait_info *timewait_info; struct cm_id_private *cm_id_priv; + unsigned long flags; int ret; timewait_info = (struct cm_timewait_info *)work; - spin_lock_irq(&cm.lock); - list_del(&timewait_info->list); - spin_unlock_irq(&cm.lock); + cm_cleanup_timewait(timewait_info); cm_id_priv = cm_acquire_id(timewait_info->work.local_id, timewait_info->work.remote_id); if (!cm_id_priv) return -EINVAL; - spin_lock_irq(&cm_id_priv->lock); + spin_lock_irqsave(&cm_id_priv->lock, flags); if (cm_id_priv->id.state != IB_CM_TIMEWAIT || cm_id_priv->remote_qpn != timewait_info->remote_qpn) { - spin_unlock_irq(&cm_id_priv->lock); + spin_unlock_irqrestore(&cm_id_priv->lock, flags); goto out; } cm_id_priv->id.state = IB_CM_IDLE; ret = atomic_inc_and_test(&cm_id_priv->work_count); if (!ret) list_add_tail(&work->list, &cm_id_priv->work_list); - spin_unlock_irq(&cm_id_priv->lock); + spin_unlock_irqrestore(&cm_id_priv->lock, flags); if (ret) cm_process_work(cm_id_priv, work); @@ -3048,7 +3008,7 @@ static void cm_work_handler(void *data) cm_free_work(work); } -static int cm_establish(struct ib_cm_id *cm_id) +int ib_cm_establish(struct ib_cm_id *cm_id) { struct cm_id_private *cm_id_priv; struct cm_work *work; @@ -3096,44 +3056,7 @@ static int cm_establish(struct ib_cm_id *cm_id) out: return ret; } - -static int cm_migrate(struct ib_cm_id *cm_id) -{ - struct cm_id_private *cm_id_priv; - unsigned long flags; - int ret = 0; - - cm_id_priv = container_of(cm_id, struct cm_id_private, id); - spin_lock_irqsave(&cm_id_priv->lock, flags); - if (cm_id->state == IB_CM_ESTABLISHED && - (cm_id->lap_state == IB_CM_LAP_UNINIT || - cm_id->lap_state == IB_CM_LAP_IDLE)) { - cm_id->lap_state = IB_CM_LAP_IDLE; - cm_id_priv->av = cm_id_priv->alt_av; - } else - ret = -EINVAL; - spin_unlock_irqrestore(&cm_id_priv->lock, flags); - - return ret; -} - -int ib_cm_notify(struct ib_cm_id *cm_id, enum ib_event_type event) -{ - int ret; - - switch (event) { - case IB_EVENT_COMM_EST: - ret = cm_establish(cm_id); - break; - case IB_EVENT_PATH_MIG: - ret = cm_migrate(cm_id); - break; - default: - ret = -EINVAL; - } - return ret; -} -EXPORT_SYMBOL(ib_cm_notify); +EXPORT_SYMBOL(ib_cm_establish); static void cm_recv_handler(struct ib_mad_agent *mad_agent, struct ib_mad_recv_wc *mad_recv_wc) @@ -3218,7 +3141,8 @@ static int cm_init_qp_init_attr(struct cm_id_private *cm_id_priv, case IB_CM_ESTABLISHED: *qp_attr_mask = IB_QP_STATE | IB_QP_ACCESS_FLAGS | IB_QP_PKEY_INDEX | IB_QP_PORT; - qp_attr->qp_access_flags = IB_ACCESS_REMOTE_WRITE; + qp_attr->qp_access_flags = IB_ACCESS_LOCAL_WRITE | + IB_ACCESS_REMOTE_WRITE; if (cm_id_priv->responder_resources) qp_attr->qp_access_flags |= IB_ACCESS_REMOTE_READ | IB_ACCESS_REMOTE_ATOMIC; @@ -3266,9 +3190,6 @@ static int cm_init_qp_rtr_attr(struct cm_id_private *cm_id_priv, if (cm_id_priv->alt_av.ah_attr.dlid) { *qp_attr_mask |= IB_QP_ALT_PATH; qp_attr->alt_port_num = cm_id_priv->alt_av.port->port_num; - qp_attr->alt_pkey_index = cm_id_priv->alt_av.pkey_index; - qp_attr->alt_timeout = - cm_id_priv->alt_av.packet_life_time + 1; qp_attr->alt_ah_attr = cm_id_priv->alt_av.ah_attr; } ret = 0; @@ -3295,31 +3216,19 @@ static int cm_init_qp_rts_attr(struct cm_id_private *cm_id_priv, case IB_CM_REP_SENT: case IB_CM_MRA_REP_RCVD: case IB_CM_ESTABLISHED: - if (cm_id_priv->id.lap_state == IB_CM_LAP_UNINIT) { - *qp_attr_mask = IB_QP_STATE | IB_QP_SQ_PSN; - qp_attr->sq_psn = be32_to_cpu(cm_id_priv->sq_psn); - if (cm_id_priv->qp_type == IB_QPT_RC) { - *qp_attr_mask |= IB_QP_TIMEOUT | IB_QP_RETRY_CNT | - IB_QP_RNR_RETRY | - IB_QP_MAX_QP_RD_ATOMIC; - qp_attr->timeout = - cm_id_priv->av.packet_life_time + 1; - qp_attr->retry_cnt = cm_id_priv->retry_count; - qp_attr->rnr_retry = cm_id_priv->rnr_retry_count; - qp_attr->max_rd_atomic = - cm_id_priv->initiator_depth; - } - if (cm_id_priv->alt_av.ah_attr.dlid) { - *qp_attr_mask |= IB_QP_PATH_MIG_STATE; - qp_attr->path_mig_state = IB_MIG_REARM; - } - } else { - *qp_attr_mask = IB_QP_ALT_PATH | IB_QP_PATH_MIG_STATE; - qp_attr->alt_port_num = cm_id_priv->alt_av.port->port_num; - qp_attr->alt_pkey_index = cm_id_priv->alt_av.pkey_index; - qp_attr->alt_timeout = - cm_id_priv->alt_av.packet_life_time + 1; - qp_attr->alt_ah_attr = cm_id_priv->alt_av.ah_attr; + *qp_attr_mask = IB_QP_STATE | IB_QP_SQ_PSN; + qp_attr->sq_psn = be32_to_cpu(cm_id_priv->sq_psn); + if (cm_id_priv->qp_type == IB_QPT_RC) { + *qp_attr_mask |= IB_QP_TIMEOUT | IB_QP_RETRY_CNT | + IB_QP_RNR_RETRY | + IB_QP_MAX_QP_RD_ATOMIC; + qp_attr->timeout = cm_id_priv->local_ack_timeout; + qp_attr->retry_cnt = cm_id_priv->retry_count; + qp_attr->rnr_retry = cm_id_priv->rnr_retry_count; + qp_attr->max_rd_atomic = cm_id_priv->initiator_depth; + } + if (cm_id_priv->alt_av.ah_attr.dlid) { + *qp_attr_mask |= IB_QP_PATH_MIG_STATE; qp_attr->path_mig_state = IB_MIG_REARM; } ret = 0; @@ -3465,7 +3374,6 @@ static int __init ib_cm_init(void) idr_init(&cm.local_id_table); get_random_bytes(&cm.random_id_operand, sizeof cm.random_id_operand); idr_pre_get(&cm.local_id_table, GFP_KERNEL); - INIT_LIST_HEAD(&cm.timewait_list); cm.wq = create_workqueue("ib_cm"); if (!cm.wq) @@ -3483,20 +3391,7 @@ static int __init ib_cm_init(void) static void __exit ib_cm_cleanup(void) { - struct cm_timewait_info *timewait_info, *tmp; - - spin_lock_irq(&cm.lock); - list_for_each_entry(timewait_info, &cm.timewait_list, list) - cancel_delayed_work(&timewait_info->work.work); - spin_unlock_irq(&cm.lock); - destroy_workqueue(cm.wq); - - list_for_each_entry_safe(timewait_info, tmp, &cm.timewait_list, list) { - list_del(&timewait_info->list); - kfree(timewait_info); - } - ib_unregister_client(&cm_client); idr_destroy(&cm.local_id_table); } diff --git a/trunk/drivers/infiniband/core/cma.c b/trunk/drivers/infiniband/core/cma.c index cf48f2697434..9ae4f3a67c70 100644 --- a/trunk/drivers/infiniband/core/cma.c +++ b/trunk/drivers/infiniband/core/cma.c @@ -63,7 +63,6 @@ static struct ib_client cma_client = { }; static struct ib_sa_client sa_client; -static struct rdma_addr_client addr_client; static LIST_HEAD(dev_list); static LIST_HEAD(listen_any_list); static DEFINE_MUTEX(lock); @@ -344,7 +343,7 @@ static int cma_init_ib_qp(struct rdma_id_private *id_priv, struct ib_qp *qp) return ret; qp_attr.qp_state = IB_QPS_INIT; - qp_attr.qp_access_flags = 0; + qp_attr.qp_access_flags = IB_ACCESS_LOCAL_WRITE; qp_attr.port_num = id_priv->id.port_num; return ib_modify_qp(qp, &qp_attr, IB_QP_STATE | IB_QP_ACCESS_FLAGS | IB_QP_PKEY_INDEX | IB_QP_PORT); @@ -935,8 +934,13 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) mutex_lock(&lock); ret = cma_acquire_dev(conn_id); mutex_unlock(&lock); - if (ret) - goto release_conn_id; + if (ret) { + ret = -ENODEV; + cma_exch(conn_id, CMA_DESTROYING); + cma_release_remove(conn_id); + rdma_destroy_id(&conn_id->id); + goto out; + } conn_id->cm_id.ib = cm_id; cm_id->context = conn_id; @@ -946,17 +950,13 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) ret = cma_notify_user(conn_id, RDMA_CM_EVENT_CONNECT_REQUEST, 0, ib_event->private_data + offset, IB_CM_REQ_PRIVATE_DATA_SIZE - offset); - if (!ret) - goto out; - - /* Destroy the CM ID by returning a non-zero value. */ - conn_id->cm_id.ib = NULL; - -release_conn_id: - cma_exch(conn_id, CMA_DESTROYING); - cma_release_remove(conn_id); - rdma_destroy_id(&conn_id->id); - + if (ret) { + /* Destroy the CM ID by returning a non-zero value. */ + conn_id->cm_id.ib = NULL; + cma_exch(conn_id, CMA_DESTROYING); + cma_release_remove(conn_id); + rdma_destroy_id(&conn_id->id); + } out: cma_release_remove(listen_id); return ret; @@ -1480,18 +1480,19 @@ static int cma_bind_loopback(struct rdma_id_private *id_priv) u8 p; mutex_lock(&lock); - if (list_empty(&dev_list)) { - ret = -ENODEV; - goto out; - } list_for_each_entry(cma_dev, &dev_list, list) for (p = 1; p <= cma_dev->device->phys_port_cnt; ++p) - if (!ib_query_port(cma_dev->device, p, &port_attr) && + if (!ib_query_port (cma_dev->device, p, &port_attr) && port_attr.state == IB_PORT_ACTIVE) goto port_found; - p = 1; - cma_dev = list_entry(dev_list.next, struct cma_device, list); + if (!list_empty(&dev_list)) { + p = 1; + cma_dev = list_entry(dev_list.next, struct cma_device, list); + } else { + ret = -ENODEV; + goto out; + } port_found: ret = ib_get_cached_gid(cma_dev->device, p, 0, &gid); @@ -1624,8 +1625,8 @@ int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr, if (cma_any_addr(dst_addr)) ret = cma_resolve_loopback(id_priv); else - ret = rdma_resolve_ip(&addr_client, &id->route.addr.src_addr, - dst_addr, &id->route.addr.dev_addr, + ret = rdma_resolve_ip(&id->route.addr.src_addr, dst_addr, + &id->route.addr.dev_addr, timeout_ms, addr_handler, id_priv); if (ret) goto err; @@ -1761,29 +1762,22 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr) if (!cma_any_addr(addr)) { ret = rdma_translate_ip(addr, &id->route.addr.dev_addr); + if (!ret) { + mutex_lock(&lock); + ret = cma_acquire_dev(id_priv); + mutex_unlock(&lock); + } if (ret) - goto err1; - - mutex_lock(&lock); - ret = cma_acquire_dev(id_priv); - mutex_unlock(&lock); - if (ret) - goto err1; + goto err; } memcpy(&id->route.addr.src_addr, addr, ip_addr_size(addr)); ret = cma_get_port(id_priv); if (ret) - goto err2; + goto err; return 0; -err2: - if (!cma_any_addr(addr)) { - mutex_lock(&lock); - cma_detach_from_dev(id_priv); - mutex_unlock(&lock); - } -err1: +err: cma_comp_exch(id_priv, CMA_ADDR_BOUND, CMA_IDLE); return ret; } @@ -2121,6 +2115,8 @@ static void cma_add_one(struct ib_device *device) cma_dev->device = device; cma_dev->node_guid = device->node_guid; + if (!cma_dev->node_guid) + goto err; init_completion(&cma_dev->comp); atomic_set(&cma_dev->refcount, 1); @@ -2132,6 +2128,9 @@ static void cma_add_one(struct ib_device *device) list_for_each_entry(id_priv, &listen_any_list, list) cma_listen_on_dev(id_priv, cma_dev); mutex_unlock(&lock); + return; +err: + kfree(cma_dev); } static int cma_remove_id_dev(struct rdma_id_private *id_priv) @@ -2211,7 +2210,6 @@ static int cma_init(void) return -ENOMEM; ib_sa_register_client(&sa_client); - rdma_addr_register_client(&addr_client); ret = ib_register_client(&cma_client); if (ret) @@ -2219,7 +2217,6 @@ static int cma_init(void) return 0; err: - rdma_addr_unregister_client(&addr_client); ib_sa_unregister_client(&sa_client); destroy_workqueue(cma_wq); return ret; @@ -2228,7 +2225,6 @@ static int cma_init(void) static void cma_cleanup(void) { ib_unregister_client(&cma_client); - rdma_addr_unregister_client(&addr_client); ib_sa_unregister_client(&sa_client); destroy_workqueue(cma_wq); idr_destroy(&sdp_ps); diff --git a/trunk/drivers/infiniband/core/iwcm.c b/trunk/drivers/infiniband/core/iwcm.c index cf797d7aea09..c3fb304a4e86 100644 --- a/trunk/drivers/infiniband/core/iwcm.c +++ b/trunk/drivers/infiniband/core/iwcm.c @@ -80,7 +80,7 @@ struct iwcm_work { * 1) in the event upcall, cm_event_handler(), for a listening cm_id. If * the backlog is exceeded, then no more connection request events will * be processed. cm_event_handler() returns -ENOMEM in this case. Its up - * to the provider to reject the connection request. + * to the provider to reject the connectino request. * 2) in the connection request workqueue handler, cm_conn_req_handler(). * If work elements cannot be allocated for the new connect request cm_id, * then IWCM will call the provider reject method. This is ok since @@ -131,25 +131,26 @@ static int alloc_work_entries(struct iwcm_id_private *cm_id_priv, int count) } /* - * Save private data from incoming connection requests to - * iw_cm_event, so the low level driver doesn't have to. Adjust + * Save private data from incoming connection requests in the + * cm_id_priv so the low level driver doesn't have to. Adjust * the event ptr to point to the local copy. */ -static int copy_private_data(struct iw_cm_event *event) +static int copy_private_data(struct iwcm_id_private *cm_id_priv, + struct iw_cm_event *event) { void *p; - p = kmemdup(event->private_data, event->private_data_len, GFP_ATOMIC); + p = kmalloc(event->private_data_len, GFP_ATOMIC); if (!p) return -ENOMEM; + memcpy(p, event->private_data, event->private_data_len); event->private_data = p; return 0; } /* - * Release a reference on cm_id. If the last reference is being - * released, enable the waiting thread (in iw_destroy_cm_id) to - * get woken up, and return 1 if a thread is already waiting. + * Release a reference on cm_id. If the last reference is being removed + * and iw_destroy_cm_id is waiting, wake up the waiting thread. */ static int iwcm_deref_id(struct iwcm_id_private *cm_id_priv) { @@ -242,7 +243,7 @@ static int iwcm_modify_qp_sqd(struct ib_qp *qp) /* * CM_ID <-- CLOSING * - * Block if a passive or active connection is currently being processed. Then + * Block if a passive or active connection is currenlty being processed. Then * process the event as follows: * - If we are ESTABLISHED, move to CLOSING and modify the QP state * based on the abrupt flag @@ -407,7 +408,7 @@ int iw_cm_listen(struct iw_cm_id *cm_id, int backlog) { struct iwcm_id_private *cm_id_priv; unsigned long flags; - int ret; + int ret = 0; cm_id_priv = container_of(cm_id, struct iwcm_id_private, id); @@ -534,7 +535,7 @@ EXPORT_SYMBOL(iw_cm_accept); int iw_cm_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *iw_param) { struct iwcm_id_private *cm_id_priv; - int ret; + int ret = 0; unsigned long flags; struct ib_qp *qp; @@ -619,7 +620,7 @@ static void cm_conn_req_handler(struct iwcm_id_private *listen_id_priv, spin_lock_irqsave(&listen_id_priv->lock, flags); if (listen_id_priv->state != IW_CM_STATE_LISTEN) { spin_unlock_irqrestore(&listen_id_priv->lock, flags); - goto out; + return; } spin_unlock_irqrestore(&listen_id_priv->lock, flags); @@ -628,7 +629,7 @@ static void cm_conn_req_handler(struct iwcm_id_private *listen_id_priv, listen_id_priv->id.context); /* If the cm_id could not be created, ignore the request */ if (IS_ERR(cm_id)) - goto out; + return; cm_id->provider_data = iw_event->provider_data; cm_id->local_addr = iw_event->local_addr; @@ -641,7 +642,7 @@ static void cm_conn_req_handler(struct iwcm_id_private *listen_id_priv, if (ret) { iw_cm_reject(cm_id, NULL, 0); iw_destroy_cm_id(cm_id); - goto out; + return; } /* Call the client CM handler */ @@ -653,7 +654,6 @@ static void cm_conn_req_handler(struct iwcm_id_private *listen_id_priv, kfree(cm_id); } -out: if (iw_event->private_data_len) kfree(iw_event->private_data); } @@ -674,7 +674,7 @@ static int cm_conn_est_handler(struct iwcm_id_private *cm_id_priv, struct iw_cm_event *iw_event) { unsigned long flags; - int ret; + int ret = 0; spin_lock_irqsave(&cm_id_priv->lock, flags); @@ -704,7 +704,7 @@ static int cm_conn_rep_handler(struct iwcm_id_private *cm_id_priv, struct iw_cm_event *iw_event) { unsigned long flags; - int ret; + int ret = 0; spin_lock_irqsave(&cm_id_priv->lock, flags); /* @@ -830,8 +830,7 @@ static int process_event(struct iwcm_id_private *cm_id_priv, */ static void cm_work_handler(void *arg) { - struct iwcm_work *work = arg; - struct iw_cm_event levent; + struct iwcm_work *work = arg, lwork; struct iwcm_id_private *cm_id_priv = work->cm_id; unsigned long flags; int empty; @@ -844,11 +843,11 @@ static void cm_work_handler(void *arg) struct iwcm_work, list); list_del_init(&work->list); empty = list_empty(&cm_id_priv->work_list); - levent = work->event; + lwork = *work; put_work(work); spin_unlock_irqrestore(&cm_id_priv->lock, flags); - ret = process_event(cm_id_priv, &levent); + ret = process_event(cm_id_priv, &work->event); if (ret) { set_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags); destroy_cm_id(&cm_id_priv->id); @@ -907,7 +906,7 @@ static int cm_event_handler(struct iw_cm_id *cm_id, if ((work->event.event == IW_CM_EVENT_CONNECT_REQUEST || work->event.event == IW_CM_EVENT_CONNECT_REPLY) && work->event.private_data_len) { - ret = copy_private_data(&work->event); + ret = copy_private_data(cm_id_priv, &work->event); if (ret) { put_work(work); goto out; diff --git a/trunk/drivers/infiniband/core/mad.c b/trunk/drivers/infiniband/core/mad.c index 3f9c16232c4d..493f4c65c7a2 100644 --- a/trunk/drivers/infiniband/core/mad.c +++ b/trunk/drivers/infiniband/core/mad.c @@ -46,7 +46,7 @@ MODULE_DESCRIPTION("kernel IB MAD API"); MODULE_AUTHOR("Hal Rosenstock"); MODULE_AUTHOR("Sean Hefty"); -static struct kmem_cache *ib_mad_cache; +static kmem_cache_t *ib_mad_cache; static struct list_head ib_mad_port_list; static u32 ib_mad_client_id = 0; @@ -1750,7 +1750,7 @@ ib_find_send_mad(struct ib_mad_agent_private *mad_agent_priv, */ (is_direct(wc->recv_buf.mad->mad_hdr.mgmt_class) || rcv_has_same_gid(mad_agent_priv, wr, wc))) - return (wr->status == IB_WC_SUCCESS) ? wr : NULL; + return wr; } /* diff --git a/trunk/drivers/infiniband/core/ucm.c b/trunk/drivers/infiniband/core/ucm.c index f15220a0ee75..ad4f4d5c2924 100644 --- a/trunk/drivers/infiniband/core/ucm.c +++ b/trunk/drivers/infiniband/core/ucm.c @@ -161,14 +161,12 @@ static void ib_ucm_cleanup_events(struct ib_ucm_context *ctx) struct ib_ucm_event, ctx_list); list_del(&uevent->file_list); list_del(&uevent->ctx_list); - mutex_unlock(&ctx->file->file_mutex); /* clear incoming connections. */ if (ib_ucm_new_cm_id(uevent->resp.event)) ib_destroy_cm_id(uevent->cm_id); kfree(uevent); - mutex_lock(&ctx->file->file_mutex); } mutex_unlock(&ctx->file->file_mutex); } @@ -330,18 +328,20 @@ static int ib_ucm_event_process(struct ib_cm_event *evt, } if (uvt->data_len) { - uvt->data = kmemdup(evt->private_data, uvt->data_len, GFP_KERNEL); + uvt->data = kmalloc(uvt->data_len, GFP_KERNEL); if (!uvt->data) goto err1; + memcpy(uvt->data, evt->private_data, uvt->data_len); uvt->resp.present |= IB_UCM_PRES_DATA; } if (uvt->info_len) { - uvt->info = kmemdup(info, uvt->info_len, GFP_KERNEL); + uvt->info = kmalloc(uvt->info_len, GFP_KERNEL); if (!uvt->info) goto err2; + memcpy(uvt->info, info, uvt->info_len); uvt->resp.present |= IB_UCM_PRES_INFO; } return 0; @@ -685,11 +685,11 @@ static ssize_t ib_ucm_listen(struct ib_ucm_file *file, return result; } -static ssize_t ib_ucm_notify(struct ib_ucm_file *file, - const char __user *inbuf, - int in_len, int out_len) +static ssize_t ib_ucm_establish(struct ib_ucm_file *file, + const char __user *inbuf, + int in_len, int out_len) { - struct ib_ucm_notify cmd; + struct ib_ucm_establish cmd; struct ib_ucm_context *ctx; int result; @@ -700,7 +700,7 @@ static ssize_t ib_ucm_notify(struct ib_ucm_file *file, if (IS_ERR(ctx)) return PTR_ERR(ctx); - result = ib_cm_notify(ctx->cm_id, (enum ib_event_type) cmd.event); + result = ib_cm_establish(ctx->cm_id); ib_ucm_ctx_put(ctx); return result; } @@ -1107,7 +1107,7 @@ static ssize_t (*ucm_cmd_table[])(struct ib_ucm_file *file, [IB_USER_CM_CMD_DESTROY_ID] = ib_ucm_destroy_id, [IB_USER_CM_CMD_ATTR_ID] = ib_ucm_attr_id, [IB_USER_CM_CMD_LISTEN] = ib_ucm_listen, - [IB_USER_CM_CMD_NOTIFY] = ib_ucm_notify, + [IB_USER_CM_CMD_ESTABLISH] = ib_ucm_establish, [IB_USER_CM_CMD_SEND_REQ] = ib_ucm_send_req, [IB_USER_CM_CMD_SEND_REP] = ib_ucm_send_rep, [IB_USER_CM_CMD_SEND_RTU] = ib_ucm_send_rtu, diff --git a/trunk/drivers/infiniband/core/uverbs_cmd.c b/trunk/drivers/infiniband/core/uverbs_cmd.c index 743247ec065e..b72c7f69ca90 100644 --- a/trunk/drivers/infiniband/core/uverbs_cmd.c +++ b/trunk/drivers/infiniband/core/uverbs_cmd.c @@ -1214,7 +1214,7 @@ ssize_t ib_uverbs_query_qp(struct ib_uverbs_file *file, resp.qp_access_flags = attr->qp_access_flags; resp.pkey_index = attr->pkey_index; resp.alt_pkey_index = attr->alt_pkey_index; - resp.sq_draining = attr->sq_draining; + resp.en_sqd_async_notify = attr->en_sqd_async_notify; resp.max_rd_atomic = attr->max_rd_atomic; resp.max_dest_rd_atomic = attr->max_dest_rd_atomic; resp.min_rnr_timer = attr->min_rnr_timer; diff --git a/trunk/drivers/infiniband/hw/amso1100/c2.c b/trunk/drivers/infiniband/hw/amso1100/c2.c index 27fe242ed435..9e9120f36019 100644 --- a/trunk/drivers/infiniband/hw/amso1100/c2.c +++ b/trunk/drivers/infiniband/hw/amso1100/c2.c @@ -72,7 +72,7 @@ static int c2_down(struct net_device *netdev); static int c2_xmit_frame(struct sk_buff *skb, struct net_device *netdev); static void c2_tx_interrupt(struct net_device *netdev); static void c2_rx_interrupt(struct net_device *netdev); -static irqreturn_t c2_interrupt(int irq, void *dev_id); +static irqreturn_t c2_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void c2_tx_timeout(struct net_device *netdev); static int c2_change_mtu(struct net_device *netdev, int new_mtu); static void c2_reset(struct c2_port *c2_port); @@ -544,7 +544,7 @@ static void c2_rx_interrupt(struct net_device *netdev) /* * Handle netisr0 TX & RX interrupts. */ -static irqreturn_t c2_interrupt(int irq, void *dev_id) +static irqreturn_t c2_interrupt(int irq, void *dev_id, struct pt_regs *regs) { unsigned int netisr0, dmaisr; int handled = 0; @@ -1155,8 +1155,7 @@ static int __devinit c2_probe(struct pci_dev *pcidev, goto bail10; } - if (c2_register_device(c2dev)) - goto bail10; + c2_register_device(c2dev); return 0; @@ -1244,7 +1243,7 @@ static struct pci_driver c2_pci_driver = { static int __init c2_init_module(void) { - return pci_register_driver(&c2_pci_driver); + return pci_module_init(&c2_pci_driver); } static void __exit c2_exit_module(void) diff --git a/trunk/drivers/infiniband/hw/amso1100/c2.h b/trunk/drivers/infiniband/hw/amso1100/c2.h index 04a9db5de881..1b17dcdd0505 100644 --- a/trunk/drivers/infiniband/hw/amso1100/c2.h +++ b/trunk/drivers/infiniband/hw/amso1100/c2.h @@ -302,7 +302,7 @@ struct c2_dev { unsigned long pa; /* PA device memory */ void **qptr_array; - struct kmem_cache *host_msg_cache; + kmem_cache_t *host_msg_cache; struct list_head cca_link; /* adapter list */ struct list_head eh_wakeup_list; /* event wakeup list */ diff --git a/trunk/drivers/infiniband/hw/amso1100/c2_ae.c b/trunk/drivers/infiniband/hw/amso1100/c2_ae.c index a31439bd3b67..3aae4978e1cb 100644 --- a/trunk/drivers/infiniband/hw/amso1100/c2_ae.c +++ b/trunk/drivers/infiniband/hw/amso1100/c2_ae.c @@ -66,6 +66,7 @@ static int c2_convert_cm_status(u32 c2_status) } } +#ifdef DEBUG static const char* to_event_str(int event) { static const char* event_str[] = { @@ -143,6 +144,7 @@ static const char *to_qp_state_str(int state) return ""; }; } +#endif void c2_ae_event(struct c2_dev *c2dev, u32 mq_index) { diff --git a/trunk/drivers/infiniband/hw/amso1100/c2_alloc.c b/trunk/drivers/infiniband/hw/amso1100/c2_alloc.c index 0315f99e4191..028a60bbfca9 100644 --- a/trunk/drivers/infiniband/hw/amso1100/c2_alloc.c +++ b/trunk/drivers/infiniband/hw/amso1100/c2_alloc.c @@ -42,14 +42,13 @@ static int c2_alloc_mqsp_chunk(struct c2_dev *c2dev, gfp_t gfp_mask, { int i; struct sp_chunk *new_head; - dma_addr_t dma_addr; - new_head = dma_alloc_coherent(&c2dev->pcidev->dev, PAGE_SIZE, - &dma_addr, gfp_mask); + new_head = (struct sp_chunk *) __get_free_page(gfp_mask); if (new_head == NULL) return -ENOMEM; - new_head->dma_addr = dma_addr; + new_head->dma_addr = dma_map_single(c2dev->ibdev.dma_device, new_head, + PAGE_SIZE, DMA_FROM_DEVICE); pci_unmap_addr_set(new_head, mapping, new_head->dma_addr); new_head->next = NULL; @@ -81,8 +80,10 @@ void c2_free_mqsp_pool(struct c2_dev *c2dev, struct sp_chunk *root) while (root) { next = root->next; - dma_free_coherent(&c2dev->pcidev->dev, PAGE_SIZE, root, - pci_unmap_addr(root, mapping)); + dma_unmap_single(c2dev->ibdev.dma_device, + pci_unmap_addr(root, mapping), PAGE_SIZE, + DMA_FROM_DEVICE); + __free_page((struct page *) root); root = next; } } diff --git a/trunk/drivers/infiniband/hw/amso1100/c2_cq.c b/trunk/drivers/infiniband/hw/amso1100/c2_cq.c index 05c9154d46f4..9d7bcc5ade93 100644 --- a/trunk/drivers/infiniband/hw/amso1100/c2_cq.c +++ b/trunk/drivers/infiniband/hw/amso1100/c2_cq.c @@ -246,17 +246,20 @@ int c2_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify notify) static void c2_free_cq_buf(struct c2_dev *c2dev, struct c2_mq *mq) { - dma_free_coherent(&c2dev->pcidev->dev, mq->q_size * mq->msg_size, - mq->msg_pool.host, pci_unmap_addr(mq, mapping)); + + dma_unmap_single(c2dev->ibdev.dma_device, pci_unmap_addr(mq, mapping), + mq->q_size * mq->msg_size, DMA_FROM_DEVICE); + free_pages((unsigned long) mq->msg_pool.host, + get_order(mq->q_size * mq->msg_size)); } static int c2_alloc_cq_buf(struct c2_dev *c2dev, struct c2_mq *mq, int q_size, int msg_size) { - u8 *pool_start; + unsigned long pool_start; - pool_start = dma_alloc_coherent(&c2dev->pcidev->dev, q_size * msg_size, - &mq->host_dma, GFP_KERNEL); + pool_start = __get_free_pages(GFP_KERNEL, + get_order(q_size * msg_size)); if (!pool_start) return -ENOMEM; @@ -264,10 +267,13 @@ static int c2_alloc_cq_buf(struct c2_dev *c2dev, struct c2_mq *mq, int q_size, 0, /* index (currently unknown) */ q_size, msg_size, - pool_start, + (u8 *) pool_start, NULL, /* peer (currently unknown) */ C2_MQ_HOST_TARGET); + mq->host_dma = dma_map_single(c2dev->ibdev.dma_device, + (void *)pool_start, + q_size * msg_size, DMA_FROM_DEVICE); pci_unmap_addr_set(mq, mapping, mq->host_dma); return 0; diff --git a/trunk/drivers/infiniband/hw/amso1100/c2_provider.c b/trunk/drivers/infiniband/hw/amso1100/c2_provider.c index fef972752912..da98d9f71429 100644 --- a/trunk/drivers/infiniband/hw/amso1100/c2_provider.c +++ b/trunk/drivers/infiniband/hw/amso1100/c2_provider.c @@ -757,17 +757,20 @@ static struct net_device *c2_pseudo_netdev_init(struct c2_dev *c2dev) int c2_register_device(struct c2_dev *dev) { - int ret = -ENOMEM; + int ret; int i; /* Register pseudo network device */ dev->pseudo_netdev = c2_pseudo_netdev_init(dev); - if (!dev->pseudo_netdev) - goto out3; - - ret = register_netdev(dev->pseudo_netdev); - if (ret) - goto out2; + if (dev->pseudo_netdev) { + ret = register_netdev(dev->pseudo_netdev); + if (ret) { + printk(KERN_ERR PFX + "Unable to register netdev, ret = %d\n", ret); + free_netdev(dev->pseudo_netdev); + return ret; + } + } pr_debug("%s:%u\n", __FUNCTION__, __LINE__); strlcpy(dev->ibdev.name, "amso%d", IB_DEVICE_NAME_MAX); @@ -845,25 +848,21 @@ int c2_register_device(struct c2_dev *dev) ret = ib_register_device(&dev->ibdev); if (ret) - goto out1; + return ret; for (i = 0; i < ARRAY_SIZE(c2_class_attributes); ++i) { ret = class_device_create_file(&dev->ibdev.class_dev, c2_class_attributes[i]); - if (ret) - goto out0; + if (ret) { + unregister_netdev(dev->pseudo_netdev); + free_netdev(dev->pseudo_netdev); + ib_unregister_device(&dev->ibdev); + return ret; + } } - goto out3; -out0: - ib_unregister_device(&dev->ibdev); -out1: - unregister_netdev(dev->pseudo_netdev); -out2: - free_netdev(dev->pseudo_netdev); -out3: - pr_debug("%s:%u ret=%d\n", __FUNCTION__, __LINE__, ret); - return ret; + pr_debug("%s:%u\n", __FUNCTION__, __LINE__); + return 0; } void c2_unregister_device(struct c2_dev *dev) diff --git a/trunk/drivers/infiniband/hw/amso1100/c2_qp.c b/trunk/drivers/infiniband/hw/amso1100/c2_qp.c index 179d005ed4a5..12261132b077 100644 --- a/trunk/drivers/infiniband/hw/amso1100/c2_qp.c +++ b/trunk/drivers/infiniband/hw/amso1100/c2_qp.c @@ -35,8 +35,6 @@ * */ -#include - #include "c2.h" #include "c2_vq.h" #include "c2_status.h" @@ -564,32 +562,6 @@ int c2_alloc_qp(struct c2_dev *c2dev, return err; } -static inline void c2_lock_cqs(struct c2_cq *send_cq, struct c2_cq *recv_cq) -{ - if (send_cq == recv_cq) - spin_lock_irq(&send_cq->lock); - else if (send_cq > recv_cq) { - spin_lock_irq(&send_cq->lock); - spin_lock_nested(&recv_cq->lock, SINGLE_DEPTH_NESTING); - } else { - spin_lock_irq(&recv_cq->lock); - spin_lock_nested(&send_cq->lock, SINGLE_DEPTH_NESTING); - } -} - -static inline void c2_unlock_cqs(struct c2_cq *send_cq, struct c2_cq *recv_cq) -{ - if (send_cq == recv_cq) - spin_unlock_irq(&send_cq->lock); - else if (send_cq > recv_cq) { - spin_unlock(&recv_cq->lock); - spin_unlock_irq(&send_cq->lock); - } else { - spin_unlock(&send_cq->lock); - spin_unlock_irq(&recv_cq->lock); - } -} - void c2_free_qp(struct c2_dev *c2dev, struct c2_qp *qp) { struct c2_cq *send_cq; @@ -602,9 +574,15 @@ void c2_free_qp(struct c2_dev *c2dev, struct c2_qp *qp) * Lock CQs here, so that CQ polling code can do QP lookup * without taking a lock. */ - c2_lock_cqs(send_cq, recv_cq); + spin_lock_irq(&send_cq->lock); + if (send_cq != recv_cq) + spin_lock(&recv_cq->lock); + c2_free_qpn(c2dev, qp->qpn); - c2_unlock_cqs(send_cq, recv_cq); + + if (send_cq != recv_cq) + spin_unlock(&recv_cq->lock); + spin_unlock_irq(&send_cq->lock); /* * Destory qp in the rnic... @@ -727,8 +705,10 @@ static inline void c2_activity(struct c2_dev *c2dev, u32 mq_index, u16 shared) * cannot get on the bus and the card and system hang in a * deadlock -- thus the need for this code. [TOT] */ - while (readl(c2dev->regs + PCI_BAR0_ADAPTER_HINT) & 0x80000000) - udelay(10); + while (readl(c2dev->regs + PCI_BAR0_ADAPTER_HINT) & 0x80000000) { + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(0); + } __raw_writel(C2_HINT_MAKE(mq_index, shared), c2dev->regs + PCI_BAR0_ADAPTER_HINT); @@ -786,7 +766,6 @@ int c2_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr, struct c2_dev *c2dev = to_c2dev(ibqp->device); struct c2_qp *qp = to_c2qp(ibqp); union c2wr wr; - unsigned long lock_flags; int err = 0; u32 flags; @@ -902,10 +881,8 @@ int c2_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr, /* * Post the puppy! */ - spin_lock_irqsave(&qp->lock, lock_flags); err = qp_wr_post(&qp->sq_mq, &wr, qp, msg_size); if (err) { - spin_unlock_irqrestore(&qp->lock, lock_flags); break; } @@ -913,7 +890,6 @@ int c2_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr, * Enqueue mq index to activity FIFO. */ c2_activity(c2dev, qp->sq_mq.index, qp->sq_mq.hint_count); - spin_unlock_irqrestore(&qp->lock, lock_flags); ib_wr = ib_wr->next; } @@ -929,7 +905,6 @@ int c2_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *ib_wr, struct c2_dev *c2dev = to_c2dev(ibqp->device); struct c2_qp *qp = to_c2qp(ibqp); union c2wr wr; - unsigned long lock_flags; int err = 0; if (qp->state > IB_QPS_RTS) @@ -970,10 +945,8 @@ int c2_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *ib_wr, break; } - spin_lock_irqsave(&qp->lock, lock_flags); err = qp_wr_post(&qp->rq_mq, &wr, qp, qp->rq_mq.msg_size); if (err) { - spin_unlock_irqrestore(&qp->lock, lock_flags); break; } @@ -981,7 +954,6 @@ int c2_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *ib_wr, * Enqueue mq index to activity FIFO */ c2_activity(c2dev, qp->rq_mq.index, qp->rq_mq.hint_count); - spin_unlock_irqrestore(&qp->lock, lock_flags); ib_wr = ib_wr->next; } diff --git a/trunk/drivers/infiniband/hw/amso1100/c2_rnic.c b/trunk/drivers/infiniband/hw/amso1100/c2_rnic.c index 1687c511cb2f..e37c5688c214 100644 --- a/trunk/drivers/infiniband/hw/amso1100/c2_rnic.c +++ b/trunk/drivers/infiniband/hw/amso1100/c2_rnic.c @@ -150,15 +150,15 @@ static int c2_rnic_query(struct c2_dev *c2dev, struct ib_device_attr *props) (struct c2wr_rnic_query_rep *) (unsigned long) (vq_req->reply_msg); if (!reply) err = -ENOMEM; - else - err = c2_errno(reply); + + err = c2_errno(reply); if (err) goto bail2; props->fw_ver = ((u64)be32_to_cpu(reply->fw_ver_major) << 32) | - ((be32_to_cpu(reply->fw_ver_minor) & 0xFFFF) << 16) | - (be32_to_cpu(reply->fw_ver_patch) & 0xFFFF); + ((be32_to_cpu(reply->fw_ver_minor) && 0xFFFF) << 16) | + (be32_to_cpu(reply->fw_ver_patch) && 0xFFFF); memcpy(&props->sys_image_guid, c2dev->netdev->dev_addr, 6); props->max_mr_size = 0xFFFFFFFF; props->page_size_cap = ~(C2_MIN_PAGESIZE-1); @@ -441,7 +441,7 @@ static int c2_rnic_close(struct c2_dev *c2dev) * involves initalizing the various limits and resouce pools that * comprise the RNIC instance. */ -int __devinit c2_rnic_init(struct c2_dev *c2dev) +int c2_rnic_init(struct c2_dev *c2dev) { int err; u32 qsize, msgsize; @@ -517,12 +517,14 @@ int __devinit c2_rnic_init(struct c2_dev *c2dev) /* Initialize the Verbs Reply Queue */ qsize = be32_to_cpu(readl(mmio_regs + C2_REGS_Q1_QSIZE)); msgsize = be32_to_cpu(readl(mmio_regs + C2_REGS_Q1_MSGSIZE)); - q1_pages = dma_alloc_coherent(&c2dev->pcidev->dev, qsize * msgsize, - &c2dev->rep_vq.host_dma, GFP_KERNEL); + q1_pages = kmalloc(qsize * msgsize, GFP_KERNEL); if (!q1_pages) { err = -ENOMEM; goto bail1; } + c2dev->rep_vq.host_dma = dma_map_single(c2dev->ibdev.dma_device, + (void *)q1_pages, qsize * msgsize, + DMA_FROM_DEVICE); pci_unmap_addr_set(&c2dev->rep_vq, mapping, c2dev->rep_vq.host_dma); pr_debug("%s rep_vq va %p dma %llx\n", __FUNCTION__, q1_pages, (unsigned long long) c2dev->rep_vq.host_dma); @@ -538,15 +540,17 @@ int __devinit c2_rnic_init(struct c2_dev *c2dev) /* Initialize the Asynchronus Event Queue */ qsize = be32_to_cpu(readl(mmio_regs + C2_REGS_Q2_QSIZE)); msgsize = be32_to_cpu(readl(mmio_regs + C2_REGS_Q2_MSGSIZE)); - q2_pages = dma_alloc_coherent(&c2dev->pcidev->dev, qsize * msgsize, - &c2dev->aeq.host_dma, GFP_KERNEL); + q2_pages = kmalloc(qsize * msgsize, GFP_KERNEL); if (!q2_pages) { err = -ENOMEM; goto bail2; } + c2dev->aeq.host_dma = dma_map_single(c2dev->ibdev.dma_device, + (void *)q2_pages, qsize * msgsize, + DMA_FROM_DEVICE); pci_unmap_addr_set(&c2dev->aeq, mapping, c2dev->aeq.host_dma); - pr_debug("%s aeq va %p dma %llx\n", __FUNCTION__, q2_pages, - (unsigned long long) c2dev->aeq.host_dma); + pr_debug("%s aeq va %p dma %llx\n", __FUNCTION__, q1_pages, + (unsigned long long) c2dev->rep_vq.host_dma); c2_mq_rep_init(&c2dev->aeq, 2, qsize, @@ -593,13 +597,17 @@ int __devinit c2_rnic_init(struct c2_dev *c2dev) bail4: vq_term(c2dev); bail3: - dma_free_coherent(&c2dev->pcidev->dev, - c2dev->aeq.q_size * c2dev->aeq.msg_size, - q2_pages, pci_unmap_addr(&c2dev->aeq, mapping)); + dma_unmap_single(c2dev->ibdev.dma_device, + pci_unmap_addr(&c2dev->aeq, mapping), + c2dev->aeq.q_size * c2dev->aeq.msg_size, + DMA_FROM_DEVICE); + kfree(q2_pages); bail2: - dma_free_coherent(&c2dev->pcidev->dev, - c2dev->rep_vq.q_size * c2dev->rep_vq.msg_size, - q1_pages, pci_unmap_addr(&c2dev->rep_vq, mapping)); + dma_unmap_single(c2dev->ibdev.dma_device, + pci_unmap_addr(&c2dev->rep_vq, mapping), + c2dev->rep_vq.q_size * c2dev->rep_vq.msg_size, + DMA_FROM_DEVICE); + kfree(q1_pages); bail1: c2_free_mqsp_pool(c2dev, c2dev->kern_mqsp_pool); bail0: @@ -611,7 +619,7 @@ int __devinit c2_rnic_init(struct c2_dev *c2dev) /* * Called by c2_remove to cleanup the RNIC resources. */ -void __devexit c2_rnic_term(struct c2_dev *c2dev) +void c2_rnic_term(struct c2_dev *c2dev) { /* Close the open adapter instance */ @@ -632,17 +640,19 @@ void __devexit c2_rnic_term(struct c2_dev *c2dev) /* Free the verbs request allocator */ vq_term(c2dev); - /* Free the asynchronus event queue */ - dma_free_coherent(&c2dev->pcidev->dev, - c2dev->aeq.q_size * c2dev->aeq.msg_size, - c2dev->aeq.msg_pool.host, - pci_unmap_addr(&c2dev->aeq, mapping)); - - /* Free the verbs reply queue */ - dma_free_coherent(&c2dev->pcidev->dev, - c2dev->rep_vq.q_size * c2dev->rep_vq.msg_size, - c2dev->rep_vq.msg_pool.host, - pci_unmap_addr(&c2dev->rep_vq, mapping)); + /* Unmap and free the asynchronus event queue */ + dma_unmap_single(c2dev->ibdev.dma_device, + pci_unmap_addr(&c2dev->aeq, mapping), + c2dev->aeq.q_size * c2dev->aeq.msg_size, + DMA_FROM_DEVICE); + kfree(c2dev->aeq.msg_pool.host); + + /* Unmap and free the verbs reply queue */ + dma_unmap_single(c2dev->ibdev.dma_device, + pci_unmap_addr(&c2dev->rep_vq, mapping), + c2dev->rep_vq.q_size * c2dev->rep_vq.msg_size, + DMA_FROM_DEVICE); + kfree(c2dev->rep_vq.msg_pool.host); /* Free the MQ shared pointer pool */ c2_free_mqsp_pool(c2dev, c2dev->kern_mqsp_pool); diff --git a/trunk/drivers/infiniband/hw/ehca/Kconfig b/trunk/drivers/infiniband/hw/ehca/Kconfig index 727b10d89686..922389b64394 100644 --- a/trunk/drivers/infiniband/hw/ehca/Kconfig +++ b/trunk/drivers/infiniband/hw/ehca/Kconfig @@ -10,7 +10,6 @@ config INFINIBAND_EHCA config INFINIBAND_EHCA_SCALING bool "Scaling support (EXPERIMENTAL)" depends on IBMEBUS && INFINIBAND_EHCA && HOTPLUG_CPU && EXPERIMENTAL - default y ---help--- eHCA scaling support schedules the CQ callbacks to different CPUs. diff --git a/trunk/drivers/infiniband/hw/ehca/ehca_av.c b/trunk/drivers/infiniband/hw/ehca/ehca_av.c index 214e2fdddeef..3bac197f9014 100644 --- a/trunk/drivers/infiniband/hw/ehca/ehca_av.c +++ b/trunk/drivers/infiniband/hw/ehca/ehca_av.c @@ -118,7 +118,8 @@ struct ib_ah *ehca_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr) } memcpy(&av->av.grh.word_1, &gid, sizeof(gid)); } - av->av.pmtu = EHCA_MAX_MTU; + /* for the time being we use a hard coded PMTU of 2048 Bytes */ + av->av.pmtu = 4; /* dgid comes in grh.word_3 */ memcpy(&av->av.grh.word_3, &ah_attr->grh.dgid, @@ -192,7 +193,7 @@ int ehca_modify_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr) memcpy(&new_ehca_av.grh.word_1, &gid, sizeof(gid)); } - new_ehca_av.pmtu = EHCA_MAX_MTU; + new_ehca_av.pmtu = 4; /* see also comment in create_ah() */ memcpy(&new_ehca_av.grh.word_3, &ah_attr->grh.dgid, sizeof(ah_attr->grh.dgid)); diff --git a/trunk/drivers/infiniband/hw/ehca/ehca_hca.c b/trunk/drivers/infiniband/hw/ehca/ehca_hca.c index e1b618c5f685..5eae6ac48425 100644 --- a/trunk/drivers/infiniband/hw/ehca/ehca_hca.c +++ b/trunk/drivers/infiniband/hw/ehca/ehca_hca.c @@ -40,7 +40,6 @@ */ #include "ehca_tools.h" -#include "ehca_iverbs.h" #include "hcp_if.h" int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props) @@ -50,7 +49,7 @@ int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props) ib_device); struct hipz_query_hca *rblock; - rblock = ehca_alloc_fw_ctrlblock(); + rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); if (!rblock) { ehca_err(&shca->ib_device, "Can't allocate rblock memory."); return -ENOMEM; @@ -97,7 +96,7 @@ int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props) = min_t(int, rblock->max_total_mcast_qp_attach, INT_MAX); query_device1: - ehca_free_fw_ctrlblock(rblock); + kfree(rblock); return ret; } @@ -110,7 +109,7 @@ int ehca_query_port(struct ib_device *ibdev, ib_device); struct hipz_query_port *rblock; - rblock = ehca_alloc_fw_ctrlblock(); + rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); if (!rblock) { ehca_err(&shca->ib_device, "Can't allocate rblock memory."); return -ENOMEM; @@ -163,7 +162,7 @@ int ehca_query_port(struct ib_device *ibdev, props->active_speed = 0x1; query_port1: - ehca_free_fw_ctrlblock(rblock); + kfree(rblock); return ret; } @@ -179,7 +178,7 @@ int ehca_query_pkey(struct ib_device *ibdev, u8 port, u16 index, u16 *pkey) return -EINVAL; } - rblock = ehca_alloc_fw_ctrlblock(); + rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); if (!rblock) { ehca_err(&shca->ib_device, "Can't allocate rblock memory."); return -ENOMEM; @@ -194,7 +193,7 @@ int ehca_query_pkey(struct ib_device *ibdev, u8 port, u16 index, u16 *pkey) memcpy(pkey, &rblock->pkey_entries + index, sizeof(u16)); query_pkey1: - ehca_free_fw_ctrlblock(rblock); + kfree(rblock); return ret; } @@ -212,7 +211,7 @@ int ehca_query_gid(struct ib_device *ibdev, u8 port, return -EINVAL; } - rblock = ehca_alloc_fw_ctrlblock(); + rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); if (!rblock) { ehca_err(&shca->ib_device, "Can't allocate rblock memory."); return -ENOMEM; @@ -228,7 +227,7 @@ int ehca_query_gid(struct ib_device *ibdev, u8 port, memcpy(&gid->raw[8], &rblock->guid_entries[index], sizeof(u64)); query_gid1: - ehca_free_fw_ctrlblock(rblock); + kfree(rblock); return ret; } diff --git a/trunk/drivers/infiniband/hw/ehca/ehca_irq.c b/trunk/drivers/infiniband/hw/ehca/ehca_irq.c index c3ea746e9045..2a65b5be1979 100644 --- a/trunk/drivers/infiniband/hw/ehca/ehca_irq.c +++ b/trunk/drivers/infiniband/hw/ehca/ehca_irq.c @@ -45,7 +45,6 @@ #include "ehca_tools.h" #include "hcp_if.h" #include "hipz_fns.h" -#include "ipz_pt_fn.h" #define EQE_COMPLETION_EVENT EHCA_BMASK_IBM(1,1) #define EQE_CQ_QP_NUMBER EHCA_BMASK_IBM(8,31) @@ -138,36 +137,38 @@ int ehca_error_data(struct ehca_shca *shca, void *data, u64 *rblock; unsigned long block_count; - rblock = ehca_alloc_fw_ctrlblock(); + rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); if (!rblock) { ehca_err(&shca->ib_device, "Cannot allocate rblock memory."); ret = -ENOMEM; goto error_data1; } - /* rblock must be 4K aligned and should be 4K large */ ret = hipz_h_error_data(shca->ipz_hca_handle, resource, rblock, &block_count); - if (ret == H_R_STATE) + if (ret == H_R_STATE) { ehca_err(&shca->ib_device, "No error data is available: %lx.", resource); + } else if (ret == H_SUCCESS) { int length; length = EHCA_BMASK_GET(ERROR_DATA_LENGTH, rblock[0]); - if (length > EHCA_PAGESIZE) - length = EHCA_PAGESIZE; + if (length > PAGE_SIZE) + length = PAGE_SIZE; print_error_data(shca, data, rblock, length); - } else + } + else { ehca_err(&shca->ib_device, "Error data could not be fetched: %lx", resource); + } - ehca_free_fw_ctrlblock(rblock); + kfree(rblock); error_data1: return ret; @@ -359,7 +360,7 @@ static inline void reset_eq_pending(struct ehca_cq *cq) return; } -irqreturn_t ehca_interrupt_neq(int irq, void *dev_id) +irqreturn_t ehca_interrupt_neq(int irq, void *dev_id, struct pt_regs *regs) { struct ehca_shca *shca = (struct ehca_shca*)dev_id; @@ -392,7 +393,7 @@ void ehca_tasklet_neq(unsigned long data) return; } -irqreturn_t ehca_interrupt_eq(int irq, void *dev_id) +irqreturn_t ehca_interrupt_eq(int irq, void *dev_id, struct pt_regs *regs) { struct ehca_shca *shca = (struct ehca_shca*)dev_id; diff --git a/trunk/drivers/infiniband/hw/ehca/ehca_irq.h b/trunk/drivers/infiniband/hw/ehca/ehca_irq.h index be579cc0adf6..85bf1fe16fe4 100644 --- a/trunk/drivers/infiniband/hw/ehca/ehca_irq.h +++ b/trunk/drivers/infiniband/hw/ehca/ehca_irq.h @@ -51,10 +51,10 @@ struct ehca_shca; int ehca_error_data(struct ehca_shca *shca, void *data, u64 resource); -irqreturn_t ehca_interrupt_neq(int irq, void *dev_id); +irqreturn_t ehca_interrupt_neq(int irq, void *dev_id, struct pt_regs *regs); void ehca_tasklet_neq(unsigned long data); -irqreturn_t ehca_interrupt_eq(int irq, void *dev_id); +irqreturn_t ehca_interrupt_eq(int irq, void *dev_id, struct pt_regs *regs); void ehca_tasklet_eq(unsigned long data); struct ehca_cpu_comp_task { diff --git a/trunk/drivers/infiniband/hw/ehca/ehca_iverbs.h b/trunk/drivers/infiniband/hw/ehca/ehca_iverbs.h index 3720e3032cce..319c39d47f3a 100644 --- a/trunk/drivers/infiniband/hw/ehca/ehca_iverbs.h +++ b/trunk/drivers/infiniband/hw/ehca/ehca_iverbs.h @@ -179,12 +179,4 @@ int ehca_mmap_register(u64 physical,void **mapped, int ehca_munmap(unsigned long addr, size_t len); -#ifdef CONFIG_PPC_64K_PAGES -void *ehca_alloc_fw_ctrlblock(void); -void ehca_free_fw_ctrlblock(void *ptr); -#else -#define ehca_alloc_fw_ctrlblock() ((void *) get_zeroed_page(GFP_KERNEL)) -#define ehca_free_fw_ctrlblock(ptr) free_page((unsigned long)(ptr)) -#endif - #endif diff --git a/trunk/drivers/infiniband/hw/ehca/ehca_main.c b/trunk/drivers/infiniband/hw/ehca/ehca_main.c index 3d1c1c535038..024d511c4b58 100644 --- a/trunk/drivers/infiniband/hw/ehca/ehca_main.c +++ b/trunk/drivers/infiniband/hw/ehca/ehca_main.c @@ -40,9 +40,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifdef CONFIG_PPC_64K_PAGES -#include -#endif #include "ehca_classes.h" #include "ehca_iverbs.h" #include "ehca_mrmw.h" @@ -52,7 +49,7 @@ MODULE_LICENSE("Dual BSD/GPL"); MODULE_AUTHOR("Christoph Raisch "); MODULE_DESCRIPTION("IBM eServer HCA InfiniBand Device Driver"); -MODULE_VERSION("SVNEHCA_0019"); +MODULE_VERSION("SVNEHCA_0017"); int ehca_open_aqp1 = 0; int ehca_debug_level = 0; @@ -97,31 +94,11 @@ spinlock_t ehca_cq_idr_lock; DEFINE_IDR(ehca_qp_idr); DEFINE_IDR(ehca_cq_idr); - static struct list_head shca_list; /* list of all registered ehcas */ static spinlock_t shca_list_lock; static struct timer_list poll_eqs_timer; -#ifdef CONFIG_PPC_64K_PAGES -static struct kmem_cache *ctblk_cache = NULL; - -void *ehca_alloc_fw_ctrlblock(void) -{ - void *ret = kmem_cache_zalloc(ctblk_cache, SLAB_KERNEL); - if (!ret) - ehca_gen_err("Out of memory for ctblk"); - return ret; -} - -void ehca_free_fw_ctrlblock(void *ptr) -{ - if (ptr) - kmem_cache_free(ctblk_cache, ptr); - -} -#endif - static int ehca_create_slab_caches(void) { int ret; @@ -156,17 +133,6 @@ static int ehca_create_slab_caches(void) goto create_slab_caches5; } -#ifdef CONFIG_PPC_64K_PAGES - ctblk_cache = kmem_cache_create("ehca_cache_ctblk", - EHCA_PAGESIZE, H_CB_ALIGNMENT, - SLAB_HWCACHE_ALIGN, - NULL, NULL); - if (!ctblk_cache) { - ehca_gen_err("Cannot create ctblk SLAB cache."); - ehca_cleanup_mrmw_cache(); - goto create_slab_caches5; - } -#endif return 0; create_slab_caches5: @@ -191,10 +157,6 @@ static void ehca_destroy_slab_caches(void) ehca_cleanup_qp_cache(); ehca_cleanup_cq_cache(); ehca_cleanup_pd_cache(); -#ifdef CONFIG_PPC_64K_PAGES - if (ctblk_cache) - kmem_cache_destroy(ctblk_cache); -#endif } #define EHCA_HCAAVER EHCA_BMASK_IBM(32,39) @@ -206,7 +168,7 @@ int ehca_sense_attributes(struct ehca_shca *shca) u64 h_ret; struct hipz_query_hca *rblock; - rblock = ehca_alloc_fw_ctrlblock(); + rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); if (!rblock) { ehca_gen_err("Cannot allocate rblock memory."); return -ENOMEM; @@ -249,7 +211,7 @@ int ehca_sense_attributes(struct ehca_shca *shca) shca->sport[1].rate = IB_RATE_30_GBPS; num_ports1: - ehca_free_fw_ctrlblock(rblock); + kfree(rblock); return ret; } @@ -258,7 +220,7 @@ static int init_node_guid(struct ehca_shca *shca) int ret = 0; struct hipz_query_hca *rblock; - rblock = ehca_alloc_fw_ctrlblock(); + rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); if (!rblock) { ehca_err(&shca->ib_device, "Can't allocate rblock memory."); return -ENOMEM; @@ -273,7 +235,7 @@ static int init_node_guid(struct ehca_shca *shca) memcpy(&shca->ib_device.node_guid, &rblock->node_guid, sizeof(u64)); init_node_guid1: - ehca_free_fw_ctrlblock(rblock); + kfree(rblock); return ret; } @@ -469,7 +431,7 @@ static ssize_t ehca_show_##name(struct device *dev, \ \ shca = dev->driver_data; \ \ - rblock = ehca_alloc_fw_ctrlblock(); \ + rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); \ if (!rblock) { \ dev_err(dev, "Can't allocate rblock memory."); \ return 0; \ @@ -477,12 +439,12 @@ static ssize_t ehca_show_##name(struct device *dev, \ \ if (hipz_h_query_hca(shca->ipz_hca_handle, rblock) != H_SUCCESS) { \ dev_err(dev, "Can't query device properties"); \ - ehca_free_fw_ctrlblock(rblock); \ + kfree(rblock); \ return 0; \ } \ \ data = rblock->name; \ - ehca_free_fw_ctrlblock(rblock); \ + kfree(rblock); \ \ if ((strcmp(#name, "num_ports") == 0) && (ehca_nr_ports == 1)) \ return snprintf(buf, 256, "1\n"); \ @@ -790,7 +752,7 @@ int __init ehca_module_init(void) int ret; printk(KERN_INFO "eHCA Infiniband Device Driver " - "(Rel.: SVNEHCA_0019)\n"); + "(Rel.: SVNEHCA_0017)\n"); idr_init(&ehca_qp_idr); idr_init(&ehca_cq_idr); spin_lock_init(&ehca_qp_idr_lock); diff --git a/trunk/drivers/infiniband/hw/ehca/ehca_mrmw.c b/trunk/drivers/infiniband/hw/ehca/ehca_mrmw.c index abce676c0ae0..5ca65441e1da 100644 --- a/trunk/drivers/infiniband/hw/ehca/ehca_mrmw.c +++ b/trunk/drivers/infiniband/hw/ehca/ehca_mrmw.c @@ -1013,7 +1013,7 @@ int ehca_reg_mr_rpages(struct ehca_shca *shca, u32 i; u64 *kpage; - kpage = ehca_alloc_fw_ctrlblock(); + kpage = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); if (!kpage) { ehca_err(&shca->ib_device, "kpage alloc failed"); ret = -ENOMEM; @@ -1092,7 +1092,7 @@ int ehca_reg_mr_rpages(struct ehca_shca *shca, ehca_reg_mr_rpages_exit1: - ehca_free_fw_ctrlblock(kpage); + kfree(kpage); ehca_reg_mr_rpages_exit0: if (ret) ehca_err(&shca->ib_device, "ret=%x shca=%p e_mr=%p pginfo=%p " @@ -1124,7 +1124,7 @@ inline int ehca_rereg_mr_rereg1(struct ehca_shca *shca, ehca_mrmw_map_acl(acl, &hipz_acl); ehca_mrmw_set_pgsize_hipz_acl(&hipz_acl); - kpage = ehca_alloc_fw_ctrlblock(); + kpage = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); if (!kpage) { ehca_err(&shca->ib_device, "kpage alloc failed"); ret = -ENOMEM; @@ -1181,7 +1181,7 @@ inline int ehca_rereg_mr_rereg1(struct ehca_shca *shca, } ehca_rereg_mr_rereg1_exit1: - ehca_free_fw_ctrlblock(kpage); + kfree(kpage); ehca_rereg_mr_rereg1_exit0: if ( ret && (ret != -EAGAIN) ) ehca_err(&shca->ib_device, "ret=%x lkey=%x rkey=%x " diff --git a/trunk/drivers/infiniband/hw/ehca/ehca_qp.c b/trunk/drivers/infiniband/hw/ehca/ehca_qp.c index 8682aa50c707..4394123cdbd7 100644 --- a/trunk/drivers/infiniband/hw/ehca/ehca_qp.c +++ b/trunk/drivers/infiniband/hw/ehca/ehca_qp.c @@ -732,7 +732,8 @@ static int prepare_sqe_rts(struct ehca_qp *my_qp, struct ehca_shca *shca, u64 h_ret; struct ipz_queue *squeue; void *bad_send_wqe_p, *bad_send_wqe_v; - u64 q_ofs; + void *squeue_start_p, *squeue_end_p; + void *squeue_start_v, *squeue_end_v; struct ehca_wqe *wqe; int qp_num = my_qp->ib_qp.qp_num; @@ -754,23 +755,26 @@ static int prepare_sqe_rts(struct ehca_qp *my_qp, struct ehca_shca *shca, if (ehca_debug_level) ehca_dmp(bad_send_wqe_v, 32, "qp_num=%x bad_wqe", qp_num); squeue = &my_qp->ipz_squeue; - if (ipz_queue_abs_to_offset(squeue, (u64)bad_send_wqe_p, &q_ofs)) { - ehca_err(&shca->ib_device, "failed to get wqe offset qp_num=%x" - " bad_send_wqe_p=%p", qp_num, bad_send_wqe_p); - return -EFAULT; - } + squeue_start_p = (void*)virt_to_abs(ipz_qeit_calc(squeue, 0L)); + squeue_end_p = squeue_start_p+squeue->queue_length; + squeue_start_v = abs_to_virt((u64)squeue_start_p); + squeue_end_v = abs_to_virt((u64)squeue_end_p); + ehca_dbg(&shca->ib_device, "qp_num=%x squeue_start_v=%p squeue_end_v=%p", + qp_num, squeue_start_v, squeue_end_v); /* loop sets wqe's purge bit */ - wqe = (struct ehca_wqe*)ipz_qeit_calc(squeue, q_ofs); + wqe = (struct ehca_wqe*)bad_send_wqe_v; *bad_wqe_cnt = 0; while (wqe->optype != 0xff && wqe->wqef != 0xff) { if (ehca_debug_level) ehca_dmp(wqe, 32, "qp_num=%x wqe", qp_num); wqe->nr_of_data_seg = 0; /* suppress data access */ wqe->wqef = WQEF_PURGE; /* WQE to be purged */ - q_ofs = ipz_queue_advance_offset(squeue, q_ofs); - wqe = (struct ehca_wqe*)ipz_qeit_calc(squeue, q_ofs); + wqe = (struct ehca_wqe*)((u8*)wqe+squeue->qe_size); *bad_wqe_cnt = (*bad_wqe_cnt)+1; + if ((void*)wqe >= squeue_end_v) { + wqe = squeue_start_v; + } } /* * bad wqe will be reprocessed and ignored when pol_cq() is called, @@ -807,8 +811,8 @@ static int internal_modify_qp(struct ib_qp *ibqp, unsigned long spl_flags = 0; /* do query_qp to obtain current attr values */ - mqpcb = ehca_alloc_fw_ctrlblock(); - if (!mqpcb) { + mqpcb = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); + if (mqpcb == NULL) { ehca_err(ibqp->device, "Could not get zeroed page for mqpcb " "ehca_qp=%p qp_num=%x ", my_qp, ibqp->qp_num); return -ENOMEM; @@ -1221,7 +1225,7 @@ static int internal_modify_qp(struct ib_qp *ibqp, } modify_qp_exit1: - ehca_free_fw_ctrlblock(mqpcb); + kfree(mqpcb); return ret; } @@ -1273,7 +1277,7 @@ int ehca_query_qp(struct ib_qp *qp, return -EINVAL; } - qpcb = ehca_alloc_fw_ctrlblock(); + qpcb = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL ); if (!qpcb) { ehca_err(qp->device,"Out of memory for qpcb " "ehca_qp=%p qp_num=%x", my_qp, qp->qp_num); @@ -1397,7 +1401,7 @@ int ehca_query_qp(struct ib_qp *qp, ehca_dmp(qpcb, 4*70, "qp_num=%x", qp->qp_num); query_qp_exit1: - ehca_free_fw_ctrlblock(qpcb); + kfree(qpcb); return ret; } diff --git a/trunk/drivers/infiniband/hw/ehca/ehca_tools.h b/trunk/drivers/infiniband/hw/ehca/ehca_tools.h index 973c4b591545..809da3ef706b 100644 --- a/trunk/drivers/infiniband/hw/ehca/ehca_tools.h +++ b/trunk/drivers/infiniband/hw/ehca/ehca_tools.h @@ -63,7 +63,6 @@ #include #include #include -#include extern int ehca_debug_level; diff --git a/trunk/drivers/infiniband/hw/ehca/hipz_hw.h b/trunk/drivers/infiniband/hw/ehca/hipz_hw.h index fad91368dc5a..3fc92b031c50 100644 --- a/trunk/drivers/infiniband/hw/ehca/hipz_hw.h +++ b/trunk/drivers/infiniband/hw/ehca/hipz_hw.h @@ -45,8 +45,6 @@ #include "ehca_tools.h" -#define EHCA_MAX_MTU 4 - /* QP Table Entry Memory Map */ struct hipz_qptemm { u64 qpx_hcr; diff --git a/trunk/drivers/infiniband/hw/ehca/ipz_pt_fn.c b/trunk/drivers/infiniband/hw/ehca/ipz_pt_fn.c index bf7a40088f61..e028ff1588cc 100644 --- a/trunk/drivers/infiniband/hw/ehca/ipz_pt_fn.c +++ b/trunk/drivers/infiniband/hw/ehca/ipz_pt_fn.c @@ -70,19 +70,6 @@ void *ipz_qeit_eq_get_inc(struct ipz_queue *queue) return ret; } -int ipz_queue_abs_to_offset(struct ipz_queue *queue, u64 addr, u64 *q_offset) -{ - int i; - for (i = 0; i < queue->queue_length / queue->pagesize; i++) { - u64 page = (u64)virt_to_abs(queue->queue_pages[i]); - if (addr >= page && addr < page + queue->pagesize) { - *q_offset = addr - page + i * queue->pagesize; - return 0; - } - } - return -EINVAL; -} - int ipz_queue_ctor(struct ipz_queue *queue, const u32 nr_of_pages, const u32 pagesize, const u32 qe_size, const u32 nr_of_sg) diff --git a/trunk/drivers/infiniband/hw/ehca/ipz_pt_fn.h b/trunk/drivers/infiniband/hw/ehca/ipz_pt_fn.h index dc3bda2634b7..2f13509d5257 100644 --- a/trunk/drivers/infiniband/hw/ehca/ipz_pt_fn.h +++ b/trunk/drivers/infiniband/hw/ehca/ipz_pt_fn.h @@ -150,21 +150,6 @@ static inline void *ipz_qeit_reset(struct ipz_queue *queue) return ipz_qeit_get(queue); } -/* - * return the q_offset corresponding to an absolute address - */ -int ipz_queue_abs_to_offset(struct ipz_queue *queue, u64 addr, u64 *q_offset); - -/* - * return the next queue offset. don't modify the queue. - */ -static inline u64 ipz_queue_advance_offset(struct ipz_queue *queue, u64 offset) -{ - offset += queue->qe_size; - if (offset >= queue->queue_length) offset = 0; - return offset; -} - /* struct generic page table */ struct ipz_pt { u64 entries[EHCA_PT_ENTRIES]; diff --git a/trunk/drivers/infiniband/hw/ipath/Kconfig b/trunk/drivers/infiniband/hw/ipath/Kconfig index 90c14543677d..574a678e7fdd 100644 --- a/trunk/drivers/infiniband/hw/ipath/Kconfig +++ b/trunk/drivers/infiniband/hw/ipath/Kconfig @@ -1,6 +1,6 @@ config INFINIBAND_IPATH tristate "QLogic InfiniPath Driver" - depends on (PCI_MSI || HT_IRQ) && 64BIT && INFINIBAND && NET + depends on PCI_MSI && 64BIT && INFINIBAND ---help--- This is a driver for QLogic InfiniPath host channel adapters, including InfiniBand verbs support. This driver allows these diff --git a/trunk/drivers/infiniband/hw/ipath/Makefile b/trunk/drivers/infiniband/hw/ipath/Makefile index 7dc10551cf18..5e29cb0095e5 100644 --- a/trunk/drivers/infiniband/hw/ipath/Makefile +++ b/trunk/drivers/infiniband/hw/ipath/Makefile @@ -10,6 +10,8 @@ ib_ipath-y := \ ipath_eeprom.o \ ipath_file_ops.o \ ipath_fs.o \ + ipath_iba6110.o \ + ipath_iba6120.o \ ipath_init_chip.o \ ipath_intr.o \ ipath_keys.o \ @@ -29,8 +31,5 @@ ib_ipath-y := \ ipath_verbs_mcast.o \ ipath_verbs.o -ib_ipath-$(CONFIG_HT_IRQ) += ipath_iba6110.o -ib_ipath-$(CONFIG_PCI_MSI) += ipath_iba6120.o - ib_ipath-$(CONFIG_X86_64) += ipath_wc_x86_64.o ib_ipath-$(CONFIG_PPC64) += ipath_wc_ppc64.o diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_diag.c b/trunk/drivers/infiniband/hw/ipath/ipath_diag.c index 28c087b824c2..29958b6e0214 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_diag.c +++ b/trunk/drivers/infiniband/hw/ipath/ipath_diag.c @@ -67,54 +67,19 @@ static struct file_operations diag_file_ops = { .release = ipath_diag_release }; -static ssize_t ipath_diagpkt_write(struct file *fp, - const char __user *data, - size_t count, loff_t *off); - -static struct file_operations diagpkt_file_ops = { - .owner = THIS_MODULE, - .write = ipath_diagpkt_write, -}; - -static atomic_t diagpkt_count = ATOMIC_INIT(0); -static struct cdev *diagpkt_cdev; -static struct class_device *diagpkt_class_dev; - int ipath_diag_add(struct ipath_devdata *dd) { char name[16]; - int ret = 0; - - if (atomic_inc_return(&diagpkt_count) == 1) { - ret = ipath_cdev_init(IPATH_DIAGPKT_MINOR, - "ipath_diagpkt", &diagpkt_file_ops, - &diagpkt_cdev, &diagpkt_class_dev); - - if (ret) { - ipath_dev_err(dd, "Couldn't create ipath_diagpkt " - "device: %d", ret); - goto done; - } - } snprintf(name, sizeof(name), "ipath_diag%d", dd->ipath_unit); - ret = ipath_cdev_init(IPATH_DIAG_MINOR_BASE + dd->ipath_unit, name, - &diag_file_ops, &dd->diag_cdev, - &dd->diag_class_dev); - if (ret) - ipath_dev_err(dd, "Couldn't create %s device: %d", - name, ret); - -done: - return ret; + return ipath_cdev_init(IPATH_DIAG_MINOR_BASE + dd->ipath_unit, name, + &diag_file_ops, &dd->diag_cdev, + &dd->diag_class_dev); } void ipath_diag_remove(struct ipath_devdata *dd) { - if (atomic_dec_and_test(&diagpkt_count)) - ipath_cdev_cleanup(&diagpkt_cdev, &diagpkt_class_dev); - ipath_cdev_cleanup(&dd->diag_cdev, &dd->diag_class_dev); } @@ -310,6 +275,30 @@ static int ipath_diag_open(struct inode *in, struct file *fp) return ret; } +static ssize_t ipath_diagpkt_write(struct file *fp, + const char __user *data, + size_t count, loff_t *off); + +static struct file_operations diagpkt_file_ops = { + .owner = THIS_MODULE, + .write = ipath_diagpkt_write, +}; + +static struct cdev *diagpkt_cdev; +static struct class_device *diagpkt_class_dev; + +int __init ipath_diagpkt_add(void) +{ + return ipath_cdev_init(IPATH_DIAGPKT_MINOR, + "ipath_diagpkt", &diagpkt_file_ops, + &diagpkt_cdev, &diagpkt_class_dev); +} + +void __exit ipath_diagpkt_remove(void) +{ + ipath_cdev_cleanup(&diagpkt_cdev, &diagpkt_class_dev); +} + /** * ipath_diagpkt_write - write an IB packet * @fp: the diag data device file pointer diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_driver.c b/trunk/drivers/infiniband/hw/ipath/ipath_driver.c index 1aeddb48e355..12cefa658f3b 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_driver.c +++ b/trunk/drivers/infiniband/hw/ipath/ipath_driver.c @@ -304,7 +304,7 @@ static int __devinit ipath_init_one(struct pci_dev *pdev, } addr = pci_resource_start(pdev, 0); len = pci_resource_len(pdev, 0); - ipath_cdbg(VERBOSE, "regbase (0) %llx len %d pdev->irq %d, vend %x/%x " + ipath_cdbg(VERBOSE, "regbase (0) %llx len %d irq %x, vend %x/%x " "driver_data %lx\n", addr, len, pdev->irq, ent->vendor, ent->device, ent->driver_data); @@ -390,16 +390,12 @@ static int __devinit ipath_init_one(struct pci_dev *pdev, /* setup the chip-specific functions, as early as possible. */ switch (ent->device) { -#ifdef CONFIG_HT_IRQ case PCI_DEVICE_ID_INFINIPATH_HT: ipath_init_iba6110_funcs(dd); break; -#endif -#ifdef CONFIG_PCI_MSI case PCI_DEVICE_ID_INFINIPATH_PE800: ipath_init_iba6120_funcs(dd); break; -#endif default: ipath_dev_err(dd, "Found unknown QLogic deviceid 0x%x, " "failing\n", ent->device); @@ -471,15 +467,15 @@ static int __devinit ipath_init_one(struct pci_dev *pdev, * check 0 irq after we return from chip-specific bus setup, since * that can affect this due to setup */ - if (!dd->ipath_irq) + if (!pdev->irq) ipath_dev_err(dd, "irq is 0, BIOS error? Interrupts won't " "work\n"); else { - ret = request_irq(dd->ipath_irq, ipath_intr, IRQF_SHARED, + ret = request_irq(pdev->irq, ipath_intr, IRQF_SHARED, IPATH_DRV_NAME, dd); if (ret) { ipath_dev_err(dd, "Couldn't setup irq handler, " - "irq=%d: %d\n", dd->ipath_irq, ret); + "irq=%u: %d\n", pdev->irq, ret); goto bail_iounmap; } } @@ -641,10 +637,11 @@ static void __devexit ipath_remove_one(struct pci_dev *pdev) * free up port 0 (kernel) rcvhdr, egr bufs, and eventually tid bufs * for all versions of the driver, if they were allocated */ - if (dd->ipath_irq) { - ipath_cdbg(VERBOSE, "unit %u free irq %d\n", - dd->ipath_unit, dd->ipath_irq); - dd->ipath_f_free_irq(dd); + if (pdev->irq) { + ipath_cdbg(VERBOSE, + "unit %u free_irq of irq %x\n", + dd->ipath_unit, pdev->irq); + free_irq(pdev->irq, dd); } else ipath_dbg("irq is 0, not doing free_irq " "for unit %u\n", dd->ipath_unit); @@ -2008,8 +2005,18 @@ static int __init infinipath_init(void) goto bail_group; } + ret = ipath_diagpkt_add(); + if (ret < 0) { + printk(KERN_ERR IPATH_DRV_NAME ": Unable to create " + "diag data device: error %d\n", -ret); + goto bail_ipathfs; + } + goto bail; +bail_ipathfs: + ipath_exit_ipathfs(); + bail_group: ipath_driver_remove_group(&ipath_driver.driver); diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_iba6110.c b/trunk/drivers/infiniband/hw/ipath/ipath_iba6110.c index e57c7a351cb5..9e4e8d4c6e20 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_iba6110.c +++ b/trunk/drivers/infiniband/hw/ipath/ipath_iba6110.c @@ -38,7 +38,6 @@ #include #include -#include #include "ipath_kernel.h" #include "ipath_registers.h" @@ -914,40 +913,49 @@ static void slave_or_pri_blk(struct ipath_devdata *dd, struct pci_dev *pdev, } } -static int ipath_ht_intconfig(struct ipath_devdata *dd) +static int set_int_handler(struct ipath_devdata *dd, struct pci_dev *pdev, + int pos) { - int ret; - - if (dd->ipath_intconfig) { - ipath_write_kreg(dd, dd->ipath_kregs->kr_interruptconfig, - dd->ipath_intconfig); /* interrupt address */ - ret = 0; - } else { - ipath_dev_err(dd, "No interrupts enabled, couldn't setup " - "interrupt address\n"); - ret = -EINVAL; - } + u32 int_handler_addr_lower; + u32 int_handler_addr_upper; + u64 ihandler; + u32 intvec; - return ret; -} - -static void ipath_ht_irq_update(struct pci_dev *dev, int irq, - struct ht_irq_msg *msg) -{ - struct ipath_devdata *dd = pci_get_drvdata(dev); - u64 prev_intconfig = dd->ipath_intconfig; + /* use indirection register to get the intr handler */ + pci_write_config_byte(pdev, pos + HT_INTR_REG_INDEX, 0x10); + pci_read_config_dword(pdev, pos + 4, &int_handler_addr_lower); + pci_write_config_byte(pdev, pos + HT_INTR_REG_INDEX, 0x11); + pci_read_config_dword(pdev, pos + 4, &int_handler_addr_upper); - dd->ipath_intconfig = msg->address_lo; - dd->ipath_intconfig |= ((u64) msg->address_hi) << 32; + ihandler = (u64) int_handler_addr_lower | + ((u64) int_handler_addr_upper << 32); /* - * If the previous value of dd->ipath_intconfig is zero, we're - * getting configured for the first time, and must not program the - * intconfig register here (it will be programmed later, when the - * hardware is ready). Otherwise, we should. + * kernels with CONFIG_PCI_MSI set the vector in the irq field of + * struct pci_device, so we use that to program the internal + * interrupt register (not config space) with that value. The BIOS + * must still have done the basic MSI setup. */ - if (prev_intconfig) - ipath_ht_intconfig(dd); + intvec = pdev->irq; + /* + * clear any vector bits there; normally not set but we'll overload + * this for some debug purposes (setting the HTC debug register + * value from software, rather than GPIOs), so it might be set on a + * driver reload. + */ + ihandler &= ~0xff0000; + /* x86 vector goes in intrinfo[23:16] */ + ihandler |= intvec << 16; + ipath_cdbg(VERBOSE, "ihandler lower %x, upper %x, intvec %x, " + "interruptconfig %llx\n", int_handler_addr_lower, + int_handler_addr_upper, intvec, + (unsigned long long) ihandler); + + /* can't program yet, so save for interrupt setup */ + dd->ipath_intconfig = ihandler; + /* keep going, so we find link control stuff also */ + + return ihandler != 0; } /** @@ -963,19 +971,12 @@ static void ipath_ht_irq_update(struct pci_dev *dev, int irq, static int ipath_setup_ht_config(struct ipath_devdata *dd, struct pci_dev *pdev) { - int pos, ret; - - ret = __ht_create_irq(pdev, 0, ipath_ht_irq_update); - if (ret < 0) { - ipath_dev_err(dd, "Couldn't create interrupt handler: " - "err %d\n", ret); - goto bail; - } - dd->ipath_irq = ret; - ret = 0; + int pos, ret = 0; + int ihandler = 0; /* - * Handle clearing CRC errors in linkctrl register if necessary. We + * Read the capability info to find the interrupt info, and also + * handle clearing CRC errors in linkctrl register if necessary. We * do this early, before we ever enable errors or hardware errors, * mostly to avoid causing the chip to enter freeze mode. */ @@ -999,9 +1000,17 @@ static int ipath_setup_ht_config(struct ipath_devdata *dd, } if (!(cap_type & 0xE0)) slave_or_pri_blk(dd, pdev, pos, cap_type); + else if (cap_type == HT_INTR_DISC_CONFIG) + ihandler = set_int_handler(dd, pdev, pos); } while ((pos = pci_find_next_capability(pdev, pos, PCI_CAP_ID_HT))); + if (!ihandler) { + ipath_dev_err(dd, "Couldn't find interrupt handler in " + "config space\n"); + ret = -ENODEV; + } + bail: return ret; } @@ -1351,6 +1360,25 @@ static void ipath_ht_quiet_serdes(struct ipath_devdata *dd) ipath_write_kreg(dd, dd->ipath_kregs->kr_serdesconfig0, val); } +static int ipath_ht_intconfig(struct ipath_devdata *dd) +{ + int ret; + + if (!dd->ipath_intconfig) { + ipath_dev_err(dd, "No interrupts enabled, couldn't setup " + "interrupt address\n"); + ret = 1; + goto bail; + } + + ipath_write_kreg(dd, dd->ipath_kregs->kr_interruptconfig, + dd->ipath_intconfig); /* interrupt address */ + ret = 0; + +bail: + return ret; +} + /** * ipath_pe_put_tid - write a TID in chip * @dd: the infinipath device @@ -1547,14 +1575,6 @@ static int ipath_ht_get_base_info(struct ipath_portdata *pd, void *kbase) return 0; } -static void ipath_ht_free_irq(struct ipath_devdata *dd) -{ - free_irq(dd->ipath_irq, dd); - ht_destroy_irq(dd->ipath_irq); - dd->ipath_irq = 0; - dd->ipath_intconfig = 0; -} - /** * ipath_init_iba6110_funcs - set up the chip-specific function pointers * @dd: the infinipath device @@ -1578,7 +1598,6 @@ void ipath_init_iba6110_funcs(struct ipath_devdata *dd) dd->ipath_f_cleanup = ipath_setup_ht_cleanup; dd->ipath_f_setextled = ipath_setup_ht_setextled; dd->ipath_f_get_base_info = ipath_ht_get_base_info; - dd->ipath_f_free_irq = ipath_ht_free_irq; /* * initialize chip-specific variables diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_iba6120.c b/trunk/drivers/infiniband/hw/ipath/ipath_iba6120.c index 6af89683f710..a72ab9de386a 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_iba6120.c +++ b/trunk/drivers/infiniband/hw/ipath/ipath_iba6120.c @@ -851,7 +851,6 @@ static int ipath_setup_pe_config(struct ipath_devdata *dd, int pos, ret; dd->ipath_msi_lo = 0; /* used as a flag during reset processing */ - dd->ipath_irq = pdev->irq; ret = pci_enable_msi(dd->pcidev); if (ret) ipath_dev_err(dd, "pci_enable_msi failed: %d, " @@ -1324,12 +1323,6 @@ static int ipath_pe_get_base_info(struct ipath_portdata *pd, void *kbase) return 0; } -static void ipath_pe_free_irq(struct ipath_devdata *dd) -{ - free_irq(dd->ipath_irq, dd); - dd->ipath_irq = 0; -} - /** * ipath_init_iba6120_funcs - set up the chip-specific function pointers * @dd: the infinipath device @@ -1356,7 +1349,6 @@ void ipath_init_iba6120_funcs(struct ipath_devdata *dd) dd->ipath_f_cleanup = ipath_setup_pe_cleanup; dd->ipath_f_setextled = ipath_setup_pe_setextled; dd->ipath_f_get_base_info = ipath_pe_get_base_info; - dd->ipath_f_free_irq = ipath_pe_free_irq; /* initialize chip-specific variables */ dd->ipath_f_tidtemplate = ipath_pe_tidtemplate; diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_intr.c b/trunk/drivers/infiniband/hw/ipath/ipath_intr.c index 5652a550d442..6bee53ce5f33 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_intr.c +++ b/trunk/drivers/infiniband/hw/ipath/ipath_intr.c @@ -710,14 +710,14 @@ static void ipath_bad_intr(struct ipath_devdata *dd, u32 * unexpectp) * linuxbios development work, and it may happen in * the future again. */ - if (dd->pcidev && dd->ipath_irq) { + if (dd->pcidev && dd->pcidev->irq) { ipath_dev_err(dd, "Now %u unexpected " "interrupts, unregistering " "interrupt handler\n", *unexpectp); - ipath_dbg("free_irq of irq %d\n", - dd->ipath_irq); - dd->ipath_f_free_irq(dd); + ipath_dbg("free_irq of irq %x\n", + dd->pcidev->irq); + free_irq(dd->pcidev->irq, dd); } } if (ipath_read_kreg32(dd, dd->ipath_kregs->kr_intmask)) { @@ -753,7 +753,7 @@ static void ipath_bad_regread(struct ipath_devdata *dd) if (allbits == 2) { ipath_dev_err(dd, "Still bad interrupt status, " "unregistering interrupt\n"); - dd->ipath_f_free_irq(dd); + free_irq(dd->pcidev->irq, dd); } else if (allbits > 2) { if ((allbits % 10000) == 0) printk("."); @@ -839,7 +839,7 @@ static void handle_urcv(struct ipath_devdata *dd, u32 istat) } } -irqreturn_t ipath_intr(int irq, void *data) +irqreturn_t ipath_intr(int irq, void *data, struct pt_regs *regs) { struct ipath_devdata *dd = data; u32 istat, chk0rcv = 0; diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_kernel.h b/trunk/drivers/infiniband/hw/ipath/ipath_kernel.h index 986b2125b8f5..d7540b71b451 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_kernel.h +++ b/trunk/drivers/infiniband/hw/ipath/ipath_kernel.h @@ -213,8 +213,6 @@ struct ipath_devdata { void (*ipath_f_setextled)(struct ipath_devdata *, u64, u64); /* fill out chip-specific fields */ int (*ipath_f_get_base_info)(struct ipath_portdata *, void *); - /* free irq */ - void (*ipath_f_free_irq)(struct ipath_devdata *); struct ipath_ibdev *verbs_dev; struct timer_list verbs_timer; /* total dwords sent (summed from counter) */ @@ -330,8 +328,6 @@ struct ipath_devdata { /* so we can rewrite it after a chip reset */ u32 ipath_pcibar1; - /* interrupt number */ - int ipath_irq; /* HT/PCI Vendor ID (here for NodeInfo) */ u16 ipath_vendorid; /* HT/PCI Device ID (here for NodeInfo) */ @@ -610,7 +606,7 @@ struct sk_buff *ipath_alloc_skb(struct ipath_devdata *dd, gfp_t); extern int ipath_diag_inuse; -irqreturn_t ipath_intr(int irq, void *devid); +irqreturn_t ipath_intr(int irq, void *devid, struct pt_regs *regs); void ipath_decode_err(char *buf, size_t blen, ipath_err_t err); #if __IPATH_INFO || __IPATH_DBG extern const char *ipath_ibcstatus_str[]; @@ -873,6 +869,9 @@ int ipath_device_create_group(struct device *, struct ipath_devdata *); void ipath_device_remove_group(struct device *, struct ipath_devdata *); int ipath_expose_reset(struct device *); +int ipath_diagpkt_add(void); +void ipath_diagpkt_remove(void); + int ipath_init_ipathfs(void); void ipath_exit_ipathfs(void); int ipathfs_add_device(struct ipath_devdata *); diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_verbs.c b/trunk/drivers/infiniband/hw/ipath/ipath_verbs.c index acdee33ee1f8..a5456108dbad 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_verbs.c +++ b/trunk/drivers/infiniband/hw/ipath/ipath_verbs.c @@ -1487,7 +1487,7 @@ int ipath_register_ib_device(struct ipath_devdata *dd) idev->pma_counter_select[1] = IB_PMA_PORT_RCV_DATA; idev->pma_counter_select[2] = IB_PMA_PORT_XMIT_PKTS; idev->pma_counter_select[3] = IB_PMA_PORT_RCV_PKTS; - idev->pma_counter_select[4] = IB_PMA_PORT_XMIT_WAIT; + idev->pma_counter_select[5] = IB_PMA_PORT_XMIT_WAIT; idev->link_width_enabled = 3; /* 1x or 4x */ /* Snapshot current HW counters to "clear" them. */ diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_av.c b/trunk/drivers/infiniband/hw/mthca/mthca_av.c index 57cdc1bc5f50..69599455aca2 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_av.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_av.c @@ -33,6 +33,7 @@ * $Id: mthca_av.c 1349 2004-12-16 21:09:43Z roland $ */ +#include #include #include @@ -322,7 +323,7 @@ int mthca_ah_query(struct ib_ah *ibah, struct ib_ah_attr *attr) return 0; } -int mthca_init_av_table(struct mthca_dev *dev) +int __devinit mthca_init_av_table(struct mthca_dev *dev) { int err; diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_cmd.c b/trunk/drivers/infiniband/hw/mthca/mthca_cmd.c index 768df7265b81..99a94d710935 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_cmd.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_cmd.c @@ -1820,11 +1820,11 @@ int mthca_MAD_IFC(struct mthca_dev *dev, int ignore_mkey, int ignore_bkey, #define MAD_IFC_BOX_SIZE 0x400 #define MAD_IFC_MY_QPN_OFFSET 0x100 -#define MAD_IFC_RQPN_OFFSET 0x108 -#define MAD_IFC_SL_OFFSET 0x10c -#define MAD_IFC_G_PATH_OFFSET 0x10d -#define MAD_IFC_RLID_OFFSET 0x10e -#define MAD_IFC_PKEY_OFFSET 0x112 +#define MAD_IFC_RQPN_OFFSET 0x104 +#define MAD_IFC_SL_OFFSET 0x108 +#define MAD_IFC_G_PATH_OFFSET 0x109 +#define MAD_IFC_RLID_OFFSET 0x10a +#define MAD_IFC_PKEY_OFFSET 0x10e #define MAD_IFC_GRH_OFFSET 0x140 inmailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); @@ -1862,7 +1862,7 @@ int mthca_MAD_IFC(struct mthca_dev *dev, int ignore_mkey, int ignore_bkey, val = in_wc->dlid_path_bits | (in_wc->wc_flags & IB_WC_GRH ? 0x80 : 0); - MTHCA_PUT(inbox, val, MAD_IFC_G_PATH_OFFSET); + MTHCA_PUT(inbox, val, MAD_IFC_GRH_OFFSET); MTHCA_PUT(inbox, in_wc->slid, MAD_IFC_RLID_OFFSET); MTHCA_PUT(inbox, in_wc->pkey_index, MAD_IFC_PKEY_OFFSET); @@ -1870,7 +1870,7 @@ int mthca_MAD_IFC(struct mthca_dev *dev, int ignore_mkey, int ignore_bkey, if (in_grh) memcpy(inbox + MAD_IFC_GRH_OFFSET, in_grh, 40); - op_modifier |= 0x4; + op_modifier |= 0x10; in_modifier |= in_wc->slid << 16; } diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_cq.c b/trunk/drivers/infiniband/hw/mthca/mthca_cq.c index 283d50b76c3d..e393681ba7d4 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_cq.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_cq.c @@ -36,10 +36,9 @@ * $Id: mthca_cq.c 1369 2004-12-20 16:17:07Z roland $ */ +#include #include -#include - #include #include "mthca_dev.h" @@ -211,11 +210,6 @@ static inline void update_cons_index(struct mthca_dev *dev, struct mthca_cq *cq, mthca_write64(doorbell, dev->kar + MTHCA_CQ_DOORBELL, MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock)); - /* - * Make sure doorbells don't leak out of CQ spinlock - * and reach the HCA out of order: - */ - mmiowb(); } } @@ -969,7 +963,7 @@ void mthca_free_cq(struct mthca_dev *dev, mthca_free_mailbox(dev, mailbox); } -int mthca_init_cq_table(struct mthca_dev *dev) +int __devinit mthca_init_cq_table(struct mthca_dev *dev) { int err; diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_eq.c b/trunk/drivers/infiniband/hw/mthca/mthca_eq.c index 8ec9fa1ff9ea..a29b1b6d82b1 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_eq.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_eq.c @@ -33,6 +33,7 @@ * $Id: mthca_eq.c 1382 2004-12-24 02:21:02Z roland $ */ +#include #include #include #include @@ -404,7 +405,7 @@ static int mthca_eq_int(struct mthca_dev *dev, struct mthca_eq *eq) return eqes_found; } -static irqreturn_t mthca_tavor_interrupt(int irq, void *dev_ptr) +static irqreturn_t mthca_tavor_interrupt(int irq, void *dev_ptr, struct pt_regs *regs) { struct mthca_dev *dev = dev_ptr; u32 ecr; @@ -431,7 +432,8 @@ static irqreturn_t mthca_tavor_interrupt(int irq, void *dev_ptr) return IRQ_HANDLED; } -static irqreturn_t mthca_tavor_msi_x_interrupt(int irq, void *eq_ptr) +static irqreturn_t mthca_tavor_msi_x_interrupt(int irq, void *eq_ptr, + struct pt_regs *regs) { struct mthca_eq *eq = eq_ptr; struct mthca_dev *dev = eq->dev; @@ -444,7 +446,7 @@ static irqreturn_t mthca_tavor_msi_x_interrupt(int irq, void *eq_ptr) return IRQ_HANDLED; } -static irqreturn_t mthca_arbel_interrupt(int irq, void *dev_ptr) +static irqreturn_t mthca_arbel_interrupt(int irq, void *dev_ptr, struct pt_regs *regs) { struct mthca_dev *dev = dev_ptr; int work = 0; @@ -465,7 +467,8 @@ static irqreturn_t mthca_arbel_interrupt(int irq, void *dev_ptr) return IRQ_RETVAL(work); } -static irqreturn_t mthca_arbel_msi_x_interrupt(int irq, void *eq_ptr) +static irqreturn_t mthca_arbel_msi_x_interrupt(int irq, void *eq_ptr, + struct pt_regs *regs) { struct mthca_eq *eq = eq_ptr; struct mthca_dev *dev = eq->dev; @@ -478,10 +481,10 @@ static irqreturn_t mthca_arbel_msi_x_interrupt(int irq, void *eq_ptr) return IRQ_HANDLED; } -static int mthca_create_eq(struct mthca_dev *dev, - int nent, - u8 intr, - struct mthca_eq *eq) +static int __devinit mthca_create_eq(struct mthca_dev *dev, + int nent, + u8 intr, + struct mthca_eq *eq) { int npages; u64 *dma_list = NULL; @@ -663,9 +666,9 @@ static void mthca_free_irqs(struct mthca_dev *dev) dev->eq_table.eq + i); } -static int mthca_map_reg(struct mthca_dev *dev, - unsigned long offset, unsigned long size, - void __iomem **map) +static int __devinit mthca_map_reg(struct mthca_dev *dev, + unsigned long offset, unsigned long size, + void __iomem **map) { unsigned long base = pci_resource_start(dev->pdev, 0); @@ -690,7 +693,7 @@ static void mthca_unmap_reg(struct mthca_dev *dev, unsigned long offset, iounmap(map); } -static int mthca_map_eq_regs(struct mthca_dev *dev) +static int __devinit mthca_map_eq_regs(struct mthca_dev *dev) { if (mthca_is_memfree(dev)) { /* @@ -780,7 +783,7 @@ static void mthca_unmap_eq_regs(struct mthca_dev *dev) } } -int mthca_map_eq_icm(struct mthca_dev *dev, u64 icm_virt) +int __devinit mthca_map_eq_icm(struct mthca_dev *dev, u64 icm_virt) { int ret; u8 status; @@ -824,7 +827,7 @@ void mthca_unmap_eq_icm(struct mthca_dev *dev) __free_page(dev->eq_table.icm_page); } -int mthca_init_eq_table(struct mthca_dev *dev) +int __devinit mthca_init_eq_table(struct mthca_dev *dev) { int err; u8 status; diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_mad.c b/trunk/drivers/infiniband/hw/mthca/mthca_mad.c index acfa41d968ee..45e106f14807 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_mad.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_mad.c @@ -317,7 +317,7 @@ int mthca_create_agents(struct mthca_dev *dev) return ret; } -void mthca_free_agents(struct mthca_dev *dev) +void __devexit mthca_free_agents(struct mthca_dev *dev) { struct ib_mad_agent *agent; int p, q; diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_main.c b/trunk/drivers/infiniband/hw/mthca/mthca_main.c index 0491ec7a7c0a..47ea02148368 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_main.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_main.c @@ -98,7 +98,7 @@ static struct mthca_profile default_profile = { .uarc_size = 1 << 18, /* Arbel only */ }; -static int mthca_tune_pci(struct mthca_dev *mdev) +static int __devinit mthca_tune_pci(struct mthca_dev *mdev) { int cap; u16 val; @@ -143,7 +143,7 @@ static int mthca_tune_pci(struct mthca_dev *mdev) return 0; } -static int mthca_dev_lim(struct mthca_dev *mdev, struct mthca_dev_lim *dev_lim) +static int __devinit mthca_dev_lim(struct mthca_dev *mdev, struct mthca_dev_lim *dev_lim) { int err; u8 status; @@ -255,7 +255,7 @@ static int mthca_dev_lim(struct mthca_dev *mdev, struct mthca_dev_lim *dev_lim) return 0; } -static int mthca_init_tavor(struct mthca_dev *mdev) +static int __devinit mthca_init_tavor(struct mthca_dev *mdev) { u8 status; int err; @@ -333,7 +333,7 @@ static int mthca_init_tavor(struct mthca_dev *mdev) return err; } -static int mthca_load_fw(struct mthca_dev *mdev) +static int __devinit mthca_load_fw(struct mthca_dev *mdev) { u8 status; int err; @@ -379,10 +379,10 @@ static int mthca_load_fw(struct mthca_dev *mdev) return err; } -static int mthca_init_icm(struct mthca_dev *mdev, - struct mthca_dev_lim *dev_lim, - struct mthca_init_hca_param *init_hca, - u64 icm_size) +static int __devinit mthca_init_icm(struct mthca_dev *mdev, + struct mthca_dev_lim *dev_lim, + struct mthca_init_hca_param *init_hca, + u64 icm_size) { u64 aux_pages; u8 status; @@ -575,7 +575,7 @@ static void mthca_free_icms(struct mthca_dev *mdev) mthca_free_icm(mdev, mdev->fw.arbel.aux_icm); } -static int mthca_init_arbel(struct mthca_dev *mdev) +static int __devinit mthca_init_arbel(struct mthca_dev *mdev) { struct mthca_dev_lim dev_lim; struct mthca_profile profile; @@ -683,7 +683,7 @@ static void mthca_close_hca(struct mthca_dev *mdev) mthca_SYS_DIS(mdev, &status); } -static int mthca_init_hca(struct mthca_dev *mdev) +static int __devinit mthca_init_hca(struct mthca_dev *mdev) { u8 status; int err; @@ -720,7 +720,7 @@ static int mthca_init_hca(struct mthca_dev *mdev) return err; } -static int mthca_setup_hca(struct mthca_dev *dev) +static int __devinit mthca_setup_hca(struct mthca_dev *dev) { int err; u8 status; @@ -875,7 +875,8 @@ static int mthca_setup_hca(struct mthca_dev *dev) return err; } -static int mthca_request_regions(struct pci_dev *pdev, int ddr_hidden) +static int __devinit mthca_request_regions(struct pci_dev *pdev, + int ddr_hidden) { int err; @@ -927,7 +928,7 @@ static void mthca_release_regions(struct pci_dev *pdev, MTHCA_HCR_SIZE); } -static int mthca_enable_msi_x(struct mthca_dev *mdev) +static int __devinit mthca_enable_msi_x(struct mthca_dev *mdev) { struct msix_entry entries[3]; int err; @@ -1212,7 +1213,7 @@ int __mthca_restart_one(struct pci_dev *pdev) } static int __devinit mthca_init_one(struct pci_dev *pdev, - const struct pci_device_id *id) + const struct pci_device_id *id) { static int mthca_version_printed = 0; int ret; diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_mcg.c b/trunk/drivers/infiniband/hw/mthca/mthca_mcg.c index a8ad072be074..47ca8a9b7247 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_mcg.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_mcg.c @@ -32,6 +32,7 @@ * $Id: mthca_mcg.c 1349 2004-12-16 21:09:43Z roland $ */ +#include #include #include @@ -370,7 +371,7 @@ int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) return err; } -int mthca_init_mcg_table(struct mthca_dev *dev) +int __devinit mthca_init_mcg_table(struct mthca_dev *dev) { int err; int table_size = dev->limits.num_mgms + dev->limits.num_amgms; diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_mr.c b/trunk/drivers/infiniband/hw/mthca/mthca_mr.c index f71ffa88db3a..a486dec1707e 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_mr.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_mr.c @@ -34,6 +34,7 @@ */ #include +#include #include #include "mthca_dev.h" @@ -134,7 +135,7 @@ static void mthca_buddy_free(struct mthca_buddy *buddy, u32 seg, int order) spin_unlock(&buddy->lock); } -static int mthca_buddy_init(struct mthca_buddy *buddy, int max_order) +static int __devinit mthca_buddy_init(struct mthca_buddy *buddy, int max_order) { int i, s; @@ -758,7 +759,7 @@ void mthca_arbel_fmr_unmap(struct mthca_dev *dev, struct mthca_fmr *fmr) *(u8 *) fmr->mem.arbel.mpt = MTHCA_MPT_STATUS_SW; } -int mthca_init_mr_table(struct mthca_dev *dev) +int __devinit mthca_init_mr_table(struct mthca_dev *dev) { unsigned long addr; int err, i; diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_pd.c b/trunk/drivers/infiniband/hw/mthca/mthca_pd.c index c1e950764bd8..59df51614c85 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_pd.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_pd.c @@ -34,6 +34,7 @@ * $Id: mthca_pd.c 1349 2004-12-16 21:09:43Z roland $ */ +#include #include #include "mthca_dev.h" @@ -68,7 +69,7 @@ void mthca_pd_free(struct mthca_dev *dev, struct mthca_pd *pd) mthca_free(&dev->pd_table.alloc, pd->pd_num); } -int mthca_init_pd_table(struct mthca_dev *dev) +int __devinit mthca_init_pd_table(struct mthca_dev *dev) { return mthca_alloc_init(&dev->pd_table.alloc, dev->limits.num_pds, diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_provider.c b/trunk/drivers/infiniband/hw/mthca/mthca_provider.c index 21422a3336ad..981fe2eebdfa 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_provider.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_provider.c @@ -179,8 +179,6 @@ static int mthca_query_port(struct ib_device *ibdev, props->max_mtu = out_mad->data[41] & 0xf; props->active_mtu = out_mad->data[36] >> 4; props->subnet_timeout = out_mad->data[51] & 0x1f; - props->max_vl_num = out_mad->data[37] >> 4; - props->init_type_reply = out_mad->data[41] >> 4; out: kfree(in_mad); @@ -1100,10 +1098,11 @@ static struct ib_fmr *mthca_alloc_fmr(struct ib_pd *pd, int mr_access_flags, struct mthca_fmr *fmr; int err; - fmr = kmemdup(fmr_attr, sizeof *fmr, GFP_KERNEL); + fmr = kmalloc(sizeof *fmr, GFP_KERNEL); if (!fmr) return ERR_PTR(-ENOMEM); + memcpy(&fmr->attr, fmr_attr, sizeof *fmr_attr); err = mthca_fmr_alloc(to_mdev(pd->device), to_mpd(pd)->pd_num, convert_access(mr_access_flags), fmr); diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_qp.c b/trunk/drivers/infiniband/hw/mthca/mthca_qp.c index 33e3ba7937f1..5e5c58b9920b 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_qp.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_qp.c @@ -35,11 +35,10 @@ * $Id: mthca_qp.c 1355 2004-12-17 15:23:43Z roland $ */ +#include #include #include -#include - #include #include #include @@ -1733,11 +1732,6 @@ int mthca_tavor_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, mthca_write64(doorbell, dev->kar + MTHCA_SEND_DOORBELL, MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock)); - /* - * Make sure doorbells don't leak out of SQ spinlock - * and reach the HCA out of order: - */ - mmiowb(); } qp->sq.next_ind = ind; @@ -1857,12 +1851,6 @@ int mthca_tavor_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr, qp->rq.next_ind = ind; qp->rq.head += nreq; - /* - * Make sure doorbells don't leak out of RQ spinlock and reach - * the HCA out of order: - */ - mmiowb(); - spin_unlock_irqrestore(&qp->rq.lock, flags); return err; } @@ -2124,12 +2112,6 @@ int mthca_arbel_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock)); } - /* - * Make sure doorbells don't leak out of SQ spinlock and reach - * the HCA out of order: - */ - mmiowb(); - spin_unlock_irqrestore(&qp->sq.lock, flags); return err; } @@ -2240,7 +2222,7 @@ void mthca_free_err_wqe(struct mthca_dev *dev, struct mthca_qp *qp, int is_send, *new_wqe = 0; } -int mthca_init_qp_table(struct mthca_dev *dev) +int __devinit mthca_init_qp_table(struct mthca_dev *dev) { int err; u8 status; diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_srq.c b/trunk/drivers/infiniband/hw/mthca/mthca_srq.c index 34d2c4768962..0f316c87bf64 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_srq.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_srq.c @@ -35,8 +35,6 @@ #include #include -#include - #include "mthca_dev.h" #include "mthca_cmd.h" #include "mthca_memfree.h" @@ -120,7 +118,7 @@ static void mthca_arbel_init_srq_context(struct mthca_dev *dev, memset(context, 0, sizeof *context); - logsize = long_log2(srq->max); + logsize = long_log2(srq->max) + srq->wqe_shift; context->state_logsize_srqn = cpu_to_be32(logsize << 24 | srq->srqn); context->lkey = cpu_to_be32(srq->mr.ibmr.lkey); context->db_index = cpu_to_be32(srq->db_index); @@ -203,8 +201,6 @@ int mthca_alloc_srq(struct mthca_dev *dev, struct mthca_pd *pd, if (mthca_is_memfree(dev)) srq->max = roundup_pow_of_two(srq->max + 1); - else - srq->max = srq->max + 1; ds = max(64UL, roundup_pow_of_two(sizeof (struct mthca_next_seg) + @@ -281,7 +277,7 @@ int mthca_alloc_srq(struct mthca_dev *dev, struct mthca_pd *pd, srq->first_free = 0; srq->last_free = srq->max - 1; - attr->max_wr = srq->max - 1; + attr->max_wr = (mthca_is_memfree(dev)) ? srq->max - 1 : srq->max; attr->max_sge = srq->max_gs; return 0; @@ -417,7 +413,7 @@ int mthca_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *srq_attr) srq_attr->srq_limit = be16_to_cpu(tavor_ctx->limit_watermark); } - srq_attr->max_wr = srq->max - 1; + srq_attr->max_wr = (mthca_is_memfree(dev)) ? srq->max - 1 : srq->max; srq_attr->max_sge = srq->max_gs; out: @@ -597,12 +593,6 @@ int mthca_tavor_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr, MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock)); } - /* - * Make sure doorbells don't leak out of SRQ spinlock and - * reach the HCA out of order: - */ - mmiowb(); - spin_unlock_irqrestore(&srq->lock, flags); return err; } @@ -715,7 +705,7 @@ int mthca_max_srq_sge(struct mthca_dev *dev) sizeof (struct mthca_data_seg)); } -int mthca_init_srq_table(struct mthca_dev *dev) +int __devinit mthca_init_srq_table(struct mthca_dev *dev) { int err; diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib.h b/trunk/drivers/infiniband/ulp/ipoib/ipoib.h index f2b61851a49c..0b8a79d53a00 100644 --- a/trunk/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib.h @@ -233,7 +233,7 @@ static inline struct ipoib_neigh **to_ipoib_neigh(struct neighbour *neigh) } struct ipoib_neigh *ipoib_neigh_alloc(struct neighbour *neigh); -void ipoib_neigh_free(struct net_device *dev, struct ipoib_neigh *neigh); +void ipoib_neigh_free(struct ipoib_neigh *neigh); extern struct workqueue_struct *ipoib_workqueue; diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/trunk/drivers/infiniband/ulp/ipoib/ipoib_ib.c index 8bf5e9ec7c95..f426a69d9a43 100644 --- a/trunk/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib_ib.c @@ -355,11 +355,6 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb, tx_req->skb = skb; addr = dma_map_single(priv->ca->dma_device, skb->data, skb->len, DMA_TO_DEVICE); - if (unlikely(dma_mapping_error(addr))) { - ++priv->stats.tx_errors; - dev_kfree_skb_any(skb); - return; - } pci_unmap_addr_set(tx_req, mapping, addr); if (unlikely(post_send(priv, priv->tx_head & (ipoib_sendq_size - 1), diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib_main.c b/trunk/drivers/infiniband/ulp/ipoib/ipoib_main.c index 5ba3154320b4..1eaf00e9862c 100644 --- a/trunk/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -49,8 +49,6 @@ #include -#define IPOIB_QPN(ha) (be32_to_cpup((__be32 *) ha) & 0xffffff) - MODULE_AUTHOR("Roland Dreier"); MODULE_DESCRIPTION("IP-over-InfiniBand net driver"); MODULE_LICENSE("Dual BSD/GPL"); @@ -264,7 +262,7 @@ static void path_free(struct net_device *dev, struct ipoib_path *path) if (neigh->ah) ipoib_put_ah(neigh->ah); - ipoib_neigh_free(dev, neigh); + ipoib_neigh_free(neigh); } spin_unlock_irqrestore(&priv->lock, flags); @@ -522,14 +520,14 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev) memcpy(&neigh->dgid.raw, &path->pathrec.dgid.raw, sizeof(union ib_gid)); - ipoib_send(dev, skb, path->ah, IPOIB_QPN(skb->dst->neighbour->ha)); + ipoib_send(dev, skb, path->ah, + be32_to_cpup((__be32 *) skb->dst->neighbour->ha)); } else { neigh->ah = NULL; + __skb_queue_tail(&neigh->queue, skb); if (!path->query && path_rec_start(dev, path)) goto err_list; - - __skb_queue_tail(&neigh->queue, skb); } spin_unlock(&priv->lock); @@ -539,7 +537,7 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev) list_del(&neigh->list); err_path: - ipoib_neigh_free(dev, neigh); + ipoib_neigh_free(neigh); ++priv->stats.tx_dropped; dev_kfree_skb_any(skb); @@ -601,7 +599,8 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev, ipoib_dbg(priv, "Send unicast ARP to %04x\n", be16_to_cpu(path->pathrec.dlid)); - ipoib_send(dev, skb, path->ah, IPOIB_QPN(phdr->hwaddr)); + ipoib_send(dev, skb, path->ah, + be32_to_cpup((__be32 *) phdr->hwaddr)); } else if ((path->query || !path_rec_start(dev, path)) && skb_queue_len(&path->queue) < IPOIB_MAX_PATH_REC_QUEUE) { /* put pseudoheader back on for next time */ @@ -656,13 +655,14 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev) */ ipoib_put_ah(neigh->ah); list_del(&neigh->list); - ipoib_neigh_free(dev, neigh); + ipoib_neigh_free(neigh); spin_unlock(&priv->lock); ipoib_path_lookup(skb, dev); goto out; } - ipoib_send(dev, skb, neigh->ah, IPOIB_QPN(skb->dst->neighbour->ha)); + ipoib_send(dev, skb, neigh->ah, + be32_to_cpup((__be32 *) skb->dst->neighbour->ha)); goto out; } @@ -694,7 +694,7 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev) IPOIB_GID_FMT "\n", skb->dst ? "neigh" : "dst", be16_to_cpup((__be16 *) skb->data), - IPOIB_QPN(phdr->hwaddr), + be32_to_cpup((__be32 *) phdr->hwaddr), IPOIB_GID_RAW_ARG(phdr->hwaddr + 4)); dev_kfree_skb_any(skb); ++priv->stats.tx_dropped; @@ -777,7 +777,7 @@ static void ipoib_neigh_destructor(struct neighbour *n) ipoib_dbg(priv, "neigh_destructor for %06x " IPOIB_GID_FMT "\n", - IPOIB_QPN(n->ha), + be32_to_cpup((__be32 *) n->ha), IPOIB_GID_RAW_ARG(n->ha + 4)); spin_lock_irqsave(&priv->lock, flags); @@ -787,7 +787,7 @@ static void ipoib_neigh_destructor(struct neighbour *n) if (neigh->ah) ah = neigh->ah; list_del(&neigh->list); - ipoib_neigh_free(n->dev, neigh); + ipoib_neigh_free(neigh); } spin_unlock_irqrestore(&priv->lock, flags); @@ -810,15 +810,9 @@ struct ipoib_neigh *ipoib_neigh_alloc(struct neighbour *neighbour) return neigh; } -void ipoib_neigh_free(struct net_device *dev, struct ipoib_neigh *neigh) +void ipoib_neigh_free(struct ipoib_neigh *neigh) { - struct ipoib_dev_priv *priv = netdev_priv(dev); - struct sk_buff *skb; *to_ipoib_neigh(neigh->neighbour) = NULL; - while ((skb = __skb_dequeue(&neigh->queue))) { - ++priv->stats.tx_dropped; - dev_kfree_skb_any(skb); - } kfree(neigh); } diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/trunk/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index d282d65e3ee0..3faa1820f0e9 100644 --- a/trunk/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib_multicast.c @@ -114,7 +114,7 @@ static void ipoib_mcast_free(struct ipoib_mcast *mcast) */ if (neigh->ah) ipoib_put_ah(neigh->ah); - ipoib_neigh_free(dev, neigh); + ipoib_neigh_free(neigh); } spin_unlock_irqrestore(&priv->lock, flags); diff --git a/trunk/drivers/infiniband/ulp/iser/iscsi_iser.c b/trunk/drivers/infiniband/ulp/iser/iscsi_iser.c index 9b2041e25d59..eb6f98d82289 100644 --- a/trunk/drivers/infiniband/ulp/iser/iscsi_iser.c +++ b/trunk/drivers/infiniband/ulp/iser/iscsi_iser.c @@ -363,11 +363,11 @@ iscsi_iser_conn_start(struct iscsi_cls_conn *cls_conn) struct iscsi_conn *conn = cls_conn->dd_data; int err; - err = iser_conn_set_full_featured_mode(conn); + err = iscsi_conn_start(cls_conn); if (err) return err; - return iscsi_conn_start(cls_conn); + return iser_conn_set_full_featured_mode(conn); } static struct iscsi_transport iscsi_iser_transport; diff --git a/trunk/drivers/infiniband/ulp/iser/iscsi_iser.h b/trunk/drivers/infiniband/ulp/iser/iscsi_iser.h index 234e5b061a75..9c53916f28c2 100644 --- a/trunk/drivers/infiniband/ulp/iser/iscsi_iser.h +++ b/trunk/drivers/infiniband/ulp/iser/iscsi_iser.h @@ -283,7 +283,7 @@ struct iser_global { struct mutex connlist_mutex; struct list_head connlist; /* all iSER IB connections */ - struct kmem_cache *desc_cache; + kmem_cache_t *desc_cache; }; extern struct iser_global ig; diff --git a/trunk/drivers/infiniband/ulp/srp/ib_srp.c b/trunk/drivers/infiniband/ulp/srp/ib_srp.c index 64ab5fc7cca3..44b9e5be6687 100644 --- a/trunk/drivers/infiniband/ulp/srp/ib_srp.c +++ b/trunk/drivers/infiniband/ulp/srp/ib_srp.c @@ -343,32 +343,29 @@ static int srp_send_req(struct srp_target_port *target) */ if (target->io_class == SRP_REV10_IB_IO_CLASS) { memcpy(req->priv.initiator_port_id, - &target->path.sgid.global.interface_id, 8); + target->srp_host->initiator_port_id + 8, 8); memcpy(req->priv.initiator_port_id + 8, - &target->initiator_ext, 8); + target->srp_host->initiator_port_id, 8); memcpy(req->priv.target_port_id, &target->ioc_guid, 8); memcpy(req->priv.target_port_id + 8, &target->id_ext, 8); } else { memcpy(req->priv.initiator_port_id, - &target->initiator_ext, 8); - memcpy(req->priv.initiator_port_id + 8, - &target->path.sgid.global.interface_id, 8); + target->srp_host->initiator_port_id, 16); memcpy(req->priv.target_port_id, &target->id_ext, 8); memcpy(req->priv.target_port_id + 8, &target->ioc_guid, 8); } /* * Topspin/Cisco SRP targets will reject our login unless we - * zero out the first 8 bytes of our initiator port ID and set - * the second 8 bytes to the local node GUID. + * zero out the first 8 bytes of our initiator port ID. The + * second 8 bytes must be our local node GUID, but we always + * use that anyway. */ if (topspin_workarounds && !memcmp(&target->ioc_guid, topspin_oui, 3)) { printk(KERN_DEBUG PFX "Topspin/Cisco initiator port ID workaround " "activated for target GUID %016llx\n", (unsigned long long) be64_to_cpu(target->ioc_guid)); memset(req->priv.initiator_port_id, 0, 8); - memcpy(req->priv.initiator_port_id + 8, - &target->srp_host->dev->dev->node_guid, 8); } status = ib_send_cm_req(target->cm_id, &req->param); @@ -1176,11 +1173,9 @@ static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event) break; } - if (!target->rx_ring[0]) { - target->status = srp_alloc_iu_bufs(target); - if (target->status) - break; - } + target->status = srp_alloc_iu_bufs(target); + if (target->status) + break; qp_attr = kmalloc(sizeof *qp_attr, GFP_KERNEL); if (!qp_attr) { @@ -1558,7 +1553,6 @@ enum { SRP_OPT_MAX_SECT = 1 << 5, SRP_OPT_MAX_CMD_PER_LUN = 1 << 6, SRP_OPT_IO_CLASS = 1 << 7, - SRP_OPT_INITIATOR_EXT = 1 << 8, SRP_OPT_ALL = (SRP_OPT_ID_EXT | SRP_OPT_IOC_GUID | SRP_OPT_DGID | @@ -1575,7 +1569,6 @@ static match_table_t srp_opt_tokens = { { SRP_OPT_MAX_SECT, "max_sect=%d" }, { SRP_OPT_MAX_CMD_PER_LUN, "max_cmd_per_lun=%d" }, { SRP_OPT_IO_CLASS, "io_class=%x" }, - { SRP_OPT_INITIATOR_EXT, "initiator_ext=%s" }, { SRP_OPT_ERR, NULL } }; @@ -1675,12 +1668,6 @@ static int srp_parse_options(const char *buf, struct srp_target_port *target) target->io_class = token; break; - case SRP_OPT_INITIATOR_EXT: - p = match_strdup(args); - target->initiator_ext = cpu_to_be64(simple_strtoull(p, NULL, 16)); - kfree(p); - break; - default: printk(KERN_WARNING PFX "unknown parameter or missing value " "'%s' in target creation request\n", p); @@ -1718,10 +1705,10 @@ static ssize_t srp_create_target(struct class_device *class_dev, if (!target_host) return -ENOMEM; - target_host->max_lun = SRP_MAX_LUN; - target_host->max_cmd_len = sizeof ((struct srp_cmd *) (void *) 0L)->cdb; + target_host->max_lun = SRP_MAX_LUN; target = host_to_target(target_host); + memset(target, 0, sizeof *target); target->io_class = SRP_REV16A_IB_IO_CLASS; target->scsi_host = target_host; @@ -1828,6 +1815,9 @@ static struct srp_host *srp_add_port(struct srp_device *device, u8 port) host->dev = device; host->port = port; + host->initiator_port_id[7] = port; + memcpy(host->initiator_port_id + 8, &device->dev->node_guid, 8); + host->class_dev.class = &srp_class; host->class_dev.dev = device->dev->dma_device; snprintf(host->class_dev.class_id, BUS_ID_SIZE, "srp-%s-%d", diff --git a/trunk/drivers/infiniband/ulp/srp/ib_srp.h b/trunk/drivers/infiniband/ulp/srp/ib_srp.h index d4e35ef51374..5b581fb8eb0d 100644 --- a/trunk/drivers/infiniband/ulp/srp/ib_srp.h +++ b/trunk/drivers/infiniband/ulp/srp/ib_srp.h @@ -91,6 +91,7 @@ struct srp_device { }; struct srp_host { + u8 initiator_port_id[16]; struct srp_device *dev; u8 port; struct class_device class_dev; @@ -121,7 +122,6 @@ struct srp_target_port { __be64 id_ext; __be64 ioc_guid; __be64 service_id; - __be64 initiator_ext; u16 io_class; struct srp_host *srp_host; struct Scsi_Host *scsi_host; diff --git a/trunk/drivers/input/gameport/fm801-gp.c b/trunk/drivers/input/gameport/fm801-gp.c index 1dec00e20dbc..90de5afe03c2 100644 --- a/trunk/drivers/input/gameport/fm801-gp.c +++ b/trunk/drivers/input/gameport/fm801-gp.c @@ -82,19 +82,17 @@ static int __devinit fm801_gp_probe(struct pci_dev *pci, const struct pci_device { struct fm801_gp *gp; struct gameport *port; - int error; gp = kzalloc(sizeof(struct fm801_gp), GFP_KERNEL); port = gameport_allocate_port(); if (!gp || !port) { printk(KERN_ERR "fm801-gp: Memory allocation failed\n"); - error = -ENOMEM; - goto err_out_free; + kfree(gp); + gameport_free_port(port); + return -ENOMEM; } - error = pci_enable_device(pci); - if (error) - goto err_out_free; + pci_enable_device(pci); port->open = fm801_gp_open; #ifdef HAVE_COOKED @@ -110,8 +108,9 @@ static int __devinit fm801_gp_probe(struct pci_dev *pci, const struct pci_device if (!gp->res_port) { printk(KERN_DEBUG "fm801-gp: unable to grab region 0x%x-0x%x\n", port->io, port->io + 0x0f); - error = -EBUSY; - goto err_out_disable_dev; + gameport_free_port(port); + kfree(gp); + return -EBUSY; } pci_set_drvdata(pci, gp); @@ -120,13 +119,6 @@ static int __devinit fm801_gp_probe(struct pci_dev *pci, const struct pci_device gameport_register_port(port); return 0; - - err_out_disable_dev: - pci_disable_device(pci); - err_out_free: - gameport_free_port(port); - kfree(gp); - return error; } static void __devexit fm801_gp_remove(struct pci_dev *pci) diff --git a/trunk/drivers/input/gameport/gameport.c b/trunk/drivers/input/gameport/gameport.c index a0af97efe6ac..3f47ae55c6f3 100644 --- a/trunk/drivers/input/gameport/gameport.c +++ b/trunk/drivers/input/gameport/gameport.c @@ -191,8 +191,6 @@ static void gameport_run_poll_handler(unsigned long d) static void gameport_bind_driver(struct gameport *gameport, struct gameport_driver *drv) { - int error; - down_write(&gameport_bus.subsys.rwsem); gameport->dev.driver = &drv->driver; @@ -200,20 +198,8 @@ static void gameport_bind_driver(struct gameport *gameport, struct gameport_driv gameport->dev.driver = NULL; goto out; } - - error = device_bind_driver(&gameport->dev); - if (error) { - printk(KERN_WARNING - "gameport: device_bind_driver() failed " - "for %s (%s) and %s, error: %d\n", - gameport->phys, gameport->name, - drv->description, error); - drv->disconnect(gameport); - gameport->dev.driver = NULL; - goto out; - } - - out: + device_bind_driver(&gameport->dev); +out: up_write(&gameport_bus.subsys.rwsem); } diff --git a/trunk/drivers/input/joystick/amijoy.c b/trunk/drivers/input/joystick/amijoy.c index 650acf3a30b7..7249d324297b 100644 --- a/trunk/drivers/input/joystick/amijoy.c +++ b/trunk/drivers/input/joystick/amijoy.c @@ -57,7 +57,7 @@ static DEFINE_MUTEX(amijoy_mutex); static struct input_dev *amijoy_dev[2]; static char *amijoy_phys[2] = { "amijoy/input0", "amijoy/input1" }; -static irqreturn_t amijoy_interrupt(int irq, void *dummy) +static irqreturn_t amijoy_interrupt(int irq, void *dummy, struct pt_regs *fp) { int i, data = 0, button = 0; @@ -69,6 +69,8 @@ static irqreturn_t amijoy_interrupt(int irq, void *dummy) case 1: data = ~amiga_custom.joy1dat; button = (~ciaa.pra >> 7) & 1; break; } + input_regs(amijoy_dev[i], fp); + input_report_key(amijoy_dev[i], BTN_TRIGGER, button); input_report_abs(amijoy_dev[i], ABS_X, ((data >> 1) & 1) - ((data >> 9) & 1)); diff --git a/trunk/drivers/input/joystick/iforce/iforce-packets.c b/trunk/drivers/input/joystick/iforce/iforce-packets.c index 808f05932a6f..8632d47a7fbe 100644 --- a/trunk/drivers/input/joystick/iforce/iforce-packets.c +++ b/trunk/drivers/input/joystick/iforce/iforce-packets.c @@ -155,7 +155,7 @@ static int mark_core_as_ready(struct iforce *iforce, unsigned short addr) return -1; } -void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data) +void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data, struct pt_regs *regs) { struct input_dev *dev = iforce->dev; int i; @@ -183,6 +183,9 @@ void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data) case 0x01: /* joystick position data */ case 0x03: /* wheel position data */ + + input_regs(dev, regs); + if (HI(cmd) == 1) { input_report_abs(dev, ABS_X, (__s16) (((__s16)data[1] << 8) | data[0])); input_report_abs(dev, ABS_Y, (__s16) (((__s16)data[3] << 8) | data[2])); @@ -221,6 +224,7 @@ void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data) break; case 0x02: /* status report */ + input_regs(dev, regs); input_report_key(dev, BTN_DEAD, data[0] & 0x02); input_sync(dev); diff --git a/trunk/drivers/input/joystick/iforce/iforce-serio.c b/trunk/drivers/input/joystick/iforce/iforce-serio.c index ca08f45c2040..64a78c515484 100644 --- a/trunk/drivers/input/joystick/iforce/iforce-serio.c +++ b/trunk/drivers/input/joystick/iforce/iforce-serio.c @@ -81,7 +81,7 @@ static void iforce_serio_write_wakeup(struct serio *serio) } static irqreturn_t iforce_serio_irq(struct serio *serio, - unsigned char data, unsigned int flags) + unsigned char data, unsigned int flags, struct pt_regs *regs) { struct iforce *iforce = serio_get_drvdata(serio); @@ -115,7 +115,7 @@ static irqreturn_t iforce_serio_irq(struct serio *serio, } if (iforce->idx == iforce->len) { - iforce_process_packet(iforce, (iforce->id << 8) | iforce->idx, iforce->data); + iforce_process_packet(iforce, (iforce->id << 8) | iforce->idx, iforce->data, regs); iforce->pkt = 0; iforce->id = 0; iforce->len = 0; diff --git a/trunk/drivers/input/joystick/iforce/iforce-usb.c b/trunk/drivers/input/joystick/iforce/iforce-usb.c index 80cdebcbcb99..fe79d158456d 100644 --- a/trunk/drivers/input/joystick/iforce/iforce-usb.c +++ b/trunk/drivers/input/joystick/iforce/iforce-usb.c @@ -74,7 +74,7 @@ void iforce_usb_xmit(struct iforce *iforce) spin_unlock_irqrestore(&iforce->xmit_lock, flags); } -static void iforce_usb_irq(struct urb *urb) +static void iforce_usb_irq(struct urb *urb, struct pt_regs *regs) { struct iforce *iforce = urb->context; int status; @@ -96,7 +96,7 @@ static void iforce_usb_irq(struct urb *urb) } iforce_process_packet(iforce, - (iforce->data[0] << 8) | (urb->actual_length - 1), iforce->data + 1); + (iforce->data[0] << 8) | (urb->actual_length - 1), iforce->data + 1, regs); exit: status = usb_submit_urb (urb, GFP_ATOMIC); @@ -105,7 +105,7 @@ static void iforce_usb_irq(struct urb *urb) __FUNCTION__, status); } -static void iforce_usb_out(struct urb *urb) +static void iforce_usb_out(struct urb *urb, struct pt_regs *regs) { struct iforce *iforce = urb->context; @@ -119,7 +119,7 @@ static void iforce_usb_out(struct urb *urb) wake_up(&iforce->wait); } -static void iforce_usb_ctrl(struct urb *urb) +static void iforce_usb_ctrl(struct urb *urb, struct pt_regs *regs) { struct iforce *iforce = urb->context; if (urb->status) return; @@ -178,9 +178,9 @@ static int iforce_usb_probe(struct usb_interface *intf, fail: if (iforce) { - usb_free_urb(iforce->irq); - usb_free_urb(iforce->out); - usb_free_urb(iforce->ctrl); + if (iforce->irq) usb_free_urb(iforce->irq); + if (iforce->out) usb_free_urb(iforce->out); + if (iforce->ctrl) usb_free_urb(iforce->ctrl); kfree(iforce); } diff --git a/trunk/drivers/input/joystick/iforce/iforce.h b/trunk/drivers/input/joystick/iforce/iforce.h index ffaeaefa1a42..947df2739843 100644 --- a/trunk/drivers/input/joystick/iforce/iforce.h +++ b/trunk/drivers/input/joystick/iforce/iforce.h @@ -160,7 +160,7 @@ void iforce_delete_device(struct iforce *iforce); /* iforce-packets.c */ int iforce_control_playback(struct iforce*, u16 id, unsigned int); -void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data); +void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data, struct pt_regs *regs); int iforce_send_packet(struct iforce *iforce, u16 cmd, unsigned char* data); void iforce_dump_packet(char *msg, u16 cmd, unsigned char *data) ; int iforce_get_id_packet(struct iforce *iforce, char *packet); diff --git a/trunk/drivers/input/joystick/magellan.c b/trunk/drivers/input/joystick/magellan.c index e3d19444ba2e..168b1061a03b 100644 --- a/trunk/drivers/input/joystick/magellan.c +++ b/trunk/drivers/input/joystick/magellan.c @@ -82,7 +82,7 @@ static int magellan_crunch_nibbles(unsigned char *data, int count) return 0; } -static void magellan_process_packet(struct magellan* magellan) +static void magellan_process_packet(struct magellan* magellan, struct pt_regs *regs) { struct input_dev *dev = magellan->dev; unsigned char *data = magellan->data; @@ -90,6 +90,8 @@ static void magellan_process_packet(struct magellan* magellan) if (!magellan->idx) return; + input_regs(dev, regs); + switch (magellan->data[0]) { case 'd': /* Axis data */ @@ -113,12 +115,12 @@ static void magellan_process_packet(struct magellan* magellan) } static irqreturn_t magellan_interrupt(struct serio *serio, - unsigned char data, unsigned int flags) + unsigned char data, unsigned int flags, struct pt_regs *regs) { struct magellan* magellan = serio_get_drvdata(serio); if (data == '\r') { - magellan_process_packet(magellan); + magellan_process_packet(magellan, regs); magellan->idx = 0; } else { if (magellan->idx < MAGELLAN_MAX_LENGTH) diff --git a/trunk/drivers/input/joystick/spaceball.c b/trunk/drivers/input/joystick/spaceball.c index 2a9808cf826f..7a19ee052972 100644 --- a/trunk/drivers/input/joystick/spaceball.c +++ b/trunk/drivers/input/joystick/spaceball.c @@ -82,7 +82,7 @@ struct spaceball { * SpaceBall. */ -static void spaceball_process_packet(struct spaceball* spaceball) +static void spaceball_process_packet(struct spaceball* spaceball, struct pt_regs *regs) { struct input_dev *dev = spaceball->dev; unsigned char *data = spaceball->data; @@ -90,6 +90,8 @@ static void spaceball_process_packet(struct spaceball* spaceball) if (spaceball->idx < 2) return; + input_regs(dev, regs); + switch (spaceball->data[0]) { case 'D': /* Ball data */ @@ -149,13 +151,13 @@ static void spaceball_process_packet(struct spaceball* spaceball) */ static irqreturn_t spaceball_interrupt(struct serio *serio, - unsigned char data, unsigned int flags) + unsigned char data, unsigned int flags, struct pt_regs *regs) { struct spaceball *spaceball = serio_get_drvdata(serio); switch (data) { case 0xd: - spaceball_process_packet(spaceball); + spaceball_process_packet(spaceball, regs); spaceball->idx = 0; spaceball->escape = 0; break; diff --git a/trunk/drivers/input/joystick/spaceorb.c b/trunk/drivers/input/joystick/spaceorb.c index c4db0247c5fb..3e2782e79834 100644 --- a/trunk/drivers/input/joystick/spaceorb.c +++ b/trunk/drivers/input/joystick/spaceorb.c @@ -74,7 +74,7 @@ static unsigned char *spaceorb_errors[] = { "EEPROM storing 0 failed", "Receive * SpaceOrb. */ -static void spaceorb_process_packet(struct spaceorb *spaceorb) +static void spaceorb_process_packet(struct spaceorb *spaceorb, struct pt_regs *regs) { struct input_dev *dev = spaceorb->dev; unsigned char *data = spaceorb->data; @@ -86,6 +86,8 @@ static void spaceorb_process_packet(struct spaceorb *spaceorb) for (i = 0; i < spaceorb->idx; i++) c ^= data[i]; if (c) return; + input_regs(dev, regs); + switch (data[0]) { case 'R': /* Reset packet */ @@ -129,12 +131,12 @@ static void spaceorb_process_packet(struct spaceorb *spaceorb) } static irqreturn_t spaceorb_interrupt(struct serio *serio, - unsigned char data, unsigned int flags) + unsigned char data, unsigned int flags, struct pt_regs *regs) { struct spaceorb* spaceorb = serio_get_drvdata(serio); if (~data & 0x80) { - if (spaceorb->idx) spaceorb_process_packet(spaceorb); + if (spaceorb->idx) spaceorb_process_packet(spaceorb, regs); spaceorb->idx = 0; } if (spaceorb->idx < SPACEORB_MAX_LENGTH) diff --git a/trunk/drivers/input/joystick/stinger.c b/trunk/drivers/input/joystick/stinger.c index 1ffb03223311..011ec4858e15 100644 --- a/trunk/drivers/input/joystick/stinger.c +++ b/trunk/drivers/input/joystick/stinger.c @@ -64,13 +64,15 @@ struct stinger { * Stinger. It updates the data accordingly. */ -static void stinger_process_packet(struct stinger *stinger) +static void stinger_process_packet(struct stinger *stinger, struct pt_regs *regs) { struct input_dev *dev = stinger->dev; unsigned char *data = stinger->data; if (!stinger->idx) return; + input_regs(dev, regs); + input_report_key(dev, BTN_A, ((data[0] & 0x20) >> 5)); input_report_key(dev, BTN_B, ((data[0] & 0x10) >> 4)); input_report_key(dev, BTN_C, ((data[0] & 0x08) >> 3)); @@ -97,7 +99,7 @@ static void stinger_process_packet(struct stinger *stinger) */ static irqreturn_t stinger_interrupt(struct serio *serio, - unsigned char data, unsigned int flags) + unsigned char data, unsigned int flags, struct pt_regs *regs) { struct stinger *stinger = serio_get_drvdata(serio); @@ -107,7 +109,7 @@ static irqreturn_t stinger_interrupt(struct serio *serio, stinger->data[stinger->idx++] = data; if (stinger->idx == 4) { - stinger_process_packet(stinger); + stinger_process_packet(stinger, regs); stinger->idx = 0; } diff --git a/trunk/drivers/input/joystick/twidjoy.c b/trunk/drivers/input/joystick/twidjoy.c index 49085df2d631..076f237d9654 100644 --- a/trunk/drivers/input/joystick/twidjoy.c +++ b/trunk/drivers/input/joystick/twidjoy.c @@ -104,7 +104,7 @@ struct twidjoy { * Twiddler. It updates the data accordingly. */ -static void twidjoy_process_packet(struct twidjoy *twidjoy) +static void twidjoy_process_packet(struct twidjoy *twidjoy, struct pt_regs *regs) { struct input_dev *dev = twidjoy->dev; unsigned char *data = twidjoy->data; @@ -113,6 +113,8 @@ static void twidjoy_process_packet(struct twidjoy *twidjoy) button_bits = ((data[1] & 0x7f) << 7) | (data[0] & 0x7f); + input_regs(dev, regs); + for (bp = twidjoy_buttons; bp->bitmask; bp++) { int value = (button_bits & (bp->bitmask << bp->bitshift)) >> bp->bitshift; int i; @@ -139,7 +141,7 @@ static void twidjoy_process_packet(struct twidjoy *twidjoy) * packet processing routine. */ -static irqreturn_t twidjoy_interrupt(struct serio *serio, unsigned char data, unsigned int flags) +static irqreturn_t twidjoy_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs) { struct twidjoy *twidjoy = serio_get_drvdata(serio); @@ -156,7 +158,7 @@ static irqreturn_t twidjoy_interrupt(struct serio *serio, unsigned char data, un twidjoy->data[twidjoy->idx++] = data; if (twidjoy->idx == TWIDJOY_MAX_LENGTH) { - twidjoy_process_packet(twidjoy); + twidjoy_process_packet(twidjoy, regs); twidjoy->idx = 0; } diff --git a/trunk/drivers/input/joystick/warrior.c b/trunk/drivers/input/joystick/warrior.c index 35edea1ab955..f9c1a03214eb 100644 --- a/trunk/drivers/input/joystick/warrior.c +++ b/trunk/drivers/input/joystick/warrior.c @@ -64,13 +64,15 @@ struct warrior { * Warrior. It updates the data accordingly. */ -static void warrior_process_packet(struct warrior *warrior) +static void warrior_process_packet(struct warrior *warrior, struct pt_regs *regs) { struct input_dev *dev = warrior->dev; unsigned char *data = warrior->data; if (!warrior->idx) return; + input_regs(dev, regs); + switch ((data[0] >> 4) & 7) { case 1: /* Button data */ input_report_key(dev, BTN_TRIGGER, data[3] & 1); @@ -99,12 +101,12 @@ static void warrior_process_packet(struct warrior *warrior) */ static irqreturn_t warrior_interrupt(struct serio *serio, - unsigned char data, unsigned int flags) + unsigned char data, unsigned int flags, struct pt_regs *regs) { struct warrior *warrior = serio_get_drvdata(serio); if (data & 0x80) { - if (warrior->idx) warrior_process_packet(warrior); + if (warrior->idx) warrior_process_packet(warrior, regs); warrior->idx = 0; warrior->len = warrior_lengths[(data >> 4) & 7]; } @@ -113,7 +115,7 @@ static irqreturn_t warrior_interrupt(struct serio *serio, warrior->data[warrior->idx++] = data; if (warrior->idx == warrior->len) { - if (warrior->idx) warrior_process_packet(warrior); + if (warrior->idx) warrior_process_packet(warrior, regs); warrior->idx = 0; warrior->len = 0; } diff --git a/trunk/drivers/input/keyboard/Kconfig b/trunk/drivers/input/keyboard/Kconfig index 81a333f73010..679bde34d247 100644 --- a/trunk/drivers/input/keyboard/Kconfig +++ b/trunk/drivers/input/keyboard/Kconfig @@ -166,7 +166,7 @@ config KEYBOARD_AMIGA config KEYBOARD_HIL_OLD tristate "HP HIL keyboard support (simple driver)" - depends on GSC || HP300 + depends on GSC default y help The "Human Interface Loop" is a older, 8-channel USB-like @@ -183,7 +183,7 @@ config KEYBOARD_HIL_OLD config KEYBOARD_HIL tristate "HP HIL keyboard support" - depends on GSC || HP300 + depends on GSC default y select HP_SDC select HIL_MLC diff --git a/trunk/drivers/input/keyboard/amikbd.c b/trunk/drivers/input/keyboard/amikbd.c index 8abdbd0ee8f9..f1f9db9d282c 100644 --- a/trunk/drivers/input/keyboard/amikbd.c +++ b/trunk/drivers/input/keyboard/amikbd.c @@ -158,7 +158,7 @@ static const char *amikbd_messages[8] = { static struct input_dev *amikbd_dev; -static irqreturn_t amikbd_interrupt(int irq, void *dummy) +static irqreturn_t amikbd_interrupt(int irq, void *dummy, struct pt_regs *fp) { unsigned char scancode, down; @@ -171,6 +171,8 @@ static irqreturn_t amikbd_interrupt(int irq, void *dummy) scancode >>= 1; if (scancode < 0x78) { /* scancodes < 0x78 are keys */ + input_regs(amikbd_dev, fp); + if (scancode == 98) { /* CapsLock is a toggle switch key on Amiga */ input_report_key(amikbd_dev, scancode, 1); input_report_key(amikbd_dev, scancode, 0); diff --git a/trunk/drivers/input/keyboard/atkbd.c b/trunk/drivers/input/keyboard/atkbd.c index cbb93669d1ce..40244d4ce0f1 100644 --- a/trunk/drivers/input/keyboard/atkbd.c +++ b/trunk/drivers/input/keyboard/atkbd.c @@ -221,7 +221,6 @@ struct atkbd { unsigned long xl_bit; unsigned int last; unsigned long time; - unsigned long err_count; struct work_struct event_work; struct mutex event_mutex; @@ -235,13 +234,11 @@ static ssize_t atkbd_attr_set_helper(struct device *dev, const char *buf, size_t #define ATKBD_DEFINE_ATTR(_name) \ static ssize_t atkbd_show_##_name(struct atkbd *, char *); \ static ssize_t atkbd_set_##_name(struct atkbd *, const char *, size_t); \ -static ssize_t atkbd_do_show_##_name(struct device *d, \ - struct device_attribute *attr, char *b) \ +static ssize_t atkbd_do_show_##_name(struct device *d, struct device_attribute *attr, char *b) \ { \ return atkbd_attr_show_helper(d, b, atkbd_show_##_name); \ } \ -static ssize_t atkbd_do_set_##_name(struct device *d, \ - struct device_attribute *attr, const char *b, size_t s) \ +static ssize_t atkbd_do_set_##_name(struct device *d, struct device_attribute *attr, const char *b, size_t s) \ { \ return atkbd_attr_set_helper(d, b, s, atkbd_set_##_name); \ } \ @@ -254,32 +251,6 @@ ATKBD_DEFINE_ATTR(set); ATKBD_DEFINE_ATTR(softrepeat); ATKBD_DEFINE_ATTR(softraw); -#define ATKBD_DEFINE_RO_ATTR(_name) \ -static ssize_t atkbd_show_##_name(struct atkbd *, char *); \ -static ssize_t atkbd_do_show_##_name(struct device *d, \ - struct device_attribute *attr, char *b) \ -{ \ - return atkbd_attr_show_helper(d, b, atkbd_show_##_name); \ -} \ -static struct device_attribute atkbd_attr_##_name = \ - __ATTR(_name, S_IRUGO, atkbd_do_show_##_name, NULL); - -ATKBD_DEFINE_RO_ATTR(err_count); - -static struct attribute *atkbd_attributes[] = { - &atkbd_attr_extra.attr, - &atkbd_attr_scroll.attr, - &atkbd_attr_set.attr, - &atkbd_attr_softrepeat.attr, - &atkbd_attr_softraw.attr, - &atkbd_attr_err_count.attr, - NULL -}; - -static struct attribute_group atkbd_attribute_group = { - .attrs = atkbd_attributes, -}; - static const unsigned int xl_table[] = { ATKBD_RET_BAT, ATKBD_RET_ERR, ATKBD_RET_ACK, ATKBD_RET_NAK, ATKBD_RET_HANJA, ATKBD_RET_HANGEUL, @@ -347,7 +318,7 @@ static unsigned int atkbd_compat_scancode(struct atkbd *atkbd, unsigned int code */ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, - unsigned int flags) + unsigned int flags, struct pt_regs *regs) { struct atkbd *atkbd = serio_get_drvdata(serio); struct input_dev *dev = atkbd->dev; @@ -425,10 +396,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, add_release_event = 1; break; case ATKBD_RET_ERR: - atkbd->err_count++; -#ifdef ATKBD_DEBUG printk(KERN_DEBUG "atkbd.c: Keyboard on %s reports too many keys pressed.\n", serio->phys); -#endif goto out; } @@ -490,6 +458,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, atkbd->time = jiffies + msecs_to_jiffies(dev->rep[REP_DELAY]) / 2; } + input_regs(dev, regs); input_event(dev, EV_KEY, keycode, value); input_sync(dev); @@ -500,6 +469,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, } if (atkbd->scroll) { + input_regs(dev, regs); if (click != -1) input_report_key(dev, BTN_MIDDLE, click); input_report_rel(dev, REL_WHEEL, scroll); @@ -818,7 +788,12 @@ static void atkbd_disconnect(struct serio *serio) synchronize_sched(); /* Allow atkbd_interrupt()s to complete. */ flush_scheduled_work(); - sysfs_remove_group(&serio->dev.kobj, &atkbd_attribute_group); + device_remove_file(&serio->dev, &atkbd_attr_extra); + device_remove_file(&serio->dev, &atkbd_attr_scroll); + device_remove_file(&serio->dev, &atkbd_attr_set); + device_remove_file(&serio->dev, &atkbd_attr_softrepeat); + device_remove_file(&serio->dev, &atkbd_attr_softraw); + input_unregister_device(atkbd->dev); serio_close(serio); serio_set_drvdata(serio, NULL); @@ -988,7 +963,11 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv) atkbd_set_keycode_table(atkbd); atkbd_set_device_attrs(atkbd); - sysfs_create_group(&serio->dev.kobj, &atkbd_attribute_group); + device_create_file(&serio->dev, &atkbd_attr_extra); + device_create_file(&serio->dev, &atkbd_attr_scroll); + device_create_file(&serio->dev, &atkbd_attr_set); + device_create_file(&serio->dev, &atkbd_attr_softrepeat); + device_create_file(&serio->dev, &atkbd_attr_softraw); atkbd_enable(atkbd); @@ -1282,11 +1261,6 @@ static ssize_t atkbd_set_softraw(struct atkbd *atkbd, const char *buf, size_t co return count; } -static ssize_t atkbd_show_err_count(struct atkbd *atkbd, char *buf) -{ - return sprintf(buf, "%lu\n", atkbd->err_count); -} - static int __init atkbd_init(void) { diff --git a/trunk/drivers/input/keyboard/corgikbd.c b/trunk/drivers/input/keyboard/corgikbd.c index befdd6006b50..1e03153b9bca 100644 --- a/trunk/drivers/input/keyboard/corgikbd.c +++ b/trunk/drivers/input/keyboard/corgikbd.c @@ -129,7 +129,7 @@ static inline void corgikbd_reset_col(int col) */ /* Scan the hardware keyboard and push any changes up through the input layer */ -static void corgikbd_scankeyboard(struct corgikbd *corgikbd_data) +static void corgikbd_scankeyboard(struct corgikbd *corgikbd_data, struct pt_regs *regs) { unsigned int row, col, rowd; unsigned long flags; @@ -140,6 +140,9 @@ static void corgikbd_scankeyboard(struct corgikbd *corgikbd_data) spin_lock_irqsave(&corgikbd_data->lock, flags); + if (regs) + input_regs(corgikbd_data->input, regs); + num_pressed = 0; for (col = 0; col < KB_COLS; col++) { /* @@ -188,14 +191,14 @@ static void corgikbd_scankeyboard(struct corgikbd *corgikbd_data) /* * corgi keyboard interrupt handler. */ -static irqreturn_t corgikbd_interrupt(int irq, void *dev_id) +static irqreturn_t corgikbd_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct corgikbd *corgikbd_data = dev_id; if (!timer_pending(&corgikbd_data->timer)) { /** wait chattering delay **/ udelay(20); - corgikbd_scankeyboard(corgikbd_data); + corgikbd_scankeyboard(corgikbd_data, regs); } return IRQ_HANDLED; @@ -207,7 +210,7 @@ static irqreturn_t corgikbd_interrupt(int irq, void *dev_id) static void corgikbd_timer_callback(unsigned long data) { struct corgikbd *corgikbd_data = (struct corgikbd *) data; - corgikbd_scankeyboard(corgikbd_data); + corgikbd_scankeyboard(corgikbd_data, NULL); } /* diff --git a/trunk/drivers/input/keyboard/hil_kbd.c b/trunk/drivers/input/keyboard/hil_kbd.c index e774dd31e99b..2e4abdc26367 100644 --- a/trunk/drivers/input/keyboard/hil_kbd.c +++ b/trunk/drivers/input/keyboard/hil_kbd.c @@ -198,7 +198,7 @@ static void hil_kbd_process_err(struct hil_kbd *kbd) { } static irqreturn_t hil_kbd_interrupt(struct serio *serio, - unsigned char data, unsigned int flags) + unsigned char data, unsigned int flags, struct pt_regs *regs) { struct hil_kbd *kbd; hil_packet packet; @@ -328,7 +328,7 @@ static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv) kbd->dev->id.vendor = PCI_VENDOR_ID_HP; kbd->dev->id.product = 0x0001; /* TODO: get from kbd->rsc */ kbd->dev->id.version = 0x0100; /* TODO: get from kbd->rsc */ - kbd->dev->cdev.dev = &serio->dev; + kbd->dev->dev = &serio->dev; for (i = 0; i < 128; i++) { set_bit(hil_kbd_set1[i], kbd->dev->keybit); diff --git a/trunk/drivers/input/keyboard/hilkbd.c b/trunk/drivers/input/keyboard/hilkbd.c index 54bc569db4b0..d22c7c624296 100644 --- a/trunk/drivers/input/keyboard/hilkbd.c +++ b/trunk/drivers/input/keyboard/hilkbd.c @@ -150,7 +150,7 @@ static inline void handle_data(unsigned char s, unsigned char c) /* * Handle HIL interrupts. */ -static irqreturn_t hil_interrupt(int irq, void *handle) +static irqreturn_t hil_interrupt(int irq, void *handle, struct pt_regs *regs) { unsigned char s, c; diff --git a/trunk/drivers/input/keyboard/lkkbd.c b/trunk/drivers/input/keyboard/lkkbd.c index 979b93e33da7..5174224cadb4 100644 --- a/trunk/drivers/input/keyboard/lkkbd.c +++ b/trunk/drivers/input/keyboard/lkkbd.c @@ -59,6 +59,11 @@ * 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 + * + * Should you need to contact me, the author, you can do so either by + * email or by paper mail: + * Jan-Benedict Glaw, Lilienstraße 16, 33790 Hörste (near Halle/Westf.), + * Germany. */ #include @@ -448,7 +453,8 @@ lkkbd_detection_done (struct lkkbd *lk) * is received. */ static irqreturn_t -lkkbd_interrupt (struct serio *serio, unsigned char data, unsigned int flags) +lkkbd_interrupt (struct serio *serio, unsigned char data, unsigned int flags, + struct pt_regs *regs) { struct lkkbd *lk = serio_get_drvdata (serio); int i; @@ -467,6 +473,7 @@ lkkbd_interrupt (struct serio *serio, unsigned char data, unsigned int flags) switch (data) { case LK_ALL_KEYS_UP: + input_regs (lk->dev, regs); for (i = 0; i < ARRAY_SIZE (lkkbd_keycode); i++) if (lk->keycode[i] != KEY_RESERVED) input_report_key (lk->dev, lk->keycode[i], 0); @@ -494,6 +501,7 @@ lkkbd_interrupt (struct serio *serio, unsigned char data, unsigned int flags) default: if (lk->keycode[data] != KEY_RESERVED) { + input_regs (lk->dev, regs); if (!test_bit (lk->keycode[data], lk->dev->key)) input_report_key (lk->dev, lk->keycode[data], 1); else diff --git a/trunk/drivers/input/keyboard/locomokbd.c b/trunk/drivers/input/keyboard/locomokbd.c index 5788dbc317bb..83906f80ba21 100644 --- a/trunk/drivers/input/keyboard/locomokbd.c +++ b/trunk/drivers/input/keyboard/locomokbd.c @@ -126,7 +126,7 @@ static inline void locomokbd_reset_col(unsigned long membase, int col) */ /* Scan the hardware keyboard and push any changes up through the input layer */ -static void locomokbd_scankeyboard(struct locomokbd *locomokbd) +static void locomokbd_scankeyboard(struct locomokbd *locomokbd, struct pt_regs *regs) { unsigned int row, col, rowd, scancode; unsigned long flags; @@ -135,6 +135,8 @@ static void locomokbd_scankeyboard(struct locomokbd *locomokbd) spin_lock_irqsave(&locomokbd->lock, flags); + input_regs(locomokbd->input, regs); + locomokbd_charge_all(membase); num_pressed = 0; @@ -169,13 +171,13 @@ static void locomokbd_scankeyboard(struct locomokbd *locomokbd) /* * LoCoMo keyboard interrupt handler. */ -static irqreturn_t locomokbd_interrupt(int irq, void *dev_id) +static irqreturn_t locomokbd_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct locomokbd *locomokbd = dev_id; /** wait chattering delay **/ udelay(100); - locomokbd_scankeyboard(locomokbd); + locomokbd_scankeyboard(locomokbd, regs); return IRQ_HANDLED; } @@ -186,7 +188,7 @@ static irqreturn_t locomokbd_interrupt(int irq, void *dev_id) static void locomokbd_timer_callback(unsigned long data) { struct locomokbd *locomokbd = (struct locomokbd *) data; - locomokbd_scankeyboard(locomokbd); + locomokbd_scankeyboard(locomokbd, NULL); } static int locomokbd_probe(struct locomo_dev *dev) diff --git a/trunk/drivers/input/keyboard/newtonkbd.c b/trunk/drivers/input/keyboard/newtonkbd.c index 9282e4e082bd..40a3f551247e 100644 --- a/trunk/drivers/input/keyboard/newtonkbd.c +++ b/trunk/drivers/input/keyboard/newtonkbd.c @@ -65,12 +65,13 @@ struct nkbd { }; static irqreturn_t nkbd_interrupt(struct serio *serio, - unsigned char data, unsigned int flags) + unsigned char data, unsigned int flags, struct pt_regs *regs) { struct nkbd *nkbd = serio_get_drvdata(serio); /* invalid scan codes are probably the init sequence, so we ignore them */ if (nkbd->keycode[data & NKBD_KEY]) { + input_regs(nkbd->dev, regs); input_report_key(nkbd->dev, nkbd->keycode[data & NKBD_KEY], data & NKBD_PRESS); input_sync(nkbd->dev); } diff --git a/trunk/drivers/input/keyboard/omap-keypad.c b/trunk/drivers/input/keyboard/omap-keypad.c index 5680a6d95b2b..d436287d1d2e 100644 --- a/trunk/drivers/input/keyboard/omap-keypad.c +++ b/trunk/drivers/input/keyboard/omap-keypad.c @@ -97,7 +97,8 @@ static u8 get_row_gpio_val(struct omap_kp *omap_kp) #define get_row_gpio_val(x) 0 #endif -static irqreturn_t omap_kp_interrupt(int irq, void *dev_id) +static irqreturn_t omap_kp_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { struct omap_kp *omap_kp = dev_id; diff --git a/trunk/drivers/input/keyboard/spitzkbd.c b/trunk/drivers/input/keyboard/spitzkbd.c index 28b2748e82d0..e385710233f4 100644 --- a/trunk/drivers/input/keyboard/spitzkbd.c +++ b/trunk/drivers/input/keyboard/spitzkbd.c @@ -176,7 +176,7 @@ static inline int spitzkbd_get_row_status(int col) */ /* Scan the hardware keyboard and push any changes up through the input layer */ -static void spitzkbd_scankeyboard(struct spitzkbd *spitzkbd_data) +static void spitzkbd_scankeyboard(struct spitzkbd *spitzkbd_data, struct pt_regs *regs) { unsigned int row, col, rowd; unsigned long flags; @@ -187,6 +187,8 @@ static void spitzkbd_scankeyboard(struct spitzkbd *spitzkbd_data) spin_lock_irqsave(&spitzkbd_data->lock, flags); + input_regs(spitzkbd_data->input, regs); + num_pressed = 0; for (col = 0; col < KB_COLS; col++) { /* @@ -237,14 +239,14 @@ static void spitzkbd_scankeyboard(struct spitzkbd *spitzkbd_data) /* * spitz keyboard interrupt handler. */ -static irqreturn_t spitzkbd_interrupt(int irq, void *dev_id) +static irqreturn_t spitzkbd_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct spitzkbd *spitzkbd_data = dev_id; if (!timer_pending(&spitzkbd_data->timer)) { /** wait chattering delay **/ udelay(20); - spitzkbd_scankeyboard(spitzkbd_data); + spitzkbd_scankeyboard(spitzkbd_data, regs); } return IRQ_HANDLED; @@ -257,7 +259,7 @@ static void spitzkbd_timer_callback(unsigned long data) { struct spitzkbd *spitzkbd_data = (struct spitzkbd *) data; - spitzkbd_scankeyboard(spitzkbd_data); + spitzkbd_scankeyboard(spitzkbd_data, NULL); } /* @@ -265,7 +267,7 @@ static void spitzkbd_timer_callback(unsigned long data) * We debounce the switches and pass them to the input system. */ -static irqreturn_t spitzkbd_hinge_isr(int irq, void *dev_id) +static irqreturn_t spitzkbd_hinge_isr(int irq, void *dev_id, struct pt_regs *regs) { struct spitzkbd *spitzkbd_data = dev_id; diff --git a/trunk/drivers/input/keyboard/stowaway.c b/trunk/drivers/input/keyboard/stowaway.c index e60937d17b1c..04c54c57f25c 100644 --- a/trunk/drivers/input/keyboard/stowaway.c +++ b/trunk/drivers/input/keyboard/stowaway.c @@ -71,12 +71,13 @@ struct skbd { }; static irqreturn_t skbd_interrupt(struct serio *serio, unsigned char data, - unsigned int flags) + unsigned int flags, struct pt_regs *regs) { struct skbd *skbd = serio_get_drvdata(serio); struct input_dev *dev = skbd->dev; if (skbd->keycode[data & SKBD_KEY_MASK]) { + input_regs(dev, regs); input_report_key(dev, skbd->keycode[data & SKBD_KEY_MASK], !(data & SKBD_RELEASE)); input_sync(dev); diff --git a/trunk/drivers/input/keyboard/sunkbd.c b/trunk/drivers/input/keyboard/sunkbd.c index cac4781103c3..9dbd7b85686d 100644 --- a/trunk/drivers/input/keyboard/sunkbd.c +++ b/trunk/drivers/input/keyboard/sunkbd.c @@ -94,7 +94,7 @@ struct sunkbd { */ static irqreturn_t sunkbd_interrupt(struct serio *serio, - unsigned char data, unsigned int flags) + unsigned char data, unsigned int flags, struct pt_regs *regs) { struct sunkbd* sunkbd = serio_get_drvdata(serio); @@ -129,6 +129,7 @@ static irqreturn_t sunkbd_interrupt(struct serio *serio, break; if (sunkbd->keycode[data & SUNKBD_KEY]) { + input_regs(sunkbd->dev, regs); input_report_key(sunkbd->dev, sunkbd->keycode[data & SUNKBD_KEY], !(data & SUNKBD_RELEASE)); input_sync(sunkbd->dev); } else { diff --git a/trunk/drivers/input/keyboard/xtkbd.c b/trunk/drivers/input/keyboard/xtkbd.c index 8c11dc935454..0821d53cf0c1 100644 --- a/trunk/drivers/input/keyboard/xtkbd.c +++ b/trunk/drivers/input/keyboard/xtkbd.c @@ -64,7 +64,7 @@ struct xtkbd { }; static irqreturn_t xtkbd_interrupt(struct serio *serio, - unsigned char data, unsigned int flags) + unsigned char data, unsigned int flags, struct pt_regs *regs) { struct xtkbd *xtkbd = serio_get_drvdata(serio); @@ -75,6 +75,7 @@ static irqreturn_t xtkbd_interrupt(struct serio *serio, default: if (xtkbd->keycode[data & XTKBD_KEY]) { + input_regs(xtkbd->dev, regs); input_report_key(xtkbd->dev, xtkbd->keycode[data & XTKBD_KEY], !(data & XTKBD_RELEASE)); input_sync(xtkbd->dev); } else { diff --git a/trunk/drivers/input/misc/Kconfig b/trunk/drivers/input/misc/Kconfig index ba0e88c64e1e..a6dfc7455733 100644 --- a/trunk/drivers/input/misc/Kconfig +++ b/trunk/drivers/input/misc/Kconfig @@ -73,7 +73,7 @@ config INPUT_UINPUT config HP_SDC_RTC tristate "HP SDC Real Time Clock" - depends on GSC || HP300 + depends on GSC select HP_SDC help Say Y here if you want to support the built-in real time clock diff --git a/trunk/drivers/input/misc/hp_sdc_rtc.c b/trunk/drivers/input/misc/hp_sdc_rtc.c index ab4da79ee560..1be963961c15 100644 --- a/trunk/drivers/input/misc/hp_sdc_rtc.c +++ b/trunk/drivers/input/misc/hp_sdc_rtc.c @@ -60,7 +60,7 @@ static struct fasync_struct *hp_sdc_rtc_async_queue; static DECLARE_WAIT_QUEUE_HEAD(hp_sdc_rtc_wait); -static ssize_t hp_sdc_rtc_read(struct file *file, char __user *buf, +static ssize_t hp_sdc_rtc_read(struct file *file, char *buf, size_t count, loff_t *ppos); static int hp_sdc_rtc_ioctl(struct inode *inode, struct file *file, @@ -385,14 +385,14 @@ static int hp_sdc_rtc_set_i8042timer (struct timeval *setto, uint8_t setcmd) return 0; } -static ssize_t hp_sdc_rtc_read(struct file *file, char __user *buf, +static ssize_t hp_sdc_rtc_read(struct file *file, char *buf, size_t count, loff_t *ppos) { ssize_t retval; if (count < sizeof(unsigned long)) return -EINVAL; - retval = put_user(68, (unsigned long __user *)buf); + retval = put_user(68, (unsigned long *)buf); return retval; } @@ -696,7 +696,7 @@ static int __init hp_sdc_rtc_init(void) if ((ret = hp_sdc_request_timer_irq(&hp_sdc_rtc_isr))) return ret; misc_register(&hp_sdc_rtc_dev); - create_proc_read_entry ("driver/rtc", 0, NULL, + create_proc_read_entry ("driver/rtc", 0, 0, hp_sdc_rtc_read_proc, NULL); printk(KERN_INFO "HP i8042 SDC + MSM-58321 RTC support loaded " diff --git a/trunk/drivers/input/misc/ixp4xx-beeper.c b/trunk/drivers/input/misc/ixp4xx-beeper.c index 105c6fc27823..805b636e73d9 100644 --- a/trunk/drivers/input/misc/ixp4xx-beeper.c +++ b/trunk/drivers/input/misc/ixp4xx-beeper.c @@ -79,7 +79,7 @@ static int ixp4xx_spkr_event(struct input_dev *dev, unsigned int type, unsigned return 0; } -static irqreturn_t ixp4xx_spkr_interrupt(int irq, void *dev_id) +static irqreturn_t ixp4xx_spkr_interrupt(int irq, void *dev_id, struct pt_regs *regs) { /* clear interrupt */ *IXP4XX_OSST = IXP4XX_OSST_TIMER_2_PEND; diff --git a/trunk/drivers/input/misc/wistron_btns.c b/trunk/drivers/input/misc/wistron_btns.c index 7b9d1c1da41a..4639537336fc 100644 --- a/trunk/drivers/input/misc/wistron_btns.c +++ b/trunk/drivers/input/misc/wistron_btns.c @@ -17,7 +17,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place Suite 330, Boston, MA 02111-1307, USA. */ -#include +#include #include #include #include diff --git a/trunk/drivers/input/mouse/Kconfig b/trunk/drivers/input/mouse/Kconfig index 35d998c3e578..f15ccf781688 100644 --- a/trunk/drivers/input/mouse/Kconfig +++ b/trunk/drivers/input/mouse/Kconfig @@ -119,7 +119,7 @@ config MOUSE_VSXXXAA config MOUSE_HIL tristate "HIL pointers (mice etc)." - depends on GSC || HP300 + depends on GSC select HP_SDC select HIL_MLC help diff --git a/trunk/drivers/input/mouse/alps.c b/trunk/drivers/input/mouse/alps.c index 4e71a66fc7fc..450b68a619fd 100644 --- a/trunk/drivers/input/mouse/alps.c +++ b/trunk/drivers/input/mouse/alps.c @@ -76,7 +76,7 @@ static const struct alps_model_info alps_model_data[] = { * on a dualpoint, etc. */ -static void alps_process_packet(struct psmouse *psmouse) +static void alps_process_packet(struct psmouse *psmouse, struct pt_regs *regs) { struct alps_data *priv = psmouse->private; unsigned char *packet = psmouse->packet; @@ -85,6 +85,8 @@ static void alps_process_packet(struct psmouse *psmouse) int x, y, z, ges, fin, left, right, middle; int back = 0, forward = 0; + input_regs(dev, regs); + if ((packet[0] & 0xc8) == 0x08) { /* 3-byte PS/2 packet */ input_report_key(dev2, BTN_LEFT, packet[0] & 1); input_report_key(dev2, BTN_RIGHT, packet[0] & 2); @@ -179,13 +181,13 @@ static void alps_process_packet(struct psmouse *psmouse) input_sync(dev); } -static psmouse_ret_t alps_process_byte(struct psmouse *psmouse) +static psmouse_ret_t alps_process_byte(struct psmouse *psmouse, struct pt_regs *regs) { struct alps_data *priv = psmouse->private; if ((psmouse->packet[0] & 0xc8) == 0x08) { /* PS/2 packet */ if (psmouse->pktcnt == 3) { - alps_process_packet(psmouse); + alps_process_packet(psmouse, regs); return PSMOUSE_FULL_PACKET; } return PSMOUSE_GOOD_DATA; @@ -200,7 +202,7 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse) return PSMOUSE_BAD_DATA; if (psmouse->pktcnt == 6) { - alps_process_packet(psmouse); + alps_process_packet(psmouse, regs); return PSMOUSE_FULL_PACKET; } diff --git a/trunk/drivers/input/mouse/amimouse.c b/trunk/drivers/input/mouse/amimouse.c index 599a7b2dc519..c8b2cc9f184c 100644 --- a/trunk/drivers/input/mouse/amimouse.c +++ b/trunk/drivers/input/mouse/amimouse.c @@ -36,7 +36,7 @@ MODULE_LICENSE("GPL"); static int amimouse_lastx, amimouse_lasty; static struct input_dev *amimouse_dev; -static irqreturn_t amimouse_interrupt(int irq, void *dummy) +static irqreturn_t amimouse_interrupt(int irq, void *dummy, struct pt_regs *fp) { unsigned short joy0dat, potgor; int nx, ny, dx, dy; @@ -59,6 +59,8 @@ static irqreturn_t amimouse_interrupt(int irq, void *dummy) potgor = amiga_custom.potgor; + input_regs(amimouse_dev, fp); + input_report_rel(amimouse_dev, REL_X, dx); input_report_rel(amimouse_dev, REL_Y, dy); diff --git a/trunk/drivers/input/mouse/hil_ptr.c b/trunk/drivers/input/mouse/hil_ptr.c index 4f2b503c1ac7..69f02178c528 100644 --- a/trunk/drivers/input/mouse/hil_ptr.c +++ b/trunk/drivers/input/mouse/hil_ptr.c @@ -190,7 +190,7 @@ static void hil_ptr_process_err(struct hil_ptr *ptr) { } static irqreturn_t hil_ptr_interrupt(struct serio *serio, - unsigned char data, unsigned int flags) + unsigned char data, unsigned int flags, struct pt_regs *regs) { struct hil_ptr *ptr; hil_packet packet; @@ -375,7 +375,7 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) ptr->dev->id.vendor = PCI_VENDOR_ID_HP; ptr->dev->id.product = 0x0001; /* TODO: get from ptr->rsc */ ptr->dev->id.version = 0x0100; /* TODO: get from ptr->rsc */ - ptr->dev->cdev.dev = &serio->dev; + ptr->dev->dev = &serio->dev; input_register_device(ptr->dev); printk(KERN_INFO "input: %s (%s), ID: %d\n", diff --git a/trunk/drivers/input/mouse/inport.c b/trunk/drivers/input/mouse/inport.c index e1252fa9a107..50f1fed10be4 100644 --- a/trunk/drivers/input/mouse/inport.c +++ b/trunk/drivers/input/mouse/inport.c @@ -88,13 +88,15 @@ __obsolete_setup("inport_irq="); static struct input_dev *inport_dev; -static irqreturn_t inport_interrupt(int irq, void *dev_id) +static irqreturn_t inport_interrupt(int irq, void *dev_id, struct pt_regs *regs) { unsigned char buttons; outb(INPORT_REG_MODE, INPORT_CONTROL_PORT); outb(INPORT_MODE_HOLD | INPORT_MODE_IRQ | INPORT_MODE_BASE, INPORT_DATA_PORT); + input_regs(inport_dev, regs); + outb(INPORT_REG_X, INPORT_CONTROL_PORT); input_report_rel(inport_dev, REL_X, inb(INPORT_DATA_PORT)); diff --git a/trunk/drivers/input/mouse/lifebook.c b/trunk/drivers/input/mouse/lifebook.c index c57e8853b949..5e9d25067513 100644 --- a/trunk/drivers/input/mouse/lifebook.c +++ b/trunk/drivers/input/mouse/lifebook.c @@ -62,7 +62,7 @@ static struct dmi_system_id lifebook_dmi_table[] = { }; -static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse) +static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse, struct pt_regs *regs) { unsigned char *packet = psmouse->packet; struct input_dev *dev = psmouse->dev; @@ -70,6 +70,8 @@ static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse) if (psmouse->pktcnt != 3) return PSMOUSE_GOOD_DATA; + input_regs(dev, regs); + /* calculate X and Y */ if ((packet[0] & 0x08) == 0x00) { input_report_abs(dev, ABS_X, diff --git a/trunk/drivers/input/mouse/logibm.c b/trunk/drivers/input/mouse/logibm.c index 8e9c2f3d69a8..9c7ce38806d7 100644 --- a/trunk/drivers/input/mouse/logibm.c +++ b/trunk/drivers/input/mouse/logibm.c @@ -79,7 +79,7 @@ __obsolete_setup("logibm_irq="); static struct input_dev *logibm_dev; -static irqreturn_t logibm_interrupt(int irq, void *dev_id) +static irqreturn_t logibm_interrupt(int irq, void *dev_id, struct pt_regs *regs) { char dx, dy; unsigned char buttons; @@ -95,6 +95,7 @@ static irqreturn_t logibm_interrupt(int irq, void *dev_id) dy |= (buttons & 0xf) << 4; buttons = ~buttons >> 5; + input_regs(logibm_dev, regs); input_report_rel(logibm_dev, REL_X, dx); input_report_rel(logibm_dev, REL_Y, dy); input_report_key(logibm_dev, BTN_RIGHT, buttons & 1); diff --git a/trunk/drivers/input/mouse/logips2pp.c b/trunk/drivers/input/mouse/logips2pp.c index 8a4f862709e7..7972eecbcfe4 100644 --- a/trunk/drivers/input/mouse/logips2pp.c +++ b/trunk/drivers/input/mouse/logips2pp.c @@ -39,7 +39,7 @@ struct ps2pp_info { * Process a PS2++ or PS2T++ packet. */ -static psmouse_ret_t ps2pp_process_byte(struct psmouse *psmouse) +static psmouse_ret_t ps2pp_process_byte(struct psmouse *psmouse, struct pt_regs *regs) { struct input_dev *dev = psmouse->dev; unsigned char *packet = psmouse->packet; @@ -51,6 +51,8 @@ static psmouse_ret_t ps2pp_process_byte(struct psmouse *psmouse) * Full packet accumulated, process it */ + input_regs(dev, regs); + if ((packet[0] & 0x48) == 0x48 && (packet[1] & 0x02) == 0x02) { /* Logitech extended packet */ diff --git a/trunk/drivers/input/mouse/pc110pad.c b/trunk/drivers/input/mouse/pc110pad.c index 8c075aa7223b..d284ea712151 100644 --- a/trunk/drivers/input/mouse/pc110pad.c +++ b/trunk/drivers/input/mouse/pc110pad.c @@ -57,7 +57,7 @@ static struct input_dev *pc110pad_dev; static int pc110pad_data[3]; static int pc110pad_count; -static irqreturn_t pc110pad_interrupt(int irq, void *ptr) +static irqreturn_t pc110pad_interrupt(int irq, void *ptr, struct pt_regs *regs) { int value = inb_p(pc110pad_io); int handshake = inb_p(pc110pad_io + 2); @@ -71,6 +71,7 @@ static irqreturn_t pc110pad_interrupt(int irq, void *ptr) if (pc110pad_count < 3) return IRQ_HANDLED; + input_regs(pc110pad_dev, regs); input_report_key(pc110pad_dev, BTN_TOUCH, pc110pad_data[0] & 0x01); input_report_abs(pc110pad_dev, ABS_X, @@ -90,9 +91,9 @@ static void pc110pad_close(struct input_dev *dev) static int pc110pad_open(struct input_dev *dev) { - pc110pad_interrupt(0, NULL); - pc110pad_interrupt(0, NULL); - pc110pad_interrupt(0, NULL); + pc110pad_interrupt(0, NULL, NULL); + pc110pad_interrupt(0, NULL, NULL); + pc110pad_interrupt(0, NULL, NULL); outb(PC110PAD_ON, pc110pad_io + 2); pc110pad_count = 0; diff --git a/trunk/drivers/input/mouse/psmouse-base.c b/trunk/drivers/input/mouse/psmouse-base.c index 6f9b2c7cc9c2..9fb7eb6b0f71 100644 --- a/trunk/drivers/input/mouse/psmouse-base.c +++ b/trunk/drivers/input/mouse/psmouse-base.c @@ -124,7 +124,7 @@ struct psmouse_protocol { * relevant events to the input module once full packet has arrived. */ -static psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse) +static psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse, struct pt_regs *regs) { struct input_dev *dev = psmouse->dev; unsigned char *packet = psmouse->packet; @@ -136,6 +136,8 @@ static psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse) * Full packet accumulated, process it */ + input_regs(dev, regs); + /* * Scroll wheel on IntelliMice, scroll buttons on NetMice */ @@ -229,9 +231,9 @@ static void psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_st * by calling corresponding protocol handler. */ -static int psmouse_handle_byte(struct psmouse *psmouse) +static int psmouse_handle_byte(struct psmouse *psmouse, struct pt_regs *regs) { - psmouse_ret_t rc = psmouse->protocol_handler(psmouse); + psmouse_ret_t rc = psmouse->protocol_handler(psmouse, regs); switch (rc) { case PSMOUSE_BAD_DATA: @@ -269,7 +271,7 @@ static int psmouse_handle_byte(struct psmouse *psmouse) */ static irqreturn_t psmouse_interrupt(struct serio *serio, - unsigned char data, unsigned int flags) + unsigned char data, unsigned int flags, struct pt_regs *regs) { struct psmouse *psmouse = serio_get_drvdata(serio); @@ -325,7 +327,7 @@ static irqreturn_t psmouse_interrupt(struct serio *serio, * Not a new device, try processing first byte normally */ psmouse->pktcnt = 1; - if (psmouse_handle_byte(psmouse)) + if (psmouse_handle_byte(psmouse, regs)) goto out; psmouse->packet[psmouse->pktcnt++] = data; @@ -344,7 +346,7 @@ static irqreturn_t psmouse_interrupt(struct serio *serio, } psmouse->last = jiffies; - psmouse_handle_byte(psmouse); + psmouse_handle_byte(psmouse, regs); out: return IRQ_HANDLED; @@ -938,7 +940,7 @@ static void psmouse_resync(void *p) psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); for (i = 0; i < psmouse->pktsize; i++) { psmouse->pktcnt++; - rc = psmouse->protocol_handler(psmouse); + rc = psmouse->protocol_handler(psmouse, NULL); if (rc != PSMOUSE_GOOD_DATA) break; } diff --git a/trunk/drivers/input/mouse/psmouse.h b/trunk/drivers/input/mouse/psmouse.h index 1b74cae8a556..4d9107fba6a1 100644 --- a/trunk/drivers/input/mouse/psmouse.h +++ b/trunk/drivers/input/mouse/psmouse.h @@ -62,7 +62,7 @@ struct psmouse { unsigned int resync_time; unsigned int smartscroll; /* Logitech only */ - psmouse_ret_t (*protocol_handler)(struct psmouse *psmouse); + psmouse_ret_t (*protocol_handler)(struct psmouse *psmouse, struct pt_regs *regs); void (*set_rate)(struct psmouse *psmouse, unsigned int rate); void (*set_resolution)(struct psmouse *psmouse, unsigned int resolution); diff --git a/trunk/drivers/input/mouse/rpcmouse.c b/trunk/drivers/input/mouse/rpcmouse.c index ea0468569610..872b30bf7aad 100644 --- a/trunk/drivers/input/mouse/rpcmouse.c +++ b/trunk/drivers/input/mouse/rpcmouse.c @@ -36,7 +36,7 @@ MODULE_LICENSE("GPL"); static short rpcmouse_lastx, rpcmouse_lasty; static struct input_dev *rpcmouse_dev; -static irqreturn_t rpcmouse_irq(int irq, void *dev_id) +static irqreturn_t rpcmouse_irq(int irq, void *dev_id, struct pt_regs *regs) { struct input_dev *dev = dev_id; short x, y, dx, dy, b; @@ -51,6 +51,8 @@ static irqreturn_t rpcmouse_irq(int irq, void *dev_id) rpcmouse_lastx = x; rpcmouse_lasty = y; + input_regs(dev, regs); + input_report_rel(dev, REL_X, dx); input_report_rel(dev, REL_Y, -dy); diff --git a/trunk/drivers/input/mouse/sermouse.c b/trunk/drivers/input/mouse/sermouse.c index 2a272c5daf08..680b32353884 100644 --- a/trunk/drivers/input/mouse/sermouse.c +++ b/trunk/drivers/input/mouse/sermouse.c @@ -61,11 +61,13 @@ struct sermouse { * second, which is as good as a PS/2 or USB mouse. */ -static void sermouse_process_msc(struct sermouse *sermouse, signed char data) +static void sermouse_process_msc(struct sermouse *sermouse, signed char data, struct pt_regs *regs) { struct input_dev *dev = sermouse->dev; signed char *buf = sermouse->buf; + input_regs(dev, regs); + switch (sermouse->count) { case 0: @@ -102,13 +104,15 @@ static void sermouse_process_msc(struct sermouse *sermouse, signed char data) * standard 3-byte packets and 1200 bps. */ -static void sermouse_process_ms(struct sermouse *sermouse, signed char data) +static void sermouse_process_ms(struct sermouse *sermouse, signed char data, struct pt_regs *regs) { struct input_dev *dev = sermouse->dev; signed char *buf = sermouse->buf; if (data & 0x40) sermouse->count = 0; + input_regs(dev, regs); + switch (sermouse->count) { case 0: @@ -202,7 +206,7 @@ static void sermouse_process_ms(struct sermouse *sermouse, signed char data) */ static irqreturn_t sermouse_interrupt(struct serio *serio, - unsigned char data, unsigned int flags) + unsigned char data, unsigned int flags, struct pt_regs *regs) { struct sermouse *sermouse = serio_get_drvdata(serio); @@ -210,9 +214,9 @@ static irqreturn_t sermouse_interrupt(struct serio *serio, sermouse->last = jiffies; if (sermouse->type > SERIO_SUN) - sermouse_process_ms(sermouse, data); + sermouse_process_ms(sermouse, data, regs); else - sermouse_process_msc(sermouse, data); + sermouse_process_msc(sermouse, data, regs); return IRQ_HANDLED; } diff --git a/trunk/drivers/input/mouse/synaptics.c b/trunk/drivers/input/mouse/synaptics.c index 49ac696d6cff..392108c436ba 100644 --- a/trunk/drivers/input/mouse/synaptics.c +++ b/trunk/drivers/input/mouse/synaptics.c @@ -216,13 +216,13 @@ static void synaptics_pass_pt_packet(struct serio *ptport, unsigned char *packet struct psmouse *child = serio_get_drvdata(ptport); if (child && child->state == PSMOUSE_ACTIVATED) { - serio_interrupt(ptport, packet[1], 0); - serio_interrupt(ptport, packet[4], 0); - serio_interrupt(ptport, packet[5], 0); + serio_interrupt(ptport, packet[1], 0, NULL); + serio_interrupt(ptport, packet[4], 0, NULL); + serio_interrupt(ptport, packet[5], 0, NULL); if (child->pktsize == 4) - serio_interrupt(ptport, packet[2], 0); + serio_interrupt(ptport, packet[2], 0, NULL); } else - serio_interrupt(ptport, packet[1], 0); + serio_interrupt(ptport, packet[1], 0, NULL); } static void synaptics_pt_activate(struct psmouse *psmouse) @@ -469,10 +469,13 @@ static unsigned char synaptics_detect_pkt_type(struct psmouse *psmouse) return SYN_NEWABS_STRICT; } -static psmouse_ret_t synaptics_process_byte(struct psmouse *psmouse) +static psmouse_ret_t synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs) { + struct input_dev *dev = psmouse->dev; struct synaptics_data *priv = psmouse->private; + input_regs(dev, regs); + if (psmouse->pktcnt >= 6) { /* Full packet received */ if (unlikely(priv->pkt_type == SYN_NEWABS)) priv->pkt_type = synaptics_detect_pkt_type(psmouse); diff --git a/trunk/drivers/input/mouse/vsxxxaa.c b/trunk/drivers/input/mouse/vsxxxaa.c index ffdb50eee93d..47edcfd022ba 100644 --- a/trunk/drivers/input/mouse/vsxxxaa.c +++ b/trunk/drivers/input/mouse/vsxxxaa.c @@ -211,7 +211,7 @@ vsxxxaa_smells_like_packet (struct vsxxxaa *mouse, unsigned char type, size_t le } static void -vsxxxaa_handle_REL_packet (struct vsxxxaa *mouse) +vsxxxaa_handle_REL_packet (struct vsxxxaa *mouse, struct pt_regs *regs) { struct input_dev *dev = mouse->dev; unsigned char *buf = mouse->buf; @@ -258,6 +258,7 @@ vsxxxaa_handle_REL_packet (struct vsxxxaa *mouse) /* * Report what we've found so far... */ + input_regs (dev, regs); input_report_key (dev, BTN_LEFT, left); input_report_key (dev, BTN_MIDDLE, middle); input_report_key (dev, BTN_RIGHT, right); @@ -268,7 +269,7 @@ vsxxxaa_handle_REL_packet (struct vsxxxaa *mouse) } static void -vsxxxaa_handle_ABS_packet (struct vsxxxaa *mouse) +vsxxxaa_handle_ABS_packet (struct vsxxxaa *mouse, struct pt_regs *regs) { struct input_dev *dev = mouse->dev; unsigned char *buf = mouse->buf; @@ -311,6 +312,7 @@ vsxxxaa_handle_ABS_packet (struct vsxxxaa *mouse) /* * Report what we've found so far... */ + input_regs (dev, regs); input_report_key (dev, BTN_LEFT, left); input_report_key (dev, BTN_MIDDLE, middle); input_report_key (dev, BTN_RIGHT, right); @@ -321,7 +323,7 @@ vsxxxaa_handle_ABS_packet (struct vsxxxaa *mouse) } static void -vsxxxaa_handle_POR_packet (struct vsxxxaa *mouse) +vsxxxaa_handle_POR_packet (struct vsxxxaa *mouse, struct pt_regs *regs) { struct input_dev *dev = mouse->dev; unsigned char *buf = mouse->buf; @@ -365,6 +367,7 @@ vsxxxaa_handle_POR_packet (struct vsxxxaa *mouse) if (error <= 0x1f) { /* No (serious) error. Report buttons */ + input_regs (dev, regs); input_report_key (dev, BTN_LEFT, left); input_report_key (dev, BTN_MIDDLE, middle); input_report_key (dev, BTN_RIGHT, right); @@ -392,7 +395,7 @@ vsxxxaa_handle_POR_packet (struct vsxxxaa *mouse) } static void -vsxxxaa_parse_buffer (struct vsxxxaa *mouse) +vsxxxaa_parse_buffer (struct vsxxxaa *mouse, struct pt_regs *regs) { unsigned char *buf = mouse->buf; int stray_bytes; @@ -429,7 +432,7 @@ vsxxxaa_parse_buffer (struct vsxxxaa *mouse) continue; } - vsxxxaa_handle_REL_packet (mouse); + vsxxxaa_handle_REL_packet (mouse, regs); continue; /* More to parse? */ } @@ -443,7 +446,7 @@ vsxxxaa_parse_buffer (struct vsxxxaa *mouse) continue; } - vsxxxaa_handle_ABS_packet (mouse); + vsxxxaa_handle_ABS_packet (mouse, regs); continue; /* More to parse? */ } @@ -457,7 +460,7 @@ vsxxxaa_parse_buffer (struct vsxxxaa *mouse) continue; } - vsxxxaa_handle_POR_packet (mouse); + vsxxxaa_handle_POR_packet (mouse, regs); continue; /* More to parse? */ } @@ -466,12 +469,13 @@ vsxxxaa_parse_buffer (struct vsxxxaa *mouse) } static irqreturn_t -vsxxxaa_interrupt (struct serio *serio, unsigned char data, unsigned int flags) +vsxxxaa_interrupt (struct serio *serio, unsigned char data, unsigned int flags, + struct pt_regs *regs) { struct vsxxxaa *mouse = serio_get_drvdata (serio); vsxxxaa_queue_byte (mouse, data); - vsxxxaa_parse_buffer (mouse); + vsxxxaa_parse_buffer (mouse, regs); return IRQ_HANDLED; } diff --git a/trunk/drivers/input/serio/Kconfig b/trunk/drivers/input/serio/Kconfig index adef447f23ea..8cdbfeca5903 100644 --- a/trunk/drivers/input/serio/Kconfig +++ b/trunk/drivers/input/serio/Kconfig @@ -112,7 +112,7 @@ config SERIO_GSCPS2 config HP_SDC tristate "HP System Device Controller i8042 Support" - depends on (GSC || HP300) && SERIO + depends on GSC && SERIO default y ---help--- This option enables support for the "System Device diff --git a/trunk/drivers/input/serio/ambakmi.c b/trunk/drivers/input/serio/ambakmi.c index 5a7b49c35539..3df5eedf8f31 100644 --- a/trunk/drivers/input/serio/ambakmi.c +++ b/trunk/drivers/input/serio/ambakmi.c @@ -37,14 +37,14 @@ struct amba_kmi_port { unsigned int open; }; -static irqreturn_t amba_kmi_int(int irq, void *dev_id) +static irqreturn_t amba_kmi_int(int irq, void *dev_id, struct pt_regs *regs) { struct amba_kmi_port *kmi = dev_id; unsigned int status = readb(KMIIR); int handled = IRQ_NONE; while (status & KMIIR_RXINTR) { - serio_interrupt(kmi->io, readb(KMIDATA), 0); + serio_interrupt(kmi->io, readb(KMIDATA), 0, regs); status = readb(KMIIR); handled = IRQ_HANDLED; } diff --git a/trunk/drivers/input/serio/ct82c710.c b/trunk/drivers/input/serio/ct82c710.c index 0d35018c23a9..bc6e87add093 100644 --- a/trunk/drivers/input/serio/ct82c710.c +++ b/trunk/drivers/input/serio/ct82c710.c @@ -71,9 +71,9 @@ static struct resource ct82c710_iores; * is waiting in the 82C710. */ -static irqreturn_t ct82c710_interrupt(int cpl, void *dev_id) +static irqreturn_t ct82c710_interrupt(int cpl, void *dev_id, struct pt_regs * regs) { - return serio_interrupt(ct82c710_port, inb(CT82C710_DATA), 0); + return serio_interrupt(ct82c710_port, inb(CT82C710_DATA), 0, regs); } /* diff --git a/trunk/drivers/input/serio/gscps2.c b/trunk/drivers/input/serio/gscps2.c index 74f14e097789..cde036a92168 100644 --- a/trunk/drivers/input/serio/gscps2.c +++ b/trunk/drivers/input/serio/gscps2.c @@ -82,7 +82,7 @@ MODULE_DEVICE_TABLE(parisc, gscps2_device_tbl); #define GSC_ID_MOUSE 1 -static irqreturn_t gscps2_interrupt(int irq, void *dev); +static irqreturn_t gscps2_interrupt(int irq, void *dev, struct pt_regs *regs); #define BUFFER_SIZE 0x0f @@ -166,7 +166,7 @@ static inline int gscps2_writeb_output(struct gscps2port *ps2port, u8 data) /* make sure any received data is returned as fast as possible */ /* this is important e.g. when we set the LEDs on the keyboard */ - gscps2_interrupt(0, NULL); + gscps2_interrupt(0, NULL, NULL); return 1; } @@ -226,7 +226,7 @@ static LIST_HEAD(ps2port_list); * later. */ -static irqreturn_t gscps2_interrupt(int irq, void *dev) +static irqreturn_t gscps2_interrupt(int irq, void *dev, struct pt_regs *regs) { struct gscps2port *ps2port; @@ -267,7 +267,7 @@ static irqreturn_t gscps2_interrupt(int irq, void *dev) rxflags = ((status & GSC_STAT_TERR) ? SERIO_TIMEOUT : 0 ) | ((status & GSC_STAT_PERR) ? SERIO_PARITY : 0 ); - serio_interrupt(ps2port->port, data, rxflags); + serio_interrupt(ps2port->port, data, rxflags, regs); } /* while() */ @@ -306,7 +306,7 @@ static int gscps2_open(struct serio *port) /* enable it */ gscps2_enable(ps2port, ENABLE); - gscps2_interrupt(0, NULL); + gscps2_interrupt(0, NULL, NULL); return 0; } diff --git a/trunk/drivers/input/serio/hil_mlc.c b/trunk/drivers/input/serio/hil_mlc.c index 49e11e2c1d5d..bbbe15e21904 100644 --- a/trunk/drivers/input/serio/hil_mlc.c +++ b/trunk/drivers/input/serio/hil_mlc.c @@ -162,10 +162,10 @@ static void hil_mlc_send_polls(hil_mlc *mlc) { if (did != (p & HIL_PKT_ADDR_MASK) >> 8) { if (drv == NULL || drv->interrupt == NULL) goto skip; - drv->interrupt(serio, 0, 0); - drv->interrupt(serio, HIL_ERR_INT >> 16, 0); - drv->interrupt(serio, HIL_PKT_CMD >> 8, 0); - drv->interrupt(serio, HIL_CMD_POL + cnt, 0); + drv->interrupt(serio, 0, 0, NULL); + drv->interrupt(serio, HIL_ERR_INT >> 16, 0, NULL); + drv->interrupt(serio, HIL_PKT_CMD >> 8, 0, NULL); + drv->interrupt(serio, HIL_CMD_POL + cnt, 0, NULL); skip: did = (p & HIL_PKT_ADDR_MASK) >> 8; serio = did ? mlc->serio[mlc->di_map[did-1]] : NULL; @@ -174,10 +174,10 @@ static void hil_mlc_send_polls(hil_mlc *mlc) { } cnt++; i++; if (drv == NULL || drv->interrupt == NULL) continue; - drv->interrupt(serio, (p >> 24), 0); - drv->interrupt(serio, (p >> 16) & 0xff, 0); - drv->interrupt(serio, (p >> 8) & ~HIL_PKT_ADDR_MASK, 0); - drv->interrupt(serio, p & 0xff, 0); + drv->interrupt(serio, (p >> 24), 0, NULL); + drv->interrupt(serio, (p >> 16) & 0xff, 0, NULL); + drv->interrupt(serio, (p >> 8) & ~HIL_PKT_ADDR_MASK, 0, NULL); + drv->interrupt(serio, p & 0xff, 0, NULL); } } @@ -391,23 +391,23 @@ static int hilse_operate(hil_mlc *mlc, int repoll) { } #define FUNC(funct, funct_arg, zero_rc, neg_rc, pos_rc) \ -{ HILSE_FUNC, { .func = funct }, funct_arg, zero_rc, neg_rc, pos_rc }, +{ HILSE_FUNC, { func: &funct }, funct_arg, zero_rc, neg_rc, pos_rc }, #define OUT(pack) \ -{ HILSE_OUT, { .packet = pack }, 0, HILSEN_NEXT, HILSEN_DOZE, 0 }, +{ HILSE_OUT, { packet: pack }, 0, HILSEN_NEXT, HILSEN_DOZE, 0 }, #define CTS \ -{ HILSE_CTS, { .packet = 0 }, 0, HILSEN_NEXT | HILSEN_SCHED | HILSEN_BREAK, HILSEN_DOZE, 0 }, +{ HILSE_CTS, { packet: 0 }, 0, HILSEN_NEXT | HILSEN_SCHED | HILSEN_BREAK, HILSEN_DOZE, 0 }, #define EXPECT(comp, to, got, got_wrong, timed_out) \ -{ HILSE_EXPECT, { .packet = comp }, to, got, got_wrong, timed_out }, +{ HILSE_EXPECT, { packet: comp }, to, got, got_wrong, timed_out }, #define EXPECT_LAST(comp, to, got, got_wrong, timed_out) \ -{ HILSE_EXPECT_LAST, { .packet = comp }, to, got, got_wrong, timed_out }, +{ HILSE_EXPECT_LAST, { packet: comp }, to, got, got_wrong, timed_out }, #define EXPECT_DISC(comp, to, got, got_wrong, timed_out) \ -{ HILSE_EXPECT_DISC, { .packet = comp }, to, got, got_wrong, timed_out }, +{ HILSE_EXPECT_DISC, { packet: comp }, to, got, got_wrong, timed_out }, #define IN(to, got, got_error, timed_out) \ -{ HILSE_IN, { .packet = 0 }, to, got, got_error, timed_out }, +{ HILSE_IN, { packet: 0 }, to, got, got_error, timed_out }, #define OUT_DISC(pack) \ -{ HILSE_OUT_DISC, { .packet = pack }, 0, 0, 0, 0 }, +{ HILSE_OUT_DISC, { packet: pack }, 0, 0, 0, 0 }, #define OUT_LAST(pack) \ -{ HILSE_OUT_LAST, { .packet = pack }, 0, 0, 0, 0 }, +{ HILSE_OUT_LAST, { packet: pack }, 0, 0, 0, 0 }, struct hilse_node hil_mlc_se[HILSEN_END] = { @@ -780,16 +780,16 @@ static int hil_mlc_serio_write(struct serio *serio, unsigned char c) { while ((last != idx) && (*last == 0)) last--; while (idx != last) { - drv->interrupt(serio, 0, 0); - drv->interrupt(serio, HIL_ERR_INT >> 16, 0); - drv->interrupt(serio, 0, 0); - drv->interrupt(serio, *idx, 0); + drv->interrupt(serio, 0, 0, NULL); + drv->interrupt(serio, HIL_ERR_INT >> 16, 0, NULL); + drv->interrupt(serio, 0, 0, NULL); + drv->interrupt(serio, *idx, 0, NULL); idx++; } - drv->interrupt(serio, 0, 0); - drv->interrupt(serio, HIL_ERR_INT >> 16, 0); - drv->interrupt(serio, HIL_PKT_CMD >> 8, 0); - drv->interrupt(serio, *idx, 0); + drv->interrupt(serio, 0, 0, NULL); + drv->interrupt(serio, HIL_ERR_INT >> 16, 0, NULL); + drv->interrupt(serio, HIL_PKT_CMD >> 8, 0, NULL); + drv->interrupt(serio, *idx, 0, NULL); mlc->serio_oidx[map->didx] = 0; mlc->serio_opacket[map->didx] = 0; diff --git a/trunk/drivers/input/serio/hp_sdc.c b/trunk/drivers/input/serio/hp_sdc.c index 9907ad3bea23..a10348bb25e9 100644 --- a/trunk/drivers/input/serio/hp_sdc.c +++ b/trunk/drivers/input/serio/hp_sdc.c @@ -202,7 +202,7 @@ static void hp_sdc_take (int irq, void *dev_id, uint8_t status, uint8_t data) { } } -static irqreturn_t hp_sdc_isr(int irq, void *dev_id) { +static irqreturn_t hp_sdc_isr(int irq, void *dev_id, struct pt_regs * regs) { uint8_t status, data; status = hp_sdc_status_in8(); @@ -253,7 +253,7 @@ static irqreturn_t hp_sdc_isr(int irq, void *dev_id) { } -static irqreturn_t hp_sdc_nmisr(int irq, void *dev_id) { +static irqreturn_t hp_sdc_nmisr(int irq, void *dev_id, struct pt_regs * regs) { int status; status = hp_sdc_status_in8(); @@ -310,7 +310,7 @@ static void hp_sdc_tasklet(unsigned long foo) { * in tasklet/bh context. */ if (curr->act.irqhook) - curr->act.irqhook(0, NULL, 0, 0); + curr->act.irqhook(0, 0, 0, 0); } curr->actidx = curr->idx; curr->idx++; @@ -525,7 +525,7 @@ unsigned long hp_sdc_put(void) { up(curr->act.semaphore); } else if (act & HP_SDC_ACT_CALLBACK) { - curr->act.irqhook(0,NULL,0,0); + curr->act.irqhook(0,0,0,0); } if (curr->idx >= curr->endidx) { /* This transaction is over. */ if (act & HP_SDC_ACT_DEALLOC) kfree(curr); diff --git a/trunk/drivers/input/serio/i8042.c b/trunk/drivers/input/serio/i8042.c index 7e3141f37e32..1bb0c76a9259 100644 --- a/trunk/drivers/input/serio/i8042.c +++ b/trunk/drivers/input/serio/i8042.c @@ -106,10 +106,9 @@ static unsigned char i8042_ctr; static unsigned char i8042_mux_present; static unsigned char i8042_kbd_irq_registered; static unsigned char i8042_aux_irq_registered; -static unsigned char i8042_suppress_kbd_ack; static struct platform_device *i8042_platform_device; -static irqreturn_t i8042_interrupt(int irq, void *dev_id); +static irqreturn_t i8042_interrupt(int irq, void *dev_id, struct pt_regs *regs); /* * The i8042_wait_read() and i8042_wait_write functions wait for the i8042 to @@ -272,7 +271,7 @@ static int i8042_aux_write(struct serio *serio, unsigned char c) * characters later. */ - i8042_interrupt(0, NULL); + i8042_interrupt(0, NULL, NULL); return retval; } @@ -310,14 +309,14 @@ static void i8042_stop(struct serio *serio) * to the upper layers. */ -static irqreturn_t i8042_interrupt(int irq, void *dev_id) +static irqreturn_t i8042_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct i8042_port *port; unsigned long flags; unsigned char str, data; unsigned int dfl; unsigned int port_no; - int ret = 1; + int ret; spin_lock_irqsave(&i8042_lock, flags); str = i8042_read_status(); @@ -379,16 +378,10 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id) dfl & SERIO_PARITY ? ", bad parity" : "", dfl & SERIO_TIMEOUT ? ", timeout" : ""); - if (unlikely(i8042_suppress_kbd_ack)) - if (port_no == I8042_KBD_PORT_NO && - (data == 0xfa || data == 0xfe)) { - i8042_suppress_kbd_ack = 0; - goto out; - } - if (likely(port->exists)) - serio_interrupt(port->serio, data, dfl); + serio_interrupt(port->serio, data, dfl, regs); + ret = 1; out: return IRQ_RETVAL(ret); } @@ -526,7 +519,7 @@ static int __devinit i8042_check_mux(void) static struct completion i8042_aux_irq_delivered __devinitdata; static int i8042_irq_being_tested __devinitdata; -static irqreturn_t __devinit i8042_aux_test_irq(int irq, void *dev_id) +static irqreturn_t __devinit i8042_aux_test_irq(int irq, void *dev_id, struct pt_regs *regs) { unsigned long flags; unsigned char str, data; @@ -849,13 +842,11 @@ static long i8042_panic_blink(long count) led ^= 0x01 | 0x04; while (i8042_read_status() & I8042_STR_IBF) DELAY; - i8042_suppress_kbd_ack = 1; i8042_write_data(0xed); /* set leds */ DELAY; while (i8042_read_status() & I8042_STR_IBF) DELAY; DELAY; - i8042_suppress_kbd_ack = 1; i8042_write_data(led); DELAY; last_blink = count; @@ -914,7 +905,7 @@ static int i8042_resume(struct platform_device *dev) if (i8042_ports[I8042_KBD_PORT_NO].serio) i8042_enable_kbd_port(); - i8042_interrupt(0, NULL); + i8042_interrupt(0, NULL, NULL); return 0; } diff --git a/trunk/drivers/input/serio/libps2.c b/trunk/drivers/input/serio/libps2.c index e5b1b60757bb..dcb16b5cbec0 100644 --- a/trunk/drivers/input/serio/libps2.c +++ b/trunk/drivers/input/serio/libps2.c @@ -189,7 +189,7 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command) return -1; } - mutex_lock(&ps2dev->cmd_mutex); + mutex_lock_nested(&ps2dev->cmd_mutex, SINGLE_DEPTH_NESTING); serio_pause_rx(ps2dev->serio); ps2dev->flags = command == PS2_CMD_GETID ? PS2_FLAG_WAITID : 0; @@ -296,7 +296,6 @@ EXPORT_SYMBOL(ps2_schedule_command); void ps2_init(struct ps2dev *ps2dev, struct serio *serio) { mutex_init(&ps2dev->cmd_mutex); - lockdep_set_subclass(&ps2dev->cmd_mutex, serio->depth); init_waitqueue_head(&ps2dev->wait); ps2dev->serio = serio; } diff --git a/trunk/drivers/input/serio/maceps2.c b/trunk/drivers/input/serio/maceps2.c index 558200e96d0f..f08a5d0cd5fa 100644 --- a/trunk/drivers/input/serio/maceps2.c +++ b/trunk/drivers/input/serio/maceps2.c @@ -72,7 +72,8 @@ static int maceps2_write(struct serio *dev, unsigned char val) return -1; } -static irqreturn_t maceps2_interrupt(int irq, void *dev_id) +static irqreturn_t maceps2_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { struct serio *dev = dev_id; struct mace_ps2port *port = ((struct maceps2_data *)dev->port_data)->port; @@ -80,7 +81,7 @@ static irqreturn_t maceps2_interrupt(int irq, void *dev_id) if (port->status & PS2_STATUS_RX_FULL) { byte = port->rx; - serio_interrupt(dev, byte & 0xff, 0); + serio_interrupt(dev, byte & 0xff, 0, regs); } return IRQ_HANDLED; diff --git a/trunk/drivers/input/serio/parkbd.c b/trunk/drivers/input/serio/parkbd.c index 688610e86a3e..a5c1fb3a4a51 100644 --- a/trunk/drivers/input/serio/parkbd.c +++ b/trunk/drivers/input/serio/parkbd.c @@ -102,7 +102,7 @@ static int parkbd_write(struct serio *port, unsigned char c) return 0; } -static void parkbd_interrupt(int irq, void *dev_id) +static void parkbd_interrupt(int irq, void *dev_id, struct pt_regs *regs) { if (parkbd_writing) { @@ -134,7 +134,7 @@ static void parkbd_interrupt(int irq, void *dev_id) parkbd_buffer |= (parkbd_readlines() >> 1) << parkbd_counter++; if (parkbd_counter == parkbd_mode + 10) - serio_interrupt(parkbd_port, (parkbd_buffer >> (2 - parkbd_mode)) & 0xff, 0); + serio_interrupt(parkbd_port, (parkbd_buffer >> (2 - parkbd_mode)) & 0xff, 0, regs); } parkbd_last = jiffies; diff --git a/trunk/drivers/input/serio/pcips2.c b/trunk/drivers/input/serio/pcips2.c index ea5e3c6ddb62..fb727c665253 100644 --- a/trunk/drivers/input/serio/pcips2.c +++ b/trunk/drivers/input/serio/pcips2.c @@ -58,7 +58,7 @@ static int pcips2_write(struct serio *io, unsigned char val) return 0; } -static irqreturn_t pcips2_interrupt(int irq, void *devid) +static irqreturn_t pcips2_interrupt(int irq, void *devid, struct pt_regs *regs) { struct pcips2_data *ps2if = devid; unsigned char status, scancode; @@ -80,7 +80,7 @@ static irqreturn_t pcips2_interrupt(int irq, void *devid) if (hweight8(scancode) & 1) flag ^= SERIO_PARITY; - serio_interrupt(ps2if->io, scancode, flag); + serio_interrupt(ps2if->io, scancode, flag, regs); } while (1); return IRQ_RETVAL(handled); } diff --git a/trunk/drivers/input/serio/q40kbd.c b/trunk/drivers/input/serio/q40kbd.c index cb89aff2e160..d3827c5fe119 100644 --- a/trunk/drivers/input/serio/q40kbd.c +++ b/trunk/drivers/input/serio/q40kbd.c @@ -53,14 +53,14 @@ DEFINE_SPINLOCK(q40kbd_lock); static struct serio *q40kbd_port; static struct platform_device *q40kbd_device; -static irqreturn_t q40kbd_interrupt(int irq, void *dev_id) +static irqreturn_t q40kbd_interrupt(int irq, void *dev_id, struct pt_regs *regs) { unsigned long flags; spin_lock_irqsave(&q40kbd_lock, flags); if (Q40_IRQ_KEYB_MASK & master_inb(INTERRUPT_REG)) - serio_interrupt(q40kbd_port, master_inb(KEYCODE_REG), 0); + serio_interrupt(q40kbd_port, master_inb(KEYCODE_REG), 0, regs); master_outb(-1, KEYBOARD_UNLOCK_REG); diff --git a/trunk/drivers/input/serio/rpckbd.c b/trunk/drivers/input/serio/rpckbd.c index 49f84315cb32..513d37fc1acf 100644 --- a/trunk/drivers/input/serio/rpckbd.c +++ b/trunk/drivers/input/serio/rpckbd.c @@ -56,7 +56,7 @@ static int rpckbd_write(struct serio *port, unsigned char val) return 0; } -static irqreturn_t rpckbd_rx(int irq, void *dev_id) +static irqreturn_t rpckbd_rx(int irq, void *dev_id, struct pt_regs *regs) { struct serio *port = dev_id; unsigned int byte; @@ -65,13 +65,13 @@ static irqreturn_t rpckbd_rx(int irq, void *dev_id) while (iomd_readb(IOMD_KCTRL) & (1 << 5)) { byte = iomd_readb(IOMD_KARTRX); - serio_interrupt(port, byte, 0); + serio_interrupt(port, byte, 0, regs); handled = IRQ_HANDLED; } return handled; } -static irqreturn_t rpckbd_tx(int irq, void *dev_id) +static irqreturn_t rpckbd_tx(int irq, void *dev_id, struct pt_regs *regs) { return IRQ_HANDLED; } diff --git a/trunk/drivers/input/serio/sa1111ps2.c b/trunk/drivers/input/serio/sa1111ps2.c index 559508795af1..ebd9976fc811 100644 --- a/trunk/drivers/input/serio/sa1111ps2.c +++ b/trunk/drivers/input/serio/sa1111ps2.c @@ -40,7 +40,7 @@ struct ps2if { * at the most one, but we loop for safety. If there was a * framing error, we have to manually clear the status. */ -static irqreturn_t ps2_rxint(int irq, void *dev_id) +static irqreturn_t ps2_rxint(int irq, void *dev_id, struct pt_regs *regs) { struct ps2if *ps2if = dev_id; unsigned int scancode, flag, status; @@ -58,7 +58,7 @@ static irqreturn_t ps2_rxint(int irq, void *dev_id) if (hweight8(scancode) & 1) flag ^= SERIO_PARITY; - serio_interrupt(ps2if->io, scancode, flag); + serio_interrupt(ps2if->io, scancode, flag, regs); status = sa1111_readl(ps2if->base + SA1111_PS2STAT); } @@ -69,7 +69,7 @@ static irqreturn_t ps2_rxint(int irq, void *dev_id) /* * Completion of ps2 write */ -static irqreturn_t ps2_txint(int irq, void *dev_id) +static irqreturn_t ps2_txint(int irq, void *dev_id, struct pt_regs *regs) { struct ps2if *ps2if = dev_id; unsigned int status; diff --git a/trunk/drivers/input/serio/serio.c b/trunk/drivers/input/serio/serio.c index 211943f85cb6..3e76ad71c9a0 100644 --- a/trunk/drivers/input/serio/serio.c +++ b/trunk/drivers/input/serio/serio.c @@ -118,8 +118,6 @@ static int serio_match_port(const struct serio_device_id *ids, struct serio *ser static void serio_bind_driver(struct serio *serio, struct serio_driver *drv) { - int error; - down_write(&serio_bus.subsys.rwsem); if (serio_match_port(drv->id_table, serio)) { @@ -128,19 +126,9 @@ static void serio_bind_driver(struct serio *serio, struct serio_driver *drv) serio->dev.driver = NULL; goto out; } - error = device_bind_driver(&serio->dev); - if (error) { - printk(KERN_WARNING - "serio: device_bind_driver() failed " - "for %s (%s) and %s, error: %d\n", - serio->phys, serio->name, - drv->description, error); - serio_disconnect_driver(serio); - serio->dev.driver = NULL; - goto out; - } + device_bind_driver(&serio->dev); } - out: +out: up_write(&serio_bus.subsys.rwsem); } @@ -550,12 +538,8 @@ static void serio_init_port(struct serio *serio) "serio%ld", (long)atomic_inc_return(&serio_no) - 1); serio->dev.bus = &serio_bus; serio->dev.release = serio_release_port; - if (serio->parent) { + if (serio->parent) serio->dev.parent = &serio->parent->dev; - serio->depth = serio->parent->depth + 1; - } else - serio->depth = 0; - lockdep_set_subclass(&serio->lock, serio->depth); } /* @@ -927,7 +911,7 @@ void serio_close(struct serio *serio) } irqreturn_t serio_interrupt(struct serio *serio, - unsigned char data, unsigned int dfl) + unsigned char data, unsigned int dfl, struct pt_regs *regs) { unsigned long flags; irqreturn_t ret = IRQ_NONE; @@ -935,7 +919,7 @@ irqreturn_t serio_interrupt(struct serio *serio, spin_lock_irqsave(&serio->lock, flags); if (likely(serio->drv)) { - ret = serio->drv->interrupt(serio, data, dfl); + ret = serio->drv->interrupt(serio, data, dfl, regs); } else if (!dfl && serio->registered) { serio_rescan(serio); ret = IRQ_HANDLED; diff --git a/trunk/drivers/input/serio/serio_raw.c b/trunk/drivers/input/serio/serio_raw.c index 7c8d0399ae82..71a8eea816cb 100644 --- a/trunk/drivers/input/serio/serio_raw.c +++ b/trunk/drivers/input/serio/serio_raw.c @@ -250,7 +250,7 @@ static struct file_operations serio_raw_fops = { *********************************************************************/ static irqreturn_t serio_raw_interrupt(struct serio *serio, unsigned char data, - unsigned int dfl) + unsigned int dfl, struct pt_regs *regs) { struct serio_raw *serio_raw = serio_get_drvdata(serio); struct serio_raw_list *list; @@ -297,7 +297,7 @@ static int serio_raw_connect(struct serio *serio, struct serio_driver *drv) serio_raw->dev.minor = PSMOUSE_MINOR; serio_raw->dev.name = serio_raw->name; - serio_raw->dev.parent = &serio->dev; + serio_raw->dev.dev = &serio->dev; serio_raw->dev.fops = &serio_raw_fops; err = misc_register(&serio_raw->dev); diff --git a/trunk/drivers/input/serio/serport.c b/trunk/drivers/input/serio/serport.c index e1a3a79ab3f9..54a680cc704d 100644 --- a/trunk/drivers/input/serio/serport.c +++ b/trunk/drivers/input/serio/serport.c @@ -117,6 +117,9 @@ static void serport_ldisc_close(struct tty_struct *tty) * serport_ldisc_receive() is called by the low level tty driver when characters * are ready for us. We forward the characters, one by one to the 'interrupt' * routine. + * + * FIXME: We should get pt_regs from the tty layer and forward them to + * serio_interrupt here. */ static void serport_ldisc_receive(struct tty_struct *tty, const unsigned char *cp, char *fp, int count) @@ -131,7 +134,7 @@ static void serport_ldisc_receive(struct tty_struct *tty, const unsigned char *c goto out; for (i = 0; i < count; i++) - serio_interrupt(serport->serio, cp[i], 0); + serio_interrupt(serport->serio, cp[i], 0, NULL); out: spin_unlock_irqrestore(&serport->lock, flags); diff --git a/trunk/drivers/input/touchscreen/ads7846.c b/trunk/drivers/input/touchscreen/ads7846.c index f56d6a0f0624..66e411badf70 100644 --- a/trunk/drivers/input/touchscreen/ads7846.c +++ b/trunk/drivers/input/touchscreen/ads7846.c @@ -487,7 +487,7 @@ static void ads7846_timer(unsigned long handle) spin_unlock_irq(&ts->lock); } -static irqreturn_t ads7846_irq(int irq, void *handle) +static irqreturn_t ads7846_irq(int irq, void *handle, struct pt_regs *regs) { struct ads7846 *ts = handle; unsigned long flags; diff --git a/trunk/drivers/input/touchscreen/corgi_ts.c b/trunk/drivers/input/touchscreen/corgi_ts.c index 66121f6a89ad..9b66271d3ba8 100644 --- a/trunk/drivers/input/touchscreen/corgi_ts.c +++ b/trunk/drivers/input/touchscreen/corgi_ts.c @@ -173,7 +173,7 @@ static int read_xydata(struct corgi_ts *corgi_ts) return 1; } -static void new_data(struct corgi_ts *corgi_ts) +static void new_data(struct corgi_ts *corgi_ts, struct pt_regs *regs) { if (corgi_ts->power_mode != PWR_MODE_ACTIVE) return; @@ -181,6 +181,7 @@ static void new_data(struct corgi_ts *corgi_ts) if (!corgi_ts->tc.pressure && corgi_ts->pendown == 0) return; + input_regs(corgi_ts->input, regs); input_report_abs(corgi_ts->input, ABS_X, corgi_ts->tc.x); input_report_abs(corgi_ts->input, ABS_Y, corgi_ts->tc.y); input_report_abs(corgi_ts->input, ABS_PRESSURE, corgi_ts->tc.pressure); @@ -188,14 +189,14 @@ static void new_data(struct corgi_ts *corgi_ts) input_sync(corgi_ts->input); } -static void ts_interrupt_main(struct corgi_ts *corgi_ts, int isTimer) +static void ts_interrupt_main(struct corgi_ts *corgi_ts, int isTimer, struct pt_regs *regs) { if ((GPLR(IRQ_TO_GPIO(corgi_ts->irq_gpio)) & GPIO_bit(IRQ_TO_GPIO(corgi_ts->irq_gpio))) == 0) { /* Disable Interrupt */ set_irq_type(corgi_ts->irq_gpio, IRQT_NOEDGE); if (read_xydata(corgi_ts)) { corgi_ts->pendown = 1; - new_data(corgi_ts); + new_data(corgi_ts, regs); } mod_timer(&corgi_ts->timer, jiffies + HZ / 100); } else { @@ -207,7 +208,7 @@ static void ts_interrupt_main(struct corgi_ts *corgi_ts, int isTimer) if (corgi_ts->pendown) { corgi_ts->tc.pressure = 0; - new_data(corgi_ts); + new_data(corgi_ts, regs); } /* Enable Falling Edge */ @@ -219,13 +220,13 @@ static void ts_interrupt_main(struct corgi_ts *corgi_ts, int isTimer) static void corgi_ts_timer(unsigned long data) { struct corgi_ts *corgits_data = (struct corgi_ts *) data; - ts_interrupt_main(corgits_data, 1); + ts_interrupt_main(corgits_data, 1, NULL); } -static irqreturn_t ts_interrupt(int irq, void *dev_id) +static irqreturn_t ts_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct corgi_ts *corgits_data = dev_id; - ts_interrupt_main(corgits_data, 0); + ts_interrupt_main(corgits_data, 0, regs); return IRQ_HANDLED; } @@ -237,7 +238,7 @@ static int corgits_suspend(struct platform_device *dev, pm_message_t state) if (corgi_ts->pendown) { del_timer_sync(&corgi_ts->timer); corgi_ts->tc.pressure = 0; - new_data(corgi_ts); + new_data(corgi_ts, NULL); corgi_ts->pendown = 0; } corgi_ts->power_mode = PWR_MODE_SUSPEND; diff --git a/trunk/drivers/input/touchscreen/elo.c b/trunk/drivers/input/touchscreen/elo.c index 913e1b73bb0e..ab565335ee44 100644 --- a/trunk/drivers/input/touchscreen/elo.c +++ b/trunk/drivers/input/touchscreen/elo.c @@ -67,7 +67,7 @@ struct elo { char phys[32]; }; -static void elo_process_data_10(struct elo *elo, unsigned char data) +static void elo_process_data_10(struct elo *elo, unsigned char data, struct pt_regs *regs) { struct input_dev *dev = elo->dev; @@ -95,6 +95,7 @@ static void elo_process_data_10(struct elo *elo, unsigned char data) break; } if (likely(elo->data[1] == ELO10_TOUCH_PACKET)) { + input_regs(dev, regs); input_report_abs(dev, ABS_X, (elo->data[4] << 8) | elo->data[3]); input_report_abs(dev, ABS_Y, (elo->data[6] << 8) | elo->data[5]); if (elo->data[2] & ELO10_PRESSURE) @@ -115,7 +116,7 @@ static void elo_process_data_10(struct elo *elo, unsigned char data) elo->csum += data; } -static void elo_process_data_6(struct elo *elo, unsigned char data) +static void elo_process_data_6(struct elo *elo, unsigned char data, struct pt_regs *regs) { struct input_dev *dev = elo->dev; @@ -133,6 +134,7 @@ static void elo_process_data_6(struct elo *elo, unsigned char data) break; } + input_regs(dev, regs); input_report_abs(dev, ABS_X, ((elo->data[0] & 0x3f) << 6) | (elo->data[1] & 0x3f)); input_report_abs(dev, ABS_Y, ((elo->data[2] & 0x3f) << 6) | (elo->data[3] & 0x3f)); @@ -162,7 +164,7 @@ static void elo_process_data_6(struct elo *elo, unsigned char data) } } -static void elo_process_data_3(struct elo *elo, unsigned char data) +static void elo_process_data_3(struct elo *elo, unsigned char data, struct pt_regs *regs) { struct input_dev *dev = elo->dev; @@ -175,6 +177,7 @@ static void elo_process_data_3(struct elo *elo, unsigned char data) elo->idx = 0; break; case 2: + input_regs(dev, regs); input_report_key(dev, BTN_TOUCH, !(elo->data[1] & 0x80)); input_report_abs(dev, ABS_X, elo->data[1]); input_report_abs(dev, ABS_Y, elo->data[2]); @@ -185,22 +188,22 @@ static void elo_process_data_3(struct elo *elo, unsigned char data) } static irqreturn_t elo_interrupt(struct serio *serio, - unsigned char data, unsigned int flags) + unsigned char data, unsigned int flags, struct pt_regs *regs) { struct elo *elo = serio_get_drvdata(serio); switch(elo->id) { case 0: - elo_process_data_10(elo, data); + elo_process_data_10(elo, data, regs); break; case 1: case 2: - elo_process_data_6(elo, data); + elo_process_data_6(elo, data, regs); break; case 3: - elo_process_data_3(elo, data); + elo_process_data_3(elo, data, regs); break; } diff --git a/trunk/drivers/input/touchscreen/gunze.c b/trunk/drivers/input/touchscreen/gunze.c index 817c2198933d..b769b21973b7 100644 --- a/trunk/drivers/input/touchscreen/gunze.c +++ b/trunk/drivers/input/touchscreen/gunze.c @@ -60,7 +60,7 @@ struct gunze { char phys[32]; }; -static void gunze_process_packet(struct gunze* gunze) +static void gunze_process_packet(struct gunze* gunze, struct pt_regs *regs) { struct input_dev *dev = gunze->dev; @@ -70,6 +70,7 @@ static void gunze_process_packet(struct gunze* gunze) return; } + input_regs(dev, regs); input_report_abs(dev, ABS_X, simple_strtoul(gunze->data + 1, NULL, 10)); input_report_abs(dev, ABS_Y, 1024 - simple_strtoul(gunze->data + 6, NULL, 10)); input_report_key(dev, BTN_TOUCH, gunze->data[0] == 'T'); @@ -77,12 +78,12 @@ static void gunze_process_packet(struct gunze* gunze) } static irqreturn_t gunze_interrupt(struct serio *serio, - unsigned char data, unsigned int flags) + unsigned char data, unsigned int flags, struct pt_regs *regs) { struct gunze* gunze = serio_get_drvdata(serio); if (data == '\r') { - gunze_process_packet(gunze); + gunze_process_packet(gunze, regs); gunze->idx = 0; } else { if (gunze->idx < GUNZE_MAX_LENGTH) diff --git a/trunk/drivers/input/touchscreen/h3600_ts_input.c b/trunk/drivers/input/touchscreen/h3600_ts_input.c index d9e61ee05ea9..e2b910018773 100644 --- a/trunk/drivers/input/touchscreen/h3600_ts_input.c +++ b/trunk/drivers/input/touchscreen/h3600_ts_input.c @@ -106,18 +106,19 @@ struct h3600_dev { char phys[32]; }; -static irqreturn_t action_button_handler(int irq, void *dev_id) +static irqreturn_t action_button_handler(int irq, void *dev_id, struct pt_regs *regs) { int down = (GPLR & GPIO_BITSY_ACTION_BUTTON) ? 0 : 1; struct input_dev *dev = (struct input_dev *) dev_id; + input_regs(dev, regs); input_report_key(dev, KEY_ENTER, down); input_sync(dev); return IRQ_HANDLED; } -static irqreturn_t npower_button_handler(int irq, void *dev_id) +static irqreturn_t npower_button_handler(int irq, void *dev_id, struct pt_regs *regs) { int down = (GPLR & GPIO_BITSY_NPOWER_BUTTON) ? 0 : 1; struct input_dev *dev = (struct input_dev *) dev_id; @@ -126,6 +127,7 @@ static irqreturn_t npower_button_handler(int irq, void *dev_id) * This interrupt is only called when we release the key. So we have * to fake a key press. */ + input_regs(dev, regs); input_report_key(dev, KEY_SUSPEND, 1); input_report_key(dev, KEY_SUSPEND, down); input_sync(dev); @@ -163,12 +165,14 @@ unsigned int h3600_flite_power(struct input_dev *dev, enum flite_pwr pwr) * packets. Some packets coming from serial are not touchscreen related. In * this case we send them off to be processed elsewhere. */ -static void h3600ts_process_packet(struct h3600_dev *ts) +static void h3600ts_process_packet(struct h3600_dev *ts, struct pt_regs *regs) { struct input_dev *dev = ts->dev; static int touched = 0; int key, down = 0; + input_regs(dev, regs); + switch (ts->event) { /* Buttons - returned as a single byte @@ -297,7 +301,7 @@ static int state; #define STATE_EOF 3 /* state where we decode checksum or EOF */ static irqreturn_t h3600ts_interrupt(struct serio *serio, unsigned char data, - unsigned int flags) + unsigned int flags, struct pt_regs *regs) { struct h3600_dev *ts = serio_get_drvdata(serio); @@ -329,7 +333,7 @@ static irqreturn_t h3600ts_interrupt(struct serio *serio, unsigned char data, case STATE_EOF: state = STATE_SOF; if (data == CHAR_EOF || data == ts->chksum) - h3600ts_process_packet(ts); + h3600ts_process_packet(ts, regs); break; default: printk("Error3\n"); diff --git a/trunk/drivers/input/touchscreen/hp680_ts_input.c b/trunk/drivers/input/touchscreen/hp680_ts_input.c index 58fca316786c..ee6c2f40cdf6 100644 --- a/trunk/drivers/input/touchscreen/hp680_ts_input.c +++ b/trunk/drivers/input/touchscreen/hp680_ts_input.c @@ -6,7 +6,7 @@ #include #include #include -#include +#include #define MODNAME "hp680_ts_input" @@ -66,7 +66,7 @@ static void do_softint(void *data) enable_irq(HP680_TS_IRQ); } -static irqreturn_t hp680_ts_interrupt(int irq, void *dev) +static irqreturn_t hp680_ts_interrupt(int irq, void *dev, struct pt_regs *regs) { disable_irq_nosync(irq); schedule_delayed_work(&work, HZ / 20); diff --git a/trunk/drivers/input/touchscreen/mk712.c b/trunk/drivers/input/touchscreen/mk712.c index 4cbcaa6a71e5..3226830eea08 100644 --- a/trunk/drivers/input/touchscreen/mk712.c +++ b/trunk/drivers/input/touchscreen/mk712.c @@ -80,7 +80,7 @@ MODULE_PARM_DESC(irq, "IRQ of MK712 touchscreen controller"); static struct input_dev *mk712_dev; static DEFINE_SPINLOCK(mk712_lock); -static irqreturn_t mk712_interrupt(int irq, void *dev_id) +static irqreturn_t mk712_interrupt(int irq, void *dev_id, struct pt_regs *regs) { unsigned char status; static int debounce = 1; @@ -88,6 +88,7 @@ static irqreturn_t mk712_interrupt(int irq, void *dev_id) static unsigned short last_y; spin_lock(&mk712_lock); + input_regs(mk712_dev, regs); status = inb(mk712_io + MK712_STATUS); diff --git a/trunk/drivers/input/touchscreen/mtouch.c b/trunk/drivers/input/touchscreen/mtouch.c index 3b4c61664b63..8647a905df80 100644 --- a/trunk/drivers/input/touchscreen/mtouch.c +++ b/trunk/drivers/input/touchscreen/mtouch.c @@ -63,11 +63,12 @@ struct mtouch { char phys[32]; }; -static void mtouch_process_format_tablet(struct mtouch *mtouch) +static void mtouch_process_format_tablet(struct mtouch *mtouch, struct pt_regs *regs) { struct input_dev *dev = mtouch->dev; if (MTOUCH_FORMAT_TABLET_LENGTH == ++mtouch->idx) { + input_regs(dev, regs); input_report_abs(dev, ABS_X, MTOUCH_GET_XC(mtouch->data)); input_report_abs(dev, ABS_Y, MTOUCH_MAX_YC - MTOUCH_GET_YC(mtouch->data)); input_report_key(dev, BTN_TOUCH, MTOUCH_GET_TOUCHED(mtouch->data)); @@ -77,7 +78,7 @@ static void mtouch_process_format_tablet(struct mtouch *mtouch) } } -static void mtouch_process_response(struct mtouch *mtouch) +static void mtouch_process_response(struct mtouch *mtouch, struct pt_regs *regs) { if (MTOUCH_RESPONSE_END_BYTE == mtouch->data[mtouch->idx++]) { /* FIXME - process response */ @@ -89,16 +90,16 @@ static void mtouch_process_response(struct mtouch *mtouch) } static irqreturn_t mtouch_interrupt(struct serio *serio, - unsigned char data, unsigned int flags) + unsigned char data, unsigned int flags, struct pt_regs *regs) { struct mtouch* mtouch = serio_get_drvdata(serio); mtouch->data[mtouch->idx] = data; if (MTOUCH_FORMAT_TABLET_STATUS_BIT & mtouch->data[0]) - mtouch_process_format_tablet(mtouch); + mtouch_process_format_tablet(mtouch, regs); else if (MTOUCH_RESPONSE_BEGIN_BYTE == mtouch->data[0]) - mtouch_process_response(mtouch); + mtouch_process_response(mtouch, regs); else printk(KERN_DEBUG "mtouch.c: unknown/unsynchronized data from device, byte %x\n",mtouch->data[0]); diff --git a/trunk/drivers/input/touchscreen/penmount.c b/trunk/drivers/input/touchscreen/penmount.c index 6c7d0c2c76cc..f7370109d43e 100644 --- a/trunk/drivers/input/touchscreen/penmount.c +++ b/trunk/drivers/input/touchscreen/penmount.c @@ -46,7 +46,7 @@ struct pm { }; static irqreturn_t pm_interrupt(struct serio *serio, - unsigned char data, unsigned int flags) + unsigned char data, unsigned int flags, struct pt_regs *regs) { struct pm *pm = serio_get_drvdata(serio); struct input_dev *dev = pm->dev; @@ -55,6 +55,7 @@ static irqreturn_t pm_interrupt(struct serio *serio, if (pm->data[0] & 0x80) { if (PM_MAX_LENGTH == ++pm->idx) { + input_regs(dev, regs); input_report_abs(dev, ABS_X, pm->data[2] * 128 + pm->data[1]); input_report_abs(dev, ABS_Y, pm->data[4] * 128 + pm->data[3]); input_report_key(dev, BTN_TOUCH, !!(pm->data[0] & 0x40)); diff --git a/trunk/drivers/input/touchscreen/touchright.c b/trunk/drivers/input/touchscreen/touchright.c index c74f74e57af0..1c89fa538651 100644 --- a/trunk/drivers/input/touchscreen/touchright.c +++ b/trunk/drivers/input/touchscreen/touchright.c @@ -56,7 +56,7 @@ struct tr { }; static irqreturn_t tr_interrupt(struct serio *serio, - unsigned char data, unsigned int flags) + unsigned char data, unsigned int flags, struct pt_regs *regs) { struct tr *tr = serio_get_drvdata(serio); struct input_dev *dev = tr->dev; @@ -65,6 +65,7 @@ static irqreturn_t tr_interrupt(struct serio *serio, if ((tr->data[0] & TR_FORMAT_STATUS_MASK) == TR_FORMAT_STATUS_BYTE) { if (++tr->idx == TR_LENGTH) { + input_regs(dev, regs); input_report_abs(dev, ABS_X, (tr->data[1] << 5) | (tr->data[2] >> 1)); input_report_abs(dev, ABS_Y, diff --git a/trunk/drivers/input/touchscreen/touchwin.c b/trunk/drivers/input/touchscreen/touchwin.c index 9911820fa2fe..a7b4c755958e 100644 --- a/trunk/drivers/input/touchscreen/touchwin.c +++ b/trunk/drivers/input/touchscreen/touchwin.c @@ -60,7 +60,7 @@ struct tw { }; static irqreturn_t tw_interrupt(struct serio *serio, - unsigned char data, unsigned int flags) + unsigned char data, unsigned int flags, struct pt_regs *regs) { struct tw *tw = serio_get_drvdata(serio); struct input_dev *dev = tw->dev; @@ -70,6 +70,7 @@ static irqreturn_t tw_interrupt(struct serio *serio, tw->data[tw->idx++] = data; /* verify length and that the two Y's are the same */ if (tw->idx == TW_LENGTH && tw->data[1] == tw->data[2]) { + input_regs(dev, regs); input_report_abs(dev, ABS_X, tw->data[0]); input_report_abs(dev, ABS_Y, tw->data[1]); input_report_key(dev, BTN_TOUCH, 1); diff --git a/trunk/drivers/isdn/act2000/act2000_isa.c b/trunk/drivers/isdn/act2000/act2000_isa.c index 3cac23739344..bc98d77c5ecd 100644 --- a/trunk/drivers/isdn/act2000/act2000_isa.c +++ b/trunk/drivers/isdn/act2000/act2000_isa.c @@ -16,6 +16,8 @@ #include "act2000_isa.h" #include "capi.h" +static act2000_card *irq2card_map[16]; + /* * Reset Controller, then try to read the Card's signature. + Return: @@ -61,11 +63,16 @@ act2000_isa_detect(unsigned short portbase) } static irqreturn_t -act2000_isa_interrupt(int irq, void *dev_id) +act2000_isa_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - act2000_card *card = dev_id; + act2000_card *card = irq2card_map[irq]; u_char istatus; + if (!card) { + printk(KERN_WARNING + "act2000: Spurious interrupt!\n"); + return IRQ_NONE; + } istatus = (inb(ISA_PORT_ISR) & 0x07); if (istatus & ISA_ISR_OUT) { /* RX fifo has data */ @@ -132,15 +139,17 @@ int act2000_isa_config_irq(act2000_card * card, short irq) { if (card->flags & ACT2000_FLAGS_IVALID) { - free_irq(card->irq, card); + free_irq(card->irq, NULL); + irq2card_map[card->irq] = NULL; } card->flags &= ~ACT2000_FLAGS_IVALID; outb(ISA_COR_IRQOFF, ISA_PORT_COR); if (!irq) return 0; - if (!request_irq(irq, &act2000_isa_interrupt, 0, card->regname, card)) { + if (!request_irq(irq, &act2000_isa_interrupt, 0, card->regname, NULL)) { card->irq = irq; + irq2card_map[card->irq] = card; card->flags |= ACT2000_FLAGS_IVALID; printk(KERN_WARNING "act2000: Could not request irq %d\n",irq); @@ -179,9 +188,10 @@ act2000_isa_release(act2000_card * card) unsigned long flags; spin_lock_irqsave(&card->lock, flags); - if (card->flags & ACT2000_FLAGS_IVALID) - free_irq(card->irq, card); - + if (card->flags & ACT2000_FLAGS_IVALID) { + free_irq(card->irq, NULL); + irq2card_map[card->irq] = NULL; + } card->flags &= ~ACT2000_FLAGS_IVALID; if (card->flags & ACT2000_FLAGS_PVALID) release_region(card->port, ISA_REGION); diff --git a/trunk/drivers/isdn/capi/capidrv.c b/trunk/drivers/isdn/capi/capidrv.c index b6f9476c0501..d10c8b82e6aa 100644 --- a/trunk/drivers/isdn/capi/capidrv.c +++ b/trunk/drivers/isdn/capi/capidrv.c @@ -1907,8 +1907,7 @@ static int if_readstat(u8 __user *buf, int len, int id, int channel) } for (p=buf, count=0; count < len; p++, count++) { - if (put_user(*card->q931_read++, p)) - return -EFAULT; + put_user(*card->q931_read++, p); if (card->q931_read > card->q931_end) card->q931_read = card->q931_buf; } diff --git a/trunk/drivers/isdn/gigaset/bas-gigaset.c b/trunk/drivers/isdn/gigaset/bas-gigaset.c index 0c937325a1b3..5cfbe6a38010 100644 --- a/trunk/drivers/isdn/gigaset/bas-gigaset.c +++ b/trunk/drivers/isdn/gigaset/bas-gigaset.c @@ -454,7 +454,7 @@ inline static int update_basstate(struct bas_cardstate *ucs, * urb USB request block * urb->context = inbuf structure for controller state */ -static void read_ctrl_callback(struct urb *urb) +static void read_ctrl_callback(struct urb *urb, struct pt_regs *regs) { struct inbuf_t *inbuf = urb->context; struct cardstate *cs = inbuf->cs; @@ -596,7 +596,7 @@ static int atread_submit(struct cardstate *cs, int timeout) * urb USB request block * urb->context = controller state structure */ -static void read_int_callback(struct urb *urb) +static void read_int_callback(struct urb *urb, struct pt_regs *regs) { struct cardstate *cs = urb->context; struct bas_cardstate *ucs = cs->hw.bas; @@ -762,7 +762,7 @@ static void read_int_callback(struct urb *urb) * urb USB request block of completed request * urb->context = bc_state structure */ -static void read_iso_callback(struct urb *urb) +static void read_iso_callback(struct urb *urb, struct pt_regs *regs) { struct bc_state *bcs; struct bas_bc_state *ubc; @@ -827,7 +827,7 @@ static void read_iso_callback(struct urb *urb) * urb USB request block of completed request * urb->context = isow_urbctx_t structure */ -static void write_iso_callback(struct urb *urb) +static void write_iso_callback(struct urb *urb, struct pt_regs *regs) { struct isow_urbctx_t *ucx; struct bas_bc_state *ubc; @@ -1415,7 +1415,7 @@ static void req_timeout(unsigned long data) * urb USB request block of completed request * urb->context = hardware specific controller state structure */ -static void write_ctrl_callback(struct urb *urb) +static void write_ctrl_callback(struct urb *urb, struct pt_regs *regs) { struct bas_cardstate *ucs = urb->context; int rc; @@ -1661,7 +1661,7 @@ static void complete_cb(struct cardstate *cs) * urb USB request block of completed request * urb->context = controller state structure */ -static void write_command_callback(struct urb *urb) +static void write_command_callback(struct urb *urb, struct pt_regs *regs) { struct cardstate *cs = urb->context; struct bas_cardstate *ucs = cs->hw.bas; diff --git a/trunk/drivers/isdn/gigaset/common.c b/trunk/drivers/isdn/gigaset/common.c index defd5743dba6..aca165d43aa0 100644 --- a/trunk/drivers/isdn/gigaset/common.c +++ b/trunk/drivers/isdn/gigaset/common.c @@ -616,7 +616,7 @@ static struct bc_state *gigaset_initbcs(struct bc_state *bcs, } else if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL) skb_reserve(bcs->skb, HW_HDR_LEN); else { - warn("could not allocate skb\n"); + dev_warn(cs->dev, "could not allocate skb\n"); bcs->inputstate |= INS_skip_frame; } @@ -702,7 +702,7 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, cs->open_count = 0; cs->dev = NULL; cs->tty = NULL; - cs->tty_dev = NULL; + cs->class = NULL; cs->cidmode = cidmode != 0; //if(onechannel) { //FIXME diff --git a/trunk/drivers/isdn/gigaset/gigaset.h b/trunk/drivers/isdn/gigaset/gigaset.h index 06298cc52bf5..884bd72c1bf4 100644 --- a/trunk/drivers/isdn/gigaset/gigaset.h +++ b/trunk/drivers/isdn/gigaset/gigaset.h @@ -444,7 +444,7 @@ struct cardstate { struct gigaset_driver *driver; unsigned minor_index; struct device *dev; - struct device *tty_dev; + struct class_device *class; const struct gigaset_ops *ops; diff --git a/trunk/drivers/isdn/gigaset/interface.c b/trunk/drivers/isdn/gigaset/interface.c index 7edea015867e..596f3aebe2f7 100644 --- a/trunk/drivers/isdn/gigaset/interface.c +++ b/trunk/drivers/isdn/gigaset/interface.c @@ -625,13 +625,13 @@ void gigaset_if_init(struct cardstate *cs) return; tasklet_init(&cs->if_wake_tasklet, &if_wake, (unsigned long) cs); - cs->tty_dev = tty_register_device(drv->tty, cs->minor_index, NULL); + cs->class = tty_register_device(drv->tty, cs->minor_index, NULL); - if (!IS_ERR(cs->tty_dev)) - dev_set_drvdata(cs->tty_dev, cs); + if (!IS_ERR(cs->class)) + class_set_devdata(cs->class, cs); else { warn("could not register device to the tty subsystem"); - cs->tty_dev = NULL; + cs->class = NULL; } } @@ -645,7 +645,7 @@ void gigaset_if_free(struct cardstate *cs) tasklet_disable(&cs->if_wake_tasklet); tasklet_kill(&cs->if_wake_tasklet); - cs->tty_dev = NULL; + cs->class = NULL; tty_unregister_device(drv->tty, cs->minor_index); } diff --git a/trunk/drivers/isdn/gigaset/proc.c b/trunk/drivers/isdn/gigaset/proc.c index e767afa55abf..9ad840e95dbe 100644 --- a/trunk/drivers/isdn/gigaset/proc.c +++ b/trunk/drivers/isdn/gigaset/proc.c @@ -16,12 +16,11 @@ #include "gigaset.h" #include -static ssize_t show_cidmode(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t show_cidmode(struct class_device *class, char *buf) { int ret; unsigned long flags; - struct cardstate *cs = dev_get_drvdata(dev); + struct cardstate *cs = class_get_devdata(class); spin_lock_irqsave(&cs->lock, flags); ret = sprintf(buf, "%u\n", cs->cidmode); @@ -30,10 +29,10 @@ static ssize_t show_cidmode(struct device *dev, return ret; } -static ssize_t set_cidmode(struct device *dev, struct device_attribute *attr, +static ssize_t set_cidmode(struct class_device *class, const char *buf, size_t count) { - struct cardstate *cs = dev_get_drvdata(dev); + struct cardstate *cs = class_get_devdata(class); long int value; char *end; @@ -65,25 +64,25 @@ static ssize_t set_cidmode(struct device *dev, struct device_attribute *attr, return count; } -static DEVICE_ATTR(cidmode, S_IRUGO|S_IWUSR, show_cidmode, set_cidmode); +static CLASS_DEVICE_ATTR(cidmode, S_IRUGO|S_IWUSR, show_cidmode, set_cidmode); /* free sysfs for device */ void gigaset_free_dev_sysfs(struct cardstate *cs) { - if (!cs->tty_dev) + if (!cs->class) return; gig_dbg(DEBUG_INIT, "removing sysfs entries"); - device_remove_file(cs->tty_dev, &dev_attr_cidmode); + class_device_remove_file(cs->class, &class_device_attr_cidmode); } /* initialize sysfs for device */ void gigaset_init_dev_sysfs(struct cardstate *cs) { - if (!cs->tty_dev) + if (!cs->class) return; gig_dbg(DEBUG_INIT, "setting up sysfs"); - if (device_create_file(cs->tty_dev, &dev_attr_cidmode)) + if (class_device_create_file(cs->class, &class_device_attr_cidmode)) dev_err(cs->dev, "could not create sysfs attribute\n"); } diff --git a/trunk/drivers/isdn/gigaset/usb-gigaset.c b/trunk/drivers/isdn/gigaset/usb-gigaset.c index 5ebf49ac9b23..6e05d9d4a51a 100644 --- a/trunk/drivers/isdn/gigaset/usb-gigaset.c +++ b/trunk/drivers/isdn/gigaset/usb-gigaset.c @@ -362,7 +362,7 @@ static void gigaset_modem_fill(unsigned long data) * * It is called if the data was received from the device. */ -static void gigaset_read_int_callback(struct urb *urb) +static void gigaset_read_int_callback(struct urb *urb, struct pt_regs *regs) { struct inbuf_t *inbuf = urb->context; struct cardstate *cs = inbuf->cs; @@ -420,7 +420,7 @@ static void gigaset_read_int_callback(struct urb *urb) /* This callback routine is called when data was transmitted to the device. */ -static void gigaset_write_bulk_callback(struct urb *urb) +static void gigaset_write_bulk_callback(struct urb *urb, struct pt_regs *regs) { struct cardstate *cs = urb->context; unsigned long flags; @@ -815,11 +815,14 @@ static int gigaset_probe(struct usb_interface *interface, return 0; error: - usb_kill_urb(ucs->read_urb); + if (ucs->read_urb) + usb_kill_urb(ucs->read_urb); kfree(ucs->bulk_out_buffer); - usb_free_urb(ucs->bulk_out_urb); + if (ucs->bulk_out_urb != NULL) + usb_free_urb(ucs->bulk_out_urb); kfree(cs->inbuf[0].rcvbuf); - usb_free_urb(ucs->read_urb); + if (ucs->read_urb != NULL) + usb_free_urb(ucs->read_urb); usb_set_intfdata(interface, NULL); ucs->read_urb = ucs->bulk_out_urb = NULL; cs->inbuf[0].rcvbuf = ucs->bulk_out_buffer = NULL; @@ -847,9 +850,11 @@ static void gigaset_disconnect(struct usb_interface *interface) usb_kill_urb(ucs->bulk_out_urb); /* FIXME: only if active? */ kfree(ucs->bulk_out_buffer); - usb_free_urb(ucs->bulk_out_urb); + if (ucs->bulk_out_urb != NULL) + usb_free_urb(ucs->bulk_out_urb); kfree(cs->inbuf[0].rcvbuf); - usb_free_urb(ucs->read_urb); + if (ucs->read_urb != NULL) + usb_free_urb(ucs->read_urb); ucs->read_urb = ucs->bulk_out_urb = NULL; cs->inbuf[0].rcvbuf = ucs->bulk_out_buffer = NULL; diff --git a/trunk/drivers/isdn/hardware/avm/avmcard.h b/trunk/drivers/isdn/hardware/avm/avmcard.h index d964f07e4a56..3b431723c7cb 100644 --- a/trunk/drivers/isdn/hardware/avm/avmcard.h +++ b/trunk/drivers/isdn/hardware/avm/avmcard.h @@ -554,7 +554,7 @@ void b1_register_appl(struct capi_ctr *ctrl, u16 appl, void b1_release_appl(struct capi_ctr *ctrl, u16 appl); u16 b1_send_message(struct capi_ctr *ctrl, struct sk_buff *skb); void b1_parse_version(avmctrl_info *card); -irqreturn_t b1_interrupt(int interrupt, void *devptr); +irqreturn_t b1_interrupt(int interrupt, void *devptr, struct pt_regs *regs); int b1ctl_read_proc(char *page, char **start, off_t off, int count, int *eof, struct capi_ctr *ctrl); @@ -567,7 +567,7 @@ void avmcard_dma_free(avmcard_dmainfo *); int b1pciv4_detect(avmcard *card); int t1pci_detect(avmcard *card); void b1dma_reset(avmcard *card); -irqreturn_t b1dma_interrupt(int interrupt, void *devptr); +irqreturn_t b1dma_interrupt(int interrupt, void *devptr, struct pt_regs *regs); int b1dma_load_firmware(struct capi_ctr *ctrl, capiloaddata *data); void b1dma_reset_ctr(struct capi_ctr *ctrl); diff --git a/trunk/drivers/isdn/hardware/avm/b1.c b/trunk/drivers/isdn/hardware/avm/b1.c index da2729247713..0c7061d55027 100644 --- a/trunk/drivers/isdn/hardware/avm/b1.c +++ b/trunk/drivers/isdn/hardware/avm/b1.c @@ -485,7 +485,7 @@ void b1_parse_version(avmctrl_info *cinfo) /* ------------------------------------------------------------- */ -irqreturn_t b1_interrupt(int interrupt, void *devptr) +irqreturn_t b1_interrupt(int interrupt, void *devptr, struct pt_regs *regs) { avmcard *card = devptr; avmctrl_info *cinfo = &card->ctrlinfo[0]; diff --git a/trunk/drivers/isdn/hardware/avm/b1dma.c b/trunk/drivers/isdn/hardware/avm/b1dma.c index ddd47cdfdb1f..a4beeb46c859 100644 --- a/trunk/drivers/isdn/hardware/avm/b1dma.c +++ b/trunk/drivers/isdn/hardware/avm/b1dma.c @@ -628,7 +628,7 @@ static void b1dma_handle_interrupt(avmcard *card) spin_unlock(&card->lock); } -irqreturn_t b1dma_interrupt(int interrupt, void *devptr) +irqreturn_t b1dma_interrupt(int interrupt, void *devptr, struct pt_regs *regs) { avmcard *card = devptr; diff --git a/trunk/drivers/isdn/hardware/avm/c4.c b/trunk/drivers/isdn/hardware/avm/c4.c index 2a3eb38f0ebb..6c3d5f5f1f4b 100644 --- a/trunk/drivers/isdn/hardware/avm/c4.c +++ b/trunk/drivers/isdn/hardware/avm/c4.c @@ -713,7 +713,7 @@ static irqreturn_t c4_handle_interrupt(avmcard *card) return IRQ_HANDLED; } -static irqreturn_t c4_interrupt(int interrupt, void *devptr) +static irqreturn_t c4_interrupt(int interrupt, void *devptr, struct pt_regs *regs) { avmcard *card = devptr; diff --git a/trunk/drivers/isdn/hardware/avm/t1isa.c b/trunk/drivers/isdn/hardware/avm/t1isa.c index e47c60b0a8ec..5a2f854d55b5 100644 --- a/trunk/drivers/isdn/hardware/avm/t1isa.c +++ b/trunk/drivers/isdn/hardware/avm/t1isa.c @@ -131,7 +131,7 @@ static int t1_detectandinit(unsigned int base, unsigned irq, int cardnr) return 0; } -static irqreturn_t t1isa_interrupt(int interrupt, void *devptr) +static irqreturn_t t1isa_interrupt(int interrupt, void *devptr, struct pt_regs *regs) { avmcard *card = devptr; avmctrl_info *cinfo = &card->ctrlinfo[0]; diff --git a/trunk/drivers/isdn/hardware/eicon/diva.c b/trunk/drivers/isdn/hardware/eicon/diva.c index ffa2afa77c2f..8ab8027f33c0 100644 --- a/trunk/drivers/isdn/hardware/eicon/diva.c +++ b/trunk/drivers/isdn/hardware/eicon/diva.c @@ -71,6 +71,8 @@ DivaIdiReqFunc(29) DivaIdiReqFunc(30) DivaIdiReqFunc(31) +struct pt_regs; + /* ** LOCALS */ @@ -513,7 +515,7 @@ diva_xdi_read(void *adapter, void *os_handle, void __user *dst, } -irqreturn_t diva_os_irq_wrapper(int irq, void *context) +irqreturn_t diva_os_irq_wrapper(int irq, void *context, struct pt_regs *regs) { diva_os_xdi_adapter_t *a = (diva_os_xdi_adapter_t *) context; diva_xdi_clear_interrupts_proc_t clear_int_proc; diff --git a/trunk/drivers/isdn/hardware/eicon/divasmain.c b/trunk/drivers/isdn/hardware/eicon/divasmain.c index dae2e83dd5e8..b7dadba13e82 100644 --- a/trunk/drivers/isdn/hardware/eicon/divasmain.c +++ b/trunk/drivers/isdn/hardware/eicon/divasmain.c @@ -58,7 +58,8 @@ static char *DRIVERLNAME = "divas"; static char *DEVNAME = "Divas"; char *DRIVERRELEASE_DIVAS = "2.0"; -extern irqreturn_t diva_os_irq_wrapper(int irq, void *context); +extern irqreturn_t diva_os_irq_wrapper(int irq, void *context, + struct pt_regs *regs); extern int create_divas_proc(void); extern void remove_divas_proc(void); extern void diva_get_vserial_number(PISDN_ADAPTER IoAdapter, char *buf); diff --git a/trunk/drivers/isdn/hardware/eicon/os_4bri.c b/trunk/drivers/isdn/hardware/eicon/os_4bri.c index 7b4ec3f60dbf..11e6f937c1e4 100644 --- a/trunk/drivers/isdn/hardware/eicon/os_4bri.c +++ b/trunk/drivers/isdn/hardware/eicon/os_4bri.c @@ -464,7 +464,7 @@ int diva_4bri_init_card(diva_os_xdi_adapter_t * a) /* ** Cleanup function will be called for master adapter only -** this is guaranteed by design: cleanup callback is set +** this is garanteed by design: cleanup callback is set ** by master adapter only */ static int diva_4bri_cleanup_adapter(diva_os_xdi_adapter_t * a) diff --git a/trunk/drivers/isdn/hisax/Kconfig b/trunk/drivers/isdn/hisax/Kconfig index cfd2718a490d..eb57a988e048 100644 --- a/trunk/drivers/isdn/hisax/Kconfig +++ b/trunk/drivers/isdn/hisax/Kconfig @@ -344,7 +344,7 @@ config HISAX_HFC_SX config HISAX_ENTERNOW_PCI bool "Formula-n enter:now PCI card" - depends on HISAX_NETJET && PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || FRV)) + depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || FRV)) help This enables HiSax support for the Formula-n enter:now PCI ISDN card. diff --git a/trunk/drivers/isdn/hisax/amd7930_fn.c b/trunk/drivers/isdn/hisax/amd7930_fn.c index bec59010bc66..8ae08c41c853 100644 --- a/trunk/drivers/isdn/hisax/amd7930_fn.c +++ b/trunk/drivers/isdn/hisax/amd7930_fn.c @@ -733,7 +733,7 @@ dbusy_timer_handler(struct IsdnCardState *cs) wByteAMD(cs, 0x21, 0x82); wByteAMD(cs, 0x21, 0x02); spin_unlock_irqrestore(&cs->lock, flags); - cs->irq_func(cs->irq, cs); + cs->irq_func(cs->irq, cs, NULL); if (cs->debug & L1_DEB_ISAC) debugl1(cs, "Amd7930: dbusy_timer_handler: Transmitter reset"); diff --git a/trunk/drivers/isdn/hisax/asuscom.c b/trunk/drivers/isdn/hisax/asuscom.c index 61e69e9c4aa9..93ff941c48f1 100644 --- a/trunk/drivers/isdn/hisax/asuscom.c +++ b/trunk/drivers/isdn/hisax/asuscom.c @@ -156,7 +156,7 @@ WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value) #include "hscx_irq.c" static irqreturn_t -asuscom_interrupt(int intno, void *dev_id) +asuscom_interrupt(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; u_char val; @@ -194,7 +194,7 @@ asuscom_interrupt(int intno, void *dev_id) } static irqreturn_t -asuscom_interrupt_ipac(int intno, void *dev_id) +asuscom_interrupt_ipac(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; u_char ista, val, icnt = 5; diff --git a/trunk/drivers/isdn/hisax/avm_a1.c b/trunk/drivers/isdn/hisax/avm_a1.c index d9028e9b9b8f..729e906bdc61 100644 --- a/trunk/drivers/isdn/hisax/avm_a1.c +++ b/trunk/drivers/isdn/hisax/avm_a1.c @@ -101,7 +101,7 @@ WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value) #include "hscx_irq.c" static irqreturn_t -avm_a1_interrupt(int intno, void *dev_id) +avm_a1_interrupt(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; u_char val, sval; diff --git a/trunk/drivers/isdn/hisax/avm_a1p.c b/trunk/drivers/isdn/hisax/avm_a1p.c index c87fa3f9b298..574e252dfa43 100644 --- a/trunk/drivers/isdn/hisax/avm_a1p.c +++ b/trunk/drivers/isdn/hisax/avm_a1p.c @@ -140,7 +140,7 @@ WriteHSCXfifo(struct IsdnCardState *cs, int hscx, u_char * data, int size) #include "hscx_irq.c" static irqreturn_t -avm_a1p_interrupt(int intno, void *dev_id) +avm_a1p_interrupt(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; u_char val, sval; diff --git a/trunk/drivers/isdn/hisax/avm_pci.c b/trunk/drivers/isdn/hisax/avm_pci.c index b04a178e5021..369afd3a3a4b 100644 --- a/trunk/drivers/isdn/hisax/avm_pci.c +++ b/trunk/drivers/isdn/hisax/avm_pci.c @@ -651,7 +651,7 @@ inithdlc(struct IsdnCardState *cs) } static irqreturn_t -avm_pcipnp_interrupt(int intno, void *dev_id) +avm_pcipnp_interrupt(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; u_long flags; diff --git a/trunk/drivers/isdn/hisax/bkm_a4t.c b/trunk/drivers/isdn/hisax/bkm_a4t.c index 871310d56a6e..87a630128a6c 100644 --- a/trunk/drivers/isdn/hisax/bkm_a4t.c +++ b/trunk/drivers/isdn/hisax/bkm_a4t.c @@ -125,7 +125,7 @@ WriteJADE(struct IsdnCardState *cs, int jade, u_char offset, u_char value) #include "jade_irq.c" static irqreturn_t -bkm_interrupt(int intno, void *dev_id) +bkm_interrupt(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; u_char val = 0; diff --git a/trunk/drivers/isdn/hisax/bkm_a8.c b/trunk/drivers/isdn/hisax/bkm_a8.c index 340310645346..dae090a9a489 100644 --- a/trunk/drivers/isdn/hisax/bkm_a8.c +++ b/trunk/drivers/isdn/hisax/bkm_a8.c @@ -140,7 +140,7 @@ set_ipac_active(struct IsdnCardState *cs, u_int active) #include "hscx_irq.c" static irqreturn_t -bkm_interrupt_ipac(int intno, void *dev_id) +bkm_interrupt_ipac(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; u_char ista, val, icnt = 5; diff --git a/trunk/drivers/isdn/hisax/config.c b/trunk/drivers/isdn/hisax/config.c index 785b08554fca..e4823ab2b127 100644 --- a/trunk/drivers/isdn/hisax/config.c +++ b/trunk/drivers/isdn/hisax/config.c @@ -631,8 +631,7 @@ static int HiSax_readstatus(u_char __user *buf, int len, int id, int channel) count = cs->status_end - cs->status_read + 1; if (count >= len) count = len; - if (copy_to_user(p, cs->status_read, count)) - return -EFAULT; + copy_to_user(p, cs->status_read, count); cs->status_read += count; if (cs->status_read > cs->status_end) cs->status_read = cs->status_buf; @@ -643,8 +642,7 @@ static int HiSax_readstatus(u_char __user *buf, int len, int id, int channel) cnt = HISAX_STATUS_BUFSIZE; else cnt = count; - if (copy_to_user(p, cs->status_read, cnt)) - return -EFAULT; + copy_to_user(p, cs->status_read, cnt); p += cnt; cs->status_read += cnt % HISAX_STATUS_BUFSIZE; count -= cnt; diff --git a/trunk/drivers/isdn/hisax/diva.c b/trunk/drivers/isdn/hisax/diva.c index 3dacfff93f5f..e294fa3918f3 100644 --- a/trunk/drivers/isdn/hisax/diva.c +++ b/trunk/drivers/isdn/hisax/diva.c @@ -289,7 +289,7 @@ MemWriteHSCX_IPACX(struct IsdnCardState *cs, int hscx, u_char offset, u_char val #include "hscx_irq.c" static irqreturn_t -diva_interrupt(int intno, void *dev_id) +diva_interrupt(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; u_char val, sval; @@ -319,7 +319,7 @@ diva_interrupt(int intno, void *dev_id) } static irqreturn_t -diva_irq_ipac_isa(int intno, void *dev_id) +diva_irq_ipac_isa(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; u_char ista,val; @@ -630,7 +630,7 @@ Memhscx_int_main(struct IsdnCardState *cs, u_char val) } static irqreturn_t -diva_irq_ipac_pci(int intno, void *dev_id) +diva_irq_ipac_pci(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; u_char ista,val; @@ -685,7 +685,7 @@ diva_irq_ipac_pci(int intno, void *dev_id) } static irqreturn_t -diva_irq_ipacx_pci(int intno, void *dev_id) +diva_irq_ipacx_pci(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; u_char val; @@ -716,10 +716,8 @@ release_io_diva(struct IsdnCardState *cs) *cfg = 0; /* disable INT0/1 */ *cfg = 2; /* reset pending INT0 */ - if (cs->hw.diva.cfg_reg) - iounmap((void *)cs->hw.diva.cfg_reg); - if (cs->hw.diva.pci_cfg) - iounmap((void *)cs->hw.diva.pci_cfg); + iounmap((void *)cs->hw.diva.cfg_reg); + iounmap((void *)cs->hw.diva.pci_cfg); return; } else if (cs->subtyp != DIVA_IPAC_ISA) { del_timer(&cs->hw.diva.tl); @@ -735,23 +733,6 @@ release_io_diva(struct IsdnCardState *cs) } } -static void -iounmap_diva(struct IsdnCardState *cs) -{ - if ((cs->subtyp == DIVA_IPAC_PCI) || (cs->subtyp == DIVA_IPACX_PCI)) { - if (cs->hw.diva.cfg_reg) { - iounmap((void *)cs->hw.diva.cfg_reg); - cs->hw.diva.cfg_reg = 0; - } - if (cs->hw.diva.pci_cfg) { - iounmap((void *)cs->hw.diva.pci_cfg); - cs->hw.diva.pci_cfg = 0; - } - } - - return; -} - static void reset_diva(struct IsdnCardState *cs) { @@ -1088,13 +1069,11 @@ setup_diva(struct IsdnCard *card) if (!cs->irq) { printk(KERN_WARNING "Diva: No IRQ for PCI card found\n"); - iounmap_diva(cs); return(0); } if (!cs->hw.diva.cfg_reg) { printk(KERN_WARNING "Diva: No IO-Adr for PCI card found\n"); - iounmap_diva(cs); return(0); } cs->irq_flags |= IRQF_SHARED; @@ -1144,7 +1123,6 @@ setup_diva(struct IsdnCard *card) CardType[card->typ], cs->hw.diva.cfg_reg, cs->hw.diva.cfg_reg + bytecnt); - iounmap_diva(cs); return (0); } } diff --git a/trunk/drivers/isdn/hisax/elsa.c b/trunk/drivers/isdn/hisax/elsa.c index fab3e4ea0595..3b3e318f6076 100644 --- a/trunk/drivers/isdn/hisax/elsa.c +++ b/trunk/drivers/isdn/hisax/elsa.c @@ -282,7 +282,7 @@ TimerRun(struct IsdnCardState *cs) #include "hscx_irq.c" static irqreturn_t -elsa_interrupt(int intno, void *dev_id) +elsa_interrupt(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; u_long flags; @@ -361,7 +361,7 @@ elsa_interrupt(int intno, void *dev_id) } static irqreturn_t -elsa_interrupt_ipac(int intno, void *dev_id) +elsa_interrupt_ipac(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; u_long flags; diff --git a/trunk/drivers/isdn/hisax/enternow_pci.c b/trunk/drivers/isdn/hisax/enternow_pci.c index b45de9d408d1..76c7d29d1b2f 100644 --- a/trunk/drivers/isdn/hisax/enternow_pci.c +++ b/trunk/drivers/isdn/hisax/enternow_pci.c @@ -240,7 +240,7 @@ enpci_card_msg(struct IsdnCardState *cs, int mt, void *arg) } static irqreturn_t -enpci_interrupt(int intno, void *dev_id) +enpci_interrupt(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; unsigned char s0val, s1val, ir; diff --git a/trunk/drivers/isdn/hisax/gazel.c b/trunk/drivers/isdn/hisax/gazel.c index 3efa719b6d29..fe2937267777 100644 --- a/trunk/drivers/isdn/hisax/gazel.c +++ b/trunk/drivers/isdn/hisax/gazel.c @@ -243,7 +243,7 @@ WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value) #include "hscx_irq.c" static irqreturn_t -gazel_interrupt(int intno, void *dev_id) +gazel_interrupt(int intno, void *dev_id, struct pt_regs *regs) { #define MAXCOUNT 5 struct IsdnCardState *cs = dev_id; @@ -274,7 +274,7 @@ gazel_interrupt(int intno, void *dev_id) static irqreturn_t -gazel_interrupt_ipac(int intno, void *dev_id) +gazel_interrupt_ipac(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; u_char ista, val; diff --git a/trunk/drivers/isdn/hisax/hfc4s8s_l1.c b/trunk/drivers/isdn/hisax/hfc4s8s_l1.c index d852c9d998b2..0ca5e66d2f5a 100644 --- a/trunk/drivers/isdn/hisax/hfc4s8s_l1.c +++ b/trunk/drivers/isdn/hisax/hfc4s8s_l1.c @@ -1268,7 +1268,7 @@ hfc4s8s_bh(hfc4s8s_hw * hw) /* interrupt handler */ /*********************/ static irqreturn_t -hfc4s8s_interrupt(int intno, void *dev_id) +hfc4s8s_interrupt(int intno, void *dev_id, struct pt_regs *regs) { hfc4s8s_hw *hw = dev_id; u_char b, ovr; diff --git a/trunk/drivers/isdn/hisax/hfc4s8s_l1.h b/trunk/drivers/isdn/hisax/hfc4s8s_l1.h index 9d5d2a56b4e9..e8f9c077fa85 100644 --- a/trunk/drivers/isdn/hisax/hfc4s8s_l1.h +++ b/trunk/drivers/isdn/hisax/hfc4s8s_l1.h @@ -16,7 +16,7 @@ /* * include Genero generated HFC-4S/8S header file hfc48scu.h -* for complete register description. This will define _HFC48SCU_H_ +* for comlete register description. This will define _HFC48SCU_H_ * to prevent redefinitions */ diff --git a/trunk/drivers/isdn/hisax/hfc_pci.c b/trunk/drivers/isdn/hisax/hfc_pci.c index 93f60b563515..1df60ca9481f 100644 --- a/trunk/drivers/isdn/hisax/hfc_pci.c +++ b/trunk/drivers/isdn/hisax/hfc_pci.c @@ -931,7 +931,7 @@ receive_emsg(struct IsdnCardState *cs) /* Interrupt handler */ /*********************/ static irqreturn_t -hfcpci_interrupt(int intno, void *dev_id) +hfcpci_interrupt(int intno, void *dev_id, struct pt_regs *regs) { u_long flags; struct IsdnCardState *cs = dev_id; diff --git a/trunk/drivers/isdn/hisax/hfc_sx.c b/trunk/drivers/isdn/hisax/hfc_sx.c index 954d1536db1f..b7e8e23be337 100644 --- a/trunk/drivers/isdn/hisax/hfc_sx.c +++ b/trunk/drivers/isdn/hisax/hfc_sx.c @@ -691,7 +691,7 @@ receive_emsg(struct IsdnCardState *cs) /* Interrupt handler */ /*********************/ static irqreturn_t -hfcsx_interrupt(int intno, void *dev_id) +hfcsx_interrupt(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; u_char exval; diff --git a/trunk/drivers/isdn/hisax/hfc_usb.c b/trunk/drivers/isdn/hisax/hfc_usb.c index 7105b043add8..6b88ecb5047d 100644 --- a/trunk/drivers/isdn/hisax/hfc_usb.c +++ b/trunk/drivers/isdn/hisax/hfc_usb.c @@ -276,7 +276,7 @@ control_action_handler(hfcusb_data * hfc, int reg, int val, int action) /* control completion routine handling background control cmds */ /***************************************************************/ static void -ctrl_complete(struct urb *urb) +ctrl_complete(struct urb *urb, struct pt_regs *regs) { hfcusb_data *hfc = (hfcusb_data *) urb->context; ctrl_buft *buf; @@ -603,7 +603,7 @@ static int iso_packets[8] = /* transmit completion routine for all ISO tx fifos */ /*****************************************************/ static void -tx_iso_complete(struct urb *urb) +tx_iso_complete(struct urb *urb, struct pt_regs *regs) { iso_urb_struct *context_iso_urb = (iso_urb_struct *) urb->context; usb_fifo *fifo = context_iso_urb->owner_fifo; @@ -726,7 +726,7 @@ tx_iso_complete(struct urb *urb) /* receive completion routine for all ISO tx fifos */ /*****************************************************/ static void -rx_iso_complete(struct urb *urb) +rx_iso_complete(struct urb *urb, struct pt_regs *regs) { iso_urb_struct *context_iso_urb = (iso_urb_struct *) urb->context; usb_fifo *fifo = context_iso_urb->owner_fifo; @@ -919,7 +919,7 @@ collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish) /* receive completion routine for all rx fifos */ /***********************************************/ static void -rx_complete(struct urb *urb) +rx_complete(struct urb *urb, struct pt_regs *regs) { int len; int status; diff --git a/trunk/drivers/isdn/hisax/hfcscard.c b/trunk/drivers/isdn/hisax/hfcscard.c index 57670dc5034d..4e7f472877e9 100644 --- a/trunk/drivers/isdn/hisax/hfcscard.c +++ b/trunk/drivers/isdn/hisax/hfcscard.c @@ -21,7 +21,7 @@ extern const char *CardType[]; static const char *hfcs_revision = "$Revision: 1.10.2.4 $"; static irqreturn_t -hfcs_interrupt(int intno, void *dev_id) +hfcs_interrupt(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; u_char val, stat; diff --git a/trunk/drivers/isdn/hisax/hisax.h b/trunk/drivers/isdn/hisax/hisax.h index 159c5896061e..2f9d5118ceaf 100644 --- a/trunk/drivers/isdn/hisax/hisax.h +++ b/trunk/drivers/isdn/hisax/hisax.h @@ -941,7 +941,7 @@ struct IsdnCardState { int (*cardmsg) (struct IsdnCardState *, int, void *); void (*setstack_d) (struct PStack *, struct IsdnCardState *); void (*DC_Close) (struct IsdnCardState *); - int (*irq_func) (int, void *); + int (*irq_func) (int, void *, struct pt_regs *); int (*auxcmd) (struct IsdnCardState *, isdn_ctrl *); struct Channel channel[2+MAX_WAITING_CALLS]; struct BCState bcs[2+MAX_WAITING_CALLS]; diff --git a/trunk/drivers/isdn/hisax/hisax_fcpcipnp.c b/trunk/drivers/isdn/hisax/hisax_fcpcipnp.c index f6db55a752c4..881a4165cfb4 100644 --- a/trunk/drivers/isdn/hisax/hisax_fcpcipnp.c +++ b/trunk/drivers/isdn/hisax/hisax_fcpcipnp.c @@ -651,7 +651,7 @@ static void fritz_b_l2l1(struct hisax_if *ifc, int pr, void *arg) // ---------------------------------------------------------------------- static irqreturn_t -fcpci2_irq(int intno, void *dev) +fcpci2_irq(int intno, void *dev, struct pt_regs *regs) { struct fritz_adapter *adapter = dev; unsigned char val; @@ -671,7 +671,7 @@ fcpci2_irq(int intno, void *dev) } static irqreturn_t -fcpci_irq(int intno, void *dev) +fcpci_irq(int intno, void *dev, struct pt_regs *regs) { struct fritz_adapter *adapter = dev; unsigned char sval; diff --git a/trunk/drivers/isdn/hisax/icc.c b/trunk/drivers/isdn/hisax/icc.c index da706925d54d..2cf7b665609e 100644 --- a/trunk/drivers/isdn/hisax/icc.c +++ b/trunk/drivers/isdn/hisax/icc.c @@ -608,7 +608,7 @@ dbusy_timer_handler(struct IsdnCardState *cs) debugl1(cs, "D-Channel Busy no skb"); } cs->writeisac(cs, ICC_CMDR, 0x01); /* Transmitter reset */ - cs->irq_func(cs->irq, cs); + cs->irq_func(cs->irq, cs, NULL); } } } diff --git a/trunk/drivers/isdn/hisax/isac.c b/trunk/drivers/isdn/hisax/isac.c index 282f349408bc..565b7892c267 100644 --- a/trunk/drivers/isdn/hisax/isac.c +++ b/trunk/drivers/isdn/hisax/isac.c @@ -609,7 +609,7 @@ dbusy_timer_handler(struct IsdnCardState *cs) debugl1(cs, "D-Channel Busy no skb"); } cs->writeisac(cs, ISAC_CMDR, 0x01); /* Transmitter reset */ - cs->irq_func(cs->irq, cs); + cs->irq_func(cs->irq, cs, NULL); } } } diff --git a/trunk/drivers/isdn/hisax/isdnl2.c b/trunk/drivers/isdn/hisax/isdnl2.c index cd3b5ad53491..6d0431725555 100644 --- a/trunk/drivers/isdn/hisax/isdnl2.c +++ b/trunk/drivers/isdn/hisax/isdnl2.c @@ -1442,7 +1442,7 @@ l2_tei_remove(struct FsmInst *fi, int event, void *arg) } static void -l2_st14_persistent_da(struct FsmInst *fi, int event, void *arg) +l2_st14_persistant_da(struct FsmInst *fi, int event, void *arg) { struct PStack *st = fi->userdata; @@ -1453,7 +1453,7 @@ l2_st14_persistent_da(struct FsmInst *fi, int event, void *arg) } static void -l2_st5_persistent_da(struct FsmInst *fi, int event, void *arg) +l2_st5_persistant_da(struct FsmInst *fi, int event, void *arg) { struct PStack *st = fi->userdata; @@ -1466,7 +1466,7 @@ l2_st5_persistent_da(struct FsmInst *fi, int event, void *arg) } static void -l2_st6_persistent_da(struct FsmInst *fi, int event, void *arg) +l2_st6_persistant_da(struct FsmInst *fi, int event, void *arg) { struct PStack *st = fi->userdata; @@ -1477,7 +1477,7 @@ l2_st6_persistent_da(struct FsmInst *fi, int event, void *arg) } static void -l2_persistent_da(struct FsmInst *fi, int event, void *arg) +l2_persistant_da(struct FsmInst *fi, int event, void *arg) { struct PStack *st = fi->userdata; @@ -1612,14 +1612,14 @@ static struct FsmNode L2FnList[] __initdata = {ST_L2_6, EV_L2_FRAME_ERROR, l2_frame_error}, {ST_L2_7, EV_L2_FRAME_ERROR, l2_frame_error_reest}, {ST_L2_8, EV_L2_FRAME_ERROR, l2_frame_error_reest}, - {ST_L2_1, EV_L1_DEACTIVATE, l2_st14_persistent_da}, + {ST_L2_1, EV_L1_DEACTIVATE, l2_st14_persistant_da}, {ST_L2_2, EV_L1_DEACTIVATE, l2_st24_tei_remove}, {ST_L2_3, EV_L1_DEACTIVATE, l2_st3_tei_remove}, - {ST_L2_4, EV_L1_DEACTIVATE, l2_st14_persistent_da}, - {ST_L2_5, EV_L1_DEACTIVATE, l2_st5_persistent_da}, - {ST_L2_6, EV_L1_DEACTIVATE, l2_st6_persistent_da}, - {ST_L2_7, EV_L1_DEACTIVATE, l2_persistent_da}, - {ST_L2_8, EV_L1_DEACTIVATE, l2_persistent_da}, + {ST_L2_4, EV_L1_DEACTIVATE, l2_st14_persistant_da}, + {ST_L2_5, EV_L1_DEACTIVATE, l2_st5_persistant_da}, + {ST_L2_6, EV_L1_DEACTIVATE, l2_st6_persistant_da}, + {ST_L2_7, EV_L1_DEACTIVATE, l2_persistant_da}, + {ST_L2_8, EV_L1_DEACTIVATE, l2_persistant_da}, }; #define L2_FN_COUNT (sizeof(L2FnList)/sizeof(struct FsmNode)) diff --git a/trunk/drivers/isdn/hisax/isurf.c b/trunk/drivers/isdn/hisax/isurf.c index 55de06953540..715a1a8cd694 100644 --- a/trunk/drivers/isdn/hisax/isurf.c +++ b/trunk/drivers/isdn/hisax/isurf.c @@ -83,7 +83,7 @@ WriteISAR(struct IsdnCardState *cs, int mode, u_char offset, u_char value) } static irqreturn_t -isurf_interrupt(int intno, void *dev_id) +isurf_interrupt(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; u_char val; diff --git a/trunk/drivers/isdn/hisax/ix1_micro.c b/trunk/drivers/isdn/hisax/ix1_micro.c index 252d79de5e5e..39717506c678 100644 --- a/trunk/drivers/isdn/hisax/ix1_micro.c +++ b/trunk/drivers/isdn/hisax/ix1_micro.c @@ -125,7 +125,7 @@ WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value) #include "hscx_irq.c" static irqreturn_t -ix1micro_interrupt(int intno, void *dev_id) +ix1micro_interrupt(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; u_char val; diff --git a/trunk/drivers/isdn/hisax/mic.c b/trunk/drivers/isdn/hisax/mic.c index a81d175d9f64..8c82519593a8 100644 --- a/trunk/drivers/isdn/hisax/mic.c +++ b/trunk/drivers/isdn/hisax/mic.c @@ -120,7 +120,7 @@ WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value) #include "hscx_irq.c" static irqreturn_t -mic_interrupt(int intno, void *dev_id) +mic_interrupt(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; u_char val; diff --git a/trunk/drivers/isdn/hisax/netjet.h b/trunk/drivers/isdn/hisax/netjet.h index 4d89d3ea4173..1080508f3c6a 100644 --- a/trunk/drivers/isdn/hisax/netjet.h +++ b/trunk/drivers/isdn/hisax/netjet.h @@ -66,7 +66,7 @@ void read_tiger(struct IsdnCardState *cs); void write_tiger(struct IsdnCardState *cs); void netjet_fill_dma(struct BCState *bcs); -void netjet_interrupt(int intno, void *dev_id); +void netjet_interrupt(int intno, void *dev_id, struct pt_regs *regs); void inittiger(struct IsdnCardState *cs); void release_io_netjet(struct IsdnCardState *cs); diff --git a/trunk/drivers/isdn/hisax/niccy.c b/trunk/drivers/isdn/hisax/niccy.c index e5918c6fe73d..0945336c28da 100644 --- a/trunk/drivers/isdn/hisax/niccy.c +++ b/trunk/drivers/isdn/hisax/niccy.c @@ -122,7 +122,8 @@ static void WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, #include "hscx_irq.c" -static irqreturn_t niccy_interrupt(int intno, void *dev_id) +static irqreturn_t niccy_interrupt(int intno, void *dev_id, + struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; u_char val; diff --git a/trunk/drivers/isdn/hisax/nj_s.c b/trunk/drivers/isdn/hisax/nj_s.c index c09ffb135330..80025fd890f4 100644 --- a/trunk/drivers/isdn/hisax/nj_s.c +++ b/trunk/drivers/isdn/hisax/nj_s.c @@ -26,7 +26,7 @@ static void dummywr(struct IsdnCardState *cs, int chan, u_char off, u_char value } static irqreturn_t -netjet_s_interrupt(int intno, void *dev_id) +netjet_s_interrupt(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; u_char val, s1val, s0val; diff --git a/trunk/drivers/isdn/hisax/nj_u.c b/trunk/drivers/isdn/hisax/nj_u.c index 8202cf34ecae..37497162d539 100644 --- a/trunk/drivers/isdn/hisax/nj_u.c +++ b/trunk/drivers/isdn/hisax/nj_u.c @@ -26,7 +26,7 @@ static void dummywr(struct IsdnCardState *cs, int chan, u_char off, u_char value } static irqreturn_t -netjet_u_interrupt(int intno, void *dev_id) +netjet_u_interrupt(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; u_char val, sval; diff --git a/trunk/drivers/isdn/hisax/s0box.c b/trunk/drivers/isdn/hisax/s0box.c index 150ef68b4ae2..e76042d323ea 100644 --- a/trunk/drivers/isdn/hisax/s0box.c +++ b/trunk/drivers/isdn/hisax/s0box.c @@ -141,7 +141,7 @@ WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value) #include "hscx_irq.c" static irqreturn_t -s0box_interrupt(int intno, void *dev_id) +s0box_interrupt(int intno, void *dev_id, struct pt_regs *regs) { #define MAXCOUNT 5 struct IsdnCardState *cs = dev_id; diff --git a/trunk/drivers/isdn/hisax/saphir.c b/trunk/drivers/isdn/hisax/saphir.c index c99b16690fb3..d943d365890b 100644 --- a/trunk/drivers/isdn/hisax/saphir.c +++ b/trunk/drivers/isdn/hisax/saphir.c @@ -117,7 +117,7 @@ WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value) #include "hscx_irq.c" static irqreturn_t -saphir_interrupt(int intno, void *dev_id) +saphir_interrupt(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; u_char val; diff --git a/trunk/drivers/isdn/hisax/sedlbauer.c b/trunk/drivers/isdn/hisax/sedlbauer.c index 9522141f4351..8d8e8a299892 100644 --- a/trunk/drivers/isdn/hisax/sedlbauer.c +++ b/trunk/drivers/isdn/hisax/sedlbauer.c @@ -260,7 +260,7 @@ WriteISAR(struct IsdnCardState *cs, int mode, u_char offset, u_char value) #include "hscx_irq.c" static irqreturn_t -sedlbauer_interrupt(int intno, void *dev_id) +sedlbauer_interrupt(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; u_char val; @@ -306,7 +306,7 @@ sedlbauer_interrupt(int intno, void *dev_id) } static irqreturn_t -sedlbauer_interrupt_ipac(int intno, void *dev_id) +sedlbauer_interrupt_ipac(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; u_char ista, val, icnt = 5; @@ -353,7 +353,7 @@ sedlbauer_interrupt_ipac(int intno, void *dev_id) } static irqreturn_t -sedlbauer_interrupt_isar(int intno, void *dev_id) +sedlbauer_interrupt_isar(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; u_char val; diff --git a/trunk/drivers/isdn/hisax/sportster.c b/trunk/drivers/isdn/hisax/sportster.c index 02209500b3b7..a49b694eb730 100644 --- a/trunk/drivers/isdn/hisax/sportster.c +++ b/trunk/drivers/isdn/hisax/sportster.c @@ -99,7 +99,7 @@ WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value) #include "hscx_irq.c" static irqreturn_t -sportster_interrupt(int intno, void *dev_id) +sportster_interrupt(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; u_char val; diff --git a/trunk/drivers/isdn/hisax/st5481_b.c b/trunk/drivers/isdn/hisax/st5481_b.c index 75d0f248e4ee..aca2a3954b14 100644 --- a/trunk/drivers/isdn/hisax/st5481_b.c +++ b/trunk/drivers/isdn/hisax/st5481_b.c @@ -161,7 +161,7 @@ static void led_blink(struct st5481_adapter *adapter) st5481_usb_device_ctrl_msg(adapter, GPIO_OUT, leds, NULL, NULL); } -static void usb_b_out_complete(struct urb *urb) +static void usb_b_out_complete(struct urb *urb, struct pt_regs *regs) { struct st5481_bcs *bcs = urb->context; struct st5481_b_out *b_out = &bcs->b_out; diff --git a/trunk/drivers/isdn/hisax/st5481_d.c b/trunk/drivers/isdn/hisax/st5481_d.c index 1d8c2618366c..98adec440590 100644 --- a/trunk/drivers/isdn/hisax/st5481_d.c +++ b/trunk/drivers/isdn/hisax/st5481_d.c @@ -370,7 +370,7 @@ static void fifo_reseted(void *context) FsmEvent(&adapter->d_out.fsm, EV_DOUT_RESETED, NULL); } -static void usb_d_out_complete(struct urb *urb) +static void usb_d_out_complete(struct urb *urb, struct pt_regs *regs) { struct st5481_adapter *adapter = urb->context; struct st5481_d_out *d_out = &adapter->d_out; diff --git a/trunk/drivers/isdn/hisax/st5481_usb.c b/trunk/drivers/isdn/hisax/st5481_usb.c index ff1595122048..b096b64b0253 100644 --- a/trunk/drivers/isdn/hisax/st5481_usb.c +++ b/trunk/drivers/isdn/hisax/st5481_usb.c @@ -125,7 +125,7 @@ void st5481_ph_command(struct st5481_adapter *adapter, unsigned int command) * Call the user provided completion routine and try * to send the next request. */ -static void usb_ctrl_complete(struct urb *urb) +static void usb_ctrl_complete(struct urb *urb, struct pt_regs *regs) { struct st5481_adapter *adapter = urb->context; struct st5481_ctrl *ctrl = &adapter->ctrl; @@ -179,7 +179,7 @@ static void usb_ctrl_complete(struct urb *urb) * Decode the register values and schedule a private event. * Called at interrupt. */ -static void usb_int_complete(struct urb *urb) +static void usb_int_complete(struct urb *urb, struct pt_regs *regs) { u8 *data = urb->transfer_buffer; u8 irqbyte; @@ -483,7 +483,7 @@ void st5481_release_isocpipes(struct urb* urb[2]) * called 50 times per second with 20 ISOC descriptors. * Called at interrupt. */ -static void usb_in_complete(struct urb *urb) +static void usb_in_complete(struct urb *urb, struct pt_regs *regs) { struct st5481_in *in = urb->context; unsigned char *ptr; diff --git a/trunk/drivers/isdn/hisax/teleint.c b/trunk/drivers/isdn/hisax/teleint.c index 0909662b7458..e94dc6f5bd62 100644 --- a/trunk/drivers/isdn/hisax/teleint.c +++ b/trunk/drivers/isdn/hisax/teleint.c @@ -157,7 +157,7 @@ WriteHFC(struct IsdnCardState *cs, int data, u_char reg, u_char value) } static irqreturn_t -TeleInt_interrupt(int intno, void *dev_id) +TeleInt_interrupt(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; u_char val; diff --git a/trunk/drivers/isdn/hisax/teles0.c b/trunk/drivers/isdn/hisax/teles0.c index 48581335f43c..f94af0930a17 100644 --- a/trunk/drivers/isdn/hisax/teles0.c +++ b/trunk/drivers/isdn/hisax/teles0.c @@ -144,7 +144,7 @@ WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value) #include "hscx_irq.c" static irqreturn_t -teles0_interrupt(int intno, void *dev_id) +teles0_interrupt(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; u_char val; diff --git a/trunk/drivers/isdn/hisax/teles3.c b/trunk/drivers/isdn/hisax/teles3.c index 6a5e379e0774..5cb712437da4 100644 --- a/trunk/drivers/isdn/hisax/teles3.c +++ b/trunk/drivers/isdn/hisax/teles3.c @@ -101,7 +101,7 @@ WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value) #include "hscx_irq.c" static irqreturn_t -teles3_interrupt(int intno, void *dev_id) +teles3_interrupt(int intno, void *dev_id, struct pt_regs *regs) { #define MAXCOUNT 5 struct IsdnCardState *cs = dev_id; diff --git a/trunk/drivers/isdn/hisax/telespci.c b/trunk/drivers/isdn/hisax/telespci.c index d09f6d033f15..dca446865f24 100644 --- a/trunk/drivers/isdn/hisax/telespci.c +++ b/trunk/drivers/isdn/hisax/telespci.c @@ -226,7 +226,7 @@ WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value) #include "hscx_irq.c" static irqreturn_t -telespci_interrupt(int intno, void *dev_id) +telespci_interrupt(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; u_char hval, ival; diff --git a/trunk/drivers/isdn/hisax/w6692.c b/trunk/drivers/isdn/hisax/w6692.c index 1655341797a9..0595293b8659 100644 --- a/trunk/drivers/isdn/hisax/w6692.c +++ b/trunk/drivers/isdn/hisax/w6692.c @@ -400,7 +400,7 @@ W6692B_interrupt(struct IsdnCardState *cs, u_char bchan) } static irqreturn_t -W6692_interrupt(int intno, void *dev_id) +W6692_interrupt(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; u_char val, exval, v1; @@ -715,7 +715,7 @@ dbusy_timer_handler(struct IsdnCardState *cs) } cs->writeW6692(cs, W_D_CMDR, W_D_CMDR_XRST); /* Transmitter reset */ spin_unlock_irqrestore(&cs->lock, flags); - cs->irq_func(cs->irq, cs); + cs->irq_func(cs->irq, cs, NULL); return; } } diff --git a/trunk/drivers/isdn/hysdn/boardergo.c b/trunk/drivers/isdn/hysdn/boardergo.c index 82e42a80dc4b..73afebdf80bd 100644 --- a/trunk/drivers/isdn/hysdn/boardergo.c +++ b/trunk/drivers/isdn/hysdn/boardergo.c @@ -33,7 +33,7 @@ /* The cards interrupt handler. Called from system */ /***************************************************/ static irqreturn_t -ergo_interrupt(int intno, void *dev_id) +ergo_interrupt(int intno, void *dev_id, struct pt_regs *regs) { hysdn_card *card = dev_id; /* parameter from irq */ tErgDpram *dpr; @@ -45,10 +45,11 @@ ergo_interrupt(int intno, void *dev_id) if (!card->irq_enabled) return IRQ_NONE; /* other device interrupting or irq switched off */ - spin_lock_irqsave(&card->hysdn_lock, flags); /* no further irqs allowed */ + save_flags(flags); + cli(); /* no further irqs allowed */ if (!(bytein(card->iobase + PCI9050_INTR_REG) & PCI9050_INTR_REG_STAT1)) { - spin_unlock_irqrestore(&card->hysdn_lock, flags); /* restore old state */ + restore_flags(flags); /* restore old state */ return IRQ_NONE; /* no interrupt requested by E1 */ } /* clear any pending ints on the board */ @@ -60,7 +61,7 @@ ergo_interrupt(int intno, void *dev_id) /* start kernel task immediately after leaving all interrupts */ if (!card->hw_lock) schedule_work(&card->irq_queue); - spin_unlock_irqrestore(&card->hysdn_lock, flags); + restore_flags(flags); return IRQ_HANDLED; } /* ergo_interrupt */ @@ -82,9 +83,10 @@ ergo_irq_bh(hysdn_card * card) dpr = card->dpram; /* point to DPRAM */ - spin_lock_irqsave(&card->hysdn_lock, flags); + save_flags(flags); + cli(); if (card->hw_lock) { - spin_unlock_irqrestore(&card->hysdn_lock, flags); /* hardware currently unavailable */ + restore_flags(flags); /* hardware currently unavailable */ return; } card->hw_lock = 1; /* we now lock the hardware */ @@ -118,7 +120,7 @@ ergo_irq_bh(hysdn_card * card) card->hw_lock = 0; /* free hardware again */ } while (again); /* until nothing more to do */ - spin_unlock_irqrestore(&card->hysdn_lock, flags); + restore_flags(flags); } /* ergo_irq_bh */ @@ -135,7 +137,8 @@ ergo_stopcard(hysdn_card * card) #ifdef CONFIG_HYSDN_CAPI hycapi_capi_stop(card); #endif /* CONFIG_HYSDN_CAPI */ - spin_lock_irqsave(&card->hysdn_lock, flags); + save_flags(flags); + cli(); val = bytein(card->iobase + PCI9050_INTR_REG); /* get actual value */ val &= ~(PCI9050_INTR_REG_ENPCI | PCI9050_INTR_REG_EN1); /* mask irq */ byteout(card->iobase + PCI9050_INTR_REG, val); @@ -144,7 +147,7 @@ ergo_stopcard(hysdn_card * card) card->state = CARD_STATE_UNUSED; card->err_log_state = ERRLOG_STATE_OFF; /* currently no log active */ - spin_unlock_irqrestore(&card->hysdn_lock, flags); + restore_flags(flags); } /* ergo_stopcard */ /**************************************************************************/ @@ -159,11 +162,12 @@ ergo_set_errlog_state(hysdn_card * card, int on) card->err_log_state = ERRLOG_STATE_OFF; /* must be off */ return; } - spin_lock_irqsave(&card->hysdn_lock, flags); + save_flags(flags); + cli(); if (((card->err_log_state == ERRLOG_STATE_OFF) && !on) || ((card->err_log_state == ERRLOG_STATE_ON) && on)) { - spin_unlock_irqrestore(&card->hysdn_lock, flags); + restore_flags(flags); return; /* nothing to do */ } if (on) @@ -171,7 +175,7 @@ ergo_set_errlog_state(hysdn_card * card, int on) else card->err_log_state = ERRLOG_STATE_STOP; /* request stop */ - spin_unlock_irqrestore(&card->hysdn_lock, flags); + restore_flags(flags); schedule_work(&card->irq_queue); } /* ergo_set_errlog_state */ @@ -352,7 +356,8 @@ ergo_waitpofready(struct HYSDN_CARD *card) if (card->debug_flags & LOG_POF_RECORD) hysdn_addlog(card, "ERGO: pof boot success"); - spin_lock_irqsave(&card->hysdn_lock, flags); + save_flags(flags); + cli(); card->state = CARD_STATE_RUN; /* now card is running */ /* enable the cards interrupt */ @@ -365,7 +370,7 @@ ergo_waitpofready(struct HYSDN_CARD *card) dpr->ToHyInt = 1; dpr->ToPcInt = 1; /* interrupt to E1 for all cards */ - spin_unlock_irqrestore(&card->hysdn_lock, flags); + restore_flags(flags); if ((hynet_enable & (1 << card->myid)) && (i = hysdn_net_create(card))) { @@ -403,7 +408,7 @@ ergo_releasehardware(hysdn_card * card) free_irq(card->irq, card); /* release interrupt */ release_region(card->iobase + PCI9050_INTR_REG, 1); /* release all io ports */ release_region(card->iobase + PCI9050_USER_IO, 1); - iounmap(card->dpram); + vfree(card->dpram); card->dpram = NULL; /* release shared mem */ } /* ergo_releasehardware */ @@ -443,7 +448,6 @@ ergo_inithardware(hysdn_card * card) card->waitpofready = ergo_waitpofready; card->set_errlog_state = ergo_set_errlog_state; INIT_WORK(&card->irq_queue, (void *) (void *) ergo_irq_bh, card); - card->hysdn_lock = SPIN_LOCK_UNLOCKED; return (0); } /* ergo_inithardware */ diff --git a/trunk/drivers/isdn/hysdn/hysdn_defs.h b/trunk/drivers/isdn/hysdn/hysdn_defs.h index 729df4089385..461e831592dd 100644 --- a/trunk/drivers/isdn/hysdn/hysdn_defs.h +++ b/trunk/drivers/isdn/hysdn/hysdn_defs.h @@ -188,8 +188,6 @@ typedef struct HYSDN_CARD { /* init and deinit stopcard for booting, too */ void (*stopcard) (struct HYSDN_CARD *); void (*releasehardware) (struct HYSDN_CARD *); - - spinlock_t hysdn_lock; #ifdef CONFIG_HYSDN_CAPI struct hycapictrl_info { char cardname[32]; diff --git a/trunk/drivers/isdn/hysdn/hysdn_proclog.c b/trunk/drivers/isdn/hysdn/hysdn_proclog.c index fcd49920b220..c4301e8338ef 100644 --- a/trunk/drivers/isdn/hysdn/hysdn_proclog.c +++ b/trunk/drivers/isdn/hysdn/hysdn_proclog.c @@ -116,7 +116,8 @@ put_log_buffer(hysdn_card * card, char *cp) strcpy(ib->log_start, cp); /* set output string */ ib->next = NULL; ib->proc_ctrl = pd; /* point to own control structure */ - spin_lock_irqsave(&card->hysdn_lock, flags); + save_flags(flags); + cli(); ib->usage_cnt = pd->if_used; if (!pd->log_head) pd->log_head = ib; /* new head */ @@ -124,7 +125,7 @@ put_log_buffer(hysdn_card * card, char *cp) pd->log_tail->next = ib; /* follows existing messages */ pd->log_tail = ib; /* new tail */ i = pd->del_lock++; /* get lock state */ - spin_unlock_irqrestore(&card->hysdn_lock, flags); + restore_flags(flags); /* delete old entrys */ if (!i) @@ -269,13 +270,14 @@ hysdn_log_open(struct inode *ino, struct file *filep) } else if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) { /* read access -> log/debug read */ - spin_lock_irqsave(&card->hysdn_lock, flags); + save_flags(flags); + cli(); pd->if_used++; if (pd->log_head) filep->private_data = &pd->log_tail->next; else filep->private_data = &pd->log_head; - spin_unlock_irqrestore(&card->hysdn_lock, flags); + restore_flags(flags); } else { /* simultaneous read/write access forbidden ! */ unlock_kernel(); return (-EPERM); /* no permission this time */ @@ -299,7 +301,7 @@ hysdn_log_close(struct inode *ino, struct file *filep) hysdn_card *card; int retval = 0; unsigned long flags; - spinlock_t hysdn_lock = SPIN_LOCK_UNLOCKED; + lock_kernel(); if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_WRITE) { @@ -309,7 +311,8 @@ hysdn_log_close(struct inode *ino, struct file *filep) /* read access -> log/debug read, mark one further file as closed */ pd = NULL; - spin_lock_irqsave(&hysdn_lock, flags); + save_flags(flags); + cli(); inf = *((struct log_data **) filep->private_data); /* get first log entry */ if (inf) pd = (struct procdata *) inf->proc_ctrl; /* still entries there */ @@ -332,7 +335,7 @@ hysdn_log_close(struct inode *ino, struct file *filep) inf->usage_cnt--; /* decrement usage count for buffers */ inf = inf->next; } - spin_unlock_irqrestore(&hysdn_lock, flags); + restore_flags(flags); if (pd) if (pd->if_used <= 0) /* delete buffers if last file closed */ diff --git a/trunk/drivers/isdn/hysdn/hysdn_sched.c b/trunk/drivers/isdn/hysdn/hysdn_sched.c index 18758772b744..1c0d54ac12ab 100644 --- a/trunk/drivers/isdn/hysdn/hysdn_sched.c +++ b/trunk/drivers/isdn/hysdn/hysdn_sched.c @@ -155,17 +155,22 @@ hysdn_tx_cfgline(hysdn_card *card, unsigned char *line, unsigned short chan) if (card->debug_flags & LOG_SCHED_ASYN) hysdn_addlog(card, "async tx-cfg chan=%d len=%d", chan, strlen(line) + 1); + save_flags(flags); + cli(); while (card->async_busy) { + sti(); if (card->debug_flags & LOG_SCHED_ASYN) hysdn_addlog(card, "async tx-cfg delayed"); msleep_interruptible(20); /* Timeout 20ms */ - if (!--cnt) + if (!--cnt) { + restore_flags(flags); return (-ERR_ASYNC_TIME); /* timed out */ + } + cli(); } /* wait for buffer to become free */ - spin_lock_irqsave(&card->hysdn_lock, flags); strcpy(card->async_data, line); card->async_len = strlen(line) + 1; card->async_channel = chan; @@ -173,23 +178,30 @@ hysdn_tx_cfgline(hysdn_card *card, unsigned char *line, unsigned short chan) /* now queue the task */ schedule_work(&card->irq_queue); - spin_unlock_irqrestore(&card->hysdn_lock, flags); + sti(); if (card->debug_flags & LOG_SCHED_ASYN) hysdn_addlog(card, "async tx-cfg data queued"); cnt++; /* short delay */ + cli(); while (card->async_busy) { + sti(); if (card->debug_flags & LOG_SCHED_ASYN) hysdn_addlog(card, "async tx-cfg waiting for tx-ready"); msleep_interruptible(20); /* Timeout 20ms */ - if (!--cnt) + if (!--cnt) { + restore_flags(flags); return (-ERR_ASYNC_TIME); /* timed out */ + } + cli(); } /* wait for buffer to become free again */ + restore_flags(flags); + if (card->debug_flags & LOG_SCHED_ASYN) hysdn_addlog(card, "async tx-cfg data send"); diff --git a/trunk/drivers/isdn/i4l/isdn_common.c b/trunk/drivers/isdn/i4l/isdn_common.c index 69aee2602aa6..c3d79eef9e32 100644 --- a/trunk/drivers/isdn/i4l/isdn_common.c +++ b/trunk/drivers/isdn/i4l/isdn_common.c @@ -1134,12 +1134,9 @@ isdn_read(struct file *file, char __user *buf, size_t count, loff_t * off) if (dev->drv[drvidx]->interface->readstat) { if (count > dev->drv[drvidx]->stavail) count = dev->drv[drvidx]->stavail; - len = dev->drv[drvidx]->interface->readstat(buf, count, - drvidx, isdn_minor2chan(minor)); - if (len < 0) { - retval = len; - goto out; - } + len = dev->drv[drvidx]->interface-> + readstat(buf, count, drvidx, + isdn_minor2chan(minor)); } else { len = 0; } diff --git a/trunk/drivers/isdn/icn/icn.c b/trunk/drivers/isdn/icn/icn.c index 730bbd07ebc7..6649f8bc9951 100644 --- a/trunk/drivers/isdn/icn/icn.c +++ b/trunk/drivers/isdn/icn/icn.c @@ -1010,8 +1010,7 @@ icn_readstatus(u_char __user *buf, int len, icn_card * card) for (p = buf, count = 0; count < len; p++, count++) { if (card->msg_buf_read == card->msg_buf_write) return count; - if (put_user(*card->msg_buf_read++, p)) - return -EFAULT; + put_user(*card->msg_buf_read++, p); if (card->msg_buf_read > card->msg_buf_end) card->msg_buf_read = card->msg_buf; } diff --git a/trunk/drivers/isdn/isdnloop/isdnloop.c b/trunk/drivers/isdn/isdnloop/isdnloop.c index c3ae2edaf6fa..fabbd461603e 100644 --- a/trunk/drivers/isdn/isdnloop/isdnloop.c +++ b/trunk/drivers/isdn/isdnloop/isdnloop.c @@ -100,11 +100,12 @@ isdnloop_pollbchan(unsigned long data) isdnloop_bchan_send(card, 1); if (card->flags & (ISDNLOOP_FLAGS_B1ACTIVE | ISDNLOOP_FLAGS_B2ACTIVE)) { /* schedule b-channel polling again */ - spin_lock_irqsave(&card->isdnloop_lock, flags); + save_flags(flags); + cli(); card->rb_timer.expires = jiffies + ISDNLOOP_TIMER_BCREAD; add_timer(&card->rb_timer); card->flags |= ISDNLOOP_FLAGS_RBTIMER; - spin_unlock_irqrestore(&card->isdnloop_lock, flags); + restore_flags(flags); } else card->flags &= ~ISDNLOOP_FLAGS_RBTIMER; } @@ -280,7 +281,8 @@ isdnloop_putmsg(isdnloop_card * card, unsigned char c) { ulong flags; - spin_lock_irqsave(&card->isdnloop_lock, flags); + save_flags(flags); + cli(); *card->msg_buf_write++ = (c == 0xff) ? '\n' : c; if (card->msg_buf_write == card->msg_buf_read) { if (++card->msg_buf_read > card->msg_buf_end) @@ -288,7 +290,7 @@ isdnloop_putmsg(isdnloop_card * card, unsigned char c) } if (card->msg_buf_write > card->msg_buf_end) card->msg_buf_write = card->msg_buf; - spin_unlock_irqrestore(&card->isdnloop_lock, flags); + restore_flags(flags); } /* @@ -370,19 +372,21 @@ isdnloop_polldchan(unsigned long data) if (!(card->flags & ISDNLOOP_FLAGS_RBTIMER)) { /* schedule b-channel polling */ card->flags |= ISDNLOOP_FLAGS_RBTIMER; - spin_lock_irqsave(&card->isdnloop_lock, flags); + save_flags(flags); + cli(); del_timer(&card->rb_timer); card->rb_timer.function = isdnloop_pollbchan; card->rb_timer.data = (unsigned long) card; card->rb_timer.expires = jiffies + ISDNLOOP_TIMER_BCREAD; add_timer(&card->rb_timer); - spin_unlock_irqrestore(&card->isdnloop_lock, flags); + restore_flags(flags); } /* schedule again */ - spin_lock_irqsave(&card->isdnloop_lock, flags); + save_flags(flags); + cli(); card->st_timer.expires = jiffies + ISDNLOOP_TIMER_DCREAD; add_timer(&card->st_timer); - spin_unlock_irqrestore(&card->isdnloop_lock, flags); + restore_flags(flags); } /* @@ -412,7 +416,8 @@ isdnloop_sendbuf(int channel, struct sk_buff *skb, isdnloop_card * card) return 0; if (card->sndcount[channel] > ISDNLOOP_MAX_SQUEUE) return 0; - spin_lock_irqsave(&card->isdnloop_lock, flags); + save_flags(flags); + cli(); nskb = dev_alloc_skb(skb->len); if (nskb) { memcpy(skb_put(nskb, len), skb->data, len); @@ -421,7 +426,7 @@ isdnloop_sendbuf(int channel, struct sk_buff *skb, isdnloop_card * card) } else len = 0; card->sndcount[channel] += len; - spin_unlock_irqrestore(&card->isdnloop_lock, flags); + restore_flags(flags); } return len; } @@ -446,8 +451,7 @@ isdnloop_readstatus(u_char __user *buf, int len, isdnloop_card * card) for (p = buf, count = 0; count < len; p++, count++) { if (card->msg_buf_read == card->msg_buf_write) return count; - if (put_user(*card->msg_buf_read++, p)) - return -EFAULT; + put_user(*card->msg_buf_read++, p); if (card->msg_buf_read > card->msg_buf_end) card->msg_buf_read = card->msg_buf; } @@ -572,7 +576,8 @@ isdnloop_atimeout(isdnloop_card * card, int ch) unsigned long flags; char buf[60]; - spin_lock_irqsave(&card->isdnloop_lock, flags); + save_flags(flags); + cli(); if (card->rcard) { isdnloop_fake(card->rcard[ch], "DDIS_I", card->rch[ch] + 1); card->rcard[ch]->rcard[card->rch[ch]] = NULL; @@ -582,7 +587,7 @@ isdnloop_atimeout(isdnloop_card * card, int ch) /* No user responding */ sprintf(buf, "CAU%s", isdnloop_unicause(card, 1, 3)); isdnloop_fake(card, buf, ch + 1); - spin_unlock_irqrestore(&card->isdnloop_lock, flags); + restore_flags(flags); } /* @@ -617,7 +622,8 @@ isdnloop_start_ctimer(isdnloop_card * card, int ch) { unsigned long flags; - spin_lock_irqsave(&card->isdnloop_lock, flags); + save_flags(flags); + cli(); init_timer(&card->c_timer[ch]); card->c_timer[ch].expires = jiffies + ISDNLOOP_TIMER_ALERTWAIT; if (ch) @@ -626,7 +632,7 @@ isdnloop_start_ctimer(isdnloop_card * card, int ch) card->c_timer[ch].function = isdnloop_atimeout0; card->c_timer[ch].data = (unsigned long) card; add_timer(&card->c_timer[ch]); - spin_unlock_irqrestore(&card->isdnloop_lock, flags); + restore_flags(flags); } /* @@ -641,9 +647,10 @@ isdnloop_kill_ctimer(isdnloop_card * card, int ch) { unsigned long flags; - spin_lock_irqsave(&card->isdnloop_lock, flags); + save_flags(flags); + cli(); del_timer(&card->c_timer[ch]); - spin_unlock_irqrestore(&card->isdnloop_lock, flags); + restore_flags(flags); } static u_char si2bit[] = @@ -699,12 +706,13 @@ isdnloop_try_call(isdnloop_card * card, char *p, int lch, isdn_ctrl * cmd) } } if (num_match) { - spin_lock_irqsave(&card->isdnloop_lock, flags); + save_flags(flags); + cli(); /* channel idle? */ if (!(cc->rcard[ch])) { /* Check SI */ if (!(si2bit[cmd->parm.setup.si1] & cc->sil[ch])) { - spin_unlock_irqrestore(&card->isdnloop_lock, flags); + restore_flags(flags); return 3; } /* ch is idle, si and number matches */ @@ -712,10 +720,10 @@ isdnloop_try_call(isdnloop_card * card, char *p, int lch, isdn_ctrl * cmd) cc->rch[ch] = lch; card->rcard[lch] = cc; card->rch[lch] = ch; - spin_unlock_irqrestore(&card->isdnloop_lock, flags); + restore_flags(flags); return 0; } else { - spin_unlock_irqrestore(&card->isdnloop_lock, flags); + restore_flags(flags); /* num matches, but busy */ if (ch == 1) return 1; @@ -1019,7 +1027,8 @@ isdnloop_stopcard(isdnloop_card * card) unsigned long flags; isdn_ctrl cmd; - spin_lock_irqsave(&card->isdnloop_lock, flags); + save_flags(flags); + cli(); if (card->flags & ISDNLOOP_FLAGS_RUNNING) { card->flags &= ~ISDNLOOP_FLAGS_RUNNING; del_timer(&card->st_timer); @@ -1030,7 +1039,7 @@ isdnloop_stopcard(isdnloop_card * card) cmd.driver = card->myid; card->interface.statcallb(&cmd); } - spin_unlock_irqrestore(&card->isdnloop_lock, flags); + restore_flags(flags); } /* @@ -1069,17 +1078,18 @@ isdnloop_start(isdnloop_card * card, isdnloop_sdef * sdefp) return -EBUSY; if (copy_from_user((char *) &sdef, (char *) sdefp, sizeof(sdef))) return -EFAULT; - spin_lock_irqsave(&card->isdnloop_lock, flags); + save_flags(flags); + cli(); switch (sdef.ptype) { case ISDN_PTYPE_EURO: if (isdnloop_fake(card, "DRV1.23EC-Q.931-CAPI-CNS-BASIS-20.02.96", -1)) { - spin_unlock_irqrestore(&card->isdnloop_lock, flags); + restore_flags(flags); return -ENOMEM; } card->sil[0] = card->sil[1] = 4; if (isdnloop_fake(card, "TEI OK", 0)) { - spin_unlock_irqrestore(&card->isdnloop_lock, flags); + restore_flags(flags); return -ENOMEM; } for (i = 0; i < 3; i++) @@ -1088,12 +1098,12 @@ isdnloop_start(isdnloop_card * card, isdnloop_sdef * sdefp) case ISDN_PTYPE_1TR6: if (isdnloop_fake(card, "DRV1.04TC-1TR6-CAPI-CNS-BASIS-29.11.95", -1)) { - spin_unlock_irqrestore(&card->isdnloop_lock, flags); + restore_flags(flags); return -ENOMEM; } card->sil[0] = card->sil[1] = 4; if (isdnloop_fake(card, "TEI OK", 0)) { - spin_unlock_irqrestore(&card->isdnloop_lock, flags); + restore_flags(flags); return -ENOMEM; } strcpy(card->s0num[0], sdef.num[0]); @@ -1101,7 +1111,7 @@ isdnloop_start(isdnloop_card * card, isdnloop_sdef * sdefp) card->s0num[2][0] = '\0'; break; default: - spin_unlock_irqrestore(&card->isdnloop_lock, flags); + restore_flags(flags); printk(KERN_WARNING "isdnloop: Illegal D-channel protocol %d\n", sdef.ptype); return -EINVAL; @@ -1112,7 +1122,7 @@ isdnloop_start(isdnloop_card * card, isdnloop_sdef * sdefp) card->st_timer.data = (unsigned long) card; add_timer(&card->st_timer); card->flags |= ISDNLOOP_FLAGS_RUNNING; - spin_unlock_irqrestore(&card->isdnloop_lock, flags); + restore_flags(flags); return 0; } @@ -1462,7 +1472,6 @@ isdnloop_initcard(char *id) skb_queue_head_init(&card->bqueue[i]); } skb_queue_head_init(&card->dqueue); - card->isdnloop_lock = SPIN_LOCK_UNLOCKED; card->next = cards; cards = card; if (!register_isdn(&card->interface)) { diff --git a/trunk/drivers/isdn/isdnloop/isdnloop.h b/trunk/drivers/isdn/isdnloop/isdnloop.h index 0d458a86f529..d699fe53e1c3 100644 --- a/trunk/drivers/isdn/isdnloop/isdnloop.h +++ b/trunk/drivers/isdn/isdnloop/isdnloop.h @@ -94,7 +94,6 @@ typedef struct isdnloop_card { struct sk_buff_head bqueue[ISDNLOOP_BCH]; /* B-Channel queues */ struct sk_buff_head dqueue; /* D-Channel queue */ - spinlock_t isdnloop_lock; } isdnloop_card; /* diff --git a/trunk/drivers/isdn/pcbit/drv.c b/trunk/drivers/isdn/pcbit/drv.c index 6ead5e1508b7..94f21486bb24 100644 --- a/trunk/drivers/isdn/pcbit/drv.c +++ b/trunk/drivers/isdn/pcbit/drv.c @@ -725,27 +725,23 @@ static int pcbit_stat(u_char __user *buf, int len, int driver, int channel) if (stat_st < stat_end) { - if (copy_to_user(buf, statbuf + stat_st, len)) - return -EFAULT; + copy_to_user(buf, statbuf + stat_st, len); stat_st += len; } else { if (len > STATBUF_LEN - stat_st) { - if (copy_to_user(buf, statbuf + stat_st, - STATBUF_LEN - stat_st)) - return -EFAULT; - if (copy_to_user(buf, statbuf, - len - (STATBUF_LEN - stat_st))) - return -EFAULT; + copy_to_user(buf, statbuf + stat_st, + STATBUF_LEN - stat_st); + copy_to_user(buf, statbuf, + len - (STATBUF_LEN - stat_st)); stat_st = len - (STATBUF_LEN - stat_st); } else { - if (copy_to_user(buf, statbuf + stat_st, len)) - return -EFAULT; + copy_to_user(buf, statbuf + stat_st, len); stat_st += len; diff --git a/trunk/drivers/isdn/pcbit/layer2.c b/trunk/drivers/isdn/pcbit/layer2.c index 937fd2120381..ba766930f088 100644 --- a/trunk/drivers/isdn/pcbit/layer2.c +++ b/trunk/drivers/isdn/pcbit/layer2.c @@ -311,7 +311,6 @@ pcbit_deliver(void *data) dev->read_queue = frame->next; spin_unlock_irqrestore(&dev->lock, flags); - msg = 0; SET_MSG_CPU(msg, 0); SET_MSG_PROC(msg, 0); SET_MSG_CMD(msg, frame->skb->data[2]); @@ -513,7 +512,7 @@ pcbit_firmware_bug(struct pcbit_dev *dev) } irqreturn_t -pcbit_irq_handler(int interrupt, void *devptr) +pcbit_irq_handler(int interrupt, void *devptr, struct pt_regs *regs) { struct pcbit_dev *dev; u_char info, diff --git a/trunk/drivers/isdn/pcbit/layer2.h b/trunk/drivers/isdn/pcbit/layer2.h index 2ac295e1a6e5..0d99da3a3e2b 100644 --- a/trunk/drivers/isdn/pcbit/layer2.h +++ b/trunk/drivers/isdn/pcbit/layer2.h @@ -124,7 +124,7 @@ struct frame_buf { extern int pcbit_l2_write(struct pcbit_dev * dev, ulong msg, ushort refnum, struct sk_buff *skb, unsigned short hdr_len); -extern irqreturn_t pcbit_irq_handler(int interrupt, void *); +extern irqreturn_t pcbit_irq_handler(int interrupt, void *, struct pt_regs *regs); extern struct pcbit_dev * dev_pcbit[MAX_PCBIT_CARDS]; diff --git a/trunk/drivers/isdn/sc/init.c b/trunk/drivers/isdn/sc/init.c index 06c9872e8c6a..a627e68023f6 100644 --- a/trunk/drivers/isdn/sc/init.c +++ b/trunk/drivers/isdn/sc/init.c @@ -35,7 +35,7 @@ module_param_array(irq, int, NULL, 0); module_param_array(ram, int, NULL, 0); module_param(do_reset, bool, 0); -extern irqreturn_t interrupt_handler(int, void *); +extern irqreturn_t interrupt_handler(int, void *, struct pt_regs *); extern int sndpkt(int, int, int, struct sk_buff *); extern int command(isdn_ctrl *); extern int indicate_status(int, int, ulong, char*); @@ -98,14 +98,13 @@ static int __init sc_init(void) * Confirm the I/O Address with a test */ if(io[b] == 0) { - pr_debug("I/O Address invalid.\n"); + pr_debug("I/O Address 0x%x is in use.\n"); continue; } outb(0x18, io[b] + 0x400 * EXP_PAGE0); if(inb(io[b] + 0x400 * EXP_PAGE0) != 0x18) { - pr_debug("I/O Base 0x%x fails test\n", - io[b] + 0x400 * EXP_PAGE0); + pr_debug("I/O Base 0x%x fails test\n"); continue; } } @@ -159,8 +158,8 @@ static int __init sc_init(void) outb(0xFF, io[b] + RESET_OFFSET); msleep_interruptible(10000); } - pr_debug("RAM Base for board %d is 0x%lx, %s probe\n", b, - ram[b], ram[b] == 0 ? "will" : "won't"); + pr_debug("RAM Base for board %d is 0x%x, %s probe\n", b, ram[b], + ram[b] == 0 ? "will" : "won't"); if(ram[b]) { /* @@ -169,7 +168,7 @@ static int __init sc_init(void) * board model */ if(request_region(ram[b], SRAM_PAGESIZE, "sc test")) { - pr_debug("request_region for RAM base 0x%lx succeeded\n", ram[b]); + pr_debug("request_region for RAM base 0x%x succeeded\n", ram[b]); model = identify_board(ram[b], io[b]); release_region(ram[b], SRAM_PAGESIZE); } @@ -205,7 +204,7 @@ static int __init sc_init(void) * Nope, there was no place in RAM for the * board, or it couldn't be identified */ - pr_debug("Failed to find an adapter at 0x%lx\n", ram[b]); + pr_debug("Failed to find an adapter at 0x%x\n", ram[b]); continue; } @@ -452,7 +451,7 @@ static int identify_board(unsigned long rambase, unsigned int iobase) HWConfig_pl hwci; int x; - pr_debug("Attempting to identify adapter @ 0x%lx io 0x%x\n", + pr_debug("Attempting to identify adapter @ 0x%x io 0x%x\n", rambase, iobase); /* @@ -491,7 +490,7 @@ static int identify_board(unsigned long rambase, unsigned int iobase) outb(PRI_BASEPG_VAL, pgport); msleep_interruptible(1000); sig = readl(rambase + SIG_OFFSET); - pr_debug("Looking for a signature, got 0x%lx\n", sig); + pr_debug("Looking for a signature, got 0x%x\n", sig); if(sig == SIGNATURE) return PRI_BOARD; @@ -501,7 +500,7 @@ static int identify_board(unsigned long rambase, unsigned int iobase) outb(BRI_BASEPG_VAL, pgport); msleep_interruptible(1000); sig = readl(rambase + SIG_OFFSET); - pr_debug("Looking for a signature, got 0x%lx\n", sig); + pr_debug("Looking for a signature, got 0x%x\n", sig); if(sig == SIGNATURE) return BRI_BOARD; @@ -511,7 +510,7 @@ static int identify_board(unsigned long rambase, unsigned int iobase) * Try to spot a card */ sig = readl(rambase + SIG_OFFSET); - pr_debug("Looking for a signature, got 0x%lx\n", sig); + pr_debug("Looking for a signature, got 0x%x\n", sig); if(sig != SIGNATURE) return -1; @@ -541,7 +540,7 @@ static int identify_board(unsigned long rambase, unsigned int iobase) memcpy_fromio(&rcvmsg, &(dpm->rsp_queue[dpm->rsp_tail]), MSG_LEN); pr_debug("Got HWConfig response, status = 0x%x\n", rcvmsg.rsp_status); memcpy(&hwci, &(rcvmsg.msg_data.HWCresponse), sizeof(HWConfig_pl)); - pr_debug("Hardware Config: Interface: %s, RAM Size: %ld, Serial: %s\n" + pr_debug("Hardware Config: Interface: %s, RAM Size: %d, Serial: %s\n" " Part: %s, Rev: %s\n", hwci.st_u_sense ? "S/T" : "U", hwci.ram_size, hwci.serial_no, hwci.part_no, hwci.rev_no); diff --git a/trunk/drivers/isdn/sc/interrupt.c b/trunk/drivers/isdn/sc/interrupt.c index cd17de18cb76..ae6263125ac2 100644 --- a/trunk/drivers/isdn/sc/interrupt.c +++ b/trunk/drivers/isdn/sc/interrupt.c @@ -45,7 +45,7 @@ static int get_card_from_irq(int irq) /* * */ -irqreturn_t interrupt_handler(int interrupt, void *cardptr) +irqreturn_t interrupt_handler(int interrupt, void *cardptr, struct pt_regs *regs) { RspMessage rcvmsg; diff --git a/trunk/drivers/isdn/sc/packet.c b/trunk/drivers/isdn/sc/packet.c index 1e04676b016b..f50defc38ae5 100644 --- a/trunk/drivers/isdn/sc/packet.c +++ b/trunk/drivers/isdn/sc/packet.c @@ -44,7 +44,7 @@ int sndpkt(int devId, int channel, struct sk_buff *data) return -ENODEV; } - pr_debug("%s: sndpkt: frst = 0x%lx nxt = %d f = %d n = %d\n", + pr_debug("%s: sndpkt: frst = 0x%x nxt = %d f = %d n = %d\n", sc_adapter[card]->devicename, sc_adapter[card]->channel[channel].first_sendbuf, sc_adapter[card]->channel[channel].next_sendbuf, @@ -66,7 +66,7 @@ int sndpkt(int devId, int channel, struct sk_buff *data) ReqLnkWrite.buff_offset = sc_adapter[card]->channel[channel].next_sendbuf * BUFFER_SIZE + sc_adapter[card]->channel[channel].first_sendbuf; ReqLnkWrite.msg_len = data->len; /* sk_buff size */ - pr_debug("%s: writing %d bytes to buffer offset 0x%lx\n", + pr_debug("%s: writing %d bytes to buffer offset 0x%x\n", sc_adapter[card]->devicename, ReqLnkWrite.msg_len, ReqLnkWrite.buff_offset); memcpy_toshmem(card, (char *)ReqLnkWrite.buff_offset, data->data, ReqLnkWrite.msg_len); @@ -74,7 +74,7 @@ int sndpkt(int devId, int channel, struct sk_buff *data) /* * sendmessage */ - pr_debug("%s: sndpkt size=%d, buf_offset=0x%lx buf_indx=%d\n", + pr_debug("%s: sndpkt size=%d, buf_offset=0x%x buf_indx=%d\n", sc_adapter[card]->devicename, ReqLnkWrite.msg_len, ReqLnkWrite.buff_offset, sc_adapter[card]->channel[channel].next_sendbuf); @@ -124,7 +124,7 @@ void rcvpkt(int card, RspMessage *rcvmsg) return; } skb_put(skb, rcvmsg->msg_data.response.msg_len); - pr_debug("%s: getting data from offset: 0x%lx\n", + pr_debug("%s: getting data from offset: 0x%x\n", sc_adapter[card]->devicename, rcvmsg->msg_data.response.buff_offset); memcpy_fromshmem(card, @@ -143,7 +143,7 @@ void rcvpkt(int card, RspMessage *rcvmsg) /* memset_shmem(card, rcvmsg->msg_data.response.buff_offset, 0, BUFFER_SIZE); */ newll.buff_offset = rcvmsg->msg_data.response.buff_offset; newll.msg_len = BUFFER_SIZE; - pr_debug("%s: recycled buffer at offset 0x%lx size %d\n", + pr_debug("%s: recycled buffer at offset 0x%x size %d\n", sc_adapter[card]->devicename, newll.buff_offset, newll.msg_len); sendmessage(card, CEPID, ceReqTypeLnk, ceReqClass1, ceReqLnkRead, @@ -186,7 +186,7 @@ int setup_buffers(int card, int c) sc_adapter[card]->channel[c-1].num_sendbufs = nBuffers / 2; sc_adapter[card]->channel[c-1].free_sendbufs = nBuffers / 2; sc_adapter[card]->channel[c-1].next_sendbuf = 0; - pr_debug("%s: send buffer setup complete: first=0x%lx n=%d f=%d, nxt=%d\n", + pr_debug("%s: send buffer setup complete: first=0x%x n=%d f=%d, nxt=%d\n", sc_adapter[card]->devicename, sc_adapter[card]->channel[c-1].first_sendbuf, sc_adapter[card]->channel[c-1].num_sendbufs, @@ -203,7 +203,7 @@ int setup_buffers(int card, int c) ((sc_adapter[card]->channel[c-1].first_sendbuf + (nBuffers / 2) * buffer_size) + (buffer_size * i)); RcvBuffOffset.msg_len = buffer_size; - pr_debug("%s: adding RcvBuffer #%d offset=0x%lx sz=%d bufsz:%d\n", + pr_debug("%s: adding RcvBuffer #%d offset=0x%x sz=%d bufsz:%d\n", sc_adapter[card]->devicename, i + 1, RcvBuffOffset.buff_offset, RcvBuffOffset.msg_len,buffer_size); diff --git a/trunk/drivers/isdn/sc/shmem.c b/trunk/drivers/isdn/sc/shmem.c index 6f58862992db..24854826ca45 100644 --- a/trunk/drivers/isdn/sc/shmem.c +++ b/trunk/drivers/isdn/sc/shmem.c @@ -61,7 +61,7 @@ void memcpy_toshmem(int card, void *dest, const void *src, size_t n) spin_unlock_irqrestore(&sc_adapter[card]->lock, flags); pr_debug("%s: set page to %#x\n",sc_adapter[card]->devicename, ((sc_adapter[card]->shmem_magic + ch * SRAM_PAGESIZE)>>14)|0x80); - pr_debug("%s: copying %d bytes from %#lx to %#lx\n", + pr_debug("%s: copying %d bytes from %#x to %#x\n", sc_adapter[card]->devicename, n, (unsigned long) src, sc_adapter[card]->rambase + ((unsigned long) dest %0x4000)); diff --git a/trunk/drivers/leds/led-class.c b/trunk/drivers/leds/led-class.c index 3c1711210e38..aecbbe2e89a9 100644 --- a/trunk/drivers/leds/led-class.c +++ b/trunk/drivers/leds/led-class.c @@ -91,8 +91,6 @@ EXPORT_SYMBOL_GPL(led_classdev_resume); */ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) { - int rc; - led_cdev->class_dev = class_device_create(leds_class, NULL, 0, parent, "%s", led_cdev->name); if (unlikely(IS_ERR(led_cdev->class_dev))) @@ -101,10 +99,8 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) class_set_devdata(led_cdev->class_dev, led_cdev); /* register the attributes */ - rc = class_device_create_file(led_cdev->class_dev, - &class_device_attr_brightness); - if (rc) - goto err_out; + class_device_create_file(led_cdev->class_dev, + &class_device_attr_brightness); /* add to the list of leds */ write_lock(&leds_list_lock); @@ -114,28 +110,16 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) #ifdef CONFIG_LEDS_TRIGGERS rwlock_init(&led_cdev->trigger_lock); - rc = class_device_create_file(led_cdev->class_dev, - &class_device_attr_trigger); - if (rc) - goto err_out_led_list; - led_trigger_set_default(led_cdev); + + class_device_create_file(led_cdev->class_dev, + &class_device_attr_trigger); #endif printk(KERN_INFO "Registered led device: %s\n", led_cdev->class_dev->class_id); return 0; - -#ifdef CONFIG_LEDS_TRIGGERS -err_out_led_list: - class_device_remove_file(led_cdev->class_dev, - &class_device_attr_brightness); - list_del(&led_cdev->node); -#endif -err_out: - class_device_unregister(led_cdev->class_dev); - return rc; } EXPORT_SYMBOL_GPL(led_classdev_register); diff --git a/trunk/drivers/leds/ledtrig-timer.c b/trunk/drivers/leds/ledtrig-timer.c index 29a8818a32ec..179c2876b541 100644 --- a/trunk/drivers/leds/ledtrig-timer.c +++ b/trunk/drivers/leds/ledtrig-timer.c @@ -123,7 +123,6 @@ static CLASS_DEVICE_ATTR(delay_off, 0644, led_delay_off_show, static void timer_trig_activate(struct led_classdev *led_cdev) { struct timer_trig_data *timer_data; - int rc; timer_data = kzalloc(sizeof(struct timer_trig_data), GFP_KERNEL); if (!timer_data) @@ -135,21 +134,10 @@ static void timer_trig_activate(struct led_classdev *led_cdev) timer_data->timer.function = led_timer_function; timer_data->timer.data = (unsigned long) led_cdev; - rc = class_device_create_file(led_cdev->class_dev, + class_device_create_file(led_cdev->class_dev, &class_device_attr_delay_on); - if (rc) goto err_out; - rc = class_device_create_file(led_cdev->class_dev, + class_device_create_file(led_cdev->class_dev, &class_device_attr_delay_off); - if (rc) goto err_out_delayon; - - return; - -err_out_delayon: - class_device_remove_file(led_cdev->class_dev, - &class_device_attr_delay_on); -err_out: - led_cdev->trigger_data = NULL; - kfree(timer_data); } static void timer_trig_deactivate(struct led_classdev *led_cdev) diff --git a/trunk/drivers/macintosh/adb-iop.c b/trunk/drivers/macintosh/adb-iop.c index 17ef5d3c01b4..d56d400b6aaa 100644 --- a/trunk/drivers/macintosh/adb-iop.c +++ b/trunk/drivers/macintosh/adb-iop.c @@ -30,7 +30,7 @@ /*#define DEBUG_ADB_IOP*/ -extern void iop_ism_irq(int, void *); +extern void iop_ism_irq(int, void *, struct pt_regs *); static struct adb_request *current_req; static struct adb_request *last_req; @@ -78,7 +78,7 @@ static void adb_iop_end_req(struct adb_request *req, int state) * This will be called when a packet has been successfully sent. */ -static void adb_iop_complete(struct iop_msg *msg) +static void adb_iop_complete(struct iop_msg *msg, struct pt_regs *regs) { struct adb_request *req; uint flags; @@ -100,7 +100,7 @@ static void adb_iop_complete(struct iop_msg *msg) * commands or autopoll packets) are received. */ -static void adb_iop_listen(struct iop_msg *msg) +static void adb_iop_listen(struct iop_msg *msg, struct pt_regs *regs) { struct adb_iopmsg *amsg = (struct adb_iopmsg *) msg->message; struct adb_request *req; @@ -143,7 +143,7 @@ static void adb_iop_listen(struct iop_msg *msg) req->reply_len = amsg->count + 1; memcpy(req->reply, &amsg->cmd, req->reply_len); } else { - adb_input(&amsg->cmd, amsg->count + 1, + adb_input(&amsg->cmd, amsg->count + 1, regs, amsg->flags & ADB_IOP_AUTOPOLL); } memcpy(msg->reply, msg->message, IOP_MSG_LEN); @@ -266,7 +266,7 @@ int adb_iop_autopoll(int devs) void adb_iop_poll(void) { if (adb_iop_state == idle) adb_iop_start(); - iop_ism_irq(0, (void *) ADB_IOP); + iop_ism_irq(0, (void *) ADB_IOP, NULL); } int adb_iop_reset_bus(void) diff --git a/trunk/drivers/macintosh/adb.c b/trunk/drivers/macintosh/adb.c index be0bd34ff6f9..360f93f6fcdb 100644 --- a/trunk/drivers/macintosh/adb.c +++ b/trunk/drivers/macintosh/adb.c @@ -103,7 +103,7 @@ static void adbdev_init(void); static int try_handler_change(int, int); static struct adb_handler { - void (*handler)(unsigned char *, int, int); + void (*handler)(unsigned char *, int, struct pt_regs *, int); int original_address; int handler_id; int busy; @@ -522,7 +522,7 @@ adb_request(struct adb_request *req, void (*done)(struct adb_request *), the handler_id id it doesn't match. */ int adb_register(int default_id, int handler_id, struct adb_ids *ids, - void (*handler)(unsigned char *, int, int)) + void (*handler)(unsigned char *, int, struct pt_regs *, int)) { int i; @@ -570,13 +570,13 @@ adb_unregister(int index) } void -adb_input(unsigned char *buf, int nb, int autopoll) +adb_input(unsigned char *buf, int nb, struct pt_regs *regs, int autopoll) { int i, id; static int dump_adb_input = 0; unsigned long flags; - void (*handler)(unsigned char *, int, int); + void (*handler)(unsigned char *, int, struct pt_regs *, int); /* We skip keystrokes and mouse moves when the sleep process * has been started. We stop autopoll, but this is another security @@ -597,7 +597,7 @@ adb_input(unsigned char *buf, int nb, int autopoll) adb_handler[id].busy = 1; write_unlock_irqrestore(&adb_handler_lock, flags); if (handler != NULL) { - (*handler)(buf, nb, autopoll); + (*handler)(buf, nb, regs, autopoll); wmb(); adb_handler[id].busy = 0; } diff --git a/trunk/drivers/macintosh/adbhid.c b/trunk/drivers/macintosh/adbhid.c index 5066e7a8ea9c..b7fb367808d8 100644 --- a/trunk/drivers/macintosh/adbhid.c +++ b/trunk/drivers/macintosh/adbhid.c @@ -222,7 +222,7 @@ static struct adbhid *adbhid[16]; static void adbhid_probe(void); -static void adbhid_input_keycode(int, int, int); +static void adbhid_input_keycode(int, int, int, struct pt_regs *); static void init_trackpad(int id); static void init_trackball(int id); @@ -253,7 +253,7 @@ static struct adb_ids buttons_ids; #define ADBMOUSE_MACALLY2 9 /* MacAlly 2-button mouse */ static void -adbhid_keyboard_input(unsigned char *data, int nb, int apoll) +adbhid_keyboard_input(unsigned char *data, int nb, struct pt_regs *regs, int apoll) { int id = (data[0] >> 4) & 0x0f; @@ -266,13 +266,13 @@ adbhid_keyboard_input(unsigned char *data, int nb, int apoll) /* first check this is from register 0 */ if (nb != 3 || (data[0] & 3) != KEYB_KEYREG) return; /* ignore it */ - adbhid_input_keycode(id, data[1], 0); + adbhid_input_keycode(id, data[1], 0, regs); if (!(data[2] == 0xff || (data[2] == 0x7f && data[1] == 0x7f))) - adbhid_input_keycode(id, data[2], 0); + adbhid_input_keycode(id, data[2], 0, regs); } static void -adbhid_input_keycode(int id, int keycode, int repeat) +adbhid_input_keycode(int id, int keycode, int repeat, struct pt_regs *regs) { struct adbhid *ahid = adbhid[id]; int up_flag; @@ -282,6 +282,7 @@ adbhid_input_keycode(int id, int keycode, int repeat) switch (keycode) { case ADB_KEY_CAPSLOCK: /* Generate down/up events for CapsLock everytime. */ + input_regs(ahid->input, regs); input_report_key(ahid->input, KEY_CAPSLOCK, 1); input_report_key(ahid->input, KEY_CAPSLOCK, 0); input_sync(ahid->input); @@ -337,6 +338,7 @@ adbhid_input_keycode(int id, int keycode, int repeat) } if (adbhid[id]->keycode[keycode]) { + input_regs(adbhid[id]->input, regs); input_report_key(adbhid[id]->input, adbhid[id]->keycode[keycode], !up_flag); input_sync(adbhid[id]->input); @@ -347,7 +349,7 @@ adbhid_input_keycode(int id, int keycode, int repeat) } static void -adbhid_mouse_input(unsigned char *data, int nb, int autopoll) +adbhid_mouse_input(unsigned char *data, int nb, struct pt_regs *regs, int autopoll) { int id = (data[0] >> 4) & 0x0f; @@ -430,6 +432,8 @@ adbhid_mouse_input(unsigned char *data, int nb, int autopoll) break; } + input_regs(adbhid[id]->input, regs); + input_report_key(adbhid[id]->input, BTN_LEFT, !((data[1] >> 7) & 1)); input_report_key(adbhid[id]->input, BTN_MIDDLE, !((data[2] >> 7) & 1)); @@ -445,7 +449,7 @@ adbhid_mouse_input(unsigned char *data, int nb, int autopoll) } static void -adbhid_buttons_input(unsigned char *data, int nb, int autopoll) +adbhid_buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int autopoll) { int id = (data[0] >> 4) & 0x0f; @@ -454,6 +458,8 @@ adbhid_buttons_input(unsigned char *data, int nb, int autopoll) return; } + input_regs(adbhid[id]->input, regs); + switch (adbhid[id]->original_handler_id) { default: case 0x02: /* Adjustable keyboard button device */ diff --git a/trunk/drivers/macintosh/macio-adb.c b/trunk/drivers/macintosh/macio-adb.c index 797cef72258f..4b08852c35ee 100644 --- a/trunk/drivers/macintosh/macio-adb.c +++ b/trunk/drivers/macintosh/macio-adb.c @@ -64,7 +64,7 @@ static DEFINE_SPINLOCK(macio_lock); static int macio_probe(void); static int macio_init(void); -static irqreturn_t macio_adb_interrupt(int irq, void *arg); +static irqreturn_t macio_adb_interrupt(int irq, void *arg, struct pt_regs *regs); static int macio_send_request(struct adb_request *req, int sync); static int macio_adb_autopoll(int devs); static void macio_adb_poll(void); @@ -189,7 +189,8 @@ static int macio_send_request(struct adb_request *req, int sync) return 0; } -static irqreturn_t macio_adb_interrupt(int irq, void *arg) +static irqreturn_t macio_adb_interrupt(int irq, void *arg, + struct pt_regs *regs) { int i, n, err; struct adb_request *req = NULL; @@ -259,7 +260,7 @@ static irqreturn_t macio_adb_interrupt(int irq, void *arg) (*done)(req); } if (ibuf_len) - adb_input(ibuf, ibuf_len, autopoll); + adb_input(ibuf, ibuf_len, regs, autopoll); return IRQ_RETVAL(handled); } @@ -270,6 +271,6 @@ static void macio_adb_poll(void) local_irq_save(flags); if (in_8(&adb->intr.r) != 0) - macio_adb_interrupt(0, NULL); + macio_adb_interrupt(0, NULL, NULL); local_irq_restore(flags); } diff --git a/trunk/drivers/macintosh/smu.c b/trunk/drivers/macintosh/smu.c index ade25b3fbb35..c0f9d82e4662 100644 --- a/trunk/drivers/macintosh/smu.c +++ b/trunk/drivers/macintosh/smu.c @@ -145,7 +145,7 @@ static void smu_start_cmd(void) } -static irqreturn_t smu_db_intr(int irq, void *arg) +static irqreturn_t smu_db_intr(int irq, void *arg, struct pt_regs *regs) { unsigned long flags; struct smu_cmd *cmd; @@ -224,7 +224,7 @@ static irqreturn_t smu_db_intr(int irq, void *arg) } -static irqreturn_t smu_msg_intr(int irq, void *arg) +static irqreturn_t smu_msg_intr(int irq, void *arg, struct pt_regs *regs) { /* I don't quite know what to do with this one, we seem to never * receive it, so I suspect we have to arm it someway in the SMU @@ -309,7 +309,7 @@ void smu_poll(void) gpio = pmac_do_feature_call(PMAC_FTR_READ_GPIO, NULL, smu->doorbell); if ((gpio & 7) == 7) - smu_db_intr(smu->db_irq, smu); + smu_db_intr(smu->db_irq, smu, NULL); } EXPORT_SYMBOL(smu_poll); diff --git a/trunk/drivers/macintosh/via-cuda.c b/trunk/drivers/macintosh/via-cuda.c index df66291b1322..7512d1c15207 100644 --- a/trunk/drivers/macintosh/via-cuda.c +++ b/trunk/drivers/macintosh/via-cuda.c @@ -98,8 +98,8 @@ static int cuda_reset_adb_bus(void); static int cuda_init_via(void); static void cuda_start(void); -static irqreturn_t cuda_interrupt(int irq, void *arg); -static void cuda_input(unsigned char *buf, int nb); +static irqreturn_t cuda_interrupt(int irq, void *arg, struct pt_regs *regs); +static void cuda_input(unsigned char *buf, int nb, struct pt_regs *regs); void cuda_poll(void); static int cuda_write(struct adb_request *req); @@ -437,12 +437,12 @@ cuda_poll(void) * disable_irq(), would that work on m68k ? --BenH */ local_irq_save(flags); - cuda_interrupt(0, NULL); + cuda_interrupt(0, NULL, NULL); local_irq_restore(flags); } static irqreturn_t -cuda_interrupt(int irq, void *arg) +cuda_interrupt(int irq, void *arg, struct pt_regs *regs) { int status; struct adb_request *req = NULL; @@ -594,12 +594,12 @@ cuda_interrupt(int irq, void *arg) (*done)(req); } if (ibuf_len) - cuda_input(ibuf, ibuf_len); + cuda_input(ibuf, ibuf_len, regs); return IRQ_HANDLED; } static void -cuda_input(unsigned char *buf, int nb) +cuda_input(unsigned char *buf, int nb, struct pt_regs *regs) { int i; @@ -615,7 +615,7 @@ cuda_input(unsigned char *buf, int nb) } #endif /* CONFIG_XMON */ #ifdef CONFIG_ADB - adb_input(buf+2, nb-2, buf[1] & 0x40); + adb_input(buf+2, nb-2, regs, buf[1] & 0x40); #endif /* CONFIG_ADB */ break; diff --git a/trunk/drivers/macintosh/via-macii.c b/trunk/drivers/macintosh/via-macii.c index 5d88d5b0ad99..2a2ffe060169 100644 --- a/trunk/drivers/macintosh/via-macii.c +++ b/trunk/drivers/macintosh/via-macii.c @@ -77,7 +77,7 @@ static volatile unsigned char *via; static int macii_init_via(void); static void macii_start(void); -static irqreturn_t macii_interrupt(int irq, void *arg); +static irqreturn_t macii_interrupt(int irq, void *arg, struct pt_regs *regs); static void macii_retransmit(int); static void macii_queue_poll(void); @@ -295,7 +295,7 @@ static void macii_poll(void) unsigned long flags; local_irq_save(flags); - if (via[IFR] & SR_INT) macii_interrupt(0, NULL); + if (via[IFR] & SR_INT) macii_interrupt(0, NULL, NULL); local_irq_restore(flags); } @@ -410,7 +410,7 @@ static void macii_start(void) * Note: As of 21/10/97, the MacII ADB part works including timeout detection * and retransmit (Talk to the last active device). */ -static irqreturn_t macii_interrupt(int irq, void *arg) +static irqreturn_t macii_interrupt(int irq, void *arg, struct pt_regs *regs) { int x, adbdir; unsigned long flags; @@ -602,7 +602,8 @@ static irqreturn_t macii_interrupt(int irq, void *arg) current_req = req->next; if (req->done) (*req->done)(req); } else { - adb_input(reply_buf, reply_ptr - reply_buf, 0); + adb_input(reply_buf, reply_ptr - reply_buf, + regs, 0); } /* diff --git a/trunk/drivers/macintosh/via-maciisi.c b/trunk/drivers/macintosh/via-maciisi.c index 1f0aa5dc9aa5..0129fcc3b183 100644 --- a/trunk/drivers/macintosh/via-maciisi.c +++ b/trunk/drivers/macintosh/via-maciisi.c @@ -84,8 +84,8 @@ static int maciisi_init(void); static int maciisi_send_request(struct adb_request* req, int sync); static void maciisi_sync(struct adb_request *req); static int maciisi_write(struct adb_request* req); -static irqreturn_t maciisi_interrupt(int irq, void* arg); -static void maciisi_input(unsigned char *buf, int nb); +static irqreturn_t maciisi_interrupt(int irq, void* arg, struct pt_regs* regs); +static void maciisi_input(unsigned char *buf, int nb, struct pt_regs *regs); static int maciisi_init_via(void); static void maciisi_poll(void); static int maciisi_start(void); @@ -421,7 +421,7 @@ maciisi_poll(void) local_irq_save(flags); if (via[IFR] & SR_INT) { - maciisi_interrupt(0, NULL); + maciisi_interrupt(0, NULL, NULL); } else /* avoid calling this function too quickly in a loop */ udelay(ADB_DELAY); @@ -433,7 +433,7 @@ maciisi_poll(void) register is either full or empty. In practice, I have no idea what it means :( */ static irqreturn_t -maciisi_interrupt(int irq, void* arg) +maciisi_interrupt(int irq, void* arg, struct pt_regs* regs) { int status; struct adb_request *req; @@ -612,7 +612,7 @@ maciisi_interrupt(int irq, void* arg) /* Obviously, we got it */ reading_reply = 0; } else { - maciisi_input(maciisi_rbuf, reply_ptr - maciisi_rbuf); + maciisi_input(maciisi_rbuf, reply_ptr - maciisi_rbuf, regs); } maciisi_state = idle; status = via[B] & (TIP|TREQ); @@ -657,7 +657,7 @@ maciisi_interrupt(int irq, void* arg) } static void -maciisi_input(unsigned char *buf, int nb) +maciisi_input(unsigned char *buf, int nb, struct pt_regs *regs) { #ifdef DEBUG_MACIISI_ADB int i; @@ -665,7 +665,7 @@ maciisi_input(unsigned char *buf, int nb) switch (buf[0]) { case ADB_PACKET: - adb_input(buf+2, nb-2, buf[1] & 0x40); + adb_input(buf+2, nb-2, regs, buf[1] & 0x40); break; default: #ifdef DEBUG_MACIISI_ADB diff --git a/trunk/drivers/macintosh/via-pmu.c b/trunk/drivers/macintosh/via-pmu.c index e63ea1c1f3c1..4f04fd0956a0 100644 --- a/trunk/drivers/macintosh/via-pmu.c +++ b/trunk/drivers/macintosh/via-pmu.c @@ -191,8 +191,8 @@ static int pmu_adb_reset_bus(void); static int init_pmu(void); static void pmu_start(void); -static irqreturn_t via_pmu_interrupt(int irq, void *arg); -static irqreturn_t gpio1_interrupt(int irq, void *arg); +static irqreturn_t via_pmu_interrupt(int irq, void *arg, struct pt_regs *regs); +static irqreturn_t gpio1_interrupt(int irq, void *arg, struct pt_regs *regs); static int proc_get_info(char *page, char **start, off_t off, int count, int *eof, void *data); static int proc_get_irqstats(char *page, char **start, off_t off, @@ -555,7 +555,7 @@ init_pmu(void) } if (pmu_state == idle) adb_int_pending = 1; - via_pmu_interrupt(0, NULL); + via_pmu_interrupt(0, NULL, NULL); udelay(10); } @@ -1215,7 +1215,7 @@ pmu_poll(void) return; if (disable_poll) return; - via_pmu_interrupt(0, NULL); + via_pmu_interrupt(0, NULL, NULL); } void @@ -1228,7 +1228,7 @@ pmu_poll_adb(void) /* Kicks ADB read when PMU is suspended */ adb_int_pending = 1; do { - via_pmu_interrupt(0, NULL); + via_pmu_interrupt(0, NULL, NULL); } while (pmu_suspended && (adb_int_pending || pmu_state != idle || req_awaiting_reply)); } @@ -1239,7 +1239,7 @@ pmu_wait_complete(struct adb_request *req) if (!via) return; while((pmu_state != idle && pmu_state != locked) || !req->complete) - via_pmu_interrupt(0, NULL); + via_pmu_interrupt(0, NULL, NULL); } /* This function loops until the PMU is idle and prevents it from @@ -1268,7 +1268,7 @@ pmu_suspend(void) spin_unlock_irqrestore(&pmu_lock, flags); if (req_awaiting_reply) adb_int_pending = 1; - via_pmu_interrupt(0, NULL); + via_pmu_interrupt(0, NULL, NULL); spin_lock_irqsave(&pmu_lock, flags); if (!adb_int_pending && pmu_state == idle && !req_awaiting_reply) { #ifdef SUSPEND_USES_PMU @@ -1318,7 +1318,7 @@ pmu_resume(void) /* Interrupt data could be the result data from an ADB cmd */ static void -pmu_handle_data(unsigned char *data, int len) +pmu_handle_data(unsigned char *data, int len, struct pt_regs *regs) { unsigned char ints, pirq; int i = 0; @@ -1393,7 +1393,7 @@ pmu_handle_data(unsigned char *data, int len) if (!(pmu_kind == PMU_OHARE_BASED && len == 4 && data[1] == 0x2c && data[3] == 0xff && (data[2] & ~1) == 0xf4)) - adb_input(data+1, len-1, 1); + adb_input(data+1, len-1, regs, 1); #endif /* CONFIG_ADB */ } } @@ -1431,7 +1431,7 @@ pmu_handle_data(unsigned char *data, int len) } static struct adb_request* -pmu_sr_intr(void) +pmu_sr_intr(struct pt_regs *regs) { struct adb_request *req; int bite = 0; @@ -1537,7 +1537,7 @@ pmu_sr_intr(void) } static irqreturn_t -via_pmu_interrupt(int irq, void *arg) +via_pmu_interrupt(int irq, void *arg, struct pt_regs *regs) { unsigned long flags; int intr; @@ -1567,7 +1567,7 @@ via_pmu_interrupt(int irq, void *arg) pmu_irq_stats[0]++; } if (intr & SR_INT) { - req = pmu_sr_intr(); + req = pmu_sr_intr(regs); if (req) break; } @@ -1613,7 +1613,7 @@ via_pmu_interrupt(int irq, void *arg) /* Deal with interrupt datas outside of the lock */ if (int_data >= 0) { - pmu_handle_data(interrupt_data[int_data], interrupt_data_len[int_data]); + pmu_handle_data(interrupt_data[int_data], interrupt_data_len[int_data], regs); spin_lock_irqsave(&pmu_lock, flags); ++disable_poll; int_data_state[int_data] = int_data_empty; @@ -1638,7 +1638,7 @@ pmu_unlock(void) static irqreturn_t -gpio1_interrupt(int irq, void *arg) +gpio1_interrupt(int irq, void *arg, struct pt_regs *regs) { unsigned long flags; @@ -1651,7 +1651,7 @@ gpio1_interrupt(int irq, void *arg) pmu_irq_stats[1]++; adb_int_pending = 1; spin_unlock_irqrestore(&pmu_lock, flags); - via_pmu_interrupt(0, NULL); + via_pmu_interrupt(0, NULL, NULL); return IRQ_HANDLED; } return IRQ_NONE; @@ -2116,7 +2116,7 @@ pmac_wakeup_devices(void) /* Force a poll of ADB interrupts */ adb_int_pending = 1; - via_pmu_interrupt(0, NULL); + via_pmu_interrupt(0, NULL, NULL); /* Restart jiffies & scheduling */ wakeup_decrementer(); diff --git a/trunk/drivers/macintosh/via-pmu68k.c b/trunk/drivers/macintosh/via-pmu68k.c index d9986f3a3fbf..9f4eff1d1a0f 100644 --- a/trunk/drivers/macintosh/via-pmu68k.c +++ b/trunk/drivers/macintosh/via-pmu68k.c @@ -107,7 +107,7 @@ BLOCKING_NOTIFIER_HEAD(sleep_notifier_list); static int pmu_probe(void); static int pmu_init(void); static void pmu_start(void); -static irqreturn_t pmu_interrupt(int irq, void *arg); +static irqreturn_t pmu_interrupt(int irq, void *arg, struct pt_regs *regs); static int pmu_send_request(struct adb_request *req, int sync); static int pmu_autopoll(int devs); void pmu_poll(void); @@ -118,7 +118,8 @@ static void pmu_start(void); static void send_byte(int x); static void recv_byte(void); static void pmu_done(struct adb_request *req); -static void pmu_handle_data(unsigned char *data, int len); +static void pmu_handle_data(unsigned char *data, int len, + struct pt_regs *regs); static void set_volume(int level); static void pmu_enable_backlight(int on); static void pmu_set_brightness(int level); @@ -221,7 +222,7 @@ pmu_init(void) } if (pmu_state == idle) { adb_int_pending = 1; - pmu_interrupt(0, NULL); + pmu_interrupt(0, NULL, NULL); } pmu_poll(); udelay(10); @@ -562,17 +563,17 @@ pmu_poll(void) local_irq_save(flags); if (via1[IFR] & SR_INT) { via1[IFR] = SR_INT; - pmu_interrupt(IRQ_MAC_ADB_SR, NULL); + pmu_interrupt(IRQ_MAC_ADB_SR, NULL, NULL); } if (via1[IFR] & CB1_INT) { via1[IFR] = CB1_INT; - pmu_interrupt(IRQ_MAC_ADB_CL, NULL); + pmu_interrupt(IRQ_MAC_ADB_CL, NULL, NULL); } local_irq_restore(flags); } static irqreturn_t -pmu_interrupt(int irq, void *dev_id) +pmu_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct adb_request *req; int timeout, bite = 0; /* to prevent compiler warning */ @@ -656,7 +657,7 @@ pmu_interrupt(int irq, void *dev_id) } if (pmu_state == reading_intr) { - pmu_handle_data(interrupt_data, data_index); + pmu_handle_data(interrupt_data, data_index, regs); } else { req = current_req; current_req = req->next; @@ -700,7 +701,7 @@ pmu_done(struct adb_request *req) /* Interrupt data could be the result data from an ADB cmd */ static void -pmu_handle_data(unsigned char *data, int len) +pmu_handle_data(unsigned char *data, int len, struct pt_regs *regs) { static int show_pmu_ints = 1; @@ -725,7 +726,7 @@ pmu_handle_data(unsigned char *data, int len) } pmu_done(req); } else { - adb_input(data+1, len-1, 1); + adb_input(data+1, len-1, regs, 1); } } else { if (data[0] == 0x08 && len == 3) { diff --git a/trunk/drivers/macintosh/windfarm_pm112.c b/trunk/drivers/macintosh/windfarm_pm112.c index b3fbb45bc90a..ef66bf2778ec 100644 --- a/trunk/drivers/macintosh/windfarm_pm112.c +++ b/trunk/drivers/macintosh/windfarm_pm112.c @@ -650,26 +650,24 @@ static struct notifier_block pm112_events = { .notifier_call = pm112_wf_notify, }; -static int wf_pm112_probe(struct platform_device *dev) +static int wf_pm112_probe(struct device *dev) { wf_register_client(&pm112_events); return 0; } -static int __devexit wf_pm112_remove(struct platform_device *dev) +static int wf_pm112_remove(struct device *dev) { wf_unregister_client(&pm112_events); /* should release all sensors and controls */ return 0; } -static struct platform_driver wf_pm112_driver = { +static struct device_driver wf_pm112_driver = { + .name = "windfarm", + .bus = &platform_bus_type, .probe = wf_pm112_probe, - .remove = __devexit_p(wf_pm112_remove), - .driver = { - .name = "windfarm", - .bus = &platform_bus_type, - }, + .remove = wf_pm112_remove, }; static int __init wf_pm112_init(void) @@ -685,24 +683,13 @@ static int __init wf_pm112_init(void) ++nr_cores; printk(KERN_INFO "windfarm: initializing for dual-core desktop G5\n"); - -#ifdef MODULE - request_module("windfarm_smu_controls"); - request_module("windfarm_smu_sensors"); - request_module("windfarm_smu_sat"); - request_module("windfarm_lm75_sensor"); - request_module("windfarm_max6690_sensor"); - request_module("windfarm_cpufreq_clamp"); - -#endif /* MODULE */ - - platform_driver_register(&wf_pm112_driver); + driver_register(&wf_pm112_driver); return 0; } static void __exit wf_pm112_exit(void) { - platform_driver_unregister(&wf_pm112_driver); + driver_unregister(&wf_pm112_driver); } module_init(wf_pm112_init); diff --git a/trunk/drivers/macintosh/windfarm_pm81.c b/trunk/drivers/macintosh/windfarm_pm81.c index f24fa734046a..2ff546e4c92f 100644 --- a/trunk/drivers/macintosh/windfarm_pm81.c +++ b/trunk/drivers/macintosh/windfarm_pm81.c @@ -131,6 +131,8 @@ static int wf_smu_mach_model; /* machine model id */ +static struct device *wf_smu_dev; + /* Controls & sensors */ static struct wf_sensor *sensor_cpu_power; static struct wf_sensor *sensor_cpu_temp; @@ -715,14 +717,16 @@ static int wf_init_pm(void) return 0; } -static int wf_smu_probe(struct platform_device *ddev) +static int wf_smu_probe(struct device *ddev) { + wf_smu_dev = ddev; + wf_register_client(&wf_smu_events); return 0; } -static int __devexit wf_smu_remove(struct platform_device *ddev) +static int wf_smu_remove(struct device *ddev) { wf_unregister_client(&wf_smu_events); @@ -762,16 +766,16 @@ static int __devexit wf_smu_remove(struct platform_device *ddev) if (wf_smu_cpu_fans) kfree(wf_smu_cpu_fans); + wf_smu_dev = NULL; + return 0; } -static struct platform_driver wf_smu_driver = { +static struct device_driver wf_smu_driver = { + .name = "windfarm", + .bus = &platform_bus_type, .probe = wf_smu_probe, - .remove = __devexit_p(wf_smu_remove), - .driver = { - .name = "windfarm", - .bus = &platform_bus_type, - }, + .remove = wf_smu_remove, }; @@ -788,10 +792,9 @@ static int __init wf_smu_init(void) request_module("windfarm_smu_controls"); request_module("windfarm_smu_sensors"); request_module("windfarm_lm75_sensor"); - request_module("windfarm_cpufreq_clamp"); #endif /* MODULE */ - platform_driver_register(&wf_smu_driver); + driver_register(&wf_smu_driver); } return rc; @@ -800,7 +803,7 @@ static int __init wf_smu_init(void) static void __exit wf_smu_exit(void) { - platform_driver_unregister(&wf_smu_driver); + driver_unregister(&wf_smu_driver); } diff --git a/trunk/drivers/macintosh/windfarm_pm91.c b/trunk/drivers/macintosh/windfarm_pm91.c index 26eee69ebe6d..59e9ffe37c39 100644 --- a/trunk/drivers/macintosh/windfarm_pm91.c +++ b/trunk/drivers/macintosh/windfarm_pm91.c @@ -63,6 +63,8 @@ */ #undef HACKED_OVERTEMP +static struct device *wf_smu_dev; + /* Controls & sensors */ static struct wf_sensor *sensor_cpu_power; static struct wf_sensor *sensor_cpu_temp; @@ -639,14 +641,16 @@ static int wf_init_pm(void) return 0; } -static int wf_smu_probe(struct platform_device *ddev) +static int wf_smu_probe(struct device *ddev) { + wf_smu_dev = ddev; + wf_register_client(&wf_smu_events); return 0; } -static int __devexit wf_smu_remove(struct platform_device *ddev) +static int wf_smu_remove(struct device *ddev) { wf_unregister_client(&wf_smu_events); @@ -694,16 +698,16 @@ static int __devexit wf_smu_remove(struct platform_device *ddev) if (wf_smu_cpu_fans) kfree(wf_smu_cpu_fans); + wf_smu_dev = NULL; + return 0; } -static struct platform_driver wf_smu_driver = { +static struct device_driver wf_smu_driver = { + .name = "windfarm", + .bus = &platform_bus_type, .probe = wf_smu_probe, - .remove = __devexit_p(wf_smu_remove), - .driver = { - .name = "windfarm", - .bus = &platform_bus_type, - }, + .remove = wf_smu_remove, }; @@ -719,10 +723,9 @@ static int __init wf_smu_init(void) request_module("windfarm_smu_controls"); request_module("windfarm_smu_sensors"); request_module("windfarm_lm75_sensor"); - request_module("windfarm_cpufreq_clamp"); #endif /* MODULE */ - platform_driver_register(&wf_smu_driver); + driver_register(&wf_smu_driver); } return rc; @@ -731,7 +734,7 @@ static int __init wf_smu_init(void) static void __exit wf_smu_exit(void) { - platform_driver_unregister(&wf_smu_driver); + driver_unregister(&wf_smu_driver); } diff --git a/trunk/drivers/mca/mca-bus.c b/trunk/drivers/mca/mca-bus.c index da862e4632dd..09baa43b2599 100644 --- a/trunk/drivers/mca/mca-bus.c +++ b/trunk/drivers/mca/mca-bus.c @@ -100,7 +100,6 @@ static DEVICE_ATTR(pos, S_IRUGO, mca_show_pos, NULL); int __init mca_register_device(int bus, struct mca_device *mca_dev) { struct mca_bus *mca_bus = mca_root_busses[bus]; - int rc; mca_dev->dev.parent = &mca_bus->dev; mca_dev->dev.bus = &mca_bus_type; @@ -109,23 +108,13 @@ int __init mca_register_device(int bus, struct mca_device *mca_dev) mca_dev->dev.dma_mask = &mca_dev->dma_mask; mca_dev->dev.coherent_dma_mask = mca_dev->dma_mask; - rc = device_register(&mca_dev->dev); - if (rc) - goto err_out; + if (device_register(&mca_dev->dev)) + return 0; - rc = device_create_file(&mca_dev->dev, &dev_attr_id); - if (rc) goto err_out_devreg; - rc = device_create_file(&mca_dev->dev, &dev_attr_pos); - if (rc) goto err_out_id; + device_create_file(&mca_dev->dev, &dev_attr_id); + device_create_file(&mca_dev->dev, &dev_attr_pos); return 1; - -err_out_id: - device_remove_file(&mca_dev->dev, &dev_attr_id); -err_out_devreg: - device_unregister(&mca_dev->dev); -err_out: - return 0; } /* */ @@ -141,16 +130,13 @@ struct mca_bus * __devinit mca_attach_bus(int bus) return NULL; } - mca_bus = kzalloc(sizeof(struct mca_bus), GFP_KERNEL); + mca_bus = kmalloc(sizeof(struct mca_bus), GFP_KERNEL); if (!mca_bus) return NULL; - + memset(mca_bus, 0, sizeof(struct mca_bus)); sprintf(mca_bus->dev.bus_id,"mca%d",bus); sprintf(mca_bus->name,"Host %s MCA Bridge", bus ? "Secondary" : "Primary"); - if (device_register(&mca_bus->dev)) { - kfree(mca_bus); - return NULL; - } + device_register(&mca_bus->dev); mca_root_busses[bus] = mca_bus; diff --git a/trunk/drivers/md/bitmap.c b/trunk/drivers/md/bitmap.c index d6f614738bbd..8e67634e79a0 100644 --- a/trunk/drivers/md/bitmap.c +++ b/trunk/drivers/md/bitmap.c @@ -536,7 +536,7 @@ static int bitmap_read_sb(struct bitmap *bitmap) printk(KERN_INFO "%s: bitmap file is out of date (%llu < %llu) " "-- forcing full recovery\n", bmname(bitmap), events, (unsigned long long) bitmap->mddev->events); - sb->state |= cpu_to_le32(BITMAP_STALE); + sb->state |= BITMAP_STALE; } success: /* assign fields using values from superblock */ @@ -544,11 +544,11 @@ static int bitmap_read_sb(struct bitmap *bitmap) bitmap->daemon_sleep = daemon_sleep; bitmap->daemon_lastrun = jiffies; bitmap->max_write_behind = write_behind; - bitmap->flags |= le32_to_cpu(sb->state); + bitmap->flags |= sb->state; if (le32_to_cpu(sb->version) == BITMAP_MAJOR_HOSTENDIAN) bitmap->flags |= BITMAP_HOSTENDIAN; bitmap->events_cleared = le64_to_cpu(sb->events_cleared); - if (sb->state & cpu_to_le32(BITMAP_STALE)) + if (sb->state & BITMAP_STALE) bitmap->events_cleared = bitmap->mddev->events; err = 0; out: @@ -578,9 +578,9 @@ static void bitmap_mask_state(struct bitmap *bitmap, enum bitmap_state bits, spin_unlock_irqrestore(&bitmap->lock, flags); sb = (bitmap_super_t *)kmap_atomic(bitmap->sb_page, KM_USER0); switch (op) { - case MASK_SET: sb->state |= cpu_to_le32(bits); + case MASK_SET: sb->state |= bits; break; - case MASK_UNSET: sb->state &= cpu_to_le32(~bits); + case MASK_UNSET: sb->state &= ~bits; break; default: BUG(); } @@ -1413,7 +1413,7 @@ int bitmap_create(mddev_t *mddev) int err; sector_t start; - BUILD_BUG_ON(sizeof(bitmap_super_t) != 256); + BUG_ON(sizeof(bitmap_super_t) != 256); if (!file && !mddev->bitmap_offset) /* bitmap disabled, nothing to do */ return 0; diff --git a/trunk/drivers/md/dm-crypt.c b/trunk/drivers/md/dm-crypt.c index 08a40f4e4f60..655d816760e5 100644 --- a/trunk/drivers/md/dm-crypt.c +++ b/trunk/drivers/md/dm-crypt.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -603,7 +602,7 @@ static void process_write(struct crypt_io *io) /* out of memory -> run queues */ if (remaining) - congestion_wait(bio_data_dir(clone), HZ/100); + blk_congestion_wait(bio_data_dir(clone), HZ/100); } } @@ -915,6 +914,8 @@ static int crypt_status(struct dm_target *ti, status_type_t type, char *result, unsigned int maxlen) { struct crypt_config *cc = (struct crypt_config *) ti->private; + const char *cipher; + const char *chainmode = NULL; unsigned int sz = 0; switch (type) { @@ -923,11 +924,14 @@ static int crypt_status(struct dm_target *ti, status_type_t type, break; case STATUSTYPE_TABLE: + cipher = crypto_blkcipher_name(cc->tfm); + + chainmode = cc->chainmode; + if (cc->iv_mode) - DMEMIT("%s-%s-%s ", cc->cipher, cc->chainmode, - cc->iv_mode); + DMEMIT("%s-%s-%s ", cipher, chainmode, cc->iv_mode); else - DMEMIT("%s-%s ", cc->cipher, cc->chainmode); + DMEMIT("%s-%s ", cipher, chainmode); if (cc->key_size > 0) { if ((maxlen - sz) < ((cc->key_size << 1) + 1)) diff --git a/trunk/drivers/md/dm-ioctl.c b/trunk/drivers/md/dm-ioctl.c index 4510ad8f971c..d13bb15a8a02 100644 --- a/trunk/drivers/md/dm-ioctl.c +++ b/trunk/drivers/md/dm-ioctl.c @@ -606,14 +606,9 @@ static struct hash_cell *__find_device_hash_cell(struct dm_ioctl *param) return __get_name_cell(param->name); md = dm_get_md(huge_decode_dev(param->dev)); - if (!md) - goto out; + if (md) + mdptr = dm_get_mdptr(md); - mdptr = dm_get_mdptr(md); - if (!mdptr) - dm_put(md); - -out: return mdptr; } diff --git a/trunk/drivers/md/dm-raid1.c b/trunk/drivers/md/dm-raid1.c index 48a653b3f518..659224cb7c53 100644 --- a/trunk/drivers/md/dm-raid1.c +++ b/trunk/drivers/md/dm-raid1.c @@ -24,7 +24,6 @@ static struct workqueue_struct *_kmirrord_wq; static struct work_struct _kmirrord_work; -static DECLARE_WAIT_QUEUE_HEAD(_kmirrord_recovery_stopped); static inline void wake(void) { @@ -84,7 +83,6 @@ struct region_hash { struct list_head *buckets; spinlock_t region_lock; - atomic_t recovery_in_flight; struct semaphore recovery_count; struct list_head clean_regions; struct list_head quiesced_regions; @@ -193,7 +191,6 @@ static int rh_init(struct region_hash *rh, struct mirror_set *ms, spin_lock_init(&rh->region_lock); sema_init(&rh->recovery_count, 0); - atomic_set(&rh->recovery_in_flight, 0); INIT_LIST_HEAD(&rh->clean_regions); INIT_LIST_HEAD(&rh->quiesced_regions); INIT_LIST_HEAD(&rh->recovered_regions); @@ -385,8 +382,6 @@ static void rh_update_states(struct region_hash *rh) rh->log->type->clear_region(rh->log, reg->key); rh->log->type->complete_resync_work(rh->log, reg->key, 1); dispatch_bios(rh->ms, ®->delayed_bios); - if (atomic_dec_and_test(&rh->recovery_in_flight)) - wake_up_all(&_kmirrord_recovery_stopped); up(&rh->recovery_count); mempool_free(reg, rh->region_pool); } @@ -507,21 +502,11 @@ static int __rh_recovery_prepare(struct region_hash *rh) static void rh_recovery_prepare(struct region_hash *rh) { - /* Extra reference to avoid race with rh_stop_recovery */ - atomic_inc(&rh->recovery_in_flight); - - while (!down_trylock(&rh->recovery_count)) { - atomic_inc(&rh->recovery_in_flight); + while (!down_trylock(&rh->recovery_count)) if (__rh_recovery_prepare(rh) <= 0) { - atomic_dec(&rh->recovery_in_flight); up(&rh->recovery_count); break; } - } - - /* Drop the extra reference */ - if (atomic_dec_and_test(&rh->recovery_in_flight)) - wake_up_all(&_kmirrord_recovery_stopped); } /* @@ -1192,11 +1177,6 @@ static void mirror_postsuspend(struct dm_target *ti) struct dirty_log *log = ms->rh.log; rh_stop_recovery(&ms->rh); - - /* Wait for all I/O we generated to complete */ - wait_event(_kmirrord_recovery_stopped, - !atomic_read(&ms->rh.recovery_in_flight)); - if (log->type->suspend && log->type->suspend(log)) /* FIXME: need better error handling */ DMWARN("log suspend failed"); diff --git a/trunk/drivers/md/dm-round-robin.c b/trunk/drivers/md/dm-round-robin.c index 6f9fcd4db9b5..c5a16c550122 100644 --- a/trunk/drivers/md/dm-round-robin.c +++ b/trunk/drivers/md/dm-round-robin.c @@ -136,7 +136,7 @@ static int rr_add_path(struct path_selector *ps, struct path *path, path->pscontext = pi; - list_add_tail(&pi->list, &s->valid_paths); + list_add(&pi->list, &s->valid_paths); return 0; } diff --git a/trunk/drivers/md/dm.c b/trunk/drivers/md/dm.c index fc4f743f3b53..b5764a86c8b5 100644 --- a/trunk/drivers/md/dm.c +++ b/trunk/drivers/md/dm.c @@ -1285,7 +1285,7 @@ int dm_suspend(struct mapped_device *md, int do_lockfs) down(&md->suspend_lock); if (dm_suspended(md)) - goto out_unlock; + goto out; map = dm_get_table(md); @@ -1361,8 +1361,6 @@ int dm_suspend(struct mapped_device *md, int do_lockfs) } dm_table_put(map); - -out_unlock: up(&md->suspend_lock); return r; } diff --git a/trunk/drivers/md/md.c b/trunk/drivers/md/md.c index 8cbf9c9df1c3..cb8281605be8 100644 --- a/trunk/drivers/md/md.c +++ b/trunk/drivers/md/md.c @@ -974,13 +974,12 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev) * version 1 superblock */ -static __le32 calc_sb_1_csum(struct mdp_superblock_1 * sb) +static unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb) { - __le32 disk_csum; - u32 csum; + unsigned int disk_csum, csum; unsigned long long newcsum; int size = 256 + le32_to_cpu(sb->max_dev)*2; - __le32 *isuper = (__le32*)sb; + unsigned int *isuper = (unsigned int*)sb; int i; disk_csum = sb->sb_csum; @@ -990,7 +989,7 @@ static __le32 calc_sb_1_csum(struct mdp_superblock_1 * sb) newcsum += le32_to_cpu(*isuper++); if (size == 2) - newcsum += le16_to_cpu(*(__le16*) isuper); + newcsum += le16_to_cpu(*(unsigned short*) isuper); csum = (newcsum & 0xffffffff) + (newcsum >> 32); sb->sb_csum = disk_csum; @@ -1107,7 +1106,7 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version) if (le32_to_cpu(sb->chunksize)) rdev->size &= ~((sector_t)le32_to_cpu(sb->chunksize)/2 - 1); - if (le64_to_cpu(sb->size) > rdev->size*2) + if (le32_to_cpu(sb->size) > rdev->size*2) return -EINVAL; return ret; } @@ -1229,7 +1228,7 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev) else sb->resync_offset = cpu_to_le64(0); - sb->cnt_corrected_read = cpu_to_le32(atomic_read(&rdev->corrected_errors)); + sb->cnt_corrected_read = atomic_read(&rdev->corrected_errors); sb->raid_disks = cpu_to_le32(mddev->raid_disks); sb->size = cpu_to_le64(mddev->size<<1); @@ -2003,7 +2002,6 @@ static mdk_rdev_t *md_import_device(dev_t newdev, int super_format, int super_mi kobject_init(&rdev->kobj); rdev->desc_nr = -1; - rdev->saved_raid_disk = -1; rdev->flags = 0; rdev->data_offset = 0; rdev->sb_events = 0; @@ -3200,7 +3198,6 @@ static int do_md_run(mddev_t * mddev) mddev->changed = 1; md_new_event(mddev); - kobject_uevent(&mddev->gendisk->kobj, KOBJ_CHANGE); return 0; } @@ -3852,7 +3849,6 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev) } clear_bit(In_sync, &rdev->flags); rdev->desc_nr = -1; - rdev->saved_raid_disk = -1; err = bind_rdev_to_array(rdev, mddev); if (err) goto abort_export; @@ -4046,8 +4042,11 @@ static int update_size(mddev_t *mddev, unsigned long size) return -EBUSY; ITERATE_RDEV(mddev,rdev,tmp) { sector_t avail; - avail = rdev->size * 2; - + if (rdev->sb_offset > rdev->data_offset) + avail = (rdev->sb_offset*2) - rdev->data_offset; + else + avail = get_capacity(rdev->bdev->bd_disk) + - rdev->data_offset; if (fit && (size == 0 || size > avail/2)) size = avail/2; if (avail < ((sector_t)size << 1)) @@ -4486,7 +4485,6 @@ static int md_thread(void * arg) * many dirty RAID5 blocks. */ - current->flags |= PF_NOFREEZE; allow_signal(SIGKILL); while (!kthread_should_stop()) { @@ -4503,6 +4501,7 @@ static int md_thread(void * arg) test_bit(THREAD_WAKEUP, &thread->flags) || kthread_should_stop(), thread->timeout); + try_to_freeze(); clear_bit(THREAD_WAKEUP, &thread->flags); @@ -4912,7 +4911,6 @@ static unsigned int mdstat_poll(struct file *filp, poll_table *wait) } static struct file_operations md_seq_fops = { - .owner = THIS_MODULE, .open = md_seq_open, .read = seq_read, .llseek = seq_lseek, diff --git a/trunk/drivers/md/multipath.c b/trunk/drivers/md/multipath.c index 14da37fee37b..171ff41b52b0 100644 --- a/trunk/drivers/md/multipath.c +++ b/trunk/drivers/md/multipath.c @@ -277,7 +277,6 @@ static void multipath_error (mddev_t *mddev, mdk_rdev_t *rdev) set_bit(Faulty, &rdev->flags); set_bit(MD_CHANGE_DEVS, &mddev->flags); conf->working_disks--; - mddev->degraded++; printk(KERN_ALERT "multipath: IO failure on %s," " disabling IO path. \n Operation continuing" " on %d IO paths.\n", @@ -337,7 +336,6 @@ static int multipath_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9); conf->working_disks++; - mddev->degraded--; rdev->raid_disk = path; set_bit(In_sync, &rdev->flags); rcu_assign_pointer(p->rdev, rdev); @@ -503,7 +501,7 @@ static int multipath_run (mddev_t *mddev) mdname(mddev)); goto out_free_conf; } - mddev->degraded = conf->raid_disks - conf->working_disks; + mddev->degraded = conf->raid_disks = conf->working_disks; conf->pool = mempool_create_kzalloc_pool(NR_RESERVED_BUFS, sizeof(struct multipath_bh)); diff --git a/trunk/drivers/md/raid1.c b/trunk/drivers/md/raid1.c index 656fae912fe3..dc9d2def0270 100644 --- a/trunk/drivers/md/raid1.c +++ b/trunk/drivers/md/raid1.c @@ -1474,8 +1474,8 @@ static void fix_read_error(conf_t *conf, int read_disk, "raid1:%s: read error corrected " "(%d sectors at %llu on %s)\n", mdname(mddev), s, - (unsigned long long)(sect + - rdev->data_offset), + (unsigned long long)sect + + rdev->data_offset, bdevname(rdev->bdev, b)); } } diff --git a/trunk/drivers/md/raid10.c b/trunk/drivers/md/raid10.c index 7492d6033ac6..1250f0eab4af 100644 --- a/trunk/drivers/md/raid10.c +++ b/trunk/drivers/md/raid10.c @@ -1470,8 +1470,8 @@ static void fix_read_error(conf_t *conf, mddev_t *mddev, r10bio_t *r10_bio) "raid10:%s: read error corrected" " (%d sectors at %llu on %s)\n", mdname(mddev), s, - (unsigned long long)(sect+ - rdev->data_offset), + (unsigned long long)sect+ + rdev->data_offset, bdevname(rdev->bdev, b)); rdev_dec_pending(rdev, mddev); @@ -2079,7 +2079,7 @@ static int run(mddev_t *mddev) disk = conf->mirrors + i; if (!disk->rdev || - !test_bit(In_sync, &disk->rdev->flags)) { + !test_bit(In_sync, &rdev->flags)) { disk->head_position = 0; mddev->degraded++; } diff --git a/trunk/drivers/md/raid5.c b/trunk/drivers/md/raid5.c index 69c3e201fa3b..e14f45780720 100644 --- a/trunk/drivers/md/raid5.c +++ b/trunk/drivers/md/raid5.c @@ -3659,7 +3659,7 @@ static void end_reshape(raid5_conf_t *conf) bdev = bdget_disk(conf->mddev->gendisk, 0); if (bdev) { mutex_lock(&bdev->bd_inode->i_mutex); - i_size_write(bdev->bd_inode, (loff_t)conf->mddev->array_size << 10); + i_size_write(bdev->bd_inode, conf->mddev->array_size << 10); mutex_unlock(&bdev->bd_inode->i_mutex); bdput(bdev); } diff --git a/trunk/drivers/media/common/saa7146_core.c b/trunk/drivers/media/common/saa7146_core.c index 86cbdbcf9d7d..b88451e33c09 100644 --- a/trunk/drivers/media/common/saa7146_core.c +++ b/trunk/drivers/media/common/saa7146_core.c @@ -230,7 +230,7 @@ int saa7146_pgtable_build_single(struct pci_dev *pci, struct saa7146_pgtable *pt /********************************************************************************/ /* interrupt handler */ -static irqreturn_t interrupt_hw(int irq, void *dev_id) +static irqreturn_t interrupt_hw(int irq, void *dev_id, struct pt_regs *regs) { struct saa7146_dev *dev = dev_id; u32 isr = 0; diff --git a/trunk/drivers/media/common/saa7146_i2c.c b/trunk/drivers/media/common/saa7146_i2c.c index 5297a365c928..d9953f7a8b6b 100644 --- a/trunk/drivers/media/common/saa7146_i2c.c +++ b/trunk/drivers/media/common/saa7146_i2c.c @@ -217,9 +217,11 @@ static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_d } /* wait until we get a transfer done or error */ timeout = jiffies + HZ/100 + 1; /* 10ms */ - /* first read usually delivers bogus results... */ - saa7146_i2c_status(dev); while(1) { + /** + * first read usually delivers bogus results... + */ + saa7146_i2c_status(dev); status = saa7146_i2c_status(dev); if ((status & 0x3) != 1) break; @@ -230,10 +232,10 @@ static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_d DEB_I2C(("saa7146_i2c_writeout: timed out waiting for end of xfer\n")); return -EIO; } - if (++trial < 50 && short_delay) + if ((++trial < 20) && short_delay) udelay(10); else - msleep(1); + msleep(1); } } diff --git a/trunk/drivers/media/dvb/b2c2/flexcop-pci.c b/trunk/drivers/media/dvb/b2c2/flexcop-pci.c index 06893243f3d4..eb2e6432c8c2 100644 --- a/trunk/drivers/media/dvb/b2c2/flexcop-pci.c +++ b/trunk/drivers/media/dvb/b2c2/flexcop-pci.c @@ -122,7 +122,7 @@ static void flexcop_pci_irq_check_work(void *data) /* When PID filtering is turned on, we use the timer IRQ, because small amounts * of data need to be passed to the user space instantly as well. When PID * filtering is turned off, we use the page-change-IRQ */ -static irqreturn_t flexcop_pci_isr(int irq, void *dev_id) +static irqreturn_t flexcop_pci_isr(int irq, void *dev_id, struct pt_regs *regs) { struct flexcop_pci *fc_pci = dev_id; struct flexcop_device *fc = fc_pci->fc_dev; diff --git a/trunk/drivers/media/dvb/b2c2/flexcop-usb.c b/trunk/drivers/media/dvb/b2c2/flexcop-usb.c index 87fb75f0d1cf..515954f96c9a 100644 --- a/trunk/drivers/media/dvb/b2c2/flexcop-usb.c +++ b/trunk/drivers/media/dvb/b2c2/flexcop-usb.c @@ -246,7 +246,7 @@ static int flexcop_usb_i2c_req(struct flexcop_usb *fc_usb, wIndex = (chipaddr << 8 ) | addr; deb_i2c("i2c %2d: %02x %02x %02x %02x %02x %02x\n",func,request_type,req, - wValue & 0xff, wValue >> 8, wIndex & 0xff, wIndex >> 8); + ((wValue && 0xff) << 8),wValue >> 8,((wIndex && 0xff) << 8),wIndex >> 8); len = usb_control_msg(fc_usb->udev,pipe, req, @@ -328,7 +328,7 @@ static void flexcop_usb_process_frame(struct flexcop_usb *fc_usb, u8 *buffer, in fc_usb->tmp_buffer_length = l; } -static void flexcop_usb_urb_complete(struct urb *urb) +static void flexcop_usb_urb_complete(struct urb *urb, struct pt_regs *ptregs) { struct flexcop_usb *fc_usb = urb->context; int i; diff --git a/trunk/drivers/media/dvb/bt8xx/bt878.c b/trunk/drivers/media/dvb/bt8xx/bt878.c index 329a51c18562..755822ee6e9b 100644 --- a/trunk/drivers/media/dvb/bt8xx/bt878.c +++ b/trunk/drivers/media/dvb/bt8xx/bt878.c @@ -266,7 +266,7 @@ EXPORT_SYMBOL(bt878_stop); /* Interrupt service routine */ /*****************************/ -static irqreturn_t bt878_irq(int irq, void *dev_id) +static irqreturn_t bt878_irq(int irq, void *dev_id, struct pt_regs *regs) { u32 stat, astat, mask; int count; diff --git a/trunk/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/trunk/drivers/media/dvb/bt8xx/dvb-bt8xx.c index 14e69a736eda..fb6c4cc8477d 100644 --- a/trunk/drivers/media/dvb/bt8xx/dvb-bt8xx.c +++ b/trunk/drivers/media/dvb/bt8xx/dvb-bt8xx.c @@ -665,10 +665,6 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) case BTTV_BOARD_TWINHAN_DST: /* DST is not a frontend driver !!! */ state = (struct dst_state *) kmalloc(sizeof (struct dst_state), GFP_KERNEL); - if (!state) { - printk("dvb_bt8xx: No memory\n"); - break; - } /* Setup the Card */ state->config = &dst_config; state->i2c = card->i2c_adapter; diff --git a/trunk/drivers/media/dvb/cinergyT2/cinergyT2.c b/trunk/drivers/media/dvb/cinergyT2/cinergyT2.c index 55bc891768c2..410fa6d620ff 100644 --- a/trunk/drivers/media/dvb/cinergyT2/cinergyT2.c +++ b/trunk/drivers/media/dvb/cinergyT2/cinergyT2.c @@ -238,7 +238,7 @@ static void cinergyt2_sleep (struct cinergyt2 *cinergyt2, int sleep) cinergyt2->sleeping = sleep; } -static void cinergyt2_stream_irq (struct urb *urb); +static void cinergyt2_stream_irq (struct urb *urb, struct pt_regs *regs); static int cinergyt2_submit_stream_urb (struct cinergyt2 *cinergyt2, struct urb *urb) { @@ -258,7 +258,7 @@ static int cinergyt2_submit_stream_urb (struct cinergyt2 *cinergyt2, struct urb return err; } -static void cinergyt2_stream_irq (struct urb *urb) +static void cinergyt2_stream_irq (struct urb *urb, struct pt_regs *regs) { struct cinergyt2 *cinergyt2 = urb->context; @@ -275,7 +275,8 @@ static void cinergyt2_free_stream_urbs (struct cinergyt2 *cinergyt2) int i; for (i=0; istream_urb[i]); + if (cinergyt2->stream_urb[i]) + usb_free_urb(cinergyt2->stream_urb[i]); usb_buffer_free(cinergyt2->udev, STREAM_URB_COUNT*STREAM_BUF_SIZE, cinergyt2->streambuf, cinergyt2->streambuf_dmahandle); @@ -319,7 +320,8 @@ static void cinergyt2_stop_stream_xfer (struct cinergyt2 *cinergyt2) cinergyt2_control_stream_transfer(cinergyt2, 0); for (i=0; istream_urb[i]); + if (cinergyt2->stream_urb[i]) + usb_kill_urb(cinergyt2->stream_urb[i]); } static int cinergyt2_start_stream_xfer (struct cinergyt2 *cinergyt2) diff --git a/trunk/drivers/media/dvb/dvb-core/Kconfig b/trunk/drivers/media/dvb/dvb-core/Kconfig index 1990eda10c46..e46eae3b9be2 100644 --- a/trunk/drivers/media/dvb/dvb-core/Kconfig +++ b/trunk/drivers/media/dvb/dvb-core/Kconfig @@ -19,6 +19,6 @@ config DVB_CORE_ATTACH allow the card drivers to only load the frontend modules they require. This saves several KBytes of memory. - Note: You will need module-init-tools v3.2 or later for this feature. + Note: You will need moudule-init-tools v3.2 or later for this feature. If unsure say Y. diff --git a/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c b/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c index a2ab2eebfc68..53304e6991ac 100644 --- a/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -348,7 +348,7 @@ static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wra static void dvb_frontend_swzigzag(struct dvb_frontend *fe) { - fe_status_t s = 0; + fe_status_t s; struct dvb_frontend_private *fepriv = fe->frontend_priv; /* if we've got no parameters, just keep idling */ diff --git a/trunk/drivers/media/dvb/dvb-usb/Kconfig b/trunk/drivers/media/dvb/dvb-usb/Kconfig index a263b3f3c21d..2cc5caa26a0a 100644 --- a/trunk/drivers/media/dvb/dvb-usb/Kconfig +++ b/trunk/drivers/media/dvb/dvb-usb/Kconfig @@ -26,7 +26,7 @@ config DVB_USB_A800 tristate "AVerMedia AverTV DVB-T USB 2.0 (A800)" depends on DVB_USB select DVB_DIB3000MC - select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE + select DVB_TUNER_MT2060 help Say Y here to support the AVerMedia AverTV DVB-T USB 2.0 (A800) receiver. @@ -34,7 +34,7 @@ config DVB_USB_DIBUSB_MB tristate "DiBcom USB DVB-T devices (based on the DiB3000M-B) (see help for device list)" depends on DVB_USB select DVB_DIB3000MB - select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE + select DVB_TUNER_MT2060 help Support for USB 1.1 and 2.0 DVB-T receivers based on reference designs made by DiBcom () equipped with a DiB3000M-B demodulator. @@ -55,7 +55,7 @@ config DVB_USB_DIBUSB_MC tristate "DiBcom USB DVB-T devices (based on the DiB3000M-C/P) (see help for device list)" depends on DVB_USB select DVB_DIB3000MC - select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE + select DVB_TUNER_MT2060 help Support for USB2.0 DVB-T receivers based on reference designs made by DiBcom () equipped with a DiB3000M-C/P demodulator. @@ -70,7 +70,7 @@ config DVB_USB_DIB0700 tristate "DiBcom DiB0700 USB DVB devices (see help for supported devices)" depends on DVB_USB select DVB_DIB3000MC - select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE + select DVB_TUNER_MT2060 help Support for USB2.0/1.1 DVB receivers based on the DiB0700 USB bridge. The USB bridge is also present in devices having the DiB7700 DVB-T-USB @@ -87,7 +87,7 @@ config DVB_USB_UMT_010 tristate "HanfTek UMT-010 DVB-T USB2.0 support" depends on DVB_USB select DVB_DIB3000MC - select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE + select DVB_TUNER_MT2060 help Say Y here to support the HanfTek UMT-010 USB2.0 stick-sized DVB-T receiver. @@ -153,7 +153,7 @@ config DVB_USB_NOVA_T_USB2 tristate "Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 support" depends on DVB_USB select DVB_DIB3000MC - select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE + select DVB_TUNER_MT2060 help Say Y here to support the Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 receiver. diff --git a/trunk/drivers/media/dvb/dvb-usb/dibusb-common.c b/trunk/drivers/media/dvb/dvb-usb/dibusb-common.c index 5143e426d283..fd3a9902f98d 100644 --- a/trunk/drivers/media/dvb/dvb-usb/dibusb-common.c +++ b/trunk/drivers/media/dvb/dvb-usb/dibusb-common.c @@ -169,7 +169,7 @@ EXPORT_SYMBOL(dibusb_read_eeprom_byte); // Config Adjacent channels Perf -cal22 static struct dibx000_agc_config dib3000p_mt2060_agc_config = { .band_caps = BAND_VHF | BAND_UHF, - .setup = (1 << 8) | (5 << 5) | (1 << 4) | (1 << 3) | (0 << 2) | (2 << 0), + .setup = (0 << 15) | (0 << 14) | (1 << 13) | (1 << 12) | (29 << 0), .agc1_max = 48497, .agc1_min = 23593, @@ -196,14 +196,10 @@ static struct dib3000mc_config stk3000p_dib3000p_config = { .ln_adc_level = 0x1cc7, .output_mpeg2_in_188_bytes = 1, - - .agc_command1 = 1, - .agc_command2 = 1, }; static struct dibx000_agc_config dib3000p_panasonic_agc_config = { - .band_caps = BAND_VHF | BAND_UHF, - .setup = (1 << 8) | (5 << 5) | (1 << 4) | (1 << 3) | (0 << 2) | (2 << 0), + .setup = (0 << 15) | (0 << 14) | (1 << 13) | (1 << 12) | (29 << 0), .agc1_max = 56361, .agc1_min = 22282, @@ -230,9 +226,6 @@ static struct dib3000mc_config mod3000p_dib3000p_config = { .ln_adc_level = 0x1cc7, .output_mpeg2_in_188_bytes = 1, - - .agc_command1 = 1, - .agc_command2 = 1, }; int dibusb_dib3000mc_frontend_attach(struct dvb_usb_adapter *adap) diff --git a/trunk/drivers/media/dvb/dvb-usb/dibusb.h b/trunk/drivers/media/dvb/dvb-usb/dibusb.h index b60781032742..5153fb943da1 100644 --- a/trunk/drivers/media/dvb/dvb-usb/dibusb.h +++ b/trunk/drivers/media/dvb/dvb-usb/dibusb.h @@ -99,9 +99,7 @@ struct dibusb_state { struct dib_fe_xfer_ops ops; int mt2060_present; -}; -struct dibusb_device_state { /* for RC5 remote control */ int old_toggle; int last_repeat_count; diff --git a/trunk/drivers/media/dvb/dvb-usb/nova-t-usb2.c b/trunk/drivers/media/dvb/dvb-usb/nova-t-usb2.c index a58874c790b2..a9219bf69b89 100644 --- a/trunk/drivers/media/dvb/dvb-usb/nova-t-usb2.c +++ b/trunk/drivers/media/dvb/dvb-usb/nova-t-usb2.c @@ -75,7 +75,7 @@ static int nova_t_rc_query(struct dvb_usb_device *d, u32 *event, int *state) u8 key[5],cmd[2] = { DIBUSB_REQ_POLL_REMOTE, 0x35 }, data,toggle,custom; u16 raw; int i; - struct dibusb_device_state *st = d->priv; + struct dibusb_state *st = d->priv; dvb_usb_generic_rw(d,cmd,2,key,5,0); @@ -184,7 +184,6 @@ static struct dvb_usb_device_properties nova_t_properties = { .size_of_priv = sizeof(struct dibusb_state), } }, - .size_of_priv = sizeof(struct dibusb_device_state), .power_ctrl = dibusb2_0_power_ctrl, .read_mac_address = nova_t_read_mac_address, diff --git a/trunk/drivers/media/dvb/dvb-usb/usb-urb.c b/trunk/drivers/media/dvb/dvb-usb/usb-urb.c index 78035ee824ca..572b2d9aa66a 100644 --- a/trunk/drivers/media/dvb/dvb-usb/usb-urb.c +++ b/trunk/drivers/media/dvb/dvb-usb/usb-urb.c @@ -11,7 +11,7 @@ #include "dvb-usb-common.h" /* URB stuff for streaming */ -static void usb_urb_complete(struct urb *urb) +static void usb_urb_complete(struct urb *urb, struct pt_regs *ptregs) { struct usb_data_stream *stream = urb->context; int ptype = usb_pipetype(urb->pipe); diff --git a/trunk/drivers/media/dvb/frontends/Kconfig b/trunk/drivers/media/dvb/frontends/Kconfig index aebb8d6f26f8..080fa257a0bc 100644 --- a/trunk/drivers/media/dvb/frontends/Kconfig +++ b/trunk/drivers/media/dvb/frontends/Kconfig @@ -276,8 +276,6 @@ config DVB_TDA826X config DVB_TUNER_MT2060 tristate "Microtune MT2060 silicon IF tuner" - depends on I2C - default m if DVB_FE_CUSTOMISE help A driver for the silicon IF tuner MT2060 from Microtune. diff --git a/trunk/drivers/media/dvb/frontends/bcm3510.h b/trunk/drivers/media/dvb/frontends/bcm3510.h index 7e4f95e1734b..6dfa839a7022 100644 --- a/trunk/drivers/media/dvb/frontends/bcm3510.h +++ b/trunk/drivers/media/dvb/frontends/bcm3510.h @@ -34,7 +34,7 @@ struct bcm3510_config int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); }; -#if defined(CONFIG_DVB_BCM3510) || (defined(CONFIG_DVB_BCM3510_MODULE) && defined(MODULE)) +#if defined(CONFIG_DVB_BCM3510) || defined(CONFIG_DVB_BCM3510_MODULE) extern struct dvb_frontend* bcm3510_attach(const struct bcm3510_config* config, struct i2c_adapter* i2c); #else diff --git a/trunk/drivers/media/dvb/frontends/cx22700.h b/trunk/drivers/media/dvb/frontends/cx22700.h index 7ac33690cdcc..10286cc29fb4 100644 --- a/trunk/drivers/media/dvb/frontends/cx22700.h +++ b/trunk/drivers/media/dvb/frontends/cx22700.h @@ -31,7 +31,7 @@ struct cx22700_config u8 demod_address; }; -#if defined(CONFIG_DVB_CX22700) || (defined(CONFIG_DVB_CX22700_MODULE) && defined(MODULE)) +#if defined(CONFIG_DVB_CX22700) || defined(CONFIG_DVB_CX22700_MODULE) extern struct dvb_frontend* cx22700_attach(const struct cx22700_config* config, struct i2c_adapter* i2c); #else diff --git a/trunk/drivers/media/dvb/frontends/cx22702.h b/trunk/drivers/media/dvb/frontends/cx22702.h index 9cd64da6ee40..bc217ddf02c0 100644 --- a/trunk/drivers/media/dvb/frontends/cx22702.h +++ b/trunk/drivers/media/dvb/frontends/cx22702.h @@ -41,7 +41,7 @@ struct cx22702_config u8 output_mode; }; -#if defined(CONFIG_DVB_CX22702) || (defined(CONFIG_DVB_CX22702_MODULE) && defined(MODULE)) +#if defined(CONFIG_DVB_CX22702) || defined(CONFIG_DVB_CX22702_MODULE) extern struct dvb_frontend* cx22702_attach(const struct cx22702_config* config, struct i2c_adapter* i2c); #else diff --git a/trunk/drivers/media/dvb/frontends/cx24110.h b/trunk/drivers/media/dvb/frontends/cx24110.h index 0ca3af4db513..c9d5ae250ebb 100644 --- a/trunk/drivers/media/dvb/frontends/cx24110.h +++ b/trunk/drivers/media/dvb/frontends/cx24110.h @@ -41,7 +41,7 @@ static inline int cx24110_pll_write(struct dvb_frontend *fe, u32 val) { return r; } -#if defined(CONFIG_DVB_CX24110) || (defined(CONFIG_DVB_CX24110_MODULE) && defined(MODULE)) +#if defined(CONFIG_DVB_CX24110) || defined(CONFIG_DVB_CX24110_MODULE) extern struct dvb_frontend* cx24110_attach(const struct cx24110_config* config, struct i2c_adapter* i2c); #else diff --git a/trunk/drivers/media/dvb/frontends/cx24123.h b/trunk/drivers/media/dvb/frontends/cx24123.h index 84f9e4f5c15e..57a1dae1dc40 100644 --- a/trunk/drivers/media/dvb/frontends/cx24123.h +++ b/trunk/drivers/media/dvb/frontends/cx24123.h @@ -35,7 +35,7 @@ struct cx24123_config int lnb_polarity; }; -#if defined(CONFIG_DVB_CX24123) || (defined(CONFIG_DVB_CX24123_MODULE) && defined(MODULE)) +#if defined(CONFIG_DVB_CX24123) || defined(CONFIG_DVB_CX24123_MODULE) extern struct dvb_frontend* cx24123_attach(const struct cx24123_config* config, struct i2c_adapter* i2c); #else diff --git a/trunk/drivers/media/dvb/frontends/dib3000.h b/trunk/drivers/media/dvb/frontends/dib3000.h index a6d3854a67bc..0caac3f0f279 100644 --- a/trunk/drivers/media/dvb/frontends/dib3000.h +++ b/trunk/drivers/media/dvb/frontends/dib3000.h @@ -41,7 +41,7 @@ struct dib_fe_xfer_ops int (*tuner_pass_ctrl)(struct dvb_frontend *fe, int onoff, u8 pll_ctrl); }; -#if defined(CONFIG_DVB_DIB3000MB) || (defined(CONFIG_DVB_DIB3000MB_MODULE) && defined(MODULE)) +#if defined(CONFIG_DVB_DIB3000MB) || defined(CONFIG_DVB_DIB3000MB_MODULE) extern struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config, struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops); #else diff --git a/trunk/drivers/media/dvb/frontends/dib3000mc.c b/trunk/drivers/media/dvb/frontends/dib3000mc.c index 3561a777568c..ccc813b525d6 100644 --- a/trunk/drivers/media/dvb/frontends/dib3000mc.c +++ b/trunk/drivers/media/dvb/frontends/dib3000mc.c @@ -345,7 +345,7 @@ static int dib3000mc_init(struct dvb_frontend *demod) /* agc */ dib3000mc_write_word(state, 36, state->cfg->max_time); - dib3000mc_write_word(state, 37, (state->cfg->agc_command1 << 13) | (state->cfg->agc_command2 << 12) | (0x1d << 0)); + dib3000mc_write_word(state, 37, agc->setup); dib3000mc_write_word(state, 38, state->cfg->pwm3_value); dib3000mc_write_word(state, 39, state->cfg->ln_adc_level); diff --git a/trunk/drivers/media/dvb/frontends/dib3000mc.h b/trunk/drivers/media/dvb/frontends/dib3000mc.h index 72d4757601d8..b198cd5b1843 100644 --- a/trunk/drivers/media/dvb/frontends/dib3000mc.h +++ b/trunk/drivers/media/dvb/frontends/dib3000mc.h @@ -28,9 +28,6 @@ struct dib3000mc_config { u16 max_time; u16 ln_adc_level; - u8 agc_command1 :1; - u8 agc_command2 :1; - u8 mobile_mode; u8 output_mpeg2_in_188_bytes; @@ -39,7 +36,7 @@ struct dib3000mc_config { #define DEFAULT_DIB3000MC_I2C_ADDRESS 16 #define DEFAULT_DIB3000P_I2C_ADDRESS 24 -#if defined(CONFIG_DVB_DIB3000MC) || (defined(CONFIG_DVB_DIB3000MC_MODULE) && defined(MODULE)) +#if defined(CONFIG_DVB_DIB3000MC) || defined(CONFIG_DVB_DIB3000MC_MODULE) extern struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg); #else static inline struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg) diff --git a/trunk/drivers/media/dvb/frontends/isl6421.h b/trunk/drivers/media/dvb/frontends/isl6421.h index ea7f78a7d3cd..1916e3eb2df3 100644 --- a/trunk/drivers/media/dvb/frontends/isl6421.h +++ b/trunk/drivers/media/dvb/frontends/isl6421.h @@ -39,7 +39,7 @@ #define ISL6421_ISEL1 0x20 #define ISL6421_DCL 0x40 -#if defined(CONFIG_DVB_ISL6421) || (defined(CONFIG_DVB_ISL6421_MODULE) && defined(MODULE)) +#if defined(CONFIG_DVB_ISL6421) || defined(CONFIG_DVB_ISL6421_MODULE) /* override_set and override_clear control which system register bits (above) to always set & clear */ extern struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr, u8 override_set, u8 override_clear); diff --git a/trunk/drivers/media/dvb/frontends/l64781.h b/trunk/drivers/media/dvb/frontends/l64781.h index cd15f76ff28d..21ba4a230760 100644 --- a/trunk/drivers/media/dvb/frontends/l64781.h +++ b/trunk/drivers/media/dvb/frontends/l64781.h @@ -31,7 +31,7 @@ struct l64781_config u8 demod_address; }; -#if defined(CONFIG_DVB_L64781) || (defined(CONFIG_DVB_L64781_MODULE) && defined(MODULE)) +#if defined(CONFIG_DVB_L64781) || defined(CONFIG_DVB_L64781_MODULE) extern struct dvb_frontend* l64781_attach(const struct l64781_config* config, struct i2c_adapter* i2c); #else diff --git a/trunk/drivers/media/dvb/frontends/lgdt330x.h b/trunk/drivers/media/dvb/frontends/lgdt330x.h index 995059004b10..3f96b485584c 100644 --- a/trunk/drivers/media/dvb/frontends/lgdt330x.h +++ b/trunk/drivers/media/dvb/frontends/lgdt330x.h @@ -52,7 +52,7 @@ struct lgdt330x_config int clock_polarity_flip; }; -#if defined(CONFIG_DVB_LGDT330X) || (defined(CONFIG_DVB_LGDT330X_MODULE) && defined(MODULE)) +#if defined(CONFIG_DVB_LGDT330X) || defined(CONFIG_DVB_LGDT330X_MODULE) extern struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config, struct i2c_adapter* i2c); #else diff --git a/trunk/drivers/media/dvb/frontends/lnbp21.h b/trunk/drivers/media/dvb/frontends/lnbp21.h index 68906acf7d63..1fe1dd179312 100644 --- a/trunk/drivers/media/dvb/frontends/lnbp21.h +++ b/trunk/drivers/media/dvb/frontends/lnbp21.h @@ -39,7 +39,7 @@ #include -#if defined(CONFIG_DVB_LNBP21) || (defined(CONFIG_DVB_LNBP21_MODULE) && defined(MODULE)) +#if defined(CONFIG_DVB_LNBP21) || defined(CONFIG_DVB_LNBP21_MODULE) /* override_set and override_clear control which system register bits (above) to always set & clear */ extern struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear); #else diff --git a/trunk/drivers/media/dvb/frontends/mt2060.h b/trunk/drivers/media/dvb/frontends/mt2060.h index 0a86eab3a954..34a37c2b556f 100644 --- a/trunk/drivers/media/dvb/frontends/mt2060.h +++ b/trunk/drivers/media/dvb/frontends/mt2060.h @@ -30,14 +30,6 @@ struct mt2060_config { u8 clock_out; /* 0 = off, 1 = CLK/4, 2 = CLK/2, 3 = CLK/1 */ }; -#if defined(CONFIG_DVB_TUNER_MT2060) || (defined(CONFIG_DVB_TUNER_MT2060_MODULE) && defined(MODULE)) extern struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1); -#else -static inline struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); - return NULL; -} -#endif // CONFIG_DVB_TUNER_MT2060 #endif diff --git a/trunk/drivers/media/dvb/frontends/mt312.h b/trunk/drivers/media/dvb/frontends/mt312.h index cf9a1505ad4b..7112fb4d58ac 100644 --- a/trunk/drivers/media/dvb/frontends/mt312.h +++ b/trunk/drivers/media/dvb/frontends/mt312.h @@ -34,7 +34,7 @@ struct mt312_config u8 demod_address; }; -#if defined(CONFIG_DVB_MT312) || (defined(CONFIG_DVB_MT312_MODULE) && defined(MODULE)) +#if defined(CONFIG_DVB_MT312) || defined(CONFIG_DVB_MT312_MODULE) struct dvb_frontend* vp310_mt312_attach(const struct mt312_config* config, struct i2c_adapter* i2c); #else diff --git a/trunk/drivers/media/dvb/frontends/mt352.h b/trunk/drivers/media/dvb/frontends/mt352.h index e9964081fd84..0035c2e2d7c2 100644 --- a/trunk/drivers/media/dvb/frontends/mt352.h +++ b/trunk/drivers/media/dvb/frontends/mt352.h @@ -51,7 +51,7 @@ struct mt352_config int (*demod_init)(struct dvb_frontend* fe); }; -#if defined(CONFIG_DVB_MT352) || (defined(CONFIG_DVB_MT352_MODULE) && defined(MODULE)) +#if defined(CONFIG_DVB_MT352) || defined(CONFIG_DVB_MT352_MODULE) extern struct dvb_frontend* mt352_attach(const struct mt352_config* config, struct i2c_adapter* i2c); #else diff --git a/trunk/drivers/media/dvb/frontends/nxt200x.h b/trunk/drivers/media/dvb/frontends/nxt200x.h index 28bc5591b319..2eb220e98062 100644 --- a/trunk/drivers/media/dvb/frontends/nxt200x.h +++ b/trunk/drivers/media/dvb/frontends/nxt200x.h @@ -45,7 +45,7 @@ struct nxt200x_config int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); }; -#if defined(CONFIG_DVB_NXT200X) || (defined(CONFIG_DVB_NXT200X_MODULE) && defined(MODULE)) +#if defined(CONFIG_DVB_NXT200X) || defined(CONFIG_DVB_NXT200X_MODULE) extern struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config, struct i2c_adapter* i2c); #else diff --git a/trunk/drivers/media/dvb/frontends/nxt6000.h b/trunk/drivers/media/dvb/frontends/nxt6000.h index 13d22518356e..9397393a6bd1 100644 --- a/trunk/drivers/media/dvb/frontends/nxt6000.h +++ b/trunk/drivers/media/dvb/frontends/nxt6000.h @@ -33,7 +33,7 @@ struct nxt6000_config u8 clock_inversion:1; }; -#if defined(CONFIG_DVB_NXT6000) || (defined(CONFIG_DVB_NXT6000_MODULE) && defined(MODULE)) +#if defined(CONFIG_DVB_NXT6000) || defined(CONFIG_DVB_NXT6000_MODULE) extern struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config, struct i2c_adapter* i2c); #else diff --git a/trunk/drivers/media/dvb/frontends/or51132.h b/trunk/drivers/media/dvb/frontends/or51132.h index add24f0a743b..9718be4fb835 100644 --- a/trunk/drivers/media/dvb/frontends/or51132.h +++ b/trunk/drivers/media/dvb/frontends/or51132.h @@ -34,7 +34,7 @@ struct or51132_config int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); }; -#if defined(CONFIG_DVB_OR51132) || (defined(CONFIG_DVB_OR51132_MODULE) && defined(MODULE)) +#if defined(CONFIG_DVB_OR51132) || defined(CONFIG_DVB_OR51132_MODULE) extern struct dvb_frontend* or51132_attach(const struct or51132_config* config, struct i2c_adapter* i2c); #else diff --git a/trunk/drivers/media/dvb/frontends/or51211.h b/trunk/drivers/media/dvb/frontends/or51211.h index 8aad8402d615..10a5419f9e00 100644 --- a/trunk/drivers/media/dvb/frontends/or51211.h +++ b/trunk/drivers/media/dvb/frontends/or51211.h @@ -37,7 +37,7 @@ struct or51211_config void (*sleep)(struct dvb_frontend * fe); }; -#if defined(CONFIG_DVB_OR51211) || (defined(CONFIG_DVB_OR51211_MODULE) && defined(MODULE)) +#if defined(CONFIG_DVB_OR51211) || defined(CONFIG_DVB_OR51211_MODULE) extern struct dvb_frontend* or51211_attach(const struct or51211_config* config, struct i2c_adapter* i2c); #else diff --git a/trunk/drivers/media/dvb/frontends/s5h1420.h b/trunk/drivers/media/dvb/frontends/s5h1420.h index 1555870f7226..efc54d7f3c55 100644 --- a/trunk/drivers/media/dvb/frontends/s5h1420.h +++ b/trunk/drivers/media/dvb/frontends/s5h1420.h @@ -34,7 +34,7 @@ struct s5h1420_config u8 invert:1; }; -#if defined(CONFIG_DVB_S5H1420) || (defined(CONFIG_DVB_S5H1420_MODULE) && defined(MODULE)) +#if defined(CONFIG_DVB_S5H1420) || defined(CONFIG_DVB_S5H1420_MODULE) extern struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config, struct i2c_adapter* i2c); #else diff --git a/trunk/drivers/media/dvb/frontends/sp8870.h b/trunk/drivers/media/dvb/frontends/sp8870.h index 909cefe7139e..4cf27d3b10f2 100644 --- a/trunk/drivers/media/dvb/frontends/sp8870.h +++ b/trunk/drivers/media/dvb/frontends/sp8870.h @@ -35,7 +35,7 @@ struct sp8870_config int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); }; -#if defined(CONFIG_DVB_SP8870) || (defined(CONFIG_DVB_SP8870_MODULE) && defined(MODULE)) +#if defined(CONFIG_DVB_SP8870) || defined(CONFIG_DVB_SP8870_MODULE) extern struct dvb_frontend* sp8870_attach(const struct sp8870_config* config, struct i2c_adapter* i2c); #else diff --git a/trunk/drivers/media/dvb/frontends/sp887x.h b/trunk/drivers/media/dvb/frontends/sp887x.h index 7ee78d7d916d..cab7ea644dfa 100644 --- a/trunk/drivers/media/dvb/frontends/sp887x.h +++ b/trunk/drivers/media/dvb/frontends/sp887x.h @@ -17,7 +17,7 @@ struct sp887x_config int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); }; -#if defined(CONFIG_DVB_SP887X) || (defined(CONFIG_DVB_SP887X_MODULE) && defined(MODULE)) +#if defined(CONFIG_DVB_SP887X) || defined(CONFIG_DVB_SP887X_MODULE) extern struct dvb_frontend* sp887x_attach(const struct sp887x_config* config, struct i2c_adapter* i2c); #else diff --git a/trunk/drivers/media/dvb/frontends/stv0297.h b/trunk/drivers/media/dvb/frontends/stv0297.h index 69f4515df2b9..760b80db43a5 100644 --- a/trunk/drivers/media/dvb/frontends/stv0297.h +++ b/trunk/drivers/media/dvb/frontends/stv0297.h @@ -42,7 +42,7 @@ struct stv0297_config u8 stop_during_read:1; }; -#if defined(CONFIG_DVB_STV0297) || (defined(CONFIG_DVB_STV0297_MODULE) && defined(MODULE)) +#if defined(CONFIG_DVB_STV0297) || defined(CONFIG_DVB_STV0297_MODULE) extern struct dvb_frontend* stv0297_attach(const struct stv0297_config* config, struct i2c_adapter* i2c); #else diff --git a/trunk/drivers/media/dvb/frontends/stv0299.h b/trunk/drivers/media/dvb/frontends/stv0299.h index 33df9495908f..7ef25207081d 100644 --- a/trunk/drivers/media/dvb/frontends/stv0299.h +++ b/trunk/drivers/media/dvb/frontends/stv0299.h @@ -89,7 +89,7 @@ struct stv0299_config int (*set_symbol_rate)(struct dvb_frontend* fe, u32 srate, u32 ratio); }; -#if defined(CONFIG_DVB_STV0299) || (defined(CONFIG_DVB_STV0299_MODULE) && defined(MODULE)) +#if defined(CONFIG_DVB_STV0299) || defined(CONFIG_DVB_STV0299_MODULE) extern struct dvb_frontend* stv0299_attach(const struct stv0299_config* config, struct i2c_adapter* i2c); #else diff --git a/trunk/drivers/media/dvb/frontends/tda10021.h b/trunk/drivers/media/dvb/frontends/tda10021.h index e3da780108f6..d68ae20c8412 100644 --- a/trunk/drivers/media/dvb/frontends/tda10021.h +++ b/trunk/drivers/media/dvb/frontends/tda10021.h @@ -32,7 +32,7 @@ struct tda10021_config u8 demod_address; }; -#if defined(CONFIG_DVB_TDA10021) || (defined(CONFIG_DVB_TDA10021_MODULE) && defined(MODULE)) +#if defined(CONFIG_DVB_TDA10021) || defined(CONFIG_DVB_TDA10021_MODULE) extern struct dvb_frontend* tda10021_attach(const struct tda10021_config* config, struct i2c_adapter* i2c, u8 pwm); #else diff --git a/trunk/drivers/media/dvb/frontends/tda1004x.h b/trunk/drivers/media/dvb/frontends/tda1004x.h index 605ad2dfc09d..e28fca05734c 100644 --- a/trunk/drivers/media/dvb/frontends/tda1004x.h +++ b/trunk/drivers/media/dvb/frontends/tda1004x.h @@ -71,7 +71,7 @@ struct tda1004x_config int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); }; -#if defined(CONFIG_DVB_TDA1004X) || (defined(CONFIG_DVB_TDA1004X_MODULE) && defined(MODULE)) +#if defined(CONFIG_DVB_TDA1004X) || defined(CONFIG_DVB_TDA1004X_MODULE) extern struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, struct i2c_adapter* i2c); diff --git a/trunk/drivers/media/dvb/frontends/tda10086.c b/trunk/drivers/media/dvb/frontends/tda10086.c index 4c27a2d90a38..7456b0b9976b 100644 --- a/trunk/drivers/media/dvb/frontends/tda10086.c +++ b/trunk/drivers/media/dvb/frontends/tda10086.c @@ -441,10 +441,6 @@ static int tda10086_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_pa dprintk ("%s\n", __FUNCTION__); - // check for invalid symbol rate - if (fe_params->u.qpsk.symbol_rate < 500000) - return -EINVAL; - // calculate the updated frequency (note: we convert from Hz->kHz) tmp64 = tda10086_read_byte(state, 0x52); tmp64 |= (tda10086_read_byte(state, 0x51) << 8); diff --git a/trunk/drivers/media/dvb/frontends/tda10086.h b/trunk/drivers/media/dvb/frontends/tda10086.h index ed584a8f4a89..e8061db11123 100644 --- a/trunk/drivers/media/dvb/frontends/tda10086.h +++ b/trunk/drivers/media/dvb/frontends/tda10086.h @@ -35,16 +35,7 @@ struct tda10086_config u8 invert; }; -#if defined(CONFIG_DVB_TDA10086) || (defined(CONFIG_DVB_TDA10086_MODULE) && defined(MODULE)) extern struct dvb_frontend* tda10086_attach(const struct tda10086_config* config, struct i2c_adapter* i2c); -#else -static inline struct dvb_frontend* tda10086_attach(const struct tda10086_config* config, - struct i2c_adapter* i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); - return NULL; -} -#endif // CONFIG_DVB_TDA10086 #endif // TDA10086_H diff --git a/trunk/drivers/media/dvb/frontends/tda8083.h b/trunk/drivers/media/dvb/frontends/tda8083.h index 2d3307999f21..aae15bdce6eb 100644 --- a/trunk/drivers/media/dvb/frontends/tda8083.h +++ b/trunk/drivers/media/dvb/frontends/tda8083.h @@ -35,7 +35,7 @@ struct tda8083_config u8 demod_address; }; -#if defined(CONFIG_DVB_TDA8083) || (defined(CONFIG_DVB_TDA8083_MODULE) && defined(MODULE)) +#if defined(CONFIG_DVB_TDA8083) || defined(CONFIG_DVB_TDA8083_MODULE) extern struct dvb_frontend* tda8083_attach(const struct tda8083_config* config, struct i2c_adapter* i2c); #else diff --git a/trunk/drivers/media/dvb/frontends/tda826x.c b/trunk/drivers/media/dvb/frontends/tda826x.c index 34815b0b97e4..eeab26bd36ed 100644 --- a/trunk/drivers/media/dvb/frontends/tda826x.c +++ b/trunk/drivers/media/dvb/frontends/tda826x.c @@ -121,7 +121,7 @@ static struct dvb_tuner_ops tda826x_tuner_ops = { .info = { .name = "Philips TDA826X", .frequency_min = 950000, - .frequency_max = 2175000 + .frequency_min = 2175000 }, .release = tda826x_release, .sleep = tda826x_sleep, diff --git a/trunk/drivers/media/dvb/frontends/tda826x.h b/trunk/drivers/media/dvb/frontends/tda826x.h index ad9981195961..3307607632b0 100644 --- a/trunk/drivers/media/dvb/frontends/tda826x.h +++ b/trunk/drivers/media/dvb/frontends/tda826x.h @@ -35,19 +35,6 @@ * @param has_loopthrough Set to 1 if the card has a loopthrough RF connector. * @return FE pointer on success, NULL on failure. */ -#if defined(CONFIG_DVB_TDA826X) || (defined(CONFIG_DVB_TDA826X_MODULE) && defined(MODULE)) -extern struct dvb_frontend* tda826x_attach(struct dvb_frontend *fe, int addr, - struct i2c_adapter *i2c, - int has_loopthrough); -#else -static inline struct dvb_frontend* tda826x_attach(struct dvb_frontend *fe, - int addr, - struct i2c_adapter *i2c, - int has_loopthrough) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); - return NULL; -} -#endif // CONFIG_DVB_TDA826X - -#endif // __DVB_TDA826X_H__ +extern struct dvb_frontend *tda826x_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c, int has_loopthrough); + +#endif diff --git a/trunk/drivers/media/dvb/frontends/tua6100.h b/trunk/drivers/media/dvb/frontends/tua6100.h index 03a665e7df6d..8f98033ffa7b 100644 --- a/trunk/drivers/media/dvb/frontends/tua6100.h +++ b/trunk/drivers/media/dvb/frontends/tua6100.h @@ -34,7 +34,7 @@ #include #include "dvb_frontend.h" -#if defined(CONFIG_DVB_TUA6100) || (defined(CONFIG_DVB_TUA6100_MODULE) && defined(MODULE)) +#if defined(CONFIG_DVB_TUA6100) || defined(CONFIG_DVB_TUA6100_MODULE) extern struct dvb_frontend *tua6100_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c); #else static inline struct dvb_frontend* tua6100_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c) diff --git a/trunk/drivers/media/dvb/frontends/ves1820.h b/trunk/drivers/media/dvb/frontends/ves1820.h index e4a2a324046a..f0c9dded39d7 100644 --- a/trunk/drivers/media/dvb/frontends/ves1820.h +++ b/trunk/drivers/media/dvb/frontends/ves1820.h @@ -41,7 +41,7 @@ struct ves1820_config u8 selagc:1; }; -#if defined(CONFIG_DVB_VES1820) || (defined(CONFIG_DVB_VES1820_MODULE) && defined(MODULE)) +#if defined(CONFIG_DVB_VES1820) || defined(CONFIG_DVB_VES1820_MODULE) extern struct dvb_frontend* ves1820_attach(const struct ves1820_config* config, struct i2c_adapter* i2c, u8 pwm); #else diff --git a/trunk/drivers/media/dvb/frontends/ves1x93.h b/trunk/drivers/media/dvb/frontends/ves1x93.h index d507f8966f81..395fed39b286 100644 --- a/trunk/drivers/media/dvb/frontends/ves1x93.h +++ b/trunk/drivers/media/dvb/frontends/ves1x93.h @@ -40,7 +40,7 @@ struct ves1x93_config u8 invert_pwm:1; }; -#if defined(CONFIG_DVB_VES1X93) || (defined(CONFIG_DVB_VES1X93_MODULE) && defined(MODULE)) +#if defined(CONFIG_DVB_VES1X93) || defined(CONFIG_DVB_VES1X93_MODULE) extern struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config, struct i2c_adapter* i2c); #else diff --git a/trunk/drivers/media/dvb/frontends/zl10353.h b/trunk/drivers/media/dvb/frontends/zl10353.h index 0bc0109737f1..79a947215c4d 100644 --- a/trunk/drivers/media/dvb/frontends/zl10353.h +++ b/trunk/drivers/media/dvb/frontends/zl10353.h @@ -36,7 +36,7 @@ struct zl10353_config int parallel_ts; }; -#if defined(CONFIG_DVB_ZL10353) || (defined(CONFIG_DVB_ZL10353_MODULE) && defined(MODULE)) +#if defined(CONFIG_DVB_ZL10353) || defined(CONFIG_DVB_ZL10353_MODULE) extern struct dvb_frontend* zl10353_attach(const struct zl10353_config *config, struct i2c_adapter *i2c); #else diff --git a/trunk/drivers/media/dvb/pluto2/pluto2.c b/trunk/drivers/media/dvb/pluto2/pluto2.c index 8e4ce101eb22..2310b2bfed4e 100644 --- a/trunk/drivers/media/dvb/pluto2/pluto2.c +++ b/trunk/drivers/media/dvb/pluto2/pluto2.c @@ -306,7 +306,7 @@ static void pluto_dma_end(struct pluto *pluto, unsigned int nbpackets) TS_DMA_BYTES, PCI_DMA_FROMDEVICE); } -static irqreturn_t pluto_irq(int irq, void *dev_id) +static irqreturn_t pluto_irq(int irq, void *dev_id, struct pt_regs *regs) { struct pluto *pluto = dev_id; u32 tscr; diff --git a/trunk/drivers/media/dvb/ttpci/budget-ci.c b/trunk/drivers/media/dvb/ttpci/budget-ci.c index cd5ec489af1c..2a2e9b400613 100644 --- a/trunk/drivers/media/dvb/ttpci/budget-ci.c +++ b/trunk/drivers/media/dvb/ttpci/budget-ci.c @@ -46,14 +46,7 @@ #include "bsbe1.h" #include "bsru6.h" -/* - * Regarding DEBIADDR_IR: - * Some CI modules hang if random addresses are read. - * Using address 0x4000 for the IR read means that we - * use the same address as for CI version, which should - * be a safe default. - */ -#define DEBIADDR_IR 0x4000 +#define DEBIADDR_IR 0x1234 #define DEBIADDR_CICONTROL 0x0000 #define DEBIADDR_CIVERSION 0x4000 #define DEBIADDR_IO 0x1000 @@ -1035,7 +1028,6 @@ static void frontend_init(struct budget_ci *budget_ci) case 0x1012: // TT DVB-T CI budget (tda10046/Philips tdm1316l(tda6651tt)) budget_ci->tuner_pll_address = 0x60; - philips_tdm1316l_config.invert = 1; budget_ci->budget.dvb_frontend = dvb_attach(tda10046_attach, &philips_tdm1316l_config, &budget_ci->budget.i2c_adap); if (budget_ci->budget.dvb_frontend) { diff --git a/trunk/drivers/media/dvb/ttpci/budget-patch.c b/trunk/drivers/media/dvb/ttpci/budget-patch.c index 9a155396d6ac..fc1267b8c892 100644 --- a/trunk/drivers/media/dvb/ttpci/budget-patch.c +++ b/trunk/drivers/media/dvb/ttpci/budget-patch.c @@ -500,14 +500,14 @@ static int budget_patch_attach (struct saa7146_dev* dev, struct saa7146_pci_exte /* New design (By Emard) ** this rps1 code will copy internal HS event to GPIO3 pin. -** GPIO3 is in budget-patch hardware connected to port B VSYNC +** GPIO3 is in budget-patch hardware connectd to port B VSYNC ** HS is an internal event of 7146, accessible with RPS ** and temporarily raised high every n lines ** (n in defined in the RPS_THRESH1 counter threshold) ** I think HS is raised high on the beginning of the n-th line ** and remains high until this n-th line that triggered -** it is completely received. When the reception of n-th line +** it is completely received. When the receiption of n-th line ** ends, HS is lowered. ** To transmit data over DMA, 7146 needs changing state at @@ -541,7 +541,7 @@ static int budget_patch_attach (struct saa7146_dev* dev, struct saa7146_pci_exte ** hardware debug note: a working budget card (including budget patch) ** with vpeirq() interrupt setup in mode "0x90" (every 64K) will ** generate 3 interrupts per 25-Hz DMA frame of 2*188*512 bytes -** and that means 3*25=75 Hz of interrupt frequency, as seen by +** and that means 3*25=75 Hz of interrupt freqency, as seen by ** watch cat /proc/interrupts ** ** If this frequency is 3x lower (and data received in the DMA @@ -550,7 +550,7 @@ static int budget_patch_attach (struct saa7146_dev* dev, struct saa7146_pci_exte ** this means VSYNC line is not connected in the hardware. ** (check soldering pcb and pins) ** The same behaviour of missing VSYNC can be duplicated on budget -** cards, by setting DD1_INIT trigger mode 7 in 3rd nibble. +** cards, by seting DD1_INIT trigger mode 7 in 3rd nibble. */ // Setup RPS1 "program" (p35) diff --git a/trunk/drivers/media/dvb/ttpci/budget.c b/trunk/drivers/media/dvb/ttpci/budget.c index 56f1c80defc6..e58f0391e9d1 100644 --- a/trunk/drivers/media/dvb/ttpci/budget.c +++ b/trunk/drivers/media/dvb/ttpci/budget.c @@ -46,10 +46,6 @@ #include "lnbp21.h" #include "bsru6.h" -static int diseqc_method; -module_param(diseqc_method, int, 0444); -MODULE_PARM_DESC(diseqc_method, "Select DiSEqC method for subsystem id 13c2:1003, 0: default, 1: more reliable (for newer revisions only)"); - static void Set22K (struct budget *budget, int state) { struct saa7146_dev *dev=budget->dev; @@ -386,11 +382,6 @@ static void frontend_init(struct budget *budget) if (budget->dvb_frontend) { budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params; budget->dvb_frontend->tuner_priv = &budget->i2c_adap; - if (budget->dev->pci->subsystem_device == 0x1003 && diseqc_method == 0) { - budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd; - budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst; - budget->dvb_frontend->ops.set_tone = budget_set_tone; - } break; } break; diff --git a/trunk/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/trunk/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c index 60820deb900b..234199875f53 100644 --- a/trunk/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c +++ b/trunk/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c @@ -732,7 +732,7 @@ static void ttusb_process_frame(struct ttusb *ttusb, u8 * data, int len) } } -static void ttusb_iso_irq(struct urb *urb) +static void ttusb_iso_irq(struct urb *urb, struct pt_regs *ptregs) { struct ttusb *ttusb = urb->context; diff --git a/trunk/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/trunk/drivers/media/dvb/ttusb-dec/ttusb_dec.c index 8135f3e76aeb..de077a757192 100644 --- a/trunk/drivers/media/dvb/ttusb-dec/ttusb_dec.c +++ b/trunk/drivers/media/dvb/ttusb-dec/ttusb_dec.c @@ -203,7 +203,7 @@ static u16 rc_keys[] = { static void ttusb_dec_set_model(struct ttusb_dec *dec, enum ttusb_dec_model model); -static void ttusb_dec_handle_irq( struct urb *urb) +static void ttusb_dec_handle_irq( struct urb *urb, struct pt_regs *regs) { struct ttusb_dec * dec = urb->context; char *buffer = dec->irq_buffer; @@ -755,7 +755,7 @@ static void ttusb_dec_process_urb_frame_list(unsigned long data) } } -static void ttusb_dec_process_urb(struct urb *urb) +static void ttusb_dec_process_urb(struct urb *urb, struct pt_regs *ptregs) { struct ttusb_dec *dec = urb->context; @@ -1135,7 +1135,8 @@ static void ttusb_dec_free_iso_urbs(struct ttusb_dec *dec) dprintk("%s\n", __FUNCTION__); for (i = 0; i < ISO_BUF_COUNT; i++) - usb_free_urb(dec->iso_urb[i]); + if (dec->iso_urb[i]) + usb_free_urb(dec->iso_urb[i]); pci_free_consistent(NULL, ISO_FRAME_SIZE * (FRAMES_PER_ISO_BUF * diff --git a/trunk/drivers/media/video/Kconfig b/trunk/drivers/media/video/Kconfig index b8fde5cf4735..afb734df6e05 100644 --- a/trunk/drivers/media/video/Kconfig +++ b/trunk/drivers/media/video/Kconfig @@ -24,7 +24,7 @@ config VIDEO_HELPER_CHIPS_AUTO decode audio/video standards. This option will autoselect all pertinent modules to each selected video module. - Unselect this only if you know exactly what you are doing, since + Unselect this only if you know exaclty what you are doing, since it may break support on some boards. In doubt, say Y. @@ -186,7 +186,7 @@ config VIDEO_KS0127 config VIDEO_SAA7110 tristate "Philips SAA7110 video decoder" - depends on VIDEO_V4L1 && I2C + depends on VIDEO_V4L1 ---help--- Support for the Philips SAA7110 video decoders. @@ -677,8 +677,6 @@ config VIDEO_M32R_AR_M64278 menu "V4L USB devices" depends on USB && VIDEO_DEV -source "drivers/media/video/pvrusb2/Kconfig" - source "drivers/media/video/em28xx/Kconfig" source "drivers/media/video/usbvideo/Kconfig" diff --git a/trunk/drivers/media/video/arv.c b/trunk/drivers/media/video/arv.c index 4861799eb430..5c5e682a3004 100644 --- a/trunk/drivers/media/video/arv.c +++ b/trunk/drivers/media/video/arv.c @@ -549,7 +549,7 @@ static int ar_ioctl(struct inode *inode, struct file *file, unsigned int cmd, /* * Interrupt handler */ -static void ar_interrupt(int irq, void *dev) +static void ar_interrupt(int irq, void *dev, struct pt_regs *regs) { struct ar_device *ar = dev; unsigned int line_count; diff --git a/trunk/drivers/media/video/bt8xx/bttv-cards.c b/trunk/drivers/media/video/bt8xx/bttv-cards.c index 21ebe8f13815..a84903e0d810 100644 --- a/trunk/drivers/media/video/bt8xx/bttv-cards.c +++ b/trunk/drivers/media/video/bt8xx/bttv-cards.c @@ -4001,7 +4001,7 @@ static void __devinit init_PXC200(struct bttv *btv) * - sleep 1ms * - write 0x0E * read from GPIO_DATA into buf (uint_32) - * - if ( buf>>18 & 0x01 ) || ( buf>>19 & 0x01 != 0 ) + * - if ( buf>>18 & 0x01 ) || ( buf>>19 && 0x01 != 0 ) * error. ERROR_CPLD_Check_Failed. */ /* ----------------------------------------------------------------------- */ diff --git a/trunk/drivers/media/video/bt8xx/bttv-driver.c b/trunk/drivers/media/video/bt8xx/bttv-driver.c index 6e1ddad9f0c1..50dde82844ec 100644 --- a/trunk/drivers/media/video/bt8xx/bttv-driver.c +++ b/trunk/drivers/media/video/bt8xx/bttv-driver.c @@ -3753,7 +3753,7 @@ bttv_irq_switch_vbi(struct bttv *btv) spin_unlock(&btv->s_lock); } -static irqreturn_t bttv_irq(int irq, void *dev_id) +static irqreturn_t bttv_irq(int irq, void *dev_id, struct pt_regs * regs) { u32 stat,astat; u32 dstat; diff --git a/trunk/drivers/media/video/cpia2/cpia2_usb.c b/trunk/drivers/media/video/cpia2/cpia2_usb.c index 28dc6a1a1e43..f4da02941493 100644 --- a/trunk/drivers/media/video/cpia2/cpia2_usb.c +++ b/trunk/drivers/media/video/cpia2/cpia2_usb.c @@ -49,7 +49,7 @@ static int frame_sizes[] = { #define FRAME_SIZE_PER_DESC frame_sizes[cam->cur_alt] static void process_frame(struct camera_data *cam); -static void cpia2_usb_complete(struct urb *urb); +static void cpia2_usb_complete(struct urb *urb, struct pt_regs *); static int cpia2_usb_probe(struct usb_interface *intf, const struct usb_device_id *id); static void cpia2_usb_disconnect(struct usb_interface *intf); @@ -199,7 +199,7 @@ static void add_COM(struct camera_data *cam) * * callback when incoming packet is received *****************************************************************************/ -static void cpia2_usb_complete(struct urb *urb) +static void cpia2_usb_complete(struct urb *urb, struct pt_regs *regs) { int i; unsigned char *cdata; diff --git a/trunk/drivers/media/video/cpia_usb.c b/trunk/drivers/media/video/cpia_usb.c index 9da4726eb9b9..2ee34a3b9280 100644 --- a/trunk/drivers/media/video/cpia_usb.c +++ b/trunk/drivers/media/video/cpia_usb.c @@ -109,7 +109,7 @@ static struct cpia_camera_ops cpia_usb_ops = { static LIST_HEAD(cam_list); static spinlock_t cam_list_lock_usb; -static void cpia_usb_complete(struct urb *urb) +static void cpia_usb_complete(struct urb *urb, struct pt_regs *regs) { int i; char *cdata; diff --git a/trunk/drivers/media/video/cx25840/cx25840-vbi.c b/trunk/drivers/media/video/cx25840/cx25840-vbi.c index f85f2084324f..48014a254e15 100644 --- a/trunk/drivers/media/video/cx25840/cx25840-vbi.c +++ b/trunk/drivers/media/video/cx25840/cx25840-vbi.c @@ -235,7 +235,6 @@ int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg) 0, 0, V4L2_SLICED_VPS, 0, 0, /* 9 */ 0, 0, 0, 0 }; - int is_pal = !(cx25840_get_v4lstd(client) & V4L2_STD_525_60); int i; fmt = arg; @@ -247,25 +246,13 @@ int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg) if ((cx25840_read(client, 0x404) & 0x10) == 0) break; - if (is_pal) { - for (i = 7; i <= 23; i++) { - u8 v = cx25840_read(client, 0x424 + i - 7); - - svbi->service_lines[0][i] = lcr2vbi[v >> 4]; - svbi->service_lines[1][i] = lcr2vbi[v & 0xf]; - svbi->service_set |= - svbi->service_lines[0][i] | svbi->service_lines[1][i]; - } - } - else { - for (i = 10; i <= 21; i++) { - u8 v = cx25840_read(client, 0x424 + i - 10); + for (i = 7; i <= 23; i++) { + u8 v = cx25840_read(client, 0x424 + i - 7); - svbi->service_lines[0][i] = lcr2vbi[v >> 4]; - svbi->service_lines[1][i] = lcr2vbi[v & 0xf]; - svbi->service_set |= - svbi->service_lines[0][i] | svbi->service_lines[1][i]; - } + svbi->service_lines[0][i] = lcr2vbi[v >> 4]; + svbi->service_lines[1][i] = lcr2vbi[v & 0xf]; + svbi->service_set |= + svbi->service_lines[0][i] | svbi->service_lines[1][i]; } break; } diff --git a/trunk/drivers/media/video/cx88/cx88-alsa.c b/trunk/drivers/media/video/cx88/cx88-alsa.c index e4355fdc3b6d..f0340662e078 100644 --- a/trunk/drivers/media/video/cx88/cx88-alsa.c +++ b/trunk/drivers/media/video/cx88/cx88-alsa.c @@ -262,7 +262,7 @@ static void cx8801_aud_irq(snd_cx88_card_t *chip) /* * BOARD Specific: Handles IRQ calls */ -static irqreturn_t cx8801_irq(int irq, void *dev_id) +static irqreturn_t cx8801_irq(int irq, void *dev_id, struct pt_regs *regs) { snd_cx88_card_t *chip = dev_id; struct cx88_core *core = chip->core; diff --git a/trunk/drivers/media/video/cx88/cx88-cards.c b/trunk/drivers/media/video/cx88/cx88-cards.c index f764a57c56be..af71d4225c76 100644 --- a/trunk/drivers/media/video/cx88/cx88-cards.c +++ b/trunk/drivers/media/video/cx88/cx88-cards.c @@ -1230,7 +1230,6 @@ struct cx88_board cx88_boards[] = { .vmux = 2, .gpio0 = 0x84bf, }}, - .mpeg = CX88_MPEG_DVB, }, [CX88_BOARD_NORWOOD_MICRO] = { .name = "Norwood Micro TV Tuner", @@ -1591,18 +1590,6 @@ struct cx88_subid cx88_subids[] = { .subvendor = 0x0070, .subdevice = 0x9000, .card = CX88_BOARD_HAUPPAUGE_DVB_T1, - },{ - .subvendor = 0x0070, - .subdevice = 0x1400, - .card = CX88_BOARD_HAUPPAUGE_HVR3000, - },{ - .subvendor = 0x0070, - .subdevice = 0x1401, - .card = CX88_BOARD_HAUPPAUGE_HVR3000, - },{ - .subvendor = 0x0070, - .subdevice = 0x1402, - .card = CX88_BOARD_HAUPPAUGE_HVR3000, }, }; const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids); @@ -1646,15 +1633,7 @@ static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data) /* Make sure we support the board model */ switch (tv.model) { - case 14009: /* WinTV-HVR3000 (Retail, IR, b/panel video, 3.5mm audio in) */ - case 14019: /* WinTV-HVR3000 (Retail, IR Blaster, b/panel video, 3.5mm audio in) */ - case 14029: /* WinTV-HVR3000 (Retail, IR, b/panel video, 3.5mm audio in - 880 bridge) */ - case 14109: /* WinTV-HVR3000 (Retail, IR, b/panel video, 3.5mm audio in - low profile) */ - case 14129: /* WinTV-HVR3000 (Retail, IR, b/panel video, 3.5mm audio in - 880 bridge - LP) */ - case 14559: /* WinTV-HVR3000 (OEM, no IR, b/panel video, 3.5mm audio in) */ case 14569: /* WinTV-HVR3000 (OEM, no IR, no back panel video) */ - case 14659: /* WinTV-HVR3000 (OEM, no IR, b/panel video, RCA audio in - Low profile) */ - case 14669: /* WinTV-HVR3000 (OEM, no IR, no b/panel video - Low profile) */ case 28552: /* WinTV-PVR 'Roslyn' (No IR) */ case 34519: /* WinTV-PCI-FM */ case 90002: /* Nova-T-PCI (9002) */ diff --git a/trunk/drivers/media/video/cx88/cx88-dvb.c b/trunk/drivers/media/video/cx88/cx88-dvb.c index 0ef13e7efa2e..bd0c8797f26d 100644 --- a/trunk/drivers/media/video/cx88/cx88-dvb.c +++ b/trunk/drivers/media/video/cx88/cx88-dvb.c @@ -315,22 +315,15 @@ static struct cx22702_config hauppauge_novat_config = { .demod_address = 0x43, .output_mode = CX22702_SERIAL_OUTPUT, }; - static struct cx22702_config hauppauge_hvr1100_config = { .demod_address = 0x63, .output_mode = CX22702_SERIAL_OUTPUT, }; - static struct cx22702_config hauppauge_hvr1300_config = { .demod_address = 0x63, .output_mode = CX22702_SERIAL_OUTPUT, }; -static struct cx22702_config hauppauge_hvr3000_config = { - .demod_address = 0x63, - .output_mode = CX22702_SERIAL_OUTPUT, -}; - static int or51132_set_ts_param(struct dvb_frontend* fe, int is_punctured) { @@ -565,16 +558,6 @@ static int dvb_register(struct cx8802_dev *dev) &dvb_pll_fmd1216me); } break; - case CX88_BOARD_HAUPPAUGE_HVR3000: - dev->dvb.frontend = dvb_attach(cx22702_attach, - &hauppauge_hvr3000_config, - &dev->core->i2c_adap); - if (dev->dvb.frontend != NULL) { - dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, - &dev->core->i2c_adap, - &dvb_pll_fmd1216me); - } - break; case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS: dev->dvb.frontend = dvb_attach(mt352_attach, &dvico_fusionhdtv, diff --git a/trunk/drivers/media/video/cx88/cx88-input.c b/trunk/drivers/media/video/cx88/cx88-input.c index 57e1c024a547..83ebf7a3c054 100644 --- a/trunk/drivers/media/video/cx88/cx88-input.c +++ b/trunk/drivers/media/video/cx88/cx88-input.c @@ -196,24 +196,17 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: case CX88_BOARD_HAUPPAUGE_HVR1100: case CX88_BOARD_HAUPPAUGE_HVR1300: - case CX88_BOARD_HAUPPAUGE_HVR3000: ir_codes = ir_codes_hauppauge_new; ir_type = IR_TYPE_RC5; ir->sampling = 1; break; case CX88_BOARD_WINFAST_DTV2000H: - ir_codes = ir_codes_winfast; - ir->gpio_addr = MO_GP0_IO; - ir->mask_keycode = 0x8f8; - ir->mask_keyup = 0x100; - ir->polling = 50; /* ms */ - break; case CX88_BOARD_WINFAST2000XP_EXPERT: ir_codes = ir_codes_winfast; ir->gpio_addr = MO_GP0_IO; ir->mask_keycode = 0x8f8; ir->mask_keyup = 0x100; - ir->polling = 1; /* ms */ + ir->polling = 50; /* ms */ break; case CX88_BOARD_IODATA_GVBCTV7E: ir_codes = ir_codes_iodata_bctv7e; @@ -222,7 +215,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) ir->mask_keydown = 0x02; ir->polling = 5; /* ms */ break; - case CX88_BOARD_PROLINK_PLAYTVPVR: + case CX88_BOARD_PROLINK_PLAYTVPVR: case CX88_BOARD_PIXELVIEW_PLAYTV_ULTRA_PRO: ir_codes = ir_codes_pixelview; ir->gpio_addr = MO_GP1_IO; @@ -426,7 +419,6 @@ void cx88_ir_irq(struct cx88_core *core) case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: case CX88_BOARD_HAUPPAUGE_HVR1100: case CX88_BOARD_HAUPPAUGE_HVR1300: - case CX88_BOARD_HAUPPAUGE_HVR3000: ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7); ir_dprintk("biphase decoded: %x\n", ircode); if ((ircode & 0xfffff000) != 0x3000) diff --git a/trunk/drivers/media/video/cx88/cx88-mpeg.c b/trunk/drivers/media/video/cx88/cx88-mpeg.c index 6b23a4e6f66d..d6d980774c21 100644 --- a/trunk/drivers/media/video/cx88/cx88-mpeg.c +++ b/trunk/drivers/media/video/cx88/cx88-mpeg.c @@ -376,7 +376,7 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev) #define MAX_IRQ_LOOP 10 -static irqreturn_t cx8802_irq(int irq, void *dev_id) +static irqreturn_t cx8802_irq(int irq, void *dev_id, struct pt_regs *regs) { struct cx8802_dev *dev = dev_id; struct cx88_core *core = dev->core; diff --git a/trunk/drivers/media/video/cx88/cx88-video.c b/trunk/drivers/media/video/cx88/cx88-video.c index 90e298d074d1..cb0c0eea20f9 100644 --- a/trunk/drivers/media/video/cx88/cx88-video.c +++ b/trunk/drivers/media/video/cx88/cx88-video.c @@ -1744,7 +1744,7 @@ static void cx8800_vid_irq(struct cx8800_dev *dev) } } -static irqreturn_t cx8800_irq(int irq, void *dev_id) +static irqreturn_t cx8800_irq(int irq, void *dev_id, struct pt_regs *regs) { struct cx8800_dev *dev = dev_id; struct cx88_core *core = dev->core; diff --git a/trunk/drivers/media/video/dabusb.c b/trunk/drivers/media/video/dabusb.c index b1012e92ee04..b9ba95f5e026 100644 --- a/trunk/drivers/media/video/dabusb.c +++ b/trunk/drivers/media/video/dabusb.c @@ -166,7 +166,7 @@ static int dabusb_free_buffers (pdabusb_t s) return 0; } /*-------------------------------------------------------------------*/ -static void dabusb_iso_complete (struct urb *purb) +static void dabusb_iso_complete (struct urb *purb, struct pt_regs *regs) { pbuff_t b = purb->context; pdabusb_t s = b->s; diff --git a/trunk/drivers/media/video/em28xx/em28xx-core.c b/trunk/drivers/media/video/em28xx/em28xx-core.c index 255a47dfb84f..4350cc75b025 100644 --- a/trunk/drivers/media/video/em28xx/em28xx-core.c +++ b/trunk/drivers/media/video/em28xx/em28xx-core.c @@ -382,7 +382,7 @@ int em28xx_resolution_set(struct em28xx *dev) /******************* isoc transfer handling ****************************/ #ifdef ENABLE_DEBUG_ISOC_FRAMES -static void em28xx_isoc_dump(struct urb *urb) +static void em28xx_isoc_dump(struct urb *urb, struct pt_regs *regs) { int len = 0; int ntrans = 0; @@ -534,7 +534,7 @@ static inline void em28xx_isoc_video_copy(struct em28xx *dev, * em28xx_isoIrq() * handles the incoming isoc urbs and fills the frames from our inqueue */ -static void em28xx_isocIrq(struct urb *urb) +static void em28xx_isocIrq(struct urb *urb, struct pt_regs *regs) { struct em28xx *dev = urb->context; int i, status; @@ -545,7 +545,7 @@ static void em28xx_isocIrq(struct urb *urb) return; #ifdef ENABLE_DEBUG_ISOC_FRAMES if (isoc_debug>1) - em28xx_isoc_dump(urb); + em28xx_isoc_dump(urb, regs); #endif if (urb->status == -ENOENT) diff --git a/trunk/drivers/media/video/em28xx/em28xx-video.c b/trunk/drivers/media/video/em28xx/em28xx-video.c index 2a461dde480c..20df657b70c8 100644 --- a/trunk/drivers/media/video/em28xx/em28xx-video.c +++ b/trunk/drivers/media/video/em28xx/em28xx-video.c @@ -174,7 +174,7 @@ static void em28xx_config_i2c(struct em28xx *dev) route.input = INPUT(dev->ctl_input)->vmux; route.output = 0; - em28xx_i2c_call_clients(dev, VIDIOC_INT_RESET, NULL); + em28xx_i2c_call_clients(dev, VIDIOC_INT_RESET, 0); em28xx_i2c_call_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route); em28xx_i2c_call_clients(dev, VIDIOC_STREAMON, NULL); diff --git a/trunk/drivers/media/video/et61x251/et61x251_core.c b/trunk/drivers/media/video/et61x251/et61x251_core.c index 86e353b26b53..8992b6e62b9f 100644 --- a/trunk/drivers/media/video/et61x251/et61x251_core.c +++ b/trunk/drivers/media/video/et61x251/et61x251_core.c @@ -398,7 +398,7 @@ int et61x251_i2c_write(struct et61x251_device* cam, u8 address, u8 value) /*****************************************************************************/ -static void et61x251_urb_complete(struct urb *urb) +static void et61x251_urb_complete(struct urb *urb, struct pt_regs* regs) { struct et61x251_device* cam = urb->context; struct et61x251_frame_t** f; @@ -973,32 +973,16 @@ static CLASS_DEVICE_ATTR(i2c_val, S_IRUGO | S_IWUSR, et61x251_show_i2c_val, et61x251_store_i2c_val); -static int et61x251_create_sysfs(struct et61x251_device* cam) +static void et61x251_create_sysfs(struct et61x251_device* cam) { struct video_device *v4ldev = cam->v4ldev; - int rc; - rc = video_device_create_file(v4ldev, &class_device_attr_reg); - if (rc) goto err; - rc = video_device_create_file(v4ldev, &class_device_attr_val); - if (rc) goto err_reg; + video_device_create_file(v4ldev, &class_device_attr_reg); + video_device_create_file(v4ldev, &class_device_attr_val); if (cam->sensor.sysfs_ops) { - rc = video_device_create_file(v4ldev, &class_device_attr_i2c_reg); - if (rc) goto err_val; - rc = video_device_create_file(v4ldev, &class_device_attr_i2c_val); - if (rc) goto err_i2c_reg; + video_device_create_file(v4ldev, &class_device_attr_i2c_reg); + video_device_create_file(v4ldev, &class_device_attr_i2c_val); } - - return 0; - -err_i2c_reg: - video_device_remove_file(v4ldev, &class_device_attr_i2c_reg); -err_val: - video_device_remove_file(v4ldev, &class_device_attr_val); -err_reg: - video_device_remove_file(v4ldev, &class_device_attr_reg); -err: - return rc; } #endif /* CONFIG_VIDEO_ADV_DEBUG */ @@ -1182,6 +1166,8 @@ static void et61x251_release_resources(struct et61x251_device* cam) video_set_drvdata(cam->v4ldev, NULL); video_unregister_device(cam->v4ldev); + usb_put_dev(cam->usbdev); + mutex_unlock(&et61x251_sysfs_lock); kfree(cam->control_buffer); @@ -1273,7 +1259,6 @@ static int et61x251_release(struct inode* inode, struct file* filp) if (cam->state & DEV_DISCONNECTED) { et61x251_release_resources(cam); - usb_put_dev(cam->usbdev); mutex_unlock(&cam->dev_mutex); kfree(cam); return 0; @@ -2549,9 +2534,7 @@ et61x251_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) dev_nr = (dev_nr < ET61X251_MAX_DEVICES-1) ? dev_nr+1 : 0; #ifdef CONFIG_VIDEO_ADV_DEBUG - err = et61x251_create_sysfs(cam); - if (err) - goto fail2; + et61x251_create_sysfs(cam); DBG(2, "Optional device control through 'sysfs' interface ready"); #endif @@ -2561,13 +2544,6 @@ et61x251_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) return 0; -#ifdef CONFIG_VIDEO_ADV_DEBUG -fail2: - video_nr[dev_nr] = -1; - dev_nr = (dev_nr < ET61X251_MAX_DEVICES-1) ? dev_nr+1 : 0; - mutex_unlock(&cam->dev_mutex); - video_unregister_device(cam->v4ldev); -#endif fail: if (cam) { kfree(cam->control_buffer); diff --git a/trunk/drivers/media/video/meye.c b/trunk/drivers/media/video/meye.c index b083338823df..e278753f8f25 100644 --- a/trunk/drivers/media/video/meye.c +++ b/trunk/drivers/media/video/meye.c @@ -786,7 +786,7 @@ static void mchip_cont_compression_start(void) /* Interrupt handling */ /****************************************************************************/ -static irqreturn_t meye_irq(int irq, void *dev_id) +static irqreturn_t meye_irq(int irq, void *dev_id, struct pt_regs *regs) { u32 v; int reqnr; diff --git a/trunk/drivers/media/video/ov511.c b/trunk/drivers/media/video/ov511.c index b4db2cbb5a84..5d8cd283fcd8 100644 --- a/trunk/drivers/media/video/ov511.c +++ b/trunk/drivers/media/video/ov511.c @@ -3503,7 +3503,7 @@ ov518_move_data(struct usb_ov511 *ov, unsigned char *in, int n) } static void -ov51x_isoc_irq(struct urb *urb) +ov51x_isoc_irq(struct urb *urb, struct pt_regs *regs) { int i; struct usb_ov511 *ov; @@ -5648,49 +5648,17 @@ static ssize_t show_exposure(struct class_device *cd, char *buf) } static CLASS_DEVICE_ATTR(exposure, S_IRUGO, show_exposure, NULL); -static int ov_create_sysfs(struct video_device *vdev) +static void ov_create_sysfs(struct video_device *vdev) { - int rc; - - rc = video_device_create_file(vdev, &class_device_attr_custom_id); - if (rc) goto err; - rc = video_device_create_file(vdev, &class_device_attr_model); - if (rc) goto err_id; - rc = video_device_create_file(vdev, &class_device_attr_bridge); - if (rc) goto err_model; - rc = video_device_create_file(vdev, &class_device_attr_sensor); - if (rc) goto err_bridge; - rc = video_device_create_file(vdev, &class_device_attr_brightness); - if (rc) goto err_sensor; - rc = video_device_create_file(vdev, &class_device_attr_saturation); - if (rc) goto err_bright; - rc = video_device_create_file(vdev, &class_device_attr_contrast); - if (rc) goto err_sat; - rc = video_device_create_file(vdev, &class_device_attr_hue); - if (rc) goto err_contrast; - rc = video_device_create_file(vdev, &class_device_attr_exposure); - if (rc) goto err_hue; - - return 0; - -err_hue: - video_device_remove_file(vdev, &class_device_attr_hue); -err_contrast: - video_device_remove_file(vdev, &class_device_attr_contrast); -err_sat: - video_device_remove_file(vdev, &class_device_attr_saturation); -err_bright: - video_device_remove_file(vdev, &class_device_attr_brightness); -err_sensor: - video_device_remove_file(vdev, &class_device_attr_sensor); -err_bridge: - video_device_remove_file(vdev, &class_device_attr_bridge); -err_model: - video_device_remove_file(vdev, &class_device_attr_model); -err_id: - video_device_remove_file(vdev, &class_device_attr_custom_id); -err: - return rc; + video_device_create_file(vdev, &class_device_attr_custom_id); + video_device_create_file(vdev, &class_device_attr_model); + video_device_create_file(vdev, &class_device_attr_bridge); + video_device_create_file(vdev, &class_device_attr_sensor); + video_device_create_file(vdev, &class_device_attr_brightness); + video_device_create_file(vdev, &class_device_attr_saturation); + video_device_create_file(vdev, &class_device_attr_contrast); + video_device_create_file(vdev, &class_device_attr_hue); + video_device_create_file(vdev, &class_device_attr_exposure); } /**************************************************************************** @@ -5849,11 +5817,7 @@ ov51x_probe(struct usb_interface *intf, const struct usb_device_id *id) ov->vdev->minor); usb_set_intfdata(intf, ov); - if (ov_create_sysfs(ov->vdev)) { - err("ov_create_sysfs failed"); - goto error; - } - + ov_create_sysfs(ov->vdev); return 0; error: diff --git a/trunk/drivers/media/video/planb.c b/trunk/drivers/media/video/planb.c index 368d6e219fa4..3484e36b6801 100644 --- a/trunk/drivers/media/video/planb.c +++ b/trunk/drivers/media/video/planb.c @@ -91,7 +91,7 @@ static void planb_close(struct video_device *); static int planb_ioctl(struct video_device *, unsigned int, void *); static int planb_init_done(struct video_device *); static int planb_mmap(struct video_device *, const char *, unsigned long); -static void planb_irq(int, void *); +static void planb_irq(int, void *, struct pt_regs *); static void release_planb(void); int init_planbs(struct video_init *); @@ -1316,7 +1316,7 @@ static volatile struct dbdma_cmd *setup_grab_cmd(int fr, struct planb *pb) return c1; } -static void planb_irq(int irq, void *dev_id) +static void planb_irq(int irq, void *dev_id, struct pt_regs * regs) { unsigned int stat, astat; struct planb *pb = (struct planb *)dev_id; diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c index c80c26be6e4d..df8feac16aee 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c @@ -221,7 +221,7 @@ static unsigned int decoder_describe(struct pvr2_v4l_cx2584x *ctxt, static void decoder_reset(struct pvr2_v4l_cx2584x *ctxt) { int ret; - ret = pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_RESET,NULL); + ret = pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_RESET,0); pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx25840 decoder_reset (ret=%d)",ret); } diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 1f787333d18c..3d8cd0daf6a9 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -1953,8 +1953,8 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, return hdw; fail: if (hdw) { - usb_free_urb(hdw->ctl_read_urb); - usb_free_urb(hdw->ctl_write_urb); + if (hdw->ctl_read_urb) usb_free_urb(hdw->ctl_read_urb); + if (hdw->ctl_write_urb) usb_free_urb(hdw->ctl_write_urb); if (hdw->ctl_read_buffer) kfree(hdw->ctl_read_buffer); if (hdw->ctl_write_buffer) kfree(hdw->ctl_write_buffer); if (hdw->controls) kfree(hdw->controls); @@ -2552,7 +2552,7 @@ void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *hdw,int v) } -static void pvr2_ctl_write_complete(struct urb *urb) +static void pvr2_ctl_write_complete(struct urb *urb, struct pt_regs *regs) { struct pvr2_hdw *hdw = urb->context; hdw->ctl_write_pend_flag = 0; @@ -2561,7 +2561,7 @@ static void pvr2_ctl_write_complete(struct urb *urb) } -static void pvr2_ctl_read_complete(struct urb *urb) +static void pvr2_ctl_read_complete(struct urb *urb, struct pt_regs *regs) { struct pvr2_hdw *hdw = urb->context; hdw->ctl_read_pend_flag = 0; @@ -2575,10 +2575,12 @@ static void pvr2_ctl_timeout(unsigned long data) struct pvr2_hdw *hdw = (struct pvr2_hdw *)data; if (hdw->ctl_write_pend_flag || hdw->ctl_read_pend_flag) { hdw->ctl_timeout_flag = !0; - if (hdw->ctl_write_pend_flag) + if (hdw->ctl_write_pend_flag && hdw->ctl_write_urb) { usb_unlink_urb(hdw->ctl_write_urb); - if (hdw->ctl_read_pend_flag) + } + if (hdw->ctl_read_pend_flag && hdw->ctl_read_urb) { usb_unlink_urb(hdw->ctl_read_urb); + } } } diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-io.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-io.c index 57fb32033543..1e393762546c 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-io.c +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-io.c @@ -289,7 +289,7 @@ static void pvr2_buffer_done(struct pvr2_buffer *bp) pvr2_buffer_set_none(bp); bp->signature = 0; bp->stream = NULL; - usb_free_urb(bp->purb); + if (bp->purb) usb_free_urb(bp->purb); pvr2_trace(PVR2_TRACE_BUF_POOL,"/*---TRACE_FLOW---*/" " bufferDone %p",bp); } @@ -429,7 +429,7 @@ static void pvr2_stream_done(struct pvr2_stream *sp) } while (0); mutex_unlock(&sp->mutex); } -static void buffer_complete(struct urb *urb) +static void buffer_complete(struct urb *urb, struct pt_regs *regs) { struct pvr2_buffer *bp = urb->context; struct pvr2_stream *sp; diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-v4l2.c index bb40e9085977..97e974d9b9c3 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-v4l2.c +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-v4l2.c @@ -711,8 +711,8 @@ static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip) dip->devbase.minor,pvr2_config_get_name(dip->config)); /* Paranoia */ - dip->v4lp = NULL; - dip->stream = NULL; + dip->v4lp = 0; + dip->stream = 0; /* Actual deallocation happens later when all internal references are gone. */ @@ -1076,7 +1076,7 @@ struct pvr2_v4l2 *pvr2_v4l2_create(struct pvr2_context *mnp) vp->vdev = kmalloc(sizeof(*vp->vdev),GFP_KERNEL); if (!vp->vdev) { kfree(vp); - return NULL; + return 0; } memset(vp->vdev,0,sizeof(*vp->vdev)); pvr2_channel_init(&vp->channel,mnp); diff --git a/trunk/drivers/media/video/pwc/pwc-if.c b/trunk/drivers/media/video/pwc/pwc-if.c index a996aad79276..53c4b5790d5c 100644 --- a/trunk/drivers/media/video/pwc/pwc-if.c +++ b/trunk/drivers/media/video/pwc/pwc-if.c @@ -682,7 +682,7 @@ static int pwc_rcv_short_packet(struct pwc_device *pdev, const struct pwc_frame_ /* This gets called for the Isochronous pipe (video). This is done in * interrupt time, so it has to be fast, not crash, and not stall. Neat. */ -static void pwc_isoc_handler(struct urb *urb) +static void pwc_isoc_handler(struct urb *urb, struct pt_regs *regs) { struct pwc_device *pdev; int i, fst, flen; @@ -866,9 +866,11 @@ int pwc_isoc_init(struct pwc_device *pdev) } if (ret) { /* De-allocate in reverse order */ - while (i--) { - usb_free_urb(pdev->sbuf[i].urb); + while (i >= 0) { + if (pdev->sbuf[i].urb != NULL) + usb_free_urb(pdev->sbuf[i].urb); pdev->sbuf[i].urb = NULL; + i--; } return ret; } @@ -1022,25 +1024,12 @@ static ssize_t show_snapshot_button_status(struct class_device *class_dev, char static CLASS_DEVICE_ATTR(button, S_IRUGO | S_IWUSR, show_snapshot_button_status, NULL); -static int pwc_create_sysfs_files(struct video_device *vdev) +static void pwc_create_sysfs_files(struct video_device *vdev) { struct pwc_device *pdev = video_get_drvdata(vdev); - int rc; - - rc = video_device_create_file(vdev, &class_device_attr_button); - if (rc) - goto err; - if (pdev->features & FEATURE_MOTOR_PANTILT) { - rc = video_device_create_file(vdev,&class_device_attr_pan_tilt); - if (rc) goto err_button; - } - - return 0; - -err_button: - video_device_remove_file(vdev, &class_device_attr_button); -err: - return rc; + if (pdev->features & FEATURE_MOTOR_PANTILT) + video_device_create_file(vdev, &class_device_attr_pan_tilt); + video_device_create_file(vdev, &class_device_attr_button); } static void pwc_remove_sysfs_files(struct video_device *vdev) @@ -1093,7 +1082,8 @@ static int pwc_video_open(struct inode *inode, struct file *file) PWC_DEBUG_OPEN(">> video_open called(vdev = 0x%p).\n", vdev); pdev = (struct pwc_device *)vdev->priv; - BUG_ON(!pdev); + if (pdev == NULL) + BUG(); if (pdev->vopen) { PWC_DEBUG_OPEN("I'm busy, someone is using the device.\n"); return -EBUSY; @@ -1418,7 +1408,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id struct usb_device *udev = interface_to_usbdev(intf); struct pwc_device *pdev = NULL; int vendor_id, product_id, type_id; - int i, hint, rc; + int i, hint; int features = 0; int video_nr = -1; /* default: use next available device */ char serial_number[30], *name; @@ -1719,8 +1709,9 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id i = video_register_device(pdev->vdev, VFL_TYPE_GRABBER, video_nr); if (i < 0) { PWC_ERROR("Failed to register as video device (%d).\n", i); - rc = i; - goto err; + video_device_release(pdev->vdev); /* Drip... drip... drip... */ + kfree(pdev); /* Oops, no memory leaks please */ + return -EIO; } else { PWC_INFO("Registered as /dev/video%d.\n", pdev->vdev->minor & 0x3F); @@ -1732,24 +1723,13 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id PWC_DEBUG_PROBE("probe() function returning struct at 0x%p.\n", pdev); usb_set_intfdata (intf, pdev); - rc = pwc_create_sysfs_files(pdev->vdev); - if (rc) - goto err_unreg; + pwc_create_sysfs_files(pdev->vdev); /* Set the leds off */ pwc_set_leds(pdev, 0, 0); pwc_camera_power(pdev, 0); return 0; - -err_unreg: - if (hint < MAX_DEV_HINTS) - device_hint[hint].pdev = NULL; - video_unregister_device(pdev->vdev); -err: - video_device_release(pdev->vdev); /* Drip... drip... drip... */ - kfree(pdev); /* Oops, no memory leaks please */ - return rc; } /* The user janked out the cable... */ diff --git a/trunk/drivers/media/video/saa6588.c b/trunk/drivers/media/video/saa6588.c index 7b9859c33018..a81285ca7d5b 100644 --- a/trunk/drivers/media/video/saa6588.c +++ b/trunk/drivers/media/video/saa6588.c @@ -212,10 +212,8 @@ static void read_from_buf(struct saa6588 *s, struct rds_command *a) if (rd_blocks > s->block_count) rd_blocks = s->block_count; - if (!rd_blocks) { - spin_unlock_irqrestore(&s->lock, flags); + if (!rd_blocks) return; - } for (i = 0; i < rd_blocks; i++) { if (block_to_user_buf(s, buf_ptr)) { diff --git a/trunk/drivers/media/video/saa7115.c b/trunk/drivers/media/video/saa7115.c index f28398dd9d93..974179d4d389 100644 --- a/trunk/drivers/media/video/saa7115.c +++ b/trunk/drivers/media/video/saa7115.c @@ -960,8 +960,6 @@ static void saa711x_set_v4lstd(struct i2c_client *client, v4l2_std_id std) reg |= 0x10; } else if (std == V4L2_STD_NTSC_M_JP) { reg |= 0x40; - } else if (std == V4L2_STD_SECAM) { - reg |= 0x50; } saa711x_write(client, R_0E_CHROMA_CNTL_1, reg); } else { @@ -1464,6 +1462,8 @@ static int saa711x_attach(struct i2c_adapter *adapter, int address, int kind) client->driver = &i2c_driver_saa711x; snprintf(client->name, sizeof(client->name) - 1, "saa7115"); + v4l_dbg(1, debug, client, "detecting saa7115 client on address 0x%x\n", address << 1); + for (i=0;i<0x0f;i++) { saa711x_write(client, 0, i); name[i] = (saa711x_read(client, 0) &0x0f) +'0'; @@ -1475,13 +1475,6 @@ static int saa711x_attach(struct i2c_adapter *adapter, int address, int kind) saa711x_write(client, 0, 5); chip_id = saa711x_read(client, 0) & 0x0f; - /* Check whether this chip is part of the saa711x series */ - if (memcmp(name, "1f711", 5)) { - v4l_dbg(1, debug, client, "chip found @ 0x%x (ID %s) does not match a known saa711x chip.\n", - address << 1, name); - return 0; - } - snprintf(client->name, sizeof(client->name) - 1, "saa711%d",chip_id); v4l_info(client, "saa711%d found (%s) @ 0x%x (%s)\n", chip_id, name, address << 1, adapter->name); diff --git a/trunk/drivers/media/video/saa7134/saa7134-alsa.c b/trunk/drivers/media/video/saa7134/saa7134-alsa.c index 4abf5c03a740..a39e0136ce3b 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-alsa.c +++ b/trunk/drivers/media/video/saa7134/saa7134-alsa.c @@ -212,7 +212,7 @@ static void saa7134_irq_alsa_done(struct saa7134_dev *dev, * */ -static irqreturn_t saa7134_alsa_irq(int irq, void *dev_id) +static irqreturn_t saa7134_alsa_irq(int irq, void *dev_id, struct pt_regs *regs) { struct saa7134_dmasound *dmasound = dev_id; struct saa7134_dev *dev = dmasound->priv_data; diff --git a/trunk/drivers/media/video/saa7134/saa7134-cards.c b/trunk/drivers/media/video/saa7134/saa7134-cards.c index 51f0cfdcb680..c9d8e3b9cc37 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-cards.c +++ b/trunk/drivers/media/video/saa7134/saa7134-cards.c @@ -2969,7 +2969,7 @@ struct saa7134_board saa7134_boards[] = { /* Petr Baudis */ .name = "AVerMedia TV Hybrid A16AR", .audio_clock = 0x187de7, - .tuner_type = TUNER_PHILIPS_TD1316, /* untested */ + .tuner_type = TUNER_PHILIPS_TDA8290, /* untested */ .radio_type = TUNER_TEA5767, /* untested */ .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, @@ -3718,7 +3718,6 @@ int saa7134_board_init1(struct saa7134_dev *dev) case SAA7134_BOARD_AVERMEDIA_STUDIO_307: case SAA7134_BOARD_AVERMEDIA_307: case SAA7134_BOARD_AVERMEDIA_GO_007_FM: - case SAA7134_BOARD_AVERMEDIA_777: /* case SAA7134_BOARD_SABRENT_SBTTVFM: */ /* not finished yet */ case SAA7134_BOARD_VIDEOMATE_TV_PVR: case SAA7134_BOARD_VIDEOMATE_GOLD_PLUS: @@ -3735,7 +3734,6 @@ int saa7134_board_init1(struct saa7134_dev *dev) case SAA7134_BOARD_FLYDVBT_LR301: case SAA7134_BOARD_FLYDVBTDUO: case SAA7134_BOARD_PROTEUS_2309: - case SAA7134_BOARD_AVERMEDIA_A16AR: dev->has_remote = SAA7134_REMOTE_GPIO; break; case SAA7134_BOARD_FLYDVBS_LR300: @@ -3774,6 +3772,7 @@ int saa7134_board_init1(struct saa7134_dev *dev) saa_writeb(SAA7134_GPIO_GPMODE3, 0x08); saa_writeb(SAA7134_GPIO_GPSTATUS3, 0x00); break; + case SAA7134_BOARD_AVERMEDIA_A16AR: case SAA7134_BOARD_AVERMEDIA_CARDBUS: /* power-up tuner chip */ saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0xffffffff, 0xffffffff); diff --git a/trunk/drivers/media/video/saa7134/saa7134-core.c b/trunk/drivers/media/video/saa7134/saa7134-core.c index 5c9e63dfbea6..09aa62f61af7 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-core.c +++ b/trunk/drivers/media/video/saa7134/saa7134-core.c @@ -495,7 +495,7 @@ static void print_irqstatus(struct saa7134_dev *dev, int loop, printk("\n"); } -static irqreturn_t saa7134_irq(int irq, void *dev_id) +static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs) { struct saa7134_dev *dev = (struct saa7134_dev*) dev_id; unsigned long report,status; diff --git a/trunk/drivers/media/video/saa7134/saa7134-dvb.c b/trunk/drivers/media/video/saa7134/saa7134-dvb.c index 6b61d9b2fcb5..1ba53b525ad2 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-dvb.c +++ b/trunk/drivers/media/video/saa7134/saa7134-dvb.c @@ -1147,8 +1147,6 @@ static int dvb_init(struct saa7134_dev *dev) &philips_europa_config, &dev->i2c_adap); if (dev->dvb.frontend) { - dev->original_demod_sleep = dev->dvb.frontend->ops.sleep; - dev->dvb.frontend->ops.sleep = philips_europa_demod_sleep; dev->dvb.frontend->ops.tuner_ops.init = philips_europa_tuner_init; dev->dvb.frontend->ops.tuner_ops.sleep = philips_europa_tuner_sleep; dev->dvb.frontend->ops.tuner_ops.set_params = philips_td1316_tuner_set_params; diff --git a/trunk/drivers/media/video/saa7134/saa7134-input.c b/trunk/drivers/media/video/saa7134/saa7134-input.c index dee83552e681..ff5991136f4e 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-input.c +++ b/trunk/drivers/media/video/saa7134/saa7134-input.c @@ -185,6 +185,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) case SAA7134_BOARD_AVERMEDIA_STUDIO_305: case SAA7134_BOARD_AVERMEDIA_STUDIO_307: case SAA7134_BOARD_AVERMEDIA_GO_007_FM: + case SAA7134_BOARD_AVERMEDIA_A16AR: ir_codes = ir_codes_avermedia; mask_keycode = 0x0007C8; mask_keydown = 0x000010; @@ -193,16 +194,6 @@ int saa7134_input_init1(struct saa7134_dev *dev) saa_setb(SAA7134_GPIO_GPMODE0, 0x4); saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4); break; - case SAA7134_BOARD_AVERMEDIA_777: - case SAA7134_BOARD_AVERMEDIA_A16AR: - ir_codes = ir_codes_avermedia; - mask_keycode = 0x02F200; - mask_keydown = 0x000400; - polling = 50; // ms - /* Without this we won't receive key up events */ - saa_setb(SAA7134_GPIO_GPMODE1, 0x1); - saa_setb(SAA7134_GPIO_GPSTATUS1, 0x1); - break; case SAA7134_BOARD_KWORLD_TERMINATOR: ir_codes = ir_codes_pixelview; mask_keycode = 0x00001f; diff --git a/trunk/drivers/media/video/saa7134/saa7134-oss.c b/trunk/drivers/media/video/saa7134/saa7134-oss.c index bfcb860d14cc..2e3ba5f31453 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-oss.c +++ b/trunk/drivers/media/video/saa7134/saa7134-oss.c @@ -814,7 +814,7 @@ struct file_operations saa7134_mixer_fops = { /* ------------------------------------------------------------------ */ -static irqreturn_t saa7134_oss_irq(int irq, void *dev_id) +static irqreturn_t saa7134_oss_irq(int irq, void *dev_id, struct pt_regs *regs) { struct saa7134_dmasound *dmasound = dev_id; struct saa7134_dev *dev = dmasound->priv_data; diff --git a/trunk/drivers/media/video/saa7134/saa7134-video.c b/trunk/drivers/media/video/saa7134/saa7134-video.c index 830617ea81cc..203302f21827 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-video.c +++ b/trunk/drivers/media/video/saa7134/saa7134-video.c @@ -2248,11 +2248,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file, t->type = V4L2_TUNER_RADIO; saa7134_i2c_call_clients(dev, VIDIOC_G_TUNER, t); - if (dev->input->amux == TV) { - t->signal = 0xf800 - ((saa_readb(0x581) & 0x1f) << 11); - t->rxsubchans = (saa_readb(0x529) & 0x08) ? - V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO; - } + return 0; } case VIDIOC_S_TUNER: diff --git a/trunk/drivers/media/video/se401.c b/trunk/drivers/media/video/se401.c index 7aeec574d7ce..67987baee77a 100644 --- a/trunk/drivers/media/video/se401.c +++ b/trunk/drivers/media/video/se401.c @@ -282,7 +282,7 @@ static void se401_auto_resetlevel(struct usb_se401 *se401) } /* irq handler for snapshot button */ -static void se401_button_irq(struct urb *urb) +static void se401_button_irq(struct urb *urb, struct pt_regs *regs) { struct usb_se401 *se401 = urb->context; int status; @@ -318,7 +318,7 @@ static void se401_button_irq(struct urb *urb) __FUNCTION__, status); } -static void se401_video_irq(struct urb *urb) +static void se401_video_irq(struct urb *urb, struct pt_regs *regs) { struct usb_se401 *se401 = urb->context; int length = urb->actual_length; diff --git a/trunk/drivers/media/video/sn9c102/sn9c102_core.c b/trunk/drivers/media/video/sn9c102/sn9c102_core.c index 18458d46c0ff..48d138a7c723 100644 --- a/trunk/drivers/media/video/sn9c102/sn9c102_core.c +++ b/trunk/drivers/media/video/sn9c102/sn9c102_core.c @@ -518,7 +518,7 @@ sn9c102_find_eof_header(struct sn9c102_device* cam, void* mem, size_t len) } -static void sn9c102_urb_complete(struct urb *urb) +static void sn9c102_urb_complete(struct urb *urb, struct pt_regs* regs) { struct sn9c102_device* cam = urb->context; struct sn9c102_frame_t** f; @@ -775,7 +775,7 @@ static int sn9c102_start_transfer(struct sn9c102_device* cam) return 0; free_urbs: - for (i = 0; i < SN9C102_URBS; i++) + for (i = 0; (i < SN9C102_URBS) && cam->urb[i]; i++) usb_free_urb(cam->urb[i]); free_buffers: @@ -1240,53 +1240,23 @@ static CLASS_DEVICE_ATTR(frame_header, S_IRUGO, sn9c102_show_frame_header, NULL); -static int sn9c102_create_sysfs(struct sn9c102_device* cam) +static void sn9c102_create_sysfs(struct sn9c102_device* cam) { struct video_device *v4ldev = cam->v4ldev; - int rc; - rc = video_device_create_file(v4ldev, &class_device_attr_reg); - if (rc) goto err; - rc = video_device_create_file(v4ldev, &class_device_attr_val); - if (rc) goto err_reg; - rc = video_device_create_file(v4ldev, &class_device_attr_frame_header); - if (rc) goto err_val; - - if (cam->sensor.sysfs_ops) { - rc = video_device_create_file(v4ldev, &class_device_attr_i2c_reg); - if (rc) goto err_frhead; - rc = video_device_create_file(v4ldev, &class_device_attr_i2c_val); - if (rc) goto err_i2c_reg; + video_device_create_file(v4ldev, &class_device_attr_reg); + video_device_create_file(v4ldev, &class_device_attr_val); + video_device_create_file(v4ldev, &class_device_attr_frame_header); + if (cam->bridge == BRIDGE_SN9C101 || cam->bridge == BRIDGE_SN9C102) + video_device_create_file(v4ldev, &class_device_attr_green); + else if (cam->bridge == BRIDGE_SN9C103) { + video_device_create_file(v4ldev, &class_device_attr_blue); + video_device_create_file(v4ldev, &class_device_attr_red); } - - if (cam->bridge == BRIDGE_SN9C101 || cam->bridge == BRIDGE_SN9C102) { - rc = video_device_create_file(v4ldev, &class_device_attr_green); - if (rc) goto err_i2c_val; - } else if (cam->bridge == BRIDGE_SN9C103) { - rc = video_device_create_file(v4ldev, &class_device_attr_blue); - if (rc) goto err_i2c_val; - rc = video_device_create_file(v4ldev, &class_device_attr_red); - if (rc) goto err_blue; + if (cam->sensor.sysfs_ops) { + video_device_create_file(v4ldev, &class_device_attr_i2c_reg); + video_device_create_file(v4ldev, &class_device_attr_i2c_val); } - - return 0; - -err_blue: - video_device_remove_file(v4ldev, &class_device_attr_blue); -err_i2c_val: - if (cam->sensor.sysfs_ops) - video_device_remove_file(v4ldev, &class_device_attr_i2c_val); -err_i2c_reg: - if (cam->sensor.sysfs_ops) - video_device_remove_file(v4ldev, &class_device_attr_i2c_reg); -err_frhead: - video_device_remove_file(v4ldev, &class_device_attr_frame_header); -err_val: - video_device_remove_file(v4ldev, &class_device_attr_val); -err_reg: - video_device_remove_file(v4ldev, &class_device_attr_reg); -err: - return rc; } #endif /* CONFIG_VIDEO_ADV_DEBUG */ @@ -1462,6 +1432,8 @@ static void sn9c102_release_resources(struct sn9c102_device* cam) video_set_drvdata(cam->v4ldev, NULL); video_unregister_device(cam->v4ldev); + usb_put_dev(cam->usbdev); + mutex_unlock(&sn9c102_sysfs_lock); kfree(cam->control_buffer); @@ -1553,7 +1525,6 @@ static int sn9c102_release(struct inode* inode, struct file* filp) if (cam->state & DEV_DISCONNECTED) { sn9c102_release_resources(cam); - usb_put_dev(cam->usbdev); mutex_unlock(&cam->dev_mutex); kfree(cam); return 0; @@ -2838,7 +2809,10 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) DBG(1, "V4L2 device registration failed"); if (err == -ENFILE && video_nr[dev_nr] == -1) DBG(1, "Free /dev/videoX node not found"); - goto fail2; + video_nr[dev_nr] = -1; + dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0; + mutex_unlock(&cam->dev_mutex); + goto fail; } DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->minor); @@ -2849,9 +2823,7 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0; #ifdef CONFIG_VIDEO_ADV_DEBUG - err = sn9c102_create_sysfs(cam); - if (err) - goto fail3; + sn9c102_create_sysfs(cam); DBG(2, "Optional device control through 'sysfs' interface ready"); #endif @@ -2861,14 +2833,6 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) return 0; -#ifdef CONFIG_VIDEO_ADV_DEBUG -fail3: - video_unregister_device(cam->v4ldev); -#endif -fail2: - video_nr[dev_nr] = -1; - dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0; - mutex_unlock(&cam->dev_mutex); fail: if (cam) { kfree(cam->control_buffer); diff --git a/trunk/drivers/media/video/stradis.c b/trunk/drivers/media/video/stradis.c index 525d81288d55..5686547ba76a 100644 --- a/trunk/drivers/media/video/stradis.c +++ b/trunk/drivers/media/video/stradis.c @@ -406,7 +406,7 @@ static void send_osd_data(struct saa7146 *saa) } } -static irqreturn_t saa7146_irq(int irq, void *dev_id) +static irqreturn_t saa7146_irq(int irq, void *dev_id, struct pt_regs *regs) { struct saa7146 *saa = dev_id; u32 stat, astat; diff --git a/trunk/drivers/media/video/stv680.c b/trunk/drivers/media/video/stv680.c index 6d1ef1e2e8ef..2ba2991a214f 100644 --- a/trunk/drivers/media/video/stv680.c +++ b/trunk/drivers/media/video/stv680.c @@ -516,45 +516,16 @@ stv680_file(frames_read, framecount, "%d\n"); stv680_file(packets_dropped, dropped, "%d\n"); stv680_file(decoding_errors, error, "%d\n"); -static int stv680_create_sysfs_files(struct video_device *vdev) +static void stv680_create_sysfs_files(struct video_device *vdev) { - int rc; - - rc = video_device_create_file(vdev, &class_device_attr_model); - if (rc) goto err; - rc = video_device_create_file(vdev, &class_device_attr_in_use); - if (rc) goto err_model; - rc = video_device_create_file(vdev, &class_device_attr_streaming); - if (rc) goto err_inuse; - rc = video_device_create_file(vdev, &class_device_attr_palette); - if (rc) goto err_stream; - rc = video_device_create_file(vdev, &class_device_attr_frames_total); - if (rc) goto err_pal; - rc = video_device_create_file(vdev, &class_device_attr_frames_read); - if (rc) goto err_framtot; - rc = video_device_create_file(vdev, &class_device_attr_packets_dropped); - if (rc) goto err_framread; - rc = video_device_create_file(vdev, &class_device_attr_decoding_errors); - if (rc) goto err_dropped; - - return 0; - -err_dropped: - video_device_remove_file(vdev, &class_device_attr_packets_dropped); -err_framread: - video_device_remove_file(vdev, &class_device_attr_frames_read); -err_framtot: - video_device_remove_file(vdev, &class_device_attr_frames_total); -err_pal: - video_device_remove_file(vdev, &class_device_attr_palette); -err_stream: - video_device_remove_file(vdev, &class_device_attr_streaming); -err_inuse: - video_device_remove_file(vdev, &class_device_attr_in_use); -err_model: - video_device_remove_file(vdev, &class_device_attr_model); -err: - return rc; + video_device_create_file(vdev, &class_device_attr_model); + video_device_create_file(vdev, &class_device_attr_in_use); + video_device_create_file(vdev, &class_device_attr_streaming); + video_device_create_file(vdev, &class_device_attr_palette); + video_device_create_file(vdev, &class_device_attr_frames_total); + video_device_create_file(vdev, &class_device_attr_frames_read); + video_device_create_file(vdev, &class_device_attr_packets_dropped); + video_device_create_file(vdev, &class_device_attr_decoding_errors); } static void stv680_remove_sysfs_files(struct video_device *vdev) @@ -611,7 +582,7 @@ static int stv680_set_pict (struct usb_stv *stv680, struct video_picture *p) return 0; } -static void stv680_video_irq (struct urb *urb) +static void stv680_video_irq (struct urb *urb, struct pt_regs *regs) { struct usb_stv *stv680 = urb->context; int length = urb->actual_length; @@ -1447,13 +1418,9 @@ static int stv680_probe (struct usb_interface *intf, const struct usb_device_id PDEBUG (0, "STV(i): registered new video device: video%d", stv680->vdev->minor); usb_set_intfdata (intf, stv680); - retval = stv680_create_sysfs_files(stv680->vdev); - if (retval) - goto error_unreg; + stv680_create_sysfs_files(stv680->vdev); return 0; -error_unreg: - video_unregister_device(stv680->vdev); error_vdev: video_device_release(stv680->vdev); error: diff --git a/trunk/drivers/media/video/tuner-types.c b/trunk/drivers/media/video/tuner-types.c index 781682373b61..8fff642fad56 100644 --- a/trunk/drivers/media/video/tuner-types.c +++ b/trunk/drivers/media/video/tuner-types.c @@ -1046,6 +1046,7 @@ static struct tuner_params tuner_samsung_tcpn_2121p30a_params[] = { .type = TUNER_PARAM_TYPE_NTSC, .ranges = tuner_samsung_tcpn_2121p30a_ntsc_ranges, .count = ARRAY_SIZE(tuner_samsung_tcpn_2121p30a_ntsc_ranges), + .has_tda9887 = 1, }, }; diff --git a/trunk/drivers/media/video/tveeprom.c b/trunk/drivers/media/video/tveeprom.c index 6b9ef731b83a..e6baaee038bf 100644 --- a/trunk/drivers/media/video/tveeprom.c +++ b/trunk/drivers/media/video/tveeprom.c @@ -468,7 +468,7 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, (eeprom_data[i+6] << 8) + (eeprom_data[i+7] << 16); - if ( (eeprom_data[i + 8] & 0xf0) && + if ( (eeprom_data[i + 8] && 0xf0) && (tvee->serial_number < 0xffffff) ) { tvee->MAC_address[0] = 0x00; tvee->MAC_address[1] = 0x0D; diff --git a/trunk/drivers/media/video/usbvideo/konicawc.c b/trunk/drivers/media/video/usbvideo/konicawc.c index abe214619092..4eee8be88314 100644 --- a/trunk/drivers/media/video/usbvideo/konicawc.c +++ b/trunk/drivers/media/video/usbvideo/konicawc.c @@ -387,7 +387,7 @@ static void resubmit_urb(struct uvd *uvd, struct urb *urb) } -static void konicawc_isoc_irq(struct urb *urb) +static void konicawc_isoc_irq(struct urb *urb, struct pt_regs *regs) { struct uvd *uvd = urb->context; struct konicawc *cam = (struct konicawc *)uvd->user_data; diff --git a/trunk/drivers/media/video/usbvideo/quickcam_messenger.c b/trunk/drivers/media/video/usbvideo/quickcam_messenger.c index bbf2beeeb449..56e01b622417 100644 --- a/trunk/drivers/media/video/usbvideo/quickcam_messenger.c +++ b/trunk/drivers/media/video/usbvideo/quickcam_messenger.c @@ -125,7 +125,7 @@ static void qcm_report_buttonstat(struct qcm *cam) } } -static void qcm_int_irq(struct urb *urb) +static void qcm_int_irq(struct urb *urb, struct pt_regs *regs) { int ret; struct uvd *uvd = urb->context; @@ -190,7 +190,8 @@ static int qcm_alloc_int_urb(struct qcm *cam) static void qcm_free_int(struct qcm *cam) { - usb_free_urb(cam->button_urb); + if (cam->button_urb) + usb_free_urb(cam->button_urb); } #endif /* CONFIG_INPUT */ @@ -605,7 +606,7 @@ static void resubmit_urb(struct uvd *uvd, struct urb *urb) err("usb_submit_urb error (%d)", ret); } -static void qcm_isoc_irq(struct urb *urb) +static void qcm_isoc_irq(struct urb *urb, struct pt_regs *regs) { int len; struct uvd *uvd = urb->context; diff --git a/trunk/drivers/media/video/usbvideo/usbvideo.c b/trunk/drivers/media/video/usbvideo/usbvideo.c index d8b88024bc2f..13b37c8c0d56 100644 --- a/trunk/drivers/media/video/usbvideo/usbvideo.c +++ b/trunk/drivers/media/video/usbvideo/usbvideo.c @@ -1680,7 +1680,7 @@ static int usbvideo_CompressIsochronous(struct uvd *uvd, struct urb *urb) return totlen; } -static void usbvideo_IsocIrq(struct urb *urb) +static void usbvideo_IsocIrq(struct urb *urb, struct pt_regs *regs) { int i, ret, len; struct uvd *uvd = urb->context; diff --git a/trunk/drivers/media/video/videodev.c b/trunk/drivers/media/video/videodev.c index d424a4129d69..479a0675cf60 100644 --- a/trunk/drivers/media/video/videodev.c +++ b/trunk/drivers/media/video/videodev.c @@ -17,11 +17,10 @@ */ #define dbgarg(cmd, fmt, arg...) \ - if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { \ + if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) \ printk (KERN_DEBUG "%s: ", vfd->name); \ v4l_printk_ioctl(cmd); \ - printk (KERN_DEBUG "%s: " fmt, vfd->name, ## arg); \ - } + printk (KERN_DEBUG "%s: " fmt, vfd->name, ## arg); #define dbgarg2(fmt, arg...) \ if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) \ @@ -1288,7 +1287,6 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, ret=vfd->vidioc_g_parm(file, fh, p); } else { struct v4l2_standard s; - int i; if (!vfd->tvnormsize) { printk (KERN_WARNING "%s: no TV norms defined!\n", @@ -1299,14 +1297,8 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; - for (i = 0; i < vfd->tvnormsize; i++) - if (vfd->tvnorms[i].id == vfd->current_norm) - break; - if (i >= vfd->tvnormsize) - return -EINVAL; - - v4l2_video_std_construct(&s, vfd->current_norm, - vfd->tvnorms[i].name); + v4l2_video_std_construct(&s, vfd->tvnorms[vfd->current_norm].id, + vfd->tvnorms[vfd->current_norm].name); memset(p,0,sizeof(*p)); diff --git a/trunk/drivers/media/video/vino.c b/trunk/drivers/media/video/vino.c index 6b6dff4d236a..d1e04f7c530b 100644 --- a/trunk/drivers/media/video/vino.c +++ b/trunk/drivers/media/video/vino.c @@ -2325,7 +2325,7 @@ static void vino_capture_tasklet(unsigned long channel) { } } -static irqreturn_t vino_interrupt(int irq, void *dev_id) +static irqreturn_t vino_interrupt(int irq, void *dev_id, struct pt_regs *regs) { u32 ctrl, intr; unsigned int fc_a, fc_b; diff --git a/trunk/drivers/media/video/vivi.c b/trunk/drivers/media/video/vivi.c index 3c8dc72dc8e9..e7c01d560b64 100644 --- a/trunk/drivers/media/video/vivi.c +++ b/trunk/drivers/media/video/vivi.c @@ -272,7 +272,7 @@ static void gen_line(struct sg_to_addr to_addr[],int inipos,int pages,int wmax, /* Get first addr pointed to pixel position */ oldpg=get_addr_pos(pos,pages,to_addr); - pg=pfn_to_page(sg_dma_address(to_addr[oldpg].sg) >> PAGE_SHIFT); + pg=pfn_to_page(to_addr[oldpg].sg->dma_address >> PAGE_SHIFT); basep = kmap_atomic(pg, KM_BOUNCE_READ)+to_addr[oldpg].sg->offset; /* We will just duplicate the second pixel at the packet */ @@ -287,7 +287,7 @@ static void gen_line(struct sg_to_addr to_addr[],int inipos,int pages,int wmax, for (color=0;color<4;color++) { pgpos=get_addr_pos(pos,pages,to_addr); if (pgpos!=oldpg) { - pg=pfn_to_page(sg_dma_address(to_addr[pgpos].sg) >> PAGE_SHIFT); + pg=pfn_to_page(to_addr[pgpos].sg->dma_address >> PAGE_SHIFT); kunmap_atomic(basep, KM_BOUNCE_READ); basep= kmap_atomic(pg, KM_BOUNCE_READ)+to_addr[pgpos].sg->offset; oldpg=pgpos; @@ -339,8 +339,8 @@ static void gen_line(struct sg_to_addr to_addr[],int inipos,int pages,int wmax, for (color=0;color<4;color++) { pgpos=get_addr_pos(pos,pages,to_addr); if (pgpos!=oldpg) { - pg=pfn_to_page(sg_dma_address( - to_addr[pgpos].sg) + pg=pfn_to_page(to_addr[pgpos]. + sg->dma_address >> PAGE_SHIFT); kunmap_atomic(basep, KM_BOUNCE_READ); @@ -386,7 +386,7 @@ static void vivi_fillbuff(struct vivi_dev *dev,struct vivi_buffer *buf) struct timeval ts; /* Test if DMA mapping is ready */ - if (!sg_dma_address(&vb->dma.sglist[0])) + if (!vb->dma.sglist[0].dma_address) return; prep_to_addr(to_addr,vb); @@ -783,7 +783,7 @@ static int vivi_map_sg(void *dev, struct scatterlist *sg, int nents, for (i = 0; i < nents; i++ ) { BUG_ON(!sg[i].page); - sg_dma_address(&sg[i]) = page_to_phys(sg[i].page) + sg[i].offset; + sg[i].dma_address = page_to_phys(sg[i].page) + sg[i].offset; } return nents; diff --git a/trunk/drivers/media/video/w9968cf.c b/trunk/drivers/media/video/w9968cf.c index ddce2fb83424..2912326a5aef 100644 --- a/trunk/drivers/media/video/w9968cf.c +++ b/trunk/drivers/media/video/w9968cf.c @@ -417,7 +417,7 @@ static int w9968cf_write_fsb(struct w9968cf_device*, u16* data); static int w9968cf_write_sb(struct w9968cf_device*, u16 value); static int w9968cf_read_sb(struct w9968cf_device*); static int w9968cf_upload_quantizationtables(struct w9968cf_device*); -static void w9968cf_urb_complete(struct urb *urb); +static void w9968cf_urb_complete(struct urb *urb, struct pt_regs *regs); /* Low-level I2C (SMBus) I/O */ static int w9968cf_smbus_start(struct w9968cf_device*); @@ -781,7 +781,7 @@ static int w9968cf_allocate_memory(struct w9968cf_device* cam) If there are no requested frames in the FIFO list, packets are collected into a temporary buffer. --------------------------------------------------------------------------*/ -static void w9968cf_urb_complete(struct urb *urb) +static void w9968cf_urb_complete(struct urb *urb, struct pt_regs *regs) { struct w9968cf_device* cam = (struct w9968cf_device*)urb->context; struct w9968cf_frame_t** f; diff --git a/trunk/drivers/media/video/zc0301/zc0301_core.c b/trunk/drivers/media/video/zc0301/zc0301_core.c index 52d0f759ee00..1b2be2d2a3ec 100644 --- a/trunk/drivers/media/video/zc0301/zc0301_core.c +++ b/trunk/drivers/media/video/zc0301/zc0301_core.c @@ -303,7 +303,7 @@ int zc0301_i2c_write(struct zc0301_device* cam, u16 address, u16 value) /*****************************************************************************/ -static void zc0301_urb_complete(struct urb *urb) +static void zc0301_urb_complete(struct urb *urb, struct pt_regs* regs) { struct zc0301_device* cam = urb->context; struct zc0301_frame_t** f; @@ -489,7 +489,7 @@ static int zc0301_start_transfer(struct zc0301_device* cam) return 0; free_urbs: - for (i = 0; i < ZC0301_URBS; i++) + for (i = 0; (i < ZC0301_URBS) && cam->urb[i]; i++) usb_free_urb(cam->urb[i]); free_buffers: diff --git a/trunk/drivers/media/video/zoran_device.c b/trunk/drivers/media/video/zoran_device.c index 168e431d7c71..3cbac2e8aed3 100644 --- a/trunk/drivers/media/video/zoran_device.c +++ b/trunk/drivers/media/video/zoran_device.c @@ -1408,14 +1408,15 @@ error_handler (struct zoran *zr, irqreturn_t zoran_irq (int irq, - void *dev_id) + void *dev_id, + struct pt_regs *regs) { u32 stat, astat; int count; struct zoran *zr; unsigned long flags; - zr = dev_id; + zr = (struct zoran *) dev_id; count = 0; if (zr->testing) { diff --git a/trunk/drivers/media/video/zoran_device.h b/trunk/drivers/media/video/zoran_device.h index 37fa86a34083..f19705cbdb39 100644 --- a/trunk/drivers/media/video/zoran_device.h +++ b/trunk/drivers/media/video/zoran_device.h @@ -64,7 +64,9 @@ extern int wait_grab_pending(struct zoran *zr); /* interrupts */ extern void print_interrupts(struct zoran *zr); extern void clear_interrupt_counters(struct zoran *zr); -extern irqreturn_t zoran_irq(int irq, void *dev_id); +extern irqreturn_t zoran_irq(int irq, + void *dev_id, + struct pt_regs *regs); /* JPEG codec access */ extern void jpeg_start(struct zoran *zr); diff --git a/trunk/drivers/media/video/zr36120.c b/trunk/drivers/media/video/zr36120.c index 0cbf564388a6..b5ffe53c40d8 100644 --- a/trunk/drivers/media/video/zr36120.c +++ b/trunk/drivers/media/video/zr36120.c @@ -335,13 +335,13 @@ DEBUG(printk(CARD_DEBUG "turning off\n",CARD)); } static -void zoran_irq(int irq, void *dev_id) +void zoran_irq(int irq, void *dev_id, struct pt_regs * regs) { u32 stat,estat; int count = 0; struct zoran *ztv = dev_id; - UNUSED(irq); + UNUSED(irq); UNUSED(regs); for (;;) { /* get/clear interrupt status bits */ stat=zrread(ZORAN_ISR); diff --git a/trunk/drivers/message/fusion/linux_compat.h b/trunk/drivers/message/fusion/linux_compat.h index bb2bf5aa0b62..048b5b8610e3 100644 --- a/trunk/drivers/message/fusion/linux_compat.h +++ b/trunk/drivers/message/fusion/linux_compat.h @@ -6,4 +6,13 @@ #include #include +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,6)) +static int inline scsi_device_online(struct scsi_device *sdev) +{ + return sdev->online; +} +#endif + + +/*}-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ #endif /* _LINUX_COMPAT_H */ diff --git a/trunk/drivers/message/fusion/mptbase.c b/trunk/drivers/message/fusion/mptbase.c index 051b7c5b8f03..29d0635cce1d 100644 --- a/trunk/drivers/message/fusion/mptbase.c +++ b/trunk/drivers/message/fusion/mptbase.c @@ -122,7 +122,7 @@ static DECLARE_WAIT_QUEUE_HEAD(mpt_waitq); /* * Forward protos... */ -static irqreturn_t mpt_interrupt(int irq, void *bus_id); +static irqreturn_t mpt_interrupt(int irq, void *bus_id, struct pt_regs *r); static int mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply); static int mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req, int replyBytes, u16 *u16reply, int maxwait, @@ -351,6 +351,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 + * @r: pt_regs pointer (not used) * * This routine is registered via the request_irq() kernel API call, * and handles all interrupts generated from a specific MPT adapter @@ -364,7 +365,7 @@ mpt_reply(MPT_ADAPTER *ioc, u32 pa) * the protocol-specific details of the MPT request completion. */ static irqreturn_t -mpt_interrupt(int irq, void *bus_id) +mpt_interrupt(int irq, void *bus_id, struct pt_regs *r) { MPT_ADAPTER *ioc = bus_id; u32 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo); @@ -6185,7 +6186,7 @@ mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info) "Abort", /* 12h */ "IO Not Yet Executed", /* 13h */ "IO Executed", /* 14h */ - "Persistent Reservation Out Not Affiliation Owner", /* 15h */ + "Persistant Reservation Out Not Affiliation Owner", /* 15h */ "Open Transmit DMA Abort", /* 16h */ "IO Device Missing Delay Retry", /* 17h */ NULL, /* 18h */ diff --git a/trunk/drivers/message/fusion/mptbase.h b/trunk/drivers/message/fusion/mptbase.h index a4afad4ecab2..c537d71c18e4 100644 --- a/trunk/drivers/message/fusion/mptbase.h +++ b/trunk/drivers/message/fusion/mptbase.h @@ -75,8 +75,8 @@ #define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR #endif -#define MPT_LINUX_VERSION_COMMON "3.04.02" -#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.02" +#define MPT_LINUX_VERSION_COMMON "3.04.01" +#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.01" #define WHAT_MAGIC_STRING "@" "(" "#" ")" #define show_mptmod_ver(s,ver) \ diff --git a/trunk/drivers/message/fusion/mptfc.c b/trunk/drivers/message/fusion/mptfc.c index 1dd491773150..e57bb035a021 100644 --- a/trunk/drivers/message/fusion/mptfc.c +++ b/trunk/drivers/message/fusion/mptfc.c @@ -96,10 +96,6 @@ static int mptfc_qcmd(struct scsi_cmnd *SCpnt, static void mptfc_target_destroy(struct scsi_target *starget); static void mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout); static void __devexit mptfc_remove(struct pci_dev *pdev); -static int mptfc_abort(struct scsi_cmnd *SCpnt); -static int mptfc_dev_reset(struct scsi_cmnd *SCpnt); -static int mptfc_bus_reset(struct scsi_cmnd *SCpnt); -static int mptfc_host_reset(struct scsi_cmnd *SCpnt); static struct scsi_host_template mptfc_driver_template = { .module = THIS_MODULE, @@ -114,10 +110,10 @@ static struct scsi_host_template mptfc_driver_template = { .target_destroy = mptfc_target_destroy, .slave_destroy = mptscsih_slave_destroy, .change_queue_depth = mptscsih_change_queue_depth, - .eh_abort_handler = mptfc_abort, - .eh_device_reset_handler = mptfc_dev_reset, - .eh_bus_reset_handler = mptfc_bus_reset, - .eh_host_reset_handler = mptfc_host_reset, + .eh_abort_handler = mptscsih_abort, + .eh_device_reset_handler = mptscsih_dev_reset, + .eh_bus_reset_handler = mptscsih_bus_reset, + .eh_host_reset_handler = mptscsih_host_reset, .bios_param = mptscsih_bios_param, .can_queue = MPT_FC_CAN_QUEUE, .this_id = -1, @@ -175,77 +171,6 @@ static struct fc_function_template mptfc_transport_functions = { .show_host_symbolic_name = 1, }; -static int -mptfc_block_error_handler(struct scsi_cmnd *SCpnt, - int (*func)(struct scsi_cmnd *SCpnt), - const char *caller) -{ - struct scsi_device *sdev = SCpnt->device; - struct Scsi_Host *shost = sdev->host; - struct fc_rport *rport = starget_to_rport(scsi_target(sdev)); - unsigned long flags; - int ready; - - spin_lock_irqsave(shost->host_lock, flags); - while ((ready = fc_remote_port_chkready(rport) >> 16) == DID_IMM_RETRY) { - spin_unlock_irqrestore(shost->host_lock, flags); - dfcprintk ((MYIOC_s_INFO_FMT - "mptfc_block_error_handler.%d: %d:%d, port status is " - "DID_IMM_RETRY, deferring %s recovery.\n", - ((MPT_SCSI_HOST *) shost->hostdata)->ioc->name, - ((MPT_SCSI_HOST *) shost->hostdata)->ioc->sh->host_no, - SCpnt->device->id,SCpnt->device->lun,caller)); - msleep(1000); - spin_lock_irqsave(shost->host_lock, flags); - } - spin_unlock_irqrestore(shost->host_lock, flags); - - if (ready == DID_NO_CONNECT || !SCpnt->device->hostdata) { - dfcprintk ((MYIOC_s_INFO_FMT - "%s.%d: %d:%d, failing recovery, " - "port state %d, vdev %p.\n", caller, - ((MPT_SCSI_HOST *) shost->hostdata)->ioc->name, - ((MPT_SCSI_HOST *) shost->hostdata)->ioc->sh->host_no, - SCpnt->device->id,SCpnt->device->lun,ready, - SCpnt->device->hostdata)); - return FAILED; - } - dfcprintk ((MYIOC_s_INFO_FMT - "%s.%d: %d:%d, executing recovery.\n", caller, - ((MPT_SCSI_HOST *) shost->hostdata)->ioc->name, - ((MPT_SCSI_HOST *) shost->hostdata)->ioc->sh->host_no, - SCpnt->device->id,SCpnt->device->lun)); - return (*func)(SCpnt); -} - -static int -mptfc_abort(struct scsi_cmnd *SCpnt) -{ - return - mptfc_block_error_handler(SCpnt, mptscsih_abort, __FUNCTION__); -} - -static int -mptfc_dev_reset(struct scsi_cmnd *SCpnt) -{ - return - mptfc_block_error_handler(SCpnt, mptscsih_dev_reset, __FUNCTION__); -} - -static int -mptfc_bus_reset(struct scsi_cmnd *SCpnt) -{ - return - mptfc_block_error_handler(SCpnt, mptscsih_bus_reset, __FUNCTION__); -} - -static int -mptfc_host_reset(struct scsi_cmnd *SCpnt) -{ - return - mptfc_block_error_handler(SCpnt, mptscsih_host_reset, __FUNCTION__); -} - static void mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout) { @@ -637,12 +562,6 @@ mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) return 0; } - if (!SCpnt->device->hostdata) { /* vdev */ - SCpnt->result = DID_NO_CONNECT << 16; - done(SCpnt); - return 0; - } - /* dd_data is null until finished adding target */ ri = *((struct mptfc_rport_info **)rport->dd_data); if (unlikely(!ri)) { diff --git a/trunk/drivers/message/i2o/bus-osm.c b/trunk/drivers/message/i2o/bus-osm.c index d96c687aee93..ac06f10c54ec 100644 --- a/trunk/drivers/message/i2o/bus-osm.c +++ b/trunk/drivers/message/i2o/bus-osm.c @@ -80,26 +80,18 @@ static DEVICE_ATTR(scan, S_IWUSR, NULL, i2o_bus_store_scan); * @dev: device to verify if it is a I2O Bus Adapter device * * Because we want all Bus Adapters always return 0. - * Except when we fail. Then we are sad. * - * Returns 0, except when we fail to excel. + * Returns 0. */ static int i2o_bus_probe(struct device *dev) { struct i2o_device *i2o_dev = to_i2o_device(get_device(dev)); - int rc; - rc = device_create_file(dev, &dev_attr_scan); - if (rc) - goto err_out; + device_create_file(dev, &dev_attr_scan); osm_info("device added (TID: %03x)\n", i2o_dev->lct_data.tid); return 0; - -err_out: - put_device(dev); - return rc; }; /** diff --git a/trunk/drivers/message/i2o/exec-osm.c b/trunk/drivers/message/i2o/exec-osm.c index a2350640384b..7bd4d85d0b42 100644 --- a/trunk/drivers/message/i2o/exec-osm.c +++ b/trunk/drivers/message/i2o/exec-osm.c @@ -124,10 +124,10 @@ static void i2o_exec_wait_free(struct i2o_exec_wait *wait) int i2o_msg_post_wait_mem(struct i2o_controller *c, struct i2o_message *msg, unsigned long timeout, struct i2o_dma *dma) { - DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq); + DECLARE_WAIT_QUEUE_HEAD(wq); struct i2o_exec_wait *wait; static u32 tcntxt = 0x80000000; - unsigned long flags; + long flags; int rc = 0; wait = i2o_exec_wait_alloc(); @@ -325,24 +325,13 @@ static DEVICE_ATTR(product_id, S_IRUGO, i2o_exec_show_product_id, NULL); static int i2o_exec_probe(struct device *dev) { struct i2o_device *i2o_dev = to_i2o_device(dev); - int rc; - rc = i2o_event_register(i2o_dev, &i2o_exec_driver, 0, 0xffffffff); - if (rc) goto err_out; + i2o_event_register(i2o_dev, &i2o_exec_driver, 0, 0xffffffff); - rc = device_create_file(dev, &dev_attr_vendor_id); - if (rc) goto err_evtreg; - rc = device_create_file(dev, &dev_attr_product_id); - if (rc) goto err_vid; + device_create_file(dev, &dev_attr_vendor_id); + device_create_file(dev, &dev_attr_product_id); return 0; - -err_vid: - device_remove_file(dev, &dev_attr_vendor_id); -err_evtreg: - i2o_event_register(to_i2o_device(dev), &i2o_exec_driver, 0, 0); -err_out: - return rc; }; /** diff --git a/trunk/drivers/message/i2o/pci.c b/trunk/drivers/message/i2o/pci.c index 8287f95c8c42..dec41cc89937 100644 --- a/trunk/drivers/message/i2o/pci.c +++ b/trunk/drivers/message/i2o/pci.c @@ -224,11 +224,12 @@ static int __devinit i2o_pci_alloc(struct i2o_controller *c) * i2o_pci_interrupt - Interrupt handler for I2O controller * @irq: interrupt line * @dev_id: pointer to the I2O controller + * @r: pointer to registers * * Handle an interrupt from a PCI based I2O controller. This turns out * to be rather simple. We keep the controller pointer in the cookie. */ -static irqreturn_t i2o_pci_interrupt(int irq, void *dev_id) +static irqreturn_t i2o_pci_interrupt(int irq, void *dev_id, struct pt_regs *r) { struct i2o_controller *c = dev_id; u32 m; @@ -320,6 +321,7 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev, struct i2o_controller *c; int rc; struct pci_dev *i960 = NULL; + int enabled = pdev->is_enabled; printk(KERN_INFO "i2o: Checking for PCI I2O controllers...\n"); @@ -329,11 +331,12 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev, return -ENODEV; } - if ((rc = pci_enable_device(pdev))) { - printk(KERN_WARNING "i2o: couldn't enable device %s\n", - pci_name(pdev)); - return rc; - } + if (!enabled) + if ((rc = pci_enable_device(pdev))) { + printk(KERN_WARNING "i2o: couldn't enable device %s\n", + pci_name(pdev)); + return rc; + } if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { printk(KERN_WARNING "i2o: no suitable DMA found for %s\n", @@ -440,7 +443,8 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev, i2o_iop_free(c); disable: - pci_disable_device(pdev); + if (!enabled) + pci_disable_device(pdev); return rc; } diff --git a/trunk/drivers/mfd/ucb1x00-core.c b/trunk/drivers/mfd/ucb1x00-core.c index 149810a084f5..2bf32721eb53 100644 --- a/trunk/drivers/mfd/ucb1x00-core.c +++ b/trunk/drivers/mfd/ucb1x00-core.c @@ -203,7 +203,7 @@ void ucb1x00_adc_disable(struct ucb1x00 *ucb) * SIBCLK to talk to the chip. We leave the clock running until * we have finished processing all interrupts from the chip. */ -static irqreturn_t ucb1x00_irq(int irqnr, void *devid) +static irqreturn_t ucb1x00_irq(int irqnr, void *devid, struct pt_regs *regs) { struct ucb1x00 *ucb = devid; struct ucb1x00_irq *irq; diff --git a/trunk/drivers/misc/Kconfig b/trunk/drivers/misc/Kconfig index 00db31c314e0..3df0e7a07c46 100644 --- a/trunk/drivers/misc/Kconfig +++ b/trunk/drivers/misc/Kconfig @@ -28,18 +28,6 @@ config IBM_ASM If unsure, say N. -config SGI_IOC4 - tristate "SGI IOC4 Base IO support" - depends on PCI - ---help--- - This option enables basic support for the IOC4 chip on certain - SGI IO controller cards (IO9, IO10, and PCI-RT). This option - does not enable any specific functions on such a card, but provides - necessary infrastructure for other drivers to utilize. - - If you have an SGI Altix with an IOC4-based card say Y. - Otherwise say N. - config TIFM_CORE tristate "TI Flash Media interface support (EXPERIMENTAL)" depends on EXPERIMENTAL @@ -69,23 +57,4 @@ config TIFM_7XX1 To compile this driver as a module, choose M here: the module will be called tifm_7xx1. -config MSI_LAPTOP - tristate "MSI Laptop Extras" - depends on X86 - depends on ACPI_EC - depends on BACKLIGHT_CLASS_DEVICE - ---help--- - This is a driver for laptops built by MSI (MICRO-STAR - INTERNATIONAL): - - MSI MegaBook S270 (MS-1013) - Cytron/TCM/Medion/Tchibo MD96100/SAM2000 - - It adds support for Bluetooth, WLAN and LCD brightness control. - - More information about this driver is available at - . - - If you have an MSI S270 laptop, say Y or M here. - endmenu diff --git a/trunk/drivers/misc/Makefile b/trunk/drivers/misc/Makefile index c9e98ab021c5..d65ece76095a 100644 --- a/trunk/drivers/misc/Makefile +++ b/trunk/drivers/misc/Makefile @@ -5,8 +5,6 @@ obj- := misc.o # Dummy rule to force built-in.o to be made obj-$(CONFIG_IBM_ASM) += ibmasm/ obj-$(CONFIG_HDPU_FEATURES) += hdpuftrs/ -obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o obj-$(CONFIG_LKDTM) += lkdtm.o obj-$(CONFIG_TIFM_CORE) += tifm_core.o obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o -obj-$(CONFIG_SGI_IOC4) += ioc4.o diff --git a/trunk/drivers/misc/ibmasm/ibmasm.h b/trunk/drivers/misc/ibmasm/ibmasm.h index 48d5abebfc30..634d538ccd14 100644 --- a/trunk/drivers/misc/ibmasm/ibmasm.h +++ b/trunk/drivers/misc/ibmasm/ibmasm.h @@ -196,10 +196,10 @@ extern int ibmasm_send_os_state(struct service_processor *sp, int os_state); /* low level message processing */ extern int ibmasm_send_i2o_message(struct service_processor *sp); -extern irqreturn_t ibmasm_interrupt_handler(int irq, void * dev_id); +extern irqreturn_t ibmasm_interrupt_handler(int irq, void * dev_id, struct pt_regs *regs); /* remote console */ -extern void ibmasm_handle_mouse_interrupt(struct service_processor *sp); +extern void ibmasm_handle_mouse_interrupt(struct service_processor *sp, struct pt_regs *regs); extern int ibmasm_init_remote_input_dev(struct service_processor *sp); extern void ibmasm_free_remote_input_dev(struct service_processor *sp); diff --git a/trunk/drivers/misc/ibmasm/lowlevel.c b/trunk/drivers/misc/ibmasm/lowlevel.c index a3c589b7cbfa..47949a2c7e94 100644 --- a/trunk/drivers/misc/ibmasm/lowlevel.c +++ b/trunk/drivers/misc/ibmasm/lowlevel.c @@ -54,7 +54,7 @@ int ibmasm_send_i2o_message(struct service_processor *sp) return 0; } -irqreturn_t ibmasm_interrupt_handler(int irq, void * dev_id) +irqreturn_t ibmasm_interrupt_handler(int irq, void * dev_id, struct pt_regs *regs) { u32 mfa; struct service_processor *sp = (struct service_processor *)dev_id; @@ -67,7 +67,7 @@ irqreturn_t ibmasm_interrupt_handler(int irq, void * dev_id) dbg("respond to interrupt at %s\n", get_timestamp(tsbuf)); if (mouse_interrupt_pending(sp)) { - ibmasm_handle_mouse_interrupt(sp); + ibmasm_handle_mouse_interrupt(sp, regs); clear_mouse_interrupt(sp); } diff --git a/trunk/drivers/misc/ibmasm/remote.c b/trunk/drivers/misc/ibmasm/remote.c index a40fda6c402c..0f9e3aa34d07 100644 --- a/trunk/drivers/misc/ibmasm/remote.c +++ b/trunk/drivers/misc/ibmasm/remote.c @@ -158,10 +158,12 @@ static void print_input(struct remote_input *input) } } -static void send_mouse_event(struct input_dev *dev, struct remote_input *input) +static void send_mouse_event(struct input_dev *dev, struct pt_regs *regs, + struct remote_input *input) { unsigned char buttons = input->mouse_buttons; + input_regs(dev, regs); input_report_abs(dev, ABS_X, input->data.mouse.x); input_report_abs(dev, ABS_Y, input->data.mouse.y); input_report_key(dev, BTN_LEFT, buttons & REMOTE_BUTTON_LEFT); @@ -170,7 +172,7 @@ static void send_mouse_event(struct input_dev *dev, struct remote_input *input) input_sync(dev); } -static void send_keyboard_event(struct input_dev *dev, +static void send_keyboard_event(struct input_dev *dev, struct pt_regs *regs, struct remote_input *input) { unsigned int key; @@ -180,11 +182,13 @@ static void send_keyboard_event(struct input_dev *dev, key = xlate_high[code & 0xff]; else key = xlate[code]; + input_regs(dev, regs); input_report_key(dev, key, (input->data.keyboard.key_down) ? 1 : 0); input_sync(dev); } -void ibmasm_handle_mouse_interrupt(struct service_processor *sp) +void ibmasm_handle_mouse_interrupt(struct service_processor *sp, + struct pt_regs *regs) { unsigned long reader; unsigned long writer; @@ -199,9 +203,9 @@ void ibmasm_handle_mouse_interrupt(struct service_processor *sp) print_input(&input); if (input.type == INPUT_TYPE_MOUSE) { - send_mouse_event(sp->remote.mouse_dev, &input); + send_mouse_event(sp->remote.mouse_dev, regs, &input); } else if (input.type == INPUT_TYPE_KEYBOARD) { - send_keyboard_event(sp->remote.keybd_dev, &input); + send_keyboard_event(sp->remote.keybd_dev, regs, &input); } else break; diff --git a/trunk/drivers/misc/lkdtm.c b/trunk/drivers/misc/lkdtm.c index db9d7df75ae0..e689ee94ac3d 100644 --- a/trunk/drivers/misc/lkdtm.c +++ b/trunk/drivers/misc/lkdtm.c @@ -44,14 +44,12 @@ */ #include -#include #include -#include #include -#include +#include #include +#include #include -#include #include #ifdef CONFIG_IDE @@ -118,25 +116,26 @@ static enum ctype cptype = NONE; static int count = DEFAULT_COUNT; module_param(recur_count, int, 0644); -MODULE_PARM_DESC(recur_count, " Recursion level for the stack overflow test, "\ - "default is 10"); +MODULE_PARM_DESC(recur_count, "Recurcion level for the stack overflow test,\ + default is 10"); module_param(cpoint_name, charp, 0644); -MODULE_PARM_DESC(cpoint_name, " Crash Point, where kernel is to be crashed"); -module_param(cpoint_type, charp, 0644); -MODULE_PARM_DESC(cpoint_type, " Crash Point Type, action to be taken on "\ - "hitting the crash point"); -module_param(cpoint_count, int, 0644); -MODULE_PARM_DESC(cpoint_count, " Crash Point Count, number of times the "\ - "crash point is to be hit to trigger action"); - -unsigned int jp_do_irq(unsigned int irq) +MODULE_PARM_DESC(cpoint_name, "Crash Point, where kernel is to be crashed"); +module_param(cpoint_type, charp, 06444); +MODULE_PARM_DESC(cpoint_type, "Crash Point Type, action to be taken on\ + hitting the crash point"); +module_param(cpoint_count, int, 06444); +MODULE_PARM_DESC(cpoint_count, "Crash Point Count, number of times the \ + crash point is to be hit to trigger action"); + +unsigned int jp_do_irq(unsigned int irq, struct pt_regs *regs) { lkdtm_handler(); jprobe_return(); return 0; } -irqreturn_t jp_handle_irq_event(unsigned int irq, struct irqaction *action) +irqreturn_t jp_handle_irq_event(unsigned int irq, struct pt_regs *regs, + struct irqaction *action) { lkdtm_handler(); jprobe_return(); @@ -157,8 +156,8 @@ void jp_ll_rw_block(int rw, int nr, struct buffer_head *bhs[]) struct scan_control; -unsigned long jp_shrink_inactive_list(unsigned long max_scan, - struct zone *zone, struct scan_control *sc) +unsigned long jp_shrink_page_list(struct list_head *page_list, + struct scan_control *sc) { lkdtm_handler(); jprobe_return(); @@ -297,8 +296,8 @@ int lkdtm_module_init(void) lkdtm.entry = (kprobe_opcode_t*) jp_ll_rw_block; break; case MEM_SWAPOUT: - lkdtm.kp.symbol_name = "shrink_inactive_list"; - lkdtm.entry = (kprobe_opcode_t*) jp_shrink_inactive_list; + lkdtm.kp.symbol_name = "shrink_page_list"; + lkdtm.entry = (kprobe_opcode_t*) jp_shrink_page_list; break; case TIMERADD: lkdtm.kp.symbol_name = "hrtimer_start"; diff --git a/trunk/drivers/misc/msi-laptop.c b/trunk/drivers/misc/msi-laptop.c deleted file mode 100644 index fdb7153f4426..000000000000 --- a/trunk/drivers/misc/msi-laptop.c +++ /dev/null @@ -1,395 +0,0 @@ -/*-*-linux-c-*-*/ - -/* - Copyright (C) 2006 Lennart Poettering - - 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 Street, Fifth Floor, Boston, MA - 02110-1301, USA. - */ - -/* - * msi-laptop.c - MSI S270 laptop support. This laptop is sold under - * various brands, including "Cytron/TCM/Medion/Tchibo MD96100". - * - * This driver exports a few files in /sys/devices/platform/msi-laptop-pf/: - * - * lcd_level - Screen brightness: contains a single integer in the - * range 0..8. (rw) - * - * auto_brightness - Enable automatic brightness control: contains - * either 0 or 1. If set to 1 the hardware adjusts the screen - * brightness automatically when the power cord is - * plugged/unplugged. (rw) - * - * wlan - WLAN subsystem enabled: contains either 0 or 1. (ro) - * - * bluetooth - Bluetooth subsystem enabled: contains either 0 or 1 - * Please note that this file is constantly 0 if no Bluetooth - * hardware is available. (ro) - * - * In addition to these platform device attributes the driver - * registers itself in the Linux backlight control subsystem and is - * available to userspace under /sys/class/backlight/msi-laptop-bl/. - * - * This driver might work on other laptops produced by MSI. If you - * want to try it you can pass force=1 as argument to the module which - * will force it to load even when the DMI data doesn't identify the - * laptop as MSI S270. YMMV. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#define MSI_DRIVER_VERSION "0.5" - -#define MSI_LCD_LEVEL_MAX 9 - -#define MSI_EC_COMMAND_WIRELESS 0x10 -#define MSI_EC_COMMAND_LCD_LEVEL 0x11 - -static int force; -module_param(force, bool, 0); -MODULE_PARM_DESC(force, "Force driver load, ignore DMI data"); - -static int auto_brightness; -module_param(auto_brightness, int, 0); -MODULE_PARM_DESC(auto_brightness, "Enable automatic brightness control (0: disabled; 1: enabled; 2: don't touch)"); - -/* Hardware access */ - -static int set_lcd_level(int level) -{ - u8 buf[2]; - - if (level < 0 || level >= MSI_LCD_LEVEL_MAX) - return -EINVAL; - - buf[0] = 0x80; - buf[1] = (u8) (level*31); - - return ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, buf, sizeof(buf), NULL, 0); -} - -static int get_lcd_level(void) -{ - u8 wdata = 0, rdata; - int result; - - result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, &wdata, 1, &rdata, 1); - if (result < 0) - return result; - - return (int) rdata / 31; -} - -static int get_auto_brightness(void) -{ - u8 wdata = 4, rdata; - int result; - - result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, &wdata, 1, &rdata, 1); - if (result < 0) - return result; - - return !!(rdata & 8); -} - -static int set_auto_brightness(int enable) -{ - u8 wdata[2], rdata; - int result; - - wdata[0] = 4; - - result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, wdata, 1, &rdata, 1); - if (result < 0) - return result; - - wdata[0] = 0x84; - wdata[1] = (rdata & 0xF7) | (enable ? 8 : 0); - - return ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, wdata, 2, NULL, 0); -} - -static int get_wireless_state(int *wlan, int *bluetooth) -{ - u8 wdata = 0, rdata; - int result; - - result = ec_transaction(MSI_EC_COMMAND_WIRELESS, &wdata, 1, &rdata, 1); - if (result < 0) - return -1; - - if (wlan) - *wlan = !!(rdata & 8); - - if (bluetooth) - *bluetooth = !!(rdata & 128); - - return 0; -} - -/* Backlight device stuff */ - -static int bl_get_brightness(struct backlight_device *b) -{ - return get_lcd_level(); -} - - -static int bl_update_status(struct backlight_device *b) -{ - return set_lcd_level(b->props->brightness); -} - -static struct backlight_properties msibl_props = { - .owner = THIS_MODULE, - .get_brightness = bl_get_brightness, - .update_status = bl_update_status, - .max_brightness = MSI_LCD_LEVEL_MAX-1, -}; - -static struct backlight_device *msibl_device; - -/* Platform device */ - -static ssize_t show_wlan(struct device *dev, - struct device_attribute *attr, char *buf) -{ - - int ret, enabled; - - ret = get_wireless_state(&enabled, NULL); - if (ret < 0) - return ret; - - return sprintf(buf, "%i\n", enabled); -} - -static ssize_t show_bluetooth(struct device *dev, - struct device_attribute *attr, char *buf) -{ - - int ret, enabled; - - ret = get_wireless_state(NULL, &enabled); - if (ret < 0) - return ret; - - return sprintf(buf, "%i\n", enabled); -} - -static ssize_t show_lcd_level(struct device *dev, - struct device_attribute *attr, char *buf) -{ - - int ret; - - ret = get_lcd_level(); - if (ret < 0) - return ret; - - return sprintf(buf, "%i\n", ret); -} - -static ssize_t store_lcd_level(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - - int level, ret; - - if (sscanf(buf, "%i", &level) != 1 || (level < 0 || level >= MSI_LCD_LEVEL_MAX)) - return -EINVAL; - - ret = set_lcd_level(level); - if (ret < 0) - return ret; - - return count; -} - -static ssize_t show_auto_brightness(struct device *dev, - struct device_attribute *attr, char *buf) -{ - - int ret; - - ret = get_auto_brightness(); - if (ret < 0) - return ret; - - return sprintf(buf, "%i\n", ret); -} - -static ssize_t store_auto_brightness(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - - int enable, ret; - - if (sscanf(buf, "%i", &enable) != 1 || (enable != (enable & 1))) - return -EINVAL; - - ret = set_auto_brightness(enable); - if (ret < 0) - return ret; - - return count; -} - -static DEVICE_ATTR(lcd_level, 0644, show_lcd_level, store_lcd_level); -static DEVICE_ATTR(auto_brightness, 0644, show_auto_brightness, store_auto_brightness); -static DEVICE_ATTR(bluetooth, 0444, show_bluetooth, NULL); -static DEVICE_ATTR(wlan, 0444, show_wlan, NULL); - -static struct attribute *msipf_attributes[] = { - &dev_attr_lcd_level.attr, - &dev_attr_auto_brightness.attr, - &dev_attr_bluetooth.attr, - &dev_attr_wlan.attr, - NULL -}; - -static struct attribute_group msipf_attribute_group = { - .attrs = msipf_attributes -}; - -static struct platform_driver msipf_driver = { - .driver = { - .name = "msi-laptop-pf", - .owner = THIS_MODULE, - } -}; - -static struct platform_device *msipf_device; - -/* Initialization */ - -static struct dmi_system_id __initdata msi_dmi_table[] = { - { - .ident = "MSI S270", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD"), - DMI_MATCH(DMI_PRODUCT_NAME, "MS-1013"), - } - }, - { - .ident = "Medion MD96100", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "NOTEBOOK"), - DMI_MATCH(DMI_PRODUCT_NAME, "SAM2000"), - } - }, - { } -}; - - -static int __init msi_init(void) -{ - int ret; - - if (acpi_disabled) - return -ENODEV; - - if (!force && !dmi_check_system(msi_dmi_table)) - return -ENODEV; - - if (auto_brightness < 0 || auto_brightness > 2) - return -EINVAL; - - /* Register backlight stuff */ - - msibl_device = backlight_device_register("msi-laptop-bl", NULL, &msibl_props); - if (IS_ERR(msibl_device)) - return PTR_ERR(msibl_device); - - ret = platform_driver_register(&msipf_driver); - if (ret) - goto fail_backlight; - - /* Register platform stuff */ - - msipf_device = platform_device_alloc("msi-laptop-pf", -1); - if (!msipf_device) { - ret = -ENOMEM; - goto fail_platform_driver; - } - - ret = platform_device_add(msipf_device); - if (ret) - goto fail_platform_device1; - - ret = sysfs_create_group(&msipf_device->dev.kobj, &msipf_attribute_group); - if (ret) - goto fail_platform_device2; - - /* Disable automatic brightness control by default because - * this module was probably loaded to do brightness control in - * software. */ - - if (auto_brightness != 2) - set_auto_brightness(auto_brightness); - - printk(KERN_INFO "msi-laptop: driver "MSI_DRIVER_VERSION" successfully loaded.\n"); - - return 0; - -fail_platform_device2: - - platform_device_del(msipf_device); - -fail_platform_device1: - - platform_device_put(msipf_device); - -fail_platform_driver: - - platform_driver_unregister(&msipf_driver); - -fail_backlight: - - backlight_device_unregister(msibl_device); - - return ret; -} - -static void __exit msi_cleanup(void) -{ - - sysfs_remove_group(&msipf_device->dev.kobj, &msipf_attribute_group); - platform_device_unregister(msipf_device); - platform_driver_unregister(&msipf_driver); - backlight_device_unregister(msibl_device); - - /* Enable automatic brightness control again */ - if (auto_brightness != 2) - set_auto_brightness(1); - - printk(KERN_INFO "msi-laptop: driver unloaded.\n"); -} - -module_init(msi_init); -module_exit(msi_cleanup); - -MODULE_AUTHOR("Lennart Poettering"); -MODULE_DESCRIPTION("MSI Laptop Support"); -MODULE_VERSION(MSI_DRIVER_VERSION); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/misc/tifm_7xx1.c b/trunk/drivers/misc/tifm_7xx1.c index 1ba8754e9383..a7ed30446185 100644 --- a/trunk/drivers/misc/tifm_7xx1.c +++ b/trunk/drivers/misc/tifm_7xx1.c @@ -48,7 +48,7 @@ static void tifm_7xx1_remove_media(void *adapter) printk(KERN_INFO DRIVER_NAME ": demand removing card from socket %d\n", cnt); sock = fm->sockets[cnt]; - fm->sockets[cnt] = NULL; + fm->sockets[cnt] = 0; fm->remove_mask &= ~(1 << cnt); writel(0x0e00, sock->addr + SOCK_CONTROL); @@ -67,7 +67,7 @@ static void tifm_7xx1_remove_media(void *adapter) class_device_put(&fm->cdev); } -static irqreturn_t tifm_7xx1_isr(int irq, void *dev_id) +static irqreturn_t tifm_7xx1_isr(int irq, void *dev_id, struct pt_regs *regs) { struct tifm_adapter *fm = dev_id; unsigned int irq_status; @@ -118,7 +118,7 @@ static irqreturn_t tifm_7xx1_isr(int irq, void *dev_id) return IRQ_HANDLED; } -static tifm_media_id tifm_7xx1_toggle_sock_power(char __iomem *sock_addr, int is_x2) +static tifm_media_id tifm_7xx1_toggle_sock_power(char *sock_addr, int is_x2) { unsigned int s_state; int cnt; @@ -163,8 +163,7 @@ static tifm_media_id tifm_7xx1_toggle_sock_power(char __iomem *sock_addr, int is return (readl(sock_addr + SOCK_PRESENT_STATE) >> 4) & 7; } -inline static char __iomem * -tifm_7xx1_sock_addr(char __iomem *base_addr, unsigned int sock_num) +inline static char *tifm_7xx1_sock_addr(char *base_addr, unsigned int sock_num) { return base_addr + ((sock_num + 1) << 10); } @@ -177,7 +176,7 @@ static void tifm_7xx1_insert_media(void *adapter) char *card_name = "xx"; int cnt, ok_to_register; unsigned int insert_mask; - struct tifm_dev *new_sock = NULL; + struct tifm_dev *new_sock = 0; if (!class_device_get(&fm->cdev)) return; @@ -231,7 +230,7 @@ static void tifm_7xx1_insert_media(void *adapter) if (!ok_to_register || device_register(&new_sock->dev)) { spin_lock_irqsave(&fm->lock, flags); - fm->sockets[cnt] = NULL; + fm->sockets[cnt] = 0; spin_unlock_irqrestore(&fm->lock, flags); tifm_free_device(&new_sock->dev); @@ -391,7 +390,7 @@ static void tifm_7xx1_remove(struct pci_dev *dev) tifm_remove_adapter(fm); - pci_set_drvdata(dev, NULL); + pci_set_drvdata(dev, 0); iounmap(fm->addr); pci_intx(dev, 0); diff --git a/trunk/drivers/misc/tifm_core.c b/trunk/drivers/misc/tifm_core.c index ee326136d03b..cca5f8522469 100644 --- a/trunk/drivers/misc/tifm_core.c +++ b/trunk/drivers/misc/tifm_core.c @@ -157,7 +157,7 @@ struct tifm_dev *tifm_alloc_device(struct tifm_adapter *fm, unsigned int id) dev->wq = create_singlethread_workqueue(dev->wq_name); if (!dev->wq) { kfree(dev); - return NULL; + return 0; } dev->dev.parent = fm->dev; dev->dev.bus = &tifm_bus_type; diff --git a/trunk/drivers/mmc/at91_mci.c b/trunk/drivers/mmc/at91_mci.c index 494b23fb0a01..cb142a66098c 100644 --- a/trunk/drivers/mmc/at91_mci.c +++ b/trunk/drivers/mmc/at91_mci.c @@ -661,7 +661,7 @@ static void at91_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) /* * Handle an interrupt */ -static irqreturn_t at91_mci_irq(int irq, void *devid) +static irqreturn_t at91_mci_irq(int irq, void *devid, struct pt_regs *regs) { struct at91mci_host *host = devid; int completed = 0; @@ -754,7 +754,7 @@ static irqreturn_t at91_mci_irq(int irq, void *devid) return IRQ_HANDLED; } -static irqreturn_t at91_mmc_det_irq(int irq, void *_host) +static irqreturn_t at91_mmc_det_irq(int irq, void *_host, struct pt_regs *regs) { struct at91mci_host *host = _host; int present = !at91_get_gpio_value(irq); diff --git a/trunk/drivers/mmc/au1xmmc.c b/trunk/drivers/mmc/au1xmmc.c index 53ffcbb14a97..61268da13957 100644 --- a/trunk/drivers/mmc/au1xmmc.c +++ b/trunk/drivers/mmc/au1xmmc.c @@ -750,7 +750,7 @@ static void au1xmmc_dma_callback(int irq, void *dev_id) #define STATUS_DATA_IN (SD_STATUS_NE) #define STATUS_DATA_OUT (SD_STATUS_TH) -static irqreturn_t au1xmmc_irq(int irq, void *dev_id) +static irqreturn_t au1xmmc_irq(int irq, void *dev_id, struct pt_regs *regs) { u32 status; diff --git a/trunk/drivers/mmc/imxmmc.c b/trunk/drivers/mmc/imxmmc.c index 659d4a822cc5..1b79dd271aae 100644 --- a/trunk/drivers/mmc/imxmmc.c +++ b/trunk/drivers/mmc/imxmmc.c @@ -635,7 +635,7 @@ static int imxmci_cpu_driven_data(struct imxmci_host *host, unsigned int *pstat) return trans_done; } -static void imxmci_dma_irq(int dma, void *devid) +static void imxmci_dma_irq(int dma, void *devid, struct pt_regs *regs) { struct imxmci_host *host = devid; uint32_t stat = MMC_STATUS; @@ -646,7 +646,7 @@ static void imxmci_dma_irq(int dma, void *devid) tasklet_schedule(&host->tasklet); } -static irqreturn_t imxmci_irq(int irq, void *devid) +static irqreturn_t imxmci_irq(int irq, void *devid, struct pt_regs *regs) { struct imxmci_host *host = devid; uint32_t stat = MMC_STATUS; diff --git a/trunk/drivers/mmc/mmc.c b/trunk/drivers/mmc/mmc.c index 766bc54406e5..ee8863c123e3 100644 --- a/trunk/drivers/mmc/mmc.c +++ b/trunk/drivers/mmc/mmc.c @@ -475,7 +475,7 @@ static u32 mmc_select_voltage(struct mmc_host *host, u32 ocr) if (bit) { bit -= 1; - ocr &= 3 << bit; + ocr = 3 << bit; host->ios.vdd = bit; mmc_set_ios(host); @@ -1178,29 +1178,14 @@ static void mmc_rescan(void *data) { struct mmc_host *host = data; struct list_head *l, *n; - unsigned char power_mode; mmc_claim_host(host); - /* - * Check for removed cards and newly inserted ones. We check for - * removed cards first so we can intelligently re-select the VDD. - */ - power_mode = host->ios.power_mode; - if (power_mode == MMC_POWER_ON) + if (host->ios.power_mode == MMC_POWER_ON) mmc_check_cards(host); mmc_setup(host); - /* - * Some broken cards process CMD1 even in stand-by state. There is - * no reply, but an ILLEGAL_COMMAND error is cached and returned - * after next command. We poll for card status here to clear any - * possibly pending error. - */ - if (power_mode == MMC_POWER_ON) - mmc_check_cards(host); - if (!list_empty(&host->cards)) { /* * (Re-)calculate the fastest clock rate which the diff --git a/trunk/drivers/mmc/mmc_block.c b/trunk/drivers/mmc/mmc_block.c index f9027c8db792..c1293f1bda87 100644 --- a/trunk/drivers/mmc/mmc_block.c +++ b/trunk/drivers/mmc/mmc_block.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include @@ -155,71 +154,6 @@ static int mmc_blk_prep_rq(struct mmc_queue *mq, struct request *req) return stat; } -static u32 mmc_sd_num_wr_blocks(struct mmc_card *card) -{ - int err; - u32 blocks; - - struct mmc_request mrq; - struct mmc_command cmd; - struct mmc_data data; - unsigned int timeout_us; - - struct scatterlist sg; - - memset(&cmd, 0, sizeof(struct mmc_command)); - - cmd.opcode = MMC_APP_CMD; - cmd.arg = card->rca << 16; - cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; - - err = mmc_wait_for_cmd(card->host, &cmd, 0); - if ((err != MMC_ERR_NONE) || !(cmd.resp[0] & R1_APP_CMD)) - return (u32)-1; - - memset(&cmd, 0, sizeof(struct mmc_command)); - - cmd.opcode = SD_APP_SEND_NUM_WR_BLKS; - cmd.arg = 0; - cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; - - memset(&data, 0, sizeof(struct mmc_data)); - - data.timeout_ns = card->csd.tacc_ns * 100; - data.timeout_clks = card->csd.tacc_clks * 100; - - timeout_us = data.timeout_ns / 1000; - timeout_us += data.timeout_clks * 1000 / - (card->host->ios.clock / 1000); - - if (timeout_us > 100000) { - data.timeout_ns = 100000000; - data.timeout_clks = 0; - } - - data.blksz = 4; - data.blocks = 1; - data.flags = MMC_DATA_READ; - data.sg = &sg; - data.sg_len = 1; - - memset(&mrq, 0, sizeof(struct mmc_request)); - - mrq.cmd = &cmd; - mrq.data = &data; - - sg_init_one(&sg, &blocks, 4); - - mmc_wait_for_req(card->host, &mrq); - - if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE) - return (u32)-1; - - blocks = ntohl(blocks); - - return blocks; -} - static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) { struct mmc_blk_data *md = mq->data; @@ -250,13 +184,10 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) /* * If the host doesn't support multiple block writes, force - * block writes to single block. SD cards are excepted from - * this rule as they support querying the number of - * successfully written sectors. + * block writes to single block. */ if (rq_data_dir(req) != READ && - !(card->host->caps & MMC_CAP_MULTIWRITE) && - !mmc_card_sd(card)) + !(card->host->caps & MMC_CAP_MULTIWRITE)) brq.data.blocks = 1; if (brq.data.blocks > 1) { @@ -345,41 +276,24 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) return 1; cmd_err: + mmc_card_release_host(card); + ret = 1; - /* - * If this is an SD card and we're writing, we can first - * mark the known good sectors as ok. - * - * If the card is not SD, we can still ok written sectors - * if the controller can do proper error reporting. + /* + * For writes and where the host claims to support proper + * error reporting, we first ok the successful blocks. * * For reads we just fail the entire chunk as that should * be safe in all cases. */ - if (rq_data_dir(req) != READ && mmc_card_sd(card)) { - u32 blocks; - unsigned int bytes; - - blocks = mmc_sd_num_wr_blocks(card); - if (blocks != (u32)-1) { - if (card->csd.write_partial) - bytes = blocks << md->block_bits; - else - bytes = blocks << 9; - spin_lock_irq(&md->lock); - ret = end_that_request_chunk(req, 1, bytes); - spin_unlock_irq(&md->lock); - } - } else if (rq_data_dir(req) != READ && - (card->host->caps & MMC_CAP_MULTIWRITE)) { + if (rq_data_dir(req) != READ && + (card->host->caps & MMC_CAP_MULTIWRITE)) { spin_lock_irq(&md->lock); ret = end_that_request_chunk(req, 1, brq.data.bytes_xfered); spin_unlock_irq(&md->lock); } - mmc_card_release_host(card); - spin_lock_irq(&md->lock); while (ret) { ret = end_that_request_chunk(req, 0, diff --git a/trunk/drivers/mmc/mmc_queue.c b/trunk/drivers/mmc/mmc_queue.c index 61a1de85cb23..4ccdd82b680f 100644 --- a/trunk/drivers/mmc/mmc_queue.c +++ b/trunk/drivers/mmc/mmc_queue.c @@ -130,8 +130,8 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock u64 limit = BLK_BOUNCE_HIGH; int ret; - if (mmc_dev(host)->dma_mask && *mmc_dev(host)->dma_mask) - limit = *mmc_dev(host)->dma_mask; + if (host->dev->dma_mask && *host->dev->dma_mask) + limit = *host->dev->dma_mask; mq->card = card; mq->queue = blk_init_queue(mmc_request, lock); diff --git a/trunk/drivers/mmc/mmc_sysfs.c b/trunk/drivers/mmc/mmc_sysfs.c index ac5329636045..10cc9734eaa0 100644 --- a/trunk/drivers/mmc/mmc_sysfs.c +++ b/trunk/drivers/mmc/mmc_sysfs.c @@ -199,7 +199,7 @@ void mmc_init_card(struct mmc_card *card, struct mmc_host *host) memset(card, 0, sizeof(struct mmc_card)); card->host = host; device_initialize(&card->dev); - card->dev.parent = mmc_dev(host); + card->dev.parent = card->host->dev; card->dev.bus = &mmc_bus_type; card->dev.release = mmc_release_card; } @@ -242,7 +242,7 @@ void mmc_remove_card(struct mmc_card *card) } -static void mmc_host_classdev_release(struct device *dev) +static void mmc_host_classdev_release(struct class_device *dev) { struct mmc_host *host = cls_dev_to_mmc_host(dev); kfree(host); @@ -250,7 +250,7 @@ static void mmc_host_classdev_release(struct device *dev) static struct class mmc_host_class = { .name = "mmc_host", - .dev_release = mmc_host_classdev_release, + .release = mmc_host_classdev_release, }; static DEFINE_IDR(mmc_host_idr); @@ -267,10 +267,10 @@ struct mmc_host *mmc_alloc_host_sysfs(int extra, struct device *dev) if (host) { memset(host, 0, sizeof(struct mmc_host) + extra); - host->parent = dev; - host->class_dev.parent = dev; + host->dev = dev; + host->class_dev.dev = host->dev; host->class_dev.class = &mmc_host_class; - device_initialize(&host->class_dev); + class_device_initialize(&host->class_dev); } return host; @@ -292,10 +292,10 @@ int mmc_add_host_sysfs(struct mmc_host *host) if (err) return err; - snprintf(host->class_dev.bus_id, BUS_ID_SIZE, + snprintf(host->class_dev.class_id, BUS_ID_SIZE, "mmc%d", host->index); - return device_add(&host->class_dev); + return class_device_add(&host->class_dev); } /* @@ -303,7 +303,7 @@ int mmc_add_host_sysfs(struct mmc_host *host) */ void mmc_remove_host_sysfs(struct mmc_host *host) { - device_del(&host->class_dev); + class_device_del(&host->class_dev); spin_lock(&mmc_host_lock); idr_remove(&mmc_host_idr, host->index); @@ -315,7 +315,7 @@ void mmc_remove_host_sysfs(struct mmc_host *host) */ void mmc_free_host_sysfs(struct mmc_host *host) { - put_device(&host->class_dev); + class_device_put(&host->class_dev); } static struct workqueue_struct *workqueue; diff --git a/trunk/drivers/mmc/mmci.c b/trunk/drivers/mmc/mmci.c index 828503c4ee62..2b5a0cc9ea56 100644 --- a/trunk/drivers/mmc/mmci.c +++ b/trunk/drivers/mmc/mmci.c @@ -261,7 +261,7 @@ static int mmci_pio_write(struct mmci_host *host, char *buffer, unsigned int rem /* * PIO data transfer IRQ handler. */ -static irqreturn_t mmci_pio_irq(int irq, void *dev_id) +static irqreturn_t mmci_pio_irq(int irq, void *dev_id, struct pt_regs *regs) { struct mmci_host *host = dev_id; void __iomem *base = host->base; @@ -347,7 +347,7 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id) /* * Handle completion of command and data transfers. */ -static irqreturn_t mmci_irq(int irq, void *dev_id) +static irqreturn_t mmci_irq(int irq, void *dev_id, struct pt_regs *regs) { struct mmci_host *host = dev_id; u32 status; diff --git a/trunk/drivers/mmc/omap.c b/trunk/drivers/mmc/omap.c index d593ef342e75..52c9e52e6b78 100644 --- a/trunk/drivers/mmc/omap.c +++ b/trunk/drivers/mmc/omap.c @@ -377,7 +377,7 @@ static inline void mmc_omap_report_irq(u16 status) } } -static irqreturn_t mmc_omap_irq(int irq, void *dev_id) +static irqreturn_t mmc_omap_irq(int irq, void *dev_id, struct pt_regs *regs) { struct mmc_omap_host * host = (struct mmc_omap_host *)dev_id; u16 status; @@ -514,7 +514,7 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id) return IRQ_HANDLED; } -static irqreturn_t mmc_omap_switch_irq(int irq, void *dev_id) +static irqreturn_t mmc_omap_switch_irq(int irq, void *dev_id, struct pt_regs *regs) { struct mmc_omap_host *host = (struct mmc_omap_host *) dev_id; @@ -640,7 +640,8 @@ mmc_omap_prepare_dma(struct mmc_omap_host *host, struct mmc_data *data) } /* Max limit for DMA frame count is 0xffff */ - BUG_ON(count > 0xffff); + if (unlikely(count > 0xffff)) + BUG(); OMAP_MMC_WRITE(host->base, BUF, buf); omap_set_dma_transfer_params(dma_ch, OMAP_DMA_DATA_TYPE_S16, diff --git a/trunk/drivers/mmc/pxamci.c b/trunk/drivers/mmc/pxamci.c index a526698b8c91..ef350908478c 100644 --- a/trunk/drivers/mmc/pxamci.c +++ b/trunk/drivers/mmc/pxamci.c @@ -299,7 +299,7 @@ static int pxamci_data_done(struct pxamci_host *host, unsigned int stat) return 1; } -static irqreturn_t pxamci_irq(int irq, void *devid) +static irqreturn_t pxamci_irq(int irq, void *devid, struct pt_regs *regs) { struct pxamci_host *host = devid; unsigned int ireg; @@ -399,13 +399,13 @@ static struct mmc_host_ops pxamci_ops = { .set_ios = pxamci_set_ios, }; -static void pxamci_dma_irq(int dma, void *devid) +static void pxamci_dma_irq(int dma, void *devid, struct pt_regs *regs) { printk(KERN_ERR "DMA%d: IRQ???\n", dma); DCSR(dma) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR; } -static irqreturn_t pxamci_detect_irq(int irq, void *devid) +static irqreturn_t pxamci_detect_irq(int irq, void *devid, struct pt_regs *regs) { struct pxamci_host *host = mmc_priv(devid); diff --git a/trunk/drivers/mmc/sdhci.c b/trunk/drivers/mmc/sdhci.c index 9a7d39b7cdbf..20711acb0120 100644 --- a/trunk/drivers/mmc/sdhci.c +++ b/trunk/drivers/mmc/sdhci.c @@ -985,7 +985,7 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) } } -static irqreturn_t sdhci_irq(int irq, void *dev_id) +static irqreturn_t sdhci_irq(int irq, void *dev_id, struct pt_regs *regs) { irqreturn_t result; struct sdhci_host* host = dev_id; @@ -1329,7 +1329,7 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot) tasklet_init(&host->finish_tasklet, sdhci_tasklet_finish, (unsigned long)host); - setup_timer(&host->timer, sdhci_timeout_timer, (unsigned long)host); + setup_timer(&host->timer, sdhci_timeout_timer, (long)host); ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED, host->slot_descr, host); diff --git a/trunk/drivers/mmc/tifm_sd.c b/trunk/drivers/mmc/tifm_sd.c index 0fdc55b08a6d..6d23dc08d169 100644 --- a/trunk/drivers/mmc/tifm_sd.c +++ b/trunk/drivers/mmc/tifm_sd.c @@ -14,7 +14,6 @@ #include #include #include -#include #define DRIVER_NAME "tifm_sd" #define DRIVER_VERSION "0.6" @@ -502,13 +501,13 @@ static void tifm_sd_end_cmd(void *data) struct tifm_dev *sock = host->dev; struct mmc_host *mmc = tifm_get_drvdata(sock); struct mmc_request *mrq; - struct mmc_data *r_data = NULL; + struct mmc_data *r_data = 0; unsigned long flags; spin_lock_irqsave(&sock->lock, flags); mrq = host->req; - host->req = NULL; + host->req = 0; host->state = IDLE; if (!mrq) { @@ -547,7 +546,7 @@ static void tifm_sd_request_nodma(struct mmc_host *mmc, struct mmc_request *mrq) struct tifm_dev *sock = host->dev; unsigned long flags; struct mmc_data *r_data = mrq->cmd->data; - char *t_buffer = NULL; + char *t_buffer = 0; if (r_data) { t_buffer = kmap(r_data->sg->page); @@ -614,13 +613,13 @@ static void tifm_sd_end_cmd_nodma(void *data) struct tifm_dev *sock = host->dev; struct mmc_host *mmc = tifm_get_drvdata(sock); struct mmc_request *mrq; - struct mmc_data *r_data = NULL; + struct mmc_data *r_data = 0; unsigned long flags; spin_lock_irqsave(&sock->lock, flags); mrq = host->req; - host->req = NULL; + host->req = 0; host->state = IDLE; if (!mrq) { @@ -645,7 +644,7 @@ static void tifm_sd_end_cmd_nodma(void *data) r_data->bytes_xfered += r_data->blksz - readl(sock->addr + SOCK_MMCSD_BLOCK_LEN) + 1; } - host->buffer = NULL; + host->buffer = 0; host->buffer_pos = 0; host->buffer_size = 0; } @@ -896,7 +895,7 @@ static void tifm_sd_remove(struct tifm_dev *sock) sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR); writel(0, sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET); - tifm_set_drvdata(sock, NULL); + tifm_set_drvdata(sock, 0); mmc_free_host(mmc); } diff --git a/trunk/drivers/mmc/wbsd.c b/trunk/drivers/mmc/wbsd.c index 682e62b0b09d..88c6f0b129f5 100644 --- a/trunk/drivers/mmc/wbsd.c +++ b/trunk/drivers/mmc/wbsd.c @@ -1256,7 +1256,7 @@ static void wbsd_tasklet_block(unsigned long param) * Interrupt handling */ -static irqreturn_t wbsd_irq(int irq, void *dev_id) +static irqreturn_t wbsd_irq(int irq, void *dev_id, struct pt_regs *regs) { struct wbsd_host *host = dev_id; int isr; @@ -1488,7 +1488,7 @@ static void __devinit wbsd_request_dma(struct wbsd_host *host, int dma) /* * Translate the address to a physical address. */ - host->dma_addr = dma_map_single(mmc_dev(host->mmc), host->dma_buffer, + host->dma_addr = dma_map_single(host->mmc->dev, host->dma_buffer, WBSD_DMA_SIZE, DMA_BIDIRECTIONAL); /* @@ -1512,7 +1512,7 @@ static void __devinit wbsd_request_dma(struct wbsd_host *host, int dma) */ BUG_ON(1); - dma_unmap_single(mmc_dev(host->mmc), host->dma_addr, + dma_unmap_single(host->mmc->dev, host->dma_addr, WBSD_DMA_SIZE, DMA_BIDIRECTIONAL); host->dma_addr = (dma_addr_t)NULL; @@ -1530,7 +1530,7 @@ static void __devinit wbsd_request_dma(struct wbsd_host *host, int dma) static void __devexit wbsd_release_dma(struct wbsd_host *host) { if (host->dma_addr) { - dma_unmap_single(mmc_dev(host->mmc), host->dma_addr, + dma_unmap_single(host->mmc->dev, host->dma_addr, WBSD_DMA_SIZE, DMA_BIDIRECTIONAL); } kfree(host->dma_buffer); diff --git a/trunk/drivers/mtd/chips/cfi_cmdset_0001.c b/trunk/drivers/mtd/chips/cfi_cmdset_0001.c index 296159ec5189..7ea49a0d5ec3 100644 --- a/trunk/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/trunk/drivers/mtd/chips/cfi_cmdset_0001.c @@ -1087,7 +1087,7 @@ static int inval_cache_and_wait_for_operation( } spin_lock(chip->mutex); - while (chip->state != chip_state) { + if (chip->state != chip_state) { /* Someone's suspended the operation: sleep */ DECLARE_WAITQUEUE(wait, current); set_current_state(TASK_UNINTERRUPTIBLE); diff --git a/trunk/drivers/mtd/maps/Kconfig b/trunk/drivers/mtd/maps/Kconfig index d132ed571f13..24747bdc3e19 100644 --- a/trunk/drivers/mtd/maps/Kconfig +++ b/trunk/drivers/mtd/maps/Kconfig @@ -607,7 +607,7 @@ config MTD_BAST_MAXSIZE default "4" config MTD_SHARP_SL - bool "ROM mapped on Sharp SL Series" + bool "ROM maped on Sharp SL Series" depends on MTD && ARCH_PXA help This enables access to the flash chip on the Sharp SL Series of PDAs. diff --git a/trunk/drivers/mtd/maps/cfi_flagadm.c b/trunk/drivers/mtd/maps/cfi_flagadm.c index 65e5ee552010..92b5d883d7b0 100644 --- a/trunk/drivers/mtd/maps/cfi_flagadm.c +++ b/trunk/drivers/mtd/maps/cfi_flagadm.c @@ -80,7 +80,7 @@ struct mtd_partition flagadm_parts[] = { .size = FLASH_PARTITION2_SIZE }, { - .name = "Persistent storage", + .name = "Persistant storage", .offset = FLASH_PARTITION3_ADDR, .size = FLASH_PARTITION3_SIZE } diff --git a/trunk/drivers/mtd/maps/physmap.c b/trunk/drivers/mtd/maps/physmap.c index d1717763f719..bc7cc71788bc 100644 --- a/trunk/drivers/mtd/maps/physmap.c +++ b/trunk/drivers/mtd/maps/physmap.c @@ -62,7 +62,7 @@ static int physmap_flash_remove(struct platform_device *dev) } if (info->map.virt != NULL) - iounmap(info->map.virt); + iounmap((void *)info->map.virt); if (info->res != NULL) { release_resource(info->res); diff --git a/trunk/drivers/mtd/nand/cs553x_nand.c b/trunk/drivers/mtd/nand/cs553x_nand.c index 94924d52a9b9..e0a1d386e581 100644 --- a/trunk/drivers/mtd/nand/cs553x_nand.c +++ b/trunk/drivers/mtd/nand/cs553x_nand.c @@ -249,7 +249,7 @@ static int __init cs553x_init_one(int cs, int mmio, unsigned long adr) goto out; out_ior: - iounmap(this->IO_ADDR_R); + iounmap((void *)this->IO_ADDR_R); out_mtd: kfree(new_mtd); out: diff --git a/trunk/drivers/mtd/nand/nand_base.c b/trunk/drivers/mtd/nand/nand_base.c index 41bfcae1fbf4..baece61169f4 100644 --- a/trunk/drivers/mtd/nand/nand_base.c +++ b/trunk/drivers/mtd/nand/nand_base.c @@ -1479,7 +1479,6 @@ static void nand_write_page_syndrome(struct mtd_info *mtd, * @buf: the data to write * @page: page number to write * @cached: cached programming - * @raw: use _raw version of write_page */ static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip, const uint8_t *buf, int page, int cached, int raw) diff --git a/trunk/drivers/net/3c501.c b/trunk/drivers/net/3c501.c index 11d170afa9c3..1b82bccd8c71 100644 --- a/trunk/drivers/net/3c501.c +++ b/trunk/drivers/net/3c501.c @@ -496,6 +496,7 @@ static int el_start_xmit(struct sk_buff *skb, struct net_device *dev) * el_interrupt: * @irq: Interrupt number * @dev_id: The 3c501 that burped + * @regs: Register data (surplus to our requirements) * * Handle the ether interface interrupts. The 3c501 needs a lot more * hand holding than most cards. In particular we get a transmit interrupt @@ -514,7 +515,7 @@ static int el_start_xmit(struct sk_buff *skb, struct net_device *dev) * TCP window. */ -static irqreturn_t el_interrupt(int irq, void *dev_id) +static irqreturn_t el_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; struct net_local *lp; diff --git a/trunk/drivers/net/3c501.h b/trunk/drivers/net/3c501.h index c56a2c62f7de..39d332474750 100644 --- a/trunk/drivers/net/3c501.h +++ b/trunk/drivers/net/3c501.h @@ -7,7 +7,7 @@ static int el1_probe1(struct net_device *dev, int ioaddr); static int el_open(struct net_device *dev); static void el_timeout(struct net_device *dev); static int el_start_xmit(struct sk_buff *skb, struct net_device *dev); -static irqreturn_t el_interrupt(int irq, void *dev_id); +static irqreturn_t el_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void el_receive(struct net_device *dev); static void el_reset(struct net_device *dev); static int el1_close(struct net_device *dev); diff --git a/trunk/drivers/net/3c505.c b/trunk/drivers/net/3c505.c index 458cb9cbe915..ab8230a68bea 100644 --- a/trunk/drivers/net/3c505.c +++ b/trunk/drivers/net/3c505.c @@ -649,7 +649,7 @@ static void receive_packet(struct net_device *dev, int len) * ******************************************************/ -static irqreturn_t elp_interrupt(int irq, void *dev_id) +static irqreturn_t elp_interrupt(int irq, void *dev_id, struct pt_regs *reg_ptr) { int len; int dlen; diff --git a/trunk/drivers/net/3c507.c b/trunk/drivers/net/3c507.c index aa43563610ae..8205a535c5b7 100644 --- a/trunk/drivers/net/3c507.c +++ b/trunk/drivers/net/3c507.c @@ -286,7 +286,7 @@ static unsigned short init_words[] = { static int el16_probe1(struct net_device *dev, int ioaddr); static int el16_open(struct net_device *dev); static int el16_send_packet(struct sk_buff *skb, struct net_device *dev); -static irqreturn_t el16_interrupt(int irq, void *dev_id); +static irqreturn_t el16_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void el16_rx(struct net_device *dev); static int el16_close(struct net_device *dev); static struct net_device_stats *el16_get_stats(struct net_device *dev); @@ -543,7 +543,7 @@ static int el16_send_packet (struct sk_buff *skb, struct net_device *dev) /* The typical workload of the driver: Handle the network interface interrupts. */ -static irqreturn_t el16_interrupt(int irq, void *dev_id) +static irqreturn_t el16_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; struct net_local *lp; diff --git a/trunk/drivers/net/3c509.c b/trunk/drivers/net/3c509.c index f791bf026e51..b936373ab2a5 100644 --- a/trunk/drivers/net/3c509.c +++ b/trunk/drivers/net/3c509.c @@ -191,7 +191,7 @@ static ushort id_read_eeprom(int index); static ushort read_eeprom(int ioaddr, int index); static int el3_open(struct net_device *dev); static int el3_start_xmit(struct sk_buff *skb, struct net_device *dev); -static irqreturn_t el3_interrupt(int irq, void *dev_id); +static irqreturn_t el3_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void update_stats(struct net_device *dev); static struct net_device_stats *el3_get_stats(struct net_device *dev); static int el3_rx(struct net_device *dev); @@ -910,13 +910,18 @@ el3_start_xmit(struct sk_buff *skb, struct net_device *dev) /* The EL3 interrupt handler. */ static irqreturn_t -el3_interrupt(int irq, void *dev_id) +el3_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct net_device *dev = dev_id; + struct net_device *dev = (struct net_device *)dev_id; struct el3_private *lp; int ioaddr, status; int i = max_interrupt_work; + if (dev == NULL) { + printk ("el3_interrupt(): irq %d for unknown device.\n", irq); + return IRQ_NONE; + } + lp = netdev_priv(dev); spin_lock(&lp->lock); @@ -1001,7 +1006,7 @@ el3_interrupt(int irq, void *dev_id) static void el3_poll_controller(struct net_device *dev) { disable_irq(dev->irq); - el3_interrupt(dev->irq, dev); + el3_interrupt(dev->irq, dev, NULL); enable_irq(dev->irq); } #endif diff --git a/trunk/drivers/net/3c515.c b/trunk/drivers/net/3c515.c index c307ce66145c..91f2232e6050 100644 --- a/trunk/drivers/net/3c515.c +++ b/trunk/drivers/net/3c515.c @@ -373,7 +373,8 @@ static int corkscrew_start_xmit(struct sk_buff *skb, static int corkscrew_rx(struct net_device *dev); static void corkscrew_timeout(struct net_device *dev); static int boomerang_rx(struct net_device *dev); -static irqreturn_t corkscrew_interrupt(int irq, void *dev_id); +static irqreturn_t corkscrew_interrupt(int irq, void *dev_id, + struct pt_regs *regs); static int corkscrew_close(struct net_device *dev); static void update_stats(int addr, struct net_device *dev); static struct net_device_stats *corkscrew_get_stats(struct net_device *dev); @@ -1115,7 +1116,8 @@ static int corkscrew_start_xmit(struct sk_buff *skb, /* The interrupt handler does all of the Rx thread work and cleans up after the Tx thread. */ -static irqreturn_t corkscrew_interrupt(int irq, void *dev_id) +static irqreturn_t corkscrew_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { /* Use the now-standard shared IRQ implementation. */ struct net_device *dev = dev_id; diff --git a/trunk/drivers/net/3c523.c b/trunk/drivers/net/3c523.c index 91849469b4f4..cf8a0bc3bf34 100644 --- a/trunk/drivers/net/3c523.c +++ b/trunk/drivers/net/3c523.c @@ -180,7 +180,7 @@ sizeof(nop_cmd) = 8; dev->name,__LINE__); \ elmc_id_reset586(); } } } -static irqreturn_t elmc_interrupt(int irq, void *dev_id); +static irqreturn_t elmc_interrupt(int irq, void *dev_id, struct pt_regs *reg_ptr); static int elmc_open(struct net_device *dev); static int elmc_close(struct net_device *dev); static int elmc_send_packet(struct sk_buff *, struct net_device *); @@ -900,13 +900,16 @@ static void *alloc_rfa(struct net_device *dev, void *ptr) */ static irqreturn_t -elmc_interrupt(int irq, void *dev_id) +elmc_interrupt(int irq, void *dev_id, struct pt_regs *reg_ptr) { - struct net_device *dev = dev_id; + struct net_device *dev = (struct net_device *) dev_id; unsigned short stat; struct priv *p; - if (!netif_running(dev)) { + if (dev == NULL) { + printk(KERN_ERR "elmc-interrupt: irq %d for unknown device.\n", (int) -(((struct pt_regs *) reg_ptr)->orig_eax + 2)); + return IRQ_NONE; + } else if (!netif_running(dev)) { /* The 3c523 has this habit of generating interrupts during the reset. I'm not sure if the ni52 has this same problem, but it's really annoying if we haven't finished initializing it. I was diff --git a/trunk/drivers/net/3c527.c b/trunk/drivers/net/3c527.c index f4aca5386add..625e57dc3b4a 100644 --- a/trunk/drivers/net/3c527.c +++ b/trunk/drivers/net/3c527.c @@ -217,7 +217,7 @@ static int mc32_command(struct net_device *dev, u16 cmd, void *data, int le static int mc32_open(struct net_device *dev); static void mc32_timeout(struct net_device *dev); static int mc32_send_packet(struct sk_buff *skb, struct net_device *dev); -static irqreturn_t mc32_interrupt(int irq, void *dev_id); +static irqreturn_t mc32_interrupt(int irq, void *dev_id, struct pt_regs *regs); static int mc32_close(struct net_device *dev); static struct net_device_stats *mc32_get_stats(struct net_device *dev); static void mc32_set_multicast_list(struct net_device *dev); @@ -1316,7 +1316,7 @@ static void mc32_tx_ring(struct net_device *dev) * */ -static irqreturn_t mc32_interrupt(int irq, void *dev_id) +static irqreturn_t mc32_interrupt(int irq, void *dev_id, struct pt_regs * regs) { struct net_device *dev = dev_id; struct mc32_local *lp; @@ -1324,6 +1324,11 @@ static irqreturn_t mc32_interrupt(int irq, void *dev_id) int rx_event = 0; int tx_event = 0; + if (dev == NULL) { + printk(KERN_WARNING "%s: irq %d for unknown device.\n", cardname, irq); + return IRQ_NONE; + } + ioaddr = dev->base_addr; lp = netdev_priv(dev); diff --git a/trunk/drivers/net/3c59x.c b/trunk/drivers/net/3c59x.c index 80bdcf846234..df42e28cc80f 100644 --- a/trunk/drivers/net/3c59x.c +++ b/trunk/drivers/net/3c59x.c @@ -717,8 +717,8 @@ static int vortex_start_xmit(struct sk_buff *skb, struct net_device *dev); static int boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev); static int vortex_rx(struct net_device *dev); static int boomerang_rx(struct net_device *dev); -static irqreturn_t vortex_interrupt(int irq, void *dev_id); -static irqreturn_t boomerang_interrupt(int irq, void *dev_id); +static irqreturn_t vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs); +static irqreturn_t boomerang_interrupt(int irq, void *dev_id, struct pt_regs *regs); static int vortex_close(struct net_device *dev); static void dump_tx_ring(struct net_device *dev); static void update_stats(void __iomem *ioaddr, struct net_device *dev); @@ -794,7 +794,7 @@ static void poll_vortex(struct net_device *dev) unsigned long flags; local_save_flags(flags); local_irq_disable(); - (vp->full_bus_master_rx ? boomerang_interrupt:vortex_interrupt)(dev->irq,dev); + (vp->full_bus_master_rx ? boomerang_interrupt:vortex_interrupt)(dev->irq,dev,NULL); local_irq_restore(flags); } #endif @@ -1849,9 +1849,9 @@ static void vortex_tx_timeout(struct net_device *dev) unsigned long flags; local_irq_save(flags); if (vp->full_bus_master_tx) - boomerang_interrupt(dev->irq, dev); + boomerang_interrupt(dev->irq, dev, NULL); else - vortex_interrupt(dev->irq, dev); + vortex_interrupt(dev->irq, dev, NULL); local_irq_restore(flags); } } @@ -2149,7 +2149,7 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev) */ static irqreturn_t -vortex_interrupt(int irq, void *dev_id) +vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; struct vortex_private *vp = netdev_priv(dev); @@ -2254,7 +2254,7 @@ vortex_interrupt(int irq, void *dev_id) */ static irqreturn_t -boomerang_interrupt(int irq, void *dev_id) +boomerang_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; struct vortex_private *vp = netdev_priv(dev); diff --git a/trunk/drivers/net/7990.c b/trunk/drivers/net/7990.c index 7733697f7776..db7b19a5cd59 100644 --- a/trunk/drivers/net/7990.c +++ b/trunk/drivers/net/7990.c @@ -438,7 +438,7 @@ static int lance_tx (struct net_device *dev) } static irqreturn_t -lance_interrupt (int irq, void *dev_id) +lance_interrupt (int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *)dev_id; struct lance_private *lp = netdev_priv(dev); @@ -674,7 +674,7 @@ void lance_poll(struct net_device *dev) WRITERAP(lp, LE_CSR0); WRITERDP(lp, LE_C0_STRT); spin_unlock (&lp->devlock); - lance_interrupt(dev->irq, dev); + lance_interrupt(dev->irq, dev, NULL); } #endif diff --git a/trunk/drivers/net/8139cp.c b/trunk/drivers/net/8139cp.c index 458dd9f830c4..5a4990ae3730 100644 --- a/trunk/drivers/net/8139cp.c +++ b/trunk/drivers/net/8139cp.c @@ -631,7 +631,8 @@ static int cp_rx_poll (struct net_device *dev, int *budget) return 1; /* not done */ } -static irqreturn_t cp_interrupt (int irq, void *dev_instance) +static irqreturn_t +cp_interrupt (int irq, void *dev_instance, struct pt_regs *regs) { struct net_device *dev = dev_instance; struct cp_private *cp; @@ -695,7 +696,7 @@ static irqreturn_t cp_interrupt (int irq, void *dev_instance) static void cp_poll_controller(struct net_device *dev) { disable_irq(dev->irq); - cp_interrupt(dev->irq, dev); + cp_interrupt(dev->irq, dev, NULL); enable_irq(dev->irq); } #endif diff --git a/trunk/drivers/net/8139too.c b/trunk/drivers/net/8139too.c index d02ed51abfcc..dbc5c0b1b96c 100644 --- a/trunk/drivers/net/8139too.c +++ b/trunk/drivers/net/8139too.c @@ -629,7 +629,8 @@ static int rtl8139_poll(struct net_device *dev, int *budget); #ifdef CONFIG_NET_POLL_CONTROLLER static void rtl8139_poll_controller(struct net_device *dev); #endif -static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance); +static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance, + struct pt_regs *regs); static int rtl8139_close (struct net_device *dev); static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd); static struct net_device_stats *rtl8139_get_stats (struct net_device *dev); @@ -2145,7 +2146,8 @@ static int rtl8139_poll(struct net_device *dev, int *budget) /* The interrupt handler does all of the Rx thread work and cleans up after the Tx thread. */ -static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance) +static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance, + struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_instance; struct rtl8139_private *tp = netdev_priv(dev); @@ -2217,7 +2219,7 @@ static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance) static void rtl8139_poll_controller(struct net_device *dev) { disable_irq(dev->irq); - rtl8139_interrupt(dev->irq, dev); + rtl8139_interrupt(dev->irq, dev, NULL); enable_irq(dev->irq); } #endif diff --git a/trunk/drivers/net/82596.c b/trunk/drivers/net/82596.c index 8236f26ffd46..c9e4dca9d410 100644 --- a/trunk/drivers/net/82596.c +++ b/trunk/drivers/net/82596.c @@ -357,7 +357,7 @@ static char init_setup[] = static int i596_open(struct net_device *dev); static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev); -static irqreturn_t i596_interrupt(int irq, void *dev_id); +static irqreturn_t i596_interrupt(int irq, void *dev_id, struct pt_regs *regs); static int i596_close(struct net_device *dev); static struct net_device_stats *i596_get_stats(struct net_device *dev); static void i596_add_cmd(struct net_device *dev, struct i596_cmd *cmd); @@ -501,7 +501,7 @@ static void i596_display_data(struct net_device *dev) #if defined(ENABLE_MVME16x_NET) || defined(ENABLE_BVME6000_NET) -static irqreturn_t i596_error(int irq, void *dev_id) +static irqreturn_t i596_error(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; #ifdef ENABLE_MVME16x_NET @@ -1283,7 +1283,7 @@ struct net_device * __init i82596_probe(int unit) return ERR_PTR(err); } -static irqreturn_t i596_interrupt(int irq, void *dev_id) +static irqreturn_t i596_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; struct i596_private *lp; @@ -1294,7 +1294,7 @@ static irqreturn_t i596_interrupt(int irq, void *dev_id) #ifdef ENABLE_BVME6000_NET if (MACH_IS_BVME6000) { if (*(char *) BVME_LOCAL_IRQ_STAT & BVME_ETHERR) { - i596_error(irq, dev_id); + i596_error(irq, dev_id, regs); return IRQ_HANDLED; } } diff --git a/trunk/drivers/net/8390.c b/trunk/drivers/net/8390.c index 3d1c599ac3cb..9d34056147ad 100644 --- a/trunk/drivers/net/8390.c +++ b/trunk/drivers/net/8390.c @@ -391,6 +391,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev) * ei_interrupt - handle the interrupts from an 8390 * @irq: interrupt number * @dev_id: a pointer to the net_device + * @regs: unused * * Handle the ether interface interrupts. We pull packets from * the 8390 via the card specific functions and fire them at the networking @@ -399,15 +400,21 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev) * needed. */ -irqreturn_t ei_interrupt(int irq, void *dev_id) +irqreturn_t ei_interrupt(int irq, void *dev_id, struct pt_regs * regs) { struct net_device *dev = dev_id; long e8390_base; int interrupts, nr_serviced = 0; struct ei_device *ei_local; + if (dev == NULL) + { + printk ("net_interrupt(): irq %d for unknown device.\n", irq); + return IRQ_NONE; + } + e8390_base = dev->base_addr; - ei_local = netdev_priv(dev); + ei_local = (struct ei_device *) netdev_priv(dev); /* * Protect the irq test too. @@ -499,7 +506,7 @@ irqreturn_t ei_interrupt(int irq, void *dev_id) void ei_poll(struct net_device *dev) { disable_irq_lockdep(dev->irq); - ei_interrupt(dev->irq, dev); + ei_interrupt(dev->irq, dev, NULL); enable_irq_lockdep(dev->irq); } #endif diff --git a/trunk/drivers/net/8390.h b/trunk/drivers/net/8390.h index f44f1220b3a5..ca4eb0ccf8cf 100644 --- a/trunk/drivers/net/8390.h +++ b/trunk/drivers/net/8390.h @@ -35,7 +35,7 @@ extern void ei_poll(struct net_device *dev); extern void NS8390_init(struct net_device *dev, int startp); extern int ei_open(struct net_device *dev); extern int ei_close(struct net_device *dev); -extern irqreturn_t ei_interrupt(int irq, void *dev_id); +extern irqreturn_t ei_interrupt(int irq, void *dev_id, struct pt_regs *regs); extern struct net_device *__alloc_ei_netdev(int size); static inline struct net_device *alloc_ei_netdev(void) { diff --git a/trunk/drivers/net/Kconfig b/trunk/drivers/net/Kconfig index b6c70c58ae99..ab92cc794c64 100644 --- a/trunk/drivers/net/Kconfig +++ b/trunk/drivers/net/Kconfig @@ -32,7 +32,7 @@ config IFB tristate "Intermediate Functional Block support" depends on NET_CLS_ACT ---help--- - This is an intermediate driver that allows sharing of + This is an intermidiate driver that allows sharing of resources. To compile this driver as a module, choose M here: the module will be called ifb. If you want to use more than one ifb @@ -486,7 +486,7 @@ config SGI_IOC3_ETH_HW_TX_CSUM config MIPS_SIM_NET tristate "MIPS simulator Network device (EXPERIMENTAL)" - depends on MIPS_SIM && EXPERIMENTAL + depends on NETDEVICES && MIPS_SIM && EXPERIMENTAL help The MIPSNET device is a simple Ethernet network device which is emulated by the MIPS Simulator. @@ -2112,7 +2112,7 @@ config SKGE config SKY2 tristate "SysKonnect Yukon2 support (EXPERIMENTAL)" - depends on PCI + depends on PCI && EXPERIMENTAL select CRC32 ---help--- This driver supports Gigabit Ethernet adapters based on the @@ -2120,8 +2120,8 @@ config SKY2 Marvell 88E8021/88E8022/88E8035/88E8036/88E8038/88E8050/88E8052/ 88E8053/88E8055/88E8061/88E8062, SysKonnect SK-9E21D/SK-9S21 - There is companion driver for the older Marvell Yukon and - Genesis based adapters: skge. + This driver does not support the original Yukon chipset: a seperate + driver, skge, is provided for Yukon-based adapters. To compile this driver as a module, choose M here: the module will be called sky2. This is recommended. @@ -2136,7 +2136,7 @@ config SK98LIN This driver supports the original Yukon chipset. A cleaner driver is also available (skge) which seems to work better than this one. - This driver does not support the newer Yukon2 chipset. A separate + This driver does not support the newer Yukon2 chipset. A seperate driver, sky2, is provided to support Yukon2-based adapters. The following adapters are supported by this driver: @@ -2288,7 +2288,7 @@ config UGETH_TX_ON_DEMOND config UGETH_HAS_GIGA bool - depends on UCC_GETH && PPC_MPC836x + depends on UCC_GETH && MPC836x config MV643XX_ETH tristate "MV-643XX Ethernet support" @@ -2467,7 +2467,7 @@ config ISERIES_VETH config RIONET tristate "RapidIO Ethernet over messaging driver support" - depends on RAPIDIO + depends on NETDEVICES && RAPIDIO config RIONET_TX_SIZE int "Number of outbound queue entries" @@ -2717,7 +2717,6 @@ config PPP_MPPE select CRYPTO select CRYPTO_SHA1 select CRYPTO_ARC4 - select CRYPTO_ECB ---help--- Support for the MPPE Encryption protocol, as employed by the Microsoft Point-to-Point Tunneling Protocol. @@ -2833,7 +2832,7 @@ config NET_FC "SCSI generic support". config SHAPER - tristate "Traffic Shaper (OBSOLETE)" + tristate "Traffic Shaper (EXPERIMENTAL)" depends on EXPERIMENTAL ---help--- The traffic shaper is a virtual network device that allows you to @@ -2842,9 +2841,9 @@ config SHAPER these virtual devices. See for more information. - An alternative to this traffic shaper are traffic schedulers which - you'll get if you say Y to "QoS and/or fair queuing" in - "Networking options". + An alternative to this traffic shaper is the experimental + Class-Based Queuing (CBQ) scheduling support which you get if you + say Y to "QoS and/or fair queuing" above. To compile this driver as a module, choose M here: the module will be called shaper. If unsure, say N. diff --git a/trunk/drivers/net/a2065.c b/trunk/drivers/net/a2065.c index d76548e75350..5f7258fea19d 100644 --- a/trunk/drivers/net/a2065.c +++ b/trunk/drivers/net/a2065.c @@ -425,7 +425,8 @@ static int lance_tx (struct net_device *dev) return 0; } -static irqreturn_t lance_interrupt (int irq, void *dev_id) +static irqreturn_t +lance_interrupt (int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev; struct lance_private *lp; diff --git a/trunk/drivers/net/acenic.c b/trunk/drivers/net/acenic.c index 33c6645455ae..71a4f60f7325 100644 --- a/trunk/drivers/net/acenic.c +++ b/trunk/drivers/net/acenic.c @@ -2144,7 +2144,7 @@ static inline void ace_tx_int(struct net_device *dev, } -static irqreturn_t ace_interrupt(int irq, void *dev_id) +static irqreturn_t ace_interrupt(int irq, void *dev_id, struct pt_regs *ptregs) { struct net_device *dev = (struct net_device *)dev_id; struct ace_private *ap = netdev_priv(dev); diff --git a/trunk/drivers/net/acenic.h b/trunk/drivers/net/acenic.h index 8ca8534d70bf..efb14b9f4d90 100644 --- a/trunk/drivers/net/acenic.h +++ b/trunk/drivers/net/acenic.h @@ -769,7 +769,7 @@ static int ace_init(struct net_device *dev); static void ace_load_std_rx_ring(struct ace_private *ap, int nr_bufs); static void ace_load_mini_rx_ring(struct ace_private *ap, int nr_bufs); static void ace_load_jumbo_rx_ring(struct ace_private *ap, int nr_bufs); -static irqreturn_t ace_interrupt(int irq, void *dev_id); +static irqreturn_t ace_interrupt(int irq, void *dev_id, struct pt_regs *regs); static int ace_load_firmware(struct net_device *dev); static int ace_open(struct net_device *dev); static int ace_start_xmit(struct sk_buff *skb, struct net_device *dev); diff --git a/trunk/drivers/net/amd8111e.c b/trunk/drivers/net/amd8111e.c index ef65e5917c8f..28855a01ed7b 100644 --- a/trunk/drivers/net/amd8111e.c +++ b/trunk/drivers/net/amd8111e.c @@ -1257,7 +1257,7 @@ static int amd8111e_calc_coalesce(struct net_device *dev) /* This is device interrupt function. It handles transmit, receive,link change and hardware timer interrupts. */ -static irqreturn_t amd8111e_interrupt(int irq, void *dev_id) +static irqreturn_t amd8111e_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device * dev = (struct net_device *) dev_id; @@ -1336,7 +1336,7 @@ static void amd8111e_poll(struct net_device *dev) unsigned long flags; local_save_flags(flags); local_irq_disable(); - amd8111e_interrupt(0, dev); + amd8111e_interrupt(0, dev, NULL); local_irq_restore(flags); } #endif diff --git a/trunk/drivers/net/apne.c b/trunk/drivers/net/apne.c index 9164d8cd670e..643b08cc7403 100644 --- a/trunk/drivers/net/apne.c +++ b/trunk/drivers/net/apne.c @@ -88,7 +88,7 @@ static void apne_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); static void apne_block_output(struct net_device *dev, const int count, const unsigned char *buf, const int start_page); -static irqreturn_t apne_interrupt(int irq, void *dev_id); +static irqreturn_t apne_interrupt(int irq, void *dev_id, struct pt_regs *regs); static int init_pcmcia(void); @@ -543,7 +543,7 @@ apne_block_output(struct net_device *dev, int count, return; } -static irqreturn_t apne_interrupt(int irq, void *dev_id) +static irqreturn_t apne_interrupt(int irq, void *dev_id, struct pt_regs *regs) { unsigned char pcmcia_intreq; @@ -559,7 +559,7 @@ static irqreturn_t apne_interrupt(int irq, void *dev_id) if (ei_debug > 3) printk("pcmcia intreq = %x\n", pcmcia_intreq); pcmcia_disable_irq(); /* to get rid of the sti() within ei_interrupt */ - ei_interrupt(irq, dev_id); + ei_interrupt(irq, dev_id, regs); pcmcia_ack_int(pcmcia_get_intreq()); pcmcia_enable_irq(); return IRQ_HANDLED; diff --git a/trunk/drivers/net/appletalk/cops.c b/trunk/drivers/net/appletalk/cops.c index cc1a27ed197f..ae7f828344d9 100644 --- a/trunk/drivers/net/appletalk/cops.c +++ b/trunk/drivers/net/appletalk/cops.c @@ -188,7 +188,7 @@ static void cops_reset (struct net_device *dev, int sleep); static void cops_load (struct net_device *dev); static int cops_nodeid (struct net_device *dev, int nodeid); -static irqreturn_t cops_interrupt (int irq, void *dev_id); +static irqreturn_t cops_interrupt (int irq, void *dev_id, struct pt_regs *regs); static void cops_poll (unsigned long ltdev); static void cops_timeout(struct net_device *dev); static void cops_rx (struct net_device *dev); @@ -721,7 +721,7 @@ static void cops_poll(unsigned long ltdev) * The typical workload of the driver: * Handle the network interface interrupts. */ -static irqreturn_t cops_interrupt(int irq, void *dev_id) +static irqreturn_t cops_interrupt(int irq, void *dev_id, struct pt_regs * regs) { struct net_device *dev = dev_id; struct cops_local *lp; diff --git a/trunk/drivers/net/appletalk/ltpc.c b/trunk/drivers/net/appletalk/ltpc.c index 2ea44ce49810..d5666c37cb0d 100644 --- a/trunk/drivers/net/appletalk/ltpc.c +++ b/trunk/drivers/net/appletalk/ltpc.c @@ -790,7 +790,7 @@ static int sendup_buffer (struct net_device *dev) /* the handler for the board interrupt */ static irqreturn_t -ltpc_interrupt(int irq, void *dev_id) +ltpc_interrupt(int irq, void *dev_id, struct pt_regs *reg_ptr) { struct net_device *dev = dev_id; diff --git a/trunk/drivers/net/arcnet/arcnet.c b/trunk/drivers/net/arcnet/arcnet.c index 4e91dab1f17f..5a95005253fa 100644 --- a/trunk/drivers/net/arcnet/arcnet.c +++ b/trunk/drivers/net/arcnet/arcnet.c @@ -752,7 +752,7 @@ static void arcnet_timeout(struct net_device *dev) * interrupts. Establish which device needs attention, and call the correct * chipset interrupt handler. */ -irqreturn_t arcnet_interrupt(int irq, void *dev_id) +irqreturn_t arcnet_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; struct arcnet_local *lp; diff --git a/trunk/drivers/net/arcnet/com20020.c b/trunk/drivers/net/arcnet/com20020.c index aa9dd8f11269..0dc70c7b7940 100644 --- a/trunk/drivers/net/arcnet/com20020.c +++ b/trunk/drivers/net/arcnet/com20020.c @@ -337,16 +337,13 @@ static void com20020_set_mc_list(struct net_device *dev) } } -#if defined(CONFIG_ARCNET_COM20020_PCI_MODULE) || \ - defined(CONFIG_ARCNET_COM20020_ISA_MODULE) +#ifdef MODULE + EXPORT_SYMBOL(com20020_check); EXPORT_SYMBOL(com20020_found); -#endif MODULE_LICENSE("GPL"); -#ifdef MODULE - int init_module(void) { BUGLVL(D_NORMAL) printk(VERSION); diff --git a/trunk/drivers/net/ariadne.c b/trunk/drivers/net/ariadne.c index 9dfc09b181c1..3aef3c10d56f 100644 --- a/trunk/drivers/net/ariadne.c +++ b/trunk/drivers/net/ariadne.c @@ -120,7 +120,7 @@ static int ariadne_start_xmit(struct sk_buff *skb, struct net_device *dev); static void ariadne_tx_timeout(struct net_device *dev); static int ariadne_rx(struct net_device *dev); static void ariadne_reset(struct net_device *dev); -static irqreturn_t ariadne_interrupt(int irq, void *data); +static irqreturn_t ariadne_interrupt(int irq, void *data, struct pt_regs *fp); static int ariadne_close(struct net_device *dev); static struct net_device_stats *ariadne_get_stats(struct net_device *dev); #ifdef HAVE_MULTICAST @@ -416,7 +416,7 @@ static inline void ariadne_reset(struct net_device *dev) } -static irqreturn_t ariadne_interrupt(int irq, void *data) +static irqreturn_t ariadne_interrupt(int irq, void *data, struct pt_regs *fp) { struct net_device *dev = (struct net_device *)data; volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr; diff --git a/trunk/drivers/net/arm/am79c961a.c b/trunk/drivers/net/arm/am79c961a.c index ddd12d44ff22..09d5c3f26985 100644 --- a/trunk/drivers/net/arm/am79c961a.c +++ b/trunk/drivers/net/arm/am79c961a.c @@ -38,7 +38,7 @@ #include "am79c961a.h" static irqreturn_t -am79c961_interrupt (int irq, void *dev_id); +am79c961_interrupt (int irq, void *dev_id, struct pt_regs *regs); static unsigned int net_debug = NET_DEBUG; @@ -596,7 +596,7 @@ am79c961_tx(struct net_device *dev, struct dev_priv *priv) } static irqreturn_t -am79c961_interrupt(int irq, void *dev_id) +am79c961_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *)dev_id; struct dev_priv *priv = netdev_priv(dev); diff --git a/trunk/drivers/net/arm/at91_ether.c b/trunk/drivers/net/arm/at91_ether.c index b54b857e357e..3ecf2cc53a7c 100644 --- a/trunk/drivers/net/arm/at91_ether.c +++ b/trunk/drivers/net/arm/at91_ether.c @@ -196,7 +196,7 @@ static void update_linkspeed(struct net_device *dev, int silent) /* * Handle interrupts from the PHY */ -static irqreturn_t at91ether_phy_interrupt(int irq, void *dev_id) +static irqreturn_t at91ether_phy_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_id; struct at91_private *lp = (struct at91_private *) dev->priv; @@ -888,7 +888,7 @@ static void at91ether_rx(struct net_device *dev) /* * MAC interrupt handler */ -static irqreturn_t at91ether_interrupt(int irq, void *dev_id) +static irqreturn_t at91ether_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_id; struct at91_private *lp = (struct at91_private *) dev->priv; diff --git a/trunk/drivers/net/arm/ep93xx_eth.c b/trunk/drivers/net/arm/ep93xx_eth.c index 8ebd68e2af98..d231efa624d4 100644 --- a/trunk/drivers/net/arm/ep93xx_eth.c +++ b/trunk/drivers/net/arm/ep93xx_eth.c @@ -193,9 +193,12 @@ static struct net_device_stats *ep93xx_get_stats(struct net_device *dev) static int ep93xx_rx(struct net_device *dev, int *budget) { struct ep93xx_priv *ep = netdev_priv(dev); + int tail_offset; int rx_done; int processed; + tail_offset = rdl(ep, REG_RXSTSQCURADD) - ep->descs_dma_addr; + rx_done = 0; processed = 0; while (*budget > 0) { @@ -208,28 +211,36 @@ static int ep93xx_rx(struct net_device *dev, int *budget) entry = ep->rx_pointer; rstat = ep->descs->rstat + entry; - - rstat0 = rstat->rstat0; - rstat1 = rstat->rstat1; - if (!(rstat0 & RSTAT0_RFP) || !(rstat1 & RSTAT1_RFP)) { + if ((void *)rstat - (void *)ep->descs == tail_offset) { rx_done = 1; break; } + rstat0 = rstat->rstat0; + rstat1 = rstat->rstat1; rstat->rstat0 = 0; rstat->rstat1 = 0; + if (!(rstat0 & RSTAT0_RFP)) + printk(KERN_CRIT "ep93xx_rx: buffer not done " + " %.8x %.8x\n", rstat0, rstat1); if (!(rstat0 & RSTAT0_EOF)) printk(KERN_CRIT "ep93xx_rx: not end-of-frame " " %.8x %.8x\n", rstat0, rstat1); if (!(rstat0 & RSTAT0_EOB)) printk(KERN_CRIT "ep93xx_rx: not end-of-buffer " " %.8x %.8x\n", rstat0, rstat1); + if (!(rstat1 & RSTAT1_RFP)) + printk(KERN_CRIT "ep93xx_rx: buffer1 not done " + " %.8x %.8x\n", rstat0, rstat1); if ((rstat1 & RSTAT1_BUFFER_INDEX) >> 16 != entry) printk(KERN_CRIT "ep93xx_rx: entry mismatch " " %.8x %.8x\n", rstat0, rstat1); if (!(rstat0 & RSTAT0_RWE)) { + printk(KERN_NOTICE "ep93xx_rx: receive error " + " %.8x %.8x\n", rstat0, rstat1); + ep->stats.rx_errors++; if (rstat0 & RSTAT0_OE) ep->stats.rx_fifo_errors++; @@ -290,8 +301,13 @@ static int ep93xx_rx(struct net_device *dev, int *budget) static int ep93xx_have_more_rx(struct ep93xx_priv *ep) { - struct ep93xx_rstat *rstat = ep->descs->rstat + ep->rx_pointer; - return !!((rstat->rstat0 & RSTAT0_RFP) && (rstat->rstat1 & RSTAT1_RFP)); + struct ep93xx_rstat *rstat; + int tail_offset; + + rstat = ep->descs->rstat + ep->rx_pointer; + tail_offset = rdl(ep, REG_RXSTSQCURADD) - ep->descs_dma_addr; + + return !((void *)rstat - (void *)ep->descs == tail_offset); } static int ep93xx_poll(struct net_device *dev, int *budget) @@ -331,7 +347,7 @@ static int ep93xx_xmit(struct sk_buff *skb, struct net_device *dev) struct ep93xx_priv *ep = netdev_priv(dev); int entry; - if (unlikely(skb->len > MAX_PKT_SIZE)) { + if (unlikely(skb->len) > MAX_PKT_SIZE) { ep->stats.tx_dropped++; dev_kfree_skb(skb); return NETDEV_TX_OK; @@ -363,8 +379,10 @@ static int ep93xx_xmit(struct sk_buff *skb, struct net_device *dev) static void ep93xx_tx_complete(struct net_device *dev) { struct ep93xx_priv *ep = netdev_priv(dev); + int tail_offset; int wake; + tail_offset = rdl(ep, REG_TXSTSQCURADD) - ep->descs_dma_addr; wake = 0; spin_lock(&ep->tx_pending_lock); @@ -375,13 +393,15 @@ static void ep93xx_tx_complete(struct net_device *dev) entry = ep->tx_clean_pointer; tstat = ep->descs->tstat + entry; - - tstat0 = tstat->tstat0; - if (!(tstat0 & TSTAT0_TXFP)) + if ((void *)tstat - (void *)ep->descs == tail_offset) break; + tstat0 = tstat->tstat0; tstat->tstat0 = 0; + if (!(tstat0 & TSTAT0_TXFP)) + printk(KERN_CRIT "ep93xx_tx_complete: buffer not done " + " %.8x\n", tstat0); if (tstat0 & TSTAT0_FA) printk(KERN_CRIT "ep93xx_tx_complete: frame aborted " " %.8x\n", tstat0); @@ -415,7 +435,7 @@ static void ep93xx_tx_complete(struct net_device *dev) netif_wake_queue(dev); } -static irqreturn_t ep93xx_irq(int irq, void *dev_id) +static irqreturn_t ep93xx_irq(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; struct ep93xx_priv *ep = netdev_priv(dev); diff --git a/trunk/drivers/net/arm/ether1.c b/trunk/drivers/net/arm/ether1.c index f3478a30e778..312955d07b28 100644 --- a/trunk/drivers/net/arm/ether1.c +++ b/trunk/drivers/net/arm/ether1.c @@ -68,7 +68,7 @@ static unsigned int net_debug = NET_DEBUG; static int ether1_open(struct net_device *dev); static int ether1_sendpacket(struct sk_buff *skb, struct net_device *dev); -static irqreturn_t ether1_interrupt(int irq, void *dev_id); +static irqreturn_t ether1_interrupt(int irq, void *dev_id, struct pt_regs *regs); static int ether1_close(struct net_device *dev); static struct net_device_stats *ether1_getstats(struct net_device *dev); static void ether1_setmulticastlist(struct net_device *dev); @@ -908,7 +908,7 @@ ether1_recv_done (struct net_device *dev) } static irqreturn_t -ether1_interrupt (int irq, void *dev_id) +ether1_interrupt (int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *)dev_id; int status; diff --git a/trunk/drivers/net/arm/ether3.c b/trunk/drivers/net/arm/ether3.c index 84686c8a5bc2..081074180e62 100644 --- a/trunk/drivers/net/arm/ether3.c +++ b/trunk/drivers/net/arm/ether3.c @@ -81,7 +81,7 @@ static int ether3_rx(struct net_device *dev, unsigned int maxcnt); static void ether3_tx(struct net_device *dev); static int ether3_open (struct net_device *dev); static int ether3_sendpacket (struct sk_buff *skb, struct net_device *dev); -static irqreturn_t ether3_interrupt (int irq, void *dev_id); +static irqreturn_t ether3_interrupt (int irq, void *dev_id, struct pt_regs *regs); static int ether3_close (struct net_device *dev); static struct net_device_stats *ether3_getstats (struct net_device *dev); static void ether3_setmulticastlist (struct net_device *dev); @@ -568,7 +568,7 @@ ether3_sendpacket(struct sk_buff *skb, struct net_device *dev) } static irqreturn_t -ether3_interrupt(int irq, void *dev_id) +ether3_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *)dev_id; unsigned int status, handled = IRQ_NONE; diff --git a/trunk/drivers/net/at1700.c b/trunk/drivers/net/at1700.c index 8620a5b470f5..4aeca11f3ee2 100644 --- a/trunk/drivers/net/at1700.c +++ b/trunk/drivers/net/at1700.c @@ -161,7 +161,7 @@ static int at1700_probe1(struct net_device *dev, int ioaddr); static int read_eeprom(long ioaddr, int location); static int net_open(struct net_device *dev); static int net_send_packet(struct sk_buff *skb, struct net_device *dev); -static irqreturn_t net_interrupt(int irq, void *dev_id); +static irqreturn_t net_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void net_rx(struct net_device *dev); static int net_close(struct net_device *dev); static struct net_device_stats *net_get_stats(struct net_device *dev); @@ -648,7 +648,8 @@ static int net_send_packet (struct sk_buff *skb, struct net_device *dev) /* The typical workload of the driver: Handle the network interface interrupts. */ -static irqreturn_t net_interrupt(int irq, void *dev_id) +static irqreturn_t +net_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; struct net_local *lp; diff --git a/trunk/drivers/net/atari_bionet.c b/trunk/drivers/net/atari_bionet.c index 4e3bf6a1f22c..92b52138acad 100644 --- a/trunk/drivers/net/atari_bionet.c +++ b/trunk/drivers/net/atari_bionet.c @@ -220,7 +220,7 @@ get_status(unsigned char *adr) { } static irqreturn_t -bionet_intr(int irq, void *data) { +bionet_intr(int irq, void *data, struct pt_regs *fp) { return IRQ_HANDLED; } diff --git a/trunk/drivers/net/atari_pamsnet.c b/trunk/drivers/net/atari_pamsnet.c index 3b5436149286..a1026251b933 100644 --- a/trunk/drivers/net/atari_pamsnet.c +++ b/trunk/drivers/net/atari_pamsnet.c @@ -163,7 +163,7 @@ static int pamsnet_close(struct net_device *dev); static struct net_device_stats *net_get_stats(struct net_device *dev); static void pamsnet_tick(unsigned long); -static irqreturn_t pamsnet_intr(int irq, void *data); +static irqreturn_t pamsnet_intr(int irq, void *data, struct pt_regs *fp); static DEFINE_TIMER(pamsnet_timer, pamsnet_tick, 0, 0); @@ -494,6 +494,7 @@ static irqreturn_t pamsnet_intr(irq, data, fp) int irq; void *data; + struct pt_regs *fp; { return IRQ_HANDLED; } diff --git a/trunk/drivers/net/atarilance.c b/trunk/drivers/net/atarilance.c index d79489e46249..b6570ca6ada7 100644 --- a/trunk/drivers/net/atarilance.c +++ b/trunk/drivers/net/atarilance.c @@ -344,7 +344,7 @@ static unsigned long lance_probe1( struct net_device *dev, struct lance_addr static int lance_open( struct net_device *dev ); static void lance_init_ring( struct net_device *dev ); static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev ); -static irqreturn_t lance_interrupt( int irq, void *dev_id ); +static irqreturn_t lance_interrupt( int irq, void *dev_id, struct pt_regs *fp ); static int lance_rx( struct net_device *dev ); static int lance_close( struct net_device *dev ); static struct net_device_stats *lance_get_stats( struct net_device *dev ); @@ -866,7 +866,7 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev ) /* The LANCE interrupt handler. */ -static irqreturn_t lance_interrupt( int irq, void *dev_id ) +static irqreturn_t lance_interrupt( int irq, void *dev_id, struct pt_regs *fp) { struct net_device *dev = dev_id; struct lance_private *lp; diff --git a/trunk/drivers/net/atp.c b/trunk/drivers/net/atp.c index 2d306fcb7f36..f2c8e0d5497b 100644 --- a/trunk/drivers/net/atp.c +++ b/trunk/drivers/net/atp.c @@ -203,7 +203,7 @@ static void hardware_init(struct net_device *dev); static void write_packet(long ioaddr, int length, unsigned char *packet, int pad, int mode); static void trigger_send(long ioaddr, int length); static int atp_send_packet(struct sk_buff *skb, struct net_device *dev); -static irqreturn_t atp_interrupt(int irq, void *dev_id); +static irqreturn_t atp_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void net_rx(struct net_device *dev); static void read_block(long ioaddr, int length, unsigned char *buffer, int data_mode); static int net_close(struct net_device *dev); @@ -596,15 +596,20 @@ static int atp_send_packet(struct sk_buff *skb, struct net_device *dev) /* The typical workload of the driver: Handle the network interface interrupts. */ -static irqreturn_t atp_interrupt(int irq, void *dev_instance) +static irqreturn_t +atp_interrupt(int irq, void *dev_instance, struct pt_regs * regs) { - struct net_device *dev = dev_instance; + struct net_device *dev = (struct net_device *)dev_instance; struct net_local *lp; long ioaddr; static int num_tx_since_rx; int boguscount = max_interrupt_work; int handled = 0; + if (dev == NULL) { + printk(KERN_ERR "ATP_interrupt(): irq %d for unknown device.\n", irq); + return IRQ_NONE; + } ioaddr = dev->base_addr; lp = netdev_priv(dev); diff --git a/trunk/drivers/net/au1000_eth.c b/trunk/drivers/net/au1000_eth.c index 7db3c8af0894..ac33b1b9cf4a 100644 --- a/trunk/drivers/net/au1000_eth.c +++ b/trunk/drivers/net/au1000_eth.c @@ -89,7 +89,7 @@ static int au1000_open(struct net_device *); static int au1000_close(struct net_device *); static int au1000_tx(struct sk_buff *, struct net_device *); static int au1000_rx(struct net_device *); -static irqreturn_t au1000_interrupt(int, void *); +static irqreturn_t au1000_interrupt(int, void *, struct pt_regs *); static void au1000_tx_timeout(struct net_device *); static void set_rx_mode(struct net_device *); static struct net_device_stats *au1000_get_stats(struct net_device *); @@ -102,7 +102,7 @@ static void enable_mac(struct net_device *, int); // externs extern int get_ethernet_addr(char *ethernet_addr); extern void str2eaddr(unsigned char *ea, unsigned char *str); -extern char * prom_getcmdline(void); +extern char * __init prom_getcmdline(void); /* * Theory of operation @@ -1253,7 +1253,7 @@ static int au1000_rx(struct net_device *dev) /* * Au1000 interrupt service routine. */ -static irqreturn_t au1000_interrupt(int irq, void *dev_id) +static irqreturn_t au1000_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_id; diff --git a/trunk/drivers/net/b44.c b/trunk/drivers/net/b44.c index 474a4e3438db..e891ea2ecc3c 100644 --- a/trunk/drivers/net/b44.c +++ b/trunk/drivers/net/b44.c @@ -896,7 +896,7 @@ static int b44_poll(struct net_device *netdev, int *budget) return (done ? 0 : 1); } -static irqreturn_t b44_interrupt(int irq, void *dev_id) +static irqreturn_t b44_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; struct b44 *bp = netdev_priv(dev); @@ -908,9 +908,8 @@ static irqreturn_t b44_interrupt(int irq, void *dev_id) istat = br32(bp, B44_ISTAT); imask = br32(bp, B44_IMASK); - /* The interrupt mask register controls which interrupt bits - * will actually raise an interrupt to the CPU when set by hw/firmware, - * but doesn't mask off the bits. + /* ??? What the fuck is the purpose of the interrupt mask + * ??? register if we have to mask it out by hand anyways? */ istat &= imask; if (istat) { @@ -1462,7 +1461,7 @@ static int b44_open(struct net_device *dev) static void b44_poll_controller(struct net_device *dev) { disable_irq(dev->irq); - b44_interrupt(dev->irq, dev); + b44_interrupt(dev->irq, dev, NULL); enable_irq(dev->irq); } #endif @@ -1707,15 +1706,14 @@ static void __b44_set_rx_mode(struct net_device *dev) __b44_set_mac_addr(bp); - if ((dev->flags & IFF_ALLMULTI) || - (dev->mc_count > B44_MCAST_TABLE_SIZE)) + if (dev->flags & IFF_ALLMULTI) val |= RXCONFIG_ALLMULTI; else i = __b44_load_mcast(bp, dev); - for (; i < 64; i++) + for (; i < 64; i++) { __b44_cam_write(bp, zero, i); - + } bw32(bp, B44_RXCONFIG, val); val = br32(bp, B44_CAM_CTRL); bw32(bp, B44_CAM_CTRL, val | CAM_CTRL_ENABLE); @@ -2057,7 +2055,7 @@ static int b44_read_eeprom(struct b44 *bp, u8 *data) u16 *ptr = (u16 *) data; for (i = 0; i < 128; i += 2) - ptr[i / 2] = cpu_to_le16(readw(bp->regs + 4096 + i)); + ptr[i / 2] = readw(bp->regs + 4096 + i); return 0; } diff --git a/trunk/drivers/net/bmac.c b/trunk/drivers/net/bmac.c index 4528ce9c4e43..4adfe7b77031 100644 --- a/trunk/drivers/net/bmac.c +++ b/trunk/drivers/net/bmac.c @@ -152,9 +152,9 @@ static void bmac_init_chip(struct net_device *dev); static void bmac_init_registers(struct net_device *dev); static void bmac_enable_and_reset_chip(struct net_device *dev); static int bmac_set_address(struct net_device *dev, void *addr); -static irqreturn_t bmac_misc_intr(int irq, void *dev_id); -static irqreturn_t bmac_txdma_intr(int irq, void *dev_id); -static irqreturn_t bmac_rxdma_intr(int irq, void *dev_id); +static irqreturn_t bmac_misc_intr(int irq, void *dev_id, struct pt_regs *regs); +static irqreturn_t bmac_txdma_intr(int irq, void *dev_id, struct pt_regs *regs); +static irqreturn_t bmac_rxdma_intr(int irq, void *dev_id, struct pt_regs *regs); static void bmac_set_timeout(struct net_device *dev); static void bmac_tx_timeout(unsigned long data); static int bmac_output(struct sk_buff *skb, struct net_device *dev); @@ -688,7 +688,7 @@ static int bmac_transmit_packet(struct sk_buff *skb, struct net_device *dev) static int rxintcount; -static irqreturn_t bmac_rxdma_intr(int irq, void *dev_id) +static irqreturn_t bmac_rxdma_intr(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_id; struct bmac_data *bp = netdev_priv(dev); @@ -765,7 +765,7 @@ static irqreturn_t bmac_rxdma_intr(int irq, void *dev_id) static int txintcount; -static irqreturn_t bmac_txdma_intr(int irq, void *dev_id) +static irqreturn_t bmac_txdma_intr(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_id; struct bmac_data *bp = netdev_priv(dev); @@ -1082,7 +1082,7 @@ static void bmac_set_multicast(struct net_device *dev) static int miscintcount; -static irqreturn_t bmac_misc_intr(int irq, void *dev_id) +static irqreturn_t bmac_misc_intr(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_id; struct bmac_data *bp = netdev_priv(dev); @@ -1091,7 +1091,7 @@ static irqreturn_t bmac_misc_intr(int irq, void *dev_id) XXDEBUG(("bmac_misc_intr\n")); } /* XXDEBUG(("bmac_misc_intr, status=%#08x\n", status)); */ - /* bmac_txdma_intr_inner(irq, dev_id); */ + /* bmac_txdma_intr_inner(irq, dev_id, regs); */ /* if (status & FrameReceived) bp->stats.rx_dropped++; */ if (status & RxErrorMask) bp->stats.rx_errors++; if (status & RxCRCCntExp) bp->stats.rx_crc_errors++; diff --git a/trunk/drivers/net/bnx2.c b/trunk/drivers/net/bnx2.c index 01b76d3aa42f..6b4edb63c4c4 100644 --- a/trunk/drivers/net/bnx2.c +++ b/trunk/drivers/net/bnx2.c @@ -1888,7 +1888,7 @@ bnx2_rx_int(struct bnx2 *bp, int budget) * is that the MSI interrupt is always serviced. */ static irqreturn_t -bnx2_msi(int irq, void *dev_instance) +bnx2_msi(int irq, void *dev_instance, struct pt_regs *regs) { struct net_device *dev = dev_instance; struct bnx2 *bp = netdev_priv(dev); @@ -1908,7 +1908,7 @@ bnx2_msi(int irq, void *dev_instance) } static irqreturn_t -bnx2_interrupt(int irq, void *dev_instance) +bnx2_interrupt(int irq, void *dev_instance, struct pt_regs *regs) { struct net_device *dev = dev_instance; struct bnx2 *bp = netdev_priv(dev); @@ -5554,7 +5554,7 @@ poll_bnx2(struct net_device *dev) struct bnx2 *bp = netdev_priv(dev); disable_irq(bp->pdev->irq); - bnx2_interrupt(bp->pdev->irq, dev); + bnx2_interrupt(bp->pdev->irq, dev, NULL); enable_irq(bp->pdev->irq); } #endif diff --git a/trunk/drivers/net/bonding/bond_alb.c b/trunk/drivers/net/bonding/bond_alb.c index 32923162179e..e83bc825f6af 100644 --- a/trunk/drivers/net/bonding/bond_alb.c +++ b/trunk/drivers/net/bonding/bond_alb.c @@ -1433,7 +1433,7 @@ void bond_alb_monitor(struct bonding *bond) * write lock to protect from other code that also * sets the promiscuity. */ - write_lock_bh(&bond->curr_slave_lock); + write_lock(&bond->curr_slave_lock); if (bond_info->primary_is_promisc && (++bond_info->rlb_promisc_timeout_counter >= RLB_PROMISC_TIMEOUT)) { @@ -1448,7 +1448,7 @@ void bond_alb_monitor(struct bonding *bond) bond_info->primary_is_promisc = 0; } - write_unlock_bh(&bond->curr_slave_lock); + write_unlock(&bond->curr_slave_lock); if (bond_info->rlb_rebalance) { bond_info->rlb_rebalance = 0; diff --git a/trunk/drivers/net/bonding/bond_main.c b/trunk/drivers/net/bonding/bond_main.c index 17a461152d39..c0bbddae4ec4 100644 --- a/trunk/drivers/net/bonding/bond_main.c +++ b/trunk/drivers/net/bonding/bond_main.c @@ -4692,8 +4692,6 @@ static int bond_check_params(struct bond_params *params) return 0; } -static struct lock_class_key bonding_netdev_xmit_lock_key; - /* Create a new bond based on the specified name and bonding parameters. * Caller must NOT hold rtnl_lock; we need to release it here before we * set up our sysfs entries. @@ -4729,9 +4727,6 @@ int bond_create(char *name, struct bond_params *params, struct bonding **newbond if (res < 0) { goto out_bond; } - - lockdep_set_class(&bond_dev->_xmit_lock, &bonding_netdev_xmit_lock_key); - if (newbond) *newbond = bond_dev->priv; diff --git a/trunk/drivers/net/cassini.c b/trunk/drivers/net/cassini.c index 521c5b71023c..7694365092f8 100644 --- a/trunk/drivers/net/cassini.c +++ b/trunk/drivers/net/cassini.c @@ -2469,7 +2469,7 @@ static inline void cas_handle_irqN(struct net_device *dev, cas_post_rxcs_ringN(dev, cp, ring); } -static irqreturn_t cas_interruptN(int irq, void *dev_id) +static irqreturn_t cas_interruptN(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; struct cas *cp = netdev_priv(dev); @@ -2522,7 +2522,7 @@ static inline void cas_handle_irq1(struct cas *cp, const u32 status) } /* ring 2 handles a few more events than 3 and 4 */ -static irqreturn_t cas_interrupt1(int irq, void *dev_id) +static irqreturn_t cas_interrupt1(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; struct cas *cp = netdev_priv(dev); @@ -2574,7 +2574,7 @@ static inline void cas_handle_irq(struct net_device *dev, cas_post_rxcs_ringN(dev, cp, 0); } -static irqreturn_t cas_interrupt(int irq, void *dev_id) +static irqreturn_t cas_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; struct cas *cp = netdev_priv(dev); @@ -2689,7 +2689,7 @@ static void cas_netpoll(struct net_device *dev) struct cas *cp = netdev_priv(dev); cas_disable_irq(cp, 0); - cas_interrupt(cp->pdev->irq, dev); + cas_interrupt(cp->pdev->irq, dev, NULL); cas_enable_irq(cp, 0); #ifdef USE_PCI_INTB diff --git a/trunk/drivers/net/chelsio/cpl5_cmd.h b/trunk/drivers/net/chelsio/cpl5_cmd.h index 5b357d9e88d6..27925e487bcf 100644 --- a/trunk/drivers/net/chelsio/cpl5_cmd.h +++ b/trunk/drivers/net/chelsio/cpl5_cmd.h @@ -108,7 +108,7 @@ struct cpl_tx_pkt_lso { u8 iff:4; #endif u16 vlan; - __be32 len; + u32 len; u32 rsvd2; u8 rsvd3; @@ -119,7 +119,7 @@ struct cpl_tx_pkt_lso { u8 ip_hdr_words:4; u8 tcp_hdr_words:4; #endif - __be16 eth_type_mss; + u16 eth_type_mss; }; struct cpl_rx_pkt { @@ -138,7 +138,7 @@ struct cpl_rx_pkt { u8 iff:4; #endif u16 csum; - __be16 vlan; + u16 vlan; u16 len; }; diff --git a/trunk/drivers/net/chelsio/cxgb2.c b/trunk/drivers/net/chelsio/cxgb2.c index ad7ff9641a7e..5f1b06753462 100644 --- a/trunk/drivers/net/chelsio/cxgb2.c +++ b/trunk/drivers/net/chelsio/cxgb2.c @@ -918,7 +918,7 @@ static void t1_netpoll(struct net_device *dev) struct adapter *adapter = dev->priv; local_irq_save(flags); - t1_select_intr_handler(adapter)(adapter->pdev->irq, adapter); + t1_select_intr_handler(adapter)(adapter->pdev->irq, adapter, NULL); local_irq_restore(flags); } #endif diff --git a/trunk/drivers/net/chelsio/sge.c b/trunk/drivers/net/chelsio/sge.c index 9799c12380fc..ddd0bdb498f4 100644 --- a/trunk/drivers/net/chelsio/sge.c +++ b/trunk/drivers/net/chelsio/sge.c @@ -1217,7 +1217,7 @@ static inline int napi_is_scheduled(struct net_device *dev) /* * NAPI version of the main interrupt handler. */ -static irqreturn_t t1_interrupt_napi(int irq, void *data) +static irqreturn_t t1_interrupt_napi(int irq, void *data, struct pt_regs *regs) { int handled; struct adapter *adapter = data; @@ -1279,7 +1279,7 @@ static irqreturn_t t1_interrupt_napi(int irq, void *data) * 5. If we took an interrupt, but no valid respQ descriptors was found we * let the slow_intr_handler run and do error handling. */ -static irqreturn_t t1_interrupt(int irq, void *cookie) +static irqreturn_t t1_interrupt(int irq, void *cookie, struct pt_regs *regs) { int work_done; struct respQ_e *e; @@ -1312,7 +1312,7 @@ static irqreturn_t t1_interrupt(int irq, void *cookie) return IRQ_RETVAL(work_done != 0); } -irq_handler_t t1_select_intr_handler(adapter_t *adapter) +intr_handler_t t1_select_intr_handler(adapter_t *adapter) { return adapter->params.sge.polling ? t1_interrupt_napi : t1_interrupt; } diff --git a/trunk/drivers/net/chelsio/sge.h b/trunk/drivers/net/chelsio/sge.h index 91af47bab7be..6d0d24a6364f 100644 --- a/trunk/drivers/net/chelsio/sge.h +++ b/trunk/drivers/net/chelsio/sge.h @@ -43,6 +43,13 @@ #include #include +#ifndef IRQ_RETVAL +#define IRQ_RETVAL(x) +typedef void irqreturn_t; +#endif + +typedef irqreturn_t (*intr_handler_t)(int, void *, struct pt_regs *); + struct sge_intr_counts { unsigned int respQ_empty; /* # times respQ empty */ unsigned int respQ_overflow; /* # respQ overflow (fatal) */ @@ -81,7 +88,7 @@ struct sge *t1_sge_create(struct adapter *, struct sge_params *); int t1_sge_configure(struct sge *, struct sge_params *); int t1_sge_set_coalesce_params(struct sge *, struct sge_params *); void t1_sge_destroy(struct sge *); -irq_handler_t t1_select_intr_handler(adapter_t *adapter); +intr_handler_t t1_select_intr_handler(adapter_t *adapter); int t1_start_xmit(struct sk_buff *skb, struct net_device *dev); void t1_set_vlan_accel(struct adapter *adapter, int on_off); void t1_sge_start(struct sge *); diff --git a/trunk/drivers/net/cris/eth_v10.c b/trunk/drivers/net/cris/eth_v10.c index a03d781f6d0a..f1501b6f247e 100644 --- a/trunk/drivers/net/cris/eth_v10.c +++ b/trunk/drivers/net/cris/eth_v10.c @@ -403,8 +403,8 @@ static int etrax_ethernet_init(void); static int e100_open(struct net_device *dev); static int e100_set_mac_address(struct net_device *dev, void *addr); static int e100_send_packet(struct sk_buff *skb, struct net_device *dev); -static irqreturn_t e100rxtx_interrupt(int irq, void *dev_id); -static irqreturn_t e100nw_interrupt(int irq, void *dev_id); +static irqreturn_t e100rxtx_interrupt(int irq, void *dev_id, struct pt_regs *regs); +static irqreturn_t e100nw_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void e100_rx(struct net_device *dev); static int e100_close(struct net_device *dev); static int e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); @@ -509,8 +509,6 @@ etrax_ethernet_init(void) * does not share cacheline with any other data (to avoid cache bug) */ RxDescList[i].skb = dev_alloc_skb(MAX_MEDIA_DATA_SIZE + 2 * L1_CACHE_BYTES); - if (!RxDescList[i].skb) - return -ENOMEM; RxDescList[i].descr.ctrl = 0; RxDescList[i].descr.sw_len = MAX_MEDIA_DATA_SIZE; RxDescList[i].descr.next = virt_to_phys(&RxDescList[i + 1]); @@ -1199,7 +1197,7 @@ e100_send_packet(struct sk_buff *skb, struct net_device *dev) */ static irqreturn_t -e100rxtx_interrupt(int irq, void *dev_id) +e100rxtx_interrupt(int irq, void *dev_id, struct pt_regs * regs) { struct net_device *dev = (struct net_device *)dev_id; struct net_local *np = (struct net_local *)dev->priv; @@ -1266,7 +1264,7 @@ e100rxtx_interrupt(int irq, void *dev_id) } static irqreturn_t -e100nw_interrupt(int irq, void *dev_id) +e100nw_interrupt(int irq, void *dev_id, struct pt_regs * regs) { struct net_device *dev = (struct net_device *)dev_id; struct net_local *np = (struct net_local *)dev->priv; diff --git a/trunk/drivers/net/cs89x0.c b/trunk/drivers/net/cs89x0.c index 4ffc9b44a8e1..e4d50f0de930 100644 --- a/trunk/drivers/net/cs89x0.c +++ b/trunk/drivers/net/cs89x0.c @@ -249,7 +249,7 @@ struct net_local { static int cs89x0_probe1(struct net_device *dev, int ioaddr, int modular); static int net_open(struct net_device *dev); static int net_send_packet(struct sk_buff *skb, struct net_device *dev); -static irqreturn_t net_interrupt(int irq, void *dev_id); +static irqreturn_t net_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void set_multicast_list(struct net_device *dev); static void net_timeout(struct net_device *dev); static void net_rx(struct net_device *dev); @@ -495,7 +495,7 @@ get_eeprom_cksum(int off, int len, int *buffer) static void net_poll_controller(struct net_device *dev) { disable_irq(dev->irq); - net_interrupt(dev->irq, dev); + net_interrupt(dev->irq, dev, NULL); enable_irq(dev->irq); } #endif @@ -1573,7 +1573,7 @@ static int net_send_packet(struct sk_buff *skb, struct net_device *dev) /* The typical workload of the driver: Handle the network interface interrupts. */ -static irqreturn_t net_interrupt(int irq, void *dev_id) +static irqreturn_t net_interrupt(int irq, void *dev_id, struct pt_regs * regs) { struct net_device *dev = dev_id; struct net_local *lp; diff --git a/trunk/drivers/net/de600.c b/trunk/drivers/net/de600.c index 690bb40b353d..0b930da5d47d 100644 --- a/trunk/drivers/net/de600.c +++ b/trunk/drivers/net/de600.c @@ -258,13 +258,19 @@ static int de600_start_xmit(struct sk_buff *skb, struct net_device *dev) * Handle the network interface interrupts. */ -static irqreturn_t de600_interrupt(int irq, void *dev_id) +static irqreturn_t de600_interrupt(int irq, void *dev_id, struct pt_regs * regs) { struct net_device *dev = dev_id; u8 irq_status; int retrig = 0; int boguscount = 0; + /* This might just as well be deleted now, no crummy drivers present :-) */ + if ((dev == NULL) || (DE600_IRQ != irq)) { + printk(KERN_ERR "%s: bogus interrupt %d\n", dev?dev->name:"DE-600", irq); + return IRQ_NONE; + } + spin_lock(&de600_lock); select_nic(); diff --git a/trunk/drivers/net/de600.h b/trunk/drivers/net/de600.h index 1288e48ba704..e4073015dcd8 100644 --- a/trunk/drivers/net/de600.h +++ b/trunk/drivers/net/de600.h @@ -125,7 +125,7 @@ static struct net_device_stats *get_stats(struct net_device *dev); static int de600_start_xmit(struct sk_buff *skb, struct net_device *dev); /* Dispatch from interrupts. */ -static irqreturn_t de600_interrupt(int irq, void *dev_id); +static irqreturn_t de600_interrupt(int irq, void *dev_id, struct pt_regs *regs); static int de600_tx_intr(struct net_device *dev, int irq_status); static void de600_rx_intr(struct net_device *dev); diff --git a/trunk/drivers/net/de620.c b/trunk/drivers/net/de620.c index b6ad0cb50552..a18d4d14b665 100644 --- a/trunk/drivers/net/de620.c +++ b/trunk/drivers/net/de620.c @@ -221,7 +221,7 @@ static void de620_set_multicast_list(struct net_device *); static int de620_start_xmit(struct sk_buff *, struct net_device *); /* Dispatch from interrupts. */ -static irqreturn_t de620_interrupt(int, void *); +static irqreturn_t de620_interrupt(int, void *, struct pt_regs *); static int de620_rx_intr(struct net_device *); /* Initialization */ @@ -591,7 +591,7 @@ static int de620_start_xmit(struct sk_buff *skb, struct net_device *dev) * */ static irqreturn_t -de620_interrupt(int irq_in, void *dev_id) +de620_interrupt(int irq_in, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; byte irq_status; diff --git a/trunk/drivers/net/declance.c b/trunk/drivers/net/declance.c index 00e2a8a134d7..bbccd741cdbf 100644 --- a/trunk/drivers/net/declance.c +++ b/trunk/drivers/net/declance.c @@ -694,17 +694,19 @@ static void lance_tx(struct net_device *dev) spin_unlock(&lp->lock); } -static irqreturn_t lance_dma_merr_int(const int irq, void *dev_id) +static irqreturn_t lance_dma_merr_int(const int irq, void *dev_id, + struct pt_regs *regs) { - struct net_device *dev = dev_id; + struct net_device *dev = (struct net_device *) dev_id; printk("%s: DMA error\n", dev->name); return IRQ_HANDLED; } -static irqreturn_t lance_interrupt(const int irq, void *dev_id) +static irqreturn_t lance_interrupt(const int irq, void *dev_id, + struct pt_regs *regs) { - struct net_device *dev = dev_id; + struct net_device *dev = (struct net_device *) dev_id; struct lance_private *lp = netdev_priv(dev); volatile struct lance_regs *ll = lp->ll; int csr0; diff --git a/trunk/drivers/net/defxx.c b/trunk/drivers/net/defxx.c index 8f514cc0debd..ae9680552b82 100644 --- a/trunk/drivers/net/defxx.c +++ b/trunk/drivers/net/defxx.c @@ -248,7 +248,8 @@ static int dfx_close(struct net_device *dev); static void dfx_int_pr_halt_id(DFX_board_t *bp); static void dfx_int_type_0_process(DFX_board_t *bp); static void dfx_int_common(struct net_device *dev); -static irqreturn_t dfx_interrupt(int irq, void *dev_id); +static irqreturn_t dfx_interrupt(int irq, void *dev_id, + struct pt_regs *regs); static struct net_device_stats *dfx_ctl_get_stats(struct net_device *dev); static void dfx_ctl_set_multicast_list(struct net_device *dev); @@ -1692,6 +1693,7 @@ static void dfx_int_common(struct net_device *dev) * Arguments: * irq - interrupt vector * dev_id - pointer to device information + * regs - pointer to registers structure * * Functional Description: * This routine calls the interrupt processing routine for this adapter. It @@ -1714,7 +1716,7 @@ static void dfx_int_common(struct net_device *dev) * Interrupts are disabled, then reenabled at the adapter. */ -static irqreturn_t dfx_interrupt(int irq, void *dev_id) +static irqreturn_t dfx_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; DFX_board_t *bp; /* private board structure pointer */ diff --git a/trunk/drivers/net/depca.c b/trunk/drivers/net/depca.c index f87f6e3dc721..af594664df51 100644 --- a/trunk/drivers/net/depca.c +++ b/trunk/drivers/net/depca.c @@ -518,7 +518,7 @@ struct depca_private { */ static int depca_open(struct net_device *dev); static int depca_start_xmit(struct sk_buff *skb, struct net_device *dev); -static irqreturn_t depca_interrupt(int irq, void *dev_id); +static irqreturn_t depca_interrupt(int irq, void *dev_id, struct pt_regs *regs); static int depca_close(struct net_device *dev); static int depca_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); static void depca_tx_timeout(struct net_device *dev); @@ -965,7 +965,7 @@ static int depca_start_xmit(struct sk_buff *skb, struct net_device *dev) /* ** The DEPCA interrupt handler. */ -static irqreturn_t depca_interrupt(int irq, void *dev_id) +static irqreturn_t depca_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; struct depca_private *lp; diff --git a/trunk/drivers/net/dgrs.c b/trunk/drivers/net/dgrs.c index a79520295fd0..d0842527b369 100644 --- a/trunk/drivers/net/dgrs.c +++ b/trunk/drivers/net/dgrs.c @@ -895,10 +895,10 @@ static int dgrs_ioctl(struct net_device *devN, struct ifreq *ifr, int cmd) * dev, priv will always refer to the 0th device in Multi-NIC mode. */ -static irqreturn_t dgrs_intr(int irq, void *dev_id) +static irqreturn_t dgrs_intr(int irq, void *dev_id, struct pt_regs *regs) { - struct net_device *dev0 = dev_id; - DGRS_PRIV *priv0 = dev0->priv; + struct net_device *dev0 = (struct net_device *) dev_id; + DGRS_PRIV *priv0 = (DGRS_PRIV *) dev0->priv; I596_CB *cbp; int cmd; int i; diff --git a/trunk/drivers/net/dl2k.c b/trunk/drivers/net/dl2k.c index 9d446a0fe0bf..7e95cf1a4872 100644 --- a/trunk/drivers/net/dl2k.c +++ b/trunk/drivers/net/dl2k.c @@ -60,7 +60,7 @@ static void rio_timer (unsigned long data); static void rio_tx_timeout (struct net_device *dev); static void alloc_list (struct net_device *dev); static int start_xmit (struct sk_buff *skb, struct net_device *dev); -static irqreturn_t rio_interrupt (int irq, void *dev_instance); +static irqreturn_t rio_interrupt (int irq, void *dev_instance, struct pt_regs *regs); static void rio_free_tx (struct net_device *dev, int irq); static void tx_error (struct net_device *dev, int tx_status); static int receive_packet (struct net_device *dev); @@ -665,7 +665,7 @@ start_xmit (struct sk_buff *skb, struct net_device *dev) } static irqreturn_t -rio_interrupt (int irq, void *dev_instance) +rio_interrupt (int irq, void *dev_instance, struct pt_regs *rgs) { struct net_device *dev = dev_instance; struct netdev_private *np; diff --git a/trunk/drivers/net/dm9000.c b/trunk/drivers/net/dm9000.c index 615d2b14efa7..a860ebbbf815 100644 --- a/trunk/drivers/net/dm9000.c +++ b/trunk/drivers/net/dm9000.c @@ -159,7 +159,7 @@ static void dm9000_init_dm9000(struct net_device *); static struct net_device_stats *dm9000_get_stats(struct net_device *); -static irqreturn_t dm9000_interrupt(int, void *); +static irqreturn_t dm9000_interrupt(int, void *, struct pt_regs *); static int dm9000_phy_read(struct net_device *dev, int phyaddr_unsused, int reg); static void dm9000_phy_write(struct net_device *dev, int phyaddr_unused, int reg, @@ -346,7 +346,7 @@ static void dm9000_timeout(struct net_device *dev) static void dm9000_poll_controller(struct net_device *dev) { disable_irq(dev->irq); - dm9000_interrupt(dev->irq,dev); + dm9000_interrupt(dev->irq,dev,NULL); enable_irq(dev->irq); } #endif @@ -804,7 +804,7 @@ dm9000_tx_done(struct net_device *dev, board_info_t * db) } static irqreturn_t -dm9000_interrupt(int irq, void *dev_id) +dm9000_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; board_info_t *db; diff --git a/trunk/drivers/net/e100.c b/trunk/drivers/net/e100.c index 3a8df479cbda..26073c345213 100644 --- a/trunk/drivers/net/e100.c +++ b/trunk/drivers/net/e100.c @@ -1215,7 +1215,7 @@ static void e100_setup_ucode(struct nic *nic, struct cb *cb, struct sk_buff *skb * the literal in the instruction before the code is loaded, the * driver can change the algorithm. * -* INTDELAY - This loads the dead-man timer with its initial value. +* INTDELAY - This loads the dead-man timer with its inital value. * When this timer expires the interrupt is asserted, and the * timer is reset each time a new packet is received. (see * BUNDLEMAX below to set the limit on number of chained packets) @@ -1949,7 +1949,7 @@ static int e100_rx_alloc_list(struct nic *nic) return 0; } -static irqreturn_t e100_intr(int irq, void *dev_id) +static irqreturn_t e100_intr(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *netdev = dev_id; struct nic *nic = netdev_priv(netdev); @@ -2005,7 +2005,7 @@ static void e100_netpoll(struct net_device *netdev) struct nic *nic = netdev_priv(netdev); e100_disable_irq(nic); - e100_intr(nic->pdev->irq, netdev); + e100_intr(nic->pdev->irq, netdev, NULL); e100_tx_clean(nic); e100_enable_irq(nic); } @@ -2039,6 +2039,7 @@ static int e100_change_mtu(struct net_device *netdev, int new_mtu) return 0; } +#ifdef CONFIG_PM static int e100_asf(struct nic *nic) { /* ASF can be enabled from eeprom */ @@ -2047,6 +2048,7 @@ static int e100_asf(struct nic *nic) !(nic->eeprom[eeprom_config_asf] & eeprom_gcl) && ((nic->eeprom[eeprom_smbus_addr] & 0xFF) != 0xFE)); } +#endif static int e100_up(struct nic *nic) { @@ -2713,35 +2715,34 @@ static void __devexit e100_remove(struct pci_dev *pdev) } } -#ifdef CONFIG_PM static int e100_suspend(struct pci_dev *pdev, pm_message_t state) { struct net_device *netdev = pci_get_drvdata(pdev); struct nic *nic = netdev_priv(netdev); -#ifdef CONFIG_E100_NAPI if (netif_running(netdev)) - netif_poll_disable(nic->netdev); -#endif - del_timer_sync(&nic->watchdog); - netif_carrier_off(nic->netdev); + e100_down(nic); + e100_hw_reset(nic); + netif_device_detach(netdev); +#ifdef CONFIG_PM pci_save_state(pdev); - - if ((nic->flags & wol_magic) | e100_asf(nic)) { - pci_enable_wake(pdev, PCI_D3hot, 1); - pci_enable_wake(pdev, PCI_D3cold, 1); - } else { - pci_enable_wake(pdev, PCI_D3hot, 0); - pci_enable_wake(pdev, PCI_D3cold, 0); - } + if (nic->flags & (wol_magic | e100_asf(nic))) +#else + if (nic->flags & (wol_magic)) +#endif + pci_enable_wake(pdev, pci_choose_state(pdev, state), 1); + else + /* disable PME */ + pci_enable_wake(pdev, 0, 0); pci_disable_device(pdev); - pci_set_power_state(pdev, PCI_D3hot); + pci_set_power_state(pdev, pci_choose_state(pdev, state)); return 0; } +#ifdef CONFIG_PM static int e100_resume(struct pci_dev *pdev) { struct net_device *netdev = pci_get_drvdata(pdev); @@ -2763,26 +2764,7 @@ static int e100_resume(struct pci_dev *pdev) static void e100_shutdown(struct pci_dev *pdev) { - struct net_device *netdev = pci_get_drvdata(pdev); - struct nic *nic = netdev_priv(netdev); - -#ifdef CONFIG_E100_NAPI - if (netif_running(netdev)) - netif_poll_disable(nic->netdev); -#endif - del_timer_sync(&nic->watchdog); - netif_carrier_off(nic->netdev); - - if ((nic->flags & wol_magic) | e100_asf(nic)) { - pci_enable_wake(pdev, PCI_D3hot, 1); - pci_enable_wake(pdev, PCI_D3cold, 1); - } else { - pci_enable_wake(pdev, PCI_D3hot, 0); - pci_enable_wake(pdev, PCI_D3cold, 0); - } - - pci_disable_device(pdev); - pci_set_power_state(pdev, PCI_D3hot); + e100_suspend(pdev, PMSG_SUSPEND); } /* ------------------ PCI Error Recovery infrastructure -------------- */ @@ -2866,9 +2848,9 @@ static struct pci_driver e100_driver = { .id_table = e100_id_table, .probe = e100_probe, .remove = __devexit_p(e100_remove), -#ifdef CONFIG_PM /* Power Management hooks */ .suspend = e100_suspend, +#ifdef CONFIG_PM .resume = e100_resume, #endif .shutdown = e100_shutdown, diff --git a/trunk/drivers/net/e1000/e1000_ethtool.c b/trunk/drivers/net/e1000/e1000_ethtool.c index c564adbd669b..778ede3c0216 100644 --- a/trunk/drivers/net/e1000/e1000_ethtool.c +++ b/trunk/drivers/net/e1000/e1000_ethtool.c @@ -461,8 +461,7 @@ e1000_get_regs(struct net_device *netdev, regs_buff[24] = (uint32_t)phy_data; /* phy local receiver status */ regs_buff[25] = regs_buff[24]; /* phy remote receiver status */ if (hw->mac_type >= e1000_82540 && - hw->mac_type < e1000_82571 && - hw->media_type == e1000_media_type_copper) { + hw->media_type == e1000_media_type_copper) { regs_buff[26] = E1000_READ_REG(hw, MANC); } } @@ -884,7 +883,8 @@ e1000_eeprom_test(struct e1000_adapter *adapter, uint64_t *data) static irqreturn_t e1000_test_intr(int irq, - void *data) + void *data, + struct pt_regs *regs) { struct net_device *netdev = (struct net_device *) data; struct e1000_adapter *adapter = netdev_priv(netdev); @@ -1691,7 +1691,6 @@ static int e1000_wol_exclusion(struct e1000_adapter *adapter, struct ethtool_wol int retval = 1; /* fail by default */ switch (hw->device_id) { - case E1000_DEV_ID_82542: case E1000_DEV_ID_82543GC_FIBER: case E1000_DEV_ID_82543GC_COPPER: case E1000_DEV_ID_82544EI_FIBER: diff --git a/trunk/drivers/net/e1000/e1000_hw.c b/trunk/drivers/net/e1000/e1000_hw.c index 796c4f7d4260..65077f39da69 100644 --- a/trunk/drivers/net/e1000/e1000_hw.c +++ b/trunk/drivers/net/e1000/e1000_hw.c @@ -3868,7 +3868,7 @@ e1000_phy_hw_reset(struct e1000_hw *hw) * * hw - Struct containing variables accessed by shared code * -* Sets bit 15 of the MII Control register +* Sets bit 15 of the MII Control regiser ******************************************************************************/ int32_t e1000_phy_reset(struct e1000_hw *hw) diff --git a/trunk/drivers/net/e1000/e1000_hw.h b/trunk/drivers/net/e1000/e1000_hw.h index 449a60303e07..112447fd8bf2 100644 --- a/trunk/drivers/net/e1000/e1000_hw.h +++ b/trunk/drivers/net/e1000/e1000_hw.h @@ -1961,9 +1961,9 @@ struct e1000_hw { #define E1000_RXDCTL_GRAN 0x01000000 /* RXDCTL Granularity */ /* Transmit Descriptor Control */ -#define E1000_TXDCTL_PTHRESH 0x0000003F /* TXDCTL Prefetch Threshold */ -#define E1000_TXDCTL_HTHRESH 0x00003F00 /* TXDCTL Host Threshold */ -#define E1000_TXDCTL_WTHRESH 0x003F0000 /* TXDCTL Writeback Threshold */ +#define E1000_TXDCTL_PTHRESH 0x000000FF /* TXDCTL Prefetch Threshold */ +#define E1000_TXDCTL_HTHRESH 0x0000FF00 /* TXDCTL Host Threshold */ +#define E1000_TXDCTL_WTHRESH 0x00FF0000 /* TXDCTL Writeback Threshold */ #define E1000_TXDCTL_GRAN 0x01000000 /* TXDCTL Granularity */ #define E1000_TXDCTL_LWTHRESH 0xFE000000 /* TXDCTL Low Threshold */ #define E1000_TXDCTL_FULL_TX_DESC_WB 0x01010000 /* GRAN=1, WTHRESH=1 */ diff --git a/trunk/drivers/net/e1000/e1000_main.c b/trunk/drivers/net/e1000/e1000_main.c index 726ec5e88ab2..7dca38fba6a1 100644 --- a/trunk/drivers/net/e1000/e1000_main.c +++ b/trunk/drivers/net/e1000/e1000_main.c @@ -35,7 +35,7 @@ static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver"; #else #define DRIVERNAPI "-NAPI" #endif -#define DRV_VERSION "7.2.9-k4"DRIVERNAPI +#define DRV_VERSION "7.2.9-k2"DRIVERNAPI char e1000_driver_version[] = DRV_VERSION; static char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation."; @@ -153,7 +153,7 @@ static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev); static struct net_device_stats * e1000_get_stats(struct net_device *netdev); static int e1000_change_mtu(struct net_device *netdev, int new_mtu); static int e1000_set_mac(struct net_device *netdev, void *p); -static irqreturn_t e1000_intr(int irq, void *data); +static irqreturn_t e1000_intr(int irq, void *data, struct pt_regs *regs); static boolean_t e1000_clean_tx_irq(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring); #ifdef CONFIG_E1000_NAPI @@ -699,10 +699,7 @@ e1000_reset(struct e1000_adapter *adapter) phy_data); } - if ((adapter->en_mng_pt) && - (adapter->hw.mac_type >= e1000_82540) && - (adapter->hw.mac_type < e1000_82571) && - (adapter->hw.media_type == e1000_media_type_copper)) { + if ((adapter->en_mng_pt) && (adapter->hw.mac_type < e1000_82571)) { manc = E1000_READ_REG(&adapter->hw, MANC); manc |= (E1000_MANC_ARP_EN | E1000_MANC_EN_MNG2HOST); E1000_WRITE_REG(&adapter->hw, MANC, manc); @@ -1079,9 +1076,8 @@ e1000_remove(struct pci_dev *pdev) flush_scheduled_work(); - if (adapter->hw.mac_type >= e1000_82540 && - adapter->hw.mac_type < e1000_82571 && - adapter->hw.media_type == e1000_media_type_copper) { + if (adapter->hw.mac_type < e1000_82571 && + adapter->hw.media_type == e1000_media_type_copper) { manc = E1000_READ_REG(&adapter->hw, MANC); if (manc & E1000_MANC_SMBUS_EN) { manc |= E1000_MANC_ARP_EN; @@ -1808,11 +1804,9 @@ e1000_setup_rctl(struct e1000_adapter *adapter) * followed by the page buffers. Therefore, skb->data is * sized to hold the largest protocol header. */ - /* allocations using alloc_page take too long for regular MTU - * so only enable packet split for jumbo frames */ pages = PAGE_USE_COUNT(adapter->netdev->mtu); - if ((adapter->hw.mac_type >= e1000_82571) && (pages <= 3) && - PAGE_SIZE <= 16384 && (rctl & E1000_RCTL_LPE)) + if ((adapter->hw.mac_type > e1000_82547_rev_2) && (pages <= 3) && + PAGE_SIZE <= 16384) adapter->rx_ps_pages = pages; else adapter->rx_ps_pages = 0; @@ -2992,11 +2986,6 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) return NETDEV_TX_OK; } - /* 82571 and newer doesn't need the workaround that limited descriptor - * length to 4kB */ - if (adapter->hw.mac_type >= e1000_82571) - max_per_txd = 8192; - #ifdef NETIF_F_TSO mss = skb_shinfo(skb)->gso_size; /* The controller does a simple calculation to @@ -3447,10 +3436,11 @@ e1000_update_stats(struct e1000_adapter *adapter) * e1000_intr - Interrupt Handler * @irq: interrupt number * @data: pointer to a network interface device structure + * @pt_regs: CPU registers structure **/ static irqreturn_t -e1000_intr(int irq, void *data) +e1000_intr(int irq, void *data, struct pt_regs *regs) { struct net_device *netdev = data; struct e1000_adapter *adapter = netdev_priv(netdev); @@ -3786,6 +3776,9 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter, length = le16_to_cpu(rx_desc->length); + /* adjust length to remove Ethernet CRC */ + length -= 4; + if (unlikely(!(status & E1000_RXD_STAT_EOP))) { /* All receives must fit into a single buffer */ E1000_DBG("%s: Receive packet consumed multiple" @@ -3813,10 +3806,6 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter, } } - /* adjust length to remove Ethernet CRC, this must be - * done after the TBI_ACCEPT workaround above */ - length -= 4; - /* code added for copybreak, this should improve * performance for small packets with large amounts * of reassembly being done in the stack */ @@ -4785,9 +4774,8 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state) pci_enable_wake(pdev, PCI_D3cold, 0); } - if (adapter->hw.mac_type >= e1000_82540 && - adapter->hw.mac_type < e1000_82571 && - adapter->hw.media_type == e1000_media_type_copper) { + if (adapter->hw.mac_type < e1000_82571 && + adapter->hw.media_type == e1000_media_type_copper) { manc = E1000_READ_REG(&adapter->hw, MANC); if (manc & E1000_MANC_SMBUS_EN) { manc |= E1000_MANC_ARP_EN; @@ -4800,9 +4788,6 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state) if (adapter->hw.phy_type == e1000_phy_igp_3) e1000_phy_powerdown_workaround(&adapter->hw); - if (netif_running(netdev)) - e1000_free_irq(adapter); - /* Release control of h/w to f/w. If f/w is AMT enabled, this * would have already happened in close and is redundant. */ e1000_release_hw_control(adapter); @@ -4833,10 +4818,6 @@ e1000_resume(struct pci_dev *pdev) pci_enable_wake(pdev, PCI_D3hot, 0); pci_enable_wake(pdev, PCI_D3cold, 0); - if (netif_running(netdev) && (err = e1000_request_irq(adapter))) - return err; - - e1000_power_up_phy(adapter); e1000_reset(adapter); E1000_WRITE_REG(&adapter->hw, WUS, ~0); @@ -4845,9 +4826,8 @@ e1000_resume(struct pci_dev *pdev) netif_device_attach(netdev); - if (adapter->hw.mac_type >= e1000_82540 && - adapter->hw.mac_type < e1000_82571 && - adapter->hw.media_type == e1000_media_type_copper) { + if (adapter->hw.mac_type < e1000_82571 && + adapter->hw.media_type == e1000_media_type_copper) { manc = E1000_READ_REG(&adapter->hw, MANC); manc &= ~(E1000_MANC_ARP_EN); E1000_WRITE_REG(&adapter->hw, MANC, manc); @@ -4882,7 +4862,7 @@ e1000_netpoll(struct net_device *netdev) struct e1000_adapter *adapter = netdev_priv(netdev); disable_irq(adapter->pdev->irq); - e1000_intr(adapter->pdev->irq, netdev); + e1000_intr(adapter->pdev->irq, netdev, NULL); e1000_clean_tx_irq(adapter, adapter->tx_ring); #ifndef CONFIG_E1000_NAPI adapter->clean_rx(adapter, adapter->rx_ring); @@ -4935,6 +4915,10 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev) pci_enable_wake(pdev, PCI_D3hot, 0); pci_enable_wake(pdev, PCI_D3cold, 0); + /* Perform card reset only on one instance of the card */ + if (PCI_FUNC (pdev->devfn) != 0) + return PCI_ERS_RESULT_RECOVERED; + e1000_reset(adapter); E1000_WRITE_REG(&adapter->hw, WUS, ~0); @@ -4965,7 +4949,6 @@ static void e1000_io_resume(struct pci_dev *pdev) netif_device_attach(netdev); if (adapter->hw.mac_type >= e1000_82540 && - adapter->hw.mac_type < e1000_82571 && adapter->hw.media_type == e1000_media_type_copper) { manc = E1000_READ_REG(&adapter->hw, MANC); manc &= ~(E1000_MANC_ARP_EN); diff --git a/trunk/drivers/net/eepro.c b/trunk/drivers/net/eepro.c index a4eb0dc99ecf..09ff9b9418f4 100644 --- a/trunk/drivers/net/eepro.c +++ b/trunk/drivers/net/eepro.c @@ -311,7 +311,7 @@ struct eepro_local { static int eepro_probe1(struct net_device *dev, int autoprobe); static int eepro_open(struct net_device *dev); static int eepro_send_packet(struct sk_buff *skb, struct net_device *dev); -static irqreturn_t eepro_interrupt(int irq, void *dev_id); +static irqreturn_t eepro_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void eepro_rx(struct net_device *dev); static void eepro_transmit_interrupt(struct net_device *dev); static int eepro_close(struct net_device *dev); @@ -994,6 +994,16 @@ static int eepro_open(struct net_device *dev) return -EAGAIN; } +#ifdef irq2dev_map + if (((irq2dev_map[dev->irq] != 0) + || (irq2dev_map[dev->irq] = dev) == 0) && + (irq2dev_map[dev->irq]!=dev)) { + /* printk("%s: IRQ map wrong\n", dev->name); */ + free_irq(dev->irq, dev); + return -EAGAIN; + } +#endif + /* Initialize the 82595. */ eepro_sw2bank2(ioaddr); /* be CAREFUL, BANK 2 now */ @@ -1186,13 +1196,19 @@ static int eepro_send_packet(struct sk_buff *skb, struct net_device *dev) Handle the network interface interrupts. */ static irqreturn_t -eepro_interrupt(int irq, void *dev_id) +eepro_interrupt(int irq, void *dev_id, struct pt_regs * regs) { - struct net_device *dev = dev_id; + struct net_device *dev = (struct net_device *)dev_id; + /* (struct net_device *)(irq2dev_map[irq]);*/ struct eepro_local *lp; int ioaddr, status, boguscount = 20; int handled = 0; + if (dev == NULL) { + printk (KERN_ERR "eepro_interrupt(): irq %d for unknown device.\\n", irq); + return IRQ_NONE; + } + lp = netdev_priv(dev); spin_lock(&lp->lock); @@ -1272,6 +1288,10 @@ static int eepro_close(struct net_device *dev) /* release the interrupt */ free_irq(dev->irq, dev); +#ifdef irq2dev_map + irq2dev_map[dev->irq] = 0; +#endif + /* Update the statistics here. What statistics? */ return 0; diff --git a/trunk/drivers/net/eepro100.c b/trunk/drivers/net/eepro100.c index e28bb1e38f8d..499e93b31f54 100644 --- a/trunk/drivers/net/eepro100.c +++ b/trunk/drivers/net/eepro100.c @@ -488,7 +488,7 @@ static int speedo_start_xmit(struct sk_buff *skb, struct net_device *dev); static void speedo_refill_rx_buffers(struct net_device *dev, int force); static int speedo_rx(struct net_device *dev); static void speedo_tx_buffer_gc(struct net_device *dev); -static irqreturn_t speedo_interrupt(int irq, void *dev_instance); +static irqreturn_t speedo_interrupt(int irq, void *dev_instance, struct pt_regs *regs); static int speedo_close(struct net_device *dev); static struct net_device_stats *speedo_get_stats(struct net_device *dev); static int speedo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); @@ -606,7 +606,7 @@ static void poll_speedo (struct net_device *dev) /* disable_irq is not very nice, but with the funny lockless design we have no other choice. */ disable_irq(dev->irq); - speedo_interrupt (dev->irq, dev); + speedo_interrupt (dev->irq, dev, NULL); enable_irq(dev->irq); } #endif @@ -1541,7 +1541,7 @@ static void speedo_tx_buffer_gc(struct net_device *dev) /* The interrupt handler does all of the Rx thread work and cleans up after the Tx thread. */ -static irqreturn_t speedo_interrupt(int irq, void *dev_instance) +static irqreturn_t speedo_interrupt(int irq, void *dev_instance, struct pt_regs *regs) { struct net_device *dev = (struct net_device *)dev_instance; struct speedo_private *sp; diff --git a/trunk/drivers/net/eexpress.c b/trunk/drivers/net/eexpress.c index e14be020e562..9cb05d99ee1b 100644 --- a/trunk/drivers/net/eexpress.c +++ b/trunk/drivers/net/eexpress.c @@ -249,7 +249,7 @@ static void eexp_timeout(struct net_device *dev); static struct net_device_stats *eexp_stats(struct net_device *dev); static int eexp_xmit(struct sk_buff *buf, struct net_device *dev); -static irqreturn_t eexp_irq(int irq, void *dev_addr); +static irqreturn_t eexp_irq(int irq, void *dev_addr, struct pt_regs *regs); static void eexp_set_multicast(struct net_device *dev); /* @@ -789,13 +789,20 @@ static void eexp_cmd_clear(struct net_device *dev) } } -static irqreturn_t eexp_irq(int irq, void *dev_info) +static irqreturn_t eexp_irq(int irq, void *dev_info, struct pt_regs *regs) { struct net_device *dev = dev_info; struct net_local *lp; unsigned short ioaddr,status,ack_cmd; unsigned short old_read_ptr, old_write_ptr; + if (dev==NULL) + { + printk(KERN_WARNING "eexpress: irq %d for unknown device\n", + irq); + return IRQ_NONE; + } + lp = netdev_priv(dev); ioaddr = dev->base_addr; diff --git a/trunk/drivers/net/ehea/ehea.h b/trunk/drivers/net/ehea/ehea.h index 39ad9f73d1ec..23b451a8ae12 100644 --- a/trunk/drivers/net/ehea/ehea.h +++ b/trunk/drivers/net/ehea/ehea.h @@ -39,7 +39,7 @@ #include #define DRV_NAME "ehea" -#define DRV_VERSION "EHEA_0043" +#define DRV_VERSION "EHEA_0028" #define EHEA_MSG_DEFAULT (NETIF_MSG_LINK | NETIF_MSG_TIMER \ | NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR) @@ -50,7 +50,6 @@ #define EHEA_MAX_ENTRIES_SQ 32767 #define EHEA_MIN_ENTRIES_QP 127 -#define EHEA_SMALL_QUEUES #define EHEA_NUM_TX_QP 1 #ifdef EHEA_SMALL_QUEUES @@ -60,11 +59,11 @@ #define EHEA_DEF_ENTRIES_RQ2 1023 #define EHEA_DEF_ENTRIES_RQ3 1023 #else -#define EHEA_MAX_CQE_COUNT 4080 -#define EHEA_DEF_ENTRIES_SQ 4080 -#define EHEA_DEF_ENTRIES_RQ1 8160 -#define EHEA_DEF_ENTRIES_RQ2 2040 -#define EHEA_DEF_ENTRIES_RQ3 2040 +#define EHEA_MAX_CQE_COUNT 32000 +#define EHEA_DEF_ENTRIES_SQ 16000 +#define EHEA_DEF_ENTRIES_RQ1 32080 +#define EHEA_DEF_ENTRIES_RQ2 4020 +#define EHEA_DEF_ENTRIES_RQ3 4020 #endif #define EHEA_MAX_ENTRIES_EQ 20 @@ -105,6 +104,9 @@ #define EHEA_BCMC_VLANID_ALL 0x01 #define EHEA_BCMC_VLANID_SINGLE 0x00 +/* Use this define to kmallocate pHYP control blocks */ +#define H_CB_ALIGNMENT 4096 + #define EHEA_CACHE_LINE 128 /* Memory Regions */ diff --git a/trunk/drivers/net/ehea/ehea_ethtool.c b/trunk/drivers/net/ehea/ehea_ethtool.c index 9f57c2e78ced..82eb2fb8c75e 100644 --- a/trunk/drivers/net/ehea/ehea_ethtool.c +++ b/trunk/drivers/net/ehea/ehea_ethtool.c @@ -238,7 +238,7 @@ static void ehea_get_ethtool_stats(struct net_device *dev, data[i++] = port->port_res[0].swqe_refill_th; data[i++] = port->resets; - cb6 = kzalloc(PAGE_SIZE, GFP_KERNEL); + cb6 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); if (!cb6) { ehea_error("no mem for cb6"); return; diff --git a/trunk/drivers/net/ehea/ehea_main.c b/trunk/drivers/net/ehea/ehea_main.c index 6ad696101418..263d1c5b3f23 100644 --- a/trunk/drivers/net/ehea/ehea_main.c +++ b/trunk/drivers/net/ehea/ehea_main.c @@ -92,7 +92,7 @@ static struct net_device_stats *ehea_get_stats(struct net_device *dev) memset(stats, 0, sizeof(*stats)); - cb2 = kzalloc(PAGE_SIZE, GFP_KERNEL); + cb2 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); if (!cb2) { ehea_error("no mem for cb2"); goto out; @@ -536,14 +536,16 @@ void ehea_send_irq_tasklet(unsigned long data) tasklet_hi_schedule(&pr->send_comp_task); } -static irqreturn_t ehea_send_irq_handler(int irq, void *param) +static irqreturn_t ehea_send_irq_handler(int irq, void *param, + struct pt_regs *regs) { struct ehea_port_res *pr = param; tasklet_hi_schedule(&pr->send_comp_task); return IRQ_HANDLED; } -static irqreturn_t ehea_recv_irq_handler(int irq, void *param) +static irqreturn_t ehea_recv_irq_handler(int irq, void *param, + struct pt_regs *regs) { struct ehea_port_res *pr = param; struct ehea_port *port = pr->port; @@ -551,7 +553,8 @@ static irqreturn_t ehea_recv_irq_handler(int irq, void *param) return IRQ_HANDLED; } -static irqreturn_t ehea_qp_aff_irq_handler(int irq, void *param) +static irqreturn_t ehea_qp_aff_irq_handler(int irq, void *param, + struct pt_regs *regs) { struct ehea_port *port = param; struct ehea_eqe *eqe; @@ -586,8 +589,8 @@ int ehea_sense_port_attr(struct ehea_port *port) u64 hret; struct hcp_ehea_port_cb0 *cb0; - cb0 = kzalloc(PAGE_SIZE, GFP_ATOMIC); /* May be called via */ - if (!cb0) { /* ehea_neq_tasklet() */ + cb0 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); + if (!cb0) { ehea_error("no mem for cb0"); ret = -ENOMEM; goto out; @@ -670,7 +673,7 @@ int ehea_set_portspeed(struct ehea_port *port, u32 port_speed) u64 hret; int ret = 0; - cb4 = kzalloc(PAGE_SIZE, GFP_KERNEL); + cb4 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); if (!cb4) { ehea_error("no mem for cb4"); ret = -ENOMEM; @@ -765,7 +768,8 @@ static void ehea_parse_eqe(struct ehea_adapter *adapter, u64 eqe) if (EHEA_BMASK_GET(NEQE_PORT_UP, eqe)) { if (!netif_carrier_ok(port->netdev)) { - ret = ehea_sense_port_attr(port); + ret = ehea_sense_port_attr( + adapter->port[portnum]); if (ret) { ehea_error("failed resensing port " "attributes"); @@ -817,7 +821,7 @@ static void ehea_parse_eqe(struct ehea_adapter *adapter, u64 eqe) netif_stop_queue(port->netdev); break; default: - ehea_error("unknown event code %x, eqe=0x%lX", ec, eqe); + ehea_error("unknown event code %x", ec); break; } } @@ -846,7 +850,8 @@ static void ehea_neq_tasklet(unsigned long data) adapter->neq->fw_handle, event_mask); } -static irqreturn_t ehea_interrupt_neq(int irq, void *param) +static irqreturn_t ehea_interrupt_neq(int irq, void *param, + struct pt_regs *regs) { struct ehea_adapter *adapter = param; tasklet_hi_schedule(&adapter->neq_tasklet); @@ -985,7 +990,7 @@ static int ehea_configure_port(struct ehea_port *port) struct hcp_ehea_port_cb0 *cb0; ret = -ENOMEM; - cb0 = kzalloc(PAGE_SIZE, GFP_KERNEL); + cb0 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); if (!cb0) goto out; @@ -1443,7 +1448,7 @@ static int ehea_set_mac_addr(struct net_device *dev, void *sa) goto out; } - cb0 = kzalloc(PAGE_SIZE, GFP_KERNEL); + cb0 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); if (!cb0) { ehea_error("no mem for cb0"); ret = -ENOMEM; @@ -1501,7 +1506,7 @@ static void ehea_promiscuous(struct net_device *dev, int enable) if ((enable && port->promisc) || (!enable && !port->promisc)) return; - cb7 = kzalloc(PAGE_SIZE, GFP_ATOMIC); + cb7 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); if (!cb7) { ehea_error("no mem for cb7"); goto out; @@ -1605,7 +1610,7 @@ static void ehea_add_multicast_entry(struct ehea_port* port, u8* mc_mac_addr) struct ehea_mc_list *ehea_mcl_entry; u64 hret; - ehea_mcl_entry = kzalloc(sizeof(*ehea_mcl_entry), GFP_ATOMIC); + ehea_mcl_entry = kzalloc(sizeof(*ehea_mcl_entry), GFP_KERNEL); if (!ehea_mcl_entry) { ehea_error("no mem for mcl_entry"); return; @@ -1840,7 +1845,7 @@ static int ehea_start_xmit(struct sk_buff *skb, struct net_device *dev) if (netif_msg_tx_queued(port)) { ehea_info("post swqe on QP %d", pr->qp->init_attr.qp_nr); - ehea_dump(swqe, 512, "swqe"); + ehea_dump(swqe, sizeof(*swqe), "swqe"); } ehea_post_swqe(pr->qp, swqe); @@ -1870,7 +1875,7 @@ static void ehea_vlan_rx_register(struct net_device *dev, port->vgrp = grp; - cb1 = kzalloc(PAGE_SIZE, GFP_KERNEL); + cb1 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); if (!cb1) { ehea_error("no mem for cb1"); goto out; @@ -1899,7 +1904,7 @@ static void ehea_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) int index; u64 hret; - cb1 = kzalloc(PAGE_SIZE, GFP_KERNEL); + cb1 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); if (!cb1) { ehea_error("no mem for cb1"); goto out; @@ -1935,7 +1940,7 @@ static void ehea_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) if (port->vgrp) port->vgrp->vlan_devices[vid] = NULL; - cb1 = kzalloc(PAGE_SIZE, GFP_KERNEL); + cb1 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); if (!cb1) { ehea_error("no mem for cb1"); goto out; @@ -1968,7 +1973,7 @@ int ehea_activate_qp(struct ehea_adapter *adapter, struct ehea_qp *qp) u64 dummy64 = 0; struct hcp_modify_qp_cb0* cb0; - cb0 = kzalloc(PAGE_SIZE, GFP_KERNEL); + cb0 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); if (!cb0) { ret = -ENOMEM; goto out; @@ -2269,7 +2274,7 @@ int ehea_sense_adapter_attr(struct ehea_adapter *adapter) u64 hret; int ret; - cb = kzalloc(PAGE_SIZE, GFP_KERNEL); + cb = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); if (!cb) { ret = -ENOMEM; goto out; @@ -2340,7 +2345,7 @@ static int ehea_setup_single_port(struct ehea_port *port, goto out; /* Enable Jumbo frames */ - cb4 = kzalloc(PAGE_SIZE, GFP_KERNEL); + cb4 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); if (!cb4) { ehea_error("no mem for cb4"); } else { diff --git a/trunk/drivers/net/ehea/ehea_phyp.c b/trunk/drivers/net/ehea/ehea_phyp.c index 0cfc2bc1a27b..4a85aca4c7e9 100644 --- a/trunk/drivers/net/ehea/ehea_phyp.c +++ b/trunk/drivers/net/ehea/ehea_phyp.c @@ -44,99 +44,71 @@ static inline u16 get_order_of_qentries(u16 queue_entries) #define H_ALL_RES_TYPE_MR 5 #define H_ALL_RES_TYPE_MW 6 -static long ehea_plpar_hcall_norets(unsigned long opcode, - unsigned long arg1, - unsigned long arg2, - unsigned long arg3, - unsigned long arg4, - unsigned long arg5, - unsigned long arg6, - unsigned long arg7) +static long ehea_hcall_9arg_9ret(unsigned long opcode, + unsigned long arg1, unsigned long arg2, + unsigned long arg3, unsigned long arg4, + unsigned long arg5, unsigned long arg6, + unsigned long arg7, unsigned long arg8, + unsigned long arg9, unsigned long *out1, + unsigned long *out2,unsigned long *out3, + unsigned long *out4,unsigned long *out5, + unsigned long *out6,unsigned long *out7, + unsigned long *out8,unsigned long *out9) { - long ret; + long hret; int i, sleep_msecs; for (i = 0; i < 5; i++) { - ret = plpar_hcall_norets(opcode, arg1, arg2, arg3, arg4, - arg5, arg6, arg7); - - if (H_IS_LONG_BUSY(ret)) { - sleep_msecs = get_longbusy_msecs(ret); + hret = plpar_hcall_9arg_9ret(opcode,arg1, arg2, arg3, arg4, + arg5, arg6, arg7, arg8, arg9, out1, + out2, out3, out4, out5, out6, out7, + out8, out9); + if (H_IS_LONG_BUSY(hret)) { + sleep_msecs = get_longbusy_msecs(hret); msleep_interruptible(sleep_msecs); continue; } - if (ret < H_SUCCESS) - ehea_error("opcode=%lx ret=%lx" - " arg1=%lx arg2=%lx arg3=%lx arg4=%lx" - " arg5=%lx arg6=%lx arg7=%lx ", - opcode, ret, - arg1, arg2, arg3, arg4, arg5, - arg6, arg7); - - return ret; + if (hret < H_SUCCESS) + ehea_error("op=%lx hret=%lx " + "i1=%lx i2=%lx i3=%lx i4=%lx i5=%lx i6=%lx " + "i7=%lx i8=%lx i9=%lx " + "o1=%lx o2=%lx o3=%lx o4=%lx o5=%lx o6=%lx " + "o7=%lx o8=%lx o9=%lx", + opcode, hret, arg1, arg2, arg3, arg4, arg5, + arg6, arg7, arg8, arg9, *out1, *out2, *out3, + *out4, *out5, *out6, *out7, *out8, *out9); + return hret; } - return H_BUSY; } -static long ehea_plpar_hcall9(unsigned long opcode, - unsigned long *outs, /* array of 9 outputs */ - unsigned long arg1, - unsigned long arg2, - unsigned long arg3, - unsigned long arg4, - unsigned long arg5, - unsigned long arg6, - unsigned long arg7, - unsigned long arg8, - unsigned long arg9) +u64 ehea_h_query_ehea_qp(const u64 adapter_handle, const u8 qp_category, + const u64 qp_handle, const u64 sel_mask, void *cb_addr) { - long ret; - int i, sleep_msecs; - - for (i = 0; i < 5; i++) { - ret = plpar_hcall9(opcode, outs, - arg1, arg2, arg3, arg4, arg5, - arg6, arg7, arg8, arg9); + u64 dummy; - if (H_IS_LONG_BUSY(ret)) { - sleep_msecs = get_longbusy_msecs(ret); - msleep_interruptible(sleep_msecs); - continue; - } - - if (ret < H_SUCCESS) - ehea_error("opcode=%lx ret=%lx" - " arg1=%lx arg2=%lx arg3=%lx arg4=%lx" - " arg5=%lx arg6=%lx arg7=%lx arg8=%lx" - " arg9=%lx" - " out1=%lx out2=%lx out3=%lx out4=%lx" - " out5=%lx out6=%lx out7=%lx out8=%lx" - " out9=%lx", - opcode, ret, - arg1, arg2, arg3, arg4, arg5, - arg6, arg7, arg8, arg9, - outs[0], outs[1], outs[2], outs[3], - outs[4], outs[5], outs[6], outs[7], - outs[8]); - - return ret; + if ((((u64)cb_addr) & (PAGE_SIZE - 1)) != 0) { + ehea_error("not on pageboundary"); + return H_PARAMETER; } - return H_BUSY; -} - -u64 ehea_h_query_ehea_qp(const u64 adapter_handle, const u8 qp_category, - const u64 qp_handle, const u64 sel_mask, void *cb_addr) -{ - return ehea_plpar_hcall_norets(H_QUERY_HEA_QP, - adapter_handle, /* R4 */ - qp_category, /* R5 */ - qp_handle, /* R6 */ - sel_mask, /* R7 */ - virt_to_abs(cb_addr), /* R8 */ - 0, 0); + return ehea_hcall_9arg_9ret(H_QUERY_HEA_QP, + adapter_handle, /* R4 */ + qp_category, /* R5 */ + qp_handle, /* R6 */ + sel_mask, /* R7 */ + virt_to_abs(cb_addr), /* R8 */ + 0, 0, 0, 0, /* R9-R12 */ + &dummy, /* R4 */ + &dummy, /* R5 */ + &dummy, /* R6 */ + &dummy, /* R7 */ + &dummy, /* R8 */ + &dummy, /* R9 */ + &dummy, /* R10 */ + &dummy, /* R11 */ + &dummy); /* R12 */ } /* input param R5 */ @@ -208,7 +180,6 @@ u64 ehea_h_alloc_resource_qp(const u64 adapter_handle, u64 *qp_handle, struct h_epas *h_epas) { u64 hret; - u64 outs[PLPAR_HCALL9_BUFSIZE]; u64 allocate_controls = EHEA_BMASK_SET(H_ALL_RES_QP_EQPO, init_attr->low_lat_rq1 ? 1 : 0) @@ -248,29 +219,45 @@ u64 ehea_h_alloc_resource_qp(const u64 adapter_handle, EHEA_BMASK_SET(H_ALL_RES_QP_TH_RQ2, init_attr->rq2_threshold) | EHEA_BMASK_SET(H_ALL_RES_QP_TH_RQ3, init_attr->rq3_threshold); - hret = ehea_plpar_hcall9(H_ALLOC_HEA_RESOURCE, - outs, - adapter_handle, /* R4 */ - allocate_controls, /* R5 */ - init_attr->send_cq_handle, /* R6 */ - init_attr->recv_cq_handle, /* R7 */ - init_attr->aff_eq_handle, /* R8 */ - r9_reg, /* R9 */ - max_r10_reg, /* R10 */ - r11_in, /* R11 */ - threshold); /* R12 */ - - *qp_handle = outs[0]; - init_attr->qp_nr = (u32)outs[1]; + u64 r5_out = 0; + u64 r6_out = 0; + u64 r7_out = 0; + u64 r8_out = 0; + u64 r9_out = 0; + u64 g_la_user_out = 0; + u64 r11_out = 0; + u64 r12_out = 0; + + hret = ehea_hcall_9arg_9ret(H_ALLOC_HEA_RESOURCE, + adapter_handle, /* R4 */ + allocate_controls, /* R5 */ + init_attr->send_cq_handle, /* R6 */ + init_attr->recv_cq_handle, /* R7 */ + init_attr->aff_eq_handle, /* R8 */ + r9_reg, /* R9 */ + max_r10_reg, /* R10 */ + r11_in, /* R11 */ + threshold, /* R12 */ + qp_handle, /* R4 */ + &r5_out, /* R5 */ + &r6_out, /* R6 */ + &r7_out, /* R7 */ + &r8_out, /* R8 */ + &r9_out, /* R9 */ + &g_la_user_out, /* R10 */ + &r11_out, /* R11 */ + &r12_out); /* R12 */ + + init_attr->qp_nr = (u32)r5_out; init_attr->act_nr_send_wqes = - (u16)EHEA_BMASK_GET(H_ALL_RES_QP_ACT_SWQE, outs[2]); + (u16)EHEA_BMASK_GET(H_ALL_RES_QP_ACT_SWQE, r6_out); init_attr->act_nr_rwqes_rq1 = - (u16)EHEA_BMASK_GET(H_ALL_RES_QP_ACT_R1WQE, outs[2]); + (u16)EHEA_BMASK_GET(H_ALL_RES_QP_ACT_R1WQE, r6_out); init_attr->act_nr_rwqes_rq2 = - (u16)EHEA_BMASK_GET(H_ALL_RES_QP_ACT_R2WQE, outs[2]); + (u16)EHEA_BMASK_GET(H_ALL_RES_QP_ACT_R2WQE, r6_out); init_attr->act_nr_rwqes_rq3 = - (u16)EHEA_BMASK_GET(H_ALL_RES_QP_ACT_R3WQE, outs[2]); + (u16)EHEA_BMASK_GET(H_ALL_RES_QP_ACT_R3WQE, r6_out); init_attr->act_wqe_size_enc_sq = init_attr->wqe_size_enc_sq; init_attr->act_wqe_size_enc_rq1 = init_attr->wqe_size_enc_rq1; @@ -278,25 +265,25 @@ u64 ehea_h_alloc_resource_qp(const u64 adapter_handle, init_attr->act_wqe_size_enc_rq3 = init_attr->wqe_size_enc_rq3; init_attr->nr_sq_pages = - (u32)EHEA_BMASK_GET(H_ALL_RES_QP_SIZE_SQ, outs[4]); + (u32)EHEA_BMASK_GET(H_ALL_RES_QP_SIZE_SQ, r8_out); init_attr->nr_rq1_pages = - (u32)EHEA_BMASK_GET(H_ALL_RES_QP_SIZE_RQ1, outs[4]); + (u32)EHEA_BMASK_GET(H_ALL_RES_QP_SIZE_RQ1, r8_out); init_attr->nr_rq2_pages = - (u32)EHEA_BMASK_GET(H_ALL_RES_QP_SIZE_RQ2, outs[5]); + (u32)EHEA_BMASK_GET(H_ALL_RES_QP_SIZE_RQ2, r9_out); init_attr->nr_rq3_pages = - (u32)EHEA_BMASK_GET(H_ALL_RES_QP_SIZE_RQ3, outs[5]); + (u32)EHEA_BMASK_GET(H_ALL_RES_QP_SIZE_RQ3, r9_out); init_attr->liobn_sq = - (u32)EHEA_BMASK_GET(H_ALL_RES_QP_LIOBN_SQ, outs[7]); + (u32)EHEA_BMASK_GET(H_ALL_RES_QP_LIOBN_SQ, r11_out); init_attr->liobn_rq1 = - (u32)EHEA_BMASK_GET(H_ALL_RES_QP_LIOBN_RQ1, outs[7]); + (u32)EHEA_BMASK_GET(H_ALL_RES_QP_LIOBN_RQ1, r11_out); init_attr->liobn_rq2 = - (u32)EHEA_BMASK_GET(H_ALL_RES_QP_LIOBN_RQ2, outs[8]); + (u32)EHEA_BMASK_GET(H_ALL_RES_QP_LIOBN_RQ2, r12_out); init_attr->liobn_rq3 = - (u32)EHEA_BMASK_GET(H_ALL_RES_QP_LIOBN_RQ3, outs[8]); + (u32)EHEA_BMASK_GET(H_ALL_RES_QP_LIOBN_RQ3, r12_out); if (!hret) - hcp_epas_ctor(h_epas, outs[6], outs[6]); + hcp_epas_ctor(h_epas, g_la_user_out, g_la_user_out); return hret; } @@ -305,24 +292,31 @@ u64 ehea_h_alloc_resource_cq(const u64 adapter_handle, struct ehea_cq_attr *cq_attr, u64 *cq_handle, struct h_epas *epas) { - u64 hret; - u64 outs[PLPAR_HCALL9_BUFSIZE]; - - hret = ehea_plpar_hcall9(H_ALLOC_HEA_RESOURCE, - outs, - adapter_handle, /* R4 */ - H_ALL_RES_TYPE_CQ, /* R5 */ - cq_attr->eq_handle, /* R6 */ - cq_attr->cq_token, /* R7 */ - cq_attr->max_nr_of_cqes, /* R8 */ - 0, 0, 0, 0); /* R9-R12 */ - - *cq_handle = outs[0]; - cq_attr->act_nr_of_cqes = outs[3]; - cq_attr->nr_pages = outs[4]; + u64 hret, dummy, act_nr_of_cqes_out, act_pages_out; + u64 g_la_privileged_out, g_la_user_out; + + hret = ehea_hcall_9arg_9ret(H_ALLOC_HEA_RESOURCE, + adapter_handle, /* R4 */ + H_ALL_RES_TYPE_CQ, /* R5 */ + cq_attr->eq_handle, /* R6 */ + cq_attr->cq_token, /* R7 */ + cq_attr->max_nr_of_cqes, /* R8 */ + 0, 0, 0, 0, /* R9-R12 */ + cq_handle, /* R4 */ + &dummy, /* R5 */ + &dummy, /* R6 */ + &act_nr_of_cqes_out, /* R7 */ + &act_pages_out, /* R8 */ + &g_la_privileged_out, /* R9 */ + &g_la_user_out, /* R10 */ + &dummy, /* R11 */ + &dummy); /* R12 */ + + cq_attr->act_nr_of_cqes = act_nr_of_cqes_out; + cq_attr->nr_pages = act_pages_out; if (!hret) - hcp_epas_ctor(epas, outs[5], outs[6]); + hcp_epas_ctor(epas, g_la_privileged_out, g_la_user_out); return hret; } @@ -367,8 +361,9 @@ u64 ehea_h_alloc_resource_cq(const u64 adapter_handle, u64 ehea_h_alloc_resource_eq(const u64 adapter_handle, struct ehea_eq_attr *eq_attr, u64 *eq_handle) { - u64 hret, allocate_controls; - u64 outs[PLPAR_HCALL9_BUFSIZE]; + u64 hret, dummy, eq_liobn, allocate_controls; + u64 ist1_out, ist2_out, ist3_out, ist4_out; + u64 act_nr_of_eqes_out, act_pages_out; /* resource type */ allocate_controls = @@ -377,20 +372,27 @@ u64 ehea_h_alloc_resource_eq(const u64 adapter_handle, | EHEA_BMASK_SET(H_ALL_RES_EQ_INH_EQE_GEN, !eq_attr->eqe_gen) | EHEA_BMASK_SET(H_ALL_RES_EQ_NON_NEQ_ISN, 1); - hret = ehea_plpar_hcall9(H_ALLOC_HEA_RESOURCE, - outs, - adapter_handle, /* R4 */ - allocate_controls, /* R5 */ - eq_attr->max_nr_of_eqes, /* R6 */ - 0, 0, 0, 0, 0, 0); /* R7-R10 */ - - *eq_handle = outs[0]; - eq_attr->act_nr_of_eqes = outs[3]; - eq_attr->nr_pages = outs[4]; - eq_attr->ist1 = outs[5]; - eq_attr->ist2 = outs[6]; - eq_attr->ist3 = outs[7]; - eq_attr->ist4 = outs[8]; + hret = ehea_hcall_9arg_9ret(H_ALLOC_HEA_RESOURCE, + adapter_handle, /* R4 */ + allocate_controls, /* R5 */ + eq_attr->max_nr_of_eqes, /* R6 */ + 0, 0, 0, 0, 0, 0, /* R7-R10 */ + eq_handle, /* R4 */ + &dummy, /* R5 */ + &eq_liobn, /* R6 */ + &act_nr_of_eqes_out, /* R7 */ + &act_pages_out, /* R8 */ + &ist1_out, /* R9 */ + &ist2_out, /* R10 */ + &ist3_out, /* R11 */ + &ist4_out); /* R12 */ + + eq_attr->act_nr_of_eqes = act_nr_of_eqes_out; + eq_attr->nr_pages = act_pages_out; + eq_attr->ist1 = ist1_out; + eq_attr->ist2 = ist2_out; + eq_attr->ist3 = ist3_out; + eq_attr->ist4 = ist4_out; return hret; } @@ -400,22 +402,31 @@ u64 ehea_h_modify_ehea_qp(const u64 adapter_handle, const u8 cat, void *cb_addr, u64 *inv_attr_id, u64 *proc_mask, u16 *out_swr, u16 *out_rwr) { - u64 hret; - u64 outs[PLPAR_HCALL9_BUFSIZE]; - - hret = ehea_plpar_hcall9(H_MODIFY_HEA_QP, - outs, - adapter_handle, /* R4 */ - (u64) cat, /* R5 */ - qp_handle, /* R6 */ - sel_mask, /* R7 */ - virt_to_abs(cb_addr), /* R8 */ - 0, 0, 0, 0); /* R9-R12 */ - - *inv_attr_id = outs[0]; - *out_swr = outs[3]; - *out_rwr = outs[4]; - *proc_mask = outs[5]; + u64 hret, dummy, act_out_swr, act_out_rwr; + + if ((((u64)cb_addr) & (PAGE_SIZE - 1)) != 0) { + ehea_error("not on page boundary"); + return H_PARAMETER; + } + + hret = ehea_hcall_9arg_9ret(H_MODIFY_HEA_QP, + adapter_handle, /* R4 */ + (u64) cat, /* R5 */ + qp_handle, /* R6 */ + sel_mask, /* R7 */ + virt_to_abs(cb_addr), /* R8 */ + 0, 0, 0, 0, /* R9-R12 */ + inv_attr_id, /* R4 */ + &dummy, /* R5 */ + &dummy, /* R6 */ + &act_out_swr, /* R7 */ + &act_out_rwr, /* R8 */ + proc_mask, /* R9 */ + &dummy, /* R10 */ + &dummy, /* R11 */ + &dummy); /* R12 */ + *out_swr = act_out_swr; + *out_rwr = act_out_rwr; return hret; } @@ -424,81 +435,122 @@ u64 ehea_h_register_rpage(const u64 adapter_handle, const u8 pagesize, const u8 queue_type, const u64 resource_handle, const u64 log_pageaddr, u64 count) { - u64 reg_control; + u64 dummy, reg_control; reg_control = EHEA_BMASK_SET(H_REG_RPAGE_PAGE_SIZE, pagesize) | EHEA_BMASK_SET(H_REG_RPAGE_QT, queue_type); - return ehea_plpar_hcall_norets(H_REGISTER_HEA_RPAGES, - adapter_handle, /* R4 */ - reg_control, /* R5 */ - resource_handle, /* R6 */ - log_pageaddr, /* R7 */ - count, /* R8 */ - 0, 0); /* R9-R10 */ + return ehea_hcall_9arg_9ret(H_REGISTER_HEA_RPAGES, + adapter_handle, /* R4 */ + reg_control, /* R5 */ + resource_handle, /* R6 */ + log_pageaddr, /* R7 */ + count, /* R8 */ + 0, 0, 0, 0, /* R9-R12 */ + &dummy, /* R4 */ + &dummy, /* R5 */ + &dummy, /* R6 */ + &dummy, /* R7 */ + &dummy, /* R8 */ + &dummy, /* R9 */ + &dummy, /* R10 */ + &dummy, /* R11 */ + &dummy); /* R12 */ } u64 ehea_h_register_smr(const u64 adapter_handle, const u64 orig_mr_handle, const u64 vaddr_in, const u32 access_ctrl, const u32 pd, struct ehea_mr *mr) { - u64 hret; - u64 outs[PLPAR_HCALL9_BUFSIZE]; - - hret = ehea_plpar_hcall9(H_REGISTER_SMR, - outs, - adapter_handle , /* R4 */ - orig_mr_handle, /* R5 */ - vaddr_in, /* R6 */ - (((u64)access_ctrl) << 32ULL), /* R7 */ - pd, /* R8 */ - 0, 0, 0, 0); /* R9-R12 */ - - mr->handle = outs[0]; - mr->lkey = (u32)outs[2]; + u64 hret, dummy, lkey_out; + + hret = ehea_hcall_9arg_9ret(H_REGISTER_SMR, + adapter_handle , /* R4 */ + orig_mr_handle, /* R5 */ + vaddr_in, /* R6 */ + (((u64)access_ctrl) << 32ULL), /* R7 */ + pd, /* R8 */ + 0, 0, 0, 0, /* R9-R12 */ + &mr->handle, /* R4 */ + &dummy, /* R5 */ + &lkey_out, /* R6 */ + &dummy, /* R7 */ + &dummy, /* R8 */ + &dummy, /* R9 */ + &dummy, /* R10 */ + &dummy, /* R11 */ + &dummy); /* R12 */ + mr->lkey = (u32)lkey_out; return hret; } u64 ehea_h_disable_and_get_hea(const u64 adapter_handle, const u64 qp_handle) { - u64 outs[PLPAR_HCALL9_BUFSIZE]; - - return ehea_plpar_hcall9(H_DISABLE_AND_GET_HEA, - outs, - adapter_handle, /* R4 */ - H_DISABLE_GET_EHEA_WQE_P, /* R5 */ - qp_handle, /* R6 */ - 0, 0, 0, 0, 0, 0); /* R7-R12 */ + u64 hret, dummy, ladr_next_sq_wqe_out; + u64 ladr_next_rq1_wqe_out, ladr_next_rq2_wqe_out, ladr_next_rq3_wqe_out; + + hret = ehea_hcall_9arg_9ret(H_DISABLE_AND_GET_HEA, + adapter_handle, /* R4 */ + H_DISABLE_GET_EHEA_WQE_P, /* R5 */ + qp_handle, /* R6 */ + 0, 0, 0, 0, 0, 0, /* R7-R12 */ + &ladr_next_sq_wqe_out, /* R4 */ + &ladr_next_rq1_wqe_out, /* R5 */ + &ladr_next_rq2_wqe_out, /* R6 */ + &ladr_next_rq3_wqe_out, /* R7 */ + &dummy, /* R8 */ + &dummy, /* R9 */ + &dummy, /* R10 */ + &dummy, /* R11 */ + &dummy); /* R12 */ + return hret; } u64 ehea_h_free_resource(const u64 adapter_handle, const u64 res_handle) { - return ehea_plpar_hcall_norets(H_FREE_RESOURCE, - adapter_handle, /* R4 */ - res_handle, /* R5 */ - 0, 0, 0, 0, 0); /* R6-R10 */ + u64 dummy; + + return ehea_hcall_9arg_9ret(H_FREE_RESOURCE, + adapter_handle, /* R4 */ + res_handle, /* R5 */ + 0, 0, 0, 0, 0, 0, 0, /* R6-R12 */ + &dummy, /* R4 */ + &dummy, /* R5 */ + &dummy, /* R6 */ + &dummy, /* R7 */ + &dummy, /* R8 */ + &dummy, /* R9 */ + &dummy, /* R10 */ + &dummy, /* R11 */ + &dummy); /* R12 */ } u64 ehea_h_alloc_resource_mr(const u64 adapter_handle, const u64 vaddr, const u64 length, const u32 access_ctrl, const u32 pd, u64 *mr_handle, u32 *lkey) { - u64 hret; - u64 outs[PLPAR_HCALL9_BUFSIZE]; - - hret = ehea_plpar_hcall9(H_ALLOC_HEA_RESOURCE, - outs, - adapter_handle, /* R4 */ - 5, /* R5 */ - vaddr, /* R6 */ - length, /* R7 */ - (((u64) access_ctrl) << 32ULL), /* R8 */ - pd, /* R9 */ - 0, 0, 0); /* R10-R12 */ - - *mr_handle = outs[0]; - *lkey = (u32)outs[2]; + u64 hret, dummy, lkey_out; + + hret = ehea_hcall_9arg_9ret(H_ALLOC_HEA_RESOURCE, + adapter_handle, /* R4 */ + 5, /* R5 */ + vaddr, /* R6 */ + length, /* R7 */ + (((u64) access_ctrl) << 32ULL),/* R8 */ + pd, /* R9 */ + 0, 0, 0, /* R10-R12 */ + mr_handle, /* R4 */ + &dummy, /* R5 */ + &lkey_out, /* R6 */ + &dummy, /* R7 */ + &dummy, /* R8 */ + &dummy, /* R9 */ + &dummy, /* R10 */ + &dummy, /* R11 */ + &dummy); /* R12 */ + *lkey = (u32) lkey_out; + return hret; } @@ -506,7 +558,7 @@ u64 ehea_h_register_rpage_mr(const u64 adapter_handle, const u64 mr_handle, const u8 pagesize, const u8 queue_type, const u64 log_pageaddr, const u64 count) { - if ((count > 1) && (log_pageaddr & ~PAGE_MASK)) { + if ((count > 1) && (log_pageaddr & 0xfff)) { ehea_error("not on pageboundary"); return H_PARAMETER; } @@ -518,14 +570,23 @@ u64 ehea_h_register_rpage_mr(const u64 adapter_handle, const u64 mr_handle, u64 ehea_h_query_ehea(const u64 adapter_handle, void *cb_addr) { - u64 hret, cb_logaddr; + u64 hret, dummy, cb_logaddr; cb_logaddr = virt_to_abs(cb_addr); - hret = ehea_plpar_hcall_norets(H_QUERY_HEA, - adapter_handle, /* R4 */ - cb_logaddr, /* R5 */ - 0, 0, 0, 0, 0); /* R6-R10 */ + hret = ehea_hcall_9arg_9ret(H_QUERY_HEA, + adapter_handle, /* R4 */ + cb_logaddr, /* R5 */ + 0, 0, 0, 0, 0, 0, 0, /* R6-R12 */ + &dummy, /* R4 */ + &dummy, /* R5 */ + &dummy, /* R6 */ + &dummy, /* R7 */ + &dummy, /* R8 */ + &dummy, /* R9 */ + &dummy, /* R10 */ + &dummy, /* R11 */ + &dummy); /* R12 */ #ifdef DEBUG ehea_dmp(cb_addr, sizeof(struct hcp_query_ehea), "hcp_query_ehea"); #endif @@ -536,28 +597,36 @@ u64 ehea_h_query_ehea_port(const u64 adapter_handle, const u16 port_num, const u8 cb_cat, const u64 select_mask, void *cb_addr) { - u64 port_info; + u64 port_info, dummy; u64 cb_logaddr = virt_to_abs(cb_addr); u64 arr_index = 0; port_info = EHEA_BMASK_SET(H_MEHEAPORT_CAT, cb_cat) | EHEA_BMASK_SET(H_MEHEAPORT_PN, port_num); - return ehea_plpar_hcall_norets(H_QUERY_HEA_PORT, - adapter_handle, /* R4 */ - port_info, /* R5 */ - select_mask, /* R6 */ - arr_index, /* R7 */ - cb_logaddr, /* R8 */ - 0, 0); /* R9-R10 */ + return ehea_hcall_9arg_9ret(H_QUERY_HEA_PORT, + adapter_handle, /* R4 */ + port_info, /* R5 */ + select_mask, /* R6 */ + arr_index, /* R7 */ + cb_logaddr, /* R8 */ + 0, 0, 0, 0, /* R9-R12 */ + &dummy, /* R4 */ + &dummy, /* R5 */ + &dummy, /* R6 */ + &dummy, /* R7 */ + &dummy, /* R8 */ + &dummy, /* R9 */ + &dummy, /* R10 */ + &dummy, /* R11 */ + &dummy); /* R12 */ } u64 ehea_h_modify_ehea_port(const u64 adapter_handle, const u16 port_num, const u8 cb_cat, const u64 select_mask, void *cb_addr) { - u64 outs[PLPAR_HCALL9_BUFSIZE]; - u64 port_info; + u64 port_info, dummy, inv_attr_ident, proc_mask; u64 arr_index = 0; u64 cb_logaddr = virt_to_abs(cb_addr); @@ -566,21 +635,29 @@ u64 ehea_h_modify_ehea_port(const u64 adapter_handle, const u16 port_num, #ifdef DEBUG ehea_dump(cb_addr, sizeof(struct hcp_ehea_port_cb0), "Before HCALL"); #endif - return ehea_plpar_hcall9(H_MODIFY_HEA_PORT, - outs, - adapter_handle, /* R4 */ - port_info, /* R5 */ - select_mask, /* R6 */ - arr_index, /* R7 */ - cb_logaddr, /* R8 */ - 0, 0, 0, 0); /* R9-R12 */ + return ehea_hcall_9arg_9ret(H_MODIFY_HEA_PORT, + adapter_handle, /* R4 */ + port_info, /* R5 */ + select_mask, /* R6 */ + arr_index, /* R7 */ + cb_logaddr, /* R8 */ + 0, 0, 0, 0, /* R9-R12 */ + &inv_attr_ident, /* R4 */ + &proc_mask, /* R5 */ + &dummy, /* R6 */ + &dummy, /* R7 */ + &dummy, /* R8 */ + &dummy, /* R9 */ + &dummy, /* R10 */ + &dummy, /* R11 */ + &dummy); /* R12 */ } u64 ehea_h_reg_dereg_bcmc(const u64 adapter_handle, const u16 port_num, const u8 reg_type, const u64 mc_mac_addr, const u16 vlan_id, const u32 hcall_id) { - u64 r5_port_num, r6_reg_type, r7_mc_mac_addr, r8_vlan_id; + u64 r5_port_num, r6_reg_type, r7_mc_mac_addr, r8_vlan_id, dummy; u64 mac_addr = mc_mac_addr >> 16; r5_port_num = EHEA_BMASK_SET(H_REGBCMC_PN, port_num); @@ -588,21 +665,41 @@ u64 ehea_h_reg_dereg_bcmc(const u64 adapter_handle, const u16 port_num, r7_mc_mac_addr = EHEA_BMASK_SET(H_REGBCMC_MACADDR, mac_addr); r8_vlan_id = EHEA_BMASK_SET(H_REGBCMC_VLANID, vlan_id); - return ehea_plpar_hcall_norets(hcall_id, - adapter_handle, /* R4 */ - r5_port_num, /* R5 */ - r6_reg_type, /* R6 */ - r7_mc_mac_addr, /* R7 */ - r8_vlan_id, /* R8 */ - 0, 0); /* R9-R12 */ + return ehea_hcall_9arg_9ret(hcall_id, + adapter_handle, /* R4 */ + r5_port_num, /* R5 */ + r6_reg_type, /* R6 */ + r7_mc_mac_addr, /* R7 */ + r8_vlan_id, /* R8 */ + 0, 0, 0, 0, /* R9-R12 */ + &dummy, /* R4 */ + &dummy, /* R5 */ + &dummy, /* R6 */ + &dummy, /* R7 */ + &dummy, /* R8 */ + &dummy, /* R9 */ + &dummy, /* R10 */ + &dummy, /* R11 */ + &dummy); /* R12 */ } u64 ehea_h_reset_events(const u64 adapter_handle, const u64 neq_handle, const u64 event_mask) { - return ehea_plpar_hcall_norets(H_RESET_EVENTS, - adapter_handle, /* R4 */ - neq_handle, /* R5 */ - event_mask, /* R6 */ - 0, 0, 0, 0); /* R7-R12 */ + u64 dummy; + + return ehea_hcall_9arg_9ret(H_RESET_EVENTS, + adapter_handle, /* R4 */ + neq_handle, /* R5 */ + event_mask, /* R6 */ + 0, 0, 0, 0, 0, 0, /* R7-R12 */ + &dummy, /* R4 */ + &dummy, /* R5 */ + &dummy, /* R6 */ + &dummy, /* R7 */ + &dummy, /* R8 */ + &dummy, /* R9 */ + &dummy, /* R10 */ + &dummy, /* R11 */ + &dummy); /* R12 */ } diff --git a/trunk/drivers/net/ehea/ehea_phyp.h b/trunk/drivers/net/ehea/ehea_phyp.h index 919f94b75933..fa51e3b5bb05 100644 --- a/trunk/drivers/net/ehea/ehea_phyp.h +++ b/trunk/drivers/net/ehea/ehea_phyp.h @@ -81,16 +81,14 @@ static inline u32 get_longbusy_msecs(int long_busy_ret_code) static inline void hcp_epas_ctor(struct h_epas *epas, u64 paddr_kernel, u64 paddr_user) { - /* To support 64k pages we must round to 64k page boundary */ - epas->kernel.addr = ioremap((paddr_kernel & PAGE_MASK), PAGE_SIZE) + - (paddr_kernel & ~PAGE_MASK); + epas->kernel.addr = ioremap(paddr_kernel, PAGE_SIZE); epas->user.addr = paddr_user; } static inline void hcp_epas_dtor(struct h_epas *epas) { if (epas->kernel.addr) - iounmap((void __iomem*)((u64)epas->kernel.addr & PAGE_MASK)); + iounmap(epas->kernel.addr); epas->user.addr = 0; epas->kernel.addr = 0; diff --git a/trunk/drivers/net/ehea/ehea_qmr.c b/trunk/drivers/net/ehea/ehea_qmr.c index 72ef7bde3346..3e1862326c88 100644 --- a/trunk/drivers/net/ehea/ehea_qmr.c +++ b/trunk/drivers/net/ehea/ehea_qmr.c @@ -209,11 +209,11 @@ int ehea_destroy_cq(struct ehea_cq *cq) { u64 adapter_handle, hret; + adapter_handle = cq->adapter->handle; + if (!cq) return 0; - adapter_handle = cq->adapter->handle; - /* deregister all previous registered pages */ hret = ehea_h_free_resource(adapter_handle, cq->fw_handle); if (hret != H_SUCCESS) { @@ -512,7 +512,7 @@ int ehea_reg_mr_adapter(struct ehea_adapter *adapter) start = KERNELBASE; end = (u64)high_memory; - nr_pages = (end - start) / EHEA_PAGESIZE; + nr_pages = (end - start) / PAGE_SIZE; pt = kzalloc(PAGE_SIZE, GFP_KERNEL); if (!pt) { @@ -538,9 +538,9 @@ int ehea_reg_mr_adapter(struct ehea_adapter *adapter) if (nr_pages > 1) { u64 num_pages = min(nr_pages, (u64)512); for (i = 0; i < num_pages; i++) - pt[i] = virt_to_abs((void*)(((u64)start) + - ((k++) * - EHEA_PAGESIZE))); + pt[i] = virt_to_abs((void*)(((u64)start) + + ((k++) * + PAGE_SIZE))); hret = ehea_h_register_rpage_mr(adapter->handle, adapter->mr.handle, 0, @@ -548,9 +548,8 @@ int ehea_reg_mr_adapter(struct ehea_adapter *adapter) num_pages); nr_pages -= num_pages; } else { - u64 abs_adr = virt_to_abs((void*)(((u64)start) + - (k * EHEA_PAGESIZE))); - + u64 abs_adr = virt_to_abs((void*)(((u64)start) + + (k * PAGE_SIZE))); hret = ehea_h_register_rpage_mr(adapter->handle, adapter->mr.handle, 0, 0, abs_adr,1); diff --git a/trunk/drivers/net/epic100.c b/trunk/drivers/net/epic100.c index 3a6a83d3ee1c..ba2565ee0439 100644 --- a/trunk/drivers/net/epic100.c +++ b/trunk/drivers/net/epic100.c @@ -297,7 +297,7 @@ static void epic_init_ring(struct net_device *dev); static int epic_start_xmit(struct sk_buff *skb, struct net_device *dev); static int epic_rx(struct net_device *dev, int budget); static int epic_poll(struct net_device *dev, int *budget); -static irqreturn_t epic_interrupt(int irq, void *dev_instance); +static irqreturn_t epic_interrupt(int irq, void *dev_instance, struct pt_regs *regs); static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); static const struct ethtool_ops netdev_ethtool_ops; static int epic_close(struct net_device *dev); @@ -1081,7 +1081,7 @@ static void epic_tx(struct net_device *dev, struct epic_private *ep) /* The interrupt handler does all of the Rx thread work and cleans up after the Tx thread. */ -static irqreturn_t epic_interrupt(int irq, void *dev_instance) +static irqreturn_t epic_interrupt(int irq, void *dev_instance, struct pt_regs *regs) { struct net_device *dev = dev_instance; struct epic_private *ep = dev->priv; diff --git a/trunk/drivers/net/eth16i.c b/trunk/drivers/net/eth16i.c index b7b8bc2a6307..f16b6a5aaa34 100644 --- a/trunk/drivers/net/eth16i.c +++ b/trunk/drivers/net/eth16i.c @@ -162,9 +162,9 @@ static char *version = #include #include #include -#include #include +#include #include @@ -410,7 +410,7 @@ static int eth16i_close(struct net_device *dev); static int eth16i_tx(struct sk_buff *skb, struct net_device *dev); static void eth16i_rx(struct net_device *dev); static void eth16i_timeout(struct net_device *dev); -static irqreturn_t eth16i_interrupt(int irq, void *dev_id); +static irqreturn_t eth16i_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void eth16i_reset(struct net_device *dev); static void eth16i_timeout(struct net_device *dev); static void eth16i_skip_packet(struct net_device *dev); @@ -1226,7 +1226,7 @@ static void eth16i_rx(struct net_device *dev) } /* while */ } -static irqreturn_t eth16i_interrupt(int irq, void *dev_id) +static irqreturn_t eth16i_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; struct eth16i_local *lp; diff --git a/trunk/drivers/net/ewrk3.c b/trunk/drivers/net/ewrk3.c index c8c41f0a47d6..75a43f7c70cf 100644 --- a/trunk/drivers/net/ewrk3.c +++ b/trunk/drivers/net/ewrk3.c @@ -300,7 +300,7 @@ struct ewrk3_private { */ static int ewrk3_open(struct net_device *dev); static int ewrk3_queue_pkt(struct sk_buff *skb, struct net_device *dev); -static irqreturn_t ewrk3_interrupt(int irq, void *dev_id); +static irqreturn_t ewrk3_interrupt(int irq, void *dev_id, struct pt_regs *regs); static int ewrk3_close(struct net_device *dev); static struct net_device_stats *ewrk3_get_stats(struct net_device *dev); static void set_multicast_list(struct net_device *dev); @@ -884,7 +884,7 @@ static int ewrk3_queue_pkt (struct sk_buff *skb, struct net_device *dev) /* ** The EWRK3 interrupt handler. */ -static irqreturn_t ewrk3_interrupt(int irq, void *dev_id) +static irqreturn_t ewrk3_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; struct ewrk3_private *lp; diff --git a/trunk/drivers/net/fealnx.c b/trunk/drivers/net/fealnx.c index 38a13f440530..191bd429076a 100644 --- a/trunk/drivers/net/fealnx.c +++ b/trunk/drivers/net/fealnx.c @@ -434,7 +434,7 @@ static void reset_timer(unsigned long data); static void tx_timeout(struct net_device *dev); static void init_ring(struct net_device *dev); static int start_tx(struct sk_buff *skb, struct net_device *dev); -static irqreturn_t intr_handler(int irq, void *dev_instance); +static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *regs); static int netdev_rx(struct net_device *dev); static void set_rx_mode(struct net_device *dev); static void __set_rx_mode(struct net_device *dev); @@ -1453,7 +1453,7 @@ static void reset_rx_descriptors(struct net_device *dev) /* The interrupt handler does all of the Rx thread work and cleans up after the Tx thread. */ -static irqreturn_t intr_handler(int irq, void *dev_instance) +static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *rgs) { struct net_device *dev = (struct net_device *) dev_instance; struct netdev_private *np = netdev_priv(dev); diff --git a/trunk/drivers/net/fec.c b/trunk/drivers/net/fec.c index 6764281b4531..55d86bc4c104 100644 --- a/trunk/drivers/net/fec.c +++ b/trunk/drivers/net/fec.c @@ -229,7 +229,7 @@ struct fec_enet_private { static int fec_enet_open(struct net_device *dev); static int fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev); static void fec_enet_mii(struct net_device *dev); -static irqreturn_t fec_enet_interrupt(int irq, void * dev_id); +static irqreturn_t fec_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs); static void fec_enet_tx(struct net_device *dev); static void fec_enet_rx(struct net_device *dev); static int fec_enet_close(struct net_device *dev); @@ -450,7 +450,7 @@ fec_timeout(struct net_device *dev) * This is called from the MPC core interrupt. */ static irqreturn_t -fec_enet_interrupt(int irq, void * dev_id) +fec_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs) { struct net_device *dev = dev_id; volatile fec_t *fecp; @@ -1236,7 +1236,7 @@ static void mii_link_interrupt(void *dev_id); #else static irqreturn_t -mii_link_interrupt(int irq, void * dev_id); +mii_link_interrupt(int irq, void * dev_id, struct pt_regs * regs); #endif #endif @@ -1251,7 +1251,7 @@ static void __inline__ fec_request_intrs(struct net_device *dev) static const struct idesc { char *name; unsigned short irq; - irq_handler_t handler; + irqreturn_t (*handler)(int, void *, struct pt_regs *); } *idp, id[] = { { "fec(RX)", 86, fec_enet_interrupt }, { "fec(TX)", 87, fec_enet_interrupt }, @@ -2117,7 +2117,7 @@ static void mii_link_interrupt(void *dev_id) #else static irqreturn_t -mii_link_interrupt(int irq, void * dev_id) +mii_link_interrupt(int irq, void * dev_id, struct pt_regs * regs) #endif { struct net_device *dev = dev_id; diff --git a/trunk/drivers/net/fec_8xx/fec_main.c b/trunk/drivers/net/fec_8xx/fec_main.c index 8e7a56fadfd2..e17a1449ee10 100644 --- a/trunk/drivers/net/fec_8xx/fec_main.c +++ b/trunk/drivers/net/fec_8xx/fec_main.c @@ -708,7 +708,7 @@ static void fec_enet_tx(struct net_device *dev) * This is called from the MPC core interrupt. */ static irqreturn_t -fec_enet_interrupt(int irq, void *dev_id) +fec_enet_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; struct fec_enet_private *fep; @@ -768,7 +768,7 @@ fec_enet_interrupt(int irq, void *dev_id) /* This interrupt occurs when the PHY detects a link change. */ static irqreturn_t -fec_mii_link_interrupt(int irq, void *dev_id) +fec_mii_link_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; struct fec_enet_private *fep; diff --git a/trunk/drivers/net/forcedeth.c b/trunk/drivers/net/forcedeth.c index c5ed635bce36..eea1d66c530e 100644 --- a/trunk/drivers/net/forcedeth.c +++ b/trunk/drivers/net/forcedeth.c @@ -2397,7 +2397,7 @@ static void nv_link_irq(struct net_device *dev) dprintk(KERN_DEBUG "%s: link change notification done.\n", dev->name); } -static irqreturn_t nv_nic_irq(int foo, void *data) +static irqreturn_t nv_nic_irq(int foo, void *data, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) data; struct fe_priv *np = netdev_priv(dev); @@ -2490,14 +2490,13 @@ static irqreturn_t nv_nic_irq(int foo, void *data) return IRQ_RETVAL(i); } -static irqreturn_t nv_nic_irq_tx(int foo, void *data) +static irqreturn_t nv_nic_irq_tx(int foo, void *data, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) data; struct fe_priv *np = netdev_priv(dev); u8 __iomem *base = get_hwbase(dev); u32 events; int i; - unsigned long flags; dprintk(KERN_DEBUG "%s: nv_nic_irq_tx\n", dev->name); @@ -2509,16 +2508,16 @@ static irqreturn_t nv_nic_irq_tx(int foo, void *data) if (!(events & np->irqmask)) break; - spin_lock_irqsave(&np->lock, flags); + spin_lock_irq(&np->lock); nv_tx_done(dev); - spin_unlock_irqrestore(&np->lock, flags); + spin_unlock_irq(&np->lock); if (events & (NVREG_IRQ_TX_ERR)) { dprintk(KERN_DEBUG "%s: received irq with events 0x%x. Probably TX fail.\n", dev->name, events); } if (i > max_interrupt_work) { - spin_lock_irqsave(&np->lock, flags); + spin_lock_irq(&np->lock); /* disable interrupts on the nic */ writel(NVREG_IRQ_TX_ALL, base + NvRegIrqMask); pci_push(base); @@ -2528,7 +2527,7 @@ static irqreturn_t nv_nic_irq_tx(int foo, void *data) mod_timer(&np->nic_poll, jiffies + POLL_WAIT); } printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_tx.\n", dev->name, i); - spin_unlock_irqrestore(&np->lock, flags); + spin_unlock_irq(&np->lock); break; } @@ -2577,7 +2576,7 @@ static int nv_napi_poll(struct net_device *dev, int *budget) #endif #ifdef CONFIG_FORCEDETH_NAPI -static irqreturn_t nv_nic_irq_rx(int foo, void *data) +static irqreturn_t nv_nic_irq_rx(int foo, void *data, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) data; u8 __iomem *base = get_hwbase(dev); @@ -2595,14 +2594,13 @@ static irqreturn_t nv_nic_irq_rx(int foo, void *data) return IRQ_HANDLED; } #else -static irqreturn_t nv_nic_irq_rx(int foo, void *data) +static irqreturn_t nv_nic_irq_rx(int foo, void *data, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) data; struct fe_priv *np = netdev_priv(dev); u8 __iomem *base = get_hwbase(dev); u32 events; int i; - unsigned long flags; dprintk(KERN_DEBUG "%s: nv_nic_irq_rx\n", dev->name); @@ -2616,14 +2614,14 @@ static irqreturn_t nv_nic_irq_rx(int foo, void *data) nv_rx_process(dev, dev->weight); if (nv_alloc_rx(dev)) { - spin_lock_irqsave(&np->lock, flags); + spin_lock_irq(&np->lock); if (!np->in_shutdown) mod_timer(&np->oom_kick, jiffies + OOM_REFILL); - spin_unlock_irqrestore(&np->lock, flags); + spin_unlock_irq(&np->lock); } if (i > max_interrupt_work) { - spin_lock_irqsave(&np->lock, flags); + spin_lock_irq(&np->lock); /* disable interrupts on the nic */ writel(NVREG_IRQ_RX_ALL, base + NvRegIrqMask); pci_push(base); @@ -2633,7 +2631,7 @@ static irqreturn_t nv_nic_irq_rx(int foo, void *data) mod_timer(&np->nic_poll, jiffies + POLL_WAIT); } printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_rx.\n", dev->name, i); - spin_unlock_irqrestore(&np->lock, flags); + spin_unlock_irq(&np->lock); break; } } @@ -2643,14 +2641,13 @@ static irqreturn_t nv_nic_irq_rx(int foo, void *data) } #endif -static irqreturn_t nv_nic_irq_other(int foo, void *data) +static irqreturn_t nv_nic_irq_other(int foo, void *data, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) data; struct fe_priv *np = netdev_priv(dev); u8 __iomem *base = get_hwbase(dev); u32 events; int i; - unsigned long flags; dprintk(KERN_DEBUG "%s: nv_nic_irq_other\n", dev->name); @@ -2663,14 +2660,14 @@ static irqreturn_t nv_nic_irq_other(int foo, void *data) break; if (events & NVREG_IRQ_LINK) { - spin_lock_irqsave(&np->lock, flags); + spin_lock_irq(&np->lock); nv_link_irq(dev); - spin_unlock_irqrestore(&np->lock, flags); + spin_unlock_irq(&np->lock); } if (np->need_linktimer && time_after(jiffies, np->link_timeout)) { - spin_lock_irqsave(&np->lock, flags); + spin_lock_irq(&np->lock); nv_linkchange(dev); - spin_unlock_irqrestore(&np->lock, flags); + spin_unlock_irq(&np->lock); np->link_timeout = jiffies + LINK_TIMEOUT; } if (events & (NVREG_IRQ_UNKNOWN)) { @@ -2678,7 +2675,7 @@ static irqreturn_t nv_nic_irq_other(int foo, void *data) dev->name, events); } if (i > max_interrupt_work) { - spin_lock_irqsave(&np->lock, flags); + spin_lock_irq(&np->lock); /* disable interrupts on the nic */ writel(NVREG_IRQ_OTHER, base + NvRegIrqMask); pci_push(base); @@ -2688,7 +2685,7 @@ static irqreturn_t nv_nic_irq_other(int foo, void *data) mod_timer(&np->nic_poll, jiffies + POLL_WAIT); } printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_other.\n", dev->name, i); - spin_unlock_irqrestore(&np->lock, flags); + spin_unlock_irq(&np->lock); break; } @@ -2698,7 +2695,7 @@ static irqreturn_t nv_nic_irq_other(int foo, void *data) return IRQ_RETVAL(i); } -static irqreturn_t nv_nic_irq_test(int foo, void *data) +static irqreturn_t nv_nic_irq_test(int foo, void *data, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) data; struct fe_priv *np = netdev_priv(dev); @@ -2908,22 +2905,22 @@ static void nv_do_nic_poll(unsigned long data) pci_push(base); if (!using_multi_irqs(dev)) { - nv_nic_irq(0, dev); + nv_nic_irq(0, dev, NULL); if (np->msi_flags & NV_MSI_X_ENABLED) enable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); else enable_irq_lockdep(dev->irq); } else { if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) { - nv_nic_irq_rx(0, dev); + nv_nic_irq_rx(0, dev, NULL); enable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector); } if (np->nic_poll_irq & NVREG_IRQ_TX_ALL) { - nv_nic_irq_tx(0, dev); + nv_nic_irq_tx(0, dev, NULL); enable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector); } if (np->nic_poll_irq & NVREG_IRQ_OTHER) { - nv_nic_irq_other(0, dev); + nv_nic_irq_other(0, dev, NULL); enable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_OTHER].vector); } } diff --git a/trunk/drivers/net/fs_enet/fs_enet-main.c b/trunk/drivers/net/fs_enet/fs_enet-main.c index cb3958704a87..d01870619a4a 100644 --- a/trunk/drivers/net/fs_enet/fs_enet-main.c +++ b/trunk/drivers/net/fs_enet/fs_enet-main.c @@ -441,7 +441,7 @@ static void fs_enet_tx(struct net_device *dev) * This is called from the MPC core interrupt. */ static irqreturn_t -fs_enet_interrupt(int irq, void *dev_id) +fs_enet_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; struct fs_enet_private *fep; @@ -667,7 +667,7 @@ static int fs_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) } static int fs_request_irq(struct net_device *dev, int irq, const char *name, - irq_handler_t irqf) + irqreturn_t (*irqf)(int irq, void *dev_id, struct pt_regs *regs)) { struct fs_enet_private *fep = netdev_priv(dev); diff --git a/trunk/drivers/net/gianfar.c b/trunk/drivers/net/gianfar.c index a06d8d1aaceb..280b114e253f 100644 --- a/trunk/drivers/net/gianfar.c +++ b/trunk/drivers/net/gianfar.c @@ -119,9 +119,9 @@ struct sk_buff *gfar_new_skb(struct net_device *dev, struct rxbd8 *bdp); static struct net_device_stats *gfar_get_stats(struct net_device *dev); static int gfar_set_mac_address(struct net_device *dev); static int gfar_change_mtu(struct net_device *dev, int new_mtu); -static irqreturn_t gfar_error(int irq, void *dev_id); -static irqreturn_t gfar_transmit(int irq, void *dev_id); -static irqreturn_t gfar_interrupt(int irq, void *dev_id); +static irqreturn_t gfar_error(int irq, void *dev_id, struct pt_regs *regs); +static irqreturn_t gfar_transmit(int irq, void *dev_id, struct pt_regs *regs); +static irqreturn_t gfar_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void adjust_link(struct net_device *dev); static void init_registers(struct net_device *dev); static int init_phy(struct net_device *dev); @@ -1173,7 +1173,7 @@ static void gfar_timeout(struct net_device *dev) } /* Interrupt Handler for Transmit complete */ -static irqreturn_t gfar_transmit(int irq, void *dev_id) +static irqreturn_t gfar_transmit(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_id; struct gfar_private *priv = netdev_priv(dev); @@ -1305,7 +1305,7 @@ static inline void count_errors(unsigned short status, struct gfar_private *priv } } -irqreturn_t gfar_receive(int irq, void *dev_id) +irqreturn_t gfar_receive(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_id; struct gfar_private *priv = netdev_priv(dev); @@ -1537,7 +1537,7 @@ static int gfar_poll(struct net_device *dev, int *budget) #endif /* The interrupt handler for devices with one interrupt */ -static irqreturn_t gfar_interrupt(int irq, void *dev_id) +static irqreturn_t gfar_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; struct gfar_private *priv = netdev_priv(dev); @@ -1550,11 +1550,11 @@ static irqreturn_t gfar_interrupt(int irq, void *dev_id) /* Check for reception */ if ((events & IEVENT_RXF0) || (events & IEVENT_RXB0)) - gfar_receive(irq, dev_id); + gfar_receive(irq, dev_id, regs); /* Check for transmit completion */ if ((events & IEVENT_TXF) || (events & IEVENT_TXB)) - gfar_transmit(irq, dev_id); + gfar_transmit(irq, dev_id, regs); /* Update error statistics */ if (events & IEVENT_TXE) { @@ -1578,7 +1578,7 @@ static irqreturn_t gfar_interrupt(int irq, void *dev_id) priv->stats.rx_errors++; priv->extra_stats.rx_bsy++; - gfar_receive(irq, dev_id); + gfar_receive(irq, dev_id, regs); #ifndef CONFIG_GFAR_NAPI /* Clear the halt bit in RSTAT */ @@ -1857,7 +1857,7 @@ static void gfar_set_mac_for_addr(struct net_device *dev, int num, u8 *addr) } /* GFAR error interrupt handler */ -static irqreturn_t gfar_error(int irq, void *dev_id) +static irqreturn_t gfar_error(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; struct gfar_private *priv = netdev_priv(dev); @@ -1898,7 +1898,7 @@ static irqreturn_t gfar_error(int irq, void *dev_id) priv->stats.rx_errors++; priv->extra_stats.rx_bsy++; - gfar_receive(irq, dev_id); + gfar_receive(irq, dev_id, regs); #ifndef CONFIG_GFAR_NAPI /* Clear the halt bit in RSTAT */ diff --git a/trunk/drivers/net/gianfar.h b/trunk/drivers/net/gianfar.h index 9e81a50cf2be..c35d47c40c39 100644 --- a/trunk/drivers/net/gianfar.h +++ b/trunk/drivers/net/gianfar.h @@ -754,7 +754,7 @@ static inline void gfar_write(volatile unsigned __iomem *addr, u32 val) out_be32(addr, val); } -extern irqreturn_t gfar_receive(int irq, void *dev_id); +extern irqreturn_t gfar_receive(int irq, void *dev_id, struct pt_regs *regs); extern int startup_gfar(struct net_device *dev); extern void stop_gfar(struct net_device *dev); extern void gfar_halt(struct net_device *dev); diff --git a/trunk/drivers/net/hamachi.c b/trunk/drivers/net/hamachi.c index c3c0d67fc383..5c89ae78a519 100644 --- a/trunk/drivers/net/hamachi.c +++ b/trunk/drivers/net/hamachi.c @@ -556,7 +556,7 @@ static void hamachi_timer(unsigned long data); static void hamachi_tx_timeout(struct net_device *dev); static void hamachi_init_ring(struct net_device *dev); static int hamachi_start_xmit(struct sk_buff *skb, struct net_device *dev); -static irqreturn_t hamachi_interrupt(int irq, void *dev_instance); +static irqreturn_t hamachi_interrupt(int irq, void *dev_instance, struct pt_regs *regs); static int hamachi_rx(struct net_device *dev); static inline int hamachi_tx(struct net_device *dev); static void hamachi_error(struct net_device *dev, int intr_status); @@ -1376,7 +1376,7 @@ static int hamachi_start_xmit(struct sk_buff *skb, struct net_device *dev) /* The interrupt handler does all of the Rx thread work and cleans up after the Tx thread. */ -static irqreturn_t hamachi_interrupt(int irq, void *dev_instance) +static irqreturn_t hamachi_interrupt(int irq, void *dev_instance, struct pt_regs *rgs) { struct net_device *dev = dev_instance; struct hamachi_private *hmp = netdev_priv(dev); diff --git a/trunk/drivers/net/hamradio/6pack.c b/trunk/drivers/net/hamradio/6pack.c index 92420f007b97..86b3bb9bec2d 100644 --- a/trunk/drivers/net/hamradio/6pack.c +++ b/trunk/drivers/net/hamradio/6pack.c @@ -914,7 +914,7 @@ static void decode_prio_command(struct sixpack *sp, unsigned char cmd) printk(KERN_DEBUG "6pack: protocol violation\n"); else sp->status = 0; - cmd &= ~SIXP_RX_DCD_MASK; + cmd &= !SIXP_RX_DCD_MASK; } sp->status = cmd & SIXP_PRIO_DATA_MASK; } else { /* output watchdog char if idle */ diff --git a/trunk/drivers/net/hamradio/baycom_epp.c b/trunk/drivers/net/hamradio/baycom_epp.c index 1ed9cccd3c11..9220de9f4fe7 100644 --- a/trunk/drivers/net/hamradio/baycom_epp.c +++ b/trunk/drivers/net/hamradio/baycom_epp.c @@ -323,7 +323,7 @@ static int eppconfig(struct baycom_state *bc) /* ---------------------------------------------------------------------- */ -static void epp_interrupt(int irq, void *dev_id) +static void epp_interrupt(int irq, void *dev_id, struct pt_regs *regs) { } diff --git a/trunk/drivers/net/hamradio/baycom_par.c b/trunk/drivers/net/hamradio/baycom_par.c index 5930aeb35015..77411a00d1ee 100644 --- a/trunk/drivers/net/hamradio/baycom_par.c +++ b/trunk/drivers/net/hamradio/baycom_par.c @@ -270,7 +270,7 @@ static __inline__ void par96_rx(struct net_device *dev, struct baycom_state *bc) /* --------------------------------------------------------------------- */ -static void par96_interrupt(int irq, void *dev_id) +static void par96_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *)dev_id; struct baycom_state *bc = netdev_priv(dev); diff --git a/trunk/drivers/net/hamradio/baycom_ser_fdx.c b/trunk/drivers/net/hamradio/baycom_ser_fdx.c index 59214e74b9cf..55906c7b4bb1 100644 --- a/trunk/drivers/net/hamradio/baycom_ser_fdx.c +++ b/trunk/drivers/net/hamradio/baycom_ser_fdx.c @@ -279,7 +279,7 @@ static __inline__ void ser12_rx(struct net_device *dev, struct baycom_state *bc, /* --------------------------------------------------------------------- */ -static irqreturn_t ser12_interrupt(int irq, void *dev_id) +static irqreturn_t ser12_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *)dev_id; struct baycom_state *bc = netdev_priv(dev); diff --git a/trunk/drivers/net/hamradio/baycom_ser_hdx.c b/trunk/drivers/net/hamradio/baycom_ser_hdx.c index 3bcc57acbe6d..de95de8983da 100644 --- a/trunk/drivers/net/hamradio/baycom_ser_hdx.c +++ b/trunk/drivers/net/hamradio/baycom_ser_hdx.c @@ -373,7 +373,7 @@ static inline void ser12_rx(struct net_device *dev, struct baycom_state *bc) /* --------------------------------------------------------------------- */ -static irqreturn_t ser12_interrupt(int irq, void *dev_id) +static irqreturn_t ser12_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *)dev_id; struct baycom_state *bc = netdev_priv(dev); diff --git a/trunk/drivers/net/hamradio/dmascc.c b/trunk/drivers/net/hamradio/dmascc.c index 0f8b9afd55b4..c9a46b89942a 100644 --- a/trunk/drivers/net/hamradio/dmascc.c +++ b/trunk/drivers/net/hamradio/dmascc.c @@ -249,7 +249,7 @@ static void start_timer(struct scc_priv *priv, int t, int r15); static inline unsigned char random(void); static inline void z8530_isr(struct scc_info *info); -static irqreturn_t scc_isr(int irq, void *dev_id); +static irqreturn_t scc_isr(int irq, void *dev_id, struct pt_regs *regs); static void rx_isr(struct scc_priv *priv); static void special_condition(struct scc_priv *priv, int rc); static void rx_bh(void *arg); @@ -1142,7 +1142,7 @@ static inline void z8530_isr(struct scc_info *info) } -static irqreturn_t scc_isr(int irq, void *dev_id) +static irqreturn_t scc_isr(int irq, void *dev_id, struct pt_regs *regs) { struct scc_info *info = dev_id; diff --git a/trunk/drivers/net/hamradio/scc.c b/trunk/drivers/net/hamradio/scc.c index ec9b6d9b6f05..df4b68142ac7 100644 --- a/trunk/drivers/net/hamradio/scc.c +++ b/trunk/drivers/net/hamradio/scc.c @@ -200,7 +200,7 @@ static void z8530_init(void); static void init_channel(struct scc_channel *scc); static void scc_key_trx (struct scc_channel *scc, char tx); -static irqreturn_t scc_isr(int irq, void *dev_id); +static irqreturn_t scc_isr(int irq, void *dev_id, struct pt_regs *regs); static void scc_init_timer(struct scc_channel *scc); static int scc_net_alloc(const char *name, struct scc_channel *scc); @@ -626,7 +626,7 @@ static void scc_isr_dispatch(struct scc_channel *scc, int vector) #define SCC_IRQTIMEOUT 30000 -static irqreturn_t scc_isr(int irq, void *dev_id) +static irqreturn_t scc_isr(int irq, void *dev_id, struct pt_regs *regs) { unsigned char vector; struct scc_channel *scc; diff --git a/trunk/drivers/net/hamradio/yam.c b/trunk/drivers/net/hamradio/yam.c index 3c4455bd466d..f98f5777dfbb 100644 --- a/trunk/drivers/net/hamradio/yam.c +++ b/trunk/drivers/net/hamradio/yam.c @@ -702,7 +702,7 @@ static void yam_tx_byte(struct net_device *dev, struct yam_port *yp) * ISR routine ************************************************************************************/ -static irqreturn_t yam_interrupt(int irq, void *dev_id) +static irqreturn_t yam_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev; struct yam_port *yp; diff --git a/trunk/drivers/net/hp100.c b/trunk/drivers/net/hp100.c index 844c136e9920..ae8ad4f763bf 100644 --- a/trunk/drivers/net/hp100.c +++ b/trunk/drivers/net/hp100.c @@ -249,7 +249,7 @@ static void hp100_misc_interrupt(struct net_device *dev); static void hp100_update_stats(struct net_device *dev); static void hp100_clear_stats(struct hp100_private *lp, int ioaddr); static void hp100_set_multicast_list(struct net_device *dev); -static irqreturn_t hp100_interrupt(int irq, void *dev_id); +static irqreturn_t hp100_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void hp100_start_interface(struct net_device *dev); static void hp100_stop_interface(struct net_device *dev); static void hp100_load_eeprom(struct net_device *dev, u_short ioaddr); @@ -2187,7 +2187,7 @@ static void hp100_set_multicast_list(struct net_device *dev) * hardware interrupt handling */ -static irqreturn_t hp100_interrupt(int irq, void *dev_id) +static irqreturn_t hp100_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_id; struct hp100_private *lp = netdev_priv(dev); diff --git a/trunk/drivers/net/ibm_emac/ibm_emac_core.c b/trunk/drivers/net/ibm_emac/ibm_emac_core.c index ffeafb28f782..d52e3bd01301 100644 --- a/trunk/drivers/net/ibm_emac/ibm_emac_core.c +++ b/trunk/drivers/net/ibm_emac/ibm_emac_core.c @@ -184,7 +184,7 @@ static const char emac_stats_keys[EMAC_ETHTOOL_STATS_COUNT][ETH_GSTRING_LEN] = { "tx_errors" }; -static irqreturn_t emac_irq(int irq, void *dev_instance); +static irqreturn_t emac_irq(int irq, void *dev_instance, struct pt_regs *regs); static void emac_clean_tx_ring(struct ocp_enet_private *dev); static inline int emac_phy_supports_gige(int phy_mode) @@ -1515,7 +1515,7 @@ static void emac_rxde(void *param) } /* Hard IRQ */ -static irqreturn_t emac_irq(int irq, void *dev_instance) +static irqreturn_t emac_irq(int irq, void *dev_instance, struct pt_regs *regs) { struct ocp_enet_private *dev = dev_instance; struct emac_regs __iomem *p = dev->emacp; diff --git a/trunk/drivers/net/ibm_emac/ibm_emac_debug.c b/trunk/drivers/net/ibm_emac/ibm_emac_debug.c index 92f970d402df..c3645908034d 100644 --- a/trunk/drivers/net/ibm_emac/ibm_emac_debug.c +++ b/trunk/drivers/net/ibm_emac/ibm_emac_debug.c @@ -179,7 +179,8 @@ void emac_dbg_dump_all(void) } #if defined(CONFIG_MAGIC_SYSRQ) -static void emac_sysrq_handler(int key, struct tty_struct *tty) +static void emac_sysrq_handler(int key, struct pt_regs *pt_regs, + struct tty_struct *tty) { emac_dbg_dump_all(); } diff --git a/trunk/drivers/net/ibm_emac/ibm_emac_mal.c b/trunk/drivers/net/ibm_emac/ibm_emac_mal.c index 6c0f071e4052..af50e7b2e0d7 100644 --- a/trunk/drivers/net/ibm_emac/ibm_emac_mal.c +++ b/trunk/drivers/net/ibm_emac/ibm_emac_mal.c @@ -168,7 +168,7 @@ static inline void mal_disable_eob_irq(struct ibm_ocp_mal *mal) MAL_DBG2("%d: disable_irq" NL, mal->def->index); } -static irqreturn_t mal_serr(int irq, void *dev_instance) +static irqreturn_t mal_serr(int irq, void *dev_instance, struct pt_regs *regs) { struct ibm_ocp_mal *mal = dev_instance; u32 esr = get_mal_dcrn(mal, MAL_ESR); @@ -216,7 +216,7 @@ static inline void mal_schedule_poll(struct ibm_ocp_mal *mal) MAL_DBG2("%d: already in poll" NL, mal->def->index); } -static irqreturn_t mal_txeob(int irq, void *dev_instance) +static irqreturn_t mal_txeob(int irq, void *dev_instance, struct pt_regs *regs) { struct ibm_ocp_mal *mal = dev_instance; u32 r = get_mal_dcrn(mal, MAL_TXEOBISR); @@ -226,7 +226,7 @@ static irqreturn_t mal_txeob(int irq, void *dev_instance) return IRQ_HANDLED; } -static irqreturn_t mal_rxeob(int irq, void *dev_instance) +static irqreturn_t mal_rxeob(int irq, void *dev_instance, struct pt_regs *regs) { struct ibm_ocp_mal *mal = dev_instance; u32 r = get_mal_dcrn(mal, MAL_RXEOBISR); @@ -236,7 +236,7 @@ static irqreturn_t mal_rxeob(int irq, void *dev_instance) return IRQ_HANDLED; } -static irqreturn_t mal_txde(int irq, void *dev_instance) +static irqreturn_t mal_txde(int irq, void *dev_instance, struct pt_regs *regs) { struct ibm_ocp_mal *mal = dev_instance; u32 deir = get_mal_dcrn(mal, MAL_TXDEIR); @@ -252,7 +252,7 @@ static irqreturn_t mal_txde(int irq, void *dev_instance) return IRQ_HANDLED; } -static irqreturn_t mal_rxde(int irq, void *dev_instance) +static irqreturn_t mal_rxde(int irq, void *dev_instance, struct pt_regs *regs) { struct ibm_ocp_mal *mal = dev_instance; struct list_head *l; diff --git a/trunk/drivers/net/ibmlana.c b/trunk/drivers/net/ibmlana.c index 3f946c811511..2a95d72fa593 100644 --- a/trunk/drivers/net/ibmlana.c +++ b/trunk/drivers/net/ibmlana.c @@ -705,7 +705,7 @@ static void irqtxerr_handler(struct net_device *dev) /* general interrupt entry */ -static irqreturn_t irq_handler(int irq, void *device) +static irqreturn_t irq_handler(int irq, void *device, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) device; u16 ival; diff --git a/trunk/drivers/net/ibmveth.c b/trunk/drivers/net/ibmveth.c index 44c9f993dcc4..767203d35bc2 100644 --- a/trunk/drivers/net/ibmveth.c +++ b/trunk/drivers/net/ibmveth.c @@ -93,7 +93,7 @@ static void ibmveth_proc_register_driver(void); static void ibmveth_proc_unregister_driver(void); static void ibmveth_proc_register_adapter(struct ibmveth_adapter *adapter); static void ibmveth_proc_unregister_adapter(struct ibmveth_adapter *adapter); -static irqreturn_t ibmveth_interrupt(int irq, void *dev_instance); +static irqreturn_t ibmveth_interrupt(int irq, void *dev_instance, struct pt_regs *regs); static inline void ibmveth_rxq_harvest_buffer(struct ibmveth_adapter *adapter); static struct kobj_type ktype_veth_pool; @@ -212,8 +212,7 @@ static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, struc break; } - free_index = pool->consumer_index; - pool->consumer_index = (pool->consumer_index + 1) % pool->size; + free_index = pool->consumer_index++ % pool->size; index = pool->free_map[free_index]; ibmveth_assert(index != IBM_VETH_INVALID_MAP); @@ -239,10 +238,7 @@ static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, struc if(lpar_rc != H_SUCCESS) { pool->free_map[free_index] = index; pool->skbuff[index] = NULL; - if (pool->consumer_index == 0) - pool->consumer_index = pool->size - 1; - else - pool->consumer_index--; + pool->consumer_index--; dma_unmap_single(&adapter->vdev->dev, pool->dma_addr[index], pool->buff_size, DMA_FROM_DEVICE); @@ -329,10 +325,7 @@ static void ibmveth_remove_buffer_from_pool(struct ibmveth_adapter *adapter, u64 adapter->rx_buff_pool[pool].buff_size, DMA_FROM_DEVICE); - free_index = adapter->rx_buff_pool[pool].producer_index; - adapter->rx_buff_pool[pool].producer_index - = (adapter->rx_buff_pool[pool].producer_index + 1) - % adapter->rx_buff_pool[pool].size; + free_index = adapter->rx_buff_pool[pool].producer_index++ % adapter->rx_buff_pool[pool].size; adapter->rx_buff_pool[pool].free_map[free_index] = index; mb(); @@ -444,31 +437,6 @@ static void ibmveth_cleanup(struct ibmveth_adapter *adapter) &adapter->rx_buff_pool[i]); } -static int ibmveth_register_logical_lan(struct ibmveth_adapter *adapter, - union ibmveth_buf_desc rxq_desc, u64 mac_address) -{ - int rc, try_again = 1; - - /* After a kexec the adapter will still be open, so our attempt to - * open it will fail. So if we get a failure we free the adapter and - * try again, but only once. */ -retry: - rc = h_register_logical_lan(adapter->vdev->unit_address, - adapter->buffer_list_dma, rxq_desc.desc, - adapter->filter_list_dma, mac_address); - - if (rc != H_SUCCESS && try_again) { - do { - rc = h_free_logical_lan(adapter->vdev->unit_address); - } while (H_IS_LONG_BUSY(rc) || (rc == H_BUSY)); - - try_again = 0; - goto retry; - } - - return rc; -} - static int ibmveth_open(struct net_device *netdev) { struct ibmveth_adapter *adapter = netdev->priv; @@ -534,9 +502,12 @@ static int ibmveth_open(struct net_device *netdev) ibmveth_debug_printk("filter list @ 0x%p\n", adapter->filter_list_addr); ibmveth_debug_printk("receive q @ 0x%p\n", adapter->rx_queue.queue_addr); - h_vio_signal(adapter->vdev->unit_address, VIO_IRQ_DISABLE); - lpar_rc = ibmveth_register_logical_lan(adapter, rxq_desc, mac_address); + lpar_rc = h_register_logical_lan(adapter->vdev->unit_address, + adapter->buffer_list_dma, + rxq_desc.desc, + adapter->filter_list_dma, + mac_address); if(lpar_rc != H_SUCCESS) { ibmveth_error_printk("h_register_logical_lan failed with %ld\n", lpar_rc); @@ -572,7 +543,7 @@ static int ibmveth_open(struct net_device *netdev) } ibmveth_debug_printk("initial replenish cycle\n"); - ibmveth_interrupt(netdev->irq, netdev); + ibmveth_interrupt(netdev->irq, netdev, NULL); netif_start_queue(netdev); @@ -845,7 +816,7 @@ static int ibmveth_poll(struct net_device *netdev, int *budget) return 0; } -static irqreturn_t ibmveth_interrupt(int irq, void *dev_instance) +static irqreturn_t ibmveth_interrupt(int irq, void *dev_instance, struct pt_regs *regs) { struct net_device *netdev = dev_instance; struct ibmveth_adapter *adapter = netdev->priv; @@ -934,14 +905,6 @@ static int ibmveth_change_mtu(struct net_device *dev, int new_mtu) return -EINVAL; } -#ifdef CONFIG_NET_POLL_CONTROLLER -static void ibmveth_poll_controller(struct net_device *dev) -{ - ibmveth_replenish_task(dev->priv); - ibmveth_interrupt(dev->irq, dev); -} -#endif - static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id) { int rc, i; @@ -1014,9 +977,6 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_ netdev->ethtool_ops = &netdev_ethtool_ops; netdev->change_mtu = ibmveth_change_mtu; SET_NETDEV_DEV(netdev, &dev->dev); -#ifdef CONFIG_NET_POLL_CONTROLLER - netdev->poll_controller = ibmveth_poll_controller; -#endif netdev->features |= NETIF_F_LLTX; spin_lock_init(&adapter->stats_lock); @@ -1172,9 +1132,7 @@ static void ibmveth_proc_register_adapter(struct ibmveth_adapter *adapter) { struct proc_dir_entry *entry; if (ibmveth_proc_dir) { - char u_addr[10]; - sprintf(u_addr, "%x", adapter->vdev->unit_address); - entry = create_proc_entry(u_addr, S_IFREG, ibmveth_proc_dir); + entry = create_proc_entry(adapter->netdev->name, S_IFREG, ibmveth_proc_dir); if (!entry) { ibmveth_error_printk("Cannot create adapter proc entry"); } else { @@ -1189,9 +1147,7 @@ static void ibmveth_proc_register_adapter(struct ibmveth_adapter *adapter) static void ibmveth_proc_unregister_adapter(struct ibmveth_adapter *adapter) { if (ibmveth_proc_dir) { - char u_addr[10]; - sprintf(u_addr, "%x", adapter->vdev->unit_address); - remove_proc_entry(u_addr, ibmveth_proc_dir); + remove_proc_entry(adapter->netdev->name, ibmveth_proc_dir); } } @@ -1305,7 +1261,7 @@ const char * buf, size_t count) } /* kick the interrupt handler to allocate/deallocate pools */ - ibmveth_interrupt(netdev->irq, netdev); + ibmveth_interrupt(netdev->irq, netdev, NULL); return count; } diff --git a/trunk/drivers/net/ioc3-eth.c b/trunk/drivers/net/ioc3-eth.c index f56b00ee385e..87650237dc5c 100644 --- a/trunk/drivers/net/ioc3-eth.c +++ b/trunk/drivers/net/ioc3-eth.c @@ -750,7 +750,7 @@ static void ioc3_error(struct ioc3_private *ip, u32 eisr) /* The interrupt handler does all of the Rx thread work and cleans up after the Tx thread. */ -static irqreturn_t ioc3_interrupt(int irq, void *_dev) +static irqreturn_t ioc3_interrupt(int irq, void *_dev, struct pt_regs *regs) { struct net_device *dev = (struct net_device *)_dev; struct ioc3_private *ip = netdev_priv(dev); @@ -1017,7 +1017,7 @@ static void ioc3_init(struct net_device *dev) struct ioc3_private *ip = netdev_priv(dev); struct ioc3 *ioc3 = ip->regs; - del_timer_sync(&ip->ioc3_timer); /* Kill if running */ + del_timer(&ip->ioc3_timer); /* Kill if running */ ioc3_w_emcr(EMCR_RST); /* Reset */ (void) ioc3_r_emcr(); /* Flush WB */ @@ -1081,7 +1081,7 @@ static int ioc3_close(struct net_device *dev) { struct ioc3_private *ip = netdev_priv(dev); - del_timer_sync(&ip->ioc3_timer); + del_timer(&ip->ioc3_timer); netif_stop_queue(dev); diff --git a/trunk/drivers/net/irda/ali-ircc.c b/trunk/drivers/net/irda/ali-ircc.c index cebf8c374bc5..68d4c418cb98 100644 --- a/trunk/drivers/net/irda/ali-ircc.c +++ b/trunk/drivers/net/irda/ali-ircc.c @@ -660,15 +660,22 @@ static int ali_ircc_read_dongle_id (int i, chipio_t *info) * An interrupt from the chip has arrived. Time to do some work * */ -static irqreturn_t ali_ircc_interrupt(int irq, void *dev_id) +static irqreturn_t ali_ircc_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { - struct net_device *dev = dev_id; + struct net_device *dev = (struct net_device *) dev_id; struct ali_ircc_cb *self; int ret; IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __FUNCTION__); - self = dev->priv; + if (!dev) { + IRDA_WARNING("%s: irq %d for unknown device.\n", + ALI_IRCC_DRIVER_NAME, irq); + return IRQ_NONE; + } + + self = (struct ali_ircc_cb *) dev->priv; spin_lock(&self->lock); diff --git a/trunk/drivers/net/irda/au1k_ir.c b/trunk/drivers/net/irda/au1k_ir.c index 37914dc5b90e..7b2b4135bb23 100644 --- a/trunk/drivers/net/irda/au1k_ir.c +++ b/trunk/drivers/net/irda/au1k_ir.c @@ -51,7 +51,7 @@ static int au1k_irda_start(struct net_device *); static int au1k_irda_stop(struct net_device *dev); static int au1k_irda_hard_xmit(struct sk_buff *, struct net_device *); static int au1k_irda_rx(struct net_device *); -static void au1k_irda_interrupt(int, void *); +static void au1k_irda_interrupt(int, void *, struct pt_regs *); static void au1k_tx_timeout(struct net_device *); static struct net_device_stats *au1k_irda_stats(struct net_device *); static int au1k_irda_ioctl(struct net_device *, struct ifreq *, int); @@ -627,7 +627,7 @@ static int au1k_irda_rx(struct net_device *dev) } -void au1k_irda_interrupt(int irq, void *dev_id) +void au1k_irda_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_id; diff --git a/trunk/drivers/net/irda/donauboe.c b/trunk/drivers/net/irda/donauboe.c index 16620bd97fbf..33c07d5275da 100644 --- a/trunk/drivers/net/irda/donauboe.c +++ b/trunk/drivers/net/irda/donauboe.c @@ -657,6 +657,12 @@ toshoboe_makemttpacket (struct toshoboe_cb *self, void *buf, int mtt) return xbofs; } +static int toshoboe_invalid_dev(int irq) +{ + printk (KERN_WARNING DRIVER_NAME ": irq %d for unknown device.\n", irq); + return 1; +} + #ifdef USE_PROBE /***********************************************************************/ /* Probe code */ @@ -703,11 +709,14 @@ stuff_byte (__u8 byte, __u8 * buf) } static irqreturn_t -toshoboe_probeinterrupt (int irq, void *dev_id) +toshoboe_probeinterrupt (int irq, void *dev_id, struct pt_regs *regs) { - struct toshoboe_cb *self = dev_id; + struct toshoboe_cb *self = (struct toshoboe_cb *) dev_id; __u8 irqstat; + if (self == NULL && toshoboe_invalid_dev(irq)) + return IRQ_NONE; + irqstat = INB (OBOE_ISR); /* was it us */ @@ -1152,12 +1161,15 @@ dumpbufs(skb->data,skb->len,'>'); /*interrupt handler */ static irqreturn_t -toshoboe_interrupt (int irq, void *dev_id) +toshoboe_interrupt (int irq, void *dev_id, struct pt_regs *regs) { - struct toshoboe_cb *self = dev_id; + struct toshoboe_cb *self = (struct toshoboe_cb *) dev_id; __u8 irqstat; struct sk_buff *skb = NULL; + if (self == NULL && toshoboe_invalid_dev(irq)) + return IRQ_NONE; + irqstat = INB (OBOE_ISR); /* was it us */ @@ -1345,11 +1357,13 @@ toshoboe_net_open (struct net_device *dev) { struct toshoboe_cb *self; unsigned long flags; - int rc; IRDA_DEBUG (4, "%s()\n", __FUNCTION__); - self = netdev_priv(dev); + IRDA_ASSERT (dev != NULL, return -1; ); + self = (struct toshoboe_cb *) dev->priv; + + IRDA_ASSERT (self != NULL, return 0; ); if (self->async) return -EBUSY; @@ -1357,10 +1371,11 @@ toshoboe_net_open (struct net_device *dev) if (self->stopped) return 0; - rc = request_irq (self->io.irq, toshoboe_interrupt, - IRQF_SHARED | IRQF_DISABLED, dev->name, self); - if (rc) - return rc; + if (request_irq (self->io.irq, toshoboe_interrupt, + IRQF_SHARED | IRQF_DISABLED, dev->name, (void *) self)) + { + return -EAGAIN; + } spin_lock_irqsave(&self->spinlock, flags); toshoboe_startchip (self); diff --git a/trunk/drivers/net/irda/irda-usb.c b/trunk/drivers/net/irda/irda-usb.c index 6e95645e7245..383cef1f5999 100644 --- a/trunk/drivers/net/irda/irda-usb.c +++ b/trunk/drivers/net/irda/irda-usb.c @@ -114,9 +114,9 @@ static void irda_usb_change_speed_xbofs(struct irda_usb_cb *self); static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *dev); static int irda_usb_open(struct irda_usb_cb *self); static void irda_usb_close(struct irda_usb_cb *self); -static void speed_bulk_callback(struct urb *urb); -static void write_bulk_callback(struct urb *urb); -static void irda_usb_receive(struct urb *urb); +static void speed_bulk_callback(struct urb *urb, struct pt_regs *regs); +static void write_bulk_callback(struct urb *urb, struct pt_regs *regs); +static void irda_usb_receive(struct urb *urb, struct pt_regs *regs); static void irda_usb_rx_defer_expired(unsigned long data); static int irda_usb_net_open(struct net_device *dev); static int irda_usb_net_close(struct net_device *dev); @@ -343,7 +343,7 @@ static void irda_usb_change_speed_xbofs(struct irda_usb_cb *self) * Speed URB callback * Now, we can only get called for the speed URB. */ -static void speed_bulk_callback(struct urb *urb) +static void speed_bulk_callback(struct urb *urb, struct pt_regs *regs) { struct irda_usb_cb *self = urb->context; @@ -562,7 +562,7 @@ static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *netdev) /* * Note : this function will be called only for tx_urb... */ -static void write_bulk_callback(struct urb *urb) +static void write_bulk_callback(struct urb *urb, struct pt_regs *regs) { unsigned long flags; struct sk_buff *skb = urb->context; @@ -809,7 +809,7 @@ static void irda_usb_submit(struct irda_usb_cb *self, struct sk_buff *skb, struc * Called by the USB subsystem when a frame has been received * */ -static void irda_usb_receive(struct urb *urb) +static void irda_usb_receive(struct urb *urb, struct pt_regs *regs) { struct sk_buff *skb = (struct sk_buff *) urb->context; struct irda_usb_cb *self; @@ -1793,8 +1793,10 @@ static int irda_usb_probe(struct usb_interface *intf, err_out_2: usb_free_urb(self->tx_urb); err_out_1: - for (i = 0; i < self->max_rx_urb; i++) - usb_free_urb(self->rx_urb[i]); + for (i = 0; i < self->max_rx_urb; i++) { + if (self->rx_urb[i]) + usb_free_urb(self->rx_urb[i]); + } free_netdev(net); err_out: return ret; diff --git a/trunk/drivers/net/irda/irport.c b/trunk/drivers/net/irda/irport.c index 654a68b490ae..ba4f3eb988b3 100644 --- a/trunk/drivers/net/irda/irport.c +++ b/trunk/drivers/net/irda/irport.c @@ -87,7 +87,8 @@ static struct net_device_stats *irport_net_get_stats(struct net_device *dev); static int irport_change_speed_complete(struct irda_task *task); static void irport_timeout(struct net_device *dev); -static irqreturn_t irport_interrupt(int irq, void *dev_id); +static irqreturn_t irport_interrupt(int irq, void *dev_id, + struct pt_regs *regs); static int irport_hard_xmit(struct sk_buff *skb, struct net_device *dev); static void irport_change_speed(void *priv, __u32 speed); static int irport_net_open(struct net_device *dev); @@ -760,20 +761,25 @@ static inline void irport_receive(struct irport_cb *self) } /* - * Function irport_interrupt (irq, dev_id) + * Function irport_interrupt (irq, dev_id, regs) * * Interrupt handler */ -static irqreturn_t irport_interrupt(int irq, void *dev_id) +static irqreturn_t irport_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { - struct net_device *dev = dev_id; + struct net_device *dev = (struct net_device *) dev_id; struct irport_cb *self; int boguscount = 0; int iobase; int iir, lsr; int handled = 0; - self = dev->priv; + if (!dev) { + IRDA_WARNING("%s() irq %d for unknown device.\n", __FUNCTION__, irq); + return IRQ_NONE; + } + self = (struct irport_cb *) dev->priv; spin_lock(&self->lock); diff --git a/trunk/drivers/net/irda/irport.h b/trunk/drivers/net/irda/irport.h index 3f46b84c6c85..fc89c8c3dd7f 100644 --- a/trunk/drivers/net/irda/irport.h +++ b/trunk/drivers/net/irda/irport.h @@ -74,7 +74,7 @@ struct irport_cb { /* For piggyback drivers */ void *priv; void (*change_speed)(void *priv, __u32 speed); - irqreturn_t (*interrupt)(int irq, void *dev_id); + int (*interrupt)(int irq, void *dev_id, struct pt_regs *regs); }; #endif /* IRPORT_H */ diff --git a/trunk/drivers/net/irda/mcs7780.c b/trunk/drivers/net/irda/mcs7780.c index b32c52ed19d7..415ba8dc94ce 100644 --- a/trunk/drivers/net/irda/mcs7780.c +++ b/trunk/drivers/net/irda/mcs7780.c @@ -764,7 +764,7 @@ static struct net_device_stats *mcs_net_get_stats(struct net_device *netdev) } /* Receive callback function. */ -static void mcs_receive_irq(struct urb *urb) +static void mcs_receive_irq(struct urb *urb, struct pt_regs *regs) { __u8 *bytes; struct mcs_cb *mcs = urb->context; @@ -813,7 +813,7 @@ static void mcs_receive_irq(struct urb *urb) } /* Transmit callback funtion. */ -static void mcs_send_irq(struct urb *urb) +static void mcs_send_irq(struct urb *urb, struct pt_regs *regs) { struct mcs_cb *mcs = urb->context; struct net_device *ndev = mcs->netdev; diff --git a/trunk/drivers/net/irda/mcs7780.h b/trunk/drivers/net/irda/mcs7780.h index b18148cee638..1a723d725c2a 100644 --- a/trunk/drivers/net/irda/mcs7780.h +++ b/trunk/drivers/net/irda/mcs7780.h @@ -156,8 +156,8 @@ static int mcs_net_close(struct net_device *netdev); static int mcs_net_open(struct net_device *netdev); static struct net_device_stats *mcs_net_get_stats(struct net_device *netdev); -static void mcs_receive_irq(struct urb *urb); -static void mcs_send_irq(struct urb *urb); +static void mcs_receive_irq(struct urb *urb, struct pt_regs *regs); +static void mcs_send_irq(struct urb *urb, struct pt_regs *regs); static int mcs_hard_xmit(struct sk_buff *skb, struct net_device *netdev); static int mcs_probe(struct usb_interface *intf, diff --git a/trunk/drivers/net/irda/nsc-ircc.c b/trunk/drivers/net/irda/nsc-ircc.c index 29b5ccd29d0b..7185a4ee3c1e 100644 --- a/trunk/drivers/net/irda/nsc-ircc.c +++ b/trunk/drivers/net/irda/nsc-ircc.c @@ -2066,14 +2066,20 @@ static void nsc_ircc_fir_interrupt(struct nsc_ircc_cb *self, int iobase, * An interrupt from the chip has arrived. Time to do some work * */ -static irqreturn_t nsc_ircc_interrupt(int irq, void *dev_id) +static irqreturn_t nsc_ircc_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { - struct net_device *dev = dev_id; + struct net_device *dev = (struct net_device *) dev_id; struct nsc_ircc_cb *self; __u8 bsr, eir; int iobase; - self = dev->priv; + if (!dev) { + IRDA_WARNING("%s: irq %d for unknown device.\n", + driver_name, irq); + return IRQ_NONE; + } + self = (struct nsc_ircc_cb *) dev->priv; spin_lock(&self->lock); diff --git a/trunk/drivers/net/irda/pxaficp_ir.c b/trunk/drivers/net/irda/pxaficp_ir.c index f9a1c88a4283..afb19e8d95c8 100644 --- a/trunk/drivers/net/irda/pxaficp_ir.c +++ b/trunk/drivers/net/irda/pxaficp_ir.c @@ -199,7 +199,7 @@ static int pxa_irda_set_speed(struct pxa_irda *si, int speed) } /* SIR interrupt service routine. */ -static irqreturn_t pxa_irda_sir_irq(int irq, void *dev_id) +static irqreturn_t pxa_irda_sir_irq(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; struct pxa_irda *si = netdev_priv(dev); @@ -281,7 +281,7 @@ static irqreturn_t pxa_irda_sir_irq(int irq, void *dev_id) } /* FIR Receive DMA interrupt handler */ -static void pxa_irda_fir_dma_rx_irq(int channel, void *data) +static void pxa_irda_fir_dma_rx_irq(int channel, void *data, struct pt_regs *regs) { int dcsr = DCSR(channel); @@ -291,7 +291,7 @@ static void pxa_irda_fir_dma_rx_irq(int channel, void *data) } /* FIR Transmit DMA interrupt handler */ -static void pxa_irda_fir_dma_tx_irq(int channel, void *data) +static void pxa_irda_fir_dma_tx_irq(int channel, void *data, struct pt_regs *regs) { struct net_device *dev = data; struct pxa_irda *si = netdev_priv(dev); @@ -388,7 +388,7 @@ static void pxa_irda_fir_irq_eif(struct pxa_irda *si, struct net_device *dev) } /* FIR interrupt handler */ -static irqreturn_t pxa_irda_fir_irq(int irq, void *dev_id) +static irqreturn_t pxa_irda_fir_irq(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; struct pxa_irda *si = netdev_priv(dev); diff --git a/trunk/drivers/net/irda/sa1100_ir.c b/trunk/drivers/net/irda/sa1100_ir.c index 937372d00398..8d5a288d7976 100644 --- a/trunk/drivers/net/irda/sa1100_ir.c +++ b/trunk/drivers/net/irda/sa1100_ir.c @@ -579,7 +579,7 @@ static void sa1100_irda_fir_irq(struct net_device *dev) sa1100_irda_rx_dma_start(si); } -static irqreturn_t sa1100_irda_irq(int irq, void *dev_id) +static irqreturn_t sa1100_irda_irq(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; if (IS_FIR(((struct sa1100_irda *)dev->priv))) diff --git a/trunk/drivers/net/irda/smsc-ircc2.c b/trunk/drivers/net/irda/smsc-ircc2.c index 31c623381ea8..22358ff68c4c 100644 --- a/trunk/drivers/net/irda/smsc-ircc2.c +++ b/trunk/drivers/net/irda/smsc-ircc2.c @@ -196,7 +196,7 @@ static void smsc_ircc_dma_xmit(struct smsc_ircc_cb *self, int bofs); static void smsc_ircc_dma_xmit_complete(struct smsc_ircc_cb *self); static void smsc_ircc_change_speed(struct smsc_ircc_cb *self, u32 speed); static void smsc_ircc_set_sir_speed(struct smsc_ircc_cb *self, u32 speed); -static irqreturn_t smsc_ircc_interrupt(int irq, void *dev_id); +static irqreturn_t smsc_ircc_interrupt(int irq, void *dev_id, struct pt_regs *regs); static irqreturn_t smsc_ircc_interrupt_sir(struct net_device *dev); static void smsc_ircc_sir_start(struct smsc_ircc_cb *self); #if SMSC_IRCC2_C_SIR_STOP @@ -1455,7 +1455,7 @@ static void smsc_ircc_sir_receive(struct smsc_ircc_cb *self) * An interrupt from the chip has arrived. Time to do some work * */ -static irqreturn_t smsc_ircc_interrupt(int irq, void *dev_id) +static irqreturn_t smsc_ircc_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_id; struct smsc_ircc_cb *self; @@ -1520,7 +1520,7 @@ static irqreturn_t smsc_ircc_interrupt(int irq, void *dev_id) } /* - * Function irport_interrupt_sir (irq, dev_id) + * Function irport_interrupt_sir (irq, dev_id, regs) * * Interrupt handler for SIR modes */ diff --git a/trunk/drivers/net/irda/stir4200.c b/trunk/drivers/net/irda/stir4200.c index 3b4c47875935..12103c93f7ef 100644 --- a/trunk/drivers/net/irda/stir4200.c +++ b/trunk/drivers/net/irda/stir4200.c @@ -15,7 +15,8 @@ * * 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. +* 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 @@ -803,7 +804,7 @@ static int stir_transmit_thread(void *arg) * Wakes up every ms (usb round trip) with wrapped * data. */ -static void stir_rcv_irq(struct urb *urb) +static void stir_rcv_irq(struct urb *urb, struct pt_regs *regs) { struct stir_cb *stir = urb->context; int err; diff --git a/trunk/drivers/net/irda/via-ircc.c b/trunk/drivers/net/irda/via-ircc.c index c3ed9b3067e5..d916e1257c47 100644 --- a/trunk/drivers/net/irda/via-ircc.c +++ b/trunk/drivers/net/irda/via-ircc.c @@ -93,7 +93,8 @@ static int via_ircc_hard_xmit_fir(struct sk_buff *skb, struct net_device *dev); static void via_hw_init(struct via_ircc_cb *self); static void via_ircc_change_speed(struct via_ircc_cb *self, __u32 baud); -static irqreturn_t via_ircc_interrupt(int irq, void *dev_id); +static irqreturn_t via_ircc_interrupt(int irq, void *dev_id, + struct pt_regs *regs); static int via_ircc_is_receiving(struct via_ircc_cb *self); static int via_ircc_read_dongle_id(int iobase); @@ -1344,12 +1345,13 @@ static int RxTimerHandler(struct via_ircc_cb *self, int iobase) /* - * Function via_ircc_interrupt (irq, dev_id) + * Function via_ircc_interrupt (irq, dev_id, regs) * * An interrupt from the chip has arrived. Time to do some work * */ -static irqreturn_t via_ircc_interrupt(int irq, void *dev_id) +static irqreturn_t via_ircc_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_id; struct via_ircc_cb *self; diff --git a/trunk/drivers/net/irda/vlsi_ir.c b/trunk/drivers/net/irda/vlsi_ir.c index 18c68193bf14..92d646cc9edc 100644 --- a/trunk/drivers/net/irda/vlsi_ir.c +++ b/trunk/drivers/net/irda/vlsi_ir.c @@ -1455,7 +1455,8 @@ static int vlsi_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd) /********************************************************/ -static irqreturn_t vlsi_interrupt(int irq, void *dev_instance) +static irqreturn_t vlsi_interrupt(int irq, void *dev_instance, + struct pt_regs *regs) { struct net_device *ndev = dev_instance; vlsi_irda_dev_t *idev = ndev->priv; diff --git a/trunk/drivers/net/irda/w83977af_ir.c b/trunk/drivers/net/irda/w83977af_ir.c index 4212657fa4f9..7de1afdeec3d 100644 --- a/trunk/drivers/net/irda/w83977af_ir.c +++ b/trunk/drivers/net/irda/w83977af_ir.c @@ -1111,14 +1111,20 @@ static __u8 w83977af_fir_interrupt(struct w83977af_ir *self, int isr) * An interrupt from the chip has arrived. Time to do some work * */ -static irqreturn_t w83977af_interrupt(int irq, void *dev_id) +static irqreturn_t w83977af_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { - struct net_device *dev = dev_id; + struct net_device *dev = (struct net_device *) dev_id; struct w83977af_ir *self; __u8 set, icr, isr; int iobase; - self = dev->priv; + if (!dev) { + printk(KERN_WARNING "%s: irq %d for unknown device.\n", + driver_name, irq); + return IRQ_NONE; + } + self = (struct w83977af_ir *) dev->priv; iobase = self->io.fir_base; diff --git a/trunk/drivers/net/isa-skeleton.c b/trunk/drivers/net/isa-skeleton.c index 0343f12d2ffb..984c31d1b3fb 100644 --- a/trunk/drivers/net/isa-skeleton.c +++ b/trunk/drivers/net/isa-skeleton.c @@ -107,7 +107,7 @@ struct net_local { static int netcard_probe1(struct net_device *dev, int ioaddr); static int net_open(struct net_device *dev); static int net_send_packet(struct sk_buff *skb, struct net_device *dev); -static irqreturn_t net_interrupt(int irq, void *dev_id); +static irqreturn_t net_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void net_rx(struct net_device *dev); static int net_close(struct net_device *dev); static struct net_device_stats *net_get_stats(struct net_device *dev); @@ -504,7 +504,7 @@ void net_tx(struct net_device *dev) * The typical workload of the driver: * Handle the network interface interrupts. */ -static irqreturn_t net_interrupt(int irq, void *dev_id) +static irqreturn_t net_interrupt(int irq, void *dev_id, struct pt_regs * regs) { struct net_device *dev = dev_id; struct net_local *np; diff --git a/trunk/drivers/net/iseries_veth.c b/trunk/drivers/net/iseries_veth.c index 2284e2ce1692..41b1d08fd57b 100644 --- a/trunk/drivers/net/iseries_veth.c +++ b/trunk/drivers/net/iseries_veth.c @@ -586,7 +586,7 @@ static void veth_handle_int(struct veth_lpevent *event) }; } -static void veth_handle_event(struct HvLpEvent *event) +static void veth_handle_event(struct HvLpEvent *event, struct pt_regs *regs) { struct veth_lpevent *veth_event = (struct veth_lpevent *)event; diff --git a/trunk/drivers/net/ixgb/ixgb_main.c b/trunk/drivers/net/ixgb/ixgb_main.c index e09f575a3a38..cfde7c2569bb 100644 --- a/trunk/drivers/net/ixgb/ixgb_main.c +++ b/trunk/drivers/net/ixgb/ixgb_main.c @@ -93,7 +93,7 @@ static int ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev); static struct net_device_stats *ixgb_get_stats(struct net_device *netdev); static int ixgb_change_mtu(struct net_device *netdev, int new_mtu); static int ixgb_set_mac(struct net_device *netdev, void *p); -static irqreturn_t ixgb_intr(int irq, void *data); +static irqreturn_t ixgb_intr(int irq, void *data, struct pt_regs *regs); static boolean_t ixgb_clean_tx_irq(struct ixgb_adapter *adapter); #ifdef CONFIG_IXGB_NAPI @@ -1687,10 +1687,11 @@ ixgb_update_stats(struct ixgb_adapter *adapter) * ixgb_intr - Interrupt Handler * @irq: interrupt number * @data: pointer to a network interface device structure + * @pt_regs: CPU registers structure **/ static irqreturn_t -ixgb_intr(int irq, void *data) +ixgb_intr(int irq, void *data, struct pt_regs *regs) { struct net_device *netdev = data; struct ixgb_adapter *adapter = netdev_priv(netdev); @@ -2212,7 +2213,7 @@ static void ixgb_netpoll(struct net_device *dev) struct ixgb_adapter *adapter = netdev_priv(dev); disable_irq(adapter->pdev->irq); - ixgb_intr(adapter->pdev->irq, dev); + ixgb_intr(adapter->pdev->irq, dev, NULL); enable_irq(adapter->pdev->irq); } #endif diff --git a/trunk/drivers/net/ixp2000/ixpdev.c b/trunk/drivers/net/ixp2000/ixpdev.c index a4eccb11d677..6eeb965b4d72 100644 --- a/trunk/drivers/net/ixp2000/ixpdev.c +++ b/trunk/drivers/net/ixp2000/ixpdev.c @@ -188,7 +188,7 @@ static void ixpdev_tx_complete(void) } } -static irqreturn_t ixpdev_interrupt(int irq, void *dev_id) +static irqreturn_t ixpdev_interrupt(int irq, void *dev_id, struct pt_regs *regs) { u32 status; diff --git a/trunk/drivers/net/lance.c b/trunk/drivers/net/lance.c index 6efbd499d752..f349e88e0ddf 100644 --- a/trunk/drivers/net/lance.c +++ b/trunk/drivers/net/lance.c @@ -301,7 +301,7 @@ static int lance_open(struct net_device *dev); static void lance_init_ring(struct net_device *dev, gfp_t mode); static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev); static int lance_rx(struct net_device *dev); -static irqreturn_t lance_interrupt(int irq, void *dev_id); +static irqreturn_t lance_interrupt(int irq, void *dev_id, struct pt_regs *regs); static int lance_close(struct net_device *dev); static struct net_device_stats *lance_get_stats(struct net_device *dev); static void set_multicast_list(struct net_device *dev); @@ -1012,13 +1012,19 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev) } /* The LANCE interrupt handler. */ -static irqreturn_t lance_interrupt(int irq, void *dev_id) +static irqreturn_t +lance_interrupt(int irq, void *dev_id, struct pt_regs * regs) { struct net_device *dev = dev_id; struct lance_private *lp; int csr0, ioaddr, boguscnt=10; int must_restart; + if (dev == NULL) { + printk ("lance_interrupt(): irq %d for unknown device.\n", irq); + return IRQ_NONE; + } + ioaddr = dev->base_addr; lp = dev->priv; diff --git a/trunk/drivers/net/lasi_82596.c b/trunk/drivers/net/lasi_82596.c index f4d815bca643..da1eedef0b55 100644 --- a/trunk/drivers/net/lasi_82596.c +++ b/trunk/drivers/net/lasi_82596.c @@ -403,7 +403,7 @@ static char init_setup[] = static int i596_open(struct net_device *dev); static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev); -static irqreturn_t i596_interrupt(int irq, void *dev_id); +static irqreturn_t i596_interrupt(int irq, void *dev_id, struct pt_regs *regs); static int i596_close(struct net_device *dev); static struct net_device_stats *i596_get_stats(struct net_device *dev); static void i596_add_cmd(struct net_device *dev, struct i596_cmd *cmd); @@ -527,7 +527,7 @@ static void i596_display_data(struct net_device *dev) #if defined(ENABLE_MVME16x_NET) || defined(ENABLE_BVME6000_NET) -static void i596_error(int irq, void *dev_id) +static void i596_error(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; volatile unsigned char *pcc2 = (unsigned char *) 0xfff42000; @@ -1252,12 +1252,12 @@ static int __devinit i82596_probe(struct net_device *dev, static void i596_poll_controller(struct net_device *dev) { disable_irq(dev->irq); - i596_interrupt(dev->irq, dev); + i596_interrupt(dev->irq, dev, NULL); enable_irq(dev->irq); } #endif -static irqreturn_t i596_interrupt(int irq, void *dev_id) +static irqreturn_t i596_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; struct i596_private *lp; diff --git a/trunk/drivers/net/loopback.c b/trunk/drivers/net/loopback.c index 82c10dec1b5a..4178b4b1d2df 100644 --- a/trunk/drivers/net/loopback.c +++ b/trunk/drivers/net/loopback.c @@ -58,11 +58,7 @@ #include #include -struct pcpu_lstats { - unsigned long packets; - unsigned long bytes; -}; -static DEFINE_PER_CPU(struct pcpu_lstats, pcpu_lstats); +static DEFINE_PER_CPU(struct net_device_stats, loopback_stats); #define LOOPBACK_OVERHEAD (128 + MAX_HEADER + 16 + 16) @@ -132,7 +128,7 @@ static void emulate_large_send_offload(struct sk_buff *skb) */ static int loopback_xmit(struct sk_buff *skb, struct net_device *dev) { - struct pcpu_lstats *lb_stats; + struct net_device_stats *lb_stats; skb_orphan(skb); @@ -153,14 +149,16 @@ static int loopback_xmit(struct sk_buff *skb, struct net_device *dev) #endif dev->last_rx = jiffies; - /* it's OK to use __get_cpu_var() because BHs are off */ - lb_stats = &__get_cpu_var(pcpu_lstats); - lb_stats->bytes += skb->len; - lb_stats->packets++; + lb_stats = &per_cpu(loopback_stats, get_cpu()); + lb_stats->rx_bytes += skb->len; + lb_stats->tx_bytes = lb_stats->rx_bytes; + lb_stats->rx_packets++; + lb_stats->tx_packets = lb_stats->rx_packets; + put_cpu(); netif_rx(skb); - return 0; + return(0); } static struct net_device_stats loopback_stats; @@ -168,21 +166,20 @@ static struct net_device_stats loopback_stats; static struct net_device_stats *get_stats(struct net_device *dev) { struct net_device_stats *stats = &loopback_stats; - unsigned long bytes = 0; - unsigned long packets = 0; int i; + memset(stats, 0, sizeof(struct net_device_stats)); + for_each_possible_cpu(i) { - const struct pcpu_lstats *lb_stats; + struct net_device_stats *lb_stats; - lb_stats = &per_cpu(pcpu_lstats, i); - bytes += lb_stats->bytes; - packets += lb_stats->packets; + lb_stats = &per_cpu(loopback_stats, i); + stats->rx_bytes += lb_stats->rx_bytes; + stats->tx_bytes += lb_stats->tx_bytes; + stats->rx_packets += lb_stats->rx_packets; + stats->tx_packets += lb_stats->tx_packets; } - stats->rx_packets = packets; - stats->tx_packets = packets; - stats->rx_bytes = bytes; - stats->tx_bytes = bytes; + return stats; } diff --git a/trunk/drivers/net/lp486e.c b/trunk/drivers/net/lp486e.c index b833016f1825..0258aaca9ed3 100644 --- a/trunk/drivers/net/lp486e.c +++ b/trunk/drivers/net/lp486e.c @@ -379,7 +379,7 @@ static char init_setup[14] = { static int i596_open(struct net_device *dev); static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev); -static irqreturn_t i596_interrupt(int irq, void *dev_id); +static irqreturn_t i596_interrupt(int irq, void *dev_id, struct pt_regs *regs); static int i596_close(struct net_device *dev); static struct net_device_stats *i596_get_stats(struct net_device *dev); static void i596_add_cmd(struct net_device *dev, struct i596_cmd *cmd); @@ -1151,7 +1151,7 @@ i596_handle_CU_completion(struct net_device *dev, } static irqreturn_t -i596_interrupt (int irq, void *dev_instance) { +i596_interrupt (int irq, void *dev_instance, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_instance; struct i596_private *lp; unsigned short status, ack_cmd = 0; diff --git a/trunk/drivers/net/mac89x0.c b/trunk/drivers/net/mac89x0.c index e960138011c0..8472b71641da 100644 --- a/trunk/drivers/net/mac89x0.c +++ b/trunk/drivers/net/mac89x0.c @@ -129,7 +129,7 @@ extern void reset_chip(struct net_device *dev); #endif static int net_open(struct net_device *dev); static int net_send_packet(struct sk_buff *skb, struct net_device *dev); -static irqreturn_t net_interrupt(int irq, void *dev_id); +static irqreturn_t net_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void set_multicast_list(struct net_device *dev); static void net_rx(struct net_device *dev); static int net_close(struct net_device *dev); @@ -431,7 +431,7 @@ net_send_packet(struct sk_buff *skb, struct net_device *dev) /* The typical workload of the driver: Handle the network interface interrupts. */ -static irqreturn_t net_interrupt(int irq, void *dev_id) +static irqreturn_t net_interrupt(int irq, void *dev_id, struct pt_regs * regs) { struct net_device *dev = dev_id; struct net_local *lp; diff --git a/trunk/drivers/net/mace.c b/trunk/drivers/net/mace.c index 2907cfb12ada..27c24eaa2414 100644 --- a/trunk/drivers/net/mace.c +++ b/trunk/drivers/net/mace.c @@ -82,9 +82,9 @@ static struct net_device_stats *mace_stats(struct net_device *dev); static void mace_set_multicast(struct net_device *dev); static void mace_reset(struct net_device *dev); static int mace_set_address(struct net_device *dev, void *addr); -static irqreturn_t mace_interrupt(int irq, void *dev_id); -static irqreturn_t mace_txdma_intr(int irq, void *dev_id); -static irqreturn_t mace_rxdma_intr(int irq, void *dev_id); +static irqreturn_t mace_interrupt(int irq, void *dev_id, struct pt_regs *regs); +static irqreturn_t mace_txdma_intr(int irq, void *dev_id, struct pt_regs *regs); +static irqreturn_t mace_rxdma_intr(int irq, void *dev_id, struct pt_regs *regs); static void mace_set_timeout(struct net_device *dev); static void mace_tx_timeout(unsigned long data); static inline void dbdma_reset(volatile struct dbdma_regs __iomem *dma); @@ -678,7 +678,7 @@ static void mace_handle_misc_intrs(struct mace_data *mp, int intr) printk(KERN_DEBUG "mace: jabbering transceiver\n"); } -static irqreturn_t mace_interrupt(int irq, void *dev_id) +static irqreturn_t mace_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_id; struct mace_data *mp = (struct mace_data *) dev->priv; @@ -890,12 +890,12 @@ static void mace_tx_timeout(unsigned long data) spin_unlock_irqrestore(&mp->lock, flags); } -static irqreturn_t mace_txdma_intr(int irq, void *dev_id) +static irqreturn_t mace_txdma_intr(int irq, void *dev_id, struct pt_regs *regs) { return IRQ_HANDLED; } -static irqreturn_t mace_rxdma_intr(int irq, void *dev_id) +static irqreturn_t mace_rxdma_intr(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_id; struct mace_data *mp = (struct mace_data *) dev->priv; diff --git a/trunk/drivers/net/macmace.c b/trunk/drivers/net/macmace.c index 464e4a6f3d5f..696d5513e558 100644 --- a/trunk/drivers/net/macmace.c +++ b/trunk/drivers/net/macmace.c @@ -77,8 +77,8 @@ static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev); static struct net_device_stats *mace_stats(struct net_device *dev); static void mace_set_multicast(struct net_device *dev); static int mace_set_address(struct net_device *dev, void *addr); -static irqreturn_t mace_interrupt(int irq, void *dev_id); -static irqreturn_t mace_dma_intr(int irq, void *dev_id); +static irqreturn_t mace_interrupt(int irq, void *dev_id, struct pt_regs *regs); +static irqreturn_t mace_dma_intr(int irq, void *dev_id, struct pt_regs *regs); static void mace_tx_timeout(struct net_device *dev); /* Bit-reverse one byte of an ethernet hardware address. */ @@ -573,7 +573,7 @@ static void mace_recv_interrupt(struct net_device *dev) * Process the chip interrupt */ -static irqreturn_t mace_interrupt(int irq, void *dev_id) +static irqreturn_t mace_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_id; struct mace_data *mp = (struct mace_data *) dev->priv; @@ -645,7 +645,7 @@ static void mace_dma_rx_frame(struct net_device *dev, struct mace_frame *mf) * The PSC has passed us a DMA interrupt event. */ -static irqreturn_t mace_dma_intr(int irq, void *dev_id) +static irqreturn_t mace_dma_intr(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_id; struct mace_data *mp = (struct mace_data *) dev->priv; diff --git a/trunk/drivers/net/meth.c b/trunk/drivers/net/meth.c index c1aa60b9a982..55b1495a70d6 100644 --- a/trunk/drivers/net/meth.c +++ b/trunk/drivers/net/meth.c @@ -92,7 +92,7 @@ struct meth_private { }; static void meth_tx_timeout(struct net_device *dev); -static irqreturn_t meth_interrupt(int irq, void *dev_id); +static irqreturn_t meth_interrupt(int irq, void *dev_id, struct pt_regs *pregs); /* global, initialized in ip32-setup.c */ char o2meth_eaddr[8]={0,0,0,0,0,0,0,0}; @@ -569,7 +569,7 @@ static void meth_error(struct net_device* dev, unsigned status) /* * The typical interrupt entry point */ -static irqreturn_t meth_interrupt(int irq, void *dev_id) +static irqreturn_t meth_interrupt(int irq, void *dev_id, struct pt_regs *pregs) { struct net_device *dev = (struct net_device *)dev_id; struct meth_private *priv = (struct meth_private *) dev->priv; diff --git a/trunk/drivers/net/mipsnet.c b/trunk/drivers/net/mipsnet.c index c9469985bd71..07e58f4a2916 100644 --- a/trunk/drivers/net/mipsnet.c +++ b/trunk/drivers/net/mipsnet.c @@ -116,7 +116,8 @@ static inline ssize_t mipsnet_get_fromdev(struct net_device *dev, size_t count) return count; } -static irqreturn_t mipsnet_interrupt(int irq, void *dev_id) +static irqreturn_t +mipsnet_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; diff --git a/trunk/drivers/net/mv643xx_eth.c b/trunk/drivers/net/mv643xx_eth.c index 9997081c6dae..7f8e5ad1b704 100644 --- a/trunk/drivers/net/mv643xx_eth.c +++ b/trunk/drivers/net/mv643xx_eth.c @@ -507,7 +507,8 @@ static void mv643xx_eth_update_pscr(struct net_device *dev, * Output : N/A */ -static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id) +static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id, + struct pt_regs *regs) { struct net_device *dev = (struct net_device *)dev_id; struct mv643xx_private *mp = netdev_priv(dev); @@ -1251,7 +1252,7 @@ static void mv643xx_netpoll(struct net_device *netdev) /* wait for previous write to complete */ mv_read(MV643XX_ETH_INTERRUPT_MASK_REG(port_num)); - mv643xx_eth_int_handler(netdev->irq, netdev); + mv643xx_eth_int_handler(netdev->irq, netdev, NULL); mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), ETH_INT_UNMASK_ALL); } @@ -2155,7 +2156,7 @@ static void eth_update_mib_counters(struct mv643xx_private *mp) for (offset = ETH_MIB_BAD_OCTETS_RECEIVED; offset <= ETH_MIB_FRAMES_1024_TO_MAX_OCTETS; offset += 4) - *(u32 *)((char *)p + offset) += read_mib(mp, offset); + *(u32 *)((char *)p + offset) = read_mib(mp, offset); p->good_octets_sent += read_mib(mp, ETH_MIB_GOOD_OCTETS_SENT_LOW); p->good_octets_sent += @@ -2164,7 +2165,7 @@ static void eth_update_mib_counters(struct mv643xx_private *mp) for (offset = ETH_MIB_GOOD_FRAMES_SENT; offset <= ETH_MIB_LATE_COLLISION; offset += 4) - *(u32 *)((char *)p + offset) += read_mib(mp, offset); + *(u32 *)((char *)p + offset) = read_mib(mp, offset); } /* diff --git a/trunk/drivers/net/myri10ge/myri10ge.c b/trunk/drivers/net/myri10ge/myri10ge.c index 806081b59733..4330197994df 100644 --- a/trunk/drivers/net/myri10ge/myri10ge.c +++ b/trunk/drivers/net/myri10ge/myri10ge.c @@ -1148,7 +1148,7 @@ static int myri10ge_poll(struct net_device *netdev, int *budget) return 1; } -static irqreturn_t myri10ge_intr(int irq, void *arg) +static irqreturn_t myri10ge_intr(int irq, void *arg, struct pt_regs *regs) { struct myri10ge_priv *mgp = arg; struct mcp_irq_data *stats = mgp->fw_stats; @@ -2416,6 +2416,7 @@ static void myri10ge_enable_ecrc(struct myri10ge_priv *mgp) * firmware image, and set tx.boundary to 4KB. */ +#define PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE 0x0132 #define PCI_DEVICE_ID_INTEL_E5000_PCIE23 0x25f7 #define PCI_DEVICE_ID_INTEL_E5000_PCIE47 0x25fa diff --git a/trunk/drivers/net/myri_code.h b/trunk/drivers/net/myri_code.h index ba7b8652c501..e21ec9b2c706 100644 --- a/trunk/drivers/net/myri_code.h +++ b/trunk/drivers/net/myri_code.h @@ -1,8 +1,8 @@ /* This is the Myrinet MCP code for LANai4.x */ /* Generated by cat $MYRI_HOME/lib/lanai/mcp4.dat > myri_code4.h */ -static unsigned int __devinitdata lanai4_code_off = 0x0000; /* half-word offset */ -static unsigned char __devinitdata lanai4_code[76256] = { +static unsigned int lanai4_code_off = 0x0000; /* half-word offset */ +static unsigned char lanai4_code[76256] __initdata = { 0xF2,0x0E, 0xFE,0x00, 0xC2,0x90, 0x00,0x00, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x01,0x4C, 0x97,0x93, 0xFF,0xFC, 0xE0,0x00, 0x00,0x14, 0x00,0x00, 0x00,0x01, 0x00,0x00, 0x00,0x00, 0x92,0x93, @@ -4774,8 +4774,8 @@ static unsigned char __devinitdata lanai4_code[76256] = { /* This is the LANai data */ -static unsigned int __devinitdata lanai4_data_off = 0x94F0; /* half-word offset */ -static unsigned char __devinitdata lanai4_data[20472]; +static unsigned int lanai4_data_off = 0x94F0; /* half-word offset */ +static unsigned char lanai4_data[20472] __initdata; #ifdef SYMBOL_DEFINES_COMPILED diff --git a/trunk/drivers/net/myri_sbus.c b/trunk/drivers/net/myri_sbus.c index 7747bfd99f91..a925bc9db4ac 100644 --- a/trunk/drivers/net/myri_sbus.c +++ b/trunk/drivers/net/myri_sbus.c @@ -168,7 +168,7 @@ static int myri_do_handshake(struct myri_eth *mp) return 0; } -static int __devinit myri_load_lanai(struct myri_eth *mp) +static int myri_load_lanai(struct myri_eth *mp) { struct net_device *dev = mp->dev; struct myri_shmem __iomem *shmem = mp->shmem; @@ -536,7 +536,7 @@ static void myri_rx(struct myri_eth *mp, struct net_device *dev) } } -static irqreturn_t myri_interrupt(int irq, void *dev_id) +static irqreturn_t myri_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_id; struct myri_eth *mp = (struct myri_eth *) dev->priv; @@ -891,7 +891,7 @@ static void dump_eeprom(struct myri_eth *mp) } #endif -static int __devinit myri_ether_init(struct sbus_dev *sdev) +static int __init myri_ether_init(struct sbus_dev *sdev) { static int num; static unsigned version_printed; diff --git a/trunk/drivers/net/natsemi.c b/trunk/drivers/net/natsemi.c index ffa0afd2eddc..d7b241f7d7bc 100644 --- a/trunk/drivers/net/natsemi.c +++ b/trunk/drivers/net/natsemi.c @@ -623,7 +623,7 @@ static void free_ring(struct net_device *dev); static void reinit_ring(struct net_device *dev); static void init_registers(struct net_device *dev); static int start_tx(struct sk_buff *skb, struct net_device *dev); -static irqreturn_t intr_handler(int irq, void *dev_instance); +static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *regs); static void netdev_error(struct net_device *dev, int intr_status); static int natsemi_poll(struct net_device *dev, int *budget); static void netdev_rx(struct net_device *dev, int *work_done, int work_to_do); @@ -2088,7 +2088,7 @@ static void netdev_tx_done(struct net_device *dev) /* The interrupt handler doesn't actually handle interrupts itself, it * schedules a NAPI poll if there is anything to do. */ -static irqreturn_t intr_handler(int irq, void *dev_instance) +static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *rgs) { struct net_device *dev = dev_instance; struct netdev_private *np = netdev_priv(dev); @@ -2373,7 +2373,7 @@ static struct net_device_stats *get_stats(struct net_device *dev) static void natsemi_poll_controller(struct net_device *dev) { disable_irq(dev->irq); - intr_handler(dev->irq, dev); + intr_handler(dev->irq, dev, NULL); enable_irq(dev->irq); } #endif diff --git a/trunk/drivers/net/netx-eth.c b/trunk/drivers/net/netx-eth.c index a53644f6a29b..30ed9a5a40e0 100644 --- a/trunk/drivers/net/netx-eth.c +++ b/trunk/drivers/net/netx-eth.c @@ -176,7 +176,7 @@ static void netx_eth_receive(struct net_device *ndev) } static irqreturn_t -netx_eth_interrupt(int irq, void *dev_id) +netx_eth_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *ndev = dev_id; struct netx_eth_priv *priv = netdev_priv(ndev); diff --git a/trunk/drivers/net/ni5010.c b/trunk/drivers/net/ni5010.c index 8be0d030d6f4..383c690eefec 100644 --- a/trunk/drivers/net/ni5010.c +++ b/trunk/drivers/net/ni5010.c @@ -99,7 +99,7 @@ struct ni5010_local { static int ni5010_probe1(struct net_device *dev, int ioaddr); static int ni5010_open(struct net_device *dev); static int ni5010_send_packet(struct sk_buff *skb, struct net_device *dev); -static irqreturn_t ni5010_interrupt(int irq, void *dev_id); +static irqreturn_t ni5010_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void ni5010_rx(struct net_device *dev); static void ni5010_timeout(struct net_device *dev); static int ni5010_close(struct net_device *dev); @@ -468,7 +468,7 @@ static int ni5010_send_packet(struct sk_buff *skb, struct net_device *dev) * The typical workload of the driver: * Handle the network interface interrupts. */ -static irqreturn_t ni5010_interrupt(int irq, void *dev_id) +static irqreturn_t ni5010_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; struct ni5010_local *lp; diff --git a/trunk/drivers/net/ni52.c b/trunk/drivers/net/ni52.c index 26e42f6e9fb1..e8889235996e 100644 --- a/trunk/drivers/net/ni52.c +++ b/trunk/drivers/net/ni52.c @@ -195,7 +195,7 @@ sizeof(nop_cmd) = 8; #define NI52_ADDR2 0x01 static int ni52_probe1(struct net_device *dev,int ioaddr); -static irqreturn_t ni52_interrupt(int irq,void *dev_id); +static irqreturn_t ni52_interrupt(int irq,void *dev_id,struct pt_regs *reg_ptr); static int ni52_open(struct net_device *dev); static int ni52_close(struct net_device *dev); static int ni52_send_packet(struct sk_buff *,struct net_device *); @@ -837,7 +837,7 @@ static void *alloc_rfa(struct net_device *dev,void *ptr) * Interrupt Handler ... */ -static irqreturn_t ni52_interrupt(int irq,void *dev_id) +static irqreturn_t ni52_interrupt(int irq,void *dev_id,struct pt_regs *reg_ptr) { struct net_device *dev = dev_id; unsigned short stat; diff --git a/trunk/drivers/net/ni65.c b/trunk/drivers/net/ni65.c index 340ad0d5388a..fab3c8593ac1 100644 --- a/trunk/drivers/net/ni65.c +++ b/trunk/drivers/net/ni65.c @@ -248,7 +248,7 @@ struct priv }; static int ni65_probe1(struct net_device *dev,int); -static irqreturn_t ni65_interrupt(int irq, void * dev_id); +static irqreturn_t ni65_interrupt(int irq, void * dev_id, struct pt_regs *regs); static void ni65_recv_intr(struct net_device *dev,int); static void ni65_xmit_intr(struct net_device *dev,int); static int ni65_open(struct net_device *dev); @@ -871,7 +871,7 @@ static int ni65_lance_reinit(struct net_device *dev) /* * interrupt handler */ -static irqreturn_t ni65_interrupt(int irq, void * dev_id) +static irqreturn_t ni65_interrupt(int irq, void * dev_id, struct pt_regs * regs) { int csr0 = 0; struct net_device *dev = dev_id; diff --git a/trunk/drivers/net/ns83820.c b/trunk/drivers/net/ns83820.c index b0127c71a5b6..e10da1aa3d30 100644 --- a/trunk/drivers/net/ns83820.c +++ b/trunk/drivers/net/ns83820.c @@ -1288,7 +1288,7 @@ static void ns83820_mib_isr(struct ns83820 *dev) } static void ns83820_do_isr(struct net_device *ndev, u32 isr); -static irqreturn_t ns83820_irq(int foo, void *data) +static irqreturn_t ns83820_irq(int foo, void *data, struct pt_regs *regs) { struct net_device *ndev = data; struct ns83820 *dev = PRIV(ndev); diff --git a/trunk/drivers/net/pci-skeleton.c b/trunk/drivers/net/pci-skeleton.c index 00ca0fdb837b..2687e747657d 100644 --- a/trunk/drivers/net/pci-skeleton.c +++ b/trunk/drivers/net/pci-skeleton.c @@ -502,7 +502,8 @@ static void netdrv_tx_timeout (struct net_device *dev); static void netdrv_init_ring (struct net_device *dev); static int netdrv_start_xmit (struct sk_buff *skb, struct net_device *dev); -static irqreturn_t netdrv_interrupt (int irq, void *dev_instance); +static irqreturn_t netdrv_interrupt (int irq, void *dev_instance, + struct pt_regs *regs); static int netdrv_close (struct net_device *dev); static int netdrv_ioctl (struct net_device *dev, struct ifreq *rq, int cmd); static struct net_device_stats *netdrv_get_stats (struct net_device *dev); @@ -1653,7 +1654,8 @@ static void netdrv_weird_interrupt (struct net_device *dev, /* The interrupt handler does all of the Rx thread work and cleans up after the Tx thread. */ -static irqreturn_t netdrv_interrupt (int irq, void *dev_instance) +static irqreturn_t netdrv_interrupt (int irq, void *dev_instance, + struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_instance; struct netdrv_private *tp = dev->priv; diff --git a/trunk/drivers/net/pcmcia/3c574_cs.c b/trunk/drivers/net/pcmcia/3c574_cs.c index 046009928526..2418cdb9d317 100644 --- a/trunk/drivers/net/pcmcia/3c574_cs.c +++ b/trunk/drivers/net/pcmcia/3c574_cs.c @@ -238,7 +238,7 @@ static void tc574_reset(struct net_device *dev); static void media_check(unsigned long arg); static int el3_open(struct net_device *dev); static int el3_start_xmit(struct sk_buff *skb, struct net_device *dev); -static irqreturn_t el3_interrupt(int irq, void *dev_id); +static irqreturn_t el3_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void update_stats(struct net_device *dev); static struct net_device_stats *el3_get_stats(struct net_device *dev); static int el3_rx(struct net_device *dev, int worklimit); @@ -817,7 +817,7 @@ static int el3_start_xmit(struct sk_buff *skb, struct net_device *dev) } /* The EL3 interrupt handler. */ -static irqreturn_t el3_interrupt(int irq, void *dev_id) +static irqreturn_t el3_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_id; struct el3_private *lp = netdev_priv(dev); @@ -927,7 +927,7 @@ static void media_check(unsigned long arg) if ((inw(ioaddr + EL3_STATUS) & IntLatch) && (inb(ioaddr + Timer) == 0xff)) { if (!lp->fast_poll) printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name); - el3_interrupt(dev->irq, lp); + el3_interrupt(dev->irq, lp, NULL); lp->fast_poll = HZ; } if (lp->fast_poll) { diff --git a/trunk/drivers/net/pcmcia/3c589_cs.c b/trunk/drivers/net/pcmcia/3c589_cs.c index 231fa2c9ec6c..a0e2b01c027c 100644 --- a/trunk/drivers/net/pcmcia/3c589_cs.c +++ b/trunk/drivers/net/pcmcia/3c589_cs.c @@ -151,7 +151,7 @@ static void media_check(unsigned long arg); static int el3_config(struct net_device *dev, struct ifmap *map); static int el3_open(struct net_device *dev); static int el3_start_xmit(struct sk_buff *skb, struct net_device *dev); -static irqreturn_t el3_interrupt(int irq, void *dev_id); +static irqreturn_t el3_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void update_stats(struct net_device *dev); static struct net_device_stats *el3_get_stats(struct net_device *dev); static int el3_rx(struct net_device *dev); @@ -645,7 +645,7 @@ static int el3_start_xmit(struct sk_buff *skb, struct net_device *dev) } /* The EL3 interrupt handler. */ -static irqreturn_t el3_interrupt(int irq, void *dev_id) +static irqreturn_t el3_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_id; struct el3_private *lp = netdev_priv(dev); @@ -748,7 +748,7 @@ static void media_check(unsigned long arg) (inb(ioaddr + EL3_TIMER) == 0xff)) { if (!lp->fast_poll) printk(KERN_WARNING "%s: interrupt(s) dropped!\n", dev->name); - el3_interrupt(dev->irq, lp); + el3_interrupt(dev->irq, lp, NULL); lp->fast_poll = HZ; } if (lp->fast_poll) { diff --git a/trunk/drivers/net/pcmcia/axnet_cs.c b/trunk/drivers/net/pcmcia/axnet_cs.c index 5ddd5742f779..a8891a9000ac 100644 --- a/trunk/drivers/net/pcmcia/axnet_cs.c +++ b/trunk/drivers/net/pcmcia/axnet_cs.c @@ -92,7 +92,7 @@ static int axnet_open(struct net_device *dev); static int axnet_close(struct net_device *dev); static int axnet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); static const struct ethtool_ops netdev_ethtool_ops; -static irqreturn_t ei_irq_wrapper(int irq, void *dev_id); +static irqreturn_t ei_irq_wrapper(int irq, void *dev_id, struct pt_regs *regs); static void ei_watchdog(u_long arg); static void axnet_reset_8390(struct net_device *dev); @@ -112,7 +112,7 @@ static void axdev_setup(struct net_device *dev); static void AX88190_init(struct net_device *dev, int startp); static int ax_open(struct net_device *dev); static int ax_close(struct net_device *dev); -static irqreturn_t ax_interrupt(int irq, void *dev_id); +static irqreturn_t ax_interrupt(int irq, void *dev_id, struct pt_regs *regs); /*====================================================================*/ @@ -599,11 +599,11 @@ static void axnet_reset_8390(struct net_device *dev) /*====================================================================*/ -static irqreturn_t ei_irq_wrapper(int irq, void *dev_id) +static irqreturn_t ei_irq_wrapper(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; PRIV(dev)->stale = 0; - return ax_interrupt(irq, dev_id); + return ax_interrupt(irq, dev_id, regs); } static void ei_watchdog(u_long arg) @@ -621,7 +621,7 @@ static void ei_watchdog(u_long arg) if (info->stale++ && (inb_p(nic_base + EN0_ISR) & ENISR_ALL)) { if (!info->fast_poll) printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name); - ei_irq_wrapper(dev->irq, dev); + ei_irq_wrapper(dev->irq, dev, NULL); info->fast_poll = HZ; } if (info->fast_poll) { @@ -1193,7 +1193,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev) * needed. */ -static irqreturn_t ax_interrupt(int irq, void *dev_id) +static irqreturn_t ax_interrupt(int irq, void *dev_id, struct pt_regs * regs) { struct net_device *dev = dev_id; long e8390_base; @@ -1201,8 +1201,14 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id) struct ei_device *ei_local; int handled = 0; + if (dev == NULL) + { + printk ("net_interrupt(): irq %d for unknown device.\n", irq); + return IRQ_NONE; + } + e8390_base = dev->base_addr; - ei_local = netdev_priv(dev); + ei_local = (struct ei_device *) netdev_priv(dev); /* * Protect the irq test too. diff --git a/trunk/drivers/net/pcmcia/fmvj18x_cs.c b/trunk/drivers/net/pcmcia/fmvj18x_cs.c index 65f6fdf43725..d682f30dea6e 100644 --- a/trunk/drivers/net/pcmcia/fmvj18x_cs.c +++ b/trunk/drivers/net/pcmcia/fmvj18x_cs.c @@ -97,7 +97,7 @@ static int fjn_config(struct net_device *dev, struct ifmap *map); static int fjn_open(struct net_device *dev); static int fjn_close(struct net_device *dev); static int fjn_start_xmit(struct sk_buff *skb, struct net_device *dev); -static irqreturn_t fjn_interrupt(int irq, void *dev_id); +static irqreturn_t fjn_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void fjn_rx(struct net_device *dev); static void fjn_reset(struct net_device *dev); static struct net_device_stats *fjn_get_stats(struct net_device *dev); @@ -733,7 +733,7 @@ module_exit(exit_fmvj18x_cs); /*====================================================================*/ -static irqreturn_t fjn_interrupt(int irq, void *dev_id) +static irqreturn_t fjn_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; local_info_t *lp = netdev_priv(dev); diff --git a/trunk/drivers/net/pcmcia/nmclan_cs.c b/trunk/drivers/net/pcmcia/nmclan_cs.c index e77110e4c288..7d5687e94607 100644 --- a/trunk/drivers/net/pcmcia/nmclan_cs.c +++ b/trunk/drivers/net/pcmcia/nmclan_cs.c @@ -426,7 +426,7 @@ static int mace_open(struct net_device *dev); static int mace_close(struct net_device *dev); static int mace_start_xmit(struct sk_buff *skb, struct net_device *dev); static void mace_tx_timeout(struct net_device *dev); -static irqreturn_t mace_interrupt(int irq, void *dev_id); +static irqreturn_t mace_interrupt(int irq, void *dev_id, struct pt_regs *regs); static struct net_device_stats *mace_get_stats(struct net_device *dev); static int mace_rx(struct net_device *dev, unsigned char RxCnt); static void restore_multicast_list(struct net_device *dev); @@ -1002,7 +1002,7 @@ static int mace_start_xmit(struct sk_buff *skb, struct net_device *dev) mace_interrupt The interrupt handler. ---------------------------------------------------------------------------- */ -static irqreturn_t mace_interrupt(int irq, void *dev_id) +static irqreturn_t mace_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_id; mace_private *lp = netdev_priv(dev); diff --git a/trunk/drivers/net/pcmcia/pcnet_cs.c b/trunk/drivers/net/pcmcia/pcnet_cs.c index 0c00d182e7fd..a09c22840f63 100644 --- a/trunk/drivers/net/pcmcia/pcnet_cs.c +++ b/trunk/drivers/net/pcmcia/pcnet_cs.c @@ -109,7 +109,7 @@ static int pcnet_open(struct net_device *dev); static int pcnet_close(struct net_device *dev); static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); static const struct ethtool_ops netdev_ethtool_ops; -static irqreturn_t ei_irq_wrapper(int irq, void *dev_id); +static irqreturn_t ei_irq_wrapper(int irq, void *dev_id, struct pt_regs *regs); static void ei_watchdog(u_long arg); static void pcnet_reset_8390(struct net_device *dev); static int set_config(struct net_device *dev, struct ifmap *map); @@ -1071,11 +1071,11 @@ static int set_config(struct net_device *dev, struct ifmap *map) /*====================================================================*/ -static irqreturn_t ei_irq_wrapper(int irq, void *dev_id) +static irqreturn_t ei_irq_wrapper(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; pcnet_dev_t *info; - irqreturn_t ret = ei_interrupt(irq, dev_id); + irqreturn_t ret = ei_interrupt(irq, dev_id, regs); if (ret == IRQ_HANDLED) { info = PRIV(dev); @@ -1100,7 +1100,7 @@ static void ei_watchdog(u_long arg) if (info->stale++ && (inb_p(nic_base + EN0_ISR) & ENISR_ALL)) { if (!info->fast_poll) printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name); - ei_irq_wrapper(dev->irq, dev); + ei_irq_wrapper(dev->irq, dev, NULL); info->fast_poll = HZ; } if (info->fast_poll) { diff --git a/trunk/drivers/net/pcmcia/smc91c92_cs.c b/trunk/drivers/net/pcmcia/smc91c92_cs.c index 20fcc3576202..a2f3a0e2a005 100644 --- a/trunk/drivers/net/pcmcia/smc91c92_cs.c +++ b/trunk/drivers/net/pcmcia/smc91c92_cs.c @@ -287,7 +287,7 @@ static int smc_close(struct net_device *dev); static int smc_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); static void smc_tx_timeout(struct net_device *dev); static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev); -static irqreturn_t smc_interrupt(int irq, void *dev_id); +static irqreturn_t smc_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void smc_rx(struct net_device *dev); static struct net_device_stats *smc_get_stats(struct net_device *dev); static void set_rx_mode(struct net_device *dev); @@ -1545,7 +1545,7 @@ static void smc_eph_irq(struct net_device *dev) /*====================================================================*/ -static irqreturn_t smc_interrupt(int irq, void *dev_id) +static irqreturn_t smc_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; struct smc_private *smc = netdev_priv(dev); @@ -1966,7 +1966,7 @@ static void media_check(u_long arg) if (smc->watchdog++ && ((i>>8) & i)) { if (!smc->fast_poll) printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name); - smc_interrupt(dev->irq, smc); + smc_interrupt(dev->irq, smc, NULL); smc->fast_poll = HZ; } if (smc->fast_poll) { diff --git a/trunk/drivers/net/pcmcia/xirc2ps_cs.c b/trunk/drivers/net/pcmcia/xirc2ps_cs.c index f3914f58d67f..62664c01eb45 100644 --- a/trunk/drivers/net/pcmcia/xirc2ps_cs.c +++ b/trunk/drivers/net/pcmcia/xirc2ps_cs.c @@ -308,7 +308,7 @@ static void xirc2ps_detach(struct pcmcia_device *p_dev); * less on other parts of the kernel. */ -static irqreturn_t xirc2ps_interrupt(int irq, void *dev_id); +static irqreturn_t xirc2ps_interrupt(int irq, void *dev_id, struct pt_regs *regs); /**************** * A linked list of "instances" of the device. Each actual @@ -1121,7 +1121,7 @@ static int xirc2ps_resume(struct pcmcia_device *link) * This is the Interrupt service route. */ static irqreturn_t -xirc2ps_interrupt(int irq, void *dev_id) +xirc2ps_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *)dev_id; local_info_t *lp = netdev_priv(dev); diff --git a/trunk/drivers/net/pcnet32.c b/trunk/drivers/net/pcnet32.c index 36f9d988278f..a43e24245b7e 100644 --- a/trunk/drivers/net/pcnet32.c +++ b/trunk/drivers/net/pcnet32.c @@ -304,7 +304,7 @@ static int pcnet32_open(struct net_device *); static int pcnet32_init_ring(struct net_device *); static int pcnet32_start_xmit(struct sk_buff *, struct net_device *); static void pcnet32_tx_timeout(struct net_device *dev); -static irqreturn_t pcnet32_interrupt(int, void *); +static irqreturn_t pcnet32_interrupt(int, void *, struct pt_regs *); static int pcnet32_close(struct net_device *); static struct net_device_stats *pcnet32_get_stats(struct net_device *); static void pcnet32_load_multicast(struct net_device *dev); @@ -674,7 +674,7 @@ static void pcnet32_purge_rx_ring(struct net_device *dev) static void pcnet32_poll_controller(struct net_device *dev) { disable_irq(dev->irq); - pcnet32_interrupt(0, dev); + pcnet32_interrupt(0, dev, NULL); enable_irq(dev->irq); } #endif @@ -2561,7 +2561,7 @@ static int pcnet32_start_xmit(struct sk_buff *skb, struct net_device *dev) /* The PCNET32 interrupt handler. */ static irqreturn_t -pcnet32_interrupt(int irq, void *dev_id) +pcnet32_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; struct pcnet32_private *lp; @@ -2569,6 +2569,13 @@ pcnet32_interrupt(int irq, void *dev_id) u16 csr0; int boguscnt = max_interrupt_work; + if (!dev) { + if (pcnet32_debug & NETIF_MSG_INTR) + printk(KERN_DEBUG "%s(): irq %d for unknown device\n", + __FUNCTION__, irq); + return IRQ_NONE; + } + ioaddr = dev->base_addr; lp = dev->priv; diff --git a/trunk/drivers/net/phy/Kconfig b/trunk/drivers/net/phy/Kconfig index ecb61f876f27..b79ec0d7480f 100644 --- a/trunk/drivers/net/phy/Kconfig +++ b/trunk/drivers/net/phy/Kconfig @@ -61,8 +61,8 @@ config FIXED_PHY depends on PHYLIB ---help--- Adds the driver to PHY layer to cover the boards that do not have any PHY bound, - but with the ability to manipulate the speed/link in software. The relevant MII - speed/duplex parameters could be effectively handled in a user-specified function. + but with the ability to manipulate with speed/link in software. The relavant MII + speed/duplex parameters could be effectively handled in user-specified fuction. Currently tested with mpc866ads. config FIXED_MII_10_FDX diff --git a/trunk/drivers/net/phy/phy.c b/trunk/drivers/net/phy/phy.c index 3af9fcf76c81..f5aad77288f9 100644 --- a/trunk/drivers/net/phy/phy.c +++ b/trunk/drivers/net/phy/phy.c @@ -480,7 +480,7 @@ void phy_error(struct phy_device *phydev) * description: When a PHY interrupt occurs, the handler disables * interrupts, and schedules a work task to clear the interrupt. */ -static irqreturn_t phy_interrupt(int irq, void *phy_dat) +static irqreturn_t phy_interrupt(int irq, void *phy_dat, struct pt_regs *regs) { struct phy_device *phydev = phy_dat; diff --git a/trunk/drivers/net/plip.c b/trunk/drivers/net/plip.c index 71afb274498f..d4f54e9798cd 100644 --- a/trunk/drivers/net/plip.c +++ b/trunk/drivers/net/plip.c @@ -143,7 +143,7 @@ static void plip_bh(struct net_device *dev); static void plip_timer_bh(struct net_device *dev); /* Interrupt handler */ -static void plip_interrupt(int irq, void *dev_id); +static void plip_interrupt(int irq, void *dev_id, struct pt_regs *regs); /* Functions for DEV methods */ static int plip_tx_packet(struct sk_buff *skb, struct net_device *dev); @@ -385,7 +385,7 @@ plip_timer_bh(struct net_device *dev) struct net_local *nl = netdev_priv(dev); if (!(atomic_read (&nl->kill_timer))) { - plip_interrupt (-1, dev); + plip_interrupt (-1, dev, NULL); schedule_delayed_work(&nl->timer, 1); } @@ -902,13 +902,18 @@ plip_error(struct net_device *dev, struct net_local *nl, /* Handle the parallel port interrupts. */ static void -plip_interrupt(int irq, void *dev_id) +plip_interrupt(int irq, void *dev_id, struct pt_regs * regs) { struct net_device *dev = dev_id; struct net_local *nl; struct plip_local *rcv; unsigned char c0; + if (dev == NULL) { + printk(KERN_DEBUG "plip_interrupt: irq %d for unknown device.\n", irq); + return; + } + nl = netdev_priv(dev); rcv = &nl->rcv_data; diff --git a/trunk/drivers/net/ppp_generic.c b/trunk/drivers/net/ppp_generic.c index c6de566188e4..f5802e7b08e9 100644 --- a/trunk/drivers/net/ppp_generic.c +++ b/trunk/drivers/net/ppp_generic.c @@ -860,7 +860,7 @@ static int __init ppp_init(void) err = PTR_ERR(ppp_class); goto out_chrdev; } - device_create(ppp_class, NULL, MKDEV(PPP_MAJOR, 0), "ppp"); + class_device_create(ppp_class, NULL, MKDEV(PPP_MAJOR, 0), NULL, "ppp"); } out: @@ -2675,7 +2675,7 @@ static void __exit ppp_cleanup(void) cardmap_destroy(&all_ppp_units); if (unregister_chrdev(PPP_MAJOR, "ppp") != 0) printk(KERN_ERR "PPP: failed to unregister PPP device\n"); - device_destroy(ppp_class, MKDEV(PPP_MAJOR, 0)); + class_device_destroy(ppp_class, MKDEV(PPP_MAJOR, 0)); class_destroy(ppp_class); } diff --git a/trunk/drivers/net/qla3xxx.c b/trunk/drivers/net/qla3xxx.c index ec640f6229ae..157471846349 100644 --- a/trunk/drivers/net/qla3xxx.c +++ b/trunk/drivers/net/qla3xxx.c @@ -1965,7 +1965,7 @@ static int ql_poll(struct net_device *ndev, int *budget) return 1; } -static irqreturn_t ql3xxx_isr(int irq, void *dev_id) +static irqreturn_t ql3xxx_isr(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *ndev = dev_id; diff --git a/trunk/drivers/net/r8169.c b/trunk/drivers/net/r8169.c index b977ed85ff39..4c47c5b10ba0 100644 --- a/trunk/drivers/net/r8169.c +++ b/trunk/drivers/net/r8169.c @@ -214,7 +214,6 @@ static struct pci_device_id rtl8169_pci_tbl[] = { { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8168), 0, 0, RTL_CFG_2 }, { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8169), 0, 0, RTL_CFG_0 }, { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4300), 0, 0, RTL_CFG_0 }, - { PCI_DEVICE(0x1259, 0xc107), 0, 0, RTL_CFG_0 }, { PCI_DEVICE(0x16ec, 0x0116), 0, 0, RTL_CFG_0 }, { PCI_VENDOR_ID_LINKSYS, 0x1032, PCI_ANY_ID, 0x0024, 0, 0, RTL_CFG_0 }, @@ -474,7 +473,8 @@ MODULE_VERSION(RTL8169_VERSION); static int rtl8169_open(struct net_device *dev); static int rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev); -static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance); +static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance, + struct pt_regs *regs); static int rtl8169_init_ring(struct net_device *dev); static void rtl8169_hw_start(struct net_device *dev); static int rtl8169_close(struct net_device *dev); @@ -1392,11 +1392,46 @@ static void rtl8169_netpoll(struct net_device *dev) struct pci_dev *pdev = tp->pci_dev; disable_irq(pdev->irq); - rtl8169_interrupt(pdev->irq, dev); + rtl8169_interrupt(pdev->irq, dev, NULL); enable_irq(pdev->irq); } #endif +static void __rtl8169_set_mac_addr(struct net_device *dev, void __iomem *ioaddr) +{ + unsigned int i, j; + + RTL_W8(Cfg9346, Cfg9346_Unlock); + for (i = 0; i < 2; i++) { + __le32 l = 0; + + for (j = 0; j < 4; j++) { + l <<= 8; + l |= dev->dev_addr[4*i + j]; + } + RTL_W32(MAC0 + 4*i, cpu_to_be32(l)); + } + RTL_W8(Cfg9346, Cfg9346_Lock); +} + +static int rtl8169_set_mac_addr(struct net_device *dev, void *p) +{ + struct rtl8169_private *tp = netdev_priv(dev); + struct sockaddr *addr = p; + + if (!is_valid_ether_addr(addr->sa_data)) + return -EINVAL; + + memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); + + if (netif_running(dev)) { + spin_lock_irq(&tp->lock); + __rtl8169_set_mac_addr(dev, tp->mmio_addr); + spin_unlock_irq(&tp->lock); + } + return 0; +} + static void rtl8169_release_board(struct pci_dev *pdev, struct net_device *dev, void __iomem *ioaddr) { @@ -1473,8 +1508,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) struct rtl8169_private *tp; struct net_device *dev; void __iomem *ioaddr; - unsigned int pm_cap; - int i, rc; + unsigned int i, pm_cap; + int rc; if (netif_msg_drv(&debug)) { printk(KERN_INFO "%s Gigabit Ethernet driver %s loaded\n", @@ -1646,6 +1681,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) dev->stop = rtl8169_close; dev->tx_timeout = rtl8169_tx_timeout; dev->set_multicast_list = rtl8169_set_rx_mode; + dev->set_mac_address = rtl8169_set_mac_addr; dev->watchdog_timeo = RTL8169_TX_TIMEOUT; dev->irq = pdev->irq; dev->base_addr = (unsigned long) ioaddr; @@ -1893,6 +1929,8 @@ rtl8169_hw_start(struct net_device *dev) /* Enable all known interrupts by setting the interrupt mask. */ RTL_W16(IntrMask, rtl8169_intr_mask); + __rtl8169_set_mac_addr(dev, ioaddr); + netif_start_queue(dev); } @@ -2554,7 +2592,7 @@ rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp, /* The interrupt handler does all of the Rx thread work and cleans up after the Tx thread. */ static irqreturn_t -rtl8169_interrupt(int irq, void *dev_instance) +rtl8169_interrupt(int irq, void *dev_instance, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_instance; struct rtl8169_private *tp = netdev_priv(dev); @@ -2663,7 +2701,6 @@ static void rtl8169_down(struct net_device *dev) struct rtl8169_private *tp = netdev_priv(dev); void __iomem *ioaddr = tp->mmio_addr; unsigned int poll_locked = 0; - unsigned int intrmask; rtl8169_delete_timer(dev); @@ -2702,11 +2739,8 @@ static void rtl8169_down(struct net_device *dev) * 2) dev->change_mtu * -> rtl8169_poll can not be issued again and re-enable the * interruptions. Let's simply issue the IRQ down sequence again. - * - * No loop if hotpluged or major error (0xffff). */ - intrmask = RTL_R16(IntrMask); - if (intrmask && (intrmask != 0xffff)) + if (RTL_R16(IntrMask)) goto core_down; rtl8169_tx_clear(tp); diff --git a/trunk/drivers/net/rrunner.c b/trunk/drivers/net/rrunner.c index d81536f90df6..6108bac8d56a 100644 --- a/trunk/drivers/net/rrunner.c +++ b/trunk/drivers/net/rrunner.c @@ -1053,7 +1053,7 @@ static void rx_int(struct net_device *dev, u32 rxlimit, u32 index) } -static irqreturn_t rr_interrupt(int irq, void *dev_id) +static irqreturn_t rr_interrupt(int irq, void *dev_id, struct pt_regs *ptregs) { struct rr_private *rrpriv; struct rr_regs __iomem *regs; diff --git a/trunk/drivers/net/rrunner.h b/trunk/drivers/net/rrunner.h index 9f3e050c4dc6..99451b523399 100644 --- a/trunk/drivers/net/rrunner.h +++ b/trunk/drivers/net/rrunner.h @@ -829,7 +829,7 @@ struct rr_private */ static int rr_init(struct net_device *dev); static int rr_init1(struct net_device *dev); -static irqreturn_t rr_interrupt(int irq, void *dev_id); +static irqreturn_t rr_interrupt(int irq, void *dev_id, struct pt_regs *regs); static int rr_open(struct net_device *dev); static int rr_start_xmit(struct sk_buff *skb, struct net_device *dev); diff --git a/trunk/drivers/net/s2io.c b/trunk/drivers/net/s2io.c index 33569ec9dbfc..1bf23e41f580 100644 --- a/trunk/drivers/net/s2io.c +++ b/trunk/drivers/net/s2io.c @@ -4029,7 +4029,8 @@ static int s2io_chk_rx_buffers(nic_t *sp, int rng_n) return 0; } -static irqreturn_t s2io_msi_handle(int irq, void *dev_id) +static irqreturn_t +s2io_msi_handle(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_id; nic_t *sp = dev->priv; @@ -4062,7 +4063,8 @@ static irqreturn_t s2io_msi_handle(int irq, void *dev_id) return IRQ_HANDLED; } -static irqreturn_t s2io_msix_ring_handle(int irq, void *dev_id) +static irqreturn_t +s2io_msix_ring_handle(int irq, void *dev_id, struct pt_regs *regs) { ring_info_t *ring = (ring_info_t *)dev_id; nic_t *sp = ring->nic; @@ -4076,7 +4078,8 @@ static irqreturn_t s2io_msix_ring_handle(int irq, void *dev_id) return IRQ_HANDLED; } -static irqreturn_t s2io_msix_fifo_handle(int irq, void *dev_id) +static irqreturn_t +s2io_msix_fifo_handle(int irq, void *dev_id, struct pt_regs *regs) { fifo_info_t *fifo = (fifo_info_t *)dev_id; nic_t *sp = fifo->nic; @@ -4152,6 +4155,7 @@ static void s2io_txpic_intr_handle(nic_t *sp) * s2io_isr - ISR handler of the device . * @irq: the irq of the device. * @dev_id: a void pointer to the dev structure of the NIC. + * @pt_regs: pointer to the registers pushed on the stack. * Description: This function is the ISR handler of the device. It * identifies the reason for the interrupt and calls the relevant * service routines. As a contongency measure, this ISR allocates the @@ -4161,7 +4165,7 @@ static void s2io_txpic_intr_handle(nic_t *sp) * IRQ_HANDLED: will be returned if IRQ was handled by this routine * IRQ_NONE: will be returned if interrupt is not from our device */ -static irqreturn_t s2io_isr(int irq, void *dev_id) +static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_id; nic_t *sp = dev->priv; @@ -5985,11 +5989,6 @@ static int set_rxd_buffer_pointer(nic_t *sp, RxD_t *rxdp, buffAdd_t *ba, ((RxD3_t*)rxdp)->Buffer1_ptr = *temp1; } else { *skb = dev_alloc_skb(size); - if (!(*skb)) { - DBG_PRINT(ERR_DBG, "%s: dev_alloc_skb failed\n", - dev->name); - return -ENOMEM; - } ((RxD3_t*)rxdp)->Buffer2_ptr = *temp2 = pci_map_single(sp->pdev, (*skb)->data, dev->mtu + 4, @@ -6012,11 +6011,7 @@ static int set_rxd_buffer_pointer(nic_t *sp, RxD_t *rxdp, buffAdd_t *ba, ((RxD3_t*)rxdp)->Buffer2_ptr = *temp2; } else { *skb = dev_alloc_skb(size); - if (!(*skb)) { - DBG_PRINT(ERR_DBG, "%s: dev_alloc_skb failed\n", - dev->name); - return -ENOMEM; - } + ((RxD3_t*)rxdp)->Buffer0_ptr = *temp0 = pci_map_single(sp->pdev, ba->ba_0, BUF0_LEN, PCI_DMA_FROMDEVICE); diff --git a/trunk/drivers/net/s2io.h b/trunk/drivers/net/s2io.h index 12b719f4d00f..3afd9126a591 100644 --- a/trunk/drivers/net/s2io.h +++ b/trunk/drivers/net/s2io.h @@ -116,179 +116,179 @@ typedef struct { /* The statistics block of Xena */ typedef struct stat_block { /* Tx MAC statistics counters. */ - __le32 tmac_data_octets; - __le32 tmac_frms; - __le64 tmac_drop_frms; - __le32 tmac_bcst_frms; - __le32 tmac_mcst_frms; - __le64 tmac_pause_ctrl_frms; - __le32 tmac_ucst_frms; - __le32 tmac_ttl_octets; - __le32 tmac_any_err_frms; - __le32 tmac_nucst_frms; - __le64 tmac_ttl_less_fb_octets; - __le64 tmac_vld_ip_octets; - __le32 tmac_drop_ip; - __le32 tmac_vld_ip; - __le32 tmac_rst_tcp; - __le32 tmac_icmp; - __le64 tmac_tcp; - __le32 reserved_0; - __le32 tmac_udp; + u32 tmac_data_octets; + u32 tmac_frms; + u64 tmac_drop_frms; + u32 tmac_bcst_frms; + u32 tmac_mcst_frms; + u64 tmac_pause_ctrl_frms; + u32 tmac_ucst_frms; + u32 tmac_ttl_octets; + u32 tmac_any_err_frms; + u32 tmac_nucst_frms; + u64 tmac_ttl_less_fb_octets; + u64 tmac_vld_ip_octets; + u32 tmac_drop_ip; + u32 tmac_vld_ip; + u32 tmac_rst_tcp; + u32 tmac_icmp; + u64 tmac_tcp; + u32 reserved_0; + u32 tmac_udp; /* Rx MAC Statistics counters. */ - __le32 rmac_data_octets; - __le32 rmac_vld_frms; - __le64 rmac_fcs_err_frms; - __le64 rmac_drop_frms; - __le32 rmac_vld_bcst_frms; - __le32 rmac_vld_mcst_frms; - __le32 rmac_out_rng_len_err_frms; - __le32 rmac_in_rng_len_err_frms; - __le64 rmac_long_frms; - __le64 rmac_pause_ctrl_frms; - __le64 rmac_unsup_ctrl_frms; - __le32 rmac_accepted_ucst_frms; - __le32 rmac_ttl_octets; - __le32 rmac_discarded_frms; - __le32 rmac_accepted_nucst_frms; - __le32 reserved_1; - __le32 rmac_drop_events; - __le64 rmac_ttl_less_fb_octets; - __le64 rmac_ttl_frms; - __le64 reserved_2; - __le32 rmac_usized_frms; - __le32 reserved_3; - __le32 rmac_frag_frms; - __le32 rmac_osized_frms; - __le32 reserved_4; - __le32 rmac_jabber_frms; - __le64 rmac_ttl_64_frms; - __le64 rmac_ttl_65_127_frms; - __le64 reserved_5; - __le64 rmac_ttl_128_255_frms; - __le64 rmac_ttl_256_511_frms; - __le64 reserved_6; - __le64 rmac_ttl_512_1023_frms; - __le64 rmac_ttl_1024_1518_frms; - __le32 rmac_ip; - __le32 reserved_7; - __le64 rmac_ip_octets; - __le32 rmac_drop_ip; - __le32 rmac_hdr_err_ip; - __le32 reserved_8; - __le32 rmac_icmp; - __le64 rmac_tcp; - __le32 rmac_err_drp_udp; - __le32 rmac_udp; - __le64 rmac_xgmii_err_sym; - __le64 rmac_frms_q0; - __le64 rmac_frms_q1; - __le64 rmac_frms_q2; - __le64 rmac_frms_q3; - __le64 rmac_frms_q4; - __le64 rmac_frms_q5; - __le64 rmac_frms_q6; - __le64 rmac_frms_q7; - __le16 rmac_full_q3; - __le16 rmac_full_q2; - __le16 rmac_full_q1; - __le16 rmac_full_q0; - __le16 rmac_full_q7; - __le16 rmac_full_q6; - __le16 rmac_full_q5; - __le16 rmac_full_q4; - __le32 reserved_9; - __le32 rmac_pause_cnt; - __le64 rmac_xgmii_data_err_cnt; - __le64 rmac_xgmii_ctrl_err_cnt; - __le32 rmac_err_tcp; - __le32 rmac_accepted_ip; + u32 rmac_data_octets; + u32 rmac_vld_frms; + u64 rmac_fcs_err_frms; + u64 rmac_drop_frms; + u32 rmac_vld_bcst_frms; + u32 rmac_vld_mcst_frms; + u32 rmac_out_rng_len_err_frms; + u32 rmac_in_rng_len_err_frms; + u64 rmac_long_frms; + u64 rmac_pause_ctrl_frms; + u64 rmac_unsup_ctrl_frms; + u32 rmac_accepted_ucst_frms; + u32 rmac_ttl_octets; + u32 rmac_discarded_frms; + u32 rmac_accepted_nucst_frms; + u32 reserved_1; + u32 rmac_drop_events; + u64 rmac_ttl_less_fb_octets; + u64 rmac_ttl_frms; + u64 reserved_2; + u32 rmac_usized_frms; + u32 reserved_3; + u32 rmac_frag_frms; + u32 rmac_osized_frms; + u32 reserved_4; + u32 rmac_jabber_frms; + u64 rmac_ttl_64_frms; + u64 rmac_ttl_65_127_frms; + u64 reserved_5; + u64 rmac_ttl_128_255_frms; + u64 rmac_ttl_256_511_frms; + u64 reserved_6; + u64 rmac_ttl_512_1023_frms; + u64 rmac_ttl_1024_1518_frms; + u32 rmac_ip; + u32 reserved_7; + u64 rmac_ip_octets; + u32 rmac_drop_ip; + u32 rmac_hdr_err_ip; + u32 reserved_8; + u32 rmac_icmp; + u64 rmac_tcp; + u32 rmac_err_drp_udp; + u32 rmac_udp; + u64 rmac_xgmii_err_sym; + u64 rmac_frms_q0; + u64 rmac_frms_q1; + u64 rmac_frms_q2; + u64 rmac_frms_q3; + u64 rmac_frms_q4; + u64 rmac_frms_q5; + u64 rmac_frms_q6; + u64 rmac_frms_q7; + u16 rmac_full_q3; + u16 rmac_full_q2; + u16 rmac_full_q1; + u16 rmac_full_q0; + u16 rmac_full_q7; + u16 rmac_full_q6; + u16 rmac_full_q5; + u16 rmac_full_q4; + u32 reserved_9; + u32 rmac_pause_cnt; + u64 rmac_xgmii_data_err_cnt; + u64 rmac_xgmii_ctrl_err_cnt; + u32 rmac_err_tcp; + u32 rmac_accepted_ip; /* PCI/PCI-X Read transaction statistics. */ - __le32 new_rd_req_cnt; - __le32 rd_req_cnt; - __le32 rd_rtry_cnt; - __le32 new_rd_req_rtry_cnt; + u32 new_rd_req_cnt; + u32 rd_req_cnt; + u32 rd_rtry_cnt; + u32 new_rd_req_rtry_cnt; /* PCI/PCI-X Write/Read transaction statistics. */ - __le32 wr_req_cnt; - __le32 wr_rtry_rd_ack_cnt; - __le32 new_wr_req_rtry_cnt; - __le32 new_wr_req_cnt; - __le32 wr_disc_cnt; - __le32 wr_rtry_cnt; + u32 wr_req_cnt; + u32 wr_rtry_rd_ack_cnt; + u32 new_wr_req_rtry_cnt; + u32 new_wr_req_cnt; + u32 wr_disc_cnt; + u32 wr_rtry_cnt; /* PCI/PCI-X Write / DMA Transaction statistics. */ - __le32 txp_wr_cnt; - __le32 rd_rtry_wr_ack_cnt; - __le32 txd_wr_cnt; - __le32 txd_rd_cnt; - __le32 rxd_wr_cnt; - __le32 rxd_rd_cnt; - __le32 rxf_wr_cnt; - __le32 txf_rd_cnt; + u32 txp_wr_cnt; + u32 rd_rtry_wr_ack_cnt; + u32 txd_wr_cnt; + u32 txd_rd_cnt; + u32 rxd_wr_cnt; + u32 rxd_rd_cnt; + u32 rxf_wr_cnt; + u32 txf_rd_cnt; /* Tx MAC statistics overflow counters. */ - __le32 tmac_data_octets_oflow; - __le32 tmac_frms_oflow; - __le32 tmac_bcst_frms_oflow; - __le32 tmac_mcst_frms_oflow; - __le32 tmac_ucst_frms_oflow; - __le32 tmac_ttl_octets_oflow; - __le32 tmac_any_err_frms_oflow; - __le32 tmac_nucst_frms_oflow; - __le64 tmac_vlan_frms; - __le32 tmac_drop_ip_oflow; - __le32 tmac_vld_ip_oflow; - __le32 tmac_rst_tcp_oflow; - __le32 tmac_icmp_oflow; - __le32 tpa_unknown_protocol; - __le32 tmac_udp_oflow; - __le32 reserved_10; - __le32 tpa_parse_failure; + u32 tmac_data_octets_oflow; + u32 tmac_frms_oflow; + u32 tmac_bcst_frms_oflow; + u32 tmac_mcst_frms_oflow; + u32 tmac_ucst_frms_oflow; + u32 tmac_ttl_octets_oflow; + u32 tmac_any_err_frms_oflow; + u32 tmac_nucst_frms_oflow; + u64 tmac_vlan_frms; + u32 tmac_drop_ip_oflow; + u32 tmac_vld_ip_oflow; + u32 tmac_rst_tcp_oflow; + u32 tmac_icmp_oflow; + u32 tpa_unknown_protocol; + u32 tmac_udp_oflow; + u32 reserved_10; + u32 tpa_parse_failure; /* Rx MAC Statistics overflow counters. */ - __le32 rmac_data_octets_oflow; - __le32 rmac_vld_frms_oflow; - __le32 rmac_vld_bcst_frms_oflow; - __le32 rmac_vld_mcst_frms_oflow; - __le32 rmac_accepted_ucst_frms_oflow; - __le32 rmac_ttl_octets_oflow; - __le32 rmac_discarded_frms_oflow; - __le32 rmac_accepted_nucst_frms_oflow; - __le32 rmac_usized_frms_oflow; - __le32 rmac_drop_events_oflow; - __le32 rmac_frag_frms_oflow; - __le32 rmac_osized_frms_oflow; - __le32 rmac_ip_oflow; - __le32 rmac_jabber_frms_oflow; - __le32 rmac_icmp_oflow; - __le32 rmac_drop_ip_oflow; - __le32 rmac_err_drp_udp_oflow; - __le32 rmac_udp_oflow; - __le32 reserved_11; - __le32 rmac_pause_cnt_oflow; - __le64 rmac_ttl_1519_4095_frms; - __le64 rmac_ttl_4096_8191_frms; - __le64 rmac_ttl_8192_max_frms; - __le64 rmac_ttl_gt_max_frms; - __le64 rmac_osized_alt_frms; - __le64 rmac_jabber_alt_frms; - __le64 rmac_gt_max_alt_frms; - __le64 rmac_vlan_frms; - __le32 rmac_len_discard; - __le32 rmac_fcs_discard; - __le32 rmac_pf_discard; - __le32 rmac_da_discard; - __le32 rmac_red_discard; - __le32 rmac_rts_discard; - __le32 reserved_12; - __le32 rmac_ingm_full_discard; - __le32 reserved_13; - __le32 rmac_accepted_ip_oflow; - __le32 reserved_14; - __le32 link_fault_cnt; + u32 rmac_data_octets_oflow; + u32 rmac_vld_frms_oflow; + u32 rmac_vld_bcst_frms_oflow; + u32 rmac_vld_mcst_frms_oflow; + u32 rmac_accepted_ucst_frms_oflow; + u32 rmac_ttl_octets_oflow; + u32 rmac_discarded_frms_oflow; + u32 rmac_accepted_nucst_frms_oflow; + u32 rmac_usized_frms_oflow; + u32 rmac_drop_events_oflow; + u32 rmac_frag_frms_oflow; + u32 rmac_osized_frms_oflow; + u32 rmac_ip_oflow; + u32 rmac_jabber_frms_oflow; + u32 rmac_icmp_oflow; + u32 rmac_drop_ip_oflow; + u32 rmac_err_drp_udp_oflow; + u32 rmac_udp_oflow; + u32 reserved_11; + u32 rmac_pause_cnt_oflow; + u64 rmac_ttl_1519_4095_frms; + u64 rmac_ttl_4096_8191_frms; + u64 rmac_ttl_8192_max_frms; + u64 rmac_ttl_gt_max_frms; + u64 rmac_osized_alt_frms; + u64 rmac_jabber_alt_frms; + u64 rmac_gt_max_alt_frms; + u64 rmac_vlan_frms; + u32 rmac_len_discard; + u32 rmac_fcs_discard; + u32 rmac_pf_discard; + u32 rmac_da_discard; + u32 rmac_red_discard; + u32 rmac_rts_discard; + u32 reserved_12; + u32 rmac_ingm_full_discard; + u32 reserved_13; + u32 rmac_accepted_ip_oflow; + u32 reserved_14; + u32 link_fault_cnt; u8 buffer[20]; swStat_t sw_stat; xpakStat_t xpak_stat; @@ -992,12 +992,12 @@ static void s2io_init_pci(nic_t * sp); static int s2io_set_mac_addr(struct net_device *dev, u8 * addr); static void s2io_alarm_handle(unsigned long data); static int s2io_enable_msi(nic_t *nic); -static irqreturn_t s2io_msi_handle(int irq, void *dev_id); +static irqreturn_t s2io_msi_handle(int irq, void *dev_id, struct pt_regs *regs); static irqreturn_t -s2io_msix_ring_handle(int irq, void *dev_id); +s2io_msix_ring_handle(int irq, void *dev_id, struct pt_regs *regs); static irqreturn_t -s2io_msix_fifo_handle(int irq, void *dev_id); -static irqreturn_t s2io_isr(int irq, void *dev_id); +s2io_msix_fifo_handle(int irq, void *dev_id, struct pt_regs *regs); +static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs); static int verify_xena_quiescence(nic_t *sp, u64 val64, int flag); static const struct ethtool_ops netdev_ethtool_ops; static void s2io_set_link(unsigned long data); diff --git a/trunk/drivers/net/saa9730.c b/trunk/drivers/net/saa9730.c index b269513cde45..c479b07be788 100644 --- a/trunk/drivers/net/saa9730.c +++ b/trunk/drivers/net/saa9730.c @@ -745,9 +745,10 @@ static int lan_saa9730_rx(struct net_device *dev) return 0; } -static irqreturn_t lan_saa9730_interrupt(const int irq, void *dev_id) +static irqreturn_t lan_saa9730_interrupt(const int irq, void *dev_id, + struct pt_regs *regs) { - struct net_device *dev = dev_id; + struct net_device *dev = (struct net_device *) dev_id; struct lan_saa9730_private *lp = netdev_priv(dev); if (lan_saa9730_debug > 5) diff --git a/trunk/drivers/net/sb1000.c b/trunk/drivers/net/sb1000.c index b9fa4fbb1398..a1789ae59278 100644 --- a/trunk/drivers/net/sb1000.c +++ b/trunk/drivers/net/sb1000.c @@ -84,7 +84,7 @@ extern int sb1000_probe(struct net_device *dev); static int sb1000_open(struct net_device *dev); static int sb1000_dev_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd); static int sb1000_start_xmit(struct sk_buff *skb, struct net_device *dev); -static irqreturn_t sb1000_interrupt(int irq, void *dev_id); +static irqreturn_t sb1000_interrupt(int irq, void *dev_id, struct pt_regs *regs); static struct net_device_stats *sb1000_stats(struct net_device *dev); static int sb1000_close(struct net_device *dev); @@ -1079,18 +1079,24 @@ sb1000_start_xmit(struct sk_buff *skb, struct net_device *dev) } /* SB1000 interrupt handler. */ -static irqreturn_t sb1000_interrupt(int irq, void *dev_id) +static irqreturn_t sb1000_interrupt(int irq, void *dev_id, struct pt_regs *regs) { char *name; unsigned char st; int ioaddr[2]; - struct net_device *dev = dev_id; + struct net_device *dev = (struct net_device *) dev_id; struct sb1000_private *lp = netdev_priv(dev); const unsigned char Command0[6] = {0x80, 0x2c, 0x00, 0x00, 0x00, 0x00}; const unsigned char Command1[6] = {0x80, 0x2e, 0x00, 0x00, 0x00, 0x00}; const int MaxRxErrorCount = 6; + if (dev == NULL) { + printk(KERN_ERR "sb1000_interrupt(): irq %d for unknown device.\n", + irq); + return IRQ_NONE; + } + ioaddr[0] = dev->base_addr; /* mem_start holds the second I/O address */ ioaddr[1] = dev->mem_start; diff --git a/trunk/drivers/net/sb1250-mac.c b/trunk/drivers/net/sb1250-mac.c index 1eae16b72b4b..e4c8896b76cb 100644 --- a/trunk/drivers/net/sb1250-mac.c +++ b/trunk/drivers/net/sb1250-mac.c @@ -294,7 +294,7 @@ static void sbmac_channel_stop(struct sbmac_softc *s); static sbmac_state_t sbmac_set_channel_state(struct sbmac_softc *,sbmac_state_t); static void sbmac_promiscuous_mode(struct sbmac_softc *sc,int onoff); static uint64_t sbmac_addr2reg(unsigned char *ptr); -static irqreturn_t sbmac_intr(int irq,void *dev_instance); +static irqreturn_t sbmac_intr(int irq,void *dev_instance,struct pt_regs *rgs); static int sbmac_start_tx(struct sk_buff *skb, struct net_device *dev); static void sbmac_setmulti(struct sbmac_softc *sc); static int sbmac_init(struct net_device *dev, int idx); @@ -2049,7 +2049,7 @@ static int sbmac_set_duplex(struct sbmac_softc *s,sbmac_duplex_t duplex,sbmac_fc * Return value: * nothing ********************************************************************* */ -static irqreturn_t sbmac_intr(int irq,void *dev_instance) +static irqreturn_t sbmac_intr(int irq,void *dev_instance,struct pt_regs *rgs) { struct net_device *dev = (struct net_device *) dev_instance; struct sbmac_softc *sc = netdev_priv(dev); @@ -2903,7 +2903,7 @@ sbmac_init_module(void) dev = alloc_etherdev(sizeof(struct sbmac_softc)); if (!dev) - return -ENOMEM; + return -ENOMEM; /* return ENOMEM */ printk(KERN_DEBUG "sbmac: configuring MAC at %lx\n", port); diff --git a/trunk/drivers/net/seeq8005.c b/trunk/drivers/net/seeq8005.c index d9d0a3a3c558..20afdc7f2b97 100644 --- a/trunk/drivers/net/seeq8005.c +++ b/trunk/drivers/net/seeq8005.c @@ -83,7 +83,7 @@ static int seeq8005_probe1(struct net_device *dev, int ioaddr); static int seeq8005_open(struct net_device *dev); static void seeq8005_timeout(struct net_device *dev); static int seeq8005_send_packet(struct sk_buff *skb, struct net_device *dev); -static irqreturn_t seeq8005_interrupt(int irq, void *dev_id); +static irqreturn_t seeq8005_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void seeq8005_rx(struct net_device *dev); static int seeq8005_close(struct net_device *dev); static struct net_device_stats *seeq8005_get_stats(struct net_device *dev); @@ -437,7 +437,7 @@ inline void wait_for_buffer(struct net_device * dev) /* The typical workload of the driver: Handle the network interface interrupts. */ -static irqreturn_t seeq8005_interrupt(int irq, void *dev_id) +static irqreturn_t seeq8005_interrupt(int irq, void *dev_id, struct pt_regs * regs) { struct net_device *dev = dev_id; struct net_local *lp; diff --git a/trunk/drivers/net/sgiseeq.c b/trunk/drivers/net/sgiseeq.c index a833e7f9757f..f95a5b0223fb 100644 --- a/trunk/drivers/net/sgiseeq.c +++ b/trunk/drivers/net/sgiseeq.c @@ -432,7 +432,7 @@ static inline void sgiseeq_tx(struct net_device *dev, struct sgiseeq_private *sp } } -static irqreturn_t sgiseeq_interrupt(int irq, void *dev_id) +static irqreturn_t sgiseeq_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_id; struct sgiseeq_private *sp = netdev_priv(dev); diff --git a/trunk/drivers/net/sis190.c b/trunk/drivers/net/sis190.c index aaba458584fb..e8f26b79bbaf 100644 --- a/trunk/drivers/net/sis190.c +++ b/trunk/drivers/net/sis190.c @@ -713,7 +713,7 @@ static void sis190_tx_interrupt(struct net_device *dev, * The interrupt handler does all of the Rx thread work and cleans up after * the Tx thread. */ -static irqreturn_t sis190_interrupt(int irq, void *__dev) +static irqreturn_t sis190_interrupt(int irq, void *__dev, struct pt_regs *regs) { struct net_device *dev = __dev; struct sis190_private *tp = netdev_priv(dev); @@ -758,7 +758,7 @@ static void sis190_netpoll(struct net_device *dev) struct pci_dev *pdev = tp->pci_dev; disable_irq(pdev->irq); - sis190_interrupt(pdev->irq, dev); + sis190_interrupt(pdev->irq, dev, NULL); enable_irq(pdev->irq); } #endif diff --git a/trunk/drivers/net/sis900.c b/trunk/drivers/net/sis900.c index fb2b53051635..28606e20df1c 100644 --- a/trunk/drivers/net/sis900.c +++ b/trunk/drivers/net/sis900.c @@ -218,7 +218,7 @@ static void sis900_init_rx_ring(struct net_device *net_dev); static int sis900_start_xmit(struct sk_buff *skb, struct net_device *net_dev); static int sis900_rx(struct net_device *net_dev); static void sis900_finish_xmit (struct net_device *net_dev); -static irqreturn_t sis900_interrupt(int irq, void *dev_instance); +static irqreturn_t sis900_interrupt(int irq, void *dev_instance, struct pt_regs *regs); static int sis900_close(struct net_device *net_dev); static int mii_ioctl(struct net_device *net_dev, struct ifreq *rq, int cmd); static struct net_device_stats *sis900_get_stats(struct net_device *net_dev); @@ -988,7 +988,7 @@ static u16 sis900_reset_phy(struct net_device *net_dev, int phy_addr) static void sis900_poll(struct net_device *dev) { disable_irq(dev->irq); - sis900_interrupt(dev->irq, dev); + sis900_interrupt(dev->irq, dev, NULL); enable_irq(dev->irq); } #endif @@ -1642,7 +1642,7 @@ sis900_start_xmit(struct sk_buff *skb, struct net_device *net_dev) * and cleans up after the Tx thread */ -static irqreturn_t sis900_interrupt(int irq, void *dev_instance) +static irqreturn_t sis900_interrupt(int irq, void *dev_instance, struct pt_regs *regs) { struct net_device *net_dev = dev_instance; struct sis900_private *sis_priv = net_dev->priv; diff --git a/trunk/drivers/net/sk98lin/h/skdrv2nd.h b/trunk/drivers/net/sk98lin/h/skdrv2nd.h index 3fa67171e832..778d9e618ebd 100644 --- a/trunk/drivers/net/sk98lin/h/skdrv2nd.h +++ b/trunk/drivers/net/sk98lin/h/skdrv2nd.h @@ -160,7 +160,7 @@ struct s_IOCTL { /* ** Interim definition of SK_DRV_TIMER placed in this file until -** common modules have been finalized +** common modules have boon finallized */ #define SK_DRV_TIMER 11 #define SK_DRV_MODERATION_TIMER 1 diff --git a/trunk/drivers/net/sk98lin/skdim.c b/trunk/drivers/net/sk98lin/skdim.c index 37ce03fb8de3..07c1b4c8699d 100644 --- a/trunk/drivers/net/sk98lin/skdim.c +++ b/trunk/drivers/net/sk98lin/skdim.c @@ -252,7 +252,7 @@ SkDimEnableModerationIfNeeded(SK_AC *pAC) { /******************************************************************************* ** Function : SkDimDisplayModerationSettings -** Description : Displays the current settings regarding interrupt moderation +** Description : Displays the current settings regaring interrupt moderation ** Programmer : Ralph Roesler ** Last Modified: 22-mar-03 ** Returns : void (!) @@ -510,7 +510,7 @@ EnableIntMod(SK_AC *pAC) { /******************************************************************************* ** Function : DisableIntMod() -** Description : Disables the interrupt moderation independent of what inter- +** Description : Disbles the interrupt moderation independent of what inter- ** rupts are running or not ** Programmer : Ralph Roesler ** Last Modified: 23-mar-03 diff --git a/trunk/drivers/net/sk98lin/skge.c b/trunk/drivers/net/sk98lin/skge.c index d4913c3de2a1..99e92627642c 100644 --- a/trunk/drivers/net/sk98lin/skge.c +++ b/trunk/drivers/net/sk98lin/skge.c @@ -196,8 +196,8 @@ static SK_BOOL BoardAllocMem(SK_AC *pAC); static void BoardFreeMem(SK_AC *pAC); static void BoardInitMem(SK_AC *pAC); static void SetupRing(SK_AC*, void*, uintptr_t, RXD**, RXD**, RXD**, int*, SK_BOOL); -static SkIsrRetVar SkGeIsr(int irq, void *dev_id); -static SkIsrRetVar SkGeIsrOnePort(int irq, void *dev_id); +static SkIsrRetVar SkGeIsr(int irq, void *dev_id, struct pt_regs *ptregs); +static SkIsrRetVar SkGeIsrOnePort(int irq, void *dev_id, struct pt_regs *ptregs); static int SkGeOpen(struct SK_NET_DEVICE *dev); static int SkGeClose(struct SK_NET_DEVICE *dev); static int SkGeXmit(struct sk_buff *skb, struct SK_NET_DEVICE *dev); @@ -880,7 +880,7 @@ int PortIndex) /* index of the port for which to re-init */ * Returns: N/A * */ -static SkIsrRetVar SkGeIsr(int irq, void *dev_id) +static SkIsrRetVar SkGeIsr(int irq, void *dev_id, struct pt_regs *ptregs) { struct SK_NET_DEVICE *dev = (struct SK_NET_DEVICE *)dev_id; DEV_NET *pNet; @@ -1029,7 +1029,7 @@ SK_U32 IntSrc; /* interrupts source register contents */ * Returns: N/A * */ -static SkIsrRetVar SkGeIsrOnePort(int irq, void *dev_id) +static SkIsrRetVar SkGeIsrOnePort(int irq, void *dev_id, struct pt_regs *ptregs) { struct SK_NET_DEVICE *dev = (struct SK_NET_DEVICE *)dev_id; DEV_NET *pNet; @@ -1140,7 +1140,7 @@ SK_U32 IntSrc; /* interrupts source register contents */ static void SkGePollController(struct net_device *dev) { disable_irq(dev->irq); - SkGeIsr(dev->irq, dev); + SkGeIsr(dev->irq, dev, NULL); enable_irq(dev->irq); } #endif diff --git a/trunk/drivers/net/sk_mca.c b/trunk/drivers/net/sk_mca.c index 96e06c51b75d..37b88da1abe5 100644 --- a/trunk/drivers/net/sk_mca.c +++ b/trunk/drivers/net/sk_mca.c @@ -732,7 +732,7 @@ static u16 irqtx_handler(struct net_device *dev, u16 oldcsr0) /* general interrupt entry */ -static irqreturn_t irq_handler(int irq, void *device) +static irqreturn_t irq_handler(int irq, void *device, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) device; u16 csr0val; diff --git a/trunk/drivers/net/skfp/skfddi.c b/trunk/drivers/net/skfp/skfddi.c index 9733a11c6146..8e4d18440a56 100644 --- a/trunk/drivers/net/skfp/skfddi.c +++ b/trunk/drivers/net/skfp/skfddi.c @@ -101,7 +101,7 @@ static const char * const boot_msg = static int skfp_driver_init(struct net_device *dev); static int skfp_open(struct net_device *dev); static int skfp_close(struct net_device *dev); -static irqreturn_t skfp_interrupt(int irq, void *dev_id); +static irqreturn_t skfp_interrupt(int irq, void *dev_id, struct pt_regs *regs); static struct net_device_stats *skfp_ctl_get_stats(struct net_device *dev); static void skfp_ctl_set_multicast_list(struct net_device *dev); static void skfp_ctl_set_multicast_list_wo_lock(struct net_device *dev); @@ -593,6 +593,7 @@ static int skfp_close(struct net_device *dev) * Arguments: * irq - interrupt vector * dev_id - pointer to device information + * regs - pointer to registers structure * * Functional Description: * This routine calls the interrupt processing routine for this adapter. It @@ -614,12 +615,17 @@ static int skfp_close(struct net_device *dev) * Interrupts are disabled, then reenabled at the adapter. */ -irqreturn_t skfp_interrupt(int irq, void *dev_id) +irqreturn_t skfp_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct net_device *dev = dev_id; + struct net_device *dev = (struct net_device *) dev_id; struct s_smc *smc; /* private board structure pointer */ skfddi_priv *bp; + if (dev == NULL) { + printk("%s: irq %d for unknown device\n", dev->name, irq); + return IRQ_NONE; + } + smc = netdev_priv(dev); bp = &smc->os; diff --git a/trunk/drivers/net/skge.c b/trunk/drivers/net/skge.c index b2949035f66a..705e9a8fa30f 100644 --- a/trunk/drivers/net/skge.c +++ b/trunk/drivers/net/skge.c @@ -11,7 +11,8 @@ * * 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. + * 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 @@ -42,7 +43,7 @@ #include "skge.h" #define DRV_NAME "skge" -#define DRV_VERSION "1.9" +#define DRV_VERSION "1.8" #define PFX DRV_NAME " " #define DEFAULT_TX_RING_SIZE 128 @@ -196,8 +197,8 @@ static u32 skge_supported_modes(const struct skge_hw *hw) else if (hw->chip_id == CHIP_ID_YUKON) supported &= ~SUPPORTED_1000baseT_Half; } else - supported = SUPPORTED_1000baseT_Full | SUPPORTED_1000baseT_Half - | SUPPORTED_FIBRE | SUPPORTED_Autoneg; + supported = SUPPORTED_1000baseT_Full | SUPPORTED_FIBRE + | SUPPORTED_Autoneg; return supported; } @@ -486,37 +487,31 @@ static void skge_get_pauseparam(struct net_device *dev, { struct skge_port *skge = netdev_priv(dev); - ecmd->rx_pause = (skge->flow_control == FLOW_MODE_SYMMETRIC) - || (skge->flow_control == FLOW_MODE_SYM_OR_REM); - ecmd->tx_pause = ecmd->rx_pause || (skge->flow_control == FLOW_MODE_LOC_SEND); + ecmd->tx_pause = (skge->flow_control == FLOW_MODE_LOC_SEND) + || (skge->flow_control == FLOW_MODE_SYMMETRIC); + ecmd->rx_pause = (skge->flow_control == FLOW_MODE_REM_SEND) + || (skge->flow_control == FLOW_MODE_SYMMETRIC); - ecmd->autoneg = ecmd->rx_pause || ecmd->tx_pause; + ecmd->autoneg = skge->autoneg; } static int skge_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *ecmd) { struct skge_port *skge = netdev_priv(dev); - struct ethtool_pauseparam old; - - skge_get_pauseparam(dev, &old); - if (ecmd->autoneg != old.autoneg) - skge->flow_control = ecmd->autoneg ? FLOW_MODE_NONE : FLOW_MODE_SYMMETRIC; - else { - if (ecmd->rx_pause && ecmd->tx_pause) - skge->flow_control = FLOW_MODE_SYMMETRIC; - else if (ecmd->rx_pause && !ecmd->tx_pause) - skge->flow_control = FLOW_MODE_SYM_OR_REM; - else if (!ecmd->rx_pause && ecmd->tx_pause) - skge->flow_control = FLOW_MODE_LOC_SEND; - else - skge->flow_control = FLOW_MODE_NONE; - } + skge->autoneg = ecmd->autoneg; + if (ecmd->rx_pause && ecmd->tx_pause) + skge->flow_control = FLOW_MODE_SYMMETRIC; + else if (ecmd->rx_pause && !ecmd->tx_pause) + skge->flow_control = FLOW_MODE_REM_SEND; + else if (!ecmd->rx_pause && ecmd->tx_pause) + skge->flow_control = FLOW_MODE_LOC_SEND; + else + skge->flow_control = FLOW_MODE_NONE; if (netif_running(dev)) skge_phy_reset(skge); - return 0; } @@ -859,23 +854,6 @@ static int skge_rx_fill(struct net_device *dev) return 0; } -static const char *skge_pause(enum pause_status status) -{ - switch(status) { - case FLOW_STAT_NONE: - return "none"; - case FLOW_STAT_REM_SEND: - return "rx only"; - case FLOW_STAT_LOC_SEND: - return "tx_only"; - case FLOW_STAT_SYMMETRIC: /* Both station may send PAUSE */ - return "both"; - default: - return "indeterminated"; - } -} - - static void skge_link_up(struct skge_port *skge) { skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG), @@ -884,13 +862,16 @@ static void skge_link_up(struct skge_port *skge) netif_carrier_on(skge->netdev); netif_wake_queue(skge->netdev); - if (netif_msg_link(skge)) { + if (netif_msg_link(skge)) printk(KERN_INFO PFX "%s: Link is up at %d Mbps, %s duplex, flow control %s\n", skge->netdev->name, skge->speed, skge->duplex == DUPLEX_FULL ? "full" : "half", - skge_pause(skge->flow_status)); - } + (skge->flow_control == FLOW_MODE_NONE) ? "none" : + (skge->flow_control == FLOW_MODE_LOC_SEND) ? "tx only" : + (skge->flow_control == FLOW_MODE_REM_SEND) ? "rx only" : + (skge->flow_control == FLOW_MODE_SYMMETRIC) ? "tx and rx" : + "unknown"); } static void skge_link_down(struct skge_port *skge) @@ -903,29 +884,6 @@ static void skge_link_down(struct skge_port *skge) printk(KERN_INFO PFX "%s: Link is down.\n", skge->netdev->name); } - -static void xm_link_down(struct skge_hw *hw, int port) -{ - struct net_device *dev = hw->dev[port]; - struct skge_port *skge = netdev_priv(dev); - u16 cmd, msk; - - if (hw->phy_type == SK_PHY_XMAC) { - msk = xm_read16(hw, port, XM_IMSK); - msk |= XM_IS_INP_ASS | XM_IS_LIPA_RC | XM_IS_RX_PAGE | XM_IS_AND; - xm_write16(hw, port, XM_IMSK, msk); - } - - cmd = xm_read16(hw, port, XM_MMU_CMD); - cmd &= ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX); - xm_write16(hw, port, XM_MMU_CMD, cmd); - /* dummy read to ensure writing */ - (void) xm_read16(hw, port, XM_MMU_CMD); - - if (netif_carrier_ok(dev)) - skge_link_down(skge); -} - static int __xm_phy_read(struct skge_hw *hw, int port, u16 reg, u16 *val) { int i; @@ -1034,15 +992,7 @@ static const u16 phy_pause_map[] = { [FLOW_MODE_NONE] = 0, [FLOW_MODE_LOC_SEND] = PHY_AN_PAUSE_ASYM, [FLOW_MODE_SYMMETRIC] = PHY_AN_PAUSE_CAP, - [FLOW_MODE_SYM_OR_REM] = PHY_AN_PAUSE_CAP | PHY_AN_PAUSE_ASYM, -}; - -/* special defines for FIBER (88E1011S only) */ -static const u16 fiber_pause_map[] = { - [FLOW_MODE_NONE] = PHY_X_P_NO_PAUSE, - [FLOW_MODE_LOC_SEND] = PHY_X_P_ASYM_MD, - [FLOW_MODE_SYMMETRIC] = PHY_X_P_SYM_MD, - [FLOW_MODE_SYM_OR_REM] = PHY_X_P_BOTH_MD, + [FLOW_MODE_REM_SEND] = PHY_AN_PAUSE_CAP | PHY_AN_PAUSE_ASYM, }; @@ -1058,7 +1008,14 @@ static void bcom_check_link(struct skge_hw *hw, int port) status = xm_phy_read(hw, port, PHY_BCOM_STAT); if ((status & PHY_ST_LSYNC) == 0) { - xm_link_down(hw, port); + u16 cmd = xm_read16(hw, port, XM_MMU_CMD); + cmd &= ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX); + xm_write16(hw, port, XM_MMU_CMD, cmd); + /* dummy read to ensure writing */ + (void) xm_read16(hw, port, XM_MMU_CMD); + + if (netif_carrier_ok(dev)) + skge_link_down(skge); return; } @@ -1091,19 +1048,20 @@ static void bcom_check_link(struct skge_hw *hw, int port) return; } + /* We are using IEEE 802.3z/D5.0 Table 37-4 */ switch (aux & PHY_B_AS_PAUSE_MSK) { case PHY_B_AS_PAUSE_MSK: - skge->flow_status = FLOW_STAT_SYMMETRIC; + skge->flow_control = FLOW_MODE_SYMMETRIC; break; case PHY_B_AS_PRR: - skge->flow_status = FLOW_STAT_REM_SEND; + skge->flow_control = FLOW_MODE_REM_SEND; break; case PHY_B_AS_PRT: - skge->flow_status = FLOW_STAT_LOC_SEND; + skge->flow_control = FLOW_MODE_LOC_SEND; break; default: - skge->flow_status = FLOW_STAT_NONE; + skge->flow_control = FLOW_MODE_NONE; } skge->speed = SPEED_1000; } @@ -1233,7 +1191,17 @@ static void xm_phy_init(struct skge_port *skge) if (skge->advertising & ADVERTISED_1000baseT_Full) ctrl |= PHY_X_AN_FD; - ctrl |= fiber_pause_map[skge->flow_control]; + switch(skge->flow_control) { + case FLOW_MODE_NONE: + ctrl |= PHY_X_P_NO_PAUSE; + break; + case FLOW_MODE_LOC_SEND: + ctrl |= PHY_X_P_ASYM_MD; + break; + case FLOW_MODE_SYMMETRIC: + ctrl |= PHY_X_P_BOTH_MD; + break; + } xm_phy_write(hw, port, PHY_XMAC_AUNE_ADV, ctrl); @@ -1267,7 +1235,14 @@ static void xm_check_link(struct net_device *dev) status = xm_phy_read(hw, port, PHY_XMAC_STAT); if ((status & PHY_ST_LSYNC) == 0) { - xm_link_down(hw, port); + u16 cmd = xm_read16(hw, port, XM_MMU_CMD); + cmd &= ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX); + xm_write16(hw, port, XM_MMU_CMD, cmd); + /* dummy read to ensure writing */ + (void) xm_read16(hw, port, XM_MMU_CMD); + + if (netif_carrier_ok(dev)) + skge_link_down(skge); return; } @@ -1301,20 +1276,15 @@ static void xm_check_link(struct net_device *dev) } /* We are using IEEE 802.3z/D5.0 Table 37-4 */ - if ((skge->flow_control == FLOW_MODE_SYMMETRIC || - skge->flow_control == FLOW_MODE_SYM_OR_REM) && - (lpa & PHY_X_P_SYM_MD)) - skge->flow_status = FLOW_STAT_SYMMETRIC; - else if (skge->flow_control == FLOW_MODE_SYM_OR_REM && - (lpa & PHY_X_RS_PAUSE) == PHY_X_P_ASYM_MD) - /* Enable PAUSE receive, disable PAUSE transmit */ - skge->flow_status = FLOW_STAT_REM_SEND; - else if (skge->flow_control == FLOW_MODE_LOC_SEND && - (lpa & PHY_X_RS_PAUSE) == PHY_X_P_BOTH_MD) - /* Disable PAUSE receive, enable PAUSE transmit */ - skge->flow_status = FLOW_STAT_LOC_SEND; + if (lpa & PHY_X_P_SYM_MD) + skge->flow_control = FLOW_MODE_SYMMETRIC; + else if ((lpa & PHY_X_RS_PAUSE) == PHY_X_P_ASYM_MD) + skge->flow_control = FLOW_MODE_REM_SEND; + else if ((lpa & PHY_X_RS_PAUSE) == PHY_X_P_BOTH_MD) + skge->flow_control = FLOW_MODE_LOC_SEND; else - skge->flow_status = FLOW_STAT_NONE; + skge->flow_control = FLOW_MODE_NONE; + skge->speed = SPEED_1000; } @@ -1598,10 +1568,6 @@ static void genesis_mac_intr(struct skge_hw *hw, int port) printk(KERN_DEBUG PFX "%s: mac interrupt status 0x%x\n", skge->netdev->name, status); - if (hw->phy_type == SK_PHY_XMAC && - (status & (XM_IS_INP_ASS | XM_IS_LIPA_RC))) - xm_link_down(hw, port); - if (status & XM_IS_TXF_UR) { xm_write32(hw, port, XM_MODE, XM_MD_FTF); ++skge->net_stats.tx_fifo_errors; @@ -1616,7 +1582,7 @@ static void genesis_link_up(struct skge_port *skge) { struct skge_hw *hw = skge->hw; int port = skge->port; - u16 cmd, msk; + u16 cmd; u32 mode; cmd = xm_read16(hw, port, XM_MMU_CMD); @@ -1625,8 +1591,8 @@ static void genesis_link_up(struct skge_port *skge) * enabling pause frame reception is required for 1000BT * because the XMAC is not reset if the link is going down */ - if (skge->flow_status == FLOW_STAT_NONE || - skge->flow_status == FLOW_STAT_LOC_SEND) + if (skge->flow_control == FLOW_MODE_NONE || + skge->flow_control == FLOW_MODE_LOC_SEND) /* Disable Pause Frame Reception */ cmd |= XM_MMU_IGN_PF; else @@ -1636,8 +1602,8 @@ static void genesis_link_up(struct skge_port *skge) xm_write16(hw, port, XM_MMU_CMD, cmd); mode = xm_read32(hw, port, XM_MODE); - if (skge->flow_status== FLOW_STAT_SYMMETRIC || - skge->flow_status == FLOW_STAT_LOC_SEND) { + if (skge->flow_control == FLOW_MODE_SYMMETRIC || + skge->flow_control == FLOW_MODE_LOC_SEND) { /* * Configure Pause Frame Generation * Use internal and external Pause Frame Generation. @@ -1665,11 +1631,7 @@ static void genesis_link_up(struct skge_port *skge) } xm_write32(hw, port, XM_MODE, mode); - msk = XM_DEF_MSK; - if (hw->phy_type != SK_PHY_XMAC) - msk |= XM_IS_INP_ASS; /* disable GP0 interrupt bit */ - - xm_write16(hw, port, XM_IMSK, msk); + xm_write16(hw, port, XM_IMSK, XM_DEF_MSK); xm_read16(hw, port, XM_ISRC); /* get MMU Command Reg. */ @@ -1817,17 +1779,11 @@ static void yukon_init(struct skge_hw *hw, int port) adv |= PHY_M_AN_10_FD; if (skge->advertising & ADVERTISED_10baseT_Half) adv |= PHY_M_AN_10_HD; + } else /* special defines for FIBER (88E1011S only) */ + adv |= PHY_M_AN_1000X_AHD | PHY_M_AN_1000X_AFD; - /* Set Flow-control capabilities */ - adv |= phy_pause_map[skge->flow_control]; - } else { - if (skge->advertising & ADVERTISED_1000baseT_Full) - adv |= PHY_M_AN_1000X_AFD; - if (skge->advertising & ADVERTISED_1000baseT_Half) - adv |= PHY_M_AN_1000X_AHD; - - adv |= fiber_pause_map[skge->flow_control]; - } + /* Set Flow-control capabilities */ + adv |= phy_pause_map[skge->flow_control]; /* Restart Auto-negotiation */ ctrl |= PHY_CT_ANE | PHY_CT_RE_CFG; @@ -1961,11 +1917,6 @@ static void yukon_mac_init(struct skge_hw *hw, int port) case FLOW_MODE_LOC_SEND: /* disable Rx flow-control */ reg |= GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS; - break; - case FLOW_MODE_SYMMETRIC: - case FLOW_MODE_SYM_OR_REM: - /* enable Tx & Rx flow-control */ - break; } gma_write16(hw, port, GM_GP_CTRL, reg); @@ -2160,11 +2111,13 @@ static void yukon_link_down(struct skge_port *skge) ctrl &= ~(GM_GPCR_RX_ENA | GM_GPCR_TX_ENA); gma_write16(hw, port, GM_GP_CTRL, ctrl); - if (skge->flow_status == FLOW_STAT_REM_SEND) { - ctrl = gm_phy_read(hw, port, PHY_MARV_AUNE_ADV); - ctrl |= PHY_M_AN_ASP; + if (skge->flow_control == FLOW_MODE_REM_SEND) { /* restore Asymmetric Pause bit */ - gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, ctrl); + gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, + gm_phy_read(hw, port, + PHY_MARV_AUNE_ADV) + | PHY_M_AN_ASP); + } yukon_reset(hw, port); @@ -2211,19 +2164,19 @@ static void yukon_phy_intr(struct skge_port *skge) /* We are using IEEE 802.3z/D5.0 Table 37-4 */ switch (phystat & PHY_M_PS_PAUSE_MSK) { case PHY_M_PS_PAUSE_MSK: - skge->flow_status = FLOW_STAT_SYMMETRIC; + skge->flow_control = FLOW_MODE_SYMMETRIC; break; case PHY_M_PS_RX_P_EN: - skge->flow_status = FLOW_STAT_REM_SEND; + skge->flow_control = FLOW_MODE_REM_SEND; break; case PHY_M_PS_TX_P_EN: - skge->flow_status = FLOW_STAT_LOC_SEND; + skge->flow_control = FLOW_MODE_LOC_SEND; break; default: - skge->flow_status = FLOW_STAT_NONE; + skge->flow_control = FLOW_MODE_NONE; } - if (skge->flow_status == FLOW_STAT_NONE || + if (skge->flow_control == FLOW_MODE_NONE || (skge->speed < SPEED_1000 && skge->duplex == DUPLEX_HALF)) skge_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF); else @@ -3098,7 +3051,7 @@ static void skge_extirq(void *arg) spin_unlock_irq(&hw->hw_lock); } -static irqreturn_t skge_intr(int irq, void *dev_id) +static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs) { struct skge_hw *hw = dev_id; u32 status; @@ -3172,7 +3125,7 @@ static void skge_netpoll(struct net_device *dev) struct skge_port *skge = netdev_priv(dev); disable_irq(dev->irq); - skge_intr(dev->irq, skge->hw); + skge_intr(dev->irq, skge->hw, NULL); enable_irq(dev->irq); } #endif @@ -3446,7 +3399,7 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port, /* Auto speed and flow control */ skge->autoneg = AUTONEG_ENABLE; - skge->flow_control = FLOW_MODE_SYM_OR_REM; + skge->flow_control = FLOW_MODE_SYMMETRIC; skge->duplex = -1; skge->speed = -1; skge->advertising = skge_supported_modes(hw); diff --git a/trunk/drivers/net/skge.h b/trunk/drivers/net/skge.h index 537c0aaa1db8..d0b47d46cf9d 100644 --- a/trunk/drivers/net/skge.h +++ b/trunk/drivers/net/skge.h @@ -2195,8 +2195,7 @@ enum { XM_IS_RX_COMP = 1<<0, /* Bit 0: Frame Rx Complete */ }; -#define XM_DEF_MSK (~(XM_IS_INP_ASS | XM_IS_LIPA_RC | \ - XM_IS_RXF_OV | XM_IS_TXF_UR)) +#define XM_DEF_MSK (~(XM_IS_RXC_OV | XM_IS_TXC_OV | XM_IS_RXF_OV | XM_IS_TXF_UR)) /* XM_HW_CFG 16 bit r/w Hardware Config Register */ @@ -2427,24 +2426,13 @@ struct skge_hw { struct mutex phy_mutex; }; -enum pause_control { - FLOW_MODE_NONE = 1, /* No Flow-Control */ - FLOW_MODE_LOC_SEND = 2, /* Local station sends PAUSE */ +enum { + FLOW_MODE_NONE = 0, /* No Flow-Control */ + FLOW_MODE_LOC_SEND = 1, /* Local station sends PAUSE */ + FLOW_MODE_REM_SEND = 2, /* Symmetric or just remote */ FLOW_MODE_SYMMETRIC = 3, /* Both stations may send PAUSE */ - FLOW_MODE_SYM_OR_REM = 4, /* Both stations may send PAUSE or - * just the remote station may send PAUSE - */ -}; - -enum pause_status { - FLOW_STAT_INDETERMINATED=0, /* indeterminated */ - FLOW_STAT_NONE, /* No Flow Control */ - FLOW_STAT_REM_SEND, /* Remote Station sends PAUSE */ - FLOW_STAT_LOC_SEND, /* Local station sends PAUSE */ - FLOW_STAT_SYMMETRIC, /* Both station may send PAUSE */ }; - struct skge_port { u32 msg_enable; struct skge_hw *hw; @@ -2457,10 +2445,9 @@ struct skge_port { struct net_device_stats net_stats; struct work_struct link_thread; - enum pause_control flow_control; - enum pause_status flow_status; u8 rx_csum; u8 blink_on; + u8 flow_control; u8 wol; u8 autoneg; /* AUTONEG_ENABLE, AUTONEG_DISABLE */ u8 duplex; /* DUPLEX_HALF, DUPLEX_FULL */ diff --git a/trunk/drivers/net/sky2.c b/trunk/drivers/net/sky2.c index 16616f5440d0..396e7df3c61b 100644 --- a/trunk/drivers/net/sky2.c +++ b/trunk/drivers/net/sky2.c @@ -10,7 +10,8 @@ * * 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. + * 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 @@ -49,7 +50,7 @@ #include "sky2.h" #define DRV_NAME "sky2" -#define DRV_VERSION "1.10" +#define DRV_VERSION "1.9" #define PFX DRV_NAME " " /* @@ -95,9 +96,9 @@ static int disable_msi = 0; module_param(disable_msi, int, 0); MODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)"); -static int idle_timeout = 0; +static int idle_timeout = 100; module_param(idle_timeout, int, 0); -MODULE_PARM_DESC(idle_timeout, "Watchdog timer for lost interrupts (ms)"); +MODULE_PARM_DESC(idle_timeout, "Idle timeout workaround for lost interrupts (ms)"); static const struct pci_device_id sky2_id_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) }, @@ -283,31 +284,6 @@ static void sky2_gmac_reset(struct sky2_hw *hw, unsigned port) gma_write16(hw, port, GM_RX_CTRL, reg); } -/* flow control to advertise bits */ -static const u16 copper_fc_adv[] = { - [FC_NONE] = 0, - [FC_TX] = PHY_M_AN_ASP, - [FC_RX] = PHY_M_AN_PC, - [FC_BOTH] = PHY_M_AN_PC | PHY_M_AN_ASP, -}; - -/* flow control to advertise bits when using 1000BaseX */ -static const u16 fiber_fc_adv[] = { - [FC_BOTH] = PHY_M_P_BOTH_MD_X, - [FC_TX] = PHY_M_P_ASYM_MD_X, - [FC_RX] = PHY_M_P_SYM_MD_X, - [FC_NONE] = PHY_M_P_NO_PAUSE_X, -}; - -/* flow control to GMA disable bits */ -static const u16 gm_fc_disable[] = { - [FC_NONE] = GM_GPCR_FC_RX_DIS | GM_GPCR_FC_TX_DIS, - [FC_TX] = GM_GPCR_FC_RX_DIS, - [FC_RX] = GM_GPCR_FC_TX_DIS, - [FC_BOTH] = 0, -}; - - static void sky2_phy_init(struct sky2_hw *hw, unsigned port) { struct sky2_port *sky2 = netdev_priv(hw->dev[port]); @@ -380,7 +356,16 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg); } - ctrl = PHY_CT_RESET; + ctrl = gm_phy_read(hw, port, PHY_MARV_CTRL); + if (sky2->autoneg == AUTONEG_DISABLE) + ctrl &= ~PHY_CT_ANE; + else + ctrl |= PHY_CT_ANE; + + ctrl |= PHY_CT_RESET; + gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl); + + ctrl = 0; ct1000 = 0; adv = PHY_AN_CSMA; reg = 0; @@ -399,17 +384,21 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) adv |= PHY_M_AN_10_FD; if (sky2->advertising & ADVERTISED_10baseT_Half) adv |= PHY_M_AN_10_HD; - - adv |= copper_fc_adv[sky2->flow_mode]; } else { /* special defines for FIBER (88E1040S only) */ if (sky2->advertising & ADVERTISED_1000baseT_Full) adv |= PHY_M_AN_1000X_AFD; if (sky2->advertising & ADVERTISED_1000baseT_Half) adv |= PHY_M_AN_1000X_AHD; - - adv |= fiber_fc_adv[sky2->flow_mode]; } + /* Set Flow-control capabilities */ + if (sky2->tx_pause && sky2->rx_pause) + adv |= PHY_AN_PAUSE_CAP; /* symmetric */ + else if (sky2->rx_pause && !sky2->tx_pause) + adv |= PHY_AN_PAUSE_ASYM | PHY_AN_PAUSE_CAP; + else if (!sky2->rx_pause && sky2->tx_pause) + adv |= PHY_AN_PAUSE_ASYM; /* local */ + /* Restart Auto-negotiation */ ctrl |= PHY_CT_ANE | PHY_CT_RE_CFG; } else { @@ -433,17 +422,25 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) if (sky2->duplex == DUPLEX_FULL) { reg |= GM_GPCR_DUP_FULL; ctrl |= PHY_CT_DUP_MD; - } else if (sky2->speed < SPEED_1000) - sky2->flow_mode = FC_NONE; + } else if (sky2->speed != SPEED_1000 && hw->chip_id != CHIP_ID_YUKON_EC_U) { + /* Turn off flow control for 10/100mbps */ + sky2->rx_pause = 0; + sky2->tx_pause = 0; + } + if (!sky2->rx_pause) + reg |= GM_GPCR_FC_RX_DIS; - reg |= gm_fc_disable[sky2->flow_mode]; + if (!sky2->tx_pause) + reg |= GM_GPCR_FC_TX_DIS; /* Forward pause packets to GMAC? */ - if (sky2->flow_mode & FC_RX) + if (sky2->tx_pause || sky2->rx_pause) sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_ON); else sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF); + + ctrl |= PHY_CT_RESET; } gma_write16(hw, port, GM_GP_CTRL, reg); @@ -686,7 +683,7 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) sky2_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON); if (hw->chip_id == CHIP_ID_YUKON_EC_U) { - sky2_write8(hw, SK_REG(port, RX_GMF_LP_THR), 512/8); + sky2_write8(hw, SK_REG(port, RX_GMF_LP_THR), 768/8); sky2_write8(hw, SK_REG(port, RX_GMF_UP_THR), 1024/8); if (hw->dev[port]->mtu > ETH_DATA_LEN) { /* set Tx GMAC FIFO Almost Empty Threshold */ @@ -698,10 +695,16 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) } -/* Assign Ram Buffer allocation in units of 64bit (8 bytes) */ -static void sky2_ramset(struct sky2_hw *hw, u16 q, u32 start, u32 end) +/* Assign Ram Buffer allocation. + * start and end are in units of 4k bytes + * ram registers are in units of 64bit words + */ +static void sky2_ramset(struct sky2_hw *hw, u16 q, u8 startk, u8 endk) { - pr_debug(PFX "q %d %#x %#x\n", q, start, end); + u32 start, end; + + start = startk * 4096/8; + end = (endk * 4096/8) - 1; sky2_write8(hw, RB_ADDR(q, RB_CTRL), RB_RST_CLR); sky2_write32(hw, RB_ADDR(q, RB_START), start); @@ -710,7 +713,7 @@ static void sky2_ramset(struct sky2_hw *hw, u16 q, u32 start, u32 end) sky2_write32(hw, RB_ADDR(q, RB_RP), start); if (q == Q_R1 || q == Q_R2) { - u32 space = end - start + 1; + u32 space = (endk - startk) * 4096/8; u32 tp = space - space/4; /* On receive queue's set the thresholds @@ -1192,16 +1195,19 @@ static int sky2_up(struct net_device *dev) sky2_mac_init(hw, port); - /* Determine available ram buffer space in qwords. */ - ramsize = sky2_read8(hw, B2_E_0) * 4096/8; - - if (ramsize > 6*1024/8) - rxspace = ramsize - (ramsize + 2) / 3; + /* Determine available ram buffer space (in 4K blocks). + * Note: not sure about the FE setting below yet + */ + if (hw->chip_id == CHIP_ID_YUKON_FE) + ramsize = 4; else - rxspace = ramsize / 2; + ramsize = sky2_read8(hw, B2_E_0); - sky2_ramset(hw, rxqaddr[port], 0, rxspace-1); - sky2_ramset(hw, txqaddr[port], rxspace, ramsize-1); + /* Give transmitter one third (rounded up) */ + rxspace = ramsize - (ramsize + 2) / 3; + + sky2_ramset(hw, rxqaddr[port], 0, rxspace); + sky2_ramset(hw, txqaddr[port], rxspace, ramsize); /* Make sure SyncQ is disabled */ sky2_write8(hw, RB_ADDR(port == 0 ? Q_XS1 : Q_XS2, RB_CTRL), @@ -1493,11 +1499,6 @@ static int sky2_down(struct net_device *dev) /* Stop more packets from being queued */ netif_stop_queue(dev); - /* Disable port IRQ */ - imask = sky2_read32(hw, B0_IMSK); - imask &= ~portirq_msk[port]; - sky2_write32(hw, B0_IMSK, imask); - sky2_gmac_reset(hw, port); /* Stop transmitter */ @@ -1548,6 +1549,11 @@ static int sky2_down(struct net_device *dev) sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET); sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET); + /* Disable port IRQ */ + imask = sky2_read32(hw, B0_IMSK); + imask &= ~portirq_msk[port]; + sky2_write32(hw, B0_IMSK, imask); + sky2_phy_power(hw, port, 0); /* turn off LED's */ @@ -1599,12 +1605,6 @@ static void sky2_link_up(struct sky2_port *sky2) struct sky2_hw *hw = sky2->hw; unsigned port = sky2->port; u16 reg; - static const char *fc_name[] = { - [FC_NONE] = "none", - [FC_TX] = "tx", - [FC_RX] = "rx", - [FC_BOTH] = "both", - }; /* enable Rx/Tx */ reg = gma_read16(hw, port, GM_GP_CTRL); @@ -1648,7 +1648,8 @@ static void sky2_link_up(struct sky2_port *sky2) "%s: Link is up at %d Mbps, %s duplex, flow control %s\n", sky2->netdev->name, sky2->speed, sky2->duplex == DUPLEX_FULL ? "full" : "half", - fc_name[sky2->flow_status]); + (sky2->tx_pause && sky2->rx_pause) ? "both" : + sky2->tx_pause ? "tx" : sky2->rx_pause ? "rx" : "none"); } static void sky2_link_down(struct sky2_port *sky2) @@ -1663,7 +1664,7 @@ static void sky2_link_down(struct sky2_port *sky2) reg &= ~(GM_GPCR_RX_ENA | GM_GPCR_TX_ENA); gma_write16(hw, port, GM_GP_CTRL, reg); - if (sky2->flow_status == FC_RX) { + if (sky2->rx_pause && !sky2->tx_pause) { /* restore Asymmetric Pause bit */ gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, gm_phy_read(hw, port, PHY_MARV_AUNE_ADV) @@ -1682,14 +1683,6 @@ static void sky2_link_down(struct sky2_port *sky2) sky2_phy_init(hw, port); } -static enum flow_control sky2_flow(int rx, int tx) -{ - if (rx) - return tx ? FC_BOTH : FC_RX; - else - return tx ? FC_TX : FC_NONE; -} - static int sky2_autoneg_done(struct sky2_port *sky2, u16 aux) { struct sky2_hw *hw = sky2->hw; @@ -1710,20 +1703,39 @@ static int sky2_autoneg_done(struct sky2_port *sky2, u16 aux) } sky2->speed = sky2_phy_speed(hw, aux); - sky2->duplex = (aux & PHY_M_PS_FULL_DUP) ? DUPLEX_FULL : DUPLEX_HALF; + if (sky2->speed == SPEED_1000) { + u16 ctl2 = gm_phy_read(hw, port, PHY_MARV_1000T_CTRL); + u16 lpa2 = gm_phy_read(hw, port, PHY_MARV_1000T_STAT); + if (lpa2 & PHY_B_1000S_MSF) { + printk(KERN_ERR PFX "%s: master/slave fault", + sky2->netdev->name); + return -1; + } + + if ((ctl2 & PHY_M_1000C_AFD) && (lpa2 & PHY_B_1000S_LP_FD)) + sky2->duplex = DUPLEX_FULL; + else + sky2->duplex = DUPLEX_HALF; + } else { + u16 adv = gm_phy_read(hw, port, PHY_MARV_AUNE_ADV); + if ((aux & adv) & PHY_AN_FULL) + sky2->duplex = DUPLEX_FULL; + else + sky2->duplex = DUPLEX_HALF; + } /* Pause bits are offset (9..8) */ if (hw->chip_id == CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U) aux >>= 6; - sky2->flow_status = sky2_flow(aux & PHY_M_PS_RX_P_EN, - aux & PHY_M_PS_TX_P_EN); + sky2->rx_pause = (aux & PHY_M_PS_RX_P_EN) != 0; + sky2->tx_pause = (aux & PHY_M_PS_TX_P_EN) != 0; - if (sky2->duplex == DUPLEX_HALF && sky2->speed < SPEED_1000 + if (sky2->duplex == DUPLEX_HALF && sky2->speed != SPEED_1000 && hw->chip_id != CHIP_ID_YUKON_EC_U) - sky2->flow_status = FC_NONE; + sky2->rx_pause = sky2->tx_pause = 0; - if (aux & PHY_M_PS_RX_P_EN) + if (sky2->rx_pause || sky2->tx_pause) sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_ON); else sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF); @@ -1738,13 +1750,13 @@ static void sky2_phy_intr(struct sky2_hw *hw, unsigned port) struct sky2_port *sky2 = netdev_priv(dev); u16 istatus, phystat; - if (!netif_running(dev)) - return; - spin_lock(&sky2->phy_lock); istatus = gm_phy_read(hw, port, PHY_MARV_INT_STAT); phystat = gm_phy_read(hw, port, PHY_MARV_PHY_STAT); + if (!netif_running(dev)) + goto out; + if (netif_msg_intr(sky2)) printk(KERN_INFO PFX "%s: phy interrupt status 0x%x 0x%x\n", sky2->netdev->name, istatus, phystat); @@ -1895,7 +1907,7 @@ static struct sk_buff *receive_copy(struct sky2_port *sky2, pci_dma_sync_single_for_device(sky2->hw->pdev, re->data_addr, length, PCI_DMA_FROMDEVICE); re->skb->ip_summed = CHECKSUM_NONE; - skb_put(skb, length); + __skb_put(skb, length); } return skb; } @@ -1958,7 +1970,7 @@ static struct sk_buff *receive_new(struct sky2_port *sky2, if (skb_shinfo(skb)->nr_frags) skb_put_frags(skb, hdr_space, length); else - skb_put(skb, length); + skb_put(skb, hdr_space); return skb; } @@ -2004,10 +2016,6 @@ static struct sk_buff *sky2_receive(struct net_device *dev, error: ++sky2->net_stats.rx_errors; - if (status & GMR_FS_RX_FF_OV) { - sky2->net_stats.rx_fifo_errors++; - goto resubmit; - } if (netif_msg_rx_err(sky2) && net_ratelimit()) printk(KERN_INFO PFX "%s: rx error, status 0x%x length %d\n", @@ -2019,6 +2027,8 @@ static struct sk_buff *sky2_receive(struct net_device *dev, sky2->net_stats.rx_frame_errors++; if (status & GMR_FS_CRC_ERR) sky2->net_stats.rx_crc_errors++; + if (status & GMR_FS_RX_FF_OV) + sky2->net_stats.rx_fifo_errors++; goto resubmit; } @@ -2210,7 +2220,8 @@ static void sky2_hw_intr(struct sky2_hw *hw) /* PCI-Express uncorrectable Error occurred */ u32 pex_err; - pex_err = sky2_pci_read32(hw, PEX_UNC_ERR_STAT); + pex_err = sky2_pci_read32(hw, + hw->err_cap + PCI_ERR_UNCOR_STATUS); if (net_ratelimit()) printk(KERN_ERR PFX "%s: pci express error (0x%x)\n", @@ -2218,15 +2229,20 @@ static void sky2_hw_intr(struct sky2_hw *hw) /* clear the interrupt */ sky2_write32(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); - sky2_pci_write32(hw, PEX_UNC_ERR_STAT, - 0xffffffffUL); + sky2_pci_write32(hw, + hw->err_cap + PCI_ERR_UNCOR_STATUS, + 0xffffffffUL); sky2_write32(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); - if (pex_err & PEX_FATAL_ERRORS) { + + /* In case of fatal error mask off to keep from getting stuck */ + if (pex_err & (PCI_ERR_UNC_POISON_TLP | PCI_ERR_UNC_FCP + | PCI_ERR_UNC_DLP)) { u32 hwmsk = sky2_read32(hw, B0_HWE_IMSK); hwmsk &= ~Y2_IS_PCI_EXP; sky2_write32(hw, B0_HWE_IMSK, hwmsk); } + } if (status & Y2_HWE_L1_MASK) @@ -2348,7 +2364,7 @@ static int sky2_poll(struct net_device *dev0, int *budget) } } -static irqreturn_t sky2_intr(int irq, void *dev_id) +static irqreturn_t sky2_intr(int irq, void *dev_id, struct pt_regs *regs) { struct sky2_hw *hw = dev_id; struct net_device *dev0 = hw->dev[0]; @@ -2407,6 +2423,7 @@ static int sky2_reset(struct sky2_hw *hw) u16 status; u8 t8; int i; + u32 msk; sky2_write8(hw, B0_CTST, CS_RST_CLR); @@ -2447,9 +2464,13 @@ static int sky2_reset(struct sky2_hw *hw) sky2_write8(hw, B0_CTST, CS_MRST_CLR); /* clear any PEX errors */ - if (pci_find_capability(hw->pdev, PCI_CAP_ID_EXP)) - sky2_pci_write32(hw, PEX_UNC_ERR_STAT, 0xffffffffUL); - + if (pci_find_capability(hw->pdev, PCI_CAP_ID_EXP)) { + hw->err_cap = pci_find_ext_capability(hw->pdev, PCI_EXT_CAP_ID_ERR); + if (hw->err_cap) + sky2_pci_write32(hw, + hw->err_cap + PCI_ERR_UNCOR_STATUS, + 0xffffffffUL); + } hw->pmd_type = sky2_read8(hw, B2_PMD_TYP); hw->ports = 1; @@ -2506,7 +2527,10 @@ static int sky2_reset(struct sky2_hw *hw) sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_XS2), SK_RI_TO_53); } - sky2_write32(hw, B0_HWE_IMSK, Y2_HWE_ALL_MASK); + msk = Y2_HWE_ALL_MASK; + if (!hw->err_cap) + msk &= ~Y2_IS_PCI_EXP; + sky2_write32(hw, B0_HWE_IMSK, msk); for (i = 0; i < hw->ports; i++) sky2_gmac_reset(hw, i); @@ -2738,7 +2762,7 @@ static int sky2_nway_reset(struct net_device *dev) { struct sky2_port *sky2 = netdev_priv(dev); - if (!netif_running(dev) || sky2->autoneg != AUTONEG_ENABLE) + if (sky2->autoneg != AUTONEG_ENABLE) return -EINVAL; sky2_phy_reinit(sky2); @@ -2840,14 +2864,6 @@ static int sky2_set_mac_address(struct net_device *dev, void *p) return 0; } -static void inline sky2_add_filter(u8 filter[8], const u8 *addr) -{ - u32 bit; - - bit = ether_crc(ETH_ALEN, addr) & 63; - filter[bit >> 3] |= 1 << (bit & 7); -} - static void sky2_set_multicast(struct net_device *dev) { struct sky2_port *sky2 = netdev_priv(dev); @@ -2856,10 +2872,7 @@ static void sky2_set_multicast(struct net_device *dev) struct dev_mc_list *list = dev->mc_list; u16 reg; u8 filter[8]; - int rx_pause; - static const u8 pause_mc_addr[ETH_ALEN] = { 0x1, 0x80, 0xc2, 0x0, 0x0, 0x1 }; - rx_pause = (sky2->flow_status == FC_RX || sky2->flow_status == FC_BOTH); memset(filter, 0, sizeof(filter)); reg = gma_read16(hw, port, GM_RX_CTRL); @@ -2867,19 +2880,18 @@ static void sky2_set_multicast(struct net_device *dev) if (dev->flags & IFF_PROMISC) /* promiscuous */ reg &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA); - else if (dev->flags & IFF_ALLMULTI) + else if ((dev->flags & IFF_ALLMULTI) || dev->mc_count > 16) /* all multicast */ memset(filter, 0xff, sizeof(filter)); - else if (dev->mc_count == 0 && !rx_pause) + else if (dev->mc_count == 0) /* no multicast */ reg &= ~GM_RXCR_MCF_ENA; else { int i; reg |= GM_RXCR_MCF_ENA; - if (rx_pause) - sky2_add_filter(filter, pause_mc_addr); - - for (i = 0; list && i < dev->mc_count; i++, list = list->next) - sky2_add_filter(filter, list->dmi_addr); + for (i = 0; list && i < dev->mc_count; i++, list = list->next) { + u32 bit = ether_crc(ETH_ALEN, list->dmi_addr) & 0x3f; + filter[bit / 8] |= 1 << (bit % 8); + } } gma_write16(hw, port, GM_MC_ADDR_H1, @@ -2992,20 +3004,8 @@ static void sky2_get_pauseparam(struct net_device *dev, { struct sky2_port *sky2 = netdev_priv(dev); - switch (sky2->flow_mode) { - case FC_NONE: - ecmd->tx_pause = ecmd->rx_pause = 0; - break; - case FC_TX: - ecmd->tx_pause = 1, ecmd->rx_pause = 0; - break; - case FC_RX: - ecmd->tx_pause = 0, ecmd->rx_pause = 1; - break; - case FC_BOTH: - ecmd->tx_pause = ecmd->rx_pause = 1; - } - + ecmd->tx_pause = sky2->tx_pause; + ecmd->rx_pause = sky2->rx_pause; ecmd->autoneg = sky2->autoneg; } @@ -3015,10 +3015,10 @@ static int sky2_set_pauseparam(struct net_device *dev, struct sky2_port *sky2 = netdev_priv(dev); sky2->autoneg = ecmd->autoneg; - sky2->flow_mode = sky2_flow(ecmd->rx_pause, ecmd->tx_pause); + sky2->tx_pause = ecmd->tx_pause != 0; + sky2->rx_pause = ecmd->rx_pause != 0; - if (netif_running(dev)) - sky2_phy_reinit(sky2); + sky2_phy_reinit(sky2); return 0; } @@ -3238,11 +3238,7 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, dev->poll = sky2_poll; dev->weight = NAPI_WEIGHT; #ifdef CONFIG_NET_POLL_CONTROLLER - /* Network console (only works on port 0) - * because netpoll makes assumptions about NAPI - */ - if (port == 0) - dev->poll_controller = sky2_netpoll; + dev->poll_controller = sky2_netpoll; #endif sky2 = netdev_priv(dev); @@ -3252,8 +3248,8 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, /* Auto speed and flow control */ sky2->autoneg = AUTONEG_ENABLE; - sky2->flow_mode = FC_BOTH; - + sky2->tx_pause = 1; + sky2->rx_pause = 1; sky2->duplex = -1; sky2->speed = -1; sky2->advertising = sky2_supported_modes(hw); @@ -3302,7 +3298,8 @@ static void __devinit sky2_show_addr(struct net_device *dev) } /* Handle software interrupt used during MSI test */ -static irqreturn_t __devinit sky2_test_intr(int irq, void *dev_id) +static irqreturn_t __devinit sky2_test_intr(int irq, void *dev_id, + struct pt_regs *regs) { struct sky2_hw *hw = dev_id; u32 status = sky2_read32(hw, B0_Y2_SP_ISRC2); @@ -3344,8 +3341,9 @@ static int __devinit sky2_test_msi(struct sky2_hw *hw) if (!hw->msi_detected) { /* MSI test failed, go back to INTx mode */ - printk(KERN_INFO PFX "%s: No interrupt generated using MSI, " - "switching to INTx mode.\n", + printk(KERN_WARNING PFX "%s: No interrupt was generated using MSI, " + "switching to INTx mode. Please report this failure to " + "the PCI maintainer and include system chipset information.\n", pci_name(pdev)); err = -EOPNOTSUPP; @@ -3353,7 +3351,6 @@ static int __devinit sky2_test_msi(struct sky2_hw *hw) } sky2_write32(hw, B0_IMSK, 0); - sky2_read32(hw, B0_IMSK); free_irq(pdev->irq, hw); diff --git a/trunk/drivers/net/sky2.h b/trunk/drivers/net/sky2.h index 6d2a23f66c9a..f66109a96d95 100644 --- a/trunk/drivers/net/sky2.h +++ b/trunk/drivers/net/sky2.h @@ -6,24 +6,15 @@ #define ETH_JUMBO_MTU 9000 /* Maximum MTU supported */ -/* PCI config registers */ +/* PCI device specific config registers */ enum { PCI_DEV_REG1 = 0x40, PCI_DEV_REG2 = 0x44, - PCI_DEV_STATUS = 0x7c, PCI_DEV_REG3 = 0x80, PCI_DEV_REG4 = 0x84, PCI_DEV_REG5 = 0x88, }; -enum { - PEX_DEV_CAP = 0xe4, - PEX_DEV_CTRL = 0xe8, - PEX_DEV_STA = 0xea, - PEX_LNK_STAT = 0xf2, - PEX_UNC_ERR_STAT= 0x104, -}; - /* Yukon-2 */ enum pci_dev_reg_1 { PCI_Y2_PIG_ENA = 1<<31, /* Enable Plug-in-Go (YUKON-2) */ @@ -72,39 +63,6 @@ enum pci_dev_reg_4 { PCI_STATUS_REC_MASTER_ABORT | \ PCI_STATUS_REC_TARGET_ABORT | \ PCI_STATUS_PARITY) - -enum pex_dev_ctrl { - PEX_DC_MAX_RRS_MSK = 7<<12, /* Bit 14..12: Max. Read Request Size */ - PEX_DC_EN_NO_SNOOP = 1<<11,/* Enable No Snoop */ - PEX_DC_EN_AUX_POW = 1<<10,/* Enable AUX Power */ - PEX_DC_EN_PHANTOM = 1<<9, /* Enable Phantom Functions */ - PEX_DC_EN_EXT_TAG = 1<<8, /* Enable Extended Tag Field */ - PEX_DC_MAX_PLS_MSK = 7<<5, /* Bit 7.. 5: Max. Payload Size Mask */ - PEX_DC_EN_REL_ORD = 1<<4, /* Enable Relaxed Ordering */ - PEX_DC_EN_UNS_RQ_RP = 1<<3, /* Enable Unsupported Request Reporting */ - PEX_DC_EN_FAT_ER_RP = 1<<2, /* Enable Fatal Error Reporting */ - PEX_DC_EN_NFA_ER_RP = 1<<1, /* Enable Non-Fatal Error Reporting */ - PEX_DC_EN_COR_ER_RP = 1<<0, /* Enable Correctable Error Reporting */ -}; -#define PEX_DC_MAX_RD_RQ_SIZE(x) (((x)<<12) & PEX_DC_MAX_RRS_MSK) - -/* PEX_UNC_ERR_STAT PEX Uncorrectable Errors Status Register (Yukon-2) */ -enum pex_err { - PEX_UNSUP_REQ = 1<<20, /* Unsupported Request Error */ - - PEX_MALFOR_TLP = 1<<18, /* Malformed TLP */ - - PEX_UNEXP_COMP = 1<<16, /* Unexpected Completion */ - - PEX_COMP_TO = 1<<14, /* Completion Timeout */ - PEX_FLOW_CTRL_P = 1<<13, /* Flow Control Protocol Error */ - PEX_POIS_TLP = 1<<12, /* Poisoned TLP */ - - PEX_DATA_LINK_P = 1<<4, /* Data Link Protocol Error */ - PEX_FATAL_ERRORS= (PEX_MALFOR_TLP | PEX_FLOW_CTRL_P | PEX_DATA_LINK_P), -}; - - enum csr_regs { B0_RAP = 0x0000, B0_CTST = 0x0004, @@ -1576,7 +1534,7 @@ enum { GMR_FS_ANY_ERR = GMR_FS_RX_FF_OV | GMR_FS_CRC_ERR | GMR_FS_FRAGMENT | GMR_FS_LONG_ERR | - GMR_FS_MII_ERR | GMR_FS_GOOD_FC | GMR_FS_BAD_FC | + GMR_FS_MII_ERR | GMR_FS_BAD_FC | GMR_FS_UN_SIZE | GMR_FS_JABBER, }; @@ -1828,13 +1786,6 @@ struct rx_ring_info { dma_addr_t frag_addr[ETH_JUMBO_MTU >> PAGE_SHIFT]; }; -enum flow_control { - FC_NONE = 0, - FC_TX = 1, - FC_RX = 2, - FC_BOTH = 3, -}; - struct sky2_port { struct sky2_hw *hw; struct net_device *netdev; @@ -1867,13 +1818,13 @@ struct sky2_port { dma_addr_t rx_le_map; dma_addr_t tx_le_map; - u16 advertising; /* ADVERTISED_ bits */ + u32 advertising; /* ADVERTISED_ bits */ u16 speed; /* SPEED_1000, SPEED_100, ... */ u8 autoneg; /* AUTONEG_ENABLE, AUTONEG_DISABLE */ u8 duplex; /* DUPLEX_HALF, DUPLEX_FULL */ + u8 rx_pause; + u8 tx_pause; u8 rx_csum; - enum flow_control flow_mode; - enum flow_control flow_status; struct net_device_stats net_stats; @@ -1885,6 +1836,7 @@ struct sky2_hw { struct net_device *dev[2]; int pm_cap; + int err_cap; u8 chip_id; u8 chip_rev; u8 pmd_type; diff --git a/trunk/drivers/net/smc-ultra.c b/trunk/drivers/net/smc-ultra.c index 889ef0d7c374..7986514883ac 100644 --- a/trunk/drivers/net/smc-ultra.c +++ b/trunk/drivers/net/smc-ultra.c @@ -127,7 +127,7 @@ MODULE_DEVICE_TABLE(isapnp, ultra_device_ids); static void ultra_poll(struct net_device *dev) { disable_irq(dev->irq); - ei_interrupt(dev->irq, dev); + ei_interrupt(dev->irq, dev, NULL); enable_irq(dev->irq); } #endif diff --git a/trunk/drivers/net/smc911x.c b/trunk/drivers/net/smc911x.c index 2c4343395a4d..a621b17456e5 100644 --- a/trunk/drivers/net/smc911x.c +++ b/trunk/drivers/net/smc911x.c @@ -1074,7 +1074,7 @@ static void smc911x_phy_interrupt(struct net_device *dev) * This is the main routine of the driver, to handle the device when * it needs some attention. */ -static irqreturn_t smc911x_interrupt(int irq, void *dev_id) +static irqreturn_t smc911x_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; unsigned long ioaddr = dev->base_addr; @@ -1251,7 +1251,7 @@ static irqreturn_t smc911x_interrupt(int irq, void *dev_id) #ifdef SMC_USE_DMA static void -smc911x_tx_dma_irq(int dma, void *data) +smc911x_tx_dma_irq(int dma, void *data, struct pt_regs *regs) { struct net_device *dev = (struct net_device *)data; struct smc911x_local *lp = netdev_priv(dev); @@ -1285,7 +1285,7 @@ smc911x_tx_dma_irq(int dma, void *data) "%s: TX DMA irq completed\n", dev->name); } static void -smc911x_rx_dma_irq(int dma, void *data) +smc911x_rx_dma_irq(int dma, void *data, struct pt_regs *regs) { struct net_device *dev = (struct net_device *)data; unsigned long ioaddr = dev->base_addr; diff --git a/trunk/drivers/net/smc9194.c b/trunk/drivers/net/smc9194.c index c0d13d650913..5506a0d3efe2 100644 --- a/trunk/drivers/net/smc9194.c +++ b/trunk/drivers/net/smc9194.c @@ -270,7 +270,7 @@ static void smc_set_multicast_list(struct net_device *dev); /* . Handles the actual interrupt */ -static irqreturn_t smc_interrupt(int irq, void *); +static irqreturn_t smc_interrupt(int irq, void *, struct pt_regs *regs); /* . This is a separate procedure to handle the receipt of a packet, to . leave the interrupt code looking slightly cleaner @@ -1391,7 +1391,7 @@ static void smc_tx( struct net_device * dev ) . ---------------------------------------------------------------------*/ -static irqreturn_t smc_interrupt(int irq, void * dev_id) +static irqreturn_t smc_interrupt(int irq, void * dev_id, struct pt_regs * regs) { struct net_device *dev = dev_id; int ioaddr = dev->base_addr; diff --git a/trunk/drivers/net/smc91x.c b/trunk/drivers/net/smc91x.c index 95b6478f55c6..d7e56438b5d6 100644 --- a/trunk/drivers/net/smc91x.c +++ b/trunk/drivers/net/smc91x.c @@ -1284,7 +1284,7 @@ static void smc_eph_interrupt(struct net_device *dev) * This is the main routine of the driver, to handle the device when * it needs some attention. */ -static irqreturn_t smc_interrupt(int irq, void *dev_id) +static irqreturn_t smc_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; struct smc_local *lp = netdev_priv(dev); @@ -1400,7 +1400,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id) static void smc_poll_controller(struct net_device *dev) { disable_irq(dev->irq); - smc_interrupt(dev->irq, dev); + smc_interrupt(dev->irq, dev, NULL); enable_irq(dev->irq); } #endif diff --git a/trunk/drivers/net/smc91x.h b/trunk/drivers/net/smc91x.h index a8640169fc77..fedd1a37bc3e 100644 --- a/trunk/drivers/net/smc91x.h +++ b/trunk/drivers/net/smc91x.h @@ -398,42 +398,6 @@ static inline void LPD7_SMC_outsw (unsigned char* a, int r, #define SMC_IRQ_FLAGS (0) -#elif defined(CONFIG_ARCH_VERSATILE) - -#define SMC_CAN_USE_8BIT 1 -#define SMC_CAN_USE_16BIT 1 -#define SMC_CAN_USE_32BIT 1 -#define SMC_NOWAIT 1 - -#define SMC_inb(a, r) readb((a) + (r)) -#define SMC_inw(a, r) readw((a) + (r)) -#define SMC_inl(a, r) readl((a) + (r)) -#define SMC_outb(v, a, r) writeb(v, (a) + (r)) -#define SMC_outw(v, a, r) writew(v, (a) + (r)) -#define SMC_outl(v, a, r) writel(v, (a) + (r)) -#define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) -#define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l) - -#define SMC_IRQ_FLAGS (0) - -#elif defined(CONFIG_ARCH_VERSATILE) - -#define SMC_CAN_USE_8BIT 1 -#define SMC_CAN_USE_16BIT 1 -#define SMC_CAN_USE_32BIT 1 -#define SMC_NOWAIT 1 - -#define SMC_inb(a, r) readb((a) + (r)) -#define SMC_inw(a, r) readw((a) + (r)) -#define SMC_inl(a, r) readl((a) + (r)) -#define SMC_outb(v, a, r) writeb(v, (a) + (r)) -#define SMC_outw(v, a, r) writew(v, (a) + (r)) -#define SMC_outl(v, a, r) writel(v, (a) + (r)) -#define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) -#define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l) - -#define SMC_IRQ_FLAGS (0) - #else #define SMC_CAN_USE_8BIT 1 @@ -543,7 +507,7 @@ smc_pxa_dma_insw(void __iomem *ioaddr, u_long physaddr, int reg, int dma, #endif static void -smc_pxa_dma_irq(int dma, void *dummy) +smc_pxa_dma_irq(int dma, void *dummy, struct pt_regs *regs) { DCSR(dma) = 0; } diff --git a/trunk/drivers/net/sonic.c b/trunk/drivers/net/sonic.c index ed7aa0a5acca..870cf6b07389 100644 --- a/trunk/drivers/net/sonic.c +++ b/trunk/drivers/net/sonic.c @@ -293,12 +293,17 @@ static int sonic_send_packet(struct sk_buff *skb, struct net_device *dev) * The typical workload of the driver: * Handle the network interface interrupts. */ -static irqreturn_t sonic_interrupt(int irq, void *dev_id) +static irqreturn_t sonic_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct net_device *dev = dev_id; + struct net_device *dev = (struct net_device *) dev_id; struct sonic_local *lp = netdev_priv(dev); int status; + if (dev == NULL) { + printk(KERN_ERR "sonic_interrupt: irq %d for unknown device.\n", irq); + return IRQ_NONE; + } + if (!(status = SONIC_READ(SONIC_ISR) & SONIC_IMR_DEFAULT)) return IRQ_NONE; diff --git a/trunk/drivers/net/sonic.h b/trunk/drivers/net/sonic.h index 7db13e4a7ea5..7f886e8ae28f 100644 --- a/trunk/drivers/net/sonic.h +++ b/trunk/drivers/net/sonic.h @@ -328,7 +328,7 @@ struct sonic_local { static int sonic_open(struct net_device *dev); static int sonic_send_packet(struct sk_buff *skb, struct net_device *dev); -static irqreturn_t sonic_interrupt(int irq, void *dev_id); +static irqreturn_t sonic_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void sonic_rx(struct net_device *dev); static int sonic_close(struct net_device *dev); static struct net_device_stats *sonic_get_stats(struct net_device *dev); diff --git a/trunk/drivers/net/spider_net.c b/trunk/drivers/net/spider_net.c index 418138dd6c68..1397fc55cf68 100644 --- a/trunk/drivers/net/spider_net.c +++ b/trunk/drivers/net/spider_net.c @@ -55,13 +55,12 @@ MODULE_AUTHOR("Utz Bacher and Jens Osterkamp " \ ""); MODULE_DESCRIPTION("Spider Southbridge Gigabit Ethernet driver"); MODULE_LICENSE("GPL"); -MODULE_VERSION(VERSION); static int rx_descriptors = SPIDER_NET_RX_DESCRIPTORS_DEFAULT; static int tx_descriptors = SPIDER_NET_TX_DESCRIPTORS_DEFAULT; -module_param(rx_descriptors, int, 0444); -module_param(tx_descriptors, int, 0444); +module_param(rx_descriptors, int, 0644); +module_param(tx_descriptors, int, 0644); MODULE_PARM_DESC(rx_descriptors, "number of descriptors used " \ "in rx chains"); @@ -301,7 +300,7 @@ static int spider_net_init_chain(struct spider_net_card *card, struct spider_net_descr_chain *chain, struct spider_net_descr *start_descr, - int no) + int direction, int no) { int i; struct spider_net_descr *descr; @@ -316,7 +315,7 @@ spider_net_init_chain(struct spider_net_card *card, buf = pci_map_single(card->pdev, descr, SPIDER_NET_DESCR_SIZE, - PCI_DMA_BIDIRECTIONAL); + direction); if (pci_dma_mapping_error(buf)) goto iommu_error; @@ -330,6 +329,11 @@ spider_net_init_chain(struct spider_net_card *card, (descr-1)->next = start_descr; start_descr->prev = descr-1; + descr = start_descr; + if (direction == PCI_DMA_FROMDEVICE) + for (i=0; i < no; i++, descr++) + descr->next_descr_addr = descr->next->bus_addr; + spin_lock_init(&chain->lock); chain->head = start_descr; chain->tail = start_descr; @@ -342,7 +346,7 @@ spider_net_init_chain(struct spider_net_card *card, if (descr->bus_addr) pci_unmap_single(card->pdev, descr->bus_addr, SPIDER_NET_DESCR_SIZE, - PCI_DMA_BIDIRECTIONAL); + direction); return -ENOMEM; } @@ -358,15 +362,15 @@ spider_net_free_rx_chain_contents(struct spider_net_card *card) struct spider_net_descr *descr; descr = card->rx_chain.head; - do { + while (descr->next != card->rx_chain.head) { if (descr->skb) { dev_kfree_skb(descr->skb); pci_unmap_single(card->pdev, descr->buf_addr, SPIDER_NET_MAX_FRAME, - PCI_DMA_BIDIRECTIONAL); + PCI_DMA_FROMDEVICE); } descr = descr->next; - } while (descr != card->rx_chain.head); + } } /** @@ -641,41 +645,26 @@ static int spider_net_prepare_tx_descr(struct spider_net_card *card, struct sk_buff *skb) { - struct spider_net_descr *descr; + struct spider_net_descr *descr = card->tx_chain.head; dma_addr_t buf; - unsigned long flags; - int length; - length = skb->len; - if (length < ETH_ZLEN) { - if (skb_pad(skb, ETH_ZLEN-length)) - return 0; - length = ETH_ZLEN; - } - - buf = pci_map_single(card->pdev, skb->data, length, PCI_DMA_TODEVICE); + buf = pci_map_single(card->pdev, skb->data, skb->len, PCI_DMA_TODEVICE); if (pci_dma_mapping_error(buf)) { if (netif_msg_tx_err(card) && net_ratelimit()) pr_err("could not iommu-map packet (%p, %i). " - "Dropping packet\n", skb->data, length); + "Dropping packet\n", skb->data, skb->len); card->spider_stats.tx_iommu_map_error++; return -ENOMEM; } - spin_lock_irqsave(&card->tx_chain.lock, flags); - descr = card->tx_chain.head; - card->tx_chain.head = descr->next; - descr->buf_addr = buf; - descr->buf_size = length; + descr->buf_size = skb->len; descr->next_descr_addr = 0; descr->skb = skb; descr->data_status = 0; descr->dmac_cmd_status = SPIDER_NET_DESCR_CARDOWNED | SPIDER_NET_DMAC_NOCS; - spin_unlock_irqrestore(&card->tx_chain.lock, flags); - if (skb->protocol == htons(ETH_P_IP)) switch (skb->nh.iph->protocol) { case IPPROTO_TCP: @@ -686,51 +675,32 @@ spider_net_prepare_tx_descr(struct spider_net_card *card, break; } - /* Chain the bus address, so that the DMA engine finds this descr. */ descr->prev->next_descr_addr = descr->bus_addr; - card->netdev->trans_start = jiffies; /* set netdev watchdog timer */ return 0; } -static int -spider_net_set_low_watermark(struct spider_net_card *card) +/** + * spider_net_release_tx_descr - processes a used tx descriptor + * @card: card structure + * @descr: descriptor to release + * + * releases a used tx descriptor (unmapping, freeing of skb) + */ +static inline void +spider_net_release_tx_descr(struct spider_net_card *card) { - unsigned long flags; - int status; - int cnt=0; - int i; struct spider_net_descr *descr = card->tx_chain.tail; + struct sk_buff *skb; - /* Measure the length of the queue. Measurement does not - * need to be precise -- does not need a lock. */ - while (descr != card->tx_chain.head) { - status = descr->dmac_cmd_status & SPIDER_NET_DESCR_NOT_IN_USE; - if (status == SPIDER_NET_DESCR_NOT_IN_USE) - break; - descr = descr->next; - cnt++; - } - - /* If TX queue is short, don't even bother with interrupts */ - if (cnt < card->num_tx_desc/4) - return cnt; - - /* Set low-watermark 3/4th's of the way into the queue. */ - descr = card->tx_chain.tail; - cnt = (cnt*3)/4; - for (i=0;inext; + card->tx_chain.tail = card->tx_chain.tail->next; + descr->dmac_cmd_status |= SPIDER_NET_DESCR_NOT_IN_USE; - /* Set the new watermark, clear the old watermark */ - spin_lock_irqsave(&card->tx_chain.lock, flags); - descr->dmac_cmd_status |= SPIDER_NET_DESCR_TXDESFLG; - if (card->low_watermark && card->low_watermark != descr) - card->low_watermark->dmac_cmd_status = - card->low_watermark->dmac_cmd_status & ~SPIDER_NET_DESCR_TXDESFLG; - card->low_watermark = descr; - spin_unlock_irqrestore(&card->tx_chain.lock, flags); - return cnt; + /* unmap the skb */ + skb = descr->skb; + pci_unmap_single(card->pdev, descr->buf_addr, skb->len, + PCI_DMA_TODEVICE); + dev_kfree_skb_any(skb); } /** @@ -749,29 +719,21 @@ static int spider_net_release_tx_chain(struct spider_net_card *card, int brutal) { struct spider_net_descr_chain *chain = &card->tx_chain; - struct spider_net_descr *descr; - struct sk_buff *skb; - u32 buf_addr; - unsigned long flags; int status; - while (chain->tail != chain->head) { - spin_lock_irqsave(&chain->lock, flags); - descr = chain->tail; + spider_net_read_reg(card, SPIDER_NET_GDTDMACCNTR); - status = spider_net_get_descr_status(descr); + while (chain->tail != chain->head) { + status = spider_net_get_descr_status(chain->tail); switch (status) { case SPIDER_NET_DESCR_COMPLETE: card->netdev_stats.tx_packets++; - card->netdev_stats.tx_bytes += descr->skb->len; + card->netdev_stats.tx_bytes += chain->tail->skb->len; break; case SPIDER_NET_DESCR_CARDOWNED: - if (!brutal) { - spin_unlock_irqrestore(&chain->lock, flags); + if (!brutal) return 1; - } - /* fallthrough, if we release the descriptors * brutally (then we don't care about * SPIDER_NET_DESCR_CARDOWNED) */ @@ -788,25 +750,11 @@ spider_net_release_tx_chain(struct spider_net_card *card, int brutal) default: card->netdev_stats.tx_dropped++; - if (!brutal) { - spin_unlock_irqrestore(&chain->lock, flags); - return 1; - } - } - - chain->tail = descr->next; - descr->dmac_cmd_status |= SPIDER_NET_DESCR_NOT_IN_USE; - skb = descr->skb; - buf_addr = descr->buf_addr; - spin_unlock_irqrestore(&chain->lock, flags); - - /* unmap the skb */ - if (skb) { - int len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len; - pci_unmap_single(card->pdev, buf_addr, len, PCI_DMA_TODEVICE); - dev_kfree_skb(skb); + return 1; } + spider_net_release_tx_descr(card); } + return 0; } @@ -815,12 +763,8 @@ spider_net_release_tx_chain(struct spider_net_card *card, int brutal) * @card: card structure * @descr: descriptor address to enable TX processing at * - * This routine will start the transmit DMA running if - * it is not already running. This routine ned only be - * called when queueing a new packet to an empty tx queue. - * Writes the current tx chain head as start address - * of the tx descriptor chain and enables the transmission - * DMA engine. + * spider_net_kick_tx_dma writes the current tx chain head as start address + * of the tx descriptor chain and enables the transmission DMA engine */ static inline void spider_net_kick_tx_dma(struct spider_net_card *card) @@ -860,43 +804,65 @@ spider_net_kick_tx_dma(struct spider_net_card *card) static int spider_net_xmit(struct sk_buff *skb, struct net_device *netdev) { - int cnt; struct spider_net_card *card = netdev_priv(netdev); struct spider_net_descr_chain *chain = &card->tx_chain; + struct spider_net_descr *descr = chain->head; + unsigned long flags; + int result; + + spin_lock_irqsave(&chain->lock, flags); spider_net_release_tx_chain(card, 0); - if ((chain->head->next == chain->tail->prev) || - (spider_net_prepare_tx_descr(card, skb) != 0)) { + if (chain->head->next == chain->tail->prev) { + card->netdev_stats.tx_dropped++; + result = NETDEV_TX_LOCKED; + goto out; + } + if (spider_net_get_descr_status(descr) != SPIDER_NET_DESCR_NOT_IN_USE) { card->netdev_stats.tx_dropped++; - netif_stop_queue(netdev); - return NETDEV_TX_BUSY; + result = NETDEV_TX_LOCKED; + goto out; } - cnt = spider_net_set_low_watermark(card); - if (cnt < 5) - spider_net_kick_tx_dma(card); - return NETDEV_TX_OK; + if (spider_net_prepare_tx_descr(card, skb) != 0) { + card->netdev_stats.tx_dropped++; + result = NETDEV_TX_BUSY; + goto out; + } + + result = NETDEV_TX_OK; + + spider_net_kick_tx_dma(card); + card->tx_chain.head = card->tx_chain.head->next; + +out: + spin_unlock_irqrestore(&chain->lock, flags); + netif_wake_queue(netdev); + return result; } /** * spider_net_cleanup_tx_ring - cleans up the TX ring * @card: card structure * - * spider_net_cleanup_tx_ring is called by either the tx_timer - * or from the NAPI polling routine. - * This routine releases resources associted with transmitted - * packets, including updating the queue tail pointer. + * spider_net_cleanup_tx_ring is called by the tx_timer (as we don't use + * interrupts to cleanup our TX ring) and returns sent packets to the stack + * by freeing them */ static void spider_net_cleanup_tx_ring(struct spider_net_card *card) { + unsigned long flags; + + spin_lock_irqsave(&card->tx_chain.lock, flags); + if ((spider_net_release_tx_chain(card, 0) != 0) && - (card->netdev->flags & IFF_UP)) { + (card->netdev->flags & IFF_UP)) spider_net_kick_tx_dma(card); - netif_wake_queue(card->netdev); - } + + spin_unlock_irqrestore(&card->tx_chain.lock, flags); } /** @@ -1087,7 +1053,6 @@ spider_net_poll(struct net_device *netdev, int *budget) int packets_to_do, packets_done = 0; int no_more_packets = 0; - spider_net_cleanup_tx_ring(card); packets_to_do = min(*budget, netdev->quota); while (packets_to_do) { @@ -1278,15 +1243,12 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg) case SPIDER_NET_PHYINT: case SPIDER_NET_GMAC2INT: case SPIDER_NET_GMAC1INT: + case SPIDER_NET_GIPSINT: case SPIDER_NET_GFIFOINT: case SPIDER_NET_DMACINT: case SPIDER_NET_GSYSINT: break; */ - case SPIDER_NET_GIPSINT: - show_error = 0; - break; - case SPIDER_NET_GPWOPCMPINT: /* PHY write operation completed */ show_error = 0; @@ -1345,10 +1307,9 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg) case SPIDER_NET_GDTDCEINT: /* chain end. If a descriptor should be sent, kick off * tx dma - if (card->tx_chain.tail != card->tx_chain.head) + if (card->tx_chain.tail == card->tx_chain.head) spider_net_kick_tx_dma(card); - */ - show_error = 0; + show_error = 0; */ break; /* case SPIDER_NET_G1TMCNTINT: not used. print a message */ @@ -1393,7 +1354,7 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg) if (netif_msg_intr(card)) pr_err("got descriptor chain end interrupt, " "restarting DMAC %c.\n", - 'D'-(i-SPIDER_NET_GDDDCEINT)/3); + 'D'+i-SPIDER_NET_GDDDCEINT); spider_net_refill_rx_chain(card); spider_net_enable_rxdmac(card); show_error = 0; @@ -1462,9 +1423,8 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg) } if ((show_error) && (netif_msg_intr(card))) - pr_err("Got error interrupt on %s, GHIINT0STS = 0x%08x, " + pr_err("Got error interrupt, GHIINT0STS = 0x%08x, " "GHIINT1STS = 0x%08x, GHIINT2STS = 0x%08x\n", - card->netdev->name, status_reg, error_reg1, error_reg2); /* clear interrupt sources */ @@ -1485,7 +1445,7 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg) * interrupts for this device and makes the stack poll the driver */ static irqreturn_t -spider_net_interrupt(int irq, void *ptr) +spider_net_interrupt(int irq, void *ptr, struct pt_regs *regs) { struct net_device *netdev = ptr; struct spider_net_card *card = netdev_priv(netdev); @@ -1500,8 +1460,6 @@ spider_net_interrupt(int irq, void *ptr) spider_net_rx_irq_off(card); netif_rx_schedule(netdev); } - if (status_reg & SPIDER_NET_TXINT) - netif_rx_schedule(netdev); if (status_reg & SPIDER_NET_ERRINT ) spider_net_handle_error_irq(card, status_reg); @@ -1523,7 +1481,7 @@ static void spider_net_poll_controller(struct net_device *netdev) { disable_irq(netdev->irq); - spider_net_interrupt(netdev->irq, netdev); + spider_net_interrupt(netdev->irq, netdev, NULL); enable_irq(netdev->irq); } #endif /* CONFIG_NET_POLL_CONTROLLER */ @@ -1641,7 +1599,7 @@ spider_net_enable_card(struct spider_net_card *card) SPIDER_NET_INT2_MASK_VALUE); spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR, - SPIDER_NET_GDTBSTA | SPIDER_NET_GDTDCEIDIS); + SPIDER_NET_GDTDCEIDIS); } /** @@ -1657,26 +1615,17 @@ int spider_net_open(struct net_device *netdev) { struct spider_net_card *card = netdev_priv(netdev); - struct spider_net_descr *descr; - int i, result; + int result; result = -ENOMEM; if (spider_net_init_chain(card, &card->tx_chain, card->descr, - card->num_tx_desc)) + PCI_DMA_TODEVICE, card->tx_desc)) goto alloc_tx_failed; - - card->low_watermark = NULL; - - /* rx_chain is after tx_chain, so offset is descr + tx_count */ if (spider_net_init_chain(card, &card->rx_chain, - card->descr + card->num_tx_desc, - card->num_rx_desc)) + card->descr + card->rx_desc, + PCI_DMA_FROMDEVICE, card->rx_desc)) goto alloc_rx_failed; - descr = card->rx_chain.head; - for (i=0; i < card->num_rx_desc; i++, descr++) - descr->next_descr_addr = descr->next->bus_addr; - /* allocate rx skbs */ if (spider_net_alloc_rx_skbs(card)) goto alloc_skbs_failed; @@ -1929,7 +1878,10 @@ spider_net_stop(struct net_device *netdev) spider_net_disable_rxdmac(card); /* release chains */ - spider_net_release_tx_chain(card, 1); + if (spin_trylock(&card->tx_chain.lock)) { + spider_net_release_tx_chain(card, 1); + spin_unlock(&card->tx_chain.lock); + } spider_net_free_chain(card, &card->tx_chain); spider_net_free_chain(card, &card->rx_chain); @@ -2060,8 +2012,8 @@ spider_net_setup_netdev(struct spider_net_card *card) card->options.rx_csum = SPIDER_NET_RX_CSUM_DEFAULT; - card->num_tx_desc = tx_descriptors; - card->num_rx_desc = rx_descriptors; + card->tx_desc = tx_descriptors; + card->rx_desc = rx_descriptors; spider_net_setup_netdev_ops(netdev); @@ -2300,8 +2252,6 @@ static struct pci_driver spider_net_driver = { */ static int __init spider_net_init(void) { - printk(KERN_INFO "Spidernet version %s.\n", VERSION); - if (rx_descriptors < SPIDER_NET_RX_DESCRIPTORS_MIN) { rx_descriptors = SPIDER_NET_RX_DESCRIPTORS_MIN; pr_info("adjusting rx descriptors to %i.\n", rx_descriptors); diff --git a/trunk/drivers/net/spider_net.h b/trunk/drivers/net/spider_net.h index b3b46119b424..a59deda2f95e 100644 --- a/trunk/drivers/net/spider_net.h +++ b/trunk/drivers/net/spider_net.h @@ -24,8 +24,6 @@ #ifndef _SPIDER_NET_H #define _SPIDER_NET_H -#define VERSION "1.1 A" - #include "sungem_phy.h" extern int spider_net_stop(struct net_device *netdev); @@ -49,7 +47,7 @@ extern char spider_net_driver_name[]; #define SPIDER_NET_TX_DESCRIPTORS_MIN 16 #define SPIDER_NET_TX_DESCRIPTORS_MAX 512 -#define SPIDER_NET_TX_TIMER (HZ/5) +#define SPIDER_NET_TX_TIMER 20 #define SPIDER_NET_RX_CSUM_DEFAULT 1 @@ -191,9 +189,7 @@ extern char spider_net_driver_name[]; #define SPIDER_NET_MACMODE_VALUE 0x00000001 #define SPIDER_NET_BURSTLMT_VALUE 0x00000200 /* about 16 us */ -/* DMAC control register GDMACCNTR - * - * 1(0) enable r/tx dma +/* 1(0) enable r/tx dma * 0000000 fixed to 0 * * 000000 fixed to 0 @@ -202,7 +198,6 @@ extern char spider_net_driver_name[]; * * 000000 fixed to 0 * 00 burst alignment: 128 bytes - * 11 burst alignment: 1024 bytes * * 00000 fixed to 0 * 0 descr writeback size 32 bytes @@ -213,13 +208,10 @@ extern char spider_net_driver_name[]; #define SPIDER_NET_DMA_RX_VALUE 0x80000000 #define SPIDER_NET_DMA_RX_FEND_VALUE 0x00030003 /* to set TX_DMA_EN */ -#define SPIDER_NET_TX_DMA_EN 0x80000000 -#define SPIDER_NET_GDTBSTA 0x00000300 -#define SPIDER_NET_GDTDCEIDIS 0x00000002 -#define SPIDER_NET_DMA_TX_VALUE SPIDER_NET_TX_DMA_EN | \ - SPIDER_NET_GDTBSTA | \ - SPIDER_NET_GDTDCEIDIS - +#define SPIDER_NET_TX_DMA_EN 0x80000000 +#define SPIDER_NET_GDTDCEIDIS 0x00000002 +#define SPIDER_NET_DMA_TX_VALUE SPIDER_NET_TX_DMA_EN | \ + SPIDER_NET_GDTDCEIDIS #define SPIDER_NET_DMA_TX_FEND_VALUE 0x00030003 /* SPIDER_NET_UA_DESCR_VALUE is OR'ed with the unicast address */ @@ -328,10 +320,13 @@ enum spider_net_int2_status { SPIDER_NET_GRISPDNGINT }; -#define SPIDER_NET_TXINT ( (1 << SPIDER_NET_GDTFDCINT) ) +#define SPIDER_NET_TXINT ( (1 << SPIDER_NET_GTTEDINT) | \ + (1 << SPIDER_NET_GDTDCEINT) | \ + (1 << SPIDER_NET_GDTFDCINT) ) -/* We rely on flagged descriptor interrupts */ -#define SPIDER_NET_RXINT ( (1 << SPIDER_NET_GDAFDCINT) ) +/* we rely on flagged descriptor interrupts*/ +#define SPIDER_NET_RXINT ( (1 << SPIDER_NET_GDAFDCINT) | \ + (1 << SPIDER_NET_GRMFLLINT) ) #define SPIDER_NET_ERRINT ( 0xffffffff & \ (~SPIDER_NET_TXINT) & \ @@ -354,7 +349,6 @@ enum spider_net_int2_status { #define SPIDER_NET_DESCR_FORCE_END 0x50000000 /* used in rx and tx */ #define SPIDER_NET_DESCR_CARDOWNED 0xA0000000 /* used in rx and tx */ #define SPIDER_NET_DESCR_NOT_IN_USE 0xF0000000 -#define SPIDER_NET_DESCR_TXDESFLG 0x00800000 struct spider_net_descr { /* as defined by the hardware */ @@ -439,7 +433,6 @@ struct spider_net_card { struct spider_net_descr_chain tx_chain; struct spider_net_descr_chain rx_chain; - struct spider_net_descr *low_watermark; struct net_device_stats netdev_stats; @@ -455,8 +448,8 @@ struct spider_net_card { /* for ethtool */ int msg_enable; - int num_rx_desc; - int num_tx_desc; + int rx_desc; + int tx_desc; struct spider_net_extra_stats spider_stats; struct spider_net_descr descr[0]; diff --git a/trunk/drivers/net/spider_net_ethtool.c b/trunk/drivers/net/spider_net_ethtool.c index 91b995102915..589e43658dee 100644 --- a/trunk/drivers/net/spider_net_ethtool.c +++ b/trunk/drivers/net/spider_net_ethtool.c @@ -76,7 +76,7 @@ spider_net_ethtool_get_drvinfo(struct net_device *netdev, /* clear and fill out info */ memset(drvinfo, 0, sizeof(struct ethtool_drvinfo)); strncpy(drvinfo->driver, spider_net_driver_name, 32); - strncpy(drvinfo->version, VERSION, 32); + strncpy(drvinfo->version, "0.1", 32); strcpy(drvinfo->fw_version, "no information"); strncpy(drvinfo->bus_info, pci_name(card->pdev), 32); } @@ -158,9 +158,9 @@ spider_net_ethtool_get_ringparam(struct net_device *netdev, struct spider_net_card *card = netdev->priv; ering->tx_max_pending = SPIDER_NET_TX_DESCRIPTORS_MAX; - ering->tx_pending = card->num_tx_desc; + ering->tx_pending = card->tx_desc; ering->rx_max_pending = SPIDER_NET_RX_DESCRIPTORS_MAX; - ering->rx_pending = card->num_rx_desc; + ering->rx_pending = card->rx_desc; } static int spider_net_get_stats_count(struct net_device *netdev) diff --git a/trunk/drivers/net/starfire.c b/trunk/drivers/net/starfire.c index 7a0aee6c869d..3d617e8f54b5 100644 --- a/trunk/drivers/net/starfire.c +++ b/trunk/drivers/net/starfire.c @@ -632,7 +632,7 @@ static void check_duplex(struct net_device *dev); static void tx_timeout(struct net_device *dev); static void init_ring(struct net_device *dev); static int start_tx(struct sk_buff *skb, struct net_device *dev); -static irqreturn_t intr_handler(int irq, void *dev_instance); +static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *regs); static void netdev_error(struct net_device *dev, int intr_status); static int __netdev_rx(struct net_device *dev, int *quota); static void refill_rx_ring(struct net_device *dev); @@ -1307,7 +1307,7 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev) /* The interrupt handler does all of the Rx thread work and cleans up after the Tx thread. */ -static irqreturn_t intr_handler(int irq, void *dev_instance) +static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *rgs) { struct net_device *dev = dev_instance; struct netdev_private *np = netdev_priv(dev); diff --git a/trunk/drivers/net/sun3_82586.c b/trunk/drivers/net/sun3_82586.c index a3220a96524f..0605461bc56d 100644 --- a/trunk/drivers/net/sun3_82586.c +++ b/trunk/drivers/net/sun3_82586.c @@ -122,7 +122,7 @@ sizeof(nop_cmd) = 8; DELAY_16(); DELAY_16(); } } static int sun3_82586_probe1(struct net_device *dev,int ioaddr); -static irqreturn_t sun3_82586_interrupt(int irq,void *dev_id); +static irqreturn_t sun3_82586_interrupt(int irq,void *dev_id,struct pt_regs *reg_ptr); static int sun3_82586_open(struct net_device *dev); static int sun3_82586_close(struct net_device *dev); static int sun3_82586_send_packet(struct sk_buff *,struct net_device *); @@ -330,7 +330,7 @@ struct net_device * __init sun3_82586_probe(int unit) out1: free_netdev(dev); out: - iounmap((void __iomem *)ioaddr); + iounmap((void *)ioaddr); return ERR_PTR(err); } @@ -678,7 +678,7 @@ static void *alloc_rfa(struct net_device *dev,void *ptr) * Interrupt Handler ... */ -static irqreturn_t sun3_82586_interrupt(int irq,void *dev_id) +static irqreturn_t sun3_82586_interrupt(int irq,void *dev_id,struct pt_regs *reg_ptr) { struct net_device *dev = dev_id; unsigned short stat; diff --git a/trunk/drivers/net/sun3lance.c b/trunk/drivers/net/sun3lance.c index b865db363ba0..61a832ce7ccf 100644 --- a/trunk/drivers/net/sun3lance.c +++ b/trunk/drivers/net/sun3lance.c @@ -237,7 +237,7 @@ static int lance_probe( struct net_device *dev); static int lance_open( struct net_device *dev ); static void lance_init_ring( struct net_device *dev ); static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev ); -static irqreturn_t lance_interrupt( int irq, void *dev_id); +static irqreturn_t lance_interrupt( int irq, void *dev_id, struct pt_regs *fp ); static int lance_rx( struct net_device *dev ); static int lance_close( struct net_device *dev ); static struct net_device_stats *lance_get_stats( struct net_device *dev ); @@ -286,7 +286,7 @@ struct net_device * __init sun3lance_probe(int unit) out1: #ifdef CONFIG_SUN3 - iounmap((void __iomem *)dev->base_addr); + iounmap((void *)dev->base_addr); #endif out: free_netdev(dev); @@ -326,7 +326,7 @@ static int __init lance_probe( struct net_device *dev) ioaddr_probe[1] = tmp2; #ifdef CONFIG_SUN3 - iounmap((void __iomem *)ioaddr); + iounmap((void *)ioaddr); #endif return 0; } @@ -642,7 +642,7 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev ) /* The LANCE interrupt handler. */ -static irqreturn_t lance_interrupt( int irq, void *dev_id) +static irqreturn_t lance_interrupt( int irq, void *dev_id, struct pt_regs *fp) { struct net_device *dev = dev_id; struct lance_private *lp = netdev_priv(dev); @@ -956,7 +956,7 @@ void cleanup_module(void) { unregister_netdev(sun3lance_dev); #ifdef CONFIG_SUN3 - iounmap((void __iomem *)sun3lance_dev->base_addr); + iounmap((void *)sun3lance_dev->base_addr); #endif free_netdev(sun3lance_dev); } diff --git a/trunk/drivers/net/sunbmac.c b/trunk/drivers/net/sunbmac.c index 18f88853e1e5..9e4be86495a0 100644 --- a/trunk/drivers/net/sunbmac.c +++ b/trunk/drivers/net/sunbmac.c @@ -42,7 +42,7 @@ #define DRV_RELDATE "11/24/03" #define DRV_AUTHOR "David S. Miller (davem@redhat.com)" -static char version[] = +static char version[] __initdata = DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " " DRV_AUTHOR "\n"; MODULE_VERSION(DRV_VERSION); @@ -888,7 +888,7 @@ static void bigmac_rx(struct bigmac *bp) printk(KERN_NOTICE "%s: Memory squeeze, deferring packet.\n", bp->dev->name); } -static irqreturn_t bigmac_interrupt(int irq, void *dev_id) +static irqreturn_t bigmac_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct bigmac *bp = (struct bigmac *) dev_id; u32 qec_status, bmac_status; diff --git a/trunk/drivers/net/sundance.c b/trunk/drivers/net/sundance.c index 41c503d8bac4..6b8f4baf87fd 100644 --- a/trunk/drivers/net/sundance.c +++ b/trunk/drivers/net/sundance.c @@ -420,7 +420,7 @@ static void tx_timeout(struct net_device *dev); static void init_ring(struct net_device *dev); static int start_tx(struct sk_buff *skb, struct net_device *dev); static int reset_tx (struct net_device *dev); -static irqreturn_t intr_handler(int irq, void *dev_instance); +static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *regs); static void rx_poll(unsigned long data); static void tx_poll(unsigned long data); static void refill_rx (struct net_device *dev); @@ -1102,7 +1102,7 @@ reset_tx (struct net_device *dev) /* The interrupt handler cleans up after the Tx thread, and schedule a Rx thread work */ -static irqreturn_t intr_handler(int irq, void *dev_instance) +static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *rgs) { struct net_device *dev = (struct net_device *)dev_instance; struct netdev_private *np = netdev_priv(dev); diff --git a/trunk/drivers/net/sungem.c b/trunk/drivers/net/sungem.c index 253e96e7ad20..0975695ae31b 100644 --- a/trunk/drivers/net/sungem.c +++ b/trunk/drivers/net/sungem.c @@ -932,7 +932,7 @@ static int gem_poll(struct net_device *dev, int *budget) return 0; } -static irqreturn_t gem_interrupt(int irq, void *dev_id) +static irqreturn_t gem_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; struct gem *gp = dev->priv; @@ -975,7 +975,7 @@ static void gem_poll_controller(struct net_device *dev) /* gem_interrupt is safe to reentrance so no need * to disable_irq here. */ - gem_interrupt(dev->irq, dev); + gem_interrupt(dev->irq, dev, NULL); } #endif diff --git a/trunk/drivers/net/sunhme.c b/trunk/drivers/net/sunhme.c index 9d7cd130c19d..f05eea53623b 100644 --- a/trunk/drivers/net/sunhme.c +++ b/trunk/drivers/net/sunhme.c @@ -2093,10 +2093,10 @@ static void happy_meal_rx(struct happy_meal *hp, struct net_device *dev) RXD((">")); } -static irqreturn_t happy_meal_interrupt(int irq, void *dev_id) +static irqreturn_t happy_meal_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct net_device *dev = dev_id; - struct happy_meal *hp = netdev_priv(dev); + struct net_device *dev = (struct net_device *) dev_id; + struct happy_meal *hp = dev->priv; u32 happy_status = hme_read32(hp, hp->gregs + GREG_STAT); HMD(("happy_meal_interrupt: status=%08x ", happy_status)); @@ -2132,7 +2132,7 @@ static irqreturn_t happy_meal_interrupt(int irq, void *dev_id) } #ifdef CONFIG_SBUS -static irqreturn_t quattro_sbus_interrupt(int irq, void *cookie) +static irqreturn_t quattro_sbus_interrupt(int irq, void *cookie, struct pt_regs *ptregs) { struct quattro *qp = (struct quattro *) cookie; int i; diff --git a/trunk/drivers/net/sunlance.c b/trunk/drivers/net/sunlance.c index 5b00d79b5573..feb42db10ee1 100644 --- a/trunk/drivers/net/sunlance.c +++ b/trunk/drivers/net/sunlance.c @@ -820,9 +820,9 @@ static void lance_tx_pio(struct net_device *dev) spin_unlock(&lp->lock); } -static irqreturn_t lance_interrupt(int irq, void *dev_id) +static irqreturn_t lance_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct net_device *dev = dev_id; + struct net_device *dev = (struct net_device *)dev_id; struct lance_private *lp = netdev_priv(dev); int csr0; diff --git a/trunk/drivers/net/sunqe.c b/trunk/drivers/net/sunqe.c index 7874eb1ef043..9202a1c369dd 100644 --- a/trunk/drivers/net/sunqe.c +++ b/trunk/drivers/net/sunqe.c @@ -466,9 +466,9 @@ static void qe_tx_reclaim(struct sunqe *qep); * so we just run through each qe and check to see who is signaling * and thus needs to be serviced. */ -static irqreturn_t qec_interrupt(int irq, void *dev_id) +static irqreturn_t qec_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct sunqec *qecp = dev_id; + struct sunqec *qecp = (struct sunqec *) dev_id; u32 qec_status; int channel = 0; diff --git a/trunk/drivers/net/tc35815.c b/trunk/drivers/net/tc35815.c index 81ed82f0b520..60f026509487 100644 --- a/trunk/drivers/net/tc35815.c +++ b/trunk/drivers/net/tc35815.c @@ -453,7 +453,7 @@ static int __devinit tc35815_probe1(struct pci_dev *pdev, unsigned int base_addr static int tc35815_open(struct net_device *dev); static int tc35815_send_packet(struct sk_buff *skb, struct net_device *dev); static void tc35815_tx_timeout(struct net_device *dev); -static irqreturn_t tc35815_interrupt(int irq, void *dev_id); +static irqreturn_t tc35815_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void tc35815_rx(struct net_device *dev); static void tc35815_txdone(struct net_device *dev); static int tc35815_close(struct net_device *dev); @@ -1044,7 +1044,7 @@ static void tc35815_fatal_error_interrupt(struct net_device *dev, int status) * The typical workload of the driver: * Handle the network interface interrupts. */ -static irqreturn_t tc35815_interrupt(int irq, void *dev_id) +static irqreturn_t tc35815_interrupt(int irq, void *dev_id, struct pt_regs * regs) { struct net_device *dev = dev_id; struct tc35815_regs *tr; diff --git a/trunk/drivers/net/tg3.c b/trunk/drivers/net/tg3.c index c20bb998e0e5..c25ba273b745 100644 --- a/trunk/drivers/net/tg3.c +++ b/trunk/drivers/net/tg3.c @@ -68,8 +68,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "3.69" -#define DRV_MODULE_RELDATE "November 15, 2006" +#define DRV_MODULE_VERSION "3.66" +#define DRV_MODULE_RELDATE "September 23, 2006" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 @@ -129,7 +129,7 @@ #define RX_JUMBO_PKT_BUF_SZ (9046 + tp->rx_offset + 64) /* minimum number of free TX descriptors required to wake up TX process */ -#define TG3_TX_WAKEUP_THRESH(tp) ((tp)->tx_pending / 4) +#define TG3_TX_WAKEUP_THRESH (TG3_TX_RING_SIZE / 4) /* number of ETHTOOL_GSTATS u64's */ #define TG3_NUM_STATS (sizeof(struct tg3_ethtool_stats)/sizeof(u64)) @@ -3075,10 +3075,10 @@ static void tg3_tx(struct tg3 *tp) smp_mb(); if (unlikely(netif_queue_stopped(tp->dev) && - (tg3_tx_avail(tp) > TG3_TX_WAKEUP_THRESH(tp)))) { + (tg3_tx_avail(tp) > TG3_TX_WAKEUP_THRESH))) { netif_tx_lock(tp->dev); if (netif_queue_stopped(tp->dev) && - (tg3_tx_avail(tp) > TG3_TX_WAKEUP_THRESH(tp))) + (tg3_tx_avail(tp) > TG3_TX_WAKEUP_THRESH)) netif_wake_queue(tp->dev); netif_tx_unlock(tp->dev); } @@ -3481,7 +3481,7 @@ static inline void tg3_full_unlock(struct tg3 *tp) /* One-shot MSI handler - Chip automatically disables interrupt * after sending MSI so driver doesn't have to do it. */ -static irqreturn_t tg3_msi_1shot(int irq, void *dev_id) +static irqreturn_t tg3_msi_1shot(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; struct tg3 *tp = netdev_priv(dev); @@ -3499,7 +3499,7 @@ static irqreturn_t tg3_msi_1shot(int irq, void *dev_id) * flush status block and interrupt mailbox. PCI ordering rules * guarantee that MSI will arrive after the status block. */ -static irqreturn_t tg3_msi(int irq, void *dev_id) +static irqreturn_t tg3_msi(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; struct tg3 *tp = netdev_priv(dev); @@ -3520,7 +3520,7 @@ static irqreturn_t tg3_msi(int irq, void *dev_id) return IRQ_RETVAL(1); } -static irqreturn_t tg3_interrupt(int irq, void *dev_id) +static irqreturn_t tg3_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; struct tg3 *tp = netdev_priv(dev); @@ -3563,7 +3563,7 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id) return IRQ_RETVAL(handled); } -static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id) +static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; struct tg3 *tp = netdev_priv(dev); @@ -3606,7 +3606,8 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id) } /* ISR for interrupt test */ -static irqreturn_t tg3_test_isr(int irq, void *dev_id) +static irqreturn_t tg3_test_isr(int irq, void *dev_id, + struct pt_regs *regs) { struct net_device *dev = dev_id; struct tg3 *tp = netdev_priv(dev); @@ -3650,7 +3651,7 @@ static void tg3_poll_controller(struct net_device *dev) { struct tg3 *tp = netdev_priv(dev); - tg3_interrupt(tp->pdev->irq, dev); + tg3_interrupt(tp->pdev->irq, dev, NULL); } #endif @@ -3928,7 +3929,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) tp->tx_prod = entry; if (unlikely(tg3_tx_avail(tp) <= (MAX_SKB_FRAGS + 1))) { netif_stop_queue(dev); - if (tg3_tx_avail(tp) > TG3_TX_WAKEUP_THRESH(tp)) + if (tg3_tx_avail(tp) > TG3_TX_WAKEUP_THRESH) netif_wake_queue(tp->dev); } @@ -4143,7 +4144,7 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev) tp->tx_prod = entry; if (unlikely(tg3_tx_avail(tp) <= (MAX_SKB_FRAGS + 1))) { netif_stop_queue(dev); - if (tg3_tx_avail(tp) > TG3_TX_WAKEUP_THRESH(tp)) + if (tg3_tx_avail(tp) > TG3_TX_WAKEUP_THRESH) netif_wake_queue(tp->dev); } @@ -4728,11 +4729,10 @@ static int tg3_poll_fw(struct tg3 *tp) u32 val; if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { - /* Wait up to 20ms for init done. */ - for (i = 0; i < 200; i++) { + for (i = 0; i < 400; i++) { if (tr32(VCPU_STATUS) & VCPU_STATUS_INIT_DONE) return 0; - udelay(100); + udelay(10); } return -ENODEV; } @@ -6015,7 +6015,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) tg3_abort_hw(tp, 1); } - if (reset_phy) + if ((tp->tg3_flags2 & TG3_FLG2_MII_SERDES) && reset_phy) tg3_phy_reset(tp); err = tg3_chip_reset(tp); @@ -6575,7 +6575,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl); } - err = tg3_setup_phy(tp, 0); + err = tg3_setup_phy(tp, reset_phy); if (err) return err; @@ -6838,7 +6838,7 @@ static void tg3_timer(unsigned long __opaque) static int tg3_request_irq(struct tg3 *tp) { - irq_handler_t fn; + irqreturn_t (*fn)(int, void *, struct pt_regs *); unsigned long flags; struct net_device *dev = tp->dev; @@ -6979,10 +6979,8 @@ static int tg3_open(struct net_device *dev) tg3_full_lock(tp, 0); err = tg3_set_power_state(tp, PCI_D0); - if (err) { - tg3_full_unlock(tp); + if (err) return err; - } tg3_disable_ints(tp); tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE; @@ -8109,10 +8107,7 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e if ((ering->rx_pending > TG3_RX_RING_SIZE - 1) || (ering->rx_jumbo_pending > TG3_RX_JUMBO_RING_SIZE - 1) || - (ering->tx_pending > TG3_TX_RING_SIZE - 1) || - (ering->tx_pending <= MAX_SKB_FRAGS) || - ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_1_BUG) && - (ering->tx_pending <= (MAX_SKB_FRAGS * 3)))) + (ering->tx_pending > TG3_TX_RING_SIZE - 1)) return -EINVAL; if (netif_running(dev)) { @@ -10215,7 +10210,7 @@ static int __devinit tg3_phy_probe(struct tg3 *tp) static void __devinit tg3_read_partno(struct tg3 *tp) { unsigned char vpd_data[256]; - unsigned int i; + int i; u32 magic; if (tg3_nvram_read_swab(tp, 0x0, &magic)) @@ -10261,9 +10256,9 @@ static void __devinit tg3_read_partno(struct tg3 *tp) } /* Now parse and find the part number. */ - for (i = 0; i < 254; ) { + for (i = 0; i < 256; ) { unsigned char val = vpd_data[i]; - unsigned int block_end; + int block_end; if (val == 0x82 || val == 0x91) { i = (i + 3 + @@ -10279,26 +10274,21 @@ static void __devinit tg3_read_partno(struct tg3 *tp) (vpd_data[i + 1] + (vpd_data[i + 2] << 8))); i += 3; - - if (block_end > 256) - goto out_not_found; - - while (i < (block_end - 2)) { + while (i < block_end) { if (vpd_data[i + 0] == 'P' && vpd_data[i + 1] == 'N') { int partno_len = vpd_data[i + 2]; - i += 3; - if (partno_len > 24 || (partno_len + i) > 256) + if (partno_len > 24) goto out_not_found; memcpy(tp->board_part_number, - &vpd_data[i], partno_len); + &vpd_data[i + 3], + partno_len); /* Success. */ return; } - i += 3 + vpd_data[i + 2]; } /* Part number not found. */ @@ -10368,7 +10358,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) u32 pci_state_reg, grc_misc_cfg; u32 val; u16 pci_cmd; - int err, pcie_cap; + int err; /* Force memory write invalidate off. If we leave it on, * then on 5700_BX chips we have to enable a workaround. @@ -10543,19 +10533,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906) tp->tg3_flags2 |= TG3_FLG2_JUMBO_CAPABLE; - pcie_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_EXP); - if (pcie_cap != 0) { + if (pci_find_capability(tp->pdev, PCI_CAP_ID_EXP) != 0) tp->tg3_flags2 |= TG3_FLG2_PCI_EXPRESS; - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { - u16 lnkctl; - - pci_read_config_word(tp->pdev, - pcie_cap + PCI_EXP_LNKCTL, - &lnkctl); - if (lnkctl & PCI_EXP_LNKCTL_CLKREQ_EN) - tp->tg3_flags2 &= ~TG3_FLG2_HW_TSO_2; - } - } /* If we have an AMD 762 or VIA K8T800 chipset, write * reordering to the mailbox registers done by the host @@ -11822,7 +11801,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 || tp->pci_chip_rev_id == CHIPREV_ID_5705_A0 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906 || (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0) { tp->tg3_flags2 &= ~TG3_FLG2_TSO_CAPABLE; } else { diff --git a/trunk/drivers/net/tlan.c b/trunk/drivers/net/tlan.c index e14f5a00f65a..8d807bf603a0 100644 --- a/trunk/drivers/net/tlan.c +++ b/trunk/drivers/net/tlan.c @@ -289,7 +289,7 @@ static void TLan_Eisa_Cleanup( void ); static int TLan_Init( struct net_device * ); static int TLan_Open( struct net_device *dev ); static int TLan_StartTx( struct sk_buff *, struct net_device *); -static irqreturn_t TLan_HandleInterrupt( int, void *); +static irqreturn_t TLan_HandleInterrupt( int, void *, struct pt_regs *); static int TLan_Close( struct net_device *); static struct net_device_stats *TLan_GetStats( struct net_device *); static void TLan_SetMulticastList( struct net_device *); @@ -824,7 +824,7 @@ static void __init TLan_EisaProbe (void) static void TLan_Poll(struct net_device *dev) { disable_irq(dev->irq); - TLan_HandleInterrupt(dev->irq, dev); + TLan_HandleInterrupt(dev->irq, dev, NULL); enable_irq(dev->irq); } #endif @@ -1151,6 +1151,7 @@ static int TLan_StartTx( struct sk_buff *skb, struct net_device *dev ) * occurred. * dev_id A pointer to the device assigned to * this irq line. + * regs ??? * * This function handles an interrupt generated by its * assigned TLAN adapter. The function deactivates @@ -1161,7 +1162,7 @@ static int TLan_StartTx( struct sk_buff *skb, struct net_device *dev ) * **************************************************************/ -static irqreturn_t TLan_HandleInterrupt(int irq, void *dev_id) +static irqreturn_t TLan_HandleInterrupt(int irq, void *dev_id, struct pt_regs *regs) { u32 ack; struct net_device *dev; diff --git a/trunk/drivers/net/tokenring/3c359.c b/trunk/drivers/net/tokenring/3c359.c index 7580bdeacadc..412390ba142e 100644 --- a/trunk/drivers/net/tokenring/3c359.c +++ b/trunk/drivers/net/tokenring/3c359.c @@ -130,7 +130,7 @@ static int xl_xmit(struct sk_buff *skb, struct net_device *dev); static void xl_dn_comp(struct net_device *dev); static int xl_close(struct net_device *dev); static void xl_set_rx_mode(struct net_device *dev); -static irqreturn_t xl_interrupt(int irq, void *dev_id); +static irqreturn_t xl_interrupt(int irq, void *dev_id, struct pt_regs *regs); static struct net_device_stats * xl_get_stats(struct net_device *dev); static int xl_set_mac_address(struct net_device *dev, void *addr) ; static void xl_arb_cmd(struct net_device *dev); @@ -1042,7 +1042,7 @@ static void xl_freemem(struct net_device *dev) return ; } -static irqreturn_t xl_interrupt(int irq, void *dev_id) +static irqreturn_t xl_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *)dev_id; struct xl_private *xl_priv =(struct xl_private *)dev->priv; diff --git a/trunk/drivers/net/tokenring/ibmtr.c b/trunk/drivers/net/tokenring/ibmtr.c index bfe59865b1dd..4470025ff7f8 100644 --- a/trunk/drivers/net/tokenring/ibmtr.c +++ b/trunk/drivers/net/tokenring/ibmtr.c @@ -197,7 +197,7 @@ static void open_sap(unsigned char type, struct net_device *dev); static void tok_set_multicast_list(struct net_device *dev); static int tok_send_packet(struct sk_buff *skb, struct net_device *dev); static int tok_close(struct net_device *dev); -static irqreturn_t tok_interrupt(int irq, void *dev_id); +static irqreturn_t tok_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void initial_tok_int(struct net_device *dev); static void tr_tx(struct net_device *dev); static void tr_rx(struct net_device *dev); @@ -1166,7 +1166,7 @@ static void dir_open_adapter (struct net_device *dev) /******************************************************************************/ -static irqreturn_t tok_interrupt(int irq, void *dev_id) +static irqreturn_t tok_interrupt(int irq, void *dev_id, struct pt_regs *regs) { unsigned char status; /* unsigned char status_even ; */ @@ -1178,7 +1178,7 @@ static irqreturn_t tok_interrupt(int irq, void *dev_id) dev = dev_id; #if TR_VERBOSE - DPRINTK("Int from tok_driver, dev : %p irq%d\n", dev,irq); + DPRINTK("Int from tok_driver, dev : %p irq%d regs=%p\n", dev,irq,regs); #endif ti = (struct tok_info *) dev->priv; if (ti->sram_phys & 1) diff --git a/trunk/drivers/net/tokenring/lanstreamer.c b/trunk/drivers/net/tokenring/lanstreamer.c index e999feb8c0bb..bfc8c3eae9a1 100644 --- a/trunk/drivers/net/tokenring/lanstreamer.c +++ b/trunk/drivers/net/tokenring/lanstreamer.c @@ -206,7 +206,8 @@ static int streamer_open(struct net_device *dev); static int streamer_xmit(struct sk_buff *skb, struct net_device *dev); static int streamer_close(struct net_device *dev); static void streamer_set_rx_mode(struct net_device *dev); -static irqreturn_t streamer_interrupt(int irq, void *dev_id); +static irqreturn_t streamer_interrupt(int irq, void *dev_id, + struct pt_regs *regs); static struct net_device_stats *streamer_get_stats(struct net_device *dev); static int streamer_set_mac_address(struct net_device *dev, void *addr); static void streamer_arb_cmd(struct net_device *dev); @@ -1027,7 +1028,7 @@ static void streamer_rx(struct net_device *dev) } /* end for all completed rx descriptors */ } -static irqreturn_t streamer_interrupt(int irq, void *dev_id) +static irqreturn_t streamer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_id; struct streamer_private *streamer_priv = diff --git a/trunk/drivers/net/tokenring/madgemc.c b/trunk/drivers/net/tokenring/madgemc.c index ed274d6909d0..666bbaaae82f 100644 --- a/trunk/drivers/net/tokenring/madgemc.c +++ b/trunk/drivers/net/tokenring/madgemc.c @@ -70,7 +70,7 @@ static void madgemc_setregpage(struct net_device *dev, int page); static void madgemc_setsifsel(struct net_device *dev, int val); static void madgemc_setint(struct net_device *dev, int val); -static irqreturn_t madgemc_interrupt(int irq, void *dev_id); +static irqreturn_t madgemc_interrupt(int irq, void *dev_id, struct pt_regs *regs); /* * These work around paging, however they don't guarentee you're on the @@ -417,7 +417,7 @@ static int __devinit madgemc_probe(struct device *device) * exhausted all contiguous interrupts. * */ -static irqreturn_t madgemc_interrupt(int irq, void *dev_id) +static irqreturn_t madgemc_interrupt(int irq, void *dev_id, struct pt_regs *regs) { int pending,reg1; struct net_device *dev; @@ -451,7 +451,7 @@ static irqreturn_t madgemc_interrupt(int irq, void *dev_id) outb(reg1, dev->base_addr + MC_CONTROL_REG1); /* Continue handling as normal */ - tms380tr_interrupt(irq, dev_id); + tms380tr_interrupt(irq, dev_id, regs); pending = SIFREADW(SIFSTS); /* restart - the SIF way */ diff --git a/trunk/drivers/net/tokenring/olympic.c b/trunk/drivers/net/tokenring/olympic.c index cd142d0302bc..85831484bc40 100644 --- a/trunk/drivers/net/tokenring/olympic.c +++ b/trunk/drivers/net/tokenring/olympic.c @@ -185,7 +185,7 @@ static int olympic_xmit(struct sk_buff *skb, struct net_device *dev); static int olympic_close(struct net_device *dev); static void olympic_set_rx_mode(struct net_device *dev); static void olympic_freemem(struct net_device *dev) ; -static irqreturn_t olympic_interrupt(int irq, void *dev_id); +static irqreturn_t olympic_interrupt(int irq, void *dev_id, struct pt_regs *regs); static struct net_device_stats * olympic_get_stats(struct net_device *dev); static int olympic_set_mac_address(struct net_device *dev, void *addr) ; static void olympic_arb_cmd(struct net_device *dev); @@ -925,7 +925,7 @@ static void olympic_freemem(struct net_device *dev) return ; } -static irqreturn_t olympic_interrupt(int irq, void *dev_id) +static irqreturn_t olympic_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev= (struct net_device *)dev_id; struct olympic_private *olympic_priv=(struct olympic_private *)dev->priv; diff --git a/trunk/drivers/net/tokenring/proteon.c b/trunk/drivers/net/tokenring/proteon.c index cb7dbb63c9d9..4f756960db2a 100644 --- a/trunk/drivers/net/tokenring/proteon.c +++ b/trunk/drivers/net/tokenring/proteon.c @@ -370,10 +370,6 @@ static int __init proteon_init(void) dev->dma = dma[i]; pdev = platform_device_register_simple("proteon", i, NULL, 0); - if (IS_ERR(pdev)) { - free_netdev(dev); - continue; - } err = setup_card(dev, &pdev->dev); if (!err) { proteon_dev[i] = pdev; @@ -389,10 +385,9 @@ static int __init proteon_init(void) /* Probe for cards. */ if (num == 0) { printk(KERN_NOTICE "proteon.c: No cards found.\n"); - platform_driver_unregister(&proteon_driver); - return -ENODEV; + return (-ENODEV); } - return 0; + return (0); } static void __exit proteon_cleanup(void) diff --git a/trunk/drivers/net/tokenring/skisa.c b/trunk/drivers/net/tokenring/skisa.c index 33afea31d87b..d6ba41cf3110 100644 --- a/trunk/drivers/net/tokenring/skisa.c +++ b/trunk/drivers/net/tokenring/skisa.c @@ -380,10 +380,6 @@ static int __init sk_isa_init(void) dev->dma = dma[i]; pdev = platform_device_register_simple("skisa", i, NULL, 0); - if (IS_ERR(pdev)) { - free_netdev(dev); - continue; - } err = setup_card(dev, &pdev->dev); if (!err) { sk_isa_dev[i] = pdev; @@ -399,10 +395,9 @@ static int __init sk_isa_init(void) /* Probe for cards. */ if (num == 0) { printk(KERN_NOTICE "skisa.c: No cards found.\n"); - platform_driver_unregister(&sk_isa_driver); - return -ENODEV; + return (-ENODEV); } - return 0; + return (0); } static void __exit sk_isa_cleanup(void) diff --git a/trunk/drivers/net/tokenring/smctr.c b/trunk/drivers/net/tokenring/smctr.c index 46dabdb12071..85a7f797d343 100644 --- a/trunk/drivers/net/tokenring/smctr.c +++ b/trunk/drivers/net/tokenring/smctr.c @@ -141,7 +141,7 @@ static int smctr_init_shared_memory(struct net_device *dev); static int smctr_init_tx_bdbs(struct net_device *dev); static int smctr_init_tx_fcbs(struct net_device *dev); static int smctr_internal_self_test(struct net_device *dev); -static irqreturn_t smctr_interrupt(int irq, void *dev_id); +static irqreturn_t smctr_interrupt(int irq, void *dev_id, struct pt_regs *regs); static int smctr_issue_enable_int_cmd(struct net_device *dev, __u16 interrupt_enable_mask); static int smctr_issue_int_ack(struct net_device *dev, __u16 iack_code, @@ -1980,7 +1980,7 @@ static int smctr_internal_self_test(struct net_device *dev) /* * The typical workload of the driver: Handle the network interface interrupts. */ -static irqreturn_t smctr_interrupt(int irq, void *dev_id) +static irqreturn_t smctr_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; struct net_local *tp; @@ -1990,8 +1990,15 @@ static irqreturn_t smctr_interrupt(int irq, void *dev_id) __u8 isb_type, isb_subtype; __u16 isb_index; + if(dev == NULL) + { + printk(KERN_CRIT "%s: irq %d for unknown device.\n", dev->name, irq); + return IRQ_NONE; + } + ioaddr = dev->base_addr; tp = netdev_priv(dev); + if(tp->status == NOT_INITIALIZED) return IRQ_NONE; diff --git a/trunk/drivers/net/tokenring/tms380tr.c b/trunk/drivers/net/tokenring/tms380tr.c index ea797ca2b988..c1925590a0e1 100644 --- a/trunk/drivers/net/tokenring/tms380tr.c +++ b/trunk/drivers/net/tokenring/tms380tr.c @@ -744,13 +744,18 @@ static void tms380tr_timer_chk(unsigned long data) /* * The typical workload of the driver: Handle the network interface interrupts. */ -irqreturn_t tms380tr_interrupt(int irq, void *dev_id) +irqreturn_t tms380tr_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; struct net_local *tp; unsigned short irq_type; int handled = 0; + if(dev == NULL) { + printk(KERN_INFO "%s: irq %d for unknown device.\n", dev->name, irq); + return IRQ_NONE; + } + tp = netdev_priv(dev); irq_type = SIFREADW(SIFSTS); diff --git a/trunk/drivers/net/tokenring/tms380tr.h b/trunk/drivers/net/tokenring/tms380tr.h index 2a16078ac3fd..30452c67bb68 100644 --- a/trunk/drivers/net/tokenring/tms380tr.h +++ b/trunk/drivers/net/tokenring/tms380tr.h @@ -16,7 +16,7 @@ /* module prototypes */ int tms380tr_open(struct net_device *dev); int tms380tr_close(struct net_device *dev); -irqreturn_t tms380tr_interrupt(int irq, void *dev_id); +irqreturn_t tms380tr_interrupt(int irq, void *dev_id, struct pt_regs *regs); int tmsdev_init(struct net_device *dev, struct device *pdev); void tmsdev_term(struct net_device *dev); void tms380tr_wait(unsigned long time); diff --git a/trunk/drivers/net/tulip/de2104x.c b/trunk/drivers/net/tulip/de2104x.c index f6b3a94e97bf..e1b48bd86646 100644 --- a/trunk/drivers/net/tulip/de2104x.c +++ b/trunk/drivers/net/tulip/de2104x.c @@ -484,7 +484,7 @@ static void de_rx (struct de_private *de) de->rx_tail = rx_tail; } -static irqreturn_t de_interrupt (int irq, void *dev_instance) +static irqreturn_t de_interrupt (int irq, void *dev_instance, struct pt_regs *regs) { struct net_device *dev = dev_instance; struct de_private *de = dev->priv; @@ -1730,7 +1730,7 @@ static void __init de21040_get_media_info(struct de_private *de) } /* Note: this routine returns extra data bits for size detection. */ -static unsigned __devinit tulip_read_eeprom(void __iomem *regs, int location, int addr_len) +static unsigned __init tulip_read_eeprom(void __iomem *regs, int location, int addr_len) { int i; unsigned retval = 0; @@ -1926,7 +1926,7 @@ static void __init de21041_get_srom_info (struct de_private *de) goto fill_defaults; } -static int __devinit de_init_one (struct pci_dev *pdev, +static int __init de_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) { struct net_device *dev; @@ -2082,7 +2082,7 @@ static int __devinit de_init_one (struct pci_dev *pdev, return rc; } -static void __devexit de_remove_one (struct pci_dev *pdev) +static void __exit de_remove_one (struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); struct de_private *de = dev->priv; @@ -2164,7 +2164,7 @@ static struct pci_driver de_driver = { .name = DRV_NAME, .id_table = de_pci_tbl, .probe = de_init_one, - .remove = __devexit_p(de_remove_one), + .remove = __exit_p(de_remove_one), #ifdef CONFIG_PM .suspend = de_suspend, .resume = de_resume, diff --git a/trunk/drivers/net/tulip/de4x5.c b/trunk/drivers/net/tulip/de4x5.c index 3f4b6408b755..fb5fa7d68888 100644 --- a/trunk/drivers/net/tulip/de4x5.c +++ b/trunk/drivers/net/tulip/de4x5.c @@ -896,7 +896,7 @@ static struct { */ static int de4x5_open(struct net_device *dev); static int de4x5_queue_pkt(struct sk_buff *skb, struct net_device *dev); -static irqreturn_t de4x5_interrupt(int irq, void *dev_id); +static irqreturn_t de4x5_interrupt(int irq, void *dev_id, struct pt_regs *regs); static int de4x5_close(struct net_device *dev); static struct net_device_stats *de4x5_get_stats(struct net_device *dev); static void de4x5_local_stats(struct net_device *dev, char *buf, int pkt_len); @@ -1538,14 +1538,18 @@ de4x5_queue_pkt(struct sk_buff *skb, struct net_device *dev) ** interrupt is asserted and this routine entered. */ static irqreturn_t -de4x5_interrupt(int irq, void *dev_id) +de4x5_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct net_device *dev = dev_id; + struct net_device *dev = (struct net_device *)dev_id; struct de4x5_private *lp; s32 imr, omr, sts, limit; u_long iobase; unsigned int handled = 0; + if (dev == NULL) { + printk ("de4x5_interrupt(): irq %d for unknown device.\n", irq); + return IRQ_NONE; + } lp = netdev_priv(dev); spin_lock(&lp->lock); iobase = dev->base_addr; diff --git a/trunk/drivers/net/tulip/dmfe.c b/trunk/drivers/net/tulip/dmfe.c index 4dd8a0bae860..ccf2c225f084 100644 --- a/trunk/drivers/net/tulip/dmfe.c +++ b/trunk/drivers/net/tulip/dmfe.c @@ -300,7 +300,7 @@ static struct net_device_stats * dmfe_get_stats(struct DEVICE *); static void dmfe_set_filter_mode(struct DEVICE *); static const struct ethtool_ops netdev_ethtool_ops; static u16 read_srom_word(long ,int); -static irqreturn_t dmfe_interrupt(int , void *); +static irqreturn_t dmfe_interrupt(int , void *, struct pt_regs *); #ifdef CONFIG_NET_POLL_CONTROLLER static void poll_dmfe (struct net_device *dev); #endif @@ -735,7 +735,7 @@ static int dmfe_stop(struct DEVICE *dev) * receive the packet to upper layer, free the transmitted packet */ -static irqreturn_t dmfe_interrupt(int irq, void *dev_id) +static irqreturn_t dmfe_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct DEVICE *dev = dev_id; struct dmfe_board_info *db = netdev_priv(dev); @@ -806,7 +806,7 @@ static void poll_dmfe (struct net_device *dev) /* disable_irq here is not very nice, but with the lockless interrupt handler we have no other choice. */ disable_irq(dev->irq); - dmfe_interrupt (dev->irq, dev); + dmfe_interrupt (dev->irq, dev, NULL); enable_irq(dev->irq); } #endif diff --git a/trunk/drivers/net/tulip/interrupt.c b/trunk/drivers/net/tulip/interrupt.c index e3488d7b8ede..7f8f5d42a761 100644 --- a/trunk/drivers/net/tulip/interrupt.c +++ b/trunk/drivers/net/tulip/interrupt.c @@ -496,7 +496,7 @@ static inline unsigned int phy_interrupt (struct net_device *dev) /* The interrupt handler does all of the Rx thread work and cleans up after the Tx thread. */ -irqreturn_t tulip_interrupt(int irq, void *dev_instance) +irqreturn_t tulip_interrupt(int irq, void *dev_instance, struct pt_regs *regs) { struct net_device *dev = (struct net_device *)dev_instance; struct tulip_private *tp = netdev_priv(dev); diff --git a/trunk/drivers/net/tulip/tulip.h b/trunk/drivers/net/tulip/tulip.h index ad107f45c7b1..25668ddb1f7e 100644 --- a/trunk/drivers/net/tulip/tulip.h +++ b/trunk/drivers/net/tulip/tulip.h @@ -424,7 +424,7 @@ int tulip_read_eeprom(struct net_device *dev, int location, int addr_len); /* interrupt.c */ extern unsigned int tulip_max_interrupt_work; extern int tulip_rx_copybreak; -irqreturn_t tulip_interrupt(int irq, void *dev_instance); +irqreturn_t tulip_interrupt(int irq, void *dev_instance, struct pt_regs *regs); int tulip_refill_rx(struct net_device *dev); #ifdef CONFIG_TULIP_NAPI int tulip_poll(struct net_device *dev, int *budget); diff --git a/trunk/drivers/net/tulip/tulip_core.c b/trunk/drivers/net/tulip/tulip_core.c index 0aee618f883c..831919a81918 100644 --- a/trunk/drivers/net/tulip/tulip_core.c +++ b/trunk/drivers/net/tulip/tulip_core.c @@ -1823,7 +1823,7 @@ static void poll_tulip (struct net_device *dev) /* disable_irq here is not very nice, but with the lockless interrupt handler we have no other choice. */ disable_irq(dev->irq); - tulip_interrupt (dev->irq, dev); + tulip_interrupt (dev->irq, dev, NULL); enable_irq(dev->irq); } #endif diff --git a/trunk/drivers/net/tulip/uli526x.c b/trunk/drivers/net/tulip/uli526x.c index 229158e8e4be..0b176be51eb3 100644 --- a/trunk/drivers/net/tulip/uli526x.c +++ b/trunk/drivers/net/tulip/uli526x.c @@ -224,7 +224,7 @@ static struct net_device_stats * uli526x_get_stats(struct net_device *); static void uli526x_set_filter_mode(struct net_device *); static const struct ethtool_ops netdev_ethtool_ops; static u16 read_srom_word(long, int); -static irqreturn_t uli526x_interrupt(int, void *); +static irqreturn_t uli526x_interrupt(int, void *, struct pt_regs *); static void uli526x_descriptor_init(struct uli526x_board_info *, unsigned long); static void allocate_rx_buffer(struct uli526x_board_info *); static void update_cr6(u32, unsigned long); @@ -659,7 +659,7 @@ static int uli526x_stop(struct net_device *dev) * receive the packet to upper layer, free the transmitted packet */ -static irqreturn_t uli526x_interrupt(int irq, void *dev_id) +static irqreturn_t uli526x_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; struct uli526x_board_info *db = netdev_priv(dev); diff --git a/trunk/drivers/net/tulip/winbond-840.c b/trunk/drivers/net/tulip/winbond-840.c index 002a05e0722f..2fca1ee24f5a 100644 --- a/trunk/drivers/net/tulip/winbond-840.c +++ b/trunk/drivers/net/tulip/winbond-840.c @@ -332,7 +332,7 @@ static void tx_timeout(struct net_device *dev); static int alloc_ringdesc(struct net_device *dev); static void free_ringdesc(struct netdev_private *np); static int start_tx(struct sk_buff *skb, struct net_device *dev); -static irqreturn_t intr_handler(int irq, void *dev_instance); +static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *regs); static void netdev_error(struct net_device *dev, int intr_status); static int netdev_rx(struct net_device *dev); static u32 __set_rx_mode(struct net_device *dev); @@ -1110,7 +1110,7 @@ static void netdev_tx_done(struct net_device *dev) /* The interrupt handler does all of the Rx thread work and cleans up after the Tx thread. */ -static irqreturn_t intr_handler(int irq, void *dev_instance) +static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *rgs) { struct net_device *dev = (struct net_device *)dev_instance; struct netdev_private *np = netdev_priv(dev); diff --git a/trunk/drivers/net/tulip/xircom_cb.c b/trunk/drivers/net/tulip/xircom_cb.c index 61d313049dd0..629eac645289 100644 --- a/trunk/drivers/net/tulip/xircom_cb.c +++ b/trunk/drivers/net/tulip/xircom_cb.c @@ -114,7 +114,7 @@ struct xircom_private { /* Function prototypes */ static int xircom_probe(struct pci_dev *pdev, const struct pci_device_id *id); static void xircom_remove(struct pci_dev *pdev); -static irqreturn_t xircom_interrupt(int irq, void *dev_instance); +static irqreturn_t xircom_interrupt(int irq, void *dev_instance, struct pt_regs *regs); static int xircom_start_xmit(struct sk_buff *skb, struct net_device *dev); static int xircom_open(struct net_device *dev); static int xircom_close(struct net_device *dev); @@ -334,7 +334,7 @@ static void __devexit xircom_remove(struct pci_dev *pdev) leave("xircom_remove"); } -static irqreturn_t xircom_interrupt(int irq, void *dev_instance) +static irqreturn_t xircom_interrupt(int irq, void *dev_instance, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_instance; struct xircom_private *card = netdev_priv(dev); @@ -513,7 +513,7 @@ static struct net_device_stats *xircom_get_stats(struct net_device *dev) static void xircom_poll_controller(struct net_device *dev) { disable_irq(dev->irq); - xircom_interrupt(dev->irq, dev); + xircom_interrupt(dev->irq, dev, NULL); enable_irq(dev->irq); } #endif diff --git a/trunk/drivers/net/tulip/xircom_tulip_cb.c b/trunk/drivers/net/tulip/xircom_tulip_cb.c index a998c5d0ae9c..312788caa4c6 100644 --- a/trunk/drivers/net/tulip/xircom_tulip_cb.c +++ b/trunk/drivers/net/tulip/xircom_tulip_cb.c @@ -328,7 +328,7 @@ static void xircom_init_ring(struct net_device *dev); static int xircom_start_xmit(struct sk_buff *skb, struct net_device *dev); static int xircom_rx(struct net_device *dev); static void xircom_media_change(struct net_device *dev); -static irqreturn_t xircom_interrupt(int irq, void *dev_instance); +static irqreturn_t xircom_interrupt(int irq, void *dev_instance, struct pt_regs *regs); static int xircom_close(struct net_device *dev); static struct net_device_stats *xircom_get_stats(struct net_device *dev); static int xircom_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); @@ -1044,7 +1044,7 @@ static void check_duplex(struct net_device *dev) /* The interrupt handler does all of the Rx thread work and cleans up after the Tx thread. */ -static irqreturn_t xircom_interrupt(int irq, void *dev_instance) +static irqreturn_t xircom_interrupt(int irq, void *dev_instance, struct pt_regs *regs) { struct net_device *dev = dev_instance; struct xircom_private *tp = netdev_priv(dev); diff --git a/trunk/drivers/net/typhoon.c b/trunk/drivers/net/typhoon.c index 3bf9e630404f..d5c32e9caa97 100644 --- a/trunk/drivers/net/typhoon.c +++ b/trunk/drivers/net/typhoon.c @@ -1826,7 +1826,7 @@ typhoon_poll(struct net_device *dev, int *total_budget) } static irqreturn_t -typhoon_interrupt(int irq, void *dev_instance) +typhoon_interrupt(int irq, void *dev_instance, struct pt_regs *rgs) { struct net_device *dev = (struct net_device *) dev_instance; struct typhoon *tp = dev->priv; diff --git a/trunk/drivers/net/ucc_geth.c b/trunk/drivers/net/ucc_geth.c index b37888011067..700ebd7d1457 100644 --- a/trunk/drivers/net/ucc_geth.c +++ b/trunk/drivers/net/ucc_geth.c @@ -2,11 +2,14 @@ * Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved. * * Author: Shlomi Gridish - * Li Yang * * Description: * QE UCC Gigabit Ethernet Driver * + * Changelog: + * Jul 6, 2006 Li Yang + * - Rearrange code and style fixes + * * 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 @@ -28,9 +31,9 @@ #include #include #include +#include #include -#include #include #include #include @@ -67,7 +70,7 @@ static DEFINE_SPINLOCK(ugeth_lock); -static struct ucc_geth_info ugeth_primary_info = { +static ucc_geth_info_t ugeth_primary_info = { .uf_info = { .bd_mem_part = MEM_PART_SYSTEM, .rtsm = UCC_FAST_SEND_IDLES_BETWEEN_FRAMES, @@ -160,7 +163,7 @@ static struct ucc_geth_info ugeth_primary_info = { .riscRx = QE_RISC_ALLOCATION_RISC1_AND_RISC2, }; -static struct ucc_geth_info ugeth_info[8]; +static ucc_geth_info_t ugeth_info[8]; #ifdef DEBUG static void mem_disp(u8 *addr, int size) @@ -216,8 +219,8 @@ static struct list_head *dequeue(struct list_head *lh) } } -static int get_interface_details(enum enet_interface enet_interface, - enum enet_speed *speed, +static int get_interface_details(enet_interface_e enet_interface, + enet_speed_e *speed, int *r10m, int *rmm, int *rpm, @@ -280,7 +283,7 @@ static int get_interface_details(enum enet_interface enet_interface, return 0; } -static struct sk_buff *get_new_skb(struct ucc_geth_private *ugeth, u8 *bd) +static struct sk_buff *get_new_skb(ucc_geth_private_t *ugeth, u8 *bd) { struct sk_buff *skb = NULL; @@ -300,19 +303,21 @@ static struct sk_buff *get_new_skb(struct ucc_geth_private *ugeth, u8 *bd) skb->dev = ugeth->dev; - out_be32(&((struct qe_bd *)bd)->buf, + BD_BUFFER_SET(bd, dma_map_single(NULL, skb->data, ugeth->ug_info->uf_info.max_rx_buf_length + UCC_GETH_RX_DATA_BUF_ALIGNMENT, DMA_FROM_DEVICE)); - out_be32((u32 *)bd, (R_E | R_I | (in_be32((u32 *)bd) & R_W))); + BD_STATUS_AND_LENGTH_SET(bd, + (R_E | R_I | + (BD_STATUS_AND_LENGTH(bd) & R_W))); return skb; } -static int rx_bd_buffer_set(struct ucc_geth_private *ugeth, u8 rxQ) +static int rx_bd_buffer_set(ucc_geth_private_t *ugeth, u8 rxQ) { u8 *bd; u32 bd_status; @@ -323,7 +328,7 @@ static int rx_bd_buffer_set(struct ucc_geth_private *ugeth, u8 rxQ) i = 0; do { - bd_status = in_be32((u32*)bd); + bd_status = BD_STATUS_AND_LENGTH(bd); skb = get_new_skb(ugeth, bd); if (!skb) /* If can not allocate data buffer, @@ -333,19 +338,19 @@ static int rx_bd_buffer_set(struct ucc_geth_private *ugeth, u8 rxQ) ugeth->rx_skbuff[rxQ][i] = skb; /* advance the BD pointer */ - bd += sizeof(struct qe_bd); + bd += UCC_GETH_SIZE_OF_BD; i++; } while (!(bd_status & R_W)); return 0; } -static int fill_init_enet_entries(struct ucc_geth_private *ugeth, +static int fill_init_enet_entries(ucc_geth_private_t *ugeth, volatile u32 *p_start, u8 num_entries, u32 thread_size, u32 thread_alignment, - enum qe_risc_allocation risc, + qe_risc_allocation_e risc, int skip_page_for_first_entry) { u32 init_enet_offset; @@ -378,10 +383,10 @@ static int fill_init_enet_entries(struct ucc_geth_private *ugeth, return 0; } -static int return_init_enet_entries(struct ucc_geth_private *ugeth, +static int return_init_enet_entries(ucc_geth_private_t *ugeth, volatile u32 *p_start, u8 num_entries, - enum qe_risc_allocation risc, + qe_risc_allocation_e risc, int skip_page_for_first_entry) { u32 init_enet_offset; @@ -411,11 +416,11 @@ static int return_init_enet_entries(struct ucc_geth_private *ugeth, } #ifdef DEBUG -static int dump_init_enet_entries(struct ucc_geth_private *ugeth, +static int dump_init_enet_entries(ucc_geth_private_t *ugeth, volatile u32 *p_start, u8 num_entries, u32 thread_size, - enum qe_risc_allocation risc, + qe_risc_allocation_e risc, int skip_page_for_first_entry) { u32 init_enet_offset; @@ -451,14 +456,14 @@ static int dump_init_enet_entries(struct ucc_geth_private *ugeth, #endif #ifdef CONFIG_UGETH_FILTERING -static struct enet_addr_container *get_enet_addr_container(void) +static enet_addr_container_t *get_enet_addr_container(void) { - struct enet_addr_container *enet_addr_cont; + enet_addr_container_t *enet_addr_cont; /* allocate memory */ - enet_addr_cont = kmalloc(sizeof(struct enet_addr_container), GFP_KERNEL); + enet_addr_cont = kmalloc(sizeof(enet_addr_container_t), GFP_KERNEL); if (!enet_addr_cont) { - ugeth_err("%s: No memory for enet_addr_container object.", + ugeth_err("%s: No memory for enet_addr_container_t object.", __FUNCTION__); return NULL; } @@ -467,43 +472,45 @@ static struct enet_addr_container *get_enet_addr_container(void) } #endif /* CONFIG_UGETH_FILTERING */ -static void put_enet_addr_container(struct enet_addr_container *enet_addr_cont) +static void put_enet_addr_container(enet_addr_container_t *enet_addr_cont) { kfree(enet_addr_cont); } -static int set_mac_addr(__be16 __iomem *reg, u8 *mac) -{ - out_be16(®[0], ((u16)mac[5] << 8) | mac[4]); - out_be16(®[1], ((u16)mac[3] << 8) | mac[2]); - out_be16(®[2], ((u16)mac[1] << 8) | mac[0]); -} - #ifdef CONFIG_UGETH_FILTERING -static int hw_add_addr_in_paddr(struct ucc_geth_private *ugeth, - u8 *p_enet_addr, u8 paddr_num) +static int hw_add_addr_in_paddr(ucc_geth_private_t *ugeth, + enet_addr_t *p_enet_addr, u8 paddr_num) { - struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt; + ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt; if (!(paddr_num < NUM_OF_PADDRS)) { - ugeth_warn("%s: Illegal paddr_num.", __FUNCTION__); + ugeth_warn("%s: Illagel paddr_num.", __FUNCTION__); return -EINVAL; } p_82xx_addr_filt = - (struct ucc_geth_82xx_address_filtering_pram *) ugeth->p_rx_glbl_pram-> + (ucc_geth_82xx_address_filtering_pram_t *) ugeth->p_rx_glbl_pram-> addressfiltering; /* Ethernet frames are defined in Little Endian mode, */ /* therefore to insert the address we reverse the bytes. */ - set_mac_addr(&p_82xx_addr_filt->paddr[paddr_num].h, p_enet_addr); + out_be16(&p_82xx_addr_filt->paddr[paddr_num].h, + (u16) (((u16) (((u16) ((*p_enet_addr)[5])) << 8)) | + (u16) (*p_enet_addr)[4])); + out_be16(&p_82xx_addr_filt->paddr[paddr_num].m, + (u16) (((u16) (((u16) ((*p_enet_addr)[3])) << 8)) | + (u16) (*p_enet_addr)[2])); + out_be16(&p_82xx_addr_filt->paddr[paddr_num].l, + (u16) (((u16) (((u16) ((*p_enet_addr)[1])) << 8)) | + (u16) (*p_enet_addr)[0])); + return 0; } #endif /* CONFIG_UGETH_FILTERING */ -static int hw_clear_addr_in_paddr(struct ucc_geth_private *ugeth, u8 paddr_num) +static int hw_clear_addr_in_paddr(ucc_geth_private_t *ugeth, u8 paddr_num) { - struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt; + ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt; if (!(paddr_num < NUM_OF_PADDRS)) { ugeth_warn("%s: Illagel paddr_num.", __FUNCTION__); @@ -511,7 +518,7 @@ static int hw_clear_addr_in_paddr(struct ucc_geth_private *ugeth, u8 paddr_num) } p_82xx_addr_filt = - (struct ucc_geth_82xx_address_filtering_pram *) ugeth->p_rx_glbl_pram-> + (ucc_geth_82xx_address_filtering_pram_t *) ugeth->p_rx_glbl_pram-> addressfiltering; /* Writing address ff.ff.ff.ff.ff.ff disables address @@ -523,14 +530,14 @@ static int hw_clear_addr_in_paddr(struct ucc_geth_private *ugeth, u8 paddr_num) return 0; } -static void hw_add_addr_in_hash(struct ucc_geth_private *ugeth, - u8 *p_enet_addr) +static void hw_add_addr_in_hash(ucc_geth_private_t *ugeth, + enet_addr_t *p_enet_addr) { - struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt; + ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt; u32 cecr_subblock; p_82xx_addr_filt = - (struct ucc_geth_82xx_address_filtering_pram *) ugeth->p_rx_glbl_pram-> + (ucc_geth_82xx_address_filtering_pram_t *) ugeth->p_rx_glbl_pram-> addressfiltering; cecr_subblock = @@ -539,18 +546,25 @@ static void hw_add_addr_in_hash(struct ucc_geth_private *ugeth, /* Ethernet frames are defined in Little Endian mode, therefor to insert */ /* the address to the hash (Big Endian mode), we reverse the bytes.*/ - - set_mac_addr(&p_82xx_addr_filt->taddr.h, p_enet_addr); + out_be16(&p_82xx_addr_filt->taddr.h, + (u16) (((u16) (((u16) ((*p_enet_addr)[5])) << 8)) | + (u16) (*p_enet_addr)[4])); + out_be16(&p_82xx_addr_filt->taddr.m, + (u16) (((u16) (((u16) ((*p_enet_addr)[3])) << 8)) | + (u16) (*p_enet_addr)[2])); + out_be16(&p_82xx_addr_filt->taddr.l, + (u16) (((u16) (((u16) ((*p_enet_addr)[1])) << 8)) | + (u16) (*p_enet_addr)[0])); qe_issue_cmd(QE_SET_GROUP_ADDRESS, cecr_subblock, - QE_CR_PROTOCOL_ETHERNET, 0); + (u8) QE_CR_PROTOCOL_ETHERNET, 0); } #ifdef CONFIG_UGETH_MAGIC_PACKET -static void magic_packet_detection_enable(struct ucc_geth_private *ugeth) +static void magic_packet_detection_enable(ucc_geth_private_t *ugeth) { - struct ucc_fast_private *uccf; - struct ucc_geth *ug_regs; + ucc_fast_private_t *uccf; + ucc_geth_t *ug_regs; u32 maccfg2, uccm; uccf = ugeth->uccf; @@ -567,10 +581,10 @@ static void magic_packet_detection_enable(struct ucc_geth_private *ugeth) out_be32(&ug_regs->maccfg2, maccfg2); } -static void magic_packet_detection_disable(struct ucc_geth_private *ugeth) +static void magic_packet_detection_disable(ucc_geth_private_t *ugeth) { - struct ucc_fast_private *uccf; - struct ucc_geth *ug_regs; + ucc_fast_private_t *uccf; + ucc_geth_t *ug_regs; u32 maccfg2, uccm; uccf = ugeth->uccf; @@ -588,26 +602,26 @@ static void magic_packet_detection_disable(struct ucc_geth_private *ugeth) } #endif /* MAGIC_PACKET */ -static inline int compare_addr(u8 **addr1, u8 **addr2) +static inline int compare_addr(enet_addr_t *addr1, enet_addr_t *addr2) { return memcmp(addr1, addr2, ENET_NUM_OCTETS_PER_ADDRESS); } #ifdef DEBUG -static void get_statistics(struct ucc_geth_private *ugeth, - struct ucc_geth_tx_firmware_statistics * +static void get_statistics(ucc_geth_private_t *ugeth, + ucc_geth_tx_firmware_statistics_t * tx_firmware_statistics, - struct ucc_geth_rx_firmware_statistics * + ucc_geth_rx_firmware_statistics_t * rx_firmware_statistics, - struct ucc_geth_hardware_statistics *hardware_statistics) + ucc_geth_hardware_statistics_t *hardware_statistics) { - struct ucc_fast *uf_regs; - struct ucc_geth *ug_regs; - struct ucc_geth_tx_firmware_statistics_pram *p_tx_fw_statistics_pram; - struct ucc_geth_rx_firmware_statistics_pram *p_rx_fw_statistics_pram; + ucc_fast_t *uf_regs; + ucc_geth_t *ug_regs; + ucc_geth_tx_firmware_statistics_pram_t *p_tx_fw_statistics_pram; + ucc_geth_rx_firmware_statistics_pram_t *p_rx_fw_statistics_pram; ug_regs = ugeth->ug_regs; - uf_regs = (struct ucc_fast *) ug_regs; + uf_regs = (ucc_fast_t *) ug_regs; p_tx_fw_statistics_pram = ugeth->p_tx_fw_statistics_pram; p_rx_fw_statistics_pram = ugeth->p_rx_fw_statistics_pram; @@ -713,7 +727,7 @@ static void get_statistics(struct ucc_geth_private *ugeth, } } -static void dump_bds(struct ucc_geth_private *ugeth) +static void dump_bds(ucc_geth_private_t *ugeth) { int i; int length; @@ -722,7 +736,7 @@ static void dump_bds(struct ucc_geth_private *ugeth) if (ugeth->p_tx_bd_ring[i]) { length = (ugeth->ug_info->bdRingLenTx[i] * - sizeof(struct qe_bd)); + UCC_GETH_SIZE_OF_BD); ugeth_info("TX BDs[%d]", i); mem_disp(ugeth->p_tx_bd_ring[i], length); } @@ -731,14 +745,14 @@ static void dump_bds(struct ucc_geth_private *ugeth) if (ugeth->p_rx_bd_ring[i]) { length = (ugeth->ug_info->bdRingLenRx[i] * - sizeof(struct qe_bd)); + UCC_GETH_SIZE_OF_BD); ugeth_info("RX BDs[%d]", i); mem_disp(ugeth->p_rx_bd_ring[i], length); } } } -static void dump_regs(struct ucc_geth_private *ugeth) +static void dump_regs(ucc_geth_private_t *ugeth) { int i; @@ -879,7 +893,7 @@ static void dump_regs(struct ucc_geth_private *ugeth) ugeth_info("Base address: 0x%08x", (u32) & ugeth->p_thread_data_tx[i]); mem_disp((u8 *) & ugeth->p_thread_data_tx[i], - sizeof(struct ucc_geth_thread_data_tx)); + sizeof(ucc_geth_thread_data_tx_t)); } } if (ugeth->p_thread_data_rx) { @@ -913,7 +927,7 @@ static void dump_regs(struct ucc_geth_private *ugeth) ugeth_info("Base address: 0x%08x", (u32) & ugeth->p_thread_data_rx[i]); mem_disp((u8 *) & ugeth->p_thread_data_rx[i], - sizeof(struct ucc_geth_thread_data_rx)); + sizeof(ucc_geth_thread_data_rx_t)); } } if (ugeth->p_exf_glbl_param) { @@ -1091,7 +1105,7 @@ static void dump_regs(struct ucc_geth_private *ugeth) ugeth_info("Base address: 0x%08x", (u32) & ugeth->p_send_q_mem_reg->sqqd[i]); mem_disp((u8 *) & ugeth->p_send_q_mem_reg->sqqd[i], - sizeof(struct ucc_geth_send_queue_qd)); + sizeof(ucc_geth_send_queue_qd_t)); } } if (ugeth->p_scheduler) { @@ -1173,7 +1187,7 @@ static void dump_regs(struct ucc_geth_private *ugeth) qe_muram_addr(in_be32 (&ugeth->p_rx_bd_qs_tbl[i]. bdbaseptr)), - sizeof(struct ucc_geth_rx_prefetched_bds)); + sizeof(ucc_geth_rx_prefetched_bds_t)); } } if (ugeth->p_init_enet_param_shadow) { @@ -1184,7 +1198,7 @@ static void dump_regs(struct ucc_geth_private *ugeth) mem_disp((u8 *) ugeth->p_init_enet_param_shadow, sizeof(*ugeth->p_init_enet_param_shadow)); - size = sizeof(struct ucc_geth_thread_rx_pram); + size = sizeof(ucc_geth_thread_rx_pram_t); if (ugeth->ug_info->rxExtendedFiltering) { size += THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING; @@ -1202,7 +1216,7 @@ static void dump_regs(struct ucc_geth_private *ugeth) &(ugeth->p_init_enet_param_shadow-> txthread[0]), ENET_INIT_PARAM_MAX_ENTRIES_TX, - sizeof(struct ucc_geth_thread_tx_pram), + sizeof(ucc_geth_thread_tx_pram_t), ugeth->ug_info->riscTx, 0); dump_init_enet_entries(ugeth, &(ugeth->p_init_enet_param_shadow-> @@ -1564,12 +1578,12 @@ static int init_min_frame_len(u16 min_frame_length, return 0; } -static int adjust_enet_interface(struct ucc_geth_private *ugeth) +static int adjust_enet_interface(ucc_geth_private_t *ugeth) { - struct ucc_geth_info *ug_info; - struct ucc_geth *ug_regs; - struct ucc_fast *uf_regs; - enum enet_speed speed; + ucc_geth_info_t *ug_info; + ucc_geth_t *ug_regs; + ucc_fast_t *uf_regs; + enet_speed_e speed; int ret_val, rpm = 0, tbi = 0, r10m = 0, rmm = 0, limited_to_full_duplex = 0; u32 upsmr, maccfg2, utbipar, tbiBaseAddress; @@ -1677,8 +1691,8 @@ static int adjust_enet_interface(struct ucc_geth_private *ugeth) */ static void adjust_link(struct net_device *dev) { - struct ucc_geth_private *ugeth = netdev_priv(dev); - struct ucc_geth *ug_regs; + ucc_geth_private_t *ugeth = netdev_priv(dev); + ucc_geth_t *ug_regs; u32 tempval; struct ugeth_mii_info *mii_info = ugeth->mii_info; @@ -1708,7 +1722,7 @@ static void adjust_link(struct net_device *dev) if (mii_info->speed != ugeth->oldspeed) { switch (mii_info->speed) { case 1000: -#ifdef CONFIG_PPC_MPC836x +#ifdef CONFIG_MPC836x /* FIXME: This code is for 100Mbs BUG fixing, remove this when it is fixed!!! */ if (ugeth->ug_info->enet_interface == @@ -1754,7 +1768,7 @@ remove this when it is fixed!!! */ break; case 100: case 10: -#ifdef CONFIG_PPC_MPC836x +#ifdef CONFIG_MPC836x /* FIXME: This code is for 100Mbs BUG fixing, remove this lines when it will be fixed!!! */ ugeth->ug_info->enet_interface = ENET_100_RGMII; @@ -1813,9 +1827,9 @@ remove this lines when it will be fixed!!! */ */ static int init_phy(struct net_device *dev) { - struct ucc_geth_private *ugeth = netdev_priv(dev); + ucc_geth_private_t *ugeth = netdev_priv(dev); struct phy_info *curphy; - struct ucc_mii_mng *mii_regs; + ucc_mii_mng_t *mii_regs; struct ugeth_mii_info *mii_info; int err; @@ -1900,17 +1914,17 @@ static int init_phy(struct net_device *dev) } #ifdef CONFIG_UGETH_TX_ON_DEMOND -static int ugeth_transmit_on_demand(struct ucc_geth_private *ugeth) +static int ugeth_transmit_on_demand(ucc_geth_private_t *ugeth) { - struct ucc_fastransmit_on_demand(ugeth->uccf); + ucc_fast_transmit_on_demand(ugeth->uccf); return 0; } #endif -static int ugeth_graceful_stop_tx(struct ucc_geth_private *ugeth) +static int ugeth_graceful_stop_tx(ucc_geth_private_t *ugeth) { - struct ucc_fast_private *uccf; + ucc_fast_private_t *uccf; u32 cecr_subblock; u32 temp; @@ -1926,7 +1940,7 @@ static int ugeth_graceful_stop_tx(struct ucc_geth_private *ugeth) cecr_subblock = ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num); qe_issue_cmd(QE_GRACEFUL_STOP_TX, cecr_subblock, - QE_CR_PROTOCOL_ETHERNET, 0); + (u8) QE_CR_PROTOCOL_ETHERNET, 0); /* Wait for command to complete */ do { @@ -1938,9 +1952,9 @@ static int ugeth_graceful_stop_tx(struct ucc_geth_private *ugeth) return 0; } -static int ugeth_graceful_stop_rx(struct ucc_geth_private * ugeth) +static int ugeth_graceful_stop_rx(ucc_geth_private_t * ugeth) { - struct ucc_fast_private *uccf; + ucc_fast_private_t *uccf; u32 cecr_subblock; u8 temp; @@ -1959,7 +1973,7 @@ static int ugeth_graceful_stop_rx(struct ucc_geth_private * ugeth) ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info. ucc_num); qe_issue_cmd(QE_GRACEFUL_STOP_RX, cecr_subblock, - QE_CR_PROTOCOL_ETHERNET, 0); + (u8) QE_CR_PROTOCOL_ETHERNET, 0); temp = ugeth->p_rx_glbl_pram->rxgstpack; } while (!(temp & GRACEFUL_STOP_ACKNOWLEDGE_RX)); @@ -1969,40 +1983,41 @@ static int ugeth_graceful_stop_rx(struct ucc_geth_private * ugeth) return 0; } -static int ugeth_restart_tx(struct ucc_geth_private *ugeth) +static int ugeth_restart_tx(ucc_geth_private_t *ugeth) { - struct ucc_fast_private *uccf; + ucc_fast_private_t *uccf; u32 cecr_subblock; uccf = ugeth->uccf; cecr_subblock = ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num); - qe_issue_cmd(QE_RESTART_TX, cecr_subblock, QE_CR_PROTOCOL_ETHERNET, 0); + qe_issue_cmd(QE_RESTART_TX, cecr_subblock, (u8) QE_CR_PROTOCOL_ETHERNET, + 0); uccf->stopped_tx = 0; return 0; } -static int ugeth_restart_rx(struct ucc_geth_private *ugeth) +static int ugeth_restart_rx(ucc_geth_private_t *ugeth) { - struct ucc_fast_private *uccf; + ucc_fast_private_t *uccf; u32 cecr_subblock; uccf = ugeth->uccf; cecr_subblock = ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num); - qe_issue_cmd(QE_RESTART_RX, cecr_subblock, QE_CR_PROTOCOL_ETHERNET, + qe_issue_cmd(QE_RESTART_RX, cecr_subblock, (u8) QE_CR_PROTOCOL_ETHERNET, 0); uccf->stopped_rx = 0; return 0; } -static int ugeth_enable(struct ucc_geth_private *ugeth, enum comm_dir mode) +static int ugeth_enable(ucc_geth_private_t *ugeth, comm_dir_e mode) { - struct ucc_fast_private *uccf; + ucc_fast_private_t *uccf; int enabled_tx, enabled_rx; uccf = ugeth->uccf; @@ -2029,9 +2044,9 @@ static int ugeth_enable(struct ucc_geth_private *ugeth, enum comm_dir mode) } -static int ugeth_disable(struct ucc_geth_private * ugeth, enum comm_dir mode) +static int ugeth_disable(ucc_geth_private_t * ugeth, comm_dir_e mode) { - struct ucc_fast_private *uccf; + ucc_fast_private_t *uccf; uccf = ugeth->uccf; @@ -2054,7 +2069,7 @@ static int ugeth_disable(struct ucc_geth_private * ugeth, enum comm_dir mode) return 0; } -static void ugeth_dump_regs(struct ucc_geth_private *ugeth) +static void ugeth_dump_regs(ucc_geth_private_t *ugeth) { #ifdef DEBUG ucc_fast_dump_regs(ugeth->uccf); @@ -2064,9 +2079,9 @@ static void ugeth_dump_regs(struct ucc_geth_private *ugeth) } #ifdef CONFIG_UGETH_FILTERING -static int ugeth_ext_filtering_serialize_tad(struct ucc_geth_tad_params * +static int ugeth_ext_filtering_serialize_tad(ucc_geth_tad_params_t * p_UccGethTadParams, - struct qe_fltr_tad *qe_fltr_tad) + qe_fltr_tad_t *qe_fltr_tad) { u16 temp; @@ -2104,11 +2119,11 @@ static int ugeth_ext_filtering_serialize_tad(struct ucc_geth_tad_params * return 0; } -static struct enet_addr_container_t - *ugeth_82xx_filtering_get_match_addr_in_hash(struct ucc_geth_private *ugeth, - struct enet_addr *p_enet_addr) +static enet_addr_container_t + *ugeth_82xx_filtering_get_match_addr_in_hash(ucc_geth_private_t *ugeth, + enet_addr_t *p_enet_addr) { - struct enet_addr_container *enet_addr_cont; + enet_addr_container_t *enet_addr_cont; struct list_head *p_lh; u16 i, num; int32_t j; @@ -2129,7 +2144,7 @@ static struct enet_addr_container_t for (i = 0; i < num; i++) { enet_addr_cont = - (struct enet_addr_container *) + (enet_addr_container_t *) ENET_ADDR_CONT_ENTRY(dequeue(p_lh)); for (j = ENET_NUM_OCTETS_PER_ADDRESS - 1; j >= 0; j--) { if ((*p_enet_addr)[j] != (enet_addr_cont->address)[j]) @@ -2142,11 +2157,11 @@ static struct enet_addr_container_t return NULL; } -static int ugeth_82xx_filtering_add_addr_in_hash(struct ucc_geth_private *ugeth, - struct enet_addr *p_enet_addr) +static int ugeth_82xx_filtering_add_addr_in_hash(ucc_geth_private_t *ugeth, + enet_addr_t *p_enet_addr) { - enum ucc_geth_enet_address_recognition_location location; - struct enet_addr_container *enet_addr_cont; + ucc_geth_enet_address_recognition_location_e location; + enet_addr_container_t *enet_addr_cont; struct list_head *p_lh; u8 i; u32 limit; @@ -2181,17 +2196,18 @@ static int ugeth_82xx_filtering_add_addr_in_hash(struct ucc_geth_private *ugeth, enqueue(p_lh, &enet_addr_cont->node); /* Put it back */ ++(*p_counter); - hw_add_addr_in_hash(ugeth, enet_addr_cont->address); + hw_add_addr_in_hash(ugeth, &(enet_addr_cont->address)); + return 0; } -static int ugeth_82xx_filtering_clear_addr_in_hash(struct ucc_geth_private *ugeth, - struct enet_addr *p_enet_addr) +static int ugeth_82xx_filtering_clear_addr_in_hash(ucc_geth_private_t *ugeth, + enet_addr_t *p_enet_addr) { - struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt; - struct enet_addr_container *enet_addr_cont; - struct ucc_fast_private *uccf; - enum comm_dir comm_dir; + ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt; + enet_addr_container_t *enet_addr_cont; + ucc_fast_private_t *uccf; + comm_dir_e comm_dir; u16 i, num; struct list_head *p_lh; u32 *addr_h, *addr_l; @@ -2200,7 +2216,7 @@ static int ugeth_82xx_filtering_clear_addr_in_hash(struct ucc_geth_private *uget uccf = ugeth->uccf; p_82xx_addr_filt = - (struct ucc_geth_82xx_address_filtering_pram *) ugeth->p_rx_glbl_pram-> + (ucc_geth_82xx_address_filtering_pram_t *) ugeth->p_rx_glbl_pram-> addressfiltering; if (! @@ -2240,9 +2256,9 @@ static int ugeth_82xx_filtering_clear_addr_in_hash(struct ucc_geth_private *uget num = --(*p_counter); for (i = 0; i < num; i++) { enet_addr_cont = - (struct enet_addr_container *) + (enet_addr_container_t *) ENET_ADDR_CONT_ENTRY(dequeue(p_lh)); - hw_add_addr_in_hash(ugeth, enet_addr_cont->address); + hw_add_addr_in_hash(ugeth, &(enet_addr_cont->address)); enqueue(p_lh, &enet_addr_cont->node); /* Put it back */ } @@ -2253,14 +2269,14 @@ static int ugeth_82xx_filtering_clear_addr_in_hash(struct ucc_geth_private *uget } #endif /* CONFIG_UGETH_FILTERING */ -static int ugeth_82xx_filtering_clear_all_addr_in_hash(struct ucc_geth_private * +static int ugeth_82xx_filtering_clear_all_addr_in_hash(ucc_geth_private_t * ugeth, - enum enet_addr_type + enet_addr_type_e enet_addr_type) { - struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt; - struct ucc_fast_private *uccf; - enum comm_dir comm_dir; + ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt; + ucc_fast_private_t *uccf; + comm_dir_e comm_dir; struct list_head *p_lh; u16 i, num; u32 *addr_h, *addr_l; @@ -2269,7 +2285,7 @@ static int ugeth_82xx_filtering_clear_all_addr_in_hash(struct ucc_geth_private * uccf = ugeth->uccf; p_82xx_addr_filt = - (struct ucc_geth_82xx_address_filtering_pram *) ugeth->p_rx_glbl_pram-> + (ucc_geth_82xx_address_filtering_pram_t *) ugeth->p_rx_glbl_pram-> addressfiltering; if (enet_addr_type == ENET_ADDR_TYPE_GROUP) { @@ -2315,8 +2331,8 @@ static int ugeth_82xx_filtering_clear_all_addr_in_hash(struct ucc_geth_private * } #ifdef CONFIG_UGETH_FILTERING -static int ugeth_82xx_filtering_add_addr_in_paddr(struct ucc_geth_private *ugeth, - struct enet_addr *p_enet_addr, +static int ugeth_82xx_filtering_add_addr_in_paddr(ucc_geth_private_t *ugeth, + enet_addr_t *p_enet_addr, u8 paddr_num) { int i; @@ -2336,14 +2352,14 @@ static int ugeth_82xx_filtering_add_addr_in_paddr(struct ucc_geth_private *ugeth } #endif /* CONFIG_UGETH_FILTERING */ -static int ugeth_82xx_filtering_clear_addr_in_paddr(struct ucc_geth_private *ugeth, +static int ugeth_82xx_filtering_clear_addr_in_paddr(ucc_geth_private_t *ugeth, u8 paddr_num) { ugeth->indAddrRegUsed[paddr_num] = 0; /* mark this paddr as not used */ return hw_clear_addr_in_paddr(ugeth, paddr_num);/* clear in hardware */ } -static void ucc_geth_memclean(struct ucc_geth_private *ugeth) +static void ucc_geth_memclean(ucc_geth_private_t *ugeth) { u16 i, j; u8 *bd; @@ -2417,8 +2433,8 @@ static void ucc_geth_memclean(struct ucc_geth_private *ugeth) for (j = 0; j < ugeth->ug_info->bdRingLenTx[i]; j++) { if (ugeth->tx_skbuff[i][j]) { dma_unmap_single(NULL, - ((qe_bd_t *)bd)->buf, - (in_be32((u32 *)bd) & + BD_BUFFER_ARG(bd), + (BD_STATUS_AND_LENGTH(bd) & BD_LENGTH_MASK), DMA_TO_DEVICE); dev_kfree_skb_any(ugeth->tx_skbuff[i][j]); @@ -2444,17 +2460,18 @@ static void ucc_geth_memclean(struct ucc_geth_private *ugeth) bd = ugeth->p_rx_bd_ring[i]; for (j = 0; j < ugeth->ug_info->bdRingLenRx[i]; j++) { if (ugeth->rx_skbuff[i][j]) { - dma_unmap_single(NULL, - ((struct qe_bd *)bd)->buf, - ugeth->ug_info-> - uf_info.max_rx_buf_length + - UCC_GETH_RX_DATA_BUF_ALIGNMENT, - DMA_FROM_DEVICE); - dev_kfree_skb_any( - ugeth->rx_skbuff[i][j]); + dma_unmap_single(NULL, BD_BUFFER(bd), + ugeth->ug_info-> + uf_info. + max_rx_buf_length + + UCC_GETH_RX_DATA_BUF_ALIGNMENT, + DMA_FROM_DEVICE); + + dev_kfree_skb_any(ugeth-> + rx_skbuff[i][j]); ugeth->rx_skbuff[i][j] = NULL; } - bd += sizeof(struct qe_bd); + bd += UCC_GETH_SIZE_OF_BD; } kfree(ugeth->rx_skbuff[i]); @@ -2479,11 +2496,11 @@ static void ucc_geth_memclean(struct ucc_geth_private *ugeth) static void ucc_geth_set_multi(struct net_device *dev) { - struct ucc_geth_private *ugeth; + ucc_geth_private_t *ugeth; struct dev_mc_list *dmi; - struct ucc_fast *uf_regs; - struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt; - u8 tempaddr[6]; + ucc_fast_t *uf_regs; + ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt; + enet_addr_t tempaddr; u8 *mcptr, *tdptr; int i, j; @@ -2500,7 +2517,7 @@ static void ucc_geth_set_multi(struct net_device *dev) uf_regs->upsmr &= ~UPSMR_PRO; p_82xx_addr_filt = - (struct ucc_geth_82xx_address_filtering_pram *) ugeth-> + (ucc_geth_82xx_address_filtering_pram_t *) ugeth-> p_rx_glbl_pram->addressfiltering; if (dev->flags & IFF_ALLMULTI) { @@ -2529,22 +2546,23 @@ static void ucc_geth_set_multi(struct net_device *dev) * copy bytes MSB first from dmi_addr. */ mcptr = (u8 *) dmi->dmi_addr + 5; - tdptr = (u8 *) tempaddr; + tdptr = (u8 *) & tempaddr; for (j = 0; j < 6; j++) *tdptr++ = *mcptr--; /* Ask CPM to run CRC and set bit in * filter mask. */ - hw_add_addr_in_hash(ugeth, tempaddr); + hw_add_addr_in_hash(ugeth, &tempaddr); + } } } } -static void ucc_geth_stop(struct ucc_geth_private *ugeth) +static void ucc_geth_stop(ucc_geth_private_t *ugeth) { - struct ucc_geth *ug_regs = ugeth->ug_regs; + ucc_geth_t *ug_regs = ugeth->ug_regs; u32 tempval; ugeth_vdbg("%s: IN", __FUNCTION__); @@ -2587,15 +2605,15 @@ static void ucc_geth_stop(struct ucc_geth_private *ugeth) ucc_geth_memclean(ugeth); } -static int ucc_geth_startup(struct ucc_geth_private *ugeth) +static int ucc_geth_startup(ucc_geth_private_t *ugeth) { - struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt; - struct ucc_geth_init_pram *p_init_enet_pram; - struct ucc_fast_private *uccf; - struct ucc_geth_info *ug_info; - struct ucc_fast_info *uf_info; - struct ucc_fast *uf_regs; - struct ucc_geth *ug_regs; + ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt; + ucc_geth_init_pram_t *p_init_enet_pram; + ucc_fast_private_t *uccf; + ucc_geth_info_t *ug_info; + ucc_fast_info_t *uf_info; + ucc_fast_t *uf_regs; + ucc_geth_t *ug_regs; int ret_val = -EINVAL; u32 remoder = UCC_GETH_REMODER_INIT; u32 init_enet_pram_offset, cecr_subblock, command, maccfg1; @@ -2770,7 +2788,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) UCC_GETH_VLAN_OPERATION_NON_TAGGED_NOP); uf_regs = uccf->uf_regs; - ug_regs = (struct ucc_geth *) (uccf->uf_regs); + ug_regs = (ucc_geth_t *) (uccf->uf_regs); ugeth->ug_regs = ug_regs; init_default_reg_vals(&uf_regs->upsmr, @@ -2851,10 +2869,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) /* Allocate in multiple of UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT, according to spec */ - length = ((ug_info->bdRingLenTx[j] * sizeof(struct qe_bd)) + length = ((ug_info->bdRingLenTx[j] * UCC_GETH_SIZE_OF_BD) / UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT) * UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT; - if ((ug_info->bdRingLenTx[j] * sizeof(struct qe_bd)) % + if ((ug_info->bdRingLenTx[j] * UCC_GETH_SIZE_OF_BD) % UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT) length += UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT; if (uf_info->bd_mem_part == MEM_PART_SYSTEM) { @@ -2886,13 +2904,13 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) } /* Zero unused end of bd ring, according to spec */ memset(ugeth->p_tx_bd_ring[j] + - ug_info->bdRingLenTx[j] * sizeof(struct qe_bd), 0, - length - ug_info->bdRingLenTx[j] * sizeof(struct qe_bd)); + ug_info->bdRingLenTx[j] * UCC_GETH_SIZE_OF_BD, 0, + length - ug_info->bdRingLenTx[j] * UCC_GETH_SIZE_OF_BD); } /* Allocate Rx bds */ for (j = 0; j < ug_info->numQueuesRx; j++) { - length = ug_info->bdRingLenRx[j] * sizeof(struct qe_bd); + length = ug_info->bdRingLenRx[j] * UCC_GETH_SIZE_OF_BD; if (uf_info->bd_mem_part == MEM_PART_SYSTEM) { u32 align = 4; if (UCC_GETH_RX_BD_RING_ALIGNMENT > 4) @@ -2942,15 +2960,12 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) ugeth->skb_curtx[j] = ugeth->skb_dirtytx[j] = 0; bd = ugeth->confBd[j] = ugeth->txBd[j] = ugeth->p_tx_bd_ring[j]; for (i = 0; i < ug_info->bdRingLenTx[j]; i++) { - /* clear bd buffer */ - out_be32(&((struct qe_bd *)bd)->buf, 0); - /* set bd status and length */ - out_be32((u32 *)bd, 0); - bd += sizeof(struct qe_bd); + BD_BUFFER_CLEAR(bd); + BD_STATUS_AND_LENGTH_SET(bd, 0); + bd += UCC_GETH_SIZE_OF_BD; } - bd -= sizeof(struct qe_bd); - /* set bd status and length */ - out_be32((u32 *)bd, T_W); /* for last BD set Wrap bit */ + bd -= UCC_GETH_SIZE_OF_BD; + BD_STATUS_AND_LENGTH_SET(bd, T_W);/* for last BD set Wrap bit */ } /* Init Rx bds */ @@ -2974,15 +2989,12 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) ugeth->skb_currx[j] = 0; bd = ugeth->rxBd[j] = ugeth->p_rx_bd_ring[j]; for (i = 0; i < ug_info->bdRingLenRx[j]; i++) { - /* set bd status and length */ - out_be32((u32 *)bd, R_I); - /* clear bd buffer */ - out_be32(&((struct qe_bd *)bd)->buf, 0); - bd += sizeof(struct qe_bd); + BD_STATUS_AND_LENGTH_SET(bd, R_I); + BD_BUFFER_CLEAR(bd); + bd += UCC_GETH_SIZE_OF_BD; } - bd -= sizeof(struct qe_bd); - /* set bd status and length */ - out_be32((u32 *)bd, R_W); /* for last BD set Wrap bit */ + bd -= UCC_GETH_SIZE_OF_BD; + BD_STATUS_AND_LENGTH_SET(bd, R_W);/* for last BD set Wrap bit */ } /* @@ -2991,7 +3003,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) /* Tx global PRAM */ /* Allocate global tx parameter RAM page */ ugeth->tx_glbl_pram_offset = - qe_muram_alloc(sizeof(struct ucc_geth_tx_global_pram), + qe_muram_alloc(sizeof(ucc_geth_tx_global_pram_t), UCC_GETH_TX_GLOBAL_PRAM_ALIGNMENT); if (IS_MURAM_ERR(ugeth->tx_glbl_pram_offset)) { ugeth_err @@ -3001,10 +3013,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) return -ENOMEM; } ugeth->p_tx_glbl_pram = - (struct ucc_geth_tx_global_pram *) qe_muram_addr(ugeth-> + (ucc_geth_tx_global_pram_t *) qe_muram_addr(ugeth-> tx_glbl_pram_offset); /* Zero out p_tx_glbl_pram */ - memset(ugeth->p_tx_glbl_pram, 0, sizeof(struct ucc_geth_tx_global_pram)); + memset(ugeth->p_tx_glbl_pram, 0, sizeof(ucc_geth_tx_global_pram_t)); /* Fill global PRAM */ @@ -3012,7 +3024,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) /* Size varies with number of Tx threads */ ugeth->thread_dat_tx_offset = qe_muram_alloc(numThreadsTxNumerical * - sizeof(struct ucc_geth_thread_data_tx) + + sizeof(ucc_geth_thread_data_tx_t) + 32 * (numThreadsTxNumerical == 1), UCC_GETH_THREAD_DATA_ALIGNMENT); if (IS_MURAM_ERR(ugeth->thread_dat_tx_offset)) { @@ -3024,7 +3036,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) } ugeth->p_thread_data_tx = - (struct ucc_geth_thread_data_tx *) qe_muram_addr(ugeth-> + (ucc_geth_thread_data_tx_t *) qe_muram_addr(ugeth-> thread_dat_tx_offset); out_be32(&ugeth->p_tx_glbl_pram->tqptr, ugeth->thread_dat_tx_offset); @@ -3041,7 +3053,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) /* Size varies with number of Tx queues */ ugeth->send_q_mem_reg_offset = qe_muram_alloc(ug_info->numQueuesTx * - sizeof(struct ucc_geth_send_queue_qd), + sizeof(ucc_geth_send_queue_qd_t), UCC_GETH_SEND_QUEUE_QUEUE_DESCRIPTOR_ALIGNMENT); if (IS_MURAM_ERR(ugeth->send_q_mem_reg_offset)) { ugeth_err @@ -3052,7 +3064,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) } ugeth->p_send_q_mem_reg = - (struct ucc_geth_send_queue_mem_region *) qe_muram_addr(ugeth-> + (ucc_geth_send_queue_mem_region_t *) qe_muram_addr(ugeth-> send_q_mem_reg_offset); out_be32(&ugeth->p_tx_glbl_pram->sqptr, ugeth->send_q_mem_reg_offset); @@ -3061,7 +3073,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) for (i = 0; i < ug_info->numQueuesTx; i++) { endOfRing = ugeth->p_tx_bd_ring[i] + (ug_info->bdRingLenTx[i] - - 1) * sizeof(struct qe_bd); + 1) * UCC_GETH_SIZE_OF_BD; if (ugeth->ug_info->uf_info.bd_mem_part == MEM_PART_SYSTEM) { out_be32(&ugeth->p_send_q_mem_reg->sqqd[i].bd_ring_base, (u32) virt_to_phys(ugeth->p_tx_bd_ring[i])); @@ -3084,7 +3096,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) if (ug_info->numQueuesTx > 1) { /* scheduler exists only if more than 1 tx queue */ ugeth->scheduler_offset = - qe_muram_alloc(sizeof(struct ucc_geth_scheduler), + qe_muram_alloc(sizeof(ucc_geth_scheduler_t), UCC_GETH_SCHEDULER_ALIGNMENT); if (IS_MURAM_ERR(ugeth->scheduler_offset)) { ugeth_err @@ -3095,12 +3107,12 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) } ugeth->p_scheduler = - (struct ucc_geth_scheduler *) qe_muram_addr(ugeth-> + (ucc_geth_scheduler_t *) qe_muram_addr(ugeth-> scheduler_offset); out_be32(&ugeth->p_tx_glbl_pram->schedulerbasepointer, ugeth->scheduler_offset); /* Zero out p_scheduler */ - memset(ugeth->p_scheduler, 0, sizeof(struct ucc_geth_scheduler)); + memset(ugeth->p_scheduler, 0, sizeof(ucc_geth_scheduler_t)); /* Set values in scheduler */ out_be32(&ugeth->p_scheduler->mblinterval, @@ -3132,7 +3144,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) statisticsMode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_TX) { ugeth->tx_fw_statistics_pram_offset = qe_muram_alloc(sizeof - (struct ucc_geth_tx_firmware_statistics_pram), + (ucc_geth_tx_firmware_statistics_pram_t), UCC_GETH_TX_STATISTICS_ALIGNMENT); if (IS_MURAM_ERR(ugeth->tx_fw_statistics_pram_offset)) { ugeth_err @@ -3142,11 +3154,11 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) return -ENOMEM; } ugeth->p_tx_fw_statistics_pram = - (struct ucc_geth_tx_firmware_statistics_pram *) + (ucc_geth_tx_firmware_statistics_pram_t *) qe_muram_addr(ugeth->tx_fw_statistics_pram_offset); /* Zero out p_tx_fw_statistics_pram */ memset(ugeth->p_tx_fw_statistics_pram, - 0, sizeof(struct ucc_geth_tx_firmware_statistics_pram)); + 0, sizeof(ucc_geth_tx_firmware_statistics_pram_t)); } /* temoder */ @@ -3171,7 +3183,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) /* Rx global PRAM */ /* Allocate global rx parameter RAM page */ ugeth->rx_glbl_pram_offset = - qe_muram_alloc(sizeof(struct ucc_geth_rx_global_pram), + qe_muram_alloc(sizeof(ucc_geth_rx_global_pram_t), UCC_GETH_RX_GLOBAL_PRAM_ALIGNMENT); if (IS_MURAM_ERR(ugeth->rx_glbl_pram_offset)) { ugeth_err @@ -3181,10 +3193,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) return -ENOMEM; } ugeth->p_rx_glbl_pram = - (struct ucc_geth_rx_global_pram *) qe_muram_addr(ugeth-> + (ucc_geth_rx_global_pram_t *) qe_muram_addr(ugeth-> rx_glbl_pram_offset); /* Zero out p_rx_glbl_pram */ - memset(ugeth->p_rx_glbl_pram, 0, sizeof(struct ucc_geth_rx_global_pram)); + memset(ugeth->p_rx_glbl_pram, 0, sizeof(ucc_geth_rx_global_pram_t)); /* Fill global PRAM */ @@ -3192,7 +3204,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) /* Size varies with number of Rx threads */ ugeth->thread_dat_rx_offset = qe_muram_alloc(numThreadsRxNumerical * - sizeof(struct ucc_geth_thread_data_rx), + sizeof(ucc_geth_thread_data_rx_t), UCC_GETH_THREAD_DATA_ALIGNMENT); if (IS_MURAM_ERR(ugeth->thread_dat_rx_offset)) { ugeth_err @@ -3203,7 +3215,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) } ugeth->p_thread_data_rx = - (struct ucc_geth_thread_data_rx *) qe_muram_addr(ugeth-> + (ucc_geth_thread_data_rx_t *) qe_muram_addr(ugeth-> thread_dat_rx_offset); out_be32(&ugeth->p_rx_glbl_pram->rqptr, ugeth->thread_dat_rx_offset); @@ -3215,7 +3227,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) statisticsMode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_RX) { ugeth->rx_fw_statistics_pram_offset = qe_muram_alloc(sizeof - (struct ucc_geth_rx_firmware_statistics_pram), + (ucc_geth_rx_firmware_statistics_pram_t), UCC_GETH_RX_STATISTICS_ALIGNMENT); if (IS_MURAM_ERR(ugeth->rx_fw_statistics_pram_offset)) { ugeth_err @@ -3225,11 +3237,11 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) return -ENOMEM; } ugeth->p_rx_fw_statistics_pram = - (struct ucc_geth_rx_firmware_statistics_pram *) + (ucc_geth_rx_firmware_statistics_pram_t *) qe_muram_addr(ugeth->rx_fw_statistics_pram_offset); /* Zero out p_rx_fw_statistics_pram */ memset(ugeth->p_rx_fw_statistics_pram, 0, - sizeof(struct ucc_geth_rx_firmware_statistics_pram)); + sizeof(ucc_geth_rx_firmware_statistics_pram_t)); } /* intCoalescingPtr */ @@ -3237,7 +3249,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) /* Size varies with number of Rx queues */ ugeth->rx_irq_coalescing_tbl_offset = qe_muram_alloc(ug_info->numQueuesRx * - sizeof(struct ucc_geth_rx_interrupt_coalescing_entry), + sizeof(ucc_geth_rx_interrupt_coalescing_entry_t), UCC_GETH_RX_INTERRUPT_COALESCING_ALIGNMENT); if (IS_MURAM_ERR(ugeth->rx_irq_coalescing_tbl_offset)) { ugeth_err @@ -3248,7 +3260,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) } ugeth->p_rx_irq_coalescing_tbl = - (struct ucc_geth_rx_interrupt_coalescing_table *) + (ucc_geth_rx_interrupt_coalescing_table_t *) qe_muram_addr(ugeth->rx_irq_coalescing_tbl_offset); out_be32(&ugeth->p_rx_glbl_pram->intcoalescingptr, ugeth->rx_irq_coalescing_tbl_offset); @@ -3288,7 +3300,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) l3qt = 0; for (i = 0; i < 8; i++) l3qt |= (ug_info->l3qt[j + i] << (28 - 4 * i)); - out_be32(&ugeth->p_rx_glbl_pram->l3qt[j/8], l3qt); + out_be32(&ugeth->p_rx_glbl_pram->l3qt[j], l3qt); } /* vlantype */ @@ -3304,8 +3316,8 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) /* Size varies with number of Rx queues */ ugeth->rx_bd_qs_tbl_offset = qe_muram_alloc(ug_info->numQueuesRx * - (sizeof(struct ucc_geth_rx_bd_queues_entry) + - sizeof(struct ucc_geth_rx_prefetched_bds)), + (sizeof(ucc_geth_rx_bd_queues_entry_t) + + sizeof(ucc_geth_rx_prefetched_bds_t)), UCC_GETH_RX_BD_QUEUES_ALIGNMENT); if (IS_MURAM_ERR(ugeth->rx_bd_qs_tbl_offset)) { ugeth_err @@ -3316,14 +3328,14 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) } ugeth->p_rx_bd_qs_tbl = - (struct ucc_geth_rx_bd_queues_entry *) qe_muram_addr(ugeth-> + (ucc_geth_rx_bd_queues_entry_t *) qe_muram_addr(ugeth-> rx_bd_qs_tbl_offset); out_be32(&ugeth->p_rx_glbl_pram->rbdqptr, ugeth->rx_bd_qs_tbl_offset); /* Zero out p_rx_bd_qs_tbl */ memset(ugeth->p_rx_bd_qs_tbl, 0, - ug_info->numQueuesRx * (sizeof(struct ucc_geth_rx_bd_queues_entry) + - sizeof(struct ucc_geth_rx_prefetched_bds))); + ug_info->numQueuesRx * (sizeof(ucc_geth_rx_bd_queues_entry_t) + + sizeof(ucc_geth_rx_prefetched_bds_t))); /* Setup the table */ /* Assume BD rings are already established */ @@ -3394,7 +3406,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) /* Allocate memory for extended filtering Mode Global Parameters */ ugeth->exf_glbl_param_offset = - qe_muram_alloc(sizeof(struct ucc_geth_exf_global_pram), + qe_muram_alloc(sizeof(ucc_geth_exf_global_pram_t), UCC_GETH_RX_EXTENDED_FILTERING_GLOBAL_PARAMETERS_ALIGNMENT); if (IS_MURAM_ERR(ugeth->exf_glbl_param_offset)) { ugeth_err @@ -3405,7 +3417,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) } ugeth->p_exf_glbl_param = - (struct ucc_geth_exf_global_pram *) qe_muram_addr(ugeth-> + (ucc_geth_exf_global_pram_t *) qe_muram_addr(ugeth-> exf_glbl_param_offset); out_be32(&ugeth->p_rx_glbl_pram->exfGlobalParam, ugeth->exf_glbl_param_offset); @@ -3427,7 +3439,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) INIT_LIST_HEAD(&ugeth->ind_hash_q); } p_82xx_addr_filt = - (struct ucc_geth_82xx_address_filtering_pram *) ugeth-> + (ucc_geth_82xx_address_filtering_pram_t *) ugeth-> p_rx_glbl_pram->addressfiltering; ugeth_82xx_filtering_clear_all_addr_in_hash(ugeth, @@ -3450,7 +3462,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) * allocated resources can be released when the channel is freed. */ if (!(ugeth->p_init_enet_param_shadow = - (struct ucc_geth_init_pram *) kmalloc(sizeof(struct ucc_geth_init_pram), + (ucc_geth_init_pram_t *) kmalloc(sizeof(ucc_geth_init_pram_t), GFP_KERNEL))) { ugeth_err ("%s: Can not allocate memory for" @@ -3460,7 +3472,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) } /* Zero out *p_init_enet_param_shadow */ memset((char *)ugeth->p_init_enet_param_shadow, - 0, sizeof(struct ucc_geth_init_pram)); + 0, sizeof(ucc_geth_init_pram_t)); /* Fill shadow InitEnet command parameter structure */ @@ -3494,7 +3506,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) } ugeth->p_init_enet_param_shadow->largestexternallookupkeysize = ug_info->largestexternallookupkeysize; - size = sizeof(struct ucc_geth_thread_rx_pram); + size = sizeof(ucc_geth_thread_rx_pram_t); if (ug_info->rxExtendedFiltering) { size += THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING; if (ug_info->largestexternallookupkeysize == @@ -3525,7 +3537,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) fill_init_enet_entries(ugeth, &(ugeth->p_init_enet_param_shadow-> txthread[0]), numThreadsTxNumerical, - sizeof(struct ucc_geth_thread_tx_pram), + sizeof(ucc_geth_thread_tx_pram_t), UCC_GETH_THREAD_TX_PRAM_ALIGNMENT, ug_info->riscTx, 0)) != 0) { ugeth_err("%s: Can not fill p_init_enet_param_shadow.", @@ -3545,7 +3557,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) } /* Allocate InitEnet command parameter structure */ - init_enet_pram_offset = qe_muram_alloc(sizeof(struct ucc_geth_init_pram), 4); + init_enet_pram_offset = qe_muram_alloc(sizeof(ucc_geth_init_pram_t), 4); if (IS_MURAM_ERR(init_enet_pram_offset)) { ugeth_err ("%s: Can not allocate DPRAM memory for p_init_enet_pram.", @@ -3554,7 +3566,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) return -ENOMEM; } p_init_enet_pram = - (struct ucc_geth_init_pram *) qe_muram_addr(init_enet_pram_offset); + (ucc_geth_init_pram_t *) qe_muram_addr(init_enet_pram_offset); /* Copy shadow InitEnet command parameter structure into PRAM */ p_init_enet_pram->resinit1 = ugeth->p_init_enet_param_shadow->resinit1; @@ -3579,7 +3591,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) /* Issue QE command */ cecr_subblock = ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num); - qe_issue_cmd(command, cecr_subblock, QE_CR_PROTOCOL_ETHERNET, + qe_issue_cmd(command, cecr_subblock, (u8) QE_CR_PROTOCOL_ETHERNET, init_enet_pram_offset); /* Free InitEnet command parameter */ @@ -3591,7 +3603,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) /* returns a net_device_stats structure pointer */ static struct net_device_stats *ucc_geth_get_stats(struct net_device *dev) { - struct ucc_geth_private *ugeth = netdev_priv(dev); + ucc_geth_private_t *ugeth = netdev_priv(dev); return &(ugeth->stats); } @@ -3602,7 +3614,7 @@ static struct net_device_stats *ucc_geth_get_stats(struct net_device *dev) * starting over will fix the problem. */ static void ucc_geth_timeout(struct net_device *dev) { - struct ucc_geth_private *ugeth = netdev_priv(dev); + ucc_geth_private_t *ugeth = netdev_priv(dev); ugeth_vdbg("%s: IN", __FUNCTION__); @@ -3622,7 +3634,7 @@ static void ucc_geth_timeout(struct net_device *dev) /* It is pointed to by the dev->hard_start_xmit function pointer */ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev) { - struct ucc_geth_private *ugeth = netdev_priv(dev); + ucc_geth_private_t *ugeth = netdev_priv(dev); u8 *bd; /* BD pointer */ u32 bd_status; u8 txQ = 0; @@ -3635,7 +3647,7 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev) /* Start from the next BD that should be filled */ bd = ugeth->txBd[txQ]; - bd_status = in_be32((u32 *)bd); + bd_status = BD_STATUS_AND_LENGTH(bd); /* Save the skb pointer so we can free it later */ ugeth->tx_skbuff[txQ][ugeth->skb_curtx[txQ]] = skb; @@ -3645,21 +3657,20 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev) 1) & TX_RING_MOD_MASK(ugeth->ug_info->bdRingLenTx[txQ]); /* set up the buffer descriptor */ - out_be32(&((struct qe_bd *)bd)->buf, + BD_BUFFER_SET(bd, dma_map_single(NULL, skb->data, skb->len, DMA_TO_DEVICE)); - /* printk(KERN_DEBUG"skb->data is 0x%x\n",skb->data); */ + //printk(KERN_DEBUG"skb->data is 0x%x\n",skb->data); bd_status = (bd_status & T_W) | T_R | T_I | T_L | skb->len; - /* set bd status and length */ - out_be32((u32 *)bd, bd_status); + BD_STATUS_AND_LENGTH_SET(bd, bd_status); dev->trans_start = jiffies; /* Move to next BD in the ring */ if (!(bd_status & T_W)) - ugeth->txBd[txQ] = bd + sizeof(struct qe_bd); + ugeth->txBd[txQ] = bd + UCC_GETH_SIZE_OF_BD; else ugeth->txBd[txQ] = ugeth->p_tx_bd_ring[txQ]; @@ -3684,7 +3695,7 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev) return 0; } -static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit) +static int ucc_geth_rx(ucc_geth_private_t *ugeth, u8 rxQ, int rx_work_limit) { struct sk_buff *skb; u8 *bd; @@ -3698,11 +3709,11 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit /* collect received buffers */ bd = ugeth->rxBd[rxQ]; - bd_status = in_be32((u32 *)bd); + bd_status = BD_STATUS_AND_LENGTH(bd); /* while there are received buffers and BD is full (~R_E) */ while (!((bd_status & (R_E)) || (--rx_work_limit < 0))) { - bdBuffer = (u8 *) in_be32(&((struct qe_bd *)bd)->buf); + bdBuffer = (u8 *) BD_BUFFER(bd); length = (u16) ((bd_status & BD_LENGTH_MASK) - 4); skb = ugeth->rx_skbuff[rxQ][ugeth->skb_currx[rxQ]]; @@ -3757,9 +3768,9 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit if (bd_status & R_W) bd = ugeth->p_rx_bd_ring[rxQ]; else - bd += sizeof(struct qe_bd); + bd += UCC_GETH_SIZE_OF_BD; - bd_status = in_be32((u32 *)bd); + bd_status = BD_STATUS_AND_LENGTH(bd); } ugeth->rxBd[rxQ] = bd; @@ -3770,12 +3781,12 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit static int ucc_geth_tx(struct net_device *dev, u8 txQ) { /* Start from the next BD that should be filled */ - struct ucc_geth_private *ugeth = netdev_priv(dev); + ucc_geth_private_t *ugeth = netdev_priv(dev); u8 *bd; /* BD pointer */ u32 bd_status; bd = ugeth->confBd[txQ]; - bd_status = in_be32((u32 *)bd); + bd_status = BD_STATUS_AND_LENGTH(bd); /* Normal processing. */ while ((bd_status & T_R) == 0) { @@ -3802,7 +3813,7 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ) /* Advance the confirmation BD pointer */ if (!(bd_status & T_W)) - ugeth->confBd[txQ] += sizeof(struct qe_bd); + ugeth->confBd[txQ] += UCC_GETH_SIZE_OF_BD; else ugeth->confBd[txQ] = ugeth->p_tx_bd_ring[txQ]; } @@ -3812,7 +3823,7 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ) #ifdef CONFIG_UGETH_NAPI static int ucc_geth_poll(struct net_device *dev, int *budget) { - struct ucc_geth_private *ugeth = netdev_priv(dev); + ucc_geth_private_t *ugeth = netdev_priv(dev); int howmany; int rx_work_limit = *budget; u8 rxQ = 0; @@ -3833,12 +3844,13 @@ static int ucc_geth_poll(struct net_device *dev, int *budget) } #endif /* CONFIG_UGETH_NAPI */ -static irqreturn_t ucc_geth_irq_handler(int irq, void *info) +static irqreturn_t ucc_geth_irq_handler(int irq, void *info, + struct pt_regs *regs) { struct net_device *dev = (struct net_device *)info; - struct ucc_geth_private *ugeth = netdev_priv(dev); - struct ucc_fast_private *uccf; - struct ucc_geth_info *ug_info; + ucc_geth_private_t *ugeth = netdev_priv(dev); + ucc_fast_private_t *uccf; + ucc_geth_info_t *ug_info; register u32 ucce = 0; register u32 bit_mask = UCCE_RXBF_SINGLE_MASK; register u32 tx_mask = UCCE_TXBF_SINGLE_MASK; @@ -3898,10 +3910,10 @@ static irqreturn_t ucc_geth_irq_handler(int irq, void *info) return IRQ_HANDLED; } -static irqreturn_t phy_interrupt(int irq, void *dev_id) +static irqreturn_t phy_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *)dev_id; - struct ucc_geth_private *ugeth = netdev_priv(dev); + ucc_geth_private_t *ugeth = netdev_priv(dev); ugeth_vdbg("%s: IN", __FUNCTION__); @@ -3921,8 +3933,8 @@ static irqreturn_t phy_interrupt(int irq, void *dev_id) static void ugeth_phy_change(void *data) { struct net_device *dev = (struct net_device *)data; - struct ucc_geth_private *ugeth = netdev_priv(dev); - struct ucc_geth *ug_regs; + ucc_geth_private_t *ugeth = netdev_priv(dev); + ucc_geth_t *ug_regs; int result = 0; ugeth_vdbg("%s: IN", __FUNCTION__); @@ -3952,7 +3964,7 @@ static void ugeth_phy_change(void *data) static void ugeth_phy_timer(unsigned long data) { struct net_device *dev = (struct net_device *)data; - struct ucc_geth_private *ugeth = netdev_priv(dev); + ucc_geth_private_t *ugeth = netdev_priv(dev); schedule_work(&ugeth->tq); @@ -3968,7 +3980,7 @@ static void ugeth_phy_timer(unsigned long data) static void ugeth_phy_startup_timer(unsigned long data) { struct ugeth_mii_info *mii_info = (struct ugeth_mii_info *)data; - struct ucc_geth_private *ugeth = netdev_priv(mii_info->dev); + ucc_geth_private_t *ugeth = netdev_priv(mii_info->dev); static int secondary = UGETH_AN_TIMEOUT; int result; @@ -4023,7 +4035,7 @@ static void ugeth_phy_startup_timer(unsigned long data) /* Returns 0 for success. */ static int ucc_geth_open(struct net_device *dev) { - struct ucc_geth_private *ugeth = netdev_priv(dev); + ucc_geth_private_t *ugeth = netdev_priv(dev); int err; ugeth_vdbg("%s: IN", __FUNCTION__); @@ -4100,7 +4112,7 @@ static int ucc_geth_open(struct net_device *dev) /* Stops the kernel queue, and halts the controller */ static int ucc_geth_close(struct net_device *dev) { - struct ucc_geth_private *ugeth = netdev_priv(dev); + ucc_geth_private_t *ugeth = netdev_priv(dev); ugeth_vdbg("%s: IN", __FUNCTION__); @@ -4119,53 +4131,30 @@ static int ucc_geth_close(struct net_device *dev) const struct ethtool_ops ucc_geth_ethtool_ops = { }; -static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *match) +static int ucc_geth_probe(struct device *device) { - struct device *device = &ofdev->dev; - struct device_node *np = ofdev->node; + struct platform_device *pdev = to_platform_device(device); + struct ucc_geth_platform_data *ugeth_pdata; struct net_device *dev = NULL; struct ucc_geth_private *ugeth = NULL; struct ucc_geth_info *ug_info; - struct resource res; - struct device_node *phy; - int err, ucc_num, phy_interface; + int err; static int mii_mng_configured = 0; - const phandle *ph; - const unsigned int *prop; ugeth_vdbg("%s: IN", __FUNCTION__); - prop = get_property(np, "device-id", NULL); - ucc_num = *prop - 1; - if ((ucc_num < 0) || (ucc_num > 7)) - return -ENODEV; - - ug_info = &ugeth_info[ucc_num]; - ug_info->uf_info.ucc_num = ucc_num; - prop = get_property(np, "rx-clock", NULL); - ug_info->uf_info.rx_clock = *prop; - prop = get_property(np, "tx-clock", NULL); - ug_info->uf_info.tx_clock = *prop; - err = of_address_to_resource(np, 0, &res); - if (err) - return -EINVAL; - - ug_info->uf_info.regs = res.start; - ug_info->uf_info.irq = irq_of_parse_and_map(np, 0); - - ph = get_property(np, "phy-handle", NULL); - phy = of_find_node_by_phandle(*ph); + ugeth_pdata = (struct ucc_geth_platform_data *)pdev->dev.platform_data; - if (phy == NULL) - return -ENODEV; - - prop = get_property(phy, "reg", NULL); - ug_info->phy_address = *prop; - prop = get_property(phy, "interface", NULL); - ug_info->enet_interface = *prop; - ug_info->phy_interrupt = irq_of_parse_and_map(phy, 0); - ug_info->board_flags = (ug_info->phy_interrupt == NO_IRQ)? - 0:FSL_UGETH_BRD_HAS_PHY_INTR; + ug_info = &ugeth_info[pdev->id]; + ug_info->uf_info.ucc_num = pdev->id; + ug_info->uf_info.rx_clock = ugeth_pdata->rx_clock; + ug_info->uf_info.tx_clock = ugeth_pdata->tx_clock; + ug_info->uf_info.regs = ugeth_pdata->phy_reg_addr; + ug_info->uf_info.irq = platform_get_irq(pdev, 0); + ug_info->phy_address = ugeth_pdata->phy_id; + ug_info->enet_interface = ugeth_pdata->phy_interface; + ug_info->board_flags = ugeth_pdata->board_flags; + ug_info->phy_interrupt = ugeth_pdata->phy_interrupt; printk(KERN_INFO "ucc_geth: UCC%1d at 0x%8x (irq = %d) \n", ug_info->uf_info.ucc_num + 1, ug_info->uf_info.regs, @@ -4173,44 +4162,12 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma if (ug_info == NULL) { ugeth_err("%s: [%d] Missing additional data!", __FUNCTION__, - ucc_num); + pdev->id); return -ENODEV; } - /* FIXME: Work around for early chip rev. */ - /* There's a bug in initial chip rev(s) in the RGMII ac */ - /* timing. */ - /* The following compensates by writing to the reserved */ - /* QE Port Output Hold Registers (CPOH1?). */ - prop = get_property(phy, "interface", NULL); - phy_interface = *prop; - if ((phy_interface == ENET_1000_RGMII) || - (phy_interface == ENET_100_RGMII) || - (phy_interface == ENET_10_RGMII)) { - struct device_node *soc; - phys_addr_t immrbase = -1; - u32 *tmp_reg; - u32 tmp_val; - - soc = of_find_node_by_type(NULL, "soc"); - if (soc) { - unsigned int size; - const void *prop = get_property(soc, "reg", &size); - immrbase = of_translate_address(soc, prop); - of_node_put(soc); - }; - - tmp_reg = (u32 *) ioremap(immrbase + 0x14A8, 0x4); - tmp_val = in_be32(tmp_reg); - if (ucc_num == 1) - out_be32(tmp_reg, tmp_val | 0x00003000); - else if (ucc_num == 2) - out_be32(tmp_reg, tmp_val | 0x0c000000); - iounmap(tmp_reg); - } - if (!mii_mng_configured) { - ucc_set_qe_mux_mii_mng(ucc_num); + ucc_set_qe_mux_mii_mng(ug_info->uf_info.ucc_num); mii_mng_configured = 1; } @@ -4257,14 +4214,13 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma ugeth->ug_info = ug_info; ugeth->dev = dev; - memcpy(dev->dev_addr, get_property(np, "mac-address", NULL), 6); + memcpy(dev->dev_addr, ugeth_pdata->mac_addr, 6); return 0; } -static int ucc_geth_remove(struct of_device* ofdev) +static int ucc_geth_remove(struct device *device) { - struct device *device = &ofdev->dev; struct net_device *dev = dev_get_drvdata(device); struct ucc_geth_private *ugeth = netdev_priv(dev); @@ -4275,38 +4231,28 @@ static int ucc_geth_remove(struct of_device* ofdev) return 0; } -static struct of_device_id ucc_geth_match[] = { - { - .type = "network", - .compatible = "ucc_geth", - }, - {}, -}; - -MODULE_DEVICE_TABLE(of, ucc_geth_match); - -static struct of_platform_driver ucc_geth_driver = { - .name = DRV_NAME, - .match_table = ucc_geth_match, - .probe = ucc_geth_probe, - .remove = ucc_geth_remove, +/* Structure for a device driver */ +static struct device_driver ucc_geth_driver = { + .name = DRV_NAME, + .bus = &platform_bus_type, + .probe = ucc_geth_probe, + .remove = ucc_geth_remove, }; static int __init ucc_geth_init(void) { int i; - printk(KERN_INFO "ucc_geth: " DRV_DESC "\n"); for (i = 0; i < 8; i++) memcpy(&(ugeth_info[i]), &ugeth_primary_info, sizeof(ugeth_primary_info)); - return of_register_driver(&ucc_geth_driver); + return driver_register(&ucc_geth_driver); } static void __exit ucc_geth_exit(void) { - of_unregister_driver(&ucc_geth_driver); + driver_unregister(&ucc_geth_driver); } module_init(ucc_geth_init); diff --git a/trunk/drivers/net/ucc_geth.h b/trunk/drivers/net/ucc_geth.h index a66561253593..005965f5dd9b 100644 --- a/trunk/drivers/net/ucc_geth.h +++ b/trunk/drivers/net/ucc_geth.h @@ -36,24 +36,24 @@ #define ENET_INIT_PARAM_MAX_ENTRIES_RX 9 #define ENET_INIT_PARAM_MAX_ENTRIES_TX 8 -struct ucc_mii_mng { +typedef struct ucc_mii_mng { u32 miimcfg; /* MII management configuration reg */ u32 miimcom; /* MII management command reg */ u32 miimadd; /* MII management address reg */ u32 miimcon; /* MII management control reg */ u32 miimstat; /* MII management status reg */ u32 miimind; /* MII management indication reg */ -} __attribute__ ((packed)); +} __attribute__ ((packed)) ucc_mii_mng_t; -struct ucc_geth { - struct ucc_fast uccf; +typedef struct ucc_geth { + ucc_fast_t uccf; u32 maccfg1; /* mac configuration reg. 1 */ u32 maccfg2; /* mac configuration reg. 2 */ u32 ipgifg; /* interframe gap reg. */ u32 hafdup; /* half-duplex reg. */ u8 res1[0x10]; - struct ucc_mii_mng miimng; /* MII management structure */ + ucc_mii_mng_t miimng; /* MII management structure */ u32 ifctl; /* interface control reg */ u32 ifstat; /* interface statux reg */ u32 macstnaddr1; /* mac station address part 1 reg */ @@ -111,7 +111,7 @@ struct ucc_geth { u32 scar; /* Statistics carry register */ u32 scam; /* Statistics caryy mask register */ u8 res5[0x200 - 0x1c4]; -} __attribute__ ((packed)); +} __attribute__ ((packed)) ucc_geth_t; /* UCC GETH TEMODR Register */ #define TEMODER_TX_RMON_STATISTICS_ENABLE 0x0100 /* enable Tx statistics @@ -508,39 +508,39 @@ struct ucc_geth { /* UCC GETH UDSR (Data Synchronization Register) */ #define UDSR_MAGIC 0x067E -struct ucc_geth_thread_data_tx { +typedef struct ucc_geth_thread_data_tx { u8 res0[104]; -} __attribute__ ((packed)); +} __attribute__ ((packed)) ucc_geth_thread_data_tx_t; -struct ucc_geth_thread_data_rx { +typedef struct ucc_geth_thread_data_rx { u8 res0[40]; -} __attribute__ ((packed)); +} __attribute__ ((packed)) ucc_geth_thread_data_rx_t; /* Send Queue Queue-Descriptor */ -struct ucc_geth_send_queue_qd { +typedef struct ucc_geth_send_queue_qd { u32 bd_ring_base; /* pointer to BD ring base address */ u8 res0[0x8]; u32 last_bd_completed_address;/* initialize to last entry in BD ring */ u8 res1[0x30]; -} __attribute__ ((packed)); +} __attribute__ ((packed)) ucc_geth_send_queue_qd_t; -struct ucc_geth_send_queue_mem_region { - struct ucc_geth_send_queue_qd sqqd[NUM_TX_QUEUES]; -} __attribute__ ((packed)); +typedef struct ucc_geth_send_queue_mem_region { + ucc_geth_send_queue_qd_t sqqd[NUM_TX_QUEUES]; +} __attribute__ ((packed)) ucc_geth_send_queue_mem_region_t; -struct ucc_geth_thread_tx_pram { +typedef struct ucc_geth_thread_tx_pram { u8 res0[64]; -} __attribute__ ((packed)); +} __attribute__ ((packed)) ucc_geth_thread_tx_pram_t; -struct ucc_geth_thread_rx_pram { +typedef struct ucc_geth_thread_rx_pram { u8 res0[128]; -} __attribute__ ((packed)); +} __attribute__ ((packed)) ucc_geth_thread_rx_pram_t; #define THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING 64 #define THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING_8 64 #define THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING_16 96 -struct ucc_geth_scheduler { +typedef struct ucc_geth_scheduler { u16 cpucount0; /* CPU packet counter */ u16 cpucount1; /* CPU packet counter */ u16 cecount0; /* QE packet counter */ @@ -574,9 +574,9 @@ struct ucc_geth_scheduler { /**< weight factor for queues */ u32 minw; /* temporary variable handled by QE */ u8 res1[0x70 - 0x64]; -} __attribute__ ((packed)); +} __attribute__ ((packed)) ucc_geth_scheduler_t; -struct ucc_geth_tx_firmware_statistics_pram { +typedef struct ucc_geth_tx_firmware_statistics_pram { u32 sicoltx; /* single collision */ u32 mulcoltx; /* multiple collision */ u32 latecoltxfr; /* late collision */ @@ -596,9 +596,9 @@ struct ucc_geth_tx_firmware_statistics_pram { and 1518 octets */ u32 txpktsjumbo; /* total packets (including bad) between 1024 and MAXLength octets */ -} __attribute__ ((packed)); +} __attribute__ ((packed)) ucc_geth_tx_firmware_statistics_pram_t; -struct ucc_geth_rx_firmware_statistics_pram { +typedef struct ucc_geth_rx_firmware_statistics_pram { u32 frrxfcser; /* frames with crc error */ u32 fraligner; /* frames with alignment error */ u32 inrangelenrxer; /* in range length error */ @@ -630,33 +630,33 @@ struct ucc_geth_rx_firmware_statistics_pram { replaced */ u32 insertvlan; /* total frames that had their VLAN tag inserted */ -} __attribute__ ((packed)); +} __attribute__ ((packed)) ucc_geth_rx_firmware_statistics_pram_t; -struct ucc_geth_rx_interrupt_coalescing_entry { +typedef struct ucc_geth_rx_interrupt_coalescing_entry { u32 interruptcoalescingmaxvalue; /* interrupt coalescing max value */ u32 interruptcoalescingcounter; /* interrupt coalescing counter, initialize to interruptcoalescingmaxvalue */ -} __attribute__ ((packed)); +} __attribute__ ((packed)) ucc_geth_rx_interrupt_coalescing_entry_t; -struct ucc_geth_rx_interrupt_coalescing_table { - struct ucc_geth_rx_interrupt_coalescing_entry coalescingentry[NUM_RX_QUEUES]; +typedef struct ucc_geth_rx_interrupt_coalescing_table { + ucc_geth_rx_interrupt_coalescing_entry_t coalescingentry[NUM_RX_QUEUES]; /**< interrupt coalescing entry */ -} __attribute__ ((packed)); +} __attribute__ ((packed)) ucc_geth_rx_interrupt_coalescing_table_t; -struct ucc_geth_rx_prefetched_bds { - struct qe_bd bd[NUM_BDS_IN_PREFETCHED_BDS]; /* prefetched bd */ -} __attribute__ ((packed)); +typedef struct ucc_geth_rx_prefetched_bds { + qe_bd_t bd[NUM_BDS_IN_PREFETCHED_BDS]; /* prefetched bd */ +} __attribute__ ((packed)) ucc_geth_rx_prefetched_bds_t; -struct ucc_geth_rx_bd_queues_entry { +typedef struct ucc_geth_rx_bd_queues_entry { u32 bdbaseptr; /* BD base pointer */ u32 bdptr; /* BD pointer */ u32 externalbdbaseptr; /* external BD base pointer */ u32 externalbdptr; /* external BD pointer */ -} __attribute__ ((packed)); +} __attribute__ ((packed)) ucc_geth_rx_bd_queues_entry_t; -struct ucc_geth_tx_global_pram { +typedef struct ucc_geth_tx_global_pram { u16 temoder; u8 res0[0x38 - 0x02]; u32 sqptr; /* a base pointer to send queue memory region */ @@ -670,15 +670,15 @@ struct ucc_geth_tx_global_pram { u32 tqptr; /* a base pointer to the Tx Queues Memory Region */ u8 res2[0x80 - 0x74]; -} __attribute__ ((packed)); +} __attribute__ ((packed)) ucc_geth_tx_global_pram_t; /* structure representing Extended Filtering Global Parameters in PRAM */ -struct ucc_geth_exf_global_pram { +typedef struct ucc_geth_exf_global_pram { u32 l2pcdptr; /* individual address filter, high */ u8 res0[0x10 - 0x04]; -} __attribute__ ((packed)); +} __attribute__ ((packed)) ucc_geth_exf_global_pram_t; -struct ucc_geth_rx_global_pram { +typedef struct ucc_geth_rx_global_pram { u32 remoder; /* ethernet mode reg. */ u32 rqptr; /* base pointer to the Rx Queues Memory Region*/ u32 res0[0x1]; @@ -710,12 +710,12 @@ struct ucc_geth_rx_global_pram { u32 exfGlobalParam; /* base address for extended filtering global parameters */ u8 res6[0x100 - 0xC4]; /* Initialize to zero */ -} __attribute__ ((packed)); +} __attribute__ ((packed)) ucc_geth_rx_global_pram_t; #define GRACEFUL_STOP_ACKNOWLEDGE_RX 0x01 /* structure representing InitEnet command */ -struct ucc_geth_init_pram { +typedef struct ucc_geth_init_pram { u8 resinit1; u8 resinit2; u8 resinit3; @@ -729,7 +729,7 @@ struct ucc_geth_init_pram { u32 txglobal; /* tx global */ u32 txthread[ENET_INIT_PARAM_MAX_ENTRIES_TX]; /* tx threads */ u8 res3[0x1]; -} __attribute__ ((packed)); +} __attribute__ ((packed)) ucc_geth_init_pram_t; #define ENET_INIT_PARAM_RGF_SHIFT (32 - 4) #define ENET_INIT_PARAM_TGF_SHIFT (32 - 8) @@ -746,27 +746,27 @@ struct ucc_geth_init_pram { #define ENET_INIT_PARAM_MAGIC_RES_INIT5 0x0400 /* structure representing 82xx Address Filtering Enet Address in PRAM */ -struct ucc_geth_82xx_enet_address { +typedef struct ucc_geth_82xx_enet_address { u8 res1[0x2]; u16 h; /* address (MSB) */ u16 m; /* address */ u16 l; /* address (LSB) */ -} __attribute__ ((packed)); +} __attribute__ ((packed)) ucc_geth_82xx_enet_address_t; /* structure representing 82xx Address Filtering PRAM */ -struct ucc_geth_82xx_address_filtering_pram { +typedef struct ucc_geth_82xx_address_filtering_pram { u32 iaddr_h; /* individual address filter, high */ u32 iaddr_l; /* individual address filter, low */ u32 gaddr_h; /* group address filter, high */ u32 gaddr_l; /* group address filter, low */ - struct ucc_geth_82xx_enet_address taddr; - struct ucc_geth_82xx_enet_address paddr[NUM_OF_PADDRS]; + ucc_geth_82xx_enet_address_t taddr; + ucc_geth_82xx_enet_address_t paddr[NUM_OF_PADDRS]; u8 res0[0x40 - 0x38]; -} __attribute__ ((packed)); +} __attribute__ ((packed)) ucc_geth_82xx_address_filtering_pram_t; /* GETH Tx firmware statistics structure, used when calling UCC_GETH_GetStatistics. */ -struct ucc_geth_tx_firmware_statistics { +typedef struct ucc_geth_tx_firmware_statistics { u32 sicoltx; /* single collision */ u32 mulcoltx; /* multiple collision */ u32 latecoltxfr; /* late collision */ @@ -786,11 +786,11 @@ struct ucc_geth_tx_firmware_statistics { and 1518 octets */ u32 txpktsjumbo; /* total packets (including bad) between 1024 and MAXLength octets */ -} __attribute__ ((packed)); +} __attribute__ ((packed)) ucc_geth_tx_firmware_statistics_t; /* GETH Rx firmware statistics structure, used when calling UCC_GETH_GetStatistics. */ -struct ucc_geth_rx_firmware_statistics { +typedef struct ucc_geth_rx_firmware_statistics { u32 frrxfcser; /* frames with crc error */ u32 fraligner; /* frames with alignment error */ u32 inrangelenrxer; /* in range length error */ @@ -822,11 +822,11 @@ struct ucc_geth_rx_firmware_statistics { replaced */ u32 insertvlan; /* total frames that had their VLAN tag inserted */ -} __attribute__ ((packed)); +} __attribute__ ((packed)) ucc_geth_rx_firmware_statistics_t; /* GETH hardware statistics structure, used when calling UCC_GETH_GetStatistics. */ -struct ucc_geth_hardware_statistics { +typedef struct ucc_geth_hardware_statistics { u32 tx64; /* Total number of frames (including bad frames) transmitted that were exactly of the minimal length (64 for un tagged, 68 for @@ -871,7 +871,7 @@ struct ucc_geth_hardware_statistics { u32 rbca; /* Total number of frames received succesfully that had destination address equal to the broadcast address */ -} __attribute__ ((packed)); +} __attribute__ ((packed)) ucc_geth_hardware_statistics_t; /* UCC GETH Tx errors returned via TxConf callback */ #define TX_ERRORS_DEF 0x0200 @@ -1013,21 +1013,21 @@ struct ucc_geth_hardware_statistics { (MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_112) /* Ethernet speed */ -enum enet_speed { +typedef enum enet_speed { ENET_SPEED_10BT, /* 10 Base T */ ENET_SPEED_100BT, /* 100 Base T */ ENET_SPEED_1000BT /* 1000 Base T */ -}; +} enet_speed_e; /* Ethernet Address Type. */ -enum enet_addr_type { +typedef enum enet_addr_type { ENET_ADDR_TYPE_INDIVIDUAL, ENET_ADDR_TYPE_GROUP, ENET_ADDR_TYPE_BROADCAST -}; +} enet_addr_type_e; /* TBI / MII Set Register */ -enum enet_tbi_mii_reg { +typedef enum enet_tbi_mii_reg { ENET_TBI_MII_CR = 0x00, /* Control (CR ) */ ENET_TBI_MII_SR = 0x01, /* Status (SR ) */ ENET_TBI_MII_ANA = 0x04, /* AN advertisement (ANA ) */ @@ -1040,10 +1040,10 @@ enum enet_tbi_mii_reg { ENET_TBI_MII_EXST = 0x0F, /* Extended status (EXST ) */ ENET_TBI_MII_JD = 0x10, /* Jitter diagnostics (JD ) */ ENET_TBI_MII_TBICON = 0x11 /* TBI control (TBICON ) */ -}; +} enet_tbi_mii_reg_e; /* UCC GETH 82xx Ethernet Address Recognition Location */ -enum ucc_geth_enet_address_recognition_location { +typedef enum ucc_geth_enet_address_recognition_location { UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_STATION_ADDRESS,/* station address */ UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_PADDR_FIRST, /* additional @@ -1065,10 +1065,10 @@ enum ucc_geth_enet_address_recognition_location { UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_GROUP_HASH, /* group hash */ UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_INDIVIDUAL_HASH /* individual hash */ -}; +} ucc_geth_enet_address_recognition_location_e; /* UCC GETH vlan operation tagged */ -enum ucc_geth_vlan_operation_tagged { +typedef enum ucc_geth_vlan_operation_tagged { UCC_GETH_VLAN_OPERATION_TAGGED_NOP = 0x0, /* Tagged - nop */ UCC_GETH_VLAN_OPERATION_TAGGED_REPLACE_VID_PORTION_OF_Q_TAG = 0x1, /* Tagged - replace vid portion of q tag */ @@ -1076,18 +1076,18 @@ enum ucc_geth_vlan_operation_tagged { = 0x2, /* Tagged - if vid0 replace vid with default value */ UCC_GETH_VLAN_OPERATION_TAGGED_EXTRACT_Q_TAG_FROM_FRAME = 0x3 /* Tagged - extract q tag from frame */ -}; +} ucc_geth_vlan_operation_tagged_e; /* UCC GETH vlan operation non-tagged */ -enum ucc_geth_vlan_operation_non_tagged { +typedef enum ucc_geth_vlan_operation_non_tagged { UCC_GETH_VLAN_OPERATION_NON_TAGGED_NOP = 0x0, /* Non tagged - nop */ UCC_GETH_VLAN_OPERATION_NON_TAGGED_Q_TAG_INSERT = 0x1 /* Non tagged - q tag insert */ -}; +} ucc_geth_vlan_operation_non_tagged_e; /* UCC GETH Rx Quality of Service Mode */ -enum ucc_geth_qos_mode { +typedef enum ucc_geth_qos_mode { UCC_GETH_QOS_MODE_DEFAULT = 0x0, /* default queue */ UCC_GETH_QOS_MODE_QUEUE_NUM_FROM_L2_CRITERIA = 0x1, /* queue determined @@ -1097,11 +1097,11 @@ enum ucc_geth_qos_mode { determined by L3 criteria */ -}; +} ucc_geth_qos_mode_e; /* UCC GETH Statistics Gathering Mode - These are bit flags, 'or' them together for combined functionality */ -enum ucc_geth_statistics_gathering_mode { +typedef enum ucc_geth_statistics_gathering_mode { UCC_GETH_STATISTICS_GATHERING_MODE_NONE = 0x00000000, /* No statistics gathering */ @@ -1122,10 +1122,10 @@ enum ucc_geth_statistics_gathering_mode { statistics gathering */ -}; +} ucc_geth_statistics_gathering_mode_e; /* UCC GETH Pad and CRC Mode - Note, Padding without CRC is not possible */ -enum ucc_geth_maccfg2_pad_and_crc_mode { +typedef enum ucc_geth_maccfg2_pad_and_crc_mode { UCC_GETH_PAD_AND_CRC_MODE_NONE = MACCFG2_PAD_AND_CRC_MODE_NONE, /* Neither Padding short frames @@ -1135,59 +1135,61 @@ enum ucc_geth_maccfg2_pad_and_crc_mode { CRC only */ UCC_GETH_PAD_AND_CRC_MODE_PAD_AND_CRC = MACCFG2_PAD_AND_CRC_MODE_PAD_AND_CRC -}; +} ucc_geth_maccfg2_pad_and_crc_mode_e; /* UCC GETH upsmr Flow Control Mode */ -enum ucc_geth_flow_control_mode { +typedef enum ucc_geth_flow_control_mode { UPSMR_AUTOMATIC_FLOW_CONTROL_MODE_NONE = 0x00000000, /* No automatic flow control */ UPSMR_AUTOMATIC_FLOW_CONTROL_MODE_PAUSE_WHEN_EMERGENCY = 0x00004000 /* Send pause frame when RxFIFO reaches its emergency threshold */ -}; +} ucc_geth_flow_control_mode_e; /* UCC GETH number of threads */ -enum ucc_geth_num_of_threads { +typedef enum ucc_geth_num_of_threads { UCC_GETH_NUM_OF_THREADS_1 = 0x1, /* 1 */ UCC_GETH_NUM_OF_THREADS_2 = 0x2, /* 2 */ UCC_GETH_NUM_OF_THREADS_4 = 0x0, /* 4 */ UCC_GETH_NUM_OF_THREADS_6 = 0x3, /* 6 */ UCC_GETH_NUM_OF_THREADS_8 = 0x4 /* 8 */ -}; +} ucc_geth_num_of_threads_e; /* UCC GETH number of station addresses */ -enum ucc_geth_num_of_station_addresses { +typedef enum ucc_geth_num_of_station_addresses { UCC_GETH_NUM_OF_STATION_ADDRESSES_1, /* 1 */ UCC_GETH_NUM_OF_STATION_ADDRESSES_5 /* 5 */ -}; +} ucc_geth_num_of_station_addresses_e; + +typedef u8 enet_addr_t[ENET_NUM_OCTETS_PER_ADDRESS]; /* UCC GETH 82xx Ethernet Address Container */ -struct enet_addr_container { - u8 address[ENET_NUM_OCTETS_PER_ADDRESS]; /* ethernet address */ - enum ucc_geth_enet_address_recognition_location location; /* location in +typedef struct enet_addr_container { + enet_addr_t address; /* ethernet address */ + ucc_geth_enet_address_recognition_location_e location; /* location in 82xx address recognition hardware */ struct list_head node; -}; +} enet_addr_container_t; -#define ENET_ADDR_CONT_ENTRY(ptr) list_entry(ptr, struct enet_addr_container, node) +#define ENET_ADDR_CONT_ENTRY(ptr) list_entry(ptr, enet_addr_container_t, node) /* UCC GETH Termination Action Descriptor (TAD) structure. */ -struct ucc_geth_tad_params { +typedef struct ucc_geth_tad_params { int rx_non_dynamic_extended_features_mode; int reject_frame; - enum ucc_geth_vlan_operation_tagged vtag_op; - enum ucc_geth_vlan_operation_non_tagged vnontag_op; - enum ucc_geth_qos_mode rqos; + ucc_geth_vlan_operation_tagged_e vtag_op; + ucc_geth_vlan_operation_non_tagged_e vnontag_op; + ucc_geth_qos_mode_e rqos; u8 vpri; u16 vid; -}; +} ucc_geth_tad_params_t; /* GETH protocol initialization structure */ -struct ucc_geth_info { - struct ucc_fast_info uf_info; +typedef struct ucc_geth_info { + ucc_fast_info_t uf_info; u8 numQueuesTx; u8 numQueuesRx; int ipCheckSumCheck; @@ -1249,51 +1251,51 @@ struct ucc_geth_info { u8 iphoffset[TX_IP_OFFSET_ENTRY_MAX]; u16 bdRingLenTx[NUM_TX_QUEUES]; u16 bdRingLenRx[NUM_RX_QUEUES]; - enum enet_interface enet_interface; - enum ucc_geth_num_of_station_addresses numStationAddresses; - enum qe_fltr_largest_external_tbl_lookup_key_size + enet_interface_e enet_interface; + ucc_geth_num_of_station_addresses_e numStationAddresses; + qe_fltr_largest_external_tbl_lookup_key_size_e largestexternallookupkeysize; - enum ucc_geth_statistics_gathering_mode statisticsMode; - enum ucc_geth_vlan_operation_tagged vlanOperationTagged; - enum ucc_geth_vlan_operation_non_tagged vlanOperationNonTagged; - enum ucc_geth_qos_mode rxQoSMode; - enum ucc_geth_flow_control_mode aufc; - enum ucc_geth_maccfg2_pad_and_crc_mode padAndCrc; - enum ucc_geth_num_of_threads numThreadsTx; - enum ucc_geth_num_of_threads numThreadsRx; - enum qe_risc_allocation riscTx; - enum qe_risc_allocation riscRx; -}; + ucc_geth_statistics_gathering_mode_e statisticsMode; + ucc_geth_vlan_operation_tagged_e vlanOperationTagged; + ucc_geth_vlan_operation_non_tagged_e vlanOperationNonTagged; + ucc_geth_qos_mode_e rxQoSMode; + ucc_geth_flow_control_mode_e aufc; + ucc_geth_maccfg2_pad_and_crc_mode_e padAndCrc; + ucc_geth_num_of_threads_e numThreadsTx; + ucc_geth_num_of_threads_e numThreadsRx; + qe_risc_allocation_e riscTx; + qe_risc_allocation_e riscRx; +} ucc_geth_info_t; /* structure representing UCC GETH */ -struct ucc_geth_private { - struct ucc_geth_info *ug_info; - struct ucc_fast_private *uccf; +typedef struct ucc_geth_private { + ucc_geth_info_t *ug_info; + ucc_fast_private_t *uccf; struct net_device *dev; struct net_device_stats stats; /* linux network statistics */ - struct ucc_geth *ug_regs; - struct ucc_geth_init_pram *p_init_enet_param_shadow; - struct ucc_geth_exf_global_pram *p_exf_glbl_param; + ucc_geth_t *ug_regs; + ucc_geth_init_pram_t *p_init_enet_param_shadow; + ucc_geth_exf_global_pram_t *p_exf_glbl_param; u32 exf_glbl_param_offset; - struct ucc_geth_rx_global_pram *p_rx_glbl_pram; + ucc_geth_rx_global_pram_t *p_rx_glbl_pram; u32 rx_glbl_pram_offset; - struct ucc_geth_tx_global_pram *p_tx_glbl_pram; + ucc_geth_tx_global_pram_t *p_tx_glbl_pram; u32 tx_glbl_pram_offset; - struct ucc_geth_send_queue_mem_region *p_send_q_mem_reg; + ucc_geth_send_queue_mem_region_t *p_send_q_mem_reg; u32 send_q_mem_reg_offset; - struct ucc_geth_thread_data_tx *p_thread_data_tx; + ucc_geth_thread_data_tx_t *p_thread_data_tx; u32 thread_dat_tx_offset; - struct ucc_geth_thread_data_rx *p_thread_data_rx; + ucc_geth_thread_data_rx_t *p_thread_data_rx; u32 thread_dat_rx_offset; - struct ucc_geth_scheduler *p_scheduler; + ucc_geth_scheduler_t *p_scheduler; u32 scheduler_offset; - struct ucc_geth_tx_firmware_statistics_pram *p_tx_fw_statistics_pram; + ucc_geth_tx_firmware_statistics_pram_t *p_tx_fw_statistics_pram; u32 tx_fw_statistics_pram_offset; - struct ucc_geth_rx_firmware_statistics_pram *p_rx_fw_statistics_pram; + ucc_geth_rx_firmware_statistics_pram_t *p_rx_fw_statistics_pram; u32 rx_fw_statistics_pram_offset; - struct ucc_geth_rx_interrupt_coalescing_table *p_rx_irq_coalescing_tbl; + ucc_geth_rx_interrupt_coalescing_table_t *p_rx_irq_coalescing_tbl; u32 rx_irq_coalescing_tbl_offset; - struct ucc_geth_rx_bd_queues_entry *p_rx_bd_qs_tbl; + ucc_geth_rx_bd_queues_entry_t *p_rx_bd_qs_tbl; u32 rx_bd_qs_tbl_offset; u8 *p_tx_bd_ring[NUM_TX_QUEUES]; u32 tx_bd_ring_offset[NUM_TX_QUEUES]; @@ -1306,7 +1308,7 @@ struct ucc_geth_private { u16 cpucount[NUM_TX_QUEUES]; volatile u16 *p_cpucount[NUM_TX_QUEUES]; int indAddrRegUsed[NUM_OF_PADDRS]; - u8 paddr[NUM_OF_PADDRS][ENET_NUM_OCTETS_PER_ADDRESS]; /* ethernet address */ + enet_addr_t paddr[NUM_OF_PADDRS]; u8 numGroupAddrInHash; u8 numIndAddrInHash; u8 numIndAddrInReg; @@ -1332,6 +1334,6 @@ struct ucc_geth_private { int oldspeed; int oldduplex; int oldlink; -}; +} ucc_geth_private_t; #endif /* __UCC_GETH_H__ */ diff --git a/trunk/drivers/net/ucc_geth_phy.c b/trunk/drivers/net/ucc_geth_phy.c index 5360ec05eaa3..67260eb3188a 100644 --- a/trunk/drivers/net/ucc_geth_phy.c +++ b/trunk/drivers/net/ucc_geth_phy.c @@ -42,6 +42,7 @@ #include "ucc_geth.h" #include "ucc_geth_phy.h" +#include #define ugphy_printk(level, format, arg...) \ printk(level format "\n", ## arg) @@ -71,14 +72,16 @@ static int genmii_read_status(struct ugeth_mii_info *mii_info); u16 phy_read(struct ugeth_mii_info *mii_info, u16 regnum); void phy_write(struct ugeth_mii_info *mii_info, u16 regnum, u16 val); +static u8 *bcsr_regs = NULL; + /* Write value to the PHY for this device to the register at regnum, */ /* waiting until the write is done before it returns. All PHY */ /* configuration has to be done through the TSEC1 MIIM regs */ void write_phy_reg(struct net_device *dev, int mii_id, int regnum, int value) { - struct ucc_geth_private *ugeth = netdev_priv(dev); - struct ucc_mii_mng *mii_regs; - enum enet_tbi_mii_reg mii_reg = (enum enet_tbi_mii_reg) regnum; + ucc_geth_private_t *ugeth = netdev_priv(dev); + ucc_mii_mng_t *mii_regs; + enet_tbi_mii_reg_e mii_reg = (enet_tbi_mii_reg_e) regnum; u32 tmp_reg; ugphy_vdbg("%s: IN", __FUNCTION__); @@ -113,9 +116,9 @@ void write_phy_reg(struct net_device *dev, int mii_id, int regnum, int value) /* configuration has to be done through the TSEC1 MIIM regs */ int read_phy_reg(struct net_device *dev, int mii_id, int regnum) { - struct ucc_geth_private *ugeth = netdev_priv(dev); - struct ucc_mii_mng *mii_regs; - enum enet_tbi_mii_reg mii_reg = (enum enet_tbi_mii_reg) regnum; + ucc_geth_private_t *ugeth = netdev_priv(dev); + ucc_mii_mng_t *mii_regs; + enet_tbi_mii_reg_e mii_reg = (enet_tbi_mii_reg_e) regnum; u32 tmp_reg; u16 value; @@ -631,6 +634,11 @@ static void dm9161_close(struct ugeth_mii_info *mii_info) static int dm9161_ack_interrupt(struct ugeth_mii_info *mii_info) { +/* FIXME: This lines are for BUG fixing in the mpc8325. +Remove this from here when it's fixed */ + if (bcsr_regs == NULL) + bcsr_regs = (u8 *) ioremap(BCSR_PHYS_ADDR, BCSR_SIZE); + bcsr_regs[14] |= 0x40; ugphy_vdbg("%s: IN", __FUNCTION__); /* Clear the interrupts by reading the reg */ @@ -642,6 +650,12 @@ static int dm9161_ack_interrupt(struct ugeth_mii_info *mii_info) static int dm9161_config_intr(struct ugeth_mii_info *mii_info) { +/* FIXME: This lines are for BUG fixing in the mpc8325. +Remove this from here when it's fixed */ + if (bcsr_regs == NULL) { + bcsr_regs = (u8 *) ioremap(BCSR_PHYS_ADDR, BCSR_SIZE); + bcsr_regs[14] &= ~0x40; + } ugphy_vdbg("%s: IN", __FUNCTION__); if (mii_info->interrupts == MII_INTERRUPT_ENABLED) diff --git a/trunk/drivers/net/ucc_geth_phy.h b/trunk/drivers/net/ucc_geth_phy.h index f5740783670f..2f98b8f1bb0a 100644 --- a/trunk/drivers/net/ucc_geth_phy.h +++ b/trunk/drivers/net/ucc_geth_phy.h @@ -126,7 +126,7 @@ struct ugeth_mii_info { /* And management functions */ struct phy_info *phyinfo; - struct ucc_mii_mng *mii_regs; + ucc_mii_mng_t *mii_regs; /* forced speed & duplex (no autoneg) * partner speed & duplex & pause (autoneg) diff --git a/trunk/drivers/net/via-rhine.c b/trunk/drivers/net/via-rhine.c index ebbda1d8f542..cbebf1b96e9d 100644 --- a/trunk/drivers/net/via-rhine.c +++ b/trunk/drivers/net/via-rhine.c @@ -404,7 +404,7 @@ static void mdio_write(struct net_device *dev, int phy_id, int location, int val static int rhine_open(struct net_device *dev); static void rhine_tx_timeout(struct net_device *dev); static int rhine_start_tx(struct sk_buff *skb, struct net_device *dev); -static irqreturn_t rhine_interrupt(int irq, void *dev_instance); +static irqreturn_t rhine_interrupt(int irq, void *dev_instance, struct pt_regs *regs); static void rhine_tx(struct net_device *dev); static int rhine_rx(struct net_device *dev, int limit); static void rhine_error(struct net_device *dev, int intr_status); @@ -569,7 +569,7 @@ static void __devinit rhine_reload_eeprom(long pioaddr, struct net_device *dev) static void rhine_poll(struct net_device *dev) { disable_irq(dev->irq); - rhine_interrupt(dev->irq, (void *)dev); + rhine_interrupt(dev->irq, (void *)dev, NULL); enable_irq(dev->irq); } #endif @@ -1290,7 +1290,7 @@ static int rhine_start_tx(struct sk_buff *skb, struct net_device *dev) /* The interrupt handler does all of the Rx thread work and cleans up after the Tx thread. */ -static irqreturn_t rhine_interrupt(int irq, void *dev_instance) +static irqreturn_t rhine_interrupt(int irq, void *dev_instance, struct pt_regs *rgs) { struct net_device *dev = dev_instance; struct rhine_private *rp = netdev_priv(dev); diff --git a/trunk/drivers/net/via-velocity.c b/trunk/drivers/net/via-velocity.c index 74f894795a1b..7d8808ce541f 100644 --- a/trunk/drivers/net/via-velocity.c +++ b/trunk/drivers/net/via-velocity.c @@ -236,7 +236,7 @@ static void velocity_print_info(struct velocity_info *vptr); static int velocity_open(struct net_device *dev); static int velocity_change_mtu(struct net_device *dev, int mtu); static int velocity_xmit(struct sk_buff *skb, struct net_device *dev); -static int velocity_intr(int irq, void *dev_instance); +static int velocity_intr(int irq, void *dev_instance, struct pt_regs *regs); static void velocity_set_multi(struct net_device *dev); static struct net_device_stats *velocity_get_stats(struct net_device *dev); static int velocity_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); @@ -2036,6 +2036,7 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev) * velocity_intr - interrupt callback * @irq: interrupt number * @dev_instance: interrupting device + * @pt_regs: CPU register state at interrupt * * Called whenever an interrupt is generated by the velocity * adapter IRQ line. We may not be the source of the interrupt @@ -2043,7 +2044,7 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev) * efficiently as possible. */ -static int velocity_intr(int irq, void *dev_instance) +static int velocity_intr(int irq, void *dev_instance, struct pt_regs *regs) { struct net_device *dev = dev_instance; struct velocity_info *vptr = netdev_priv(dev); diff --git a/trunk/drivers/net/wan/Kconfig b/trunk/drivers/net/wan/Kconfig index b5d0d7fb647a..58b7efbb0750 100644 --- a/trunk/drivers/net/wan/Kconfig +++ b/trunk/drivers/net/wan/Kconfig @@ -127,7 +127,7 @@ config LANMEDIA # There is no way to detect a Sealevel board. Force it modular config SEALEVEL_4021 tristate "Sealevel Systems 4021 support" - depends on WAN && ISA && m && ISA_DMA_API && INET + depends on WAN && ISA && m && ISA_DMA_API help This is a driver for the Sealevel Systems ACB 56 serial I/O adapter. diff --git a/trunk/drivers/net/wan/cosa.c b/trunk/drivers/net/wan/cosa.c index e1bf8b93f958..1f95b4864ea1 100644 --- a/trunk/drivers/net/wan/cosa.c +++ b/trunk/drivers/net/wan/cosa.c @@ -345,7 +345,7 @@ static void put_driver_status(struct cosa_data *cosa); static void put_driver_status_nolock(struct cosa_data *cosa); /* Interrupt handling */ -static irqreturn_t cosa_interrupt(int irq, void *cosa); +static irqreturn_t cosa_interrupt(int irq, void *cosa, struct pt_regs *regs); /* I/O ops debugging */ #ifdef DEBUG_IO @@ -1972,7 +1972,7 @@ static inline void eot_interrupt(struct cosa_data *cosa, int status) spin_unlock_irqrestore(&cosa->lock, flags); } -static irqreturn_t cosa_interrupt(int irq, void *cosa_) +static irqreturn_t cosa_interrupt(int irq, void *cosa_, struct pt_regs *regs) { unsigned status; int count = 0; diff --git a/trunk/drivers/net/wan/cycx_main.c b/trunk/drivers/net/wan/cycx_main.c index 6e5f1c898517..a5e7ce1bd16a 100644 --- a/trunk/drivers/net/wan/cycx_main.c +++ b/trunk/drivers/net/wan/cycx_main.c @@ -74,7 +74,7 @@ static int cycx_wan_setup(struct wan_device *wandev, wandev_conf_t *conf); static int cycx_wan_shutdown(struct wan_device *wandev); /* Miscellaneous functions */ -static irqreturn_t cycx_isr(int irq, void *dev_id); +static irqreturn_t cycx_isr(int irq, void *dev_id, struct pt_regs *regs); /* Global Data * Note: All data must be explicitly initialized!!! @@ -301,11 +301,11 @@ out: return ret; * o acknowledge Cyclom 2X hardware interrupt. * o call protocol-specific interrupt service routine, if any. */ -static irqreturn_t cycx_isr(int irq, void *dev_id) +static irqreturn_t cycx_isr(int irq, void *dev_id, struct pt_regs *regs) { - struct cycx_device *card = dev_id; + struct cycx_device *card = (struct cycx_device *)dev_id; - if (card->wandev.state == WAN_UNCONFIGURED) + if (!card || card->wandev.state == WAN_UNCONFIGURED) goto out; if (card->in_isr) { diff --git a/trunk/drivers/net/wan/dscc4.c b/trunk/drivers/net/wan/dscc4.c index 25021a7992a9..af4d4155905b 100644 --- a/trunk/drivers/net/wan/dscc4.c +++ b/trunk/drivers/net/wan/dscc4.c @@ -365,7 +365,7 @@ static int dscc4_init_ring(struct net_device *); static void dscc4_release_ring(struct dscc4_dev_priv *); static void dscc4_timer(unsigned long); static void dscc4_tx_timeout(struct net_device *); -static irqreturn_t dscc4_irq(int irq, void *dev_id); +static irqreturn_t dscc4_irq(int irq, void *dev_id, struct pt_regs *ptregs); static int dscc4_hdlc_attach(struct net_device *, unsigned short, unsigned short); static int dscc4_set_iface(struct dscc4_dev_priv *, struct net_device *); #ifdef DSCC4_POLLING @@ -1476,7 +1476,7 @@ static int dscc4_set_iface(struct dscc4_dev_priv *dpriv, struct net_device *dev) return ret; } -static irqreturn_t dscc4_irq(int irq, void *token) +static irqreturn_t dscc4_irq(int irq, void *token, struct pt_regs *ptregs) { struct dscc4_dev_priv *root = token; struct dscc4_pci_priv *priv; diff --git a/trunk/drivers/net/wan/farsync.c b/trunk/drivers/net/wan/farsync.c index c45d6a83339d..564351aafa41 100644 --- a/trunk/drivers/net/wan/farsync.c +++ b/trunk/drivers/net/wan/farsync.c @@ -1498,7 +1498,7 @@ do_bottom_half_rx(struct fst_card_info *card) * Dev_id is our fst_card_info pointer */ static irqreturn_t -fst_intr(int irq, void *dev_id) +fst_intr(int irq, void *dev_id, struct pt_regs *regs) { struct fst_card_info *card; struct fst_port_info *port; diff --git a/trunk/drivers/net/wan/hd6457x.c b/trunk/drivers/net/wan/hd6457x.c index 8d0a1f2f00e5..dce2bb317b82 100644 --- a/trunk/drivers/net/wan/hd6457x.c +++ b/trunk/drivers/net/wan/hd6457x.c @@ -424,7 +424,7 @@ static inline void sca_tx_intr(port_t *port) -static irqreturn_t sca_intr(int irq, void* dev_id) +static irqreturn_t sca_intr(int irq, void* dev_id, struct pt_regs *regs) { card_t *card = dev_id; int i; diff --git a/trunk/drivers/net/wan/lmc/lmc_main.c b/trunk/drivers/net/wan/lmc/lmc_main.c index 2b54f1bc3a0d..7b5d81deb028 100644 --- a/trunk/drivers/net/wan/lmc/lmc_main.c +++ b/trunk/drivers/net/wan/lmc/lmc_main.c @@ -100,7 +100,7 @@ static int lmc_rx (struct net_device *dev); static int lmc_open(struct net_device *dev); static int lmc_close(struct net_device *dev); static struct net_device_stats *lmc_get_stats(struct net_device *dev); -static irqreturn_t lmc_interrupt(int irq, void *dev_instance); +static irqreturn_t lmc_interrupt(int irq, void *dev_instance, struct pt_regs *regs); static void lmc_initcsrs(lmc_softc_t * const sc, lmc_csrptr_t csr_base, size_t csr_size); static void lmc_softreset(lmc_softc_t * const); static void lmc_running_reset(struct net_device *dev); @@ -1273,7 +1273,7 @@ static int lmc_ifdown (struct net_device *dev) /*fold00*/ /* Interrupt handling routine. This will take an incoming packet, or clean * up after a trasmit. */ -static irqreturn_t lmc_interrupt (int irq, void *dev_instance) /*fold00*/ +static irqreturn_t lmc_interrupt (int irq, void *dev_instance, struct pt_regs *regs) /*fold00*/ { struct net_device *dev = (struct net_device *) dev_instance; lmc_softc_t *sc; diff --git a/trunk/drivers/net/wan/n2.c b/trunk/drivers/net/wan/n2.c index 5c322dfb79f6..dcf46add3adf 100644 --- a/trunk/drivers/net/wan/n2.c +++ b/trunk/drivers/net/wan/n2.c @@ -500,7 +500,7 @@ static int __init n2_init(void) #ifdef MODULE printk(KERN_INFO "n2: no card initialized\n"); #endif - return -EINVAL; /* no parameters specified, abort */ + return -ENOSYS; /* no parameters specified, abort */ } printk(KERN_INFO "%s\n", version); @@ -538,11 +538,11 @@ static int __init n2_init(void) n2_run(io, irq, ram, valid[0], valid[1]); if (*hw == '\x0') - return first_card ? 0 : -EINVAL; + return first_card ? 0 : -ENOSYS; }while(*hw++ == ':'); printk(KERN_ERR "n2: invalid hardware parameters\n"); - return first_card ? 0 : -EINVAL; + return first_card ? 0 : -ENOSYS; } diff --git a/trunk/drivers/net/wan/pc300_drv.c b/trunk/drivers/net/wan/pc300_drv.c index 36d1c3ff7078..8d9b959bf15b 100644 --- a/trunk/drivers/net/wan/pc300_drv.c +++ b/trunk/drivers/net/wan/pc300_drv.c @@ -284,7 +284,7 @@ static void rx_dma_buf_pt_init(pc300_t *, int); static void rx_dma_buf_init(pc300_t *, int); static void tx_dma_buf_check(pc300_t *, int); static void rx_dma_buf_check(pc300_t *, int); -static irqreturn_t cpc_intr(int, void *); +static irqreturn_t cpc_intr(int, void *, struct pt_regs *); static struct net_device_stats *cpc_get_stats(struct net_device *); static int clock_rate_calc(uclong, uclong, int *); static uclong detect_ram(pc300_t *); @@ -2363,7 +2363,7 @@ static void falc_intr(pc300_t * card) } } -static irqreturn_t cpc_intr(int irq, void *dev_id) +static irqreturn_t cpc_intr(int irq, void *dev_id, struct pt_regs *regs) { pc300_t *card; volatile ucchar plx_status; @@ -2867,6 +2867,7 @@ static int ch_config(pc300dev_t * d) uclong clktype = chan->conf.phys_settings.clock_type; ucshort encoding = chan->conf.proto_settings.encoding; ucshort parity = chan->conf.proto_settings.parity; + int tmc, br; ucchar md0, md2; /* Reset the channel */ @@ -2939,12 +2940,8 @@ static int ch_config(pc300dev_t * d) case PC300_RSV: case PC300_X21: if (clktype == CLOCK_INT || clktype == CLOCK_TXINT) { - int tmc, br; - /* Calculate the clkrate parameters */ tmc = clock_rate_calc(clkrate, card->hw.clock, &br); - if (tmc < 0) - return -EIO; cpc_writeb(scabase + M_REG(TMCT, ch), tmc); cpc_writeb(scabase + M_REG(TXS, ch), (TXS_DTRXC | TXS_IBRG | br)); @@ -3100,16 +3097,14 @@ static int cpc_attach(struct net_device *dev, unsigned short encoding, return 0; } -static int cpc_opench(pc300dev_t * d) +static void cpc_opench(pc300dev_t * d) { pc300ch_t *chan = (pc300ch_t *) d->chan; pc300_t *card = (pc300_t *) chan->card; - int ch = chan->channel, rc; + int ch = chan->channel; void __iomem *scabase = card->hw.scabase; - rc = ch_config(d); - if (rc) - return rc; + ch_config(d); rx_config(d); @@ -3118,8 +3113,6 @@ static int cpc_opench(pc300dev_t * d) /* Assert RTS and DTR */ cpc_writeb(scabase + M_REG(CTL, ch), cpc_readb(scabase + M_REG(CTL, ch)) & ~(CTL_RTS | CTL_DTR)); - - return 0; } static void cpc_closech(pc300dev_t * d) @@ -3175,16 +3168,9 @@ int cpc_open(struct net_device *dev) } sprintf(ifr.ifr_name, "%s", dev->name); - result = cpc_opench(d); - if (result) - goto err_out; - + cpc_opench(d); netif_start_queue(dev); return 0; - -err_out: - hdlc_close(dev); - return result; } static int cpc_close(struct net_device *dev) diff --git a/trunk/drivers/net/wan/sbni.c b/trunk/drivers/net/wan/sbni.c index fc5c0c611ffd..fc75bec19029 100644 --- a/trunk/drivers/net/wan/sbni.c +++ b/trunk/drivers/net/wan/sbni.c @@ -119,7 +119,7 @@ static int sbni_ioctl( struct net_device *, struct ifreq *, int ); static struct net_device_stats *sbni_get_stats( struct net_device * ); static void set_multicast_list( struct net_device * ); -static irqreturn_t sbni_interrupt( int, void * ); +static irqreturn_t sbni_interrupt( int, void *, struct pt_regs * ); static void handle_channel( struct net_device * ); static int recv_frame( struct net_device * ); static void send_frame( struct net_device * ); @@ -501,7 +501,7 @@ sbni_start_xmit( struct sk_buff *skb, struct net_device *dev ) */ static irqreturn_t -sbni_interrupt( int irq, void *dev_id ) +sbni_interrupt( int irq, void *dev_id, struct pt_regs *regs ) { struct net_device *dev = (struct net_device *) dev_id; struct net_local *nl = (struct net_local *) dev->priv; diff --git a/trunk/drivers/net/wan/sdla.c b/trunk/drivers/net/wan/sdla.c index 6a485f0556f4..0ba018f8382b 100644 --- a/trunk/drivers/net/wan/sdla.c +++ b/trunk/drivers/net/wan/sdla.c @@ -867,7 +867,7 @@ static void sdla_receive(struct net_device *dev) spin_unlock_irqrestore(&sdla_lock, flags); } -static irqreturn_t sdla_isr(int irq, void *dev_id) +static irqreturn_t sdla_isr(int irq, void *dev_id, struct pt_regs * regs) { struct net_device *dev; struct frad_local *flp; @@ -875,7 +875,13 @@ static irqreturn_t sdla_isr(int irq, void *dev_id) dev = dev_id; - flp = netdev_priv(dev); + if (dev == NULL) + { + printk(KERN_WARNING "sdla_isr(): irq %d for unknown device.\n", irq); + return IRQ_NONE; + } + + flp = dev->priv; if (!flp->initialized) { diff --git a/trunk/drivers/net/wan/wanxl.c b/trunk/drivers/net/wan/wanxl.c index c73601574334..ec68f7dfd93f 100644 --- a/trunk/drivers/net/wan/wanxl.c +++ b/trunk/drivers/net/wan/wanxl.c @@ -244,7 +244,7 @@ static inline void wanxl_rx_intr(card_t *card) -static irqreturn_t wanxl_intr(int irq, void* dev_id) +static irqreturn_t wanxl_intr(int irq, void* dev_id, struct pt_regs *regs) { card_t *card = dev_id; int i; diff --git a/trunk/drivers/net/wan/z85230.c b/trunk/drivers/net/wan/z85230.c index 59ddd21c3958..caa48f12fd0f 100644 --- a/trunk/drivers/net/wan/z85230.c +++ b/trunk/drivers/net/wan/z85230.c @@ -728,7 +728,7 @@ EXPORT_SYMBOL(z8530_nop); * channel). c->lock for both channels points to dev->lock */ -irqreturn_t z8530_interrupt(int irq, void *dev_id) +irqreturn_t z8530_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct z8530_dev *dev=dev_id; u8 intr; diff --git a/trunk/drivers/net/wan/z85230.h b/trunk/drivers/net/wan/z85230.h index 158aea7b8eac..77e53208045f 100644 --- a/trunk/drivers/net/wan/z85230.h +++ b/trunk/drivers/net/wan/z85230.h @@ -396,7 +396,7 @@ struct z8530_dev extern u8 z8530_dead_port[]; extern u8 z8530_hdlc_kilostream_85230[]; extern u8 z8530_hdlc_kilostream[]; -extern irqreturn_t z8530_interrupt(int, void *); +extern irqreturn_t z8530_interrupt(int, void *, struct pt_regs *); extern void z8530_describe(struct z8530_dev *, char *mapping, unsigned long io); extern int z8530_init(struct z8530_dev *); extern int z8530_shutdown(struct z8530_dev *); diff --git a/trunk/drivers/net/wireless/airo.c b/trunk/drivers/net/wireless/airo.c index efcdaf1c5f73..39d09345027c 100644 --- a/trunk/drivers/net/wireless/airo.c +++ b/trunk/drivers/net/wireless/airo.c @@ -1120,7 +1120,8 @@ static void mpi_receive_802_3(struct airo_info *ai); static void mpi_receive_802_11(struct airo_info *ai); static int waitbusy (struct airo_info *ai); -static irqreturn_t airo_interrupt( int irq, void* dev_id); +static irqreturn_t airo_interrupt( int irq, void* dev_id, struct pt_regs + *regs); static int airo_thread(void *data); static void timer_func( struct net_device *dev ); static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); @@ -2897,8 +2898,6 @@ static struct net_device *_init_airo_card( unsigned short irq, int port, goto err_out_map; } ai->wifidev = init_wifidev(ai, dev); - if (!ai->wifidev) - goto err_out_reg; set_bit(FLAG_REGISTERED,&ai->flags); airo_print_info(dev->name, "MAC enabled %x:%x:%x:%x:%x:%x", @@ -2910,18 +2909,11 @@ static struct net_device *_init_airo_card( unsigned short irq, int port, for( i = 0; i < MAX_FIDS; i++ ) ai->fids[i] = transmit_allocate(ai,AIRO_DEF_MTU,i>=MAX_FIDS/2); - if (setup_proc_entry(dev, dev->priv) < 0) - goto err_out_wifi; - + setup_proc_entry( dev, dev->priv ); /* XXX check for failure */ netif_start_queue(dev); SET_MODULE_OWNER(dev); return dev; -err_out_wifi: - unregister_netdev(ai->wifidev); - free_netdev(ai->wifidev); -err_out_reg: - unregister_netdev(dev); err_out_map: if (test_bit(FLAG_MPI,&ai->flags) && pci) { pci_free_consistent(pci, PCI_SHARED_LEN, ai->shared, ai->shared_dma); @@ -3098,8 +3090,7 @@ static int airo_thread(void *data) { set_bit(JOB_AUTOWEP, &ai->jobs); break; } - if (!kthread_should_stop() && - !freezing(current)) { + if (!kthread_should_stop()) { unsigned long wake_at; if (!ai->expires || !ai->scan_timeout) { wake_at = max(ai->expires, @@ -3111,8 +3102,7 @@ static int airo_thread(void *data) { schedule_timeout(wake_at - jiffies); continue; } - } else if (!kthread_should_stop() && - !freezing(current)) { + } else if (!kthread_should_stop()) { schedule(); continue; } @@ -3161,7 +3151,7 @@ static int airo_thread(void *data) { return 0; } -static irqreturn_t airo_interrupt ( int irq, void* dev_id) { +static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *)dev_id; u16 status; u16 fid; @@ -4506,128 +4496,91 @@ static int setup_proc_entry( struct net_device *dev, apriv->proc_entry = create_proc_entry(apriv->proc_name, S_IFDIR|airo_perm, airo_entry); - if (!apriv->proc_entry) - goto fail; - apriv->proc_entry->uid = proc_uid; - apriv->proc_entry->gid = proc_gid; - apriv->proc_entry->owner = THIS_MODULE; + apriv->proc_entry->uid = proc_uid; + apriv->proc_entry->gid = proc_gid; + apriv->proc_entry->owner = THIS_MODULE; /* Setup the StatsDelta */ entry = create_proc_entry("StatsDelta", S_IFREG | (S_IRUGO&proc_perm), apriv->proc_entry); - if (!entry) - goto fail_stats_delta; - entry->uid = proc_uid; - entry->gid = proc_gid; + entry->uid = proc_uid; + entry->gid = proc_gid; entry->data = dev; - entry->owner = THIS_MODULE; + entry->owner = THIS_MODULE; SETPROC_OPS(entry, proc_statsdelta_ops); /* Setup the Stats */ entry = create_proc_entry("Stats", S_IFREG | (S_IRUGO&proc_perm), apriv->proc_entry); - if (!entry) - goto fail_stats; - entry->uid = proc_uid; - entry->gid = proc_gid; + entry->uid = proc_uid; + entry->gid = proc_gid; entry->data = dev; - entry->owner = THIS_MODULE; + entry->owner = THIS_MODULE; SETPROC_OPS(entry, proc_stats_ops); /* Setup the Status */ entry = create_proc_entry("Status", S_IFREG | (S_IRUGO&proc_perm), apriv->proc_entry); - if (!entry) - goto fail_status; - entry->uid = proc_uid; - entry->gid = proc_gid; + entry->uid = proc_uid; + entry->gid = proc_gid; entry->data = dev; - entry->owner = THIS_MODULE; + entry->owner = THIS_MODULE; SETPROC_OPS(entry, proc_status_ops); /* Setup the Config */ entry = create_proc_entry("Config", S_IFREG | proc_perm, apriv->proc_entry); - if (!entry) - goto fail_config; - entry->uid = proc_uid; - entry->gid = proc_gid; + entry->uid = proc_uid; + entry->gid = proc_gid; entry->data = dev; - entry->owner = THIS_MODULE; + entry->owner = THIS_MODULE; SETPROC_OPS(entry, proc_config_ops); /* Setup the SSID */ entry = create_proc_entry("SSID", S_IFREG | proc_perm, apriv->proc_entry); - if (!entry) - goto fail_ssid; - entry->uid = proc_uid; - entry->gid = proc_gid; + entry->uid = proc_uid; + entry->gid = proc_gid; entry->data = dev; - entry->owner = THIS_MODULE; + entry->owner = THIS_MODULE; SETPROC_OPS(entry, proc_SSID_ops); /* Setup the APList */ entry = create_proc_entry("APList", S_IFREG | proc_perm, apriv->proc_entry); - if (!entry) - goto fail_aplist; - entry->uid = proc_uid; - entry->gid = proc_gid; + entry->uid = proc_uid; + entry->gid = proc_gid; entry->data = dev; - entry->owner = THIS_MODULE; + entry->owner = THIS_MODULE; SETPROC_OPS(entry, proc_APList_ops); /* Setup the BSSList */ entry = create_proc_entry("BSSList", S_IFREG | proc_perm, apriv->proc_entry); - if (!entry) - goto fail_bsslist; entry->uid = proc_uid; entry->gid = proc_gid; entry->data = dev; - entry->owner = THIS_MODULE; + entry->owner = THIS_MODULE; SETPROC_OPS(entry, proc_BSSList_ops); /* Setup the WepKey */ entry = create_proc_entry("WepKey", S_IFREG | proc_perm, apriv->proc_entry); - if (!entry) - goto fail_wepkey; - entry->uid = proc_uid; - entry->gid = proc_gid; + entry->uid = proc_uid; + entry->gid = proc_gid; entry->data = dev; - entry->owner = THIS_MODULE; + entry->owner = THIS_MODULE; SETPROC_OPS(entry, proc_wepkey_ops); return 0; - -fail_wepkey: - remove_proc_entry("BSSList", apriv->proc_entry); -fail_bsslist: - remove_proc_entry("APList", apriv->proc_entry); -fail_aplist: - remove_proc_entry("SSID", apriv->proc_entry); -fail_ssid: - remove_proc_entry("Config", apriv->proc_entry); -fail_config: - remove_proc_entry("Status", apriv->proc_entry); -fail_status: - remove_proc_entry("Stats", apriv->proc_entry); -fail_stats: - remove_proc_entry("StatsDelta", apriv->proc_entry); -fail_stats_delta: - remove_proc_entry(apriv->proc_name, airo_entry); -fail: - return -ENOMEM; } static int takedown_proc_entry( struct net_device *dev, @@ -5972,6 +5925,7 @@ static int airo_get_essid(struct net_device *dev, /* Get the current SSID */ memcpy(extra, status_rid.SSID, status_rid.SSIDlen); + extra[status_rid.SSIDlen] = '\0'; /* If none, we may want to get the one that was set */ /* Push it out ! */ diff --git a/trunk/drivers/net/wireless/arlan-main.c b/trunk/drivers/net/wireless/arlan-main.c index 4688e56b69c7..bb6bea4f3233 100644 --- a/trunk/drivers/net/wireless/arlan-main.c +++ b/trunk/drivers/net/wireless/arlan-main.c @@ -78,7 +78,7 @@ static int arlans_found; static int arlan_open(struct net_device *dev); static int arlan_tx(struct sk_buff *skb, struct net_device *dev); -static irqreturn_t arlan_interrupt(int irq, void *dev_id); +static irqreturn_t arlan_interrupt(int irq, void *dev_id, struct pt_regs *regs); static int arlan_close(struct net_device *dev); static struct net_device_stats * arlan_statistics (struct net_device *dev); @@ -1651,7 +1651,7 @@ static void arlan_process_interrupt(struct net_device *dev) return; } -static irqreturn_t arlan_interrupt(int irq, void *dev_id) +static irqreturn_t arlan_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; struct arlan_private *priv = netdev_priv(dev); diff --git a/trunk/drivers/net/wireless/atmel.c b/trunk/drivers/net/wireless/atmel.c index 0c07b8b7250d..0fc267d626dc 100644 --- a/trunk/drivers/net/wireless/atmel.c +++ b/trunk/drivers/net/wireless/atmel.c @@ -1145,7 +1145,7 @@ static void rx_done_irq(struct atmel_private *priv) } } -static irqreturn_t service_interrupt(int irq, void *dev_id) +static irqreturn_t service_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_id; struct atmel_private *priv = netdev_priv(dev); @@ -1678,9 +1678,11 @@ static int atmel_get_essid(struct net_device *dev, /* Get the current SSID */ if (priv->new_SSID_size != 0) { memcpy(extra, priv->new_SSID, priv->new_SSID_size); + extra[priv->new_SSID_size] = '\0'; dwrq->length = priv->new_SSID_size; } else { memcpy(extra, priv->SSID, priv->SSID_size); + extra[priv->SSID_size] = '\0'; dwrq->length = priv->SSID_size; } diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_dma.c b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_dma.c index 978ed099e285..76e3aed4b471 100644 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_dma.c +++ b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_dma.c @@ -705,30 +705,11 @@ int bcm43xx_dma_init(struct bcm43xx_private *bcm) struct bcm43xx_dmaring *ring; int err = -ENOMEM; int dma64 = 0; - u64 mask = bcm43xx_get_supported_dma_mask(bcm); - int nobits; + u32 sbtmstatehi; - if (mask == DMA_64BIT_MASK) { + sbtmstatehi = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH); + if (sbtmstatehi & BCM43xx_SBTMSTATEHIGH_DMA64BIT) dma64 = 1; - nobits = 64; - } else if (mask == DMA_32BIT_MASK) - nobits = 32; - else - nobits = 30; - err = pci_set_dma_mask(bcm->pci_dev, mask); - err |= pci_set_consistent_dma_mask(bcm->pci_dev, mask); - if (err) { -#ifdef CONFIG_BCM43XX_PIO - printk(KERN_WARNING PFX "DMA not supported on this device." - " Falling back to PIO.\n"); - bcm->__using_pio = 1; - return -ENOSYS; -#else - printk(KERN_ERR PFX "FATAL: DMA not supported and PIO not configured. " - "Please recompile the driver with PIO support.\n"); - return -ENODEV; -#endif /* CONFIG_BCM43XX_PIO */ - } /* setup TX DMA channels. */ ring = bcm43xx_setup_dmaring(bcm, 0, 1, dma64); @@ -774,7 +755,8 @@ int bcm43xx_dma_init(struct bcm43xx_private *bcm) dma->rx_ring3 = ring; } - dprintk(KERN_INFO PFX "%d-bit DMA initialized\n", nobits); + dprintk(KERN_INFO PFX "%s DMA initialized\n", + dma64 ? "64-bit" : "32-bit"); err = 0; out: return err; diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_dma.h b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_dma.h index d1105e569a41..e04bcaddd1d0 100644 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_dma.h +++ b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_dma.h @@ -4,7 +4,6 @@ #include #include #include -#include #include #include @@ -315,23 +314,6 @@ int bcm43xx_dma_tx(struct bcm43xx_private *bcm, struct ieee80211_txb *txb); void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring); -/* Helper function that returns the dma mask for this device. */ -static inline -u64 bcm43xx_get_supported_dma_mask(struct bcm43xx_private *bcm) -{ - int dma64 = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH) & - BCM43xx_SBTMSTATEHIGH_DMA64BIT; - u16 mmio_base = bcm43xx_dmacontroller_base(dma64, 0); - u32 mask = BCM43xx_DMA32_TXADDREXT_MASK; - - if (dma64) - return DMA_64BIT_MASK; - bcm43xx_write32(bcm, mmio_base + BCM43xx_DMA32_TXCTL, mask); - if (bcm43xx_read32(bcm, mmio_base + BCM43xx_DMA32_TXCTL) & mask) - return DMA_32BIT_MASK; - return DMA_30BIT_MASK; -} - #else /* CONFIG_BCM43XX_DMA */ diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_leds.c b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_leds.c index 7d383a27b927..c3f90c8563d9 100644 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_leds.c +++ b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_leds.c @@ -189,24 +189,20 @@ void bcm43xx_leds_update(struct bcm43xx_private *bcm, int activity) case BCM43xx_LED_INACTIVE: continue; case BCM43xx_LED_OFF: - case BCM43xx_LED_BCM4303_3: break; case BCM43xx_LED_ON: turn_on = 1; break; case BCM43xx_LED_ACTIVITY: - case BCM43xx_LED_BCM4303_0: turn_on = activity; break; case BCM43xx_LED_RADIO_ALL: turn_on = radio->enabled; break; case BCM43xx_LED_RADIO_A: - case BCM43xx_LED_BCM4303_2: turn_on = (radio->enabled && phy->type == BCM43xx_PHYTYPE_A); break; case BCM43xx_LED_RADIO_B: - case BCM43xx_LED_BCM4303_1: turn_on = (radio->enabled && (phy->type == BCM43xx_PHYTYPE_B || phy->type == BCM43xx_PHYTYPE_G)); @@ -246,7 +242,7 @@ void bcm43xx_leds_update(struct bcm43xx_private *bcm, int activity) //TODO break; case BCM43xx_LED_ASSOC: - if (bcm->softmac->associnfo.associated) + if (bcm->softmac->associated) turn_on = 1; break; #ifdef CONFIG_BCM43XX_DEBUG @@ -261,8 +257,7 @@ void bcm43xx_leds_update(struct bcm43xx_private *bcm, int activity) continue; #endif /* CONFIG_BCM43XX_DEBUG */ default: - dprintkl(KERN_INFO PFX "Bad value in leds_update," - " led->behaviour: 0x%x\n", led->behaviour); + assert(0); }; if (led->activelow) diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_leds.h b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_leds.h index 811e14a81198..d3716cf3aebc 100644 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_leds.h +++ b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_leds.h @@ -46,12 +46,6 @@ enum { /* LED behaviour values */ BCM43xx_LED_TEST_BLINKSLOW, BCM43xx_LED_TEST_BLINKMEDIUM, BCM43xx_LED_TEST_BLINKFAST, - - /* Misc values for BCM4303 */ - BCM43xx_LED_BCM4303_0 = 0x2B, - BCM43xx_LED_BCM4303_1 = 0x78, - BCM43xx_LED_BCM4303_2 = 0x2E, - BCM43xx_LED_BCM4303_3 = 0x19, }; int bcm43xx_leds_init(struct bcm43xx_private *bcm); diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_main.c index a1b783813d8e..eb65db7393ba 100644 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_main.c +++ b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_main.c @@ -746,7 +746,7 @@ int bcm43xx_sprom_write(struct bcm43xx_private *bcm, const u16 *sprom) if (err) goto err_ctlreg; spromctl |= 0x10; /* SPROM WRITE enable. */ - err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_SPROMCTL, spromctl); + bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_SPROMCTL, spromctl); if (err) goto err_ctlreg; /* We must burn lots of CPU cycles here, but that does not @@ -768,7 +768,7 @@ int bcm43xx_sprom_write(struct bcm43xx_private *bcm, const u16 *sprom) mdelay(20); } spromctl &= ~0x10; /* SPROM WRITE enable. */ - err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_SPROMCTL, spromctl); + bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_SPROMCTL, spromctl); if (err) goto err_ctlreg; mdelay(500); @@ -1463,23 +1463,6 @@ static void handle_irq_transmit_status(struct bcm43xx_private *bcm) } } -static void drain_txstatus_queue(struct bcm43xx_private *bcm) -{ - u32 dummy; - - if (bcm->current_core->rev < 5) - return; - /* Read all entries from the microcode TXstatus FIFO - * and throw them away. - */ - while (1) { - dummy = bcm43xx_read32(bcm, BCM43xx_MMIO_XMITSTAT_0); - if (!dummy) - break; - dummy = bcm43xx_read32(bcm, BCM43xx_MMIO_XMITSTAT_1); - } -} - static void bcm43xx_generate_noise_sample(struct bcm43xx_private *bcm) { bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x408, 0x7F7F); @@ -1851,7 +1834,7 @@ static void bcm43xx_interrupt_ack(struct bcm43xx_private *bcm, u32 reason) } /* Interrupt handler top-half */ -static irqreturn_t bcm43xx_interrupt_handler(int irq, void *dev_id) +static irqreturn_t bcm43xx_interrupt_handler(int irq, void *dev_id, struct pt_regs *regs) { irqreturn_t ret = IRQ_HANDLED; struct bcm43xx_private *bcm = dev_id; @@ -2942,13 +2925,10 @@ static int bcm43xx_wireless_core_init(struct bcm43xx_private *bcm, bcm43xx_write16(bcm, 0x043C, 0x000C); if (active_wlcore) { - if (bcm43xx_using_pio(bcm)) { + if (bcm43xx_using_pio(bcm)) err = bcm43xx_pio_init(bcm); - } else { + else err = bcm43xx_dma_init(bcm); - if (err == -ENOSYS) - err = bcm43xx_pio_init(bcm); - } if (err) goto err_chip_cleanup; } @@ -3180,30 +3160,17 @@ static int estimate_periodic_work_badness(unsigned int state) static void bcm43xx_periodic_work_handler(void *d) { struct bcm43xx_private *bcm = d; - struct net_device *net_dev = bcm->net_dev; unsigned long flags; u32 savedirqs = 0; int badness; - unsigned long orig_trans_start = 0; - mutex_lock(&bcm->mutex); badness = estimate_periodic_work_badness(bcm->periodic_state); if (badness > BADNESS_LIMIT) { /* Periodic work will take a long time, so we want it to * be preemtible. */ - - netif_tx_lock_bh(net_dev); - /* We must fake a started transmission here, as we are going to - * disable TX. If we wouldn't fake a TX, it would be possible to - * trigger the netdev watchdog, if the last real TX is already - * some time on the past (slightly less than 5secs) - */ - orig_trans_start = net_dev->trans_start; - net_dev->trans_start = jiffies; - netif_stop_queue(net_dev); - netif_tx_unlock_bh(net_dev); - + mutex_lock(&bcm->mutex); + netif_tx_disable(bcm->net_dev); spin_lock_irqsave(&bcm->irq_lock, flags); bcm43xx_mac_suspend(bcm); if (bcm43xx_using_pio(bcm)) @@ -3215,6 +3182,7 @@ static void bcm43xx_periodic_work_handler(void *d) /* Periodic work should take short time, so we want low * locking overhead. */ + mutex_lock(&bcm->mutex); spin_lock_irqsave(&bcm->irq_lock, flags); } @@ -3228,7 +3196,6 @@ static void bcm43xx_periodic_work_handler(void *d) bcm43xx_pio_thaw_txqueues(bcm); bcm43xx_mac_enable(bcm); netif_wake_queue(bcm->net_dev); - net_dev->trans_start = orig_trans_start; } mmiowb(); spin_unlock_irqrestore(&bcm->irq_lock, flags); @@ -3549,7 +3516,6 @@ int bcm43xx_select_wireless_core(struct bcm43xx_private *bcm, bcm43xx_macfilter_clear(bcm, BCM43xx_MACFILTER_ASSOC); bcm43xx_macfilter_set(bcm, BCM43xx_MACFILTER_SELF, (u8 *)(bcm->net_dev->dev_addr)); bcm43xx_security_init(bcm); - drain_txstatus_queue(bcm); ieee80211softmac_start(bcm->net_dev); /* Let's go! Be careful after enabling the IRQs. @@ -3997,7 +3963,7 @@ static void bcm43xx_net_poll_controller(struct net_device *net_dev) local_irq_save(flags); if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) - bcm43xx_interrupt_handler(bcm->irq, bcm); + bcm43xx_interrupt_handler(bcm->irq, bcm, NULL); local_irq_restore(flags); } #endif /* CONFIG_NET_POLL_CONTROLLER */ @@ -4027,6 +3993,8 @@ static int bcm43xx_init_private(struct bcm43xx_private *bcm, struct net_device *net_dev, struct pci_dev *pci_dev) { + int err; + bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT); bcm->ieee = netdev_priv(net_dev); bcm->softmac = ieee80211_priv(net_dev); @@ -4044,8 +4012,22 @@ static int bcm43xx_init_private(struct bcm43xx_private *bcm, (void (*)(unsigned long))bcm43xx_interrupt_tasklet, (unsigned long)bcm); tasklet_disable_nosync(&bcm->isr_tasklet); - if (modparam_pio) + if (modparam_pio) { bcm->__using_pio = 1; + } else { + err = pci_set_dma_mask(pci_dev, DMA_30BIT_MASK); + err |= pci_set_consistent_dma_mask(pci_dev, DMA_30BIT_MASK); + if (err) { +#ifdef CONFIG_BCM43XX_PIO + printk(KERN_WARNING PFX "DMA not supported. Falling back to PIO.\n"); + bcm->__using_pio = 1; +#else + printk(KERN_ERR PFX "FATAL: DMA not supported and PIO not configured. " + "Recompile the driver with PIO support, please.\n"); + return -ENODEV; +#endif /* CONFIG_BCM43XX_PIO */ + } + } bcm->rts_threshold = BCM43xx_DEFAULT_RTS_THRESHOLD; /* default to sw encryption for now */ @@ -4226,11 +4208,7 @@ static int bcm43xx_resume(struct pci_dev *pdev) dprintk(KERN_INFO PFX "Resuming...\n"); pci_set_power_state(pdev, 0); - err = pci_enable_device(pdev); - if (err) { - printk(KERN_ERR PFX "Failure with pci_enable_device!\n"); - return err; - } + pci_enable_device(pdev); pci_restore_state(pdev); bcm43xx_chipset_attach(bcm); diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_wx.c b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_wx.c index d27016f8c736..9b7b15cf6561 100644 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_wx.c +++ b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_wx.c @@ -847,7 +847,7 @@ static struct iw_statistics *bcm43xx_get_wireless_stats(struct net_device *net_d unsigned long flags; wstats = &bcm->stats.wstats; - if (!mac->associnfo.associated) { + if (!mac->associated) { wstats->miss.beacon = 0; // bcm->ieee->ieee_stats.tx_retry_limit_exceeded = 0; // FIXME: should this be cleared here? wstats->discard.retries = 0; diff --git a/trunk/drivers/net/wireless/hostap/hostap_cs.c b/trunk/drivers/net/wireless/hostap/hostap_cs.c index f63909e4bc32..686d895116de 100644 --- a/trunk/drivers/net/wireless/hostap/hostap_cs.c +++ b/trunk/drivers/net/wireless/hostap/hostap_cs.c @@ -887,13 +887,6 @@ static struct pcmcia_device_id hostap_cs_ids[] = { PCMCIA_DEVICE_PROD_ID123( "U.S. Robotics", "IEEE 802.11b PC-CARD", "Version 01.02", 0xc7b8df9d, 0x1700d087, 0x4b74baa0), - PCMCIA_DEVICE_PROD_ID123( - "Allied Telesyn", "AT-WCL452 Wireless PCMCIA Radio", - "Ver. 1.00", - 0x5cd01705, 0x4271660f, 0x9d08ee12), - PCMCIA_DEVICE_PROD_ID123( - "corega", "WL PCCL-11", "ISL37300P", - 0xa21501a, 0x59868926, 0xc9049a39), PCMCIA_DEVICE_NULL }; MODULE_DEVICE_TABLE(pcmcia, hostap_cs_ids); diff --git a/trunk/drivers/net/wireless/hostap/hostap_hw.c b/trunk/drivers/net/wireless/hostap/hostap_hw.c index ed00ebb6e7f4..d500012fdc7a 100644 --- a/trunk/drivers/net/wireless/hostap/hostap_hw.c +++ b/trunk/drivers/net/wireless/hostap/hostap_hw.c @@ -2622,7 +2622,7 @@ static void prism2_check_magic(local_info_t *local) /* Called only from hardware IRQ */ -static irqreturn_t prism2_interrupt(int irq, void *dev_id) +static irqreturn_t prism2_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_id; struct hostap_interface *iface; diff --git a/trunk/drivers/net/wireless/hostap/hostap_plx.c b/trunk/drivers/net/wireless/hostap/hostap_plx.c index bc81b13a5a2a..6dfa041be66d 100644 --- a/trunk/drivers/net/wireless/hostap/hostap_plx.c +++ b/trunk/drivers/net/wireless/hostap/hostap_plx.c @@ -364,7 +364,7 @@ static int prism2_plx_check_cis(void __iomem *attr_mem, int attr_len, pos = 0; while (pos < CIS_MAX_LEN - 1 && cis[pos] != CISTPL_END) { - if (pos + 2 + cis[pos + 1] > CIS_MAX_LEN) + if (pos + cis[pos + 1] >= CIS_MAX_LEN) goto cis_error; switch (cis[pos]) { @@ -391,7 +391,7 @@ static int prism2_plx_check_cis(void __iomem *attr_mem, int attr_len, break; case CISTPL_MANFID: - if (cis[pos + 1] < 4) + if (cis[pos + 1] < 5) goto cis_error; manfid1 = cis[pos + 2] + (cis[pos + 3] << 8); manfid2 = cis[pos + 4] + (cis[pos + 5] << 8); diff --git a/trunk/drivers/net/wireless/ipw2100.c b/trunk/drivers/net/wireless/ipw2100.c index 4e4eaa2a99ca..599e2fe76188 100644 --- a/trunk/drivers/net/wireless/ipw2100.c +++ b/trunk/drivers/net/wireless/ipw2100.c @@ -3255,7 +3255,7 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv) IPW_DEBUG_ISR("exit\n"); } -static irqreturn_t ipw2100_interrupt(int irq, void *data) +static irqreturn_t ipw2100_interrupt(int irq, void *data, struct pt_regs *regs) { struct ipw2100_priv *priv = data; u32 inta, inta_mask; diff --git a/trunk/drivers/net/wireless/ipw2200.c b/trunk/drivers/net/wireless/ipw2200.c index 72120d5c2f7b..5685d7ba55bb 100644 --- a/trunk/drivers/net/wireless/ipw2200.c +++ b/trunk/drivers/net/wireless/ipw2200.c @@ -6920,8 +6920,8 @@ static int ipw_qos_association(struct ipw_priv *priv, } /* -* handling the beaconing responses. if we get different QoS setting -* off the network from the associated setting, adjust the QoS +* handling the beaconing responces. if we get different QoS setting +* of the network from the the associated setting adjust the QoS * setting */ static int ipw_qos_association_resp(struct ipw_priv *priv, @@ -10467,7 +10467,7 @@ static const struct ethtool_ops ipw_ethtool_ops = { .set_eeprom = ipw_ethtool_set_eeprom, }; -static irqreturn_t ipw_isr(int irq, void *data) +static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs) { struct ipw_priv *priv = data; u32 inta, inta_mask; diff --git a/trunk/drivers/net/wireless/netwave_cs.c b/trunk/drivers/net/wireless/netwave_cs.c index 6714e0dfa8d6..36b5e004305e 100644 --- a/trunk/drivers/net/wireless/netwave_cs.c +++ b/trunk/drivers/net/wireless/netwave_cs.c @@ -207,7 +207,7 @@ static int netwave_start_xmit( struct sk_buff *skb, struct net_device *dev); static int netwave_rx( struct net_device *dev); /* Interrupt routines */ -static irqreturn_t netwave_interrupt(int irq, void *dev_id); +static irqreturn_t netwave_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void netwave_watchdog(struct net_device *); /* Statistics */ @@ -1072,7 +1072,7 @@ static int netwave_start_xmit(struct sk_buff *skb, struct net_device *dev) { } /* netwave_start_xmit */ /* - * Function netwave_interrupt (irq, dev_id) + * Function netwave_interrupt (irq, dev_id, regs) * * This function is the interrupt handler for the Netwave card. This * routine will be called whenever: @@ -1081,7 +1081,7 @@ static int netwave_start_xmit(struct sk_buff *skb, struct net_device *dev) { * ready to transmit another packet. * 3. A command has completed execution. */ -static irqreturn_t netwave_interrupt(int irq, void* dev_id) +static irqreturn_t netwave_interrupt(int irq, void* dev_id, struct pt_regs *regs) { kio_addr_t iobase; u_char __iomem *ramBase; diff --git a/trunk/drivers/net/wireless/orinoco.c b/trunk/drivers/net/wireless/orinoco.c index 336cabac13b3..9e19a963febc 100644 --- a/trunk/drivers/net/wireless/orinoco.c +++ b/trunk/drivers/net/wireless/orinoco.c @@ -1952,9 +1952,9 @@ static void __orinoco_ev_wterr(struct net_device *dev, hermes_t *hw) dev->name); } -irqreturn_t orinoco_interrupt(int irq, void *dev_id) +irqreturn_t orinoco_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct net_device *dev = dev_id; + struct net_device *dev = (struct net_device *)dev_id; struct orinoco_private *priv = netdev_priv(dev); hermes_t *hw = &priv->hw; int count = MAX_IRQLOOPS_PER_IRQ; @@ -2457,7 +2457,6 @@ void free_orinocodev(struct net_device *dev) /* Wireless extensions */ /********************************************************************/ -/* Return : < 0 -> error code ; >= 0 -> length */ static int orinoco_hw_get_essid(struct orinoco_private *priv, int *active, char buf[IW_ESSID_MAX_SIZE+1]) { @@ -2502,9 +2501,9 @@ static int orinoco_hw_get_essid(struct orinoco_private *priv, int *active, len = le16_to_cpu(essidbuf.len); BUG_ON(len > IW_ESSID_MAX_SIZE); - memset(buf, 0, IW_ESSID_MAX_SIZE); + memset(buf, 0, IW_ESSID_MAX_SIZE+1); memcpy(buf, p, len); - err = len; + buf[len] = '\0'; fail_unlock: orinoco_unlock(priv, &flags); @@ -3028,18 +3027,17 @@ static int orinoco_ioctl_getessid(struct net_device *dev, if (netif_running(dev)) { err = orinoco_hw_get_essid(priv, &active, essidbuf); - if (err < 0) + if (err) return err; - erq->length = err; } else { if (orinoco_lock(priv, &flags) != 0) return -EBUSY; - memcpy(essidbuf, priv->desired_essid, IW_ESSID_MAX_SIZE); - erq->length = strlen(priv->desired_essid); + memcpy(essidbuf, priv->desired_essid, IW_ESSID_MAX_SIZE + 1); orinoco_unlock(priv, &flags); } erq->flags = 1; + erq->length = strlen(essidbuf); return 0; } @@ -3077,10 +3075,10 @@ static int orinoco_ioctl_getnick(struct net_device *dev, if (orinoco_lock(priv, &flags) != 0) return -EBUSY; - memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE); + memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE+1); orinoco_unlock(priv, &flags); - nrq->length = strlen(priv->nick); + nrq->length = strlen(nickbuf); return 0; } diff --git a/trunk/drivers/net/wireless/orinoco.h b/trunk/drivers/net/wireless/orinoco.h index 4720fb20d66d..fb5700d6c454 100644 --- a/trunk/drivers/net/wireless/orinoco.h +++ b/trunk/drivers/net/wireless/orinoco.h @@ -128,7 +128,7 @@ extern void free_orinocodev(struct net_device *dev); extern int __orinoco_up(struct net_device *dev); extern int __orinoco_down(struct net_device *dev); extern int orinoco_reinit_firmware(struct net_device *dev); -extern irqreturn_t orinoco_interrupt(int irq, void * dev_id); +extern irqreturn_t orinoco_interrupt(int irq, void * dev_id, struct pt_regs *regs); /********************************************************************/ /* Locking and synchronization functions */ diff --git a/trunk/drivers/net/wireless/prism54/islpci_dev.c b/trunk/drivers/net/wireless/prism54/islpci_dev.c index ec1c00f19eb3..ab3c5a27efd9 100644 --- a/trunk/drivers/net/wireless/prism54/islpci_dev.c +++ b/trunk/drivers/net/wireless/prism54/islpci_dev.c @@ -182,7 +182,7 @@ isl_upload_firmware(islpci_private *priv) ******************************************************************************/ irqreturn_t -islpci_interrupt(int irq, void *config) +islpci_interrupt(int irq, void *config, struct pt_regs *regs) { u32 reg; islpci_private *priv = config; diff --git a/trunk/drivers/net/wireless/prism54/islpci_dev.h b/trunk/drivers/net/wireless/prism54/islpci_dev.h index 2f7e525d0cf6..5049f37455b1 100644 --- a/trunk/drivers/net/wireless/prism54/islpci_dev.h +++ b/trunk/drivers/net/wireless/prism54/islpci_dev.h @@ -198,7 +198,7 @@ islpci_state_t islpci_set_state(islpci_private *priv, islpci_state_t new_state); #define ISLPCI_TX_TIMEOUT (2*HZ) -irqreturn_t islpci_interrupt(int, void *); +irqreturn_t islpci_interrupt(int, void *, struct pt_regs *); int prism54_post_setup(islpci_private *, int); int islpci_reset(islpci_private *, int); diff --git a/trunk/drivers/net/wireless/ray_cs.c b/trunk/drivers/net/wireless/ray_cs.c index 7fbfc9e41d07..e82548ea609a 100644 --- a/trunk/drivers/net/wireless/ray_cs.c +++ b/trunk/drivers/net/wireless/ray_cs.c @@ -130,7 +130,7 @@ static void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value, i static void verify_dl_startup(u_long); /* Prototypes for interrpt time functions **********************************/ -static irqreturn_t ray_interrupt (int reg, void *dev_id); +static irqreturn_t ray_interrupt (int reg, void *dev_id, struct pt_regs *regs); static void clear_interrupt(ray_dev_t *local); static void rx_deauthenticate(ray_dev_t *local, struct rcs __iomem *prcs, unsigned int pkt_addr, int rx_len); @@ -1198,6 +1198,7 @@ static int ray_get_essid(struct net_device *dev, /* Get the essid that was set */ memcpy(extra, local->sparm.b5.a_current_ess_id, IW_ESSID_MAX_SIZE); + extra[IW_ESSID_MAX_SIZE] = '\0'; /* Push it out ! */ dwrq->length = strlen(extra); @@ -1939,7 +1940,7 @@ static void set_multicast_list(struct net_device *dev) /*============================================================================= * All routines below here are run at interrupt time. =============================================================================*/ -static irqreturn_t ray_interrupt(int irq, void *dev_id) +static irqreturn_t ray_interrupt(int irq, void *dev_id, struct pt_regs * regs) { struct net_device *dev = (struct net_device *)dev_id; struct pcmcia_device *link; diff --git a/trunk/drivers/net/wireless/wavelan.c b/trunk/drivers/net/wireless/wavelan.c index 24221e476cd3..5b69befdab74 100644 --- a/trunk/drivers/net/wireless/wavelan.c +++ b/trunk/drivers/net/wireless/wavelan.c @@ -3768,7 +3768,7 @@ static int wv_check_ioaddr(unsigned long ioaddr, u8 * mac) * This function is the interrupt handler for the WaveLAN card. This * routine will be called whenever: */ -static irqreturn_t wavelan_interrupt(int irq, void *dev_id) +static irqreturn_t wavelan_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev; unsigned long ioaddr; diff --git a/trunk/drivers/net/wireless/wavelan.p.h b/trunk/drivers/net/wireless/wavelan.p.h index 72b646c77d5a..5cb0bc8bb128 100644 --- a/trunk/drivers/net/wireless/wavelan.p.h +++ b/trunk/drivers/net/wireless/wavelan.p.h @@ -642,7 +642,8 @@ static int /* ---------------------- INTERRUPT HANDLING ---------------------- */ static irqreturn_t wavelan_interrupt(int, /* interrupt handler */ - void *); + void *, + struct pt_regs *); static void wavelan_watchdog(struct net_device *); /* transmission watchdog */ /* ------------------- CONFIGURATION CALLBACKS ------------------- */ diff --git a/trunk/drivers/net/wireless/wavelan_cs.c b/trunk/drivers/net/wireless/wavelan_cs.c index aafb301041b1..0065f057bb1c 100644 --- a/trunk/drivers/net/wireless/wavelan_cs.c +++ b/trunk/drivers/net/wireless/wavelan_cs.c @@ -4117,14 +4117,24 @@ wv_pcmcia_release(struct pcmcia_device *link) */ static irqreturn_t wavelan_interrupt(int irq, - void * dev_id) + void * dev_id, + struct pt_regs * regs) { - struct net_device * dev = dev_id; + struct net_device * dev; net_local * lp; kio_addr_t base; int status0; u_int tx_status; + if ((dev = dev_id) == NULL) + { +#ifdef DEBUG_INTERRUPT_ERROR + printk(KERN_WARNING "wavelan_interrupt(): irq %d for unknown device.\n", + irq); +#endif + return IRQ_NONE; + } + #ifdef DEBUG_INTERRUPT_TRACE printk(KERN_DEBUG "%s: ->wavelan_interrupt()\n", dev->name); #endif diff --git a/trunk/drivers/net/wireless/wavelan_cs.p.h b/trunk/drivers/net/wireless/wavelan_cs.p.h index 4d1c4905c749..f34a36b0c7b0 100644 --- a/trunk/drivers/net/wireless/wavelan_cs.p.h +++ b/trunk/drivers/net/wireless/wavelan_cs.p.h @@ -738,7 +738,8 @@ static void /* ---------------------- INTERRUPT HANDLING ---------------------- */ static irqreturn_t wavelan_interrupt(int, /* Interrupt handler */ - void *); + void *, + struct pt_regs *); static void wavelan_watchdog(struct net_device *); /* Transmission watchdog */ /* ------------------- CONFIGURATION CALLBACKS ------------------- */ diff --git a/trunk/drivers/net/wireless/wl3501_cs.c b/trunk/drivers/net/wireless/wl3501_cs.c index 5b98a7876982..e3ae5f60d5be 100644 --- a/trunk/drivers/net/wireless/wl3501_cs.c +++ b/trunk/drivers/net/wireless/wl3501_cs.c @@ -1145,6 +1145,7 @@ static inline void wl3501_ack_interrupt(struct wl3501_card *this) * wl3501_interrupt - Hardware interrupt from card. * @irq - Interrupt number * @dev_id - net_device + * @regs - registers * * We must acknowledge the interrupt as soon as possible, and block the * interrupt from the same card immediately to prevent re-entry. @@ -1153,20 +1154,27 @@ static inline void wl3501_ack_interrupt(struct wl3501_card *this) * On the other hand, to prevent SUTRO from malfunctioning, we must * unlock the SUTRO as soon as possible. */ -static irqreturn_t wl3501_interrupt(int irq, void *dev_id) +static irqreturn_t wl3501_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct net_device *dev = dev_id; + struct net_device *dev = (struct net_device *)dev_id; struct wl3501_card *this; + int handled = 1; - this = netdev_priv(dev); + if (!dev) + goto unknown; + this = dev->priv; spin_lock(&this->lock); wl3501_ack_interrupt(this); wl3501_block_interrupt(this); wl3501_rx_interrupt(dev); wl3501_unblock_interrupt(this); spin_unlock(&this->lock); - - return IRQ_HANDLED; +out: + return IRQ_RETVAL(handled); +unknown: + handled = 0; + printk(KERN_ERR "%s: irq %d for unknown device.\n", __FUNCTION__, irq); + goto out; } static int wl3501_reset_board(struct wl3501_card *this) diff --git a/trunk/drivers/net/wireless/zd1201.c b/trunk/drivers/net/wireless/zd1201.c index 6cb66a356c96..80af9a9fcbb3 100644 --- a/trunk/drivers/net/wireless/zd1201.c +++ b/trunk/drivers/net/wireless/zd1201.c @@ -112,7 +112,7 @@ static int zd1201_fw_upload(struct usb_device *dev, int apfw) return err; } -static void zd1201_usbfree(struct urb *urb) +static void zd1201_usbfree(struct urb *urb, struct pt_regs *regs) { struct zd1201 *zd = urb->context; @@ -177,7 +177,7 @@ static int zd1201_docmd(struct zd1201 *zd, int cmd, int parm0, } /* Callback after sending out a packet */ -static void zd1201_usbtx(struct urb *urb) +static void zd1201_usbtx(struct urb *urb, struct pt_regs *regs) { struct zd1201 *zd = urb->context; netif_wake_queue(zd->dev); @@ -185,7 +185,7 @@ static void zd1201_usbtx(struct urb *urb) } /* Incoming data */ -static void zd1201_usbrx(struct urb *urb) +static void zd1201_usbrx(struct urb *urb, struct pt_regs *regs) { struct zd1201 *zd = urb->context; int free = 0; @@ -193,8 +193,10 @@ static void zd1201_usbrx(struct urb *urb) struct sk_buff *skb; unsigned char type; - if (!zd) - return; + if (!zd) { + free = 1; + goto exit; + } switch(urb->status) { case -EILSEQ: @@ -1828,8 +1830,10 @@ static int zd1201_probe(struct usb_interface *interface, /* Leave the device in reset state */ zd1201_docmd(zd, ZD1201_CMDCODE_INIT, 0, 0, 0); err_zd: - usb_free_urb(zd->tx_urb); - usb_free_urb(zd->rx_urb); + if (zd->tx_urb) + usb_free_urb(zd->tx_urb); + if (zd->rx_urb) + usb_free_urb(zd->rx_urb); kfree(zd); return err; } diff --git a/trunk/drivers/net/wireless/zd1211rw/zd_mac.c b/trunk/drivers/net/wireless/zd1211rw/zd_mac.c index a7d29bddb298..2d12837052b0 100644 --- a/trunk/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/trunk/drivers/net/wireless/zd1211rw/zd_mac.c @@ -1099,7 +1099,7 @@ static void link_led_handler(void *p) int r; spin_lock_irq(&mac->lock); - is_associated = sm->associnfo.associated != 0; + is_associated = sm->associated != 0; spin_unlock_irq(&mac->lock); r = zd_chip_control_leds(chip, diff --git a/trunk/drivers/net/wireless/zd1211rw/zd_usb.c b/trunk/drivers/net/wireless/zd1211rw/zd_usb.c index 3faaeb2b7c89..5c265ad0485a 100644 --- a/trunk/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/trunk/drivers/net/wireless/zd1211rw/zd_usb.c @@ -408,7 +408,7 @@ static inline void handle_retry_failed_int(struct urb *urb) } -static void int_urb_complete(struct urb *urb) +static void int_urb_complete(struct urb *urb, struct pt_regs *pt_regs) { int r; struct usb_int_header *hdr; @@ -609,7 +609,7 @@ static void handle_rx_packet(struct zd_usb *usb, const u8 *buffer, } } -static void rx_urb_complete(struct urb *urb) +static void rx_urb_complete(struct urb *urb, struct pt_regs *pt_regs) { struct zd_usb *usb; struct zd_usb_rx *rx; @@ -779,7 +779,7 @@ void zd_usb_disable_rx(struct zd_usb *usb) spin_unlock_irqrestore(&rx->lock, flags); } -static void tx_urb_complete(struct urb *urb) +static void tx_urb_complete(struct urb *urb, struct pt_regs *pt_regs) { int r; diff --git a/trunk/drivers/net/yellowfin.c b/trunk/drivers/net/yellowfin.c index 2412ce4917f2..a4c4953f1365 100644 --- a/trunk/drivers/net/yellowfin.c +++ b/trunk/drivers/net/yellowfin.c @@ -350,7 +350,7 @@ static void yellowfin_timer(unsigned long data); static void yellowfin_tx_timeout(struct net_device *dev); static void yellowfin_init_ring(struct net_device *dev); static int yellowfin_start_xmit(struct sk_buff *skb, struct net_device *dev); -static irqreturn_t yellowfin_interrupt(int irq, void *dev_instance); +static irqreturn_t yellowfin_interrupt(int irq, void *dev_instance, struct pt_regs *regs); static int yellowfin_rx(struct net_device *dev); static void yellowfin_error(struct net_device *dev, int intr_status); static int yellowfin_close(struct net_device *dev); @@ -888,7 +888,7 @@ static int yellowfin_start_xmit(struct sk_buff *skb, struct net_device *dev) /* The interrupt handler does all of the Rx thread work and cleans up after the Tx thread. */ -static irqreturn_t yellowfin_interrupt(int irq, void *dev_instance) +static irqreturn_t yellowfin_interrupt(int irq, void *dev_instance, struct pt_regs *regs) { struct net_device *dev = dev_instance; struct yellowfin_private *yp; @@ -896,6 +896,13 @@ static irqreturn_t yellowfin_interrupt(int irq, void *dev_instance) int boguscnt = max_interrupt_work; unsigned int handled = 0; +#ifndef final_version /* Can never occur. */ + if (dev == NULL) { + printk (KERN_ERR "yellowfin_interrupt(): irq %d for unknown device.\n", irq); + return IRQ_NONE; + } +#endif + yp = netdev_priv(dev); ioaddr = yp->base; diff --git a/trunk/drivers/net/znet.c b/trunk/drivers/net/znet.c index b24b0727108c..656d5a02908b 100644 --- a/trunk/drivers/net/znet.c +++ b/trunk/drivers/net/znet.c @@ -158,7 +158,7 @@ struct netidblk { static int znet_open(struct net_device *dev); static int znet_send_packet(struct sk_buff *skb, struct net_device *dev); -static irqreturn_t znet_interrupt(int irq, void *dev_id); +static irqreturn_t znet_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void znet_rx(struct net_device *dev); static int znet_close(struct net_device *dev); static struct net_device_stats *net_get_stats(struct net_device *dev); @@ -602,7 +602,7 @@ static int znet_send_packet(struct sk_buff *skb, struct net_device *dev) } /* The ZNET interrupt handler. */ -static irqreturn_t znet_interrupt(int irq, void *dev_id) +static irqreturn_t znet_interrupt(int irq, void *dev_id, struct pt_regs * regs) { struct net_device *dev = dev_id; struct znet_private *znet = dev->priv; @@ -610,6 +610,11 @@ static irqreturn_t znet_interrupt(int irq, void *dev_id) int boguscnt = 20; int handled = 0; + if (dev == NULL) { + printk(KERN_WARNING "znet_interrupt(): IRQ %d for unknown device.\n", irq); + return IRQ_NONE; + } + spin_lock (&znet->lock); ioaddr = dev->base_addr; diff --git a/trunk/drivers/parisc/ccio-dma.c b/trunk/drivers/parisc/ccio-dma.c index fe3f5f5365c5..68cb3a080050 100644 --- a/trunk/drivers/parisc/ccio-dma.c +++ b/trunk/drivers/parisc/ccio-dma.c @@ -486,7 +486,7 @@ typedef unsigned long space_t; ** This bit tells U2 to do R/M/W for partial cachelines. "Streaming" ** data can avoid this if the mapping covers full cache lines. ** o STOP_MOST is needed for atomicity across cachelines. -** Apparently only "some EISA devices" need this. +** Apperently only "some EISA devices" need this. ** Using CONFIG_ISA is hack. Only the IOA with EISA under it needs ** to use this hint iff the EISA devices needs this feature. ** According to the U2 ERS, STOP_MOST enabled pages hurt performance. diff --git a/trunk/drivers/parisc/dino.c b/trunk/drivers/parisc/dino.c index 03c763c2d0e0..0d96c50ffe9c 100644 --- a/trunk/drivers/parisc/dino.c +++ b/trunk/drivers/parisc/dino.c @@ -368,7 +368,8 @@ static struct hw_interrupt_type dino_interrupt_type = { * ilr_loop counter is a kluge to prevent a "stuck" IRQ line from * wedging the CPU. Could be removed or made optional at some point. */ -static irqreturn_t dino_isr(int irq, void *intr_dev) +static irqreturn_t +dino_isr(int irq, void *intr_dev, struct pt_regs *regs) { struct dino_device *dino_dev = intr_dev; u32 mask; @@ -389,7 +390,7 @@ static irqreturn_t dino_isr(int irq, void *intr_dev) int irq = dino_dev->global_irq[local_irq]; DBG(KERN_DEBUG "%s(%d, %p) mask 0x%x\n", __FUNCTION__, irq, intr_dev, mask); - __do_IRQ(irq); + __do_IRQ(irq, regs); mask &= ~(1 << local_irq); } while (mask); diff --git a/trunk/drivers/parisc/eisa.c b/trunk/drivers/parisc/eisa.c index e97cecbc4d18..884965cedec9 100644 --- a/trunk/drivers/parisc/eisa.c +++ b/trunk/drivers/parisc/eisa.c @@ -199,7 +199,7 @@ static struct hw_interrupt_type eisa_interrupt_type = { .end = no_end_irq, }; -static irqreturn_t eisa_irq(int wax_irq, void *intr_dev) +static irqreturn_t eisa_irq(int wax_irq, void *intr_dev, struct pt_regs *regs) { int irq = gsc_readb(0xfc01f000); /* EISA supports 16 irqs */ unsigned long flags; @@ -234,7 +234,7 @@ static irqreturn_t eisa_irq(int wax_irq, void *intr_dev) } spin_unlock_irqrestore(&eisa_irq_lock, flags); - __do_IRQ(irq); + __do_IRQ(irq, regs); spin_lock_irqsave(&eisa_irq_lock, flags); /* unmask */ @@ -249,7 +249,7 @@ static irqreturn_t eisa_irq(int wax_irq, void *intr_dev) return IRQ_HANDLED; } -static irqreturn_t dummy_irq2_handler(int _, void *dev) +static irqreturn_t dummy_irq2_handler(int _, void *dev, struct pt_regs *regs) { printk(KERN_ALERT "eisa: uhh, irq2?\n"); return IRQ_HANDLED; diff --git a/trunk/drivers/parisc/gsc.c b/trunk/drivers/parisc/gsc.c index 1b3e3fd12d95..b45aa5c675a0 100644 --- a/trunk/drivers/parisc/gsc.c +++ b/trunk/drivers/parisc/gsc.c @@ -73,7 +73,7 @@ EXPORT_SYMBOL(gsc_alloc_irq); EXPORT_SYMBOL(gsc_claim_irq); /* Common interrupt demultiplexer used by Asp, Lasi & Wax. */ -irqreturn_t gsc_asic_intr(int gsc_asic_irq, void *dev) +irqreturn_t gsc_asic_intr(int gsc_asic_irq, void *dev, struct pt_regs *regs) { unsigned long irr; struct gsc_asic *gsc_asic = dev; @@ -87,7 +87,7 @@ irqreturn_t gsc_asic_intr(int gsc_asic_irq, void *dev) do { int local_irq = __ffs(irr); unsigned int irq = gsc_asic->global_irq[local_irq]; - __do_IRQ(irq); + __do_IRQ(irq, regs); irr &= ~(1 << local_irq); } while (irr); diff --git a/trunk/drivers/parisc/gsc.h b/trunk/drivers/parisc/gsc.h index 762a1babad60..a3dc456709d7 100644 --- a/trunk/drivers/parisc/gsc.h +++ b/trunk/drivers/parisc/gsc.h @@ -44,4 +44,4 @@ void gsc_fixup_irqs(struct parisc_device *parent, void *ctrl, void (*choose)(struct parisc_device *child, void *ctrl)); void gsc_asic_assign_irq(struct gsc_asic *asic, int local_irq, int *irqp); -irqreturn_t gsc_asic_intr(int irq, void *dev); +irqreturn_t gsc_asic_intr(int irq, void *dev, struct pt_regs *regs); diff --git a/trunk/drivers/parisc/iosapic.c b/trunk/drivers/parisc/iosapic.c index 12bab64a62a1..c2949b4367e5 100644 --- a/trunk/drivers/parisc/iosapic.c +++ b/trunk/drivers/parisc/iosapic.c @@ -50,12 +50,12 @@ ** ** PA Firmware ** ----------- -** PA-RISC platforms have two fundamentally different types of firmware. +** PA-RISC platforms have two fundementally different types of firmware. ** For PCI devices, "Legacy" PDC initializes the "INTERRUPT_LINE" register ** and BARs similar to a traditional PC BIOS. ** The newer "PAT" firmware supports PDC calls which return tables. -** PAT firmware only initializes the PCI Console and Boot interface. -** With these tables, the OS can program all other PCI devices. +** PAT firmware only initializes PCI Console and Boot interface. +** With these tables, the OS can progam all other PCI devices. ** ** One such PAT PDC call returns the "Interrupt Routing Table" (IRT). ** The IRT maps each PCI slot's INTA-D "output" line to an I/O SAPIC diff --git a/trunk/drivers/parisc/power.c b/trunk/drivers/parisc/power.c index 97e9dc066f95..2eb3577a88c5 100644 --- a/trunk/drivers/parisc/power.c +++ b/trunk/drivers/parisc/power.c @@ -188,7 +188,7 @@ static void polling_tasklet_func(unsigned long soft_power_reg) * powerfail interruption handler (irq IRQ_FROM_REGION(CPU_IRQ_REGION)+2) */ #if 0 -static void powerfail_interrupt(int code, void *x) +static void powerfail_interrupt(int code, void *x, struct pt_regs *regs) { printk(KERN_CRIT "POWERFAIL INTERRUPTION !\n"); poweroff(); diff --git a/trunk/drivers/parisc/sba_iommu.c b/trunk/drivers/parisc/sba_iommu.c index f1e7ccd5475b..294c1117098d 100644 --- a/trunk/drivers/parisc/sba_iommu.c +++ b/trunk/drivers/parisc/sba_iommu.c @@ -1320,12 +1320,12 @@ sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num) ** the GART code to handshake on. */ klist_iter_init(&sba->dev.klist_children, &i); - while ((dev = next_device(&i))) { + while (dev = next_device(&i)) { struct parisc_device *lba = to_parisc_device(dev); if (IS_QUICKSILVER(lba)) agp_found = 1; } - klist_iter_exit(&i); + klist_iter_exit(&sba->dev.klist_children, &i); if (agp_found && sba_reserve_agpgart) { printk(KERN_INFO "%s: reserving %dMb of IOVA space for agpgart\n", diff --git a/trunk/drivers/parisc/superio.c b/trunk/drivers/parisc/superio.c index 1fd97f7c8b98..4ee26a6d9e25 100644 --- a/trunk/drivers/parisc/superio.c +++ b/trunk/drivers/parisc/superio.c @@ -94,7 +94,7 @@ static struct superio_device sio_dev; #define PFX SUPERIO ": " static irqreturn_t -superio_interrupt(int parent_irq, void *devp) +superio_interrupt(int parent_irq, void *devp, struct pt_regs *regs) { u8 results; u8 local_irq; @@ -138,7 +138,7 @@ superio_interrupt(int parent_irq, void *devp) } /* Call the appropriate device's interrupt */ - __do_IRQ(local_irq); + __do_IRQ(local_irq, regs); /* set EOI - forces a new interrupt if a lower priority device * still needs service. diff --git a/trunk/drivers/parport/daisy.c b/trunk/drivers/parport/daisy.c index ff9f34453530..83ee095ec6e2 100644 --- a/trunk/drivers/parport/daisy.c +++ b/trunk/drivers/parport/daisy.c @@ -216,7 +216,7 @@ void parport_daisy_fini(struct parport *port) struct pardevice *parport_open(int devnum, const char *name, int (*pf) (void *), void (*kf) (void *), - void (*irqf) (int, void *), + void (*irqf) (int, void *, struct pt_regs *), int flags, void *handle) { struct daisydev *p = topology; diff --git a/trunk/drivers/parport/ieee1284.c b/trunk/drivers/parport/ieee1284.c index 5accaa7bde31..7ff09f0f858f 100644 --- a/trunk/drivers/parport/ieee1284.c +++ b/trunk/drivers/parport/ieee1284.c @@ -571,7 +571,7 @@ static int parport_ieee1284_ack_data_avail (struct parport *port) #endif /* IEEE1284 support */ /* Handle an interrupt. */ -void parport_ieee1284_interrupt (int which, void *handle) +void parport_ieee1284_interrupt (int which, void *handle, struct pt_regs *regs) { struct parport *port = handle; parport_ieee1284_wakeup (port); diff --git a/trunk/drivers/parport/parport_amiga.c b/trunk/drivers/parport/parport_amiga.c index a0afaee5ebe5..5126e74ac2ec 100644 --- a/trunk/drivers/parport/parport_amiga.c +++ b/trunk/drivers/parport/parport_amiga.c @@ -138,9 +138,9 @@ static unsigned char amiga_read_status(struct parport *p) } /* as this ports irq handling is already done, we use a generic funktion */ -static irqreturn_t amiga_interrupt(int irq, void *dev_id) +static irqreturn_t amiga_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - parport_generic_irq(irq, (struct parport *) dev_id); + parport_generic_irq(irq, (struct parport *) dev_id, regs); return IRQ_HANDLED; } diff --git a/trunk/drivers/parport/parport_atari.c b/trunk/drivers/parport/parport_atari.c index 6ea9929b8c7f..78c3f34108bc 100644 --- a/trunk/drivers/parport/parport_atari.c +++ b/trunk/drivers/parport/parport_atari.c @@ -104,9 +104,9 @@ parport_atari_restore_state(struct parport *p, struct parport_state *s) } static irqreturn_t -parport_atari_interrupt(int irq, void *dev_id) +parport_atari_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - parport_generic_irq(irq, (struct parport *) dev_id); + parport_generic_irq(irq, (struct parport *) dev_id, regs); return IRQ_HANDLED; } diff --git a/trunk/drivers/parport/parport_ax88796.c b/trunk/drivers/parport/parport_ax88796.c index 74f4e9742c6c..1850632590fd 100644 --- a/trunk/drivers/parport/parport_ax88796.c +++ b/trunk/drivers/parport/parport_ax88796.c @@ -233,9 +233,9 @@ parport_ax88796_restore_state(struct parport *p, struct parport_state *s) } static irqreturn_t -parport_ax88796_interrupt(int irq, void *dev_id) +parport_ax88796_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - parport_generic_irq(irq, dev_id); + parport_generic_irq(irq, dev_id, regs); return IRQ_HANDLED; } diff --git a/trunk/drivers/parport/parport_gsc.c b/trunk/drivers/parport/parport_gsc.c index a7c5ead9a3d3..7352104f7b30 100644 --- a/trunk/drivers/parport/parport_gsc.c +++ b/trunk/drivers/parport/parport_gsc.c @@ -81,9 +81,9 @@ static int clear_epp_timeout(struct parport *pb) * of these are in parport_gsc.h. */ -static irqreturn_t parport_gsc_interrupt(int irq, void *dev_id) +static irqreturn_t parport_gsc_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - parport_generic_irq(irq, (struct parport *) dev_id); + parport_generic_irq(irq, (struct parport *) dev_id, regs); return IRQ_HANDLED; } diff --git a/trunk/drivers/parport/parport_ip32.c b/trunk/drivers/parport/parport_ip32.c index ec44efdbb84e..46e06e596d73 100644 --- a/trunk/drivers/parport/parport_ip32.c +++ b/trunk/drivers/parport/parport_ip32.c @@ -548,8 +548,10 @@ static void parport_ip32_dma_setup_context(unsigned int limit) * parport_ip32_dma_interrupt - DMA interrupt handler * @irq: interrupt number * @dev_id: unused + * @regs: pointer to &struct pt_regs */ -static irqreturn_t parport_ip32_dma_interrupt(int irq, void *dev_id) +static irqreturn_t parport_ip32_dma_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { if (parport_ip32_dma.left) pr_trace(NULL, "(%d): ctx=%d", irq, parport_ip32_dma.ctx); @@ -558,7 +560,8 @@ static irqreturn_t parport_ip32_dma_interrupt(int irq, void *dev_id) } #if DEBUG_PARPORT_IP32 -static irqreturn_t parport_ip32_merr_interrupt(int irq, void *dev_id) +static irqreturn_t parport_ip32_merr_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { pr_trace1(NULL, "(%d)", irq); return IRQ_HANDLED; @@ -769,18 +772,20 @@ static inline void parport_ip32_wakeup(struct parport *p) * parport_ip32_interrupt - interrupt handler * @irq: interrupt number * @dev_id: pointer to &struct parport + * @regs: pointer to &struct pt_regs * * Caught interrupts are forwarded to the upper parport layer if IRQ_mode is * %PARPORT_IP32_IRQ_FWD. */ -static irqreturn_t parport_ip32_interrupt(int irq, void *dev_id) +static irqreturn_t parport_ip32_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { struct parport * const p = dev_id; struct parport_ip32_private * const priv = p->physport->private_data; enum parport_ip32_irq_mode irq_mode = priv->irq_mode; switch (irq_mode) { case PARPORT_IP32_IRQ_FWD: - parport_generic_irq(irq, p); + parport_generic_irq(irq, p, regs); break; case PARPORT_IP32_IRQ_HERE: parport_ip32_wakeup(p); diff --git a/trunk/drivers/parport/parport_mfc3.c b/trunk/drivers/parport/parport_mfc3.c index e5b0a544de40..b2b8092a2b39 100644 --- a/trunk/drivers/parport/parport_mfc3.c +++ b/trunk/drivers/parport/parport_mfc3.c @@ -211,7 +211,7 @@ static void mfc3_change_mode( struct parport *p, int m) static int use_cnt = 0; -static irqreturn_t mfc3_interrupt(int irq, void *dev_id) +static irqreturn_t mfc3_interrupt(int irq, void *dev_id, struct pt_regs *regs) { int i; @@ -219,7 +219,7 @@ static irqreturn_t mfc3_interrupt(int irq, void *dev_id) if (this_port[i] != NULL) if (pia(this_port[i])->crb & 128) { /* Board caused interrupt */ dummy = pia(this_port[i])->pprb; /* clear irq bit */ - parport_generic_irq(irq, this_port[i]); + parport_generic_irq(irq, this_port[i], regs); } return IRQ_HANDLED; } diff --git a/trunk/drivers/parport/parport_pc.c b/trunk/drivers/parport/parport_pc.c index 39c96641bc72..fe800dc0be9f 100644 --- a/trunk/drivers/parport/parport_pc.c +++ b/trunk/drivers/parport/parport_pc.c @@ -270,9 +270,9 @@ static int clear_epp_timeout(struct parport *pb) * of these are in parport_pc.h. */ -static irqreturn_t parport_pc_interrupt(int irq, void *dev_id) +static irqreturn_t parport_pc_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - parport_generic_irq(irq, (struct parport *) dev_id); + parport_generic_irq(irq, (struct parport *) dev_id, regs); /* FIXME! Was it really ours? */ return IRQ_HANDLED; } diff --git a/trunk/drivers/parport/parport_sunbpp.c b/trunk/drivers/parport/parport_sunbpp.c index 9793533276ec..fac333b279bf 100644 --- a/trunk/drivers/parport/parport_sunbpp.c +++ b/trunk/drivers/parport/parport_sunbpp.c @@ -46,9 +46,9 @@ #define dprintk(x) #endif -static irqreturn_t parport_sunbpp_interrupt(int irq, void *dev_id) +static irqreturn_t parport_sunbpp_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - parport_generic_irq(irq, (struct parport *) dev_id); + parport_generic_irq(irq, (struct parport *) dev_id, regs); return IRQ_HANDLED; } diff --git a/trunk/drivers/parport/share.c b/trunk/drivers/parport/share.c index fd9129e424f9..94dc506b83d1 100644 --- a/trunk/drivers/parport/share.c +++ b/trunk/drivers/parport/share.c @@ -519,7 +519,7 @@ void parport_remove_port(struct parport *port) struct pardevice * parport_register_device(struct parport *port, const char *name, int (*pf)(void *), void (*kf)(void *), - void (*irq_func)(int, void *), + void (*irq_func)(int, void *, struct pt_regs *), int flags, void *handle) { struct pardevice *tmp; diff --git a/trunk/drivers/pci/Kconfig b/trunk/drivers/pci/Kconfig index f1dd81a1d592..30294127a0aa 100644 --- a/trunk/drivers/pci/Kconfig +++ b/trunk/drivers/pci/Kconfig @@ -27,14 +27,14 @@ config PCI_MULTITHREAD_PROBE smaller speedup on single processor machines. But it can also cause lots of bad things to happen. A number - of PCI drivers cannot properly handle running in this way, + of PCI drivers can not properly handle running in this way, some will just not work properly at all, while others might decide to blow up power supplies with a huge load all at once, so use this option at your own risk. It is very unwise to use this option if you are not using a boot process that can handle devices being created in any - order. A program that can create persistent block and network + order. A program that can create persistant block and network device names (like udev) is a good idea if you wish to use this option. @@ -55,7 +55,7 @@ config PCI_DEBUG config HT_IRQ bool "Interrupts on hypertransport devices" default y - depends on PCI && X86_LOCAL_APIC && X86_IO_APIC + depends on X86_LOCAL_APIC && X86_IO_APIC help This allows native hypertransport devices to use interrupts. diff --git a/trunk/drivers/pci/access.c b/trunk/drivers/pci/access.c index 73a58c73d526..ea16805a153c 100644 --- a/trunk/drivers/pci/access.c +++ b/trunk/drivers/pci/access.c @@ -1,7 +1,6 @@ #include #include #include -#include #include "pci.h" @@ -64,42 +63,30 @@ EXPORT_SYMBOL(pci_bus_write_config_byte); EXPORT_SYMBOL(pci_bus_write_config_word); EXPORT_SYMBOL(pci_bus_write_config_dword); -/* - * The following routines are to prevent the user from accessing PCI config - * space when it's unsafe to do so. Some devices require this during BIST and - * we're required to prevent it during D-state transitions. - * - * We have a bit per device to indicate it's blocked and a global wait queue - * for callers to sleep on until devices are unblocked. - */ -static DECLARE_WAIT_QUEUE_HEAD(pci_ucfg_wait); - -static noinline void pci_wait_ucfg(struct pci_dev *dev) +static u32 pci_user_cached_config(struct pci_dev *dev, int pos) { - DECLARE_WAITQUEUE(wait, current); - - __add_wait_queue(&pci_ucfg_wait, &wait); - do { - set_current_state(TASK_UNINTERRUPTIBLE); - spin_unlock_irq(&pci_lock); - schedule(); - spin_lock_irq(&pci_lock); - } while (dev->block_ucfg_access); - __remove_wait_queue(&pci_ucfg_wait, &wait); + u32 data; + + data = dev->saved_config_space[pos/sizeof(dev->saved_config_space[0])]; + data >>= (pos % sizeof(dev->saved_config_space[0])) * 8; + return data; } #define PCI_USER_READ_CONFIG(size,type) \ int pci_user_read_config_##size \ (struct pci_dev *dev, int pos, type *val) \ { \ + unsigned long flags; \ int ret = 0; \ u32 data = -1; \ if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \ - spin_lock_irq(&pci_lock); \ - if (unlikely(dev->block_ucfg_access)) pci_wait_ucfg(dev); \ - ret = dev->bus->ops->read(dev->bus, dev->devfn, \ + spin_lock_irqsave(&pci_lock, flags); \ + if (likely(!dev->block_ucfg_access)) \ + ret = dev->bus->ops->read(dev->bus, dev->devfn, \ pos, sizeof(type), &data); \ - spin_unlock_irq(&pci_lock); \ + else if (pos < sizeof(dev->saved_config_space)) \ + data = pci_user_cached_config(dev, pos); \ + spin_unlock_irqrestore(&pci_lock, flags); \ *val = (type)data; \ return ret; \ } @@ -108,13 +95,14 @@ int pci_user_read_config_##size \ int pci_user_write_config_##size \ (struct pci_dev *dev, int pos, type val) \ { \ + unsigned long flags; \ int ret = -EIO; \ if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \ - spin_lock_irq(&pci_lock); \ - if (unlikely(dev->block_ucfg_access)) pci_wait_ucfg(dev); \ - ret = dev->bus->ops->write(dev->bus, dev->devfn, \ + spin_lock_irqsave(&pci_lock, flags); \ + if (likely(!dev->block_ucfg_access)) \ + ret = dev->bus->ops->write(dev->bus, dev->devfn, \ pos, sizeof(type), val); \ - spin_unlock_irq(&pci_lock); \ + spin_unlock_irqrestore(&pci_lock, flags); \ return ret; \ } @@ -129,23 +117,21 @@ PCI_USER_WRITE_CONFIG(dword, u32) * pci_block_user_cfg_access - Block userspace PCI config reads/writes * @dev: pci device struct * - * When user access is blocked, any reads or writes to config space will - * sleep until access is unblocked again. We don't allow nesting of - * block/unblock calls. - */ + * This function blocks any userspace PCI config accesses from occurring. + * When blocked, any writes will be bit bucketed and reads will return the + * data saved using pci_save_state for the first 64 bytes of config + * space and return 0xff for all other config reads. + **/ void pci_block_user_cfg_access(struct pci_dev *dev) { unsigned long flags; - int was_blocked; + pci_save_state(dev); + + /* spinlock to synchronize with anyone reading config space now */ spin_lock_irqsave(&pci_lock, flags); - was_blocked = dev->block_ucfg_access; dev->block_ucfg_access = 1; spin_unlock_irqrestore(&pci_lock, flags); - - /* If we BUG() inside the pci_lock, we're guaranteed to hose - * the machine */ - BUG_ON(was_blocked); } EXPORT_SYMBOL_GPL(pci_block_user_cfg_access); @@ -154,19 +140,14 @@ EXPORT_SYMBOL_GPL(pci_block_user_cfg_access); * @dev: pci device struct * * This function allows userspace PCI config accesses to resume. - */ + **/ void pci_unblock_user_cfg_access(struct pci_dev *dev) { unsigned long flags; + /* spinlock to synchronize with anyone reading saved config space */ spin_lock_irqsave(&pci_lock, flags); - - /* This indicates a problem in the caller, but we don't need - * to kill them, unlike a double-block above. */ - WARN_ON(!dev->block_ucfg_access); - dev->block_ucfg_access = 0; - wake_up_all(&pci_ucfg_wait); spin_unlock_irqrestore(&pci_lock, flags); } EXPORT_SYMBOL_GPL(pci_unblock_user_cfg_access); diff --git a/trunk/drivers/pci/hotplug/acpi_pcihp.c b/trunk/drivers/pci/hotplug/acpi_pcihp.c index 270a33cc08f6..51cb9f817c22 100644 --- a/trunk/drivers/pci/hotplug/acpi_pcihp.c +++ b/trunk/drivers/pci/hotplug/acpi_pcihp.c @@ -29,10 +29,10 @@ #include #include #include -#include #include #include #include +#include "pci_hotplug.h" #define MY_NAME "acpi_pcihp" diff --git a/trunk/drivers/pci/hotplug/acpiphp.h b/trunk/drivers/pci/hotplug/acpiphp.h index ddbadd95387e..7fff07e877c7 100644 --- a/trunk/drivers/pci/hotplug/acpiphp.h +++ b/trunk/drivers/pci/hotplug/acpiphp.h @@ -38,7 +38,7 @@ #include #include /* for KOBJ_NAME_LEN */ #include -#include +#include "pci_hotplug.h" #define dbg(format, arg...) \ do { \ @@ -62,10 +62,10 @@ struct acpiphp_slot; struct slot { struct hotplug_slot *hotplug_slot; struct acpiphp_slot *acpi_slot; - struct hotplug_slot_info info; - char name[SLOT_NAME_SIZE]; }; + + /** * struct acpiphp_bridge - PCI bridge information * diff --git a/trunk/drivers/pci/hotplug/acpiphp_core.c b/trunk/drivers/pci/hotplug/acpiphp_core.c index 40c79b03c7ef..e2fef60c2d06 100644 --- a/trunk/drivers/pci/hotplug/acpiphp_core.c +++ b/trunk/drivers/pci/hotplug/acpiphp_core.c @@ -37,10 +37,10 @@ #include #include -#include #include #include #include +#include "pci_hotplug.h" #include "acpiphp.h" #define MY_NAME "acpiphp" @@ -303,15 +303,25 @@ static int __init init_acpi(void) /* read initial number of slots */ if (!retval) { num_slots = acpiphp_get_num_slots(); - if (num_slots == 0) { - acpiphp_glue_exit(); + if (num_slots == 0) retval = -ENODEV; - } } return retval; } + +/** + * make_slot_name - make a slot name that appears in pcihpfs + * @slot: slot to name + * + */ +static void make_slot_name(struct slot *slot) +{ + snprintf(slot->hotplug_slot->name, SLOT_NAME_SIZE, "%u", + slot->acpi_slot->sun); +} + /** * release_slot - free up the memory used by a slot * @hotplug_slot: slot to free @@ -322,6 +332,8 @@ static void release_slot(struct hotplug_slot *hotplug_slot) dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); + kfree(slot->hotplug_slot->info); + kfree(slot->hotplug_slot->name); kfree(slot->hotplug_slot); kfree(slot); } @@ -330,19 +342,26 @@ static void release_slot(struct hotplug_slot *hotplug_slot) int acpiphp_register_hotplug_slot(struct acpiphp_slot *acpiphp_slot) { struct slot *slot; + struct hotplug_slot *hotplug_slot; + struct hotplug_slot_info *hotplug_slot_info; int retval = -ENOMEM; slot = kzalloc(sizeof(*slot), GFP_KERNEL); if (!slot) goto error; - slot->hotplug_slot = kzalloc(sizeof(*slot->hotplug_slot), GFP_KERNEL); + slot->hotplug_slot = kzalloc(sizeof(*hotplug_slot), GFP_KERNEL); if (!slot->hotplug_slot) goto error_slot; - slot->hotplug_slot->info = &slot->info; + slot->hotplug_slot->info = kzalloc(sizeof(*hotplug_slot_info), + GFP_KERNEL); + if (!slot->hotplug_slot->info) + goto error_hpslot; - slot->hotplug_slot->name = slot->name; + slot->hotplug_slot->name = kzalloc(SLOT_NAME_SIZE, GFP_KERNEL); + if (!slot->hotplug_slot->name) + goto error_info; slot->hotplug_slot->private = slot; slot->hotplug_slot->release = &release_slot; @@ -357,17 +376,21 @@ int acpiphp_register_hotplug_slot(struct acpiphp_slot *acpiphp_slot) slot->hotplug_slot->info->cur_bus_speed = PCI_SPEED_UNKNOWN; acpiphp_slot->slot = slot; - snprintf(slot->name, sizeof(slot->name), "%u", slot->acpi_slot->sun); + make_slot_name(slot); retval = pci_hp_register(slot->hotplug_slot); if (retval) { err("pci_hp_register failed with error %d\n", retval); - goto error_hpslot; + goto error_name; } info("Slot [%s] registered\n", slot->hotplug_slot->name); return 0; +error_name: + kfree(slot->hotplug_slot->name); +error_info: + kfree(slot->hotplug_slot->info); error_hpslot: kfree(slot->hotplug_slot); error_slot: diff --git a/trunk/drivers/pci/hotplug/acpiphp_glue.c b/trunk/drivers/pci/hotplug/acpiphp_glue.c index 0b9d0db1590a..83e8e4412de5 100644 --- a/trunk/drivers/pci/hotplug/acpiphp_glue.c +++ b/trunk/drivers/pci/hotplug/acpiphp_glue.c @@ -45,11 +45,11 @@ #include #include -#include #include #include #include "../pci.h" +#include "pci_hotplug.h" #include "acpiphp.h" static LIST_HEAD(bridge_list); @@ -1693,10 +1693,14 @@ void __exit acpiphp_glue_exit(void) */ int __init acpiphp_get_num_slots(void) { + struct list_head *node; struct acpiphp_bridge *bridge; - int num_slots = 0; + int num_slots; + + num_slots = 0; - list_for_each_entry (bridge, &bridge_list, list) { + list_for_each (node, &bridge_list) { + bridge = (struct acpiphp_bridge *)node; dbg("Bus %04x:%02x has %d slot%s\n", pci_domain_nr(bridge->pci_bus), bridge->pci_bus->number, bridge->nr_slots, @@ -1803,8 +1807,8 @@ u8 acpiphp_get_power_status(struct acpiphp_slot *slot) /* - * latch open: 1 - * latch closed: 0 + * latch closed: 1 + * latch open: 0 */ u8 acpiphp_get_latch_status(struct acpiphp_slot *slot) { @@ -1812,7 +1816,7 @@ u8 acpiphp_get_latch_status(struct acpiphp_slot *slot) sta = get_slot_status(slot); - return (sta & ACPI_STA_SHOW_IN_UI) ? 0 : 1; + return (sta & ACPI_STA_SHOW_IN_UI) ? 1 : 0; } diff --git a/trunk/drivers/pci/hotplug/acpiphp_ibm.c b/trunk/drivers/pci/hotplug/acpiphp_ibm.c index bd40aee10e16..d0a07d9ab30c 100644 --- a/trunk/drivers/pci/hotplug/acpiphp_ibm.c +++ b/trunk/drivers/pci/hotplug/acpiphp_ibm.c @@ -35,6 +35,7 @@ #include #include "acpiphp.h" +#include "pci_hotplug.h" #define DRIVER_VERSION "1.0.1" #define DRIVER_AUTHOR "Irene Zubarev , Vernon Mauery " diff --git a/trunk/drivers/pci/hotplug/cpci_hotplug_core.c b/trunk/drivers/pci/hotplug/cpci_hotplug_core.c index 684551559d44..d5df5871cfa2 100644 --- a/trunk/drivers/pci/hotplug/cpci_hotplug_core.c +++ b/trunk/drivers/pci/hotplug/cpci_hotplug_core.c @@ -29,12 +29,12 @@ #include #include #include -#include #include #include #include #include #include +#include "pci_hotplug.h" #include "cpci_hotplug.h" #define DRIVER_AUTHOR "Scott Murray " @@ -342,7 +342,7 @@ cpci_hp_unregister_bus(struct pci_bus *bus) /* This is the interrupt mode interrupt handler */ static irqreturn_t -cpci_hp_intr(int irq, void *data) +cpci_hp_intr(int irq, void *data, struct pt_regs *regs) { dbg("entered cpci_hp_intr"); diff --git a/trunk/drivers/pci/hotplug/cpci_hotplug_pci.c b/trunk/drivers/pci/hotplug/cpci_hotplug_pci.c index 7b1beaad2752..4afcaffd031c 100644 --- a/trunk/drivers/pci/hotplug/cpci_hotplug_pci.c +++ b/trunk/drivers/pci/hotplug/cpci_hotplug_pci.c @@ -26,9 +26,9 @@ #include #include #include -#include #include #include "../pci.h" +#include "pci_hotplug.h" #include "cpci_hotplug.h" #define MY_NAME "cpci_hotplug" diff --git a/trunk/drivers/pci/hotplug/cpcihp_generic.c b/trunk/drivers/pci/hotplug/cpcihp_generic.c index f3852a6b74ea..e847f0d6c7fe 100644 --- a/trunk/drivers/pci/hotplug/cpcihp_generic.c +++ b/trunk/drivers/pci/hotplug/cpcihp_generic.c @@ -84,7 +84,7 @@ static int __init validate_parameters(void) if(!bridge) { info("not configured, disabling."); - return -EINVAL; + return 1; } str = bridge; if(!*str) @@ -147,7 +147,7 @@ static int __init cpcihp_generic_init(void) info(DRIVER_DESC " version: " DRIVER_VERSION); status = validate_parameters(); - if (status) + if(status != 0) return status; r = request_region(port, 1, "#ENUM hotswap signal register"); diff --git a/trunk/drivers/pci/hotplug/cpqphp.h b/trunk/drivers/pci/hotplug/cpqphp.h index 298ad7f3f4f4..c74e9e37e76b 100644 --- a/trunk/drivers/pci/hotplug/cpqphp.h +++ b/trunk/drivers/pci/hotplug/cpqphp.h @@ -28,6 +28,7 @@ #ifndef _CPQPHP_H #define _CPQPHP_H +#include "pci_hotplug.h" #include #include /* for read? and write? functions */ #include /* for delays */ @@ -408,7 +409,7 @@ extern void cpqhp_remove_debugfs_files (struct controller *ctrl); /* controller functions */ extern void cpqhp_pushbutton_thread (unsigned long event_pointer); -extern irqreturn_t cpqhp_ctrl_intr (int IRQ, void *data); +extern irqreturn_t cpqhp_ctrl_intr (int IRQ, void *data, struct pt_regs *regs); extern int cpqhp_find_available_resources (struct controller *ctrl, void __iomem *rom_start); extern int cpqhp_event_start_thread (void); extern void cpqhp_event_stop_thread (void); diff --git a/trunk/drivers/pci/hotplug/cpqphp_core.c b/trunk/drivers/pci/hotplug/cpqphp_core.c index 5617cfdadc5c..1fc259913b68 100644 --- a/trunk/drivers/pci/hotplug/cpqphp_core.c +++ b/trunk/drivers/pci/hotplug/cpqphp_core.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include diff --git a/trunk/drivers/pci/hotplug/cpqphp_ctrl.c b/trunk/drivers/pci/hotplug/cpqphp_ctrl.c index 79ff6b4de3a6..ae2dd36efef2 100644 --- a/trunk/drivers/pci/hotplug/cpqphp_ctrl.c +++ b/trunk/drivers/pci/hotplug/cpqphp_ctrl.c @@ -36,7 +36,6 @@ #include #include #include -#include #include "cpqphp.h" static u32 configure_new_device(struct controller* ctrl, struct pci_func *func, @@ -890,7 +889,7 @@ int cpqhp_resource_sort_and_combine(struct pci_resource **head) } -irqreturn_t cpqhp_ctrl_intr(int IRQ, void *data) +irqreturn_t cpqhp_ctrl_intr(int IRQ, void *data, struct pt_regs *regs) { struct controller *ctrl = data; u8 schedule_flag = 0; diff --git a/trunk/drivers/pci/hotplug/cpqphp_nvram.c b/trunk/drivers/pci/hotplug/cpqphp_nvram.c index 298a6cfd8406..cf0878917537 100644 --- a/trunk/drivers/pci/hotplug/cpqphp_nvram.c +++ b/trunk/drivers/pci/hotplug/cpqphp_nvram.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include "cpqphp.h" diff --git a/trunk/drivers/pci/hotplug/cpqphp_pci.c b/trunk/drivers/pci/hotplug/cpqphp_pci.c index fc7c74d72595..0d9688952f4a 100644 --- a/trunk/drivers/pci/hotplug/cpqphp_pci.c +++ b/trunk/drivers/pci/hotplug/cpqphp_pci.c @@ -33,7 +33,6 @@ #include #include #include -#include #include "../pci.h" #include "cpqphp.h" #include "cpqphp_nvram.h" diff --git a/trunk/drivers/pci/hotplug/cpqphp_sysfs.c b/trunk/drivers/pci/hotplug/cpqphp_sysfs.c index 634f74d919d3..5bab666cd67e 100644 --- a/trunk/drivers/pci/hotplug/cpqphp_sysfs.c +++ b/trunk/drivers/pci/hotplug/cpqphp_sysfs.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include "cpqphp.h" diff --git a/trunk/drivers/pci/hotplug/fakephp.c b/trunk/drivers/pci/hotplug/fakephp.c index e27907c91d92..05a4f0f90186 100644 --- a/trunk/drivers/pci/hotplug/fakephp.c +++ b/trunk/drivers/pci/hotplug/fakephp.c @@ -35,10 +35,10 @@ #include #include #include -#include #include #include #include +#include "pci_hotplug.h" #include "../pci.h" #if !defined(MODULE) @@ -181,9 +181,7 @@ static void pci_rescan_slot(struct pci_dev *temp) if (!pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type)) { temp->hdr_type = hdr_type & 0x7f; - if ((dev = pci_get_slot(bus, temp->devfn)) != NULL) - pci_dev_put(dev); - else { + if (!pci_find_slot(bus->number, temp->devfn)) { dev = pci_scan_single_device(bus, temp->devfn); if (dev) { dbg("New device on %s function %x:%x\n", @@ -207,9 +205,7 @@ static void pci_rescan_slot(struct pci_dev *temp) continue; temp->hdr_type = hdr_type & 0x7f; - if ((dev = pci_get_slot(bus, temp->devfn)) != NULL) - pci_dev_put(dev); - else { + if (!pci_find_slot(bus->number, temp->devfn)) { dev = pci_scan_single_device(bus, temp->devfn); if (dev) { dbg("New device on %s function %x:%x\n", @@ -309,7 +305,7 @@ static int disable_slot(struct hotplug_slot *slot) /* search for subfunctions and disable them first */ if (!(dslot->dev->devfn & 7)) { for (func = 1; func < 8; func++) { - dev = pci_get_slot(dslot->dev->bus, + dev = pci_find_slot(dslot->dev->bus->number, dslot->dev->devfn + func); if (dev) { hslot = get_slot_from_dev(dev); @@ -319,7 +315,6 @@ static int disable_slot(struct hotplug_slot *slot) err("Hotplug slot not found for subfunction of PCI device\n"); return -ENODEV; } - pci_dev_put(dev); } else dbg("No device in slot found\n"); } diff --git a/trunk/drivers/pci/hotplug/ibmphp.h b/trunk/drivers/pci/hotplug/ibmphp.h index 612d96301509..dba6d8ca9bda 100644 --- a/trunk/drivers/pci/hotplug/ibmphp.h +++ b/trunk/drivers/pci/hotplug/ibmphp.h @@ -30,7 +30,7 @@ * */ -#include +#include "pci_hotplug.h" extern int ibmphp_debug; diff --git a/trunk/drivers/pci/hotplug/ibmphp_hpc.c b/trunk/drivers/pci/hotplug/ibmphp_hpc.c index f55ac3885cb3..c3ac98a0a6a6 100644 --- a/trunk/drivers/pci/hotplug/ibmphp_hpc.c +++ b/trunk/drivers/pci/hotplug/ibmphp_hpc.c @@ -531,7 +531,7 @@ static u8 hpc_readcmdtoindex (u8 cmd, u8 index) * * Action: issue a READ command to HPC * -* Input: pslot - cannot be NULL for READ_ALLSTAT +* Input: pslot - can not be NULL for READ_ALLSTAT * pstatus - can be NULL for READ_ALLSTAT * * Return 0 or error codes diff --git a/trunk/drivers/pci/hotplug/ibmphp_pci.c b/trunk/drivers/pci/hotplug/ibmphp_pci.c index d8f05d7a3c72..d87a9e3eaeeb 100644 --- a/trunk/drivers/pci/hotplug/ibmphp_pci.c +++ b/trunk/drivers/pci/hotplug/ibmphp_pci.c @@ -1371,12 +1371,12 @@ static int unconfigure_boot_bridge (u8 busno, u8 device, u8 function) } bus = ibmphp_find_res_bus (sec_number); + debug ("bus->busno is %x\n", bus->busno); + debug ("sec_number is %x\n", sec_number); if (!bus) { err ("cannot find Bus structure for the bridged device\n"); return -EINVAL; } - debug("bus->busno is %x\n", bus->busno); - debug("sec_number is %x\n", sec_number); ibmphp_remove_bus (bus, busno); diff --git a/trunk/include/linux/pci_hotplug.h b/trunk/drivers/pci/hotplug/pci_hotplug.h similarity index 99% rename from trunk/include/linux/pci_hotplug.h rename to trunk/drivers/pci/hotplug/pci_hotplug.h index a675a05c4091..772523dc3860 100644 --- a/trunk/include/linux/pci_hotplug.h +++ b/trunk/drivers/pci/hotplug/pci_hotplug.h @@ -22,7 +22,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * Send feedback to + * Send feedback to * */ #ifndef _PCI_HOTPLUG_H diff --git a/trunk/drivers/pci/hotplug/pci_hotplug_core.c b/trunk/drivers/pci/hotplug/pci_hotplug_core.c index f5d632e72323..e2823ea9c4ed 100644 --- a/trunk/drivers/pci/hotplug/pci_hotplug_core.c +++ b/trunk/drivers/pci/hotplug/pci_hotplug_core.c @@ -21,7 +21,9 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * Send feedback to + * Send feedback to + * + * Filesystem portion based on work done by Pat Mochel on ddfs/driverfs * */ @@ -30,8 +32,6 @@ #include #include #include -#include -#include #include #include #include @@ -39,8 +39,11 @@ #include #include #include -#include #include +#include +#include +#include "pci_hotplug.h" + #define MY_NAME "pci_hotplug" diff --git a/trunk/drivers/pci/hotplug/pciehp.h b/trunk/drivers/pci/hotplug/pciehp.h index 4fb12fcda563..eaea9d36a1bb 100644 --- a/trunk/drivers/pci/hotplug/pciehp.h +++ b/trunk/drivers/pci/hotplug/pciehp.h @@ -31,11 +31,11 @@ #include #include -#include #include #include /* signal_pending() */ #include #include +#include "pci_hotplug.h" #define MY_NAME "pciehp" @@ -92,7 +92,6 @@ struct php_ctlr_state_s { struct controller { struct controller *next; struct mutex crit_sect; /* critical section mutex */ - struct mutex ctrl_lock; /* controller lock */ struct php_ctlr_state_s *hpc_ctlr_handle; /* HPC controller handle */ int num_slots; /* Number of slots on ctlr */ int slot_num_inc; /* 1 or -1 */ @@ -167,10 +166,10 @@ struct controller { * error Messages */ #define msg_initialization_err "Initialization failure, error=%d\n" -#define msg_button_on "PCI slot #%s - powering on due to button press.\n" -#define msg_button_off "PCI slot #%s - powering off due to button press.\n" -#define msg_button_cancel "PCI slot #%s - action canceled due to button press.\n" -#define msg_button_ignore "PCI slot #%s - button press ignored. (action in progress...)\n" +#define msg_button_on "PCI slot #%d - powering on due to button press.\n" +#define msg_button_off "PCI slot #%d - powering off due to button press.\n" +#define msg_button_cancel "PCI slot #%d - action canceled due to button press.\n" +#define msg_button_ignore "PCI slot #%d - button press ignored. (action in progress...)\n" /* controller functions */ extern int pciehp_event_start_thread (void); diff --git a/trunk/drivers/pci/hotplug/pciehp_core.c b/trunk/drivers/pci/hotplug/pciehp_core.c index f13f31323e85..c67b7c3f1ddf 100644 --- a/trunk/drivers/pci/hotplug/pciehp_core.c +++ b/trunk/drivers/pci/hotplug/pciehp_core.c @@ -448,7 +448,7 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ } /* Wait for exclusive access to hardware */ - mutex_lock(&ctrl->ctrl_lock); + mutex_lock(&ctrl->crit_sect); t_slot->hpc_ops->get_adapter_status(t_slot, &value); /* Check if slot is occupied */ @@ -456,7 +456,7 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ rc = t_slot->hpc_ops->power_off_slot(t_slot); /* Power off slot if not occupied*/ if (rc) { /* Done with exclusive hardware access */ - mutex_unlock(&ctrl->ctrl_lock); + mutex_unlock(&ctrl->crit_sect); goto err_out_free_ctrl_slot; } else /* Wait for the command to complete */ @@ -464,7 +464,7 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ } /* Done with exclusive hardware access */ - mutex_unlock(&ctrl->ctrl_lock); + mutex_unlock(&ctrl->crit_sect); return 0; @@ -521,9 +521,14 @@ static void __exit unload_pciehpd(void) } +static int hpdriver_context = 0; + static void pciehp_remove (struct pcie_device *device) { - /* XXX - Needs to be adapted to device driver model */ + printk("%s ENTRY\n", __FUNCTION__); + printk("%s -> Call free_irq for irq = %d\n", + __FUNCTION__, device->irq); + free_irq(device->irq, &hpdriver_context); } #ifdef CONFIG_PM diff --git a/trunk/drivers/pci/hotplug/pciehp_ctrl.c b/trunk/drivers/pci/hotplug/pciehp_ctrl.c index 372c63e35aa9..41290a106bd8 100644 --- a/trunk/drivers/pci/hotplug/pciehp_ctrl.c +++ b/trunk/drivers/pci/hotplug/pciehp_ctrl.c @@ -43,11 +43,6 @@ static int event_finished; static unsigned long pushbutton_pending; /* = 0 */ static unsigned long surprise_rm_pending; /* = 0 */ -static inline char *slot_name(struct slot *p_slot) -{ - return p_slot->hotplug_slot->name; -} - u8 pciehp_handle_attention_button(u8 hp_slot, void *inst_id) { struct controller *ctrl = (struct controller *) inst_id; @@ -73,7 +68,7 @@ u8 pciehp_handle_attention_button(u8 hp_slot, void *inst_id) /* * Button pressed - See if need to TAKE ACTION!!! */ - info("Button pressed on Slot(%s)\n", slot_name(p_slot)); + info("Button pressed on Slot(%d)\n", ctrl->first_slot + hp_slot); taskInfo->event_type = INT_BUTTON_PRESS; if ((p_slot->state == BLINKINGON_STATE) @@ -83,7 +78,7 @@ u8 pciehp_handle_attention_button(u8 hp_slot, void *inst_id) * or hot-remove */ taskInfo->event_type = INT_BUTTON_CANCEL; - info("Button cancel on Slot(%s)\n", slot_name(p_slot)); + info("Button cancel on Slot(%d)\n", ctrl->first_slot + hp_slot); } else if ((p_slot->state == POWERON_STATE) || (p_slot->state == POWEROFF_STATE)) { /* Ignore if the slot is on power-on or power-off state; this @@ -91,7 +86,7 @@ u8 pciehp_handle_attention_button(u8 hp_slot, void *inst_id) * hot-remove is undergoing */ taskInfo->event_type = INT_BUTTON_IGNORE; - info("Button ignore on Slot(%s)\n", slot_name(p_slot)); + info("Button ignore on Slot(%d)\n", ctrl->first_slot + hp_slot); } if (rc) @@ -127,13 +122,13 @@ u8 pciehp_handle_switch_change(u8 hp_slot, void *inst_id) /* * Switch opened */ - info("Latch open on Slot(%s)\n", slot_name(p_slot)); + info("Latch open on Slot(%d)\n", ctrl->first_slot + hp_slot); taskInfo->event_type = INT_SWITCH_OPEN; } else { /* * Switch closed */ - info("Latch close on Slot(%s)\n", slot_name(p_slot)); + info("Latch close on Slot(%d)\n", ctrl->first_slot + hp_slot); taskInfo->event_type = INT_SWITCH_CLOSE; } @@ -171,13 +166,13 @@ u8 pciehp_handle_presence_change(u8 hp_slot, void *inst_id) /* * Card Present */ - info("Card present on Slot(%s)\n", slot_name(p_slot)); + info("Card present on Slot(%d)\n", ctrl->first_slot + hp_slot); taskInfo->event_type = INT_PRESENCE_ON; } else { /* * Not Present */ - info("Card not present on Slot(%s)\n", slot_name(p_slot)); + info("Card not present on Slot(%d)\n", ctrl->first_slot + hp_slot); taskInfo->event_type = INT_PRESENCE_OFF; } @@ -211,13 +206,13 @@ u8 pciehp_handle_power_fault(u8 hp_slot, void *inst_id) /* * power fault Cleared */ - info("Power fault cleared on Slot(%s)\n", slot_name(p_slot)); + info("Power fault cleared on Slot(%d)\n", ctrl->first_slot + hp_slot); taskInfo->event_type = INT_POWER_FAULT_CLEAR; } else { /* * power fault */ - info("Power fault on Slot(%s)\n", slot_name(p_slot)); + info("Power fault on Slot(%d)\n", ctrl->first_slot + hp_slot); taskInfo->event_type = INT_POWER_FAULT; info("power fault bit %x set\n", hp_slot); } @@ -234,13 +229,13 @@ u8 pciehp_handle_power_fault(u8 hp_slot, void *inst_id) static void set_slot_off(struct controller *ctrl, struct slot * pslot) { /* Wait for exclusive access to hardware */ - mutex_lock(&ctrl->ctrl_lock); + mutex_lock(&ctrl->crit_sect); /* turn off slot, turn on Amber LED, turn off Green LED if supported*/ if (POWER_CTRL(ctrl->ctrlcap)) { if (pslot->hpc_ops->power_off_slot(pslot)) { err("%s: Issue of Slot Power Off command failed\n", __FUNCTION__); - mutex_unlock(&ctrl->ctrl_lock); + mutex_unlock(&ctrl->crit_sect); return; } wait_for_ctrl_irq (ctrl); @@ -254,14 +249,14 @@ static void set_slot_off(struct controller *ctrl, struct slot * pslot) if (ATTN_LED(ctrl->ctrlcap)) { if (pslot->hpc_ops->set_attention_status(pslot, 1)) { err("%s: Issue of Set Attention Led command failed\n", __FUNCTION__); - mutex_unlock(&ctrl->ctrl_lock); + mutex_unlock(&ctrl->crit_sect); return; } wait_for_ctrl_irq (ctrl); } /* Done with exclusive hardware access */ - mutex_unlock(&ctrl->ctrl_lock); + mutex_unlock(&ctrl->crit_sect); } /** @@ -284,13 +279,13 @@ static int board_added(struct slot *p_slot) ctrl->slot_device_offset, hp_slot); /* Wait for exclusive access to hardware */ - mutex_lock(&ctrl->ctrl_lock); + mutex_lock(&ctrl->crit_sect); if (POWER_CTRL(ctrl->ctrlcap)) { /* Power on slot */ rc = p_slot->hpc_ops->power_on_slot(p_slot); if (rc) { - mutex_unlock(&ctrl->ctrl_lock); + mutex_unlock(&ctrl->crit_sect); return -1; } @@ -306,7 +301,7 @@ static int board_added(struct slot *p_slot) } /* Done with exclusive hardware access */ - mutex_unlock(&ctrl->ctrl_lock); + mutex_unlock(&ctrl->crit_sect); /* Wait for ~1 second */ wait_for_ctrl_irq (ctrl); @@ -340,7 +335,7 @@ static int board_added(struct slot *p_slot) pci_fixup_device(pci_fixup_final, ctrl->pci_dev); if (PWR_LED(ctrl->ctrlcap)) { /* Wait for exclusive access to hardware */ - mutex_lock(&ctrl->ctrl_lock); + mutex_lock(&ctrl->crit_sect); p_slot->hpc_ops->green_led_on(p_slot); @@ -348,7 +343,7 @@ static int board_added(struct slot *p_slot) wait_for_ctrl_irq (ctrl); /* Done with exclusive hardware access */ - mutex_unlock(&ctrl->ctrl_lock); + mutex_unlock(&ctrl->crit_sect); } return 0; @@ -380,14 +375,14 @@ static int remove_board(struct slot *p_slot) dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot); /* Wait for exclusive access to hardware */ - mutex_lock(&ctrl->ctrl_lock); + mutex_lock(&ctrl->crit_sect); if (POWER_CTRL(ctrl->ctrlcap)) { /* power off slot */ rc = p_slot->hpc_ops->power_off_slot(p_slot); if (rc) { err("%s: Issue of Slot Disable command failed\n", __FUNCTION__); - mutex_unlock(&ctrl->ctrl_lock); + mutex_unlock(&ctrl->crit_sect); return rc; } /* Wait for the command to complete */ @@ -403,7 +398,7 @@ static int remove_board(struct slot *p_slot) } /* Done with exclusive hardware access */ - mutex_unlock(&ctrl->ctrl_lock); + mutex_unlock(&ctrl->crit_sect); return 0; } @@ -450,7 +445,7 @@ static void pciehp_pushbutton_thread(unsigned long slot) if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) { /* Wait for exclusive access to hardware */ - mutex_lock(&p_slot->ctrl->ctrl_lock); + mutex_lock(&p_slot->ctrl->crit_sect); p_slot->hpc_ops->green_led_off(p_slot); @@ -458,7 +453,7 @@ static void pciehp_pushbutton_thread(unsigned long slot) wait_for_ctrl_irq (p_slot->ctrl); /* Done with exclusive hardware access */ - mutex_unlock(&p_slot->ctrl->ctrl_lock); + mutex_unlock(&p_slot->ctrl->crit_sect); } p_slot->state = STATIC_STATE; } @@ -500,7 +495,7 @@ static void pciehp_surprise_rm_thread(unsigned long slot) if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) { /* Wait for exclusive access to hardware */ - mutex_lock(&p_slot->ctrl->ctrl_lock); + mutex_lock(&p_slot->ctrl->crit_sect); p_slot->hpc_ops->green_led_off(p_slot); @@ -508,7 +503,7 @@ static void pciehp_surprise_rm_thread(unsigned long slot) wait_for_ctrl_irq (p_slot->ctrl); /* Done with exclusive hardware access */ - mutex_unlock(&p_slot->ctrl->ctrl_lock); + mutex_unlock(&p_slot->ctrl->crit_sect); } p_slot->state = STATIC_STATE; } @@ -621,7 +616,7 @@ static void interrupt_event_handler(struct controller *ctrl) switch (p_slot->state) { case BLINKINGOFF_STATE: /* Wait for exclusive access to hardware */ - mutex_lock(&ctrl->ctrl_lock); + mutex_lock(&ctrl->crit_sect); if (PWR_LED(ctrl->ctrlcap)) { p_slot->hpc_ops->green_led_on(p_slot); @@ -635,11 +630,11 @@ static void interrupt_event_handler(struct controller *ctrl) wait_for_ctrl_irq (ctrl); } /* Done with exclusive hardware access */ - mutex_unlock(&ctrl->ctrl_lock); + mutex_unlock(&ctrl->crit_sect); break; case BLINKINGON_STATE: /* Wait for exclusive access to hardware */ - mutex_lock(&ctrl->ctrl_lock); + mutex_lock(&ctrl->crit_sect); if (PWR_LED(ctrl->ctrlcap)) { p_slot->hpc_ops->green_led_off(p_slot); @@ -652,14 +647,14 @@ static void interrupt_event_handler(struct controller *ctrl) wait_for_ctrl_irq (ctrl); } /* Done with exclusive hardware access */ - mutex_unlock(&ctrl->ctrl_lock); + mutex_unlock(&ctrl->crit_sect); break; default: warn("Not a valid state\n"); return; } - info(msg_button_cancel, slot_name(p_slot)); + info(msg_button_cancel, p_slot->number); p_slot->state = STATIC_STATE; } /* ***********Button Pressed (No action on 1st press...) */ @@ -672,16 +667,16 @@ static void interrupt_event_handler(struct controller *ctrl) /* slot is on */ dbg("slot is on\n"); p_slot->state = BLINKINGOFF_STATE; - info(msg_button_off, slot_name(p_slot)); + info(msg_button_off, p_slot->number); } else { /* slot is off */ dbg("slot is off\n"); p_slot->state = BLINKINGON_STATE; - info(msg_button_on, slot_name(p_slot)); + info(msg_button_on, p_slot->number); } /* Wait for exclusive access to hardware */ - mutex_lock(&ctrl->ctrl_lock); + mutex_lock(&ctrl->crit_sect); /* blink green LED and turn off amber */ if (PWR_LED(ctrl->ctrlcap)) { @@ -698,7 +693,7 @@ static void interrupt_event_handler(struct controller *ctrl) } /* Done with exclusive hardware access */ - mutex_unlock(&ctrl->ctrl_lock); + mutex_unlock(&ctrl->crit_sect); init_timer(&p_slot->task_event); p_slot->task_event.expires = jiffies + 5 * HZ; /* 5 second delay */ @@ -713,7 +708,7 @@ static void interrupt_event_handler(struct controller *ctrl) if (POWER_CTRL(ctrl->ctrlcap)) { dbg("power fault\n"); /* Wait for exclusive access to hardware */ - mutex_lock(&ctrl->ctrl_lock); + mutex_lock(&ctrl->crit_sect); if (ATTN_LED(ctrl->ctrlcap)) { p_slot->hpc_ops->set_attention_status(p_slot, 1); @@ -726,7 +721,7 @@ static void interrupt_event_handler(struct controller *ctrl) } /* Done with exclusive hardware access */ - mutex_unlock(&ctrl->ctrl_lock); + mutex_unlock(&ctrl->crit_sect); } } /***********SURPRISE REMOVAL********************/ @@ -765,16 +760,14 @@ int pciehp_enable_slot(struct slot *p_slot) rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); if (rc || !getstatus) { - info("%s: no adapter on slot(%s)\n", __FUNCTION__, - slot_name(p_slot)); + info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number); mutex_unlock(&p_slot->ctrl->crit_sect); return -ENODEV; } if (MRL_SENS(p_slot->ctrl->ctrlcap)) { rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); if (rc || getstatus) { - info("%s: latch open on slot(%s)\n", __FUNCTION__, - slot_name(p_slot)); + info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); mutex_unlock(&p_slot->ctrl->crit_sect); return -ENODEV; } @@ -783,12 +776,12 @@ int pciehp_enable_slot(struct slot *p_slot) if (POWER_CTRL(p_slot->ctrl->ctrlcap)) { rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); if (rc || getstatus) { - info("%s: already enabled on slot(%s)\n", __FUNCTION__, - slot_name(p_slot)); + info("%s: already enabled on slot(%x)\n", __FUNCTION__, p_slot->number); mutex_unlock(&p_slot->ctrl->crit_sect); return -EINVAL; } } + mutex_unlock(&p_slot->ctrl->crit_sect); p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); @@ -797,9 +790,9 @@ int pciehp_enable_slot(struct slot *p_slot) p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); } - update_slot_info(p_slot); + if (p_slot) + update_slot_info(p_slot); - mutex_unlock(&p_slot->ctrl->crit_sect); return rc; } @@ -818,8 +811,7 @@ int pciehp_disable_slot(struct slot *p_slot) if (!HP_SUPR_RM(p_slot->ctrl->ctrlcap)) { ret = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); if (ret || !getstatus) { - info("%s: no adapter on slot(%s)\n", __FUNCTION__, - slot_name(p_slot)); + info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number); mutex_unlock(&p_slot->ctrl->crit_sect); return -ENODEV; } @@ -828,8 +820,7 @@ int pciehp_disable_slot(struct slot *p_slot) if (MRL_SENS(p_slot->ctrl->ctrlcap)) { ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); if (ret || getstatus) { - info("%s: latch open on slot(%s)\n", __FUNCTION__, - slot_name(p_slot)); + info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); mutex_unlock(&p_slot->ctrl->crit_sect); return -ENODEV; } @@ -838,17 +829,16 @@ int pciehp_disable_slot(struct slot *p_slot) if (POWER_CTRL(p_slot->ctrl->ctrlcap)) { ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); if (ret || !getstatus) { - info("%s: already disabled slot(%s)\n", __FUNCTION__, - slot_name(p_slot)); + info("%s: already disabled slot(%x)\n", __FUNCTION__, p_slot->number); mutex_unlock(&p_slot->ctrl->crit_sect); return -EINVAL; } } + mutex_unlock(&p_slot->ctrl->crit_sect); + ret = remove_board(p_slot); update_slot_info(p_slot); - - mutex_unlock(&p_slot->ctrl->crit_sect); return ret; } diff --git a/trunk/drivers/pci/hotplug/pciehp_hpc.c b/trunk/drivers/pci/hotplug/pciehp_hpc.c index 6d3f580f2666..6ab3b6cd2b54 100644 --- a/trunk/drivers/pci/hotplug/pciehp_hpc.c +++ b/trunk/drivers/pci/hotplug/pciehp_hpc.c @@ -222,7 +222,7 @@ static struct php_ctlr_state_s *php_ctlr_list_head; /* HPC state linked list */ static int ctlr_seq_num = 0; /* Controller sequence # */ static spinlock_t list_lock; -static irqreturn_t pcie_isr(int IRQ, void *dev_id); +static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs); static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds); @@ -239,7 +239,7 @@ static void int_poll_timeout(unsigned long lphp_ctlr) } /* Poll for interrupt events. regs == NULL => polling */ - pcie_isr( 0, (void *)php_ctlr ); + pcie_isr( 0, (void *)php_ctlr, NULL ); init_timer(&php_ctlr->int_poll_timer); @@ -718,6 +718,8 @@ static void hpc_release_ctlr(struct controller *ctrl) if (php_ctlr->irq) { free_irq(php_ctlr->irq, ctrl); php_ctlr->irq = 0; + if (!pcie_mch_quirk) + pci_disable_msi(php_ctlr->pci_dev); } } if (php_ctlr->pci_dev) @@ -861,7 +863,7 @@ static int hpc_power_off_slot(struct slot * slot) return retval; } -static irqreturn_t pcie_isr(int IRQ, void *dev_id) +static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs) { struct controller *ctrl = NULL; struct php_ctlr_state_s *php_ctlr; @@ -1400,8 +1402,6 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) pdev->subsystem_vendor, pdev->subsystem_device); mutex_init(&ctrl->crit_sect); - mutex_init(&ctrl->ctrl_lock); - /* setup wait queue */ init_waitqueue_head(&ctrl->queue); diff --git a/trunk/drivers/pci/hotplug/pcihp_skeleton.c b/trunk/drivers/pci/hotplug/pcihp_skeleton.c index 50bcd3fe61da..2b9e10e38613 100644 --- a/trunk/drivers/pci/hotplug/pcihp_skeleton.c +++ b/trunk/drivers/pci/hotplug/pcihp_skeleton.c @@ -33,8 +33,8 @@ #include #include #include -#include #include +#include "pci_hotplug.h" #define SLOT_NAME_SIZE 10 struct slot { diff --git a/trunk/drivers/pci/hotplug/rpadlpar_core.c b/trunk/drivers/pci/hotplug/rpadlpar_core.c index 72383467a0d5..46825fee3ae4 100644 --- a/trunk/drivers/pci/hotplug/rpadlpar_core.c +++ b/trunk/drivers/pci/hotplug/rpadlpar_core.c @@ -63,7 +63,7 @@ static struct device_node *find_php_slot_pci_node(char *drc_name, char *type; int rc; - while ((np = of_find_node_by_name(np, "pci"))) { + while ((np = of_find_node_by_type(np, "pci"))) { rc = rpaphp_get_drc_props(np, NULL, &name, &type, NULL); if (rc == 0) if (!strcmp(drc_name, name) && !strcmp(drc_type, type)) diff --git a/trunk/drivers/pci/hotplug/rpadlpar_sysfs.c b/trunk/drivers/pci/hotplug/rpadlpar_sysfs.c index 6c5be3ff578c..db69be85b458 100644 --- a/trunk/drivers/pci/hotplug/rpadlpar_sysfs.c +++ b/trunk/drivers/pci/hotplug/rpadlpar_sysfs.c @@ -14,7 +14,7 @@ */ #include #include -#include +#include "pci_hotplug.h" #include "rpadlpar.h" #define DLPAR_KOBJ_NAME "control" diff --git a/trunk/drivers/pci/hotplug/rpaphp.h b/trunk/drivers/pci/hotplug/rpaphp.h index 2e7accf0f734..310b6186c0e5 100644 --- a/trunk/drivers/pci/hotplug/rpaphp.h +++ b/trunk/drivers/pci/hotplug/rpaphp.h @@ -28,7 +28,7 @@ #define _PPC64PHP_H #include -#include +#include "pci_hotplug.h" #define DR_INDICATOR 9002 #define DR_ENTITY_SENSE 9003 diff --git a/trunk/drivers/pci/hotplug/rpaphp_core.c b/trunk/drivers/pci/hotplug/rpaphp_core.c index 71a2cb8baa4a..7288a3eccfb3 100644 --- a/trunk/drivers/pci/hotplug/rpaphp_core.c +++ b/trunk/drivers/pci/hotplug/rpaphp_core.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include @@ -37,6 +36,7 @@ #include "../pci.h" /* for pci_add_new_bus */ /* and pci_do_scan_bus */ #include "rpaphp.h" +#include "pci_hotplug.h" int debug; static struct semaphore rpaphp_sem; @@ -356,7 +356,7 @@ static int __init rpaphp_init(void) info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); init_MUTEX(&rpaphp_sem); - while ((dn = of_find_node_by_name(dn, "pci"))) + while ((dn = of_find_node_by_type(dn, "pci"))) rpaphp_add_slot(dn); return 0; diff --git a/trunk/drivers/pci/hotplug/sgi_hotplug.c b/trunk/drivers/pci/hotplug/sgi_hotplug.c index 5d188c558386..f31d83c2c633 100644 --- a/trunk/drivers/pci/hotplug/sgi_hotplug.c +++ b/trunk/drivers/pci/hotplug/sgi_hotplug.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -30,6 +29,7 @@ #include #include "../pci.h" +#include "pci_hotplug.h" MODULE_LICENSE("GPL"); MODULE_AUTHOR("SGI (prarit@sgi.com, dickie@sgi.com, habeck@sgi.com)"); @@ -205,6 +205,21 @@ static struct hotplug_slot * sn_hp_destroy(void) return bss_hotplug_slot; } +static void sn_bus_alloc_data(struct pci_dev *dev) +{ + struct pci_bus *subordinate_bus; + struct pci_dev *child; + + sn_pci_fixup_slot(dev); + + /* Recursively sets up the sn_irq_info structs */ + if (dev->subordinate) { + subordinate_bus = dev->subordinate; + list_for_each_entry(child, &subordinate_bus->devices, bus_list) + sn_bus_alloc_data(child); + } +} + static void sn_bus_free_data(struct pci_dev *dev) { struct pci_bus *subordinate_bus; @@ -322,11 +337,6 @@ static int sn_slot_disable(struct hotplug_slot *bss_hotplug_slot, return rc; } -/* - * Power up and configure the slot via a SAL call to PROM. - * Scan slot (and any children), do any platform specific fixup, - * and find device driver. - */ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) { struct slot *slot = bss_hotplug_slot->private; @@ -335,7 +345,6 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) int func, num_funcs; int new_ppb = 0; int rc; - void pcibios_fixup_device_resources(struct pci_dev *); /* Serialize the Linux PCI infrastructure */ mutex_lock(&sn_hotplug_mutex); @@ -358,6 +367,9 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) return -ENODEV; } + sn_pci_controller_fixup(pci_domain_nr(slot->pci_bus), + slot->pci_bus->number, + slot->pci_bus); /* * Map SN resources for all functions on the card * to the Linux PCI interface and tell the drivers @@ -368,13 +380,6 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) PCI_DEVFN(slot->device_num + 1, PCI_FUNC(func))); if (dev) { - /* Need to do slot fixup on PPB before fixup of children - * (PPB's pcidev_info needs to be in pcidev_info list - * before child's SN_PCIDEV_INFO() call to setup - * pdi_host_pcidev_info). - */ - pcibios_fixup_device_resources(dev); - sn_pci_fixup_slot(dev); if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { unsigned char sec_bus; pci_read_config_byte(dev, PCI_SECONDARY_BUS, @@ -382,8 +387,12 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) new_bus = pci_add_new_bus(dev->bus, dev, sec_bus); pci_scan_child_bus(new_bus); + sn_pci_controller_fixup(pci_domain_nr(new_bus), + new_bus->number, + new_bus); new_ppb = 1; } + sn_bus_alloc_data(dev); pci_dev_put(dev); } } diff --git a/trunk/drivers/pci/hotplug/shpchp.h b/trunk/drivers/pci/hotplug/shpchp.h index ea2087c34149..c7103ac5cd06 100644 --- a/trunk/drivers/pci/hotplug/shpchp.h +++ b/trunk/drivers/pci/hotplug/shpchp.h @@ -31,11 +31,12 @@ #include #include -#include #include #include /* signal_pending(), struct timer_list */ #include +#include "pci_hotplug.h" + #if !defined(MODULE) #define MY_NAME "shpchp" #else @@ -102,6 +103,7 @@ struct controller { u32 cap_offset; unsigned long mmio_base; unsigned long mmio_size; + volatile int cmd_busy; }; diff --git a/trunk/drivers/pci/hotplug/shpchp_hpc.c b/trunk/drivers/pci/hotplug/shpchp_hpc.c index 83a5226ba9ed..0f9798df4704 100644 --- a/trunk/drivers/pci/hotplug/shpchp_hpc.c +++ b/trunk/drivers/pci/hotplug/shpchp_hpc.c @@ -218,7 +218,7 @@ static spinlock_t list_lock; static atomic_t shpchp_num_controllers = ATOMIC_INIT(0); -static irqreturn_t shpc_isr(int irq, void *dev_id); +static irqreturn_t shpc_isr(int irq, void *dev_id, struct pt_regs *regs); static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int sec); static int hpc_check_cmd_status(struct controller *ctrl); @@ -276,7 +276,7 @@ static void int_poll_timeout(unsigned long lphp_ctlr) DBG_ENTER_ROUTINE /* Poll for interrupt events. regs == NULL => polling */ - shpc_isr(0, php_ctlr->callback_instance_id); + shpc_isr(0, php_ctlr->callback_instance_id, NULL); init_timer(&php_ctlr->int_poll_timer); if (!shpchp_poll_time) @@ -302,51 +302,21 @@ static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int sec) add_timer(&php_ctlr->int_poll_timer); } -static inline int is_ctrl_busy(struct controller *ctrl) -{ - u16 cmd_status = shpc_readw(ctrl, CMD_STATUS); - return cmd_status & 0x1; -} - -/* - * Returns 1 if SHPC finishes executing a command within 1 sec, - * otherwise returns 0. - */ -static inline int shpc_poll_ctrl_busy(struct controller *ctrl) -{ - int i; - - if (!is_ctrl_busy(ctrl)) - return 1; - - /* Check every 0.1 sec for a total of 1 sec */ - for (i = 0; i < 10; i++) { - msleep(100); - if (!is_ctrl_busy(ctrl)) - return 1; - } - - return 0; -} - static inline int shpc_wait_cmd(struct controller *ctrl) { int retval = 0; - unsigned long timeout = msecs_to_jiffies(1000); - int rc; - - if (shpchp_poll_mode) - rc = shpc_poll_ctrl_busy(ctrl); - else - rc = wait_event_interruptible_timeout(ctrl->queue, - !is_ctrl_busy(ctrl), timeout); - if (!rc && is_ctrl_busy(ctrl)) { + unsigned int timeout_msec = shpchp_poll_mode ? 2000 : 1000; + unsigned long timeout = msecs_to_jiffies(timeout_msec); + int rc = wait_event_interruptible_timeout(ctrl->queue, + !ctrl->cmd_busy, timeout); + if (!rc) { retval = -EIO; - err("Command not completed in 1000 msec\n"); + err("Command not completed in %d msec\n", timeout_msec); } else if (rc < 0) { retval = -EINTR; info("Command was interrupted by a signal\n"); } + ctrl->cmd_busy = 0; return retval; } @@ -357,15 +327,26 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) u16 cmd_status; int retval = 0; u16 temp_word; + int i; DBG_ENTER_ROUTINE mutex_lock(&slot->ctrl->cmd_lock); - if (!shpc_poll_ctrl_busy(ctrl)) { + for (i = 0; i < 10; i++) { + cmd_status = shpc_readw(ctrl, CMD_STATUS); + + if (!(cmd_status & 0x1)) + break; + /* Check every 0.1 sec for a total of 1 sec*/ + msleep(100); + } + + cmd_status = shpc_readw(ctrl, CMD_STATUS); + + if (cmd_status & 0x1) { /* After 1 sec and and the controller is still busy */ - err("%s : Controller is still busy after 1 sec.\n", - __FUNCTION__); + err("%s : Controller is still busy after 1 sec.\n", __FUNCTION__); retval = -EBUSY; goto out; } @@ -377,6 +358,7 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) /* To make sure the Controller Busy bit is 0 before we send out the * command. */ + slot->ctrl->cmd_busy = 1; shpc_writew(ctrl, CMD, temp_word); /* @@ -888,7 +870,7 @@ static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value) return retval; } -static irqreturn_t shpc_isr(int irq, void *dev_id) +static irqreturn_t shpc_isr(int irq, void *dev_id, struct pt_regs *regs) { struct controller *ctrl = (struct controller *)dev_id; struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle; @@ -926,6 +908,7 @@ static irqreturn_t shpc_isr(int irq, void *dev_id) serr_int &= ~SERR_INTR_RSVDZ_MASK; shpc_writel(ctrl, SERR_INTR_ENABLE, serr_int); + ctrl->cmd_busy = 0; wake_up_interruptible(&ctrl->queue); } @@ -1118,7 +1101,7 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) { struct php_ctlr_state_s *php_ctlr, *p; void *instance_id = ctrl; - int rc = -1, num_slots = 0; + int rc, num_slots = 0; u8 hp_slot; u32 shpc_base_offset; u32 tempdword, slot_reg, slot_config; @@ -1184,15 +1167,11 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", pdev->vendor, pdev->device, pdev->subsystem_vendor, pdev->subsystem_device); - rc = pci_enable_device(pdev); - if (rc) { - err("%s: pci_enable_device failed\n", __FUNCTION__); + if (pci_enable_device(pdev)) goto abort_free_ctlr; - } if (!request_mem_region(ctrl->mmio_base, ctrl->mmio_size, MY_NAME)) { err("%s: cannot reserve MMIO region\n", __FUNCTION__); - rc = -1; goto abort_free_ctlr; } @@ -1201,7 +1180,6 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) err("%s: cannot remap MMIO region %lx @ %lx\n", __FUNCTION__, ctrl->mmio_size, ctrl->mmio_base); release_mem_region(ctrl->mmio_base, ctrl->mmio_size); - rc = -1; goto abort_free_ctlr; } dbg("%s: php_ctlr->creg %p\n", __FUNCTION__, php_ctlr->creg); @@ -1304,10 +1282,8 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) */ if (atomic_add_return(1, &shpchp_num_controllers) == 1) { shpchp_wq = create_singlethread_workqueue("shpchpd"); - if (!shpchp_wq) { - rc = -ENOMEM; - goto abort_free_ctlr; - } + if (!shpchp_wq) + return -ENOMEM; } /* @@ -1337,10 +1313,8 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) /* We end up here for the many possible ways to fail this API. */ abort_free_ctlr: - if (php_ctlr->creg) - iounmap(php_ctlr->creg); kfree(php_ctlr); abort: DBG_LEAVE_ROUTINE - return rc; + return -1; } diff --git a/trunk/drivers/pci/htirq.c b/trunk/drivers/pci/htirq.c index 0a8d1cce9fa0..0e27f2404a83 100644 --- a/trunk/drivers/pci/htirq.c +++ b/trunk/drivers/pci/htirq.c @@ -25,72 +25,97 @@ static DEFINE_SPINLOCK(ht_irq_lock); struct ht_irq_cfg { struct pci_dev *dev; - /* Update callback used to cope with buggy hardware */ - ht_irq_update_t *update; unsigned pos; unsigned idx; - struct ht_irq_msg msg; }; +void write_ht_irq_low(unsigned int irq, u32 data) +{ + struct ht_irq_cfg *cfg = get_irq_data(irq); + unsigned long flags; + spin_lock_irqsave(&ht_irq_lock, flags); + pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx); + pci_write_config_dword(cfg->dev, cfg->pos + 4, data); + spin_unlock_irqrestore(&ht_irq_lock, flags); +} -void write_ht_irq_msg(unsigned int irq, struct ht_irq_msg *msg) +void write_ht_irq_high(unsigned int irq, u32 data) { struct ht_irq_cfg *cfg = get_irq_data(irq); unsigned long flags; spin_lock_irqsave(&ht_irq_lock, flags); - if (cfg->msg.address_lo != msg->address_lo) { - pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx); - pci_write_config_dword(cfg->dev, cfg->pos + 4, msg->address_lo); - } - if (cfg->msg.address_hi != msg->address_hi) { - pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx + 1); - pci_write_config_dword(cfg->dev, cfg->pos + 4, msg->address_hi); - } - if (cfg->update) - cfg->update(cfg->dev, irq, msg); + pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx + 1); + pci_write_config_dword(cfg->dev, cfg->pos + 4, data); spin_unlock_irqrestore(&ht_irq_lock, flags); - cfg->msg = *msg; } -void fetch_ht_irq_msg(unsigned int irq, struct ht_irq_msg *msg) +u32 read_ht_irq_low(unsigned int irq) { struct ht_irq_cfg *cfg = get_irq_data(irq); - *msg = cfg->msg; + unsigned long flags; + u32 data; + spin_lock_irqsave(&ht_irq_lock, flags); + pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx); + pci_read_config_dword(cfg->dev, cfg->pos + 4, &data); + spin_unlock_irqrestore(&ht_irq_lock, flags); + return data; +} + +u32 read_ht_irq_high(unsigned int irq) +{ + struct ht_irq_cfg *cfg = get_irq_data(irq); + unsigned long flags; + u32 data; + spin_lock_irqsave(&ht_irq_lock, flags); + pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx + 1); + pci_read_config_dword(cfg->dev, cfg->pos + 4, &data); + spin_unlock_irqrestore(&ht_irq_lock, flags); + return data; } void mask_ht_irq(unsigned int irq) { struct ht_irq_cfg *cfg; - struct ht_irq_msg msg; + unsigned long flags; + u32 data; cfg = get_irq_data(irq); - msg = cfg->msg; - msg.address_lo |= 1; - write_ht_irq_msg(irq, &msg); + spin_lock_irqsave(&ht_irq_lock, flags); + pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx); + pci_read_config_dword(cfg->dev, cfg->pos + 4, &data); + data |= 1; + pci_write_config_dword(cfg->dev, cfg->pos + 4, data); + spin_unlock_irqrestore(&ht_irq_lock, flags); } void unmask_ht_irq(unsigned int irq) { struct ht_irq_cfg *cfg; - struct ht_irq_msg msg; + unsigned long flags; + u32 data; cfg = get_irq_data(irq); - msg = cfg->msg; - msg.address_lo &= ~1; - write_ht_irq_msg(irq, &msg); + spin_lock_irqsave(&ht_irq_lock, flags); + pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx); + pci_read_config_dword(cfg->dev, cfg->pos + 4, &data); + data &= ~1; + pci_write_config_dword(cfg->dev, cfg->pos + 4, data); + spin_unlock_irqrestore(&ht_irq_lock, flags); } /** - * __ht_create_irq - create an irq and attach it to a device. + * ht_create_irq - create an irq and attach it to a device. * @dev: The hypertransport device to find the irq capability on. * @idx: Which of the possible irqs to attach to. - * @update: Function to be called when changing the htirq message + * + * ht_create_irq is needs to be called for all hypertransport devices + * that generate irqs. * * The irq number of the new irq or a negative error value is returned. */ -int __ht_create_irq(struct pci_dev *dev, int idx, ht_irq_update_t *update) +int ht_create_irq(struct pci_dev *dev, int idx) { struct ht_irq_cfg *cfg; unsigned long flags; @@ -125,12 +150,8 @@ int __ht_create_irq(struct pci_dev *dev, int idx, ht_irq_update_t *update) return -ENOMEM; cfg->dev = dev; - cfg->update = update; cfg->pos = pos; cfg->idx = 0x10 + (idx * 2); - /* Initialize msg to a value that will never match the first write. */ - cfg->msg.address_lo = 0xffffffff; - cfg->msg.address_hi = 0xffffffff; irq = create_irq(); if (irq < 0) { @@ -147,21 +168,6 @@ int __ht_create_irq(struct pci_dev *dev, int idx, ht_irq_update_t *update) return irq; } -/** - * ht_create_irq - create an irq and attach it to a device. - * @dev: The hypertransport device to find the irq capability on. - * @idx: Which of the possible irqs to attach to. - * - * ht_create_irq needs to be called for all hypertransport devices - * that generate irqs. - * - * The irq number of the new irq or a negative error value is returned. - */ -int ht_create_irq(struct pci_dev *dev, int idx) -{ - return __ht_create_irq(dev, idx, NULL); -} - /** * ht_destroy_irq - destroy an irq created with ht_create_irq * @@ -180,6 +186,5 @@ void ht_destroy_irq(unsigned int irq) kfree(cfg); } -EXPORT_SYMBOL(__ht_create_irq); EXPORT_SYMBOL(ht_create_irq); EXPORT_SYMBOL(ht_destroy_irq); diff --git a/trunk/drivers/pci/msi.c b/trunk/drivers/pci/msi.c index 9fc9a34ef24a..f9fdc54473c4 100644 --- a/trunk/drivers/pci/msi.c +++ b/trunk/drivers/pci/msi.c @@ -627,24 +627,22 @@ static int msix_capability_init(struct pci_dev *dev, * pci_msi_supported - check whether MSI may be enabled on device * @dev: pointer to the pci_dev data structure of MSI device function * - * Look at global flags, the device itself, and its parent busses - * to return 0 if MSI are supported for the device. + * MSI must be globally enabled and supported by the device and its root + * bus. But, the root bus is not easy to find since some architectures + * have virtual busses on top of the PCI hierarchy (for instance the + * hypertransport bus), while the actual bus where MSI must be supported + * is below. So we test the MSI flag on all parent busses and assume + * that no quirk will ever set the NO_MSI flag on a non-root bus. **/ static int pci_msi_supported(struct pci_dev * dev) { struct pci_bus *bus; - /* MSI must be globally enabled and supported by the device */ if (!pci_msi_enable || !dev || dev->no_msi) return -EINVAL; - /* Any bridge which does NOT route MSI transactions from it's - * secondary bus to it's primary bus must set NO_MSI flag on - * the secondary pci_bus. - * We expect only arch-specific PCI host bus controller driver - * or quirks for specific PCI bridges to be setting NO_MSI. - */ + /* check MSI flags of all parent busses */ for (bus = dev->bus; bus; bus = bus->parent) if (bus->bus_flags & PCI_BUS_FLAGS_NO_MSI) return -EINVAL; diff --git a/trunk/drivers/pci/msi.h b/trunk/drivers/pci/msi.h index 3898f5237144..f0cca1772f9c 100644 --- a/trunk/drivers/pci/msi.h +++ b/trunk/drivers/pci/msi.h @@ -6,6 +6,14 @@ #ifndef MSI_H #define MSI_H +/* + * MSI-X Address Register + */ +#define PCI_MSIX_FLAGS_QSIZE 0x7FF +#define PCI_MSIX_FLAGS_ENABLE (1 << 15) +#define PCI_MSIX_FLAGS_BIRMASK (7 << 0) +#define PCI_MSIX_FLAGS_BITMASK (1 << 0) + #define PCI_MSIX_ENTRY_SIZE 16 #define PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET 0 #define PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET 4 diff --git a/trunk/drivers/pci/pci-acpi.c b/trunk/drivers/pci/pci-acpi.c index a064f36a0805..bb7456c1dbac 100644 --- a/trunk/drivers/pci/pci-acpi.c +++ b/trunk/drivers/pci/pci-acpi.c @@ -36,7 +36,6 @@ acpi_query_osc ( struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL}; union acpi_object *out_obj; u32 osc_dw0; - acpi_status *ret_status = (acpi_status *)retval; /* Setting up input parameters */ @@ -57,7 +56,6 @@ acpi_query_osc ( if (ACPI_FAILURE (status)) { printk(KERN_DEBUG "Evaluate _OSC Set fails. Status = 0x%04x\n", status); - *ret_status = status; return status; } out_obj = output.pointer; @@ -92,7 +90,6 @@ acpi_query_osc ( query_osc_out: kfree(output.pointer); - *ret_status = status; return status; } @@ -169,7 +166,6 @@ acpi_run_osc ( acpi_status pci_osc_support_set(u32 flags) { u32 temp; - acpi_status retval; if (!(flags & OSC_SUPPORT_MASKS)) { return AE_TYPE; @@ -183,13 +179,9 @@ acpi_status pci_osc_support_set(u32 flags) acpi_get_devices ( PCI_ROOT_HID_STRING, acpi_query_osc, ctrlset_buf, - (void **) &retval ); + NULL ); ctrlset_buf[OSC_QUERY_TYPE] = !OSC_QUERY_ENABLE; ctrlset_buf[OSC_CONTROL_TYPE] = temp; - if (ACPI_FAILURE(retval)) { - /* no osc support at all */ - ctrlset_buf[OSC_SUPPORT_TYPE] = 0; - } return AE_OK; } EXPORT_SYMBOL(pci_osc_support_set); diff --git a/trunk/drivers/pci/pci-driver.c b/trunk/drivers/pci/pci-driver.c index e5ae3a0c13bb..b1c0c707d96c 100644 --- a/trunk/drivers/pci/pci-driver.c +++ b/trunk/drivers/pci/pci-driver.c @@ -264,13 +264,6 @@ static int pci_device_remove(struct device * dev) pci_dev->driver = NULL; } - /* - * If the device is still on, set the power state as "unknown", - * since it might change by the next time we load the driver. - */ - if (pci_dev->current_state == PCI_D0) - pci_dev->current_state = PCI_UNKNOWN; - /* * We would love to complain here if pci_dev->is_enabled is set, that * the driver should have called pci_disable_device(), but the @@ -295,12 +288,6 @@ static int pci_device_suspend(struct device * dev, pm_message_t state) suspend_report_result(drv->suspend, i); } else { pci_save_state(pci_dev); - /* - * mark its power state as "unknown", since we don't know if - * e.g. the BIOS will change its device state when we suspend. - */ - if (pci_dev->current_state == PCI_D0) - pci_dev->current_state = PCI_UNKNOWN; } return i; } @@ -329,8 +316,8 @@ static int pci_default_resume(struct pci_dev *pci_dev) /* restore the PCI config space */ pci_restore_state(pci_dev); /* if the device was enabled before suspend, reenable */ - if (atomic_read(&pci_dev->enable_cnt)) - retval = __pci_enable_device(pci_dev); + if (pci_dev->is_enabled) + retval = pci_enable_device(pci_dev); /* if the device was busmaster before the suspend, make it busmaster again */ if (pci_dev->is_busmaster) pci_set_master(pci_dev); @@ -445,12 +432,9 @@ int __pci_register_driver(struct pci_driver *drv, struct module *owner) /* register with core */ error = driver_register(&drv->driver); - if (error) - return error; - error = pci_create_newid_file(drv); - if (error) - driver_unregister(&drv->driver); + if (!error) + error = pci_create_newid_file(drv); return error; } diff --git a/trunk/drivers/pci/pci-sysfs.c b/trunk/drivers/pci/pci-sysfs.c index 7a94076752d0..a1d2e979b17f 100644 --- a/trunk/drivers/pci/pci-sysfs.c +++ b/trunk/drivers/pci/pci-sysfs.c @@ -42,6 +42,7 @@ pci_config_attr(subsystem_vendor, "0x%04x\n"); pci_config_attr(subsystem_device, "0x%04x\n"); pci_config_attr(class, "0x%06x\n"); pci_config_attr(irq, "%u\n"); +pci_config_attr(is_enabled, "%u\n"); static ssize_t broken_parity_status_show(struct device *dev, struct device_attribute *attr, @@ -111,36 +112,26 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, (u8)(pci_dev->class >> 16), (u8)(pci_dev->class >> 8), (u8)(pci_dev->class)); } - -static ssize_t is_enabled_store(struct device *dev, - struct device_attribute *attr, const char *buf, - size_t count) +static ssize_t +is_enabled_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { - ssize_t result = -EINVAL; struct pci_dev *pdev = to_pci_dev(dev); + int retval = 0; /* this can crash the machine when done on the "wrong" device */ if (!capable(CAP_SYS_ADMIN)) return count; - if (*buf == '0') { - if (atomic_read(&pdev->enable_cnt) != 0) - pci_disable_device(pdev); - else - result = -EIO; - } else if (*buf == '1') - result = pci_enable_device(pdev); - - return result < 0 ? result : count; -} + if (*buf == '0') + pci_disable_device(pdev); -static ssize_t is_enabled_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct pci_dev *pdev; + if (*buf == '1') + retval = pci_enable_device(pdev); - pdev = to_pci_dev (dev); - return sprintf (buf, "%u\n", atomic_read(&pdev->enable_cnt)); + if (retval) + return retval; + return count; } static ssize_t @@ -651,9 +642,6 @@ int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev) */ void pci_remove_sysfs_dev_files(struct pci_dev *pdev) { - if (!sysfs_initialized) - return; - if (pdev->cfg_size < 4096) sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr); else diff --git a/trunk/drivers/pci/pci.c b/trunk/drivers/pci/pci.c index 5a14b73cf3a1..a544997399b3 100644 --- a/trunk/drivers/pci/pci.c +++ b/trunk/drivers/pci/pci.c @@ -490,47 +490,6 @@ static void pci_restore_pcie_state(struct pci_dev *dev) kfree(save_state); } - -static int pci_save_pcix_state(struct pci_dev *dev) -{ - int pos, i = 0; - struct pci_cap_saved_state *save_state; - u16 *cap; - - pos = pci_find_capability(dev, PCI_CAP_ID_PCIX); - if (pos <= 0) - return 0; - - save_state = kzalloc(sizeof(*save_state) + sizeof(u16), GFP_KERNEL); - if (!save_state) { - dev_err(&dev->dev, "Out of memory in pci_save_pcie_state\n"); - return -ENOMEM; - } - cap = (u16 *)&save_state->data[0]; - - pci_read_config_word(dev, pos + PCI_X_CMD, &cap[i++]); - pci_add_saved_cap(dev, save_state); - return 0; -} - -static void pci_restore_pcix_state(struct pci_dev *dev) -{ - int i = 0, pos; - struct pci_cap_saved_state *save_state; - u16 *cap; - - save_state = pci_find_saved_cap(dev, PCI_CAP_ID_PCIX); - pos = pci_find_capability(dev, PCI_CAP_ID_PCIX); - if (!save_state || pos <= 0) - return; - cap = (u16 *)&save_state->data[0]; - - pci_write_config_word(dev, pos + PCI_X_CMD, cap[i++]); - pci_remove_saved_cap(save_state); - kfree(save_state); -} - - /** * pci_save_state - save the PCI configuration space of a device before suspending * @dev: - PCI device that we're dealing with @@ -548,8 +507,6 @@ pci_save_state(struct pci_dev *dev) return i; if ((i = pci_save_pcie_state(dev)) != 0) return i; - if ((i = pci_save_pcix_state(dev)) != 0) - return i; return 0; } @@ -581,7 +538,6 @@ pci_restore_state(struct pci_dev *dev) dev->saved_config_space[i]); } } - pci_restore_pcix_state(dev); pci_restore_msi_state(dev); pci_restore_msix_state(dev); return 0; @@ -612,50 +568,29 @@ pci_enable_device_bars(struct pci_dev *dev, int bars) } /** - * __pci_enable_device - Initialize device before it's used by a driver. + * pci_enable_device - Initialize device before it's used by a driver. * @dev: PCI device to be initialized * * Initialize device before it's used by a driver. Ask low-level code * to enable I/O and memory. Wake up the device if it was suspended. * Beware, this function can fail. - * - * Note this function is a backend and is not supposed to be called by - * normal code, use pci_enable_device() instead. */ int -__pci_enable_device(struct pci_dev *dev) +pci_enable_device(struct pci_dev *dev) { int err; + if (dev->is_enabled) + return 0; + err = pci_enable_device_bars(dev, (1 << PCI_NUM_RESOURCES) - 1); if (err) return err; pci_fixup_device(pci_fixup_enable, dev); + dev->is_enabled = 1; return 0; } -/** - * pci_enable_device - Initialize device before it's used by a driver. - * @dev: PCI device to be initialized - * - * Initialize device before it's used by a driver. Ask low-level code - * to enable I/O and memory. Wake up the device if it was suspended. - * Beware, this function can fail. - * - * Note we don't actually enable the device many times if we call - * this function repeatedly (we just increment the count). - */ -int pci_enable_device(struct pci_dev *dev) -{ - int result; - if (atomic_add_return(1, &dev->enable_cnt) > 1) - return 0; /* already enabled */ - result = __pci_enable_device(dev); - if (result < 0) - atomic_dec(&dev->enable_cnt); - return result; -} - /** * pcibios_disable_device - disable arch specific PCI resources for device dev * @dev: the PCI device to disable @@ -672,18 +607,12 @@ void __attribute__ ((weak)) pcibios_disable_device (struct pci_dev *dev) {} * * Signal to the system that the PCI device is not in use by the system * anymore. This only involves disabling PCI bus-mastering, if active. - * - * Note we don't actually disable the device until all callers of - * pci_device_enable() have called pci_device_disable(). */ void pci_disable_device(struct pci_dev *dev) { u16 pci_command; - if (atomic_sub_return(1, &dev->enable_cnt) != 0) - return; - if (dev->msi_enabled) disable_msi_mode(dev, pci_find_capability(dev, PCI_CAP_ID_MSI), PCI_CAP_ID_MSI); @@ -699,6 +628,7 @@ pci_disable_device(struct pci_dev *dev) dev->is_busmaster = 0; pcibios_disable_device(dev); + dev->is_enabled = 0; } /** @@ -901,38 +831,22 @@ pci_set_master(struct pci_dev *dev) pcibios_set_master(dev); } -#ifdef PCI_DISABLE_MWI -int pci_set_mwi(struct pci_dev *dev) -{ - return 0; -} - -void pci_clear_mwi(struct pci_dev *dev) -{ -} - -#else - -#ifndef PCI_CACHE_LINE_BYTES -#define PCI_CACHE_LINE_BYTES L1_CACHE_BYTES -#endif - +#ifndef HAVE_ARCH_PCI_MWI /* This can be overridden by arch code. */ -/* Don't forget this is measured in 32-bit words, not bytes */ -u8 pci_cache_line_size = PCI_CACHE_LINE_BYTES / 4; +u8 pci_cache_line_size = L1_CACHE_BYTES >> 2; /** - * pci_set_cacheline_size - ensure the CACHE_LINE_SIZE register is programmed - * @dev: the PCI device for which MWI is to be enabled + * pci_generic_prep_mwi - helper function for pci_set_mwi + * @dev: the PCI device for which MWI is enabled * - * Helper function for pci_set_mwi. - * Originally copied from drivers/net/acenic.c. + * Helper function for generic implementation of pcibios_prep_mwi + * function. Originally copied from drivers/net/acenic.c. * Copyright 1998-2001 by Jes Sorensen, . * * RETURNS: An appropriate -ERRNO error value on error, or zero for success. */ static int -pci_set_cacheline_size(struct pci_dev *dev) +pci_generic_prep_mwi(struct pci_dev *dev) { u8 cacheline_size; @@ -958,6 +872,7 @@ pci_set_cacheline_size(struct pci_dev *dev) return -EINVAL; } +#endif /* !HAVE_ARCH_PCI_MWI */ /** * pci_set_mwi - enables memory-write-invalidate PCI transaction @@ -975,7 +890,12 @@ pci_set_mwi(struct pci_dev *dev) int rc; u16 cmd; - rc = pci_set_cacheline_size(dev); +#ifdef HAVE_ARCH_PCI_MWI + rc = pcibios_prep_mwi(dev); +#else + rc = pci_generic_prep_mwi(dev); +#endif + if (rc) return rc; @@ -1006,7 +926,6 @@ pci_clear_mwi(struct pci_dev *dev) pci_write_config_word(dev, PCI_COMMAND, cmd); } } -#endif /* ! PCI_DISABLE_MWI */ /** * pci_intx - enables/disables PCI INTx for device dev diff --git a/trunk/drivers/pci/pci.h b/trunk/drivers/pci/pci.h index 398852f526a6..6bf327db5c5e 100644 --- a/trunk/drivers/pci/pci.h +++ b/trunk/drivers/pci/pci.h @@ -1,6 +1,5 @@ /* Functions internal to the PCI core code */ -extern int __must_check __pci_enable_device(struct pci_dev *); extern int pci_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size); extern int pci_create_sysfs_dev_files(struct pci_dev *pdev); diff --git a/trunk/drivers/pci/pcie/aer/aerdrv.c b/trunk/drivers/pci/pcie/aer/aerdrv.c index 04c43ef529ac..0d4ac027d53e 100644 --- a/trunk/drivers/pci/pcie/aer/aerdrv.c +++ b/trunk/drivers/pci/pcie/aer/aerdrv.c @@ -85,10 +85,11 @@ static struct pcie_port_service_driver aerdrv = { * aer_irq - Root Port's ISR * @irq: IRQ assigned to Root Port * @context: pointer to Root Port data structure + * @r: pointer struct pt_regs * * Invoked when Root Port detects AER messages. **/ -static irqreturn_t aer_irq(int irq, void *context) +static irqreturn_t aer_irq(int irq, void *context, struct pt_regs * r) { unsigned int status, id; struct pcie_device *pdev = (struct pcie_device *)context; diff --git a/trunk/drivers/pci/pcie/portdrv.h b/trunk/drivers/pci/pcie/portdrv.h index 3656e0349dd1..67fcd176babd 100644 --- a/trunk/drivers/pci/pcie/portdrv.h +++ b/trunk/drivers/pci/pcie/portdrv.h @@ -9,8 +9,6 @@ #ifndef _PORTDRV_H_ #define _PORTDRV_H_ -#include - #if !defined(PCI_CAP_ID_PME) #define PCI_CAP_ID_PME 1 #endif @@ -41,7 +39,7 @@ extern int pcie_port_device_suspend(struct pci_dev *dev, pm_message_t state); extern int pcie_port_device_resume(struct pci_dev *dev); #endif extern void pcie_port_device_remove(struct pci_dev *dev); -extern int __must_check pcie_port_bus_register(void); +extern int pcie_port_bus_register(void); extern void pcie_port_bus_unregister(void); #endif /* _PORTDRV_H_ */ diff --git a/trunk/drivers/pci/pcie/portdrv_core.c b/trunk/drivers/pci/pcie/portdrv_core.c index b20a9b81dae2..bd6615b4d40e 100644 --- a/trunk/drivers/pci/pcie/portdrv_core.c +++ b/trunk/drivers/pci/pcie/portdrv_core.c @@ -6,6 +6,7 @@ * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com) */ +#include #include #include #include @@ -400,7 +401,7 @@ void pcie_port_device_remove(struct pci_dev *dev) pci_disable_msi(dev); } -int pcie_port_bus_register(void) +int __must_check pcie_port_bus_register(void) { return bus_register(&pcie_port_bus_type); } diff --git a/trunk/drivers/pci/pcie/portdrv_pci.c b/trunk/drivers/pci/pcie/portdrv_pci.c index b4da7954611e..037690e08f5f 100644 --- a/trunk/drivers/pci/pcie/portdrv_pci.c +++ b/trunk/drivers/pci/pcie/portdrv_pci.c @@ -37,6 +37,7 @@ static int pcie_portdrv_save_config(struct pci_dev *dev) return pci_save_state(dev); } +#ifdef CONFIG_PM static int pcie_portdrv_restore_config(struct pci_dev *dev) { int retval; @@ -49,7 +50,6 @@ static int pcie_portdrv_restore_config(struct pci_dev *dev) return 0; } -#ifdef CONFIG_PM static int pcie_portdrv_suspend(struct pci_dev *dev, pm_message_t state) { int ret = pcie_port_device_suspend(dev, state); diff --git a/trunk/drivers/pci/probe.c b/trunk/drivers/pci/probe.c index 0eeac60042b3..a3b0a5eb5054 100644 --- a/trunk/drivers/pci/probe.c +++ b/trunk/drivers/pci/probe.c @@ -679,33 +679,6 @@ static int pci_setup_device(struct pci_dev * dev) pci_read_bases(dev, 6, PCI_ROM_ADDRESS); pci_read_config_word(dev, PCI_SUBSYSTEM_VENDOR_ID, &dev->subsystem_vendor); pci_read_config_word(dev, PCI_SUBSYSTEM_ID, &dev->subsystem_device); - - /* - * Do the ugly legacy mode stuff here rather than broken chip - * quirk code. Legacy mode ATA controllers have fixed - * addresses. These are not always echoed in BAR0-3, and - * BAR0-3 in a few cases contain junk! - */ - if (class == PCI_CLASS_STORAGE_IDE) { - u8 progif; - pci_read_config_byte(dev, PCI_CLASS_PROG, &progif); - if ((progif & 1) == 0) { - dev->resource[0].start = 0x1F0; - dev->resource[0].end = 0x1F7; - dev->resource[0].flags = IORESOURCE_IO; - dev->resource[1].start = 0x3F6; - dev->resource[1].end = 0x3F6; - dev->resource[1].flags = IORESOURCE_IO; - } - if ((progif & 4) == 0) { - dev->resource[2].start = 0x170; - dev->resource[2].end = 0x177; - dev->resource[2].flags = IORESOURCE_IO; - dev->resource[3].start = 0x376; - dev->resource[3].end = 0x376; - dev->resource[3].flags = IORESOURCE_IO; - } - } break; case PCI_HEADER_TYPE_BRIDGE: /* bridge header */ @@ -1094,95 +1067,3 @@ EXPORT_SYMBOL(pci_scan_bridge); EXPORT_SYMBOL(pci_scan_single_device); EXPORT_SYMBOL_GPL(pci_scan_child_bus); #endif - -static int __init pci_sort_bf_cmp(const struct pci_dev *a, const struct pci_dev *b) -{ - if (pci_domain_nr(a->bus) < pci_domain_nr(b->bus)) return -1; - else if (pci_domain_nr(a->bus) > pci_domain_nr(b->bus)) return 1; - - if (a->bus->number < b->bus->number) return -1; - else if (a->bus->number > b->bus->number) return 1; - - if (a->devfn < b->devfn) return -1; - else if (a->devfn > b->devfn) return 1; - - return 0; -} - -/* - * Yes, this forcably breaks the klist abstraction temporarily. It - * just wants to sort the klist, not change reference counts and - * take/drop locks rapidly in the process. It does all this while - * holding the lock for the list, so objects can't otherwise be - * added/removed while we're swizzling. - */ -static void __init pci_insertion_sort_klist(struct pci_dev *a, struct list_head *list) -{ - struct list_head *pos; - struct klist_node *n; - struct device *dev; - struct pci_dev *b; - - list_for_each(pos, list) { - n = container_of(pos, struct klist_node, n_node); - dev = container_of(n, struct device, knode_bus); - b = to_pci_dev(dev); - if (pci_sort_bf_cmp(a, b) <= 0) { - list_move_tail(&a->dev.knode_bus.n_node, &b->dev.knode_bus.n_node); - return; - } - } - list_move_tail(&a->dev.knode_bus.n_node, list); -} - -static void __init pci_sort_breadthfirst_klist(void) -{ - LIST_HEAD(sorted_devices); - struct list_head *pos, *tmp; - struct klist_node *n; - struct device *dev; - struct pci_dev *pdev; - - spin_lock(&pci_bus_type.klist_devices.k_lock); - list_for_each_safe(pos, tmp, &pci_bus_type.klist_devices.k_list) { - n = container_of(pos, struct klist_node, n_node); - dev = container_of(n, struct device, knode_bus); - pdev = to_pci_dev(dev); - pci_insertion_sort_klist(pdev, &sorted_devices); - } - list_splice(&sorted_devices, &pci_bus_type.klist_devices.k_list); - spin_unlock(&pci_bus_type.klist_devices.k_lock); -} - -static void __init pci_insertion_sort_devices(struct pci_dev *a, struct list_head *list) -{ - struct pci_dev *b; - - list_for_each_entry(b, list, global_list) { - if (pci_sort_bf_cmp(a, b) <= 0) { - list_move_tail(&a->global_list, &b->global_list); - return; - } - } - list_move_tail(&a->global_list, list); -} - -static void __init pci_sort_breadthfirst_devices(void) -{ - LIST_HEAD(sorted_devices); - struct pci_dev *dev, *tmp; - - down_write(&pci_bus_sem); - list_for_each_entry_safe(dev, tmp, &pci_devices, global_list) { - pci_insertion_sort_devices(dev, &sorted_devices); - } - list_splice(&sorted_devices, &pci_devices); - up_write(&pci_bus_sem); -} - -void __init pci_sort_breadthfirst(void) -{ - pci_sort_breadthfirst_devices(); - pci_sort_breadthfirst_klist(); -} - diff --git a/trunk/drivers/pci/quirks.c b/trunk/drivers/pci/quirks.c index 9ca9b9bf6160..23b599d6a9d5 100644 --- a/trunk/drivers/pci/quirks.c +++ b/trunk/drivers/pci/quirks.c @@ -453,12 +453,6 @@ static void __devinit quirk_ich6_lpc_acpi(struct pci_dev *dev) } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0, quirk_ich6_lpc_acpi ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, quirk_ich6_lpc_acpi ); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0, quirk_ich6_lpc_acpi ); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1, quirk_ich6_lpc_acpi ); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_31, quirk_ich6_lpc_acpi ); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_0, quirk_ich6_lpc_acpi ); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_2, quirk_ich6_lpc_acpi ); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_3, quirk_ich6_lpc_acpi ); /* * VIA ACPI: One IO region pointed to by longword at @@ -654,43 +648,11 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_vi * Some of the on-chip devices are actually '586 devices' so they are * listed here. */ - -static int via_irq_fixup_needed = -1; - -/* - * As some VIA hardware is available in PCI-card form, we need to restrict - * this quirk to VIA PCI hardware built onto VIA-based motherboards only. - * We try to locate a VIA southbridge before deciding whether the quirk - * should be applied. - */ -static const struct pci_device_id via_irq_fixup_tbl[] = { - { - .vendor = PCI_VENDOR_ID_VIA, - .device = PCI_ANY_ID, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .class = PCI_CLASS_BRIDGE_ISA << 8, - .class_mask = 0xffff00, - }, - { 0, }, -}; - static void quirk_via_irq(struct pci_dev *dev) { u8 irq, new_irq; - if (via_irq_fixup_needed == -1) - via_irq_fixup_needed = pci_dev_present(via_irq_fixup_tbl); - - if (!via_irq_fixup_needed) - return; - - new_irq = dev->irq; - - /* Don't quirk interrupts outside the legacy IRQ range */ - if (!new_irq || new_irq > 15) - return; - + new_irq = dev->irq & 0xf; pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); if (new_irq != irq) { printk(KERN_INFO "PCI: VIA IRQ fixup for %s, from %d to %d\n", @@ -699,7 +661,14 @@ static void quirk_via_irq(struct pci_dev *dev) pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq); } } -DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_irq); +DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_0, quirk_via_irq); +DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, quirk_via_irq); +DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2, quirk_via_irq); +DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_via_irq); +DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235_USB_2, quirk_via_irq); +DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_irq); +DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_via_irq); +DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_5, quirk_via_irq); /* * VIA VT82C598 has its device ID settable and many BIOSes @@ -714,6 +683,33 @@ static void __devinit quirk_vt82c598_id(struct pci_dev *dev) } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C597_0, quirk_vt82c598_id ); +#ifdef CONFIG_ACPI_SLEEP + +/* + * Some VIA systems boot with the abnormal status flag set. This can cause + * the BIOS to re-POST the system on resume rather than passing control + * back to the OS. Clear the flag on boot + */ +static void __devinit quirk_via_abnormal_poweroff(struct pci_dev *dev) +{ + u32 reg; + + acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_STATUS, + ®); + + if (reg & 0x800) { + printk("Clearing abnormal poweroff flag\n"); + acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, + ACPI_REGISTER_PM1_STATUS, + (u16)0x800); + } +} + +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, quirk_via_abnormal_poweroff); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, quirk_via_abnormal_poweroff); + +#endif + /* * CardBus controllers have a legacy base address that enables them * to respond as i82365 pcmcia controllers. We don't want them to @@ -796,6 +792,56 @@ static void __init quirk_mediagx_master(struct pci_dev *dev) } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_PCI_MASTER, quirk_mediagx_master ); +/* + * As per PCI spec, ignore base address registers 0-3 of the IDE controllers + * running in Compatible mode (bits 0 and 2 in the ProgIf for primary and + * secondary channels respectively). If the device reports Compatible mode + * but does use BAR0-3 for address decoding, we assume that firmware has + * programmed these BARs with standard values (0x1f0,0x3f4 and 0x170,0x374). + * Exceptions (if they exist) must be handled in chip/architecture specific + * fixups. + * + * Note: for non x86 people. You may need an arch specific quirk to handle + * moving IDE devices to native mode as well. Some plug in card devices power + * up in compatible mode and assume the BIOS will adjust them. + * + * Q: should we load the 0x1f0,0x3f4 into the registers or zap them as + * we do now ? We don't want is pci_enable_device to come along + * and assign new resources. Both approaches work for that. + */ +static void __devinit quirk_ide_bases(struct pci_dev *dev) +{ + struct resource *res; + int first_bar = 2, last_bar = 0; + + if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE) + return; + + res = &dev->resource[0]; + + /* primary channel: ProgIf bit 0, BAR0, BAR1 */ + if (!(dev->class & 1) && (res[0].flags || res[1].flags)) { + res[0].start = res[0].end = res[0].flags = 0; + res[1].start = res[1].end = res[1].flags = 0; + first_bar = 0; + last_bar = 1; + } + + /* secondary channel: ProgIf bit 2, BAR2, BAR3 */ + if (!(dev->class & 4) && (res[2].flags || res[3].flags)) { + res[2].start = res[2].end = res[2].flags = 0; + res[3].start = res[3].end = res[3].flags = 0; + last_bar = 3; + } + + if (!last_bar) + return; + + printk(KERN_INFO "PCI: Ignoring BAR%d-%d of IDE controller %s\n", + first_bar, last_bar, pci_name(dev)); +} +DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, quirk_ide_bases); + /* * Ensure C0 rev restreaming is off. This is normally done by * the BIOS but in the odd case it is not the results are corruption @@ -830,10 +876,11 @@ static void __devinit quirk_svwks_csb5ide(struct pci_dev *pdev) prog &= ~5; pdev->class &= ~5; pci_write_config_byte(pdev, PCI_CLASS_PROG, prog); - /* PCI layer will sort out resources */ + /* need to re-assign BARs for compat mode */ + quirk_ide_bases(pdev); } } -DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, quirk_svwks_csb5ide ); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, quirk_svwks_csb5ide ); /* * Intel 82801CAM ICH3-M datasheet says IDE modes must be the same @@ -849,9 +896,11 @@ static void __init quirk_ide_samemode(struct pci_dev *pdev) prog &= ~5; pdev->class &= ~5; pci_write_config_byte(pdev, PCI_CLASS_PROG, prog); + /* need to re-assign BARs for compat mode */ + quirk_ide_bases(pdev); } } -DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_10, quirk_ide_samemode); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_10, quirk_ide_samemode); /* This was originally an Alpha specific thing, but it really fits here. * The i82375 PCI/EISA bridge appears as non-classified. Fix that. @@ -1407,6 +1456,33 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2609, quirk_intel_pcie_pm); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x260a, quirk_intel_pcie_pm); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x260b, quirk_intel_pcie_pm); +/* + * Fixup the cardbus bridges on the IBM Dock II docking station + */ +static void __devinit quirk_ibm_dock2_cardbus(struct pci_dev *dev) +{ + u32 val; + + /* + * tie the 2 interrupt pins to INTA, and configure the + * multifunction routing register to handle this. + */ + if ((dev->subsystem_vendor == PCI_VENDOR_ID_IBM) && + (dev->subsystem_device == 0x0148)) { + printk(KERN_INFO "PCI: Found IBM Dock II Cardbus Bridge " + "applying quirk\n"); + pci_read_config_dword(dev, 0x8c, &val); + val = ((val & 0xffffff00) | 0x1002); + pci_write_config_dword(dev, 0x8c, val); + pci_read_config_dword(dev, 0x80, &val); + val = ((val & 0x00ffff00) | 0x2864c077); + pci_write_config_dword(dev, 0x80, val); + } +} + +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1420, + quirk_ibm_dock2_cardbus); + static void __devinit quirk_netmos(struct pci_dev *dev) { unsigned int num_parallel = (dev->subsystem_device & 0xf0) >> 4; @@ -1512,6 +1588,7 @@ static void __devinit fixup_rev1_53c810(struct pci_dev* dev) } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, fixup_rev1_53c810); + static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_fixup *end) { while (f < end) { @@ -1687,7 +1764,7 @@ static void __devinit quirk_nvidia_ck804_msi_ht_cap(struct pci_dev *dev) /* check HT MSI cap on this chipset and the root one. * a single one having MSI is enough to be sure that MSI are supported. */ - pdev = pci_get_slot(dev->bus, 0); + pdev = pci_find_slot(dev->bus->number, 0); if (dev->subordinate && !msi_ht_cap_enabled(dev) && !msi_ht_cap_enabled(pdev)) { printk(KERN_WARNING "PCI: MSI quirk detected. " @@ -1695,7 +1772,6 @@ static void __devinit quirk_nvidia_ck804_msi_ht_cap(struct pci_dev *dev) pci_name(dev)); dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI; } - pci_dev_put(pdev); } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, quirk_nvidia_ck804_msi_ht_cap); diff --git a/trunk/drivers/pci/rom.c b/trunk/drivers/pci/rom.c index d087e0817715..f5ee7ce16fa6 100644 --- a/trunk/drivers/pci/rom.c +++ b/trunk/drivers/pci/rom.c @@ -71,18 +71,13 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size) void __iomem *image; int last_image; - /* - * IORESOURCE_ROM_SHADOW set on x86, x86_64 and IA64 supports legacy - * memory map if the VGA enable bit of the Bridge Control register is - * set for embedded VGA. - */ + /* IORESOURCE_ROM_SHADOW only set on x86 */ if (res->flags & IORESOURCE_ROM_SHADOW) { /* primary video rom always starts here */ start = (loff_t)0xC0000; *size = 0x20000; /* cover C000:0 through E000:0 */ } else { - if (res->flags & - (IORESOURCE_ROM_COPY | IORESOURCE_ROM_BIOS_COPY)) { + if (res->flags & IORESOURCE_ROM_COPY) { *size = pci_resource_len(pdev, PCI_ROM_RESOURCE); return (void __iomem *)(unsigned long) pci_resource_start(pdev, PCI_ROM_RESOURCE); @@ -166,8 +161,7 @@ void __iomem *pci_map_rom_copy(struct pci_dev *pdev, size_t *size) if (!rom) return NULL; - if (res->flags & (IORESOURCE_ROM_COPY | IORESOURCE_ROM_SHADOW | - IORESOURCE_ROM_BIOS_COPY)) + if (res->flags & (IORESOURCE_ROM_COPY | IORESOURCE_ROM_SHADOW)) return rom; res->start = (unsigned long)kmalloc(*size, GFP_KERNEL); @@ -193,7 +187,7 @@ void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom) { struct resource *res = &pdev->resource[PCI_ROM_RESOURCE]; - if (res->flags & (IORESOURCE_ROM_COPY | IORESOURCE_ROM_BIOS_COPY)) + if (res->flags & IORESOURCE_ROM_COPY) return; iounmap(rom); @@ -217,7 +211,6 @@ void pci_remove_rom(struct pci_dev *pdev) sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr); if (!(res->flags & (IORESOURCE_ROM_ENABLE | IORESOURCE_ROM_SHADOW | - IORESOURCE_ROM_BIOS_COPY | IORESOURCE_ROM_COPY))) pci_disable_rom(pdev); } diff --git a/trunk/drivers/pci/search.c b/trunk/drivers/pci/search.c index 2f13eba5d5ae..d529462d1b53 100644 --- a/trunk/drivers/pci/search.c +++ b/trunk/drivers/pci/search.c @@ -139,31 +139,6 @@ struct pci_dev * pci_get_slot(struct pci_bus *bus, unsigned int devfn) return dev; } -/** - * pci_get_bus_and_slot - locate PCI device from a given PCI slot - * @bus: number of PCI bus on which desired PCI device resides - * @devfn: encodes number of PCI slot in which the desired PCI - * device resides and the logical device number within that slot - * in case of multi-function devices. - * - * Given a PCI bus and slot/function number, the desired PCI device - * is located in system global list of PCI devices. If the device - * is found, a pointer to its data structure is returned. If no - * device is found, %NULL is returned. The returned device has its - * reference count bumped by one. - */ - -struct pci_dev * pci_get_bus_and_slot(unsigned int bus, unsigned int devfn) -{ - struct pci_dev *dev = NULL; - - while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { - if (dev->bus->number == bus && dev->devfn == devfn) - return dev; - } - return NULL; -} - /** * pci_find_subsys - begin or continue searching for a PCI device by vendor/subvendor/device/subdevice id * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids @@ -299,45 +274,6 @@ pci_get_device(unsigned int vendor, unsigned int device, struct pci_dev *from) return pci_get_subsys(vendor, device, PCI_ANY_ID, PCI_ANY_ID, from); } -/** - * pci_get_device_reverse - begin or continue searching for a PCI device by vendor/device id - * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids - * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids - * @from: Previous PCI device found in search, or %NULL for new search. - * - * Iterates through the list of known PCI devices in the reverse order of - * pci_get_device. - * If a PCI device is found with a matching @vendor and @device, the reference - * count to the device is incremented and a pointer to its device structure - * is returned Otherwise, %NULL is returned. A new search is initiated by - * passing %NULL as the @from argument. Otherwise if @from is not %NULL, - * searches continue from next device on the global list. The reference - * count for @from is always decremented if it is not %NULL. - */ -struct pci_dev * -pci_get_device_reverse(unsigned int vendor, unsigned int device, struct pci_dev *from) -{ - struct list_head *n; - struct pci_dev *dev; - - WARN_ON(in_interrupt()); - down_read(&pci_bus_sem); - n = from ? from->global_list.prev : pci_devices.prev; - - while (n && (n != &pci_devices)) { - dev = pci_dev_g(n); - if ((vendor == PCI_ANY_ID || dev->vendor == vendor) && - (device == PCI_ANY_ID || dev->device == device)) - goto exit; - n = n->prev; - } - dev = NULL; -exit: - dev = pci_dev_get(dev); - up_read(&pci_bus_sem); - pci_dev_put(from); - return dev; -} /** * pci_find_device_reverse - begin or continue searching for a PCI device by vendor/device id @@ -446,16 +382,12 @@ int pci_dev_present(const struct pci_device_id *ids) } EXPORT_SYMBOL(pci_dev_present); +EXPORT_SYMBOL(pci_find_bus); +EXPORT_SYMBOL(pci_find_next_bus); EXPORT_SYMBOL(pci_find_device); EXPORT_SYMBOL(pci_find_device_reverse); EXPORT_SYMBOL(pci_find_slot); -/* For boot time work */ -EXPORT_SYMBOL(pci_find_bus); -EXPORT_SYMBOL(pci_find_next_bus); -/* For everyone */ EXPORT_SYMBOL(pci_get_device); -EXPORT_SYMBOL(pci_get_device_reverse); EXPORT_SYMBOL(pci_get_subsys); EXPORT_SYMBOL(pci_get_slot); -EXPORT_SYMBOL(pci_get_bus_and_slot); EXPORT_SYMBOL(pci_get_class); diff --git a/trunk/drivers/pcmcia/at91_cf.c b/trunk/drivers/pcmcia/at91_cf.c index 3bcb7dc32995..40569f40e90e 100644 --- a/trunk/drivers/pcmcia/at91_cf.c +++ b/trunk/drivers/pcmcia/at91_cf.c @@ -64,9 +64,9 @@ static int at91_cf_ss_init(struct pcmcia_socket *s) return 0; } -static irqreturn_t at91_cf_irq(int irq, void *_cf) +static irqreturn_t at91_cf_irq(int irq, void *_cf, struct pt_regs *r) { - struct at91_cf_socket *cf = _cf; + struct at91_cf_socket *cf = (struct at91_cf_socket *) _cf; if (irq == cf->board->det_pin) { unsigned present = at91_cf_present(cf); @@ -241,6 +241,12 @@ static int __init at91_cf_probe(struct platform_device *pdev) csa = at91_sys_read(AT91_EBI_CSA); at91_sys_write(AT91_EBI_CSA, csa | AT91_EBI_CS4A_SMC_COMPACTFLASH); + /* force poweron defaults for these pins ... */ + (void) at91_set_A_periph(AT91_PIN_PC9, 0); /* A25/CFRNW */ + (void) at91_set_A_periph(AT91_PIN_PC10, 0); /* NCS4/CFCS */ + (void) at91_set_A_periph(AT91_PIN_PC11, 0); /* NCS5/CFCE1 */ + (void) at91_set_A_periph(AT91_PIN_PC12, 0); /* NCS6/CFCE2 */ + /* nWAIT is _not_ a default setting */ (void) at91_set_A_periph(AT91_PIN_PC6, 1); /* nWAIT */ @@ -310,14 +316,12 @@ static int __init at91_cf_probe(struct platform_device *pdev) return 0; fail2: + iounmap((void __iomem *) cf->socket.io_offset); release_mem_region(io->start, io->end + 1 - io->start); fail1: - if (cf->socket.io_offset) - iounmap((void __iomem *) cf->socket.io_offset); if (board->irq_pin) free_irq(board->irq_pin, cf); fail0a: - device_init_wakeup(&pdev->dev, 0); free_irq(board->det_pin, cf); device_init_wakeup(&pdev->dev, 0); fail0: @@ -356,20 +360,26 @@ static int at91_cf_suspend(struct platform_device *pdev, pm_message_t mesg) struct at91_cf_data *board = cf->board; pcmcia_socket_dev_suspend(&pdev->dev, mesg); - if (device_may_wakeup(&pdev->dev)) { + if (device_may_wakeup(&pdev->dev)) enable_irq_wake(board->det_pin); - if (board->irq_pin) - enable_irq_wake(board->irq_pin); - } else { + else { disable_irq_wake(board->det_pin); - if (board->irq_pin) - disable_irq_wake(board->irq_pin); + disable_irq(board->det_pin); } + if (board->irq_pin) + disable_irq(board->irq_pin); return 0; } static int at91_cf_resume(struct platform_device *pdev) { + struct at91_cf_socket *cf = platform_get_drvdata(pdev); + struct at91_cf_data *board = cf->board; + + if (board->irq_pin) + enable_irq(board->irq_pin); + if (!device_may_wakeup(&pdev->dev)) + enable_irq(board->det_pin); pcmcia_socket_dev_resume(&pdev->dev); return 0; } diff --git a/trunk/drivers/pcmcia/au1000_generic.c b/trunk/drivers/pcmcia/au1000_generic.c index 551bde5d9430..d5dd0ce65536 100644 --- a/trunk/drivers/pcmcia/au1000_generic.c +++ b/trunk/drivers/pcmcia/au1000_generic.c @@ -351,7 +351,6 @@ struct skt_dev_info { int au1x00_pcmcia_socket_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr) { struct skt_dev_info *sinfo; - struct au1000_pcmcia_socket *skt; int ret, i; sinfo = kzalloc(sizeof(struct skt_dev_info), GFP_KERNEL); @@ -366,7 +365,7 @@ int au1x00_pcmcia_socket_probe(struct device *dev, struct pcmcia_low_level *ops, * Initialise the per-socket structure. */ for (i = 0; i < nr; i++) { - skt = PCMCIA_SOCKET(i); + struct au1000_pcmcia_socket *skt = PCMCIA_SOCKET(i); memset(skt, 0, sizeof(*skt)); skt->socket.resource_ops = &pccard_static_ops; @@ -439,29 +438,17 @@ int au1x00_pcmcia_socket_probe(struct device *dev, struct pcmcia_low_level *ops, dev_set_drvdata(dev, sinfo); return 0; - -out_err: - flush_scheduled_work(); - ops->hw_shutdown(skt); - while (i-- > 0) { - skt = PCMCIA_SOCKET(i); + do { + struct au1000_pcmcia_socket *skt = PCMCIA_SOCKET(i); del_timer_sync(&skt->poll_timer); pcmcia_unregister_socket(&skt->socket); +out_err: flush_scheduled_work(); - if (i == 0) { - iounmap(skt->virt_io + (u32)mips_io_port_base); - skt->virt_io = NULL; - } -#ifndef CONFIG_MIPS_XXS1500 - else { - iounmap(skt->virt_io + (u32)mips_io_port_base); - skt->virt_io = NULL; - } -#endif ops->hw_shutdown(skt); - } + i--; + } while (i > 0); kfree(sinfo); out: return ret; diff --git a/trunk/drivers/pcmcia/ds.c b/trunk/drivers/pcmcia/ds.c index 21d83a895b21..74b3124e8247 100644 --- a/trunk/drivers/pcmcia/ds.c +++ b/trunk/drivers/pcmcia/ds.c @@ -717,7 +717,6 @@ static int pcmcia_requery(struct device *dev, void * _data) static void pcmcia_bus_rescan(struct pcmcia_socket *skt) { int no_devices=0; - int ret = 0; unsigned long flags; /* must be called with skt_mutex held */ @@ -730,7 +729,7 @@ static void pcmcia_bus_rescan(struct pcmcia_socket *skt) * missing resource information or other trouble, we need to * do this now. */ if (no_devices) { - ret = pcmcia_card_add(skt); + int ret = pcmcia_card_add(skt); if (ret) return; } @@ -742,9 +741,7 @@ static void pcmcia_bus_rescan(struct pcmcia_socket *skt) /* we re-scan all devices, not just the ones connected to this * socket. This does not matter, though. */ - ret = bus_rescan_devices(&pcmcia_bus_type); - if (ret) - printk(KERN_INFO "pcmcia: bus_rescan_devices failed\n"); + bus_rescan_devices(&pcmcia_bus_type); } static inline int pcmcia_devmatch(struct pcmcia_device *dev, @@ -1004,7 +1001,6 @@ static ssize_t pcmcia_store_allow_func_id_match(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct pcmcia_device *p_dev = to_pcmcia_dev(dev); - int ret; if (!count) return -EINVAL; @@ -1013,10 +1009,7 @@ static ssize_t pcmcia_store_allow_func_id_match(struct device *dev, p_dev->allow_func_id_match = 1; mutex_unlock(&p_dev->socket->skt_mutex); - ret = bus_rescan_devices(&pcmcia_bus_type); - if (ret) - printk(KERN_INFO "pcmcia: bus_rescan_devices failed after " - "allowing func_id matches\n"); + bus_rescan_devices(&pcmcia_bus_type); return count; } @@ -1271,11 +1264,6 @@ static void pcmcia_bus_remove_socket(struct class_device *class_dev, socket->pcmcia_state.dead = 1; pccard_register_pcmcia(socket, NULL); - /* unregister any unbound devices */ - mutex_lock(&socket->skt_mutex); - pcmcia_card_remove(socket, NULL); - mutex_unlock(&socket->skt_mutex); - pcmcia_put_socket(socket); return; @@ -1304,22 +1292,10 @@ struct bus_type pcmcia_bus_type = { static int __init init_pcmcia_bus(void) { - int ret; - spin_lock_init(&pcmcia_dev_list_lock); - ret = bus_register(&pcmcia_bus_type); - if (ret < 0) { - printk(KERN_WARNING "pcmcia: bus_register error: %d\n", ret); - return ret; - } - ret = class_interface_register(&pcmcia_bus_interface); - if (ret < 0) { - printk(KERN_WARNING - "pcmcia: class_interface_register error: %d\n", ret); - bus_unregister(&pcmcia_bus_type); - return ret; - } + bus_register(&pcmcia_bus_type); + class_interface_register(&pcmcia_bus_interface); pcmcia_setup_ioctl(); diff --git a/trunk/drivers/pcmcia/hd64465_ss.c b/trunk/drivers/pcmcia/hd64465_ss.c index caca0dc9d30f..ad02629c8be2 100644 --- a/trunk/drivers/pcmcia/hd64465_ss.c +++ b/trunk/drivers/pcmcia/hd64465_ss.c @@ -650,7 +650,7 @@ static int hs_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *mem) */ static int hs_irq_demux(int irq, void *dev) { - hs_socket_t *sp = dev; + hs_socket_t *sp = (hs_socket_t *)dev; u_int cscr; DPRINTK("hs_irq_demux(irq=%d)\n", irq); @@ -671,12 +671,13 @@ static int hs_irq_demux(int irq, void *dev) * Interrupt handling routine. */ -static irqreturn_t hs_interrupt(int irq, void *dev) +static irqreturn_t hs_interrupt(int irq, void *dev, struct pt_regs *regs) { - hs_socket_t *sp = dev; + hs_socket_t *sp = (hs_socket_t *)dev; u_int events = 0; u_int cscr; - + + cscr = hs_in(sp, CSCR); DPRINTK("hs_interrupt, cscr=%04x\n", cscr); diff --git a/trunk/drivers/pcmcia/i82092.c b/trunk/drivers/pcmcia/i82092.c index c2ea07aa7a12..2163aa75a257 100644 --- a/trunk/drivers/pcmcia/i82092.c +++ b/trunk/drivers/pcmcia/i82092.c @@ -41,7 +41,6 @@ static struct pci_device_id i82092aa_pci_ids[] = { }; MODULE_DEVICE_TABLE(pci, i82092aa_pci_ids); -#ifdef CONFIG_PM static int i82092aa_socket_suspend (struct pci_dev *dev, pm_message_t state) { return pcmcia_socket_dev_suspend(&dev->dev, state); @@ -51,17 +50,14 @@ static int i82092aa_socket_resume (struct pci_dev *dev) { return pcmcia_socket_dev_resume(&dev->dev); } -#endif static struct pci_driver i82092aa_pci_drv = { .name = "i82092aa", .id_table = i82092aa_pci_ids, .probe = i82092aa_pci_probe, .remove = __devexit_p(i82092aa_pci_remove), -#ifdef CONFIG_PM .suspend = i82092aa_socket_suspend, .resume = i82092aa_socket_resume, -#endif }; @@ -319,7 +315,7 @@ static int to_cycles(int ns) /* Interrupt handler functionality */ -static irqreturn_t i82092aa_interrupt(int irq, void *dev) +static irqreturn_t i82092aa_interrupt(int irq, void *dev, struct pt_regs *regs) { int i; int loopcount = 0; @@ -709,7 +705,10 @@ static int i82092aa_set_mem_map(struct pcmcia_socket *socket, struct pccard_mem_ static int i82092aa_module_init(void) { - return pci_register_driver(&i82092aa_pci_drv); + enter("i82092aa_module_init"); + pci_register_driver(&i82092aa_pci_drv); + leave("i82092aa_module_init"); + return 0; } static void i82092aa_module_exit(void) diff --git a/trunk/drivers/pcmcia/i82092aa.h b/trunk/drivers/pcmcia/i82092aa.h index b0d453303c5d..9c14599d0673 100644 --- a/trunk/drivers/pcmcia/i82092aa.h +++ b/trunk/drivers/pcmcia/i82092aa.h @@ -23,7 +23,7 @@ static int i82092aa_pci_probe(struct pci_dev *dev, const struct pci_device_id *id); static void i82092aa_pci_remove(struct pci_dev *dev); static int card_present(int socketno); -static irqreturn_t i82092aa_interrupt(int irq, void *dev); +static irqreturn_t i82092aa_interrupt(int irq, void *dev, struct pt_regs *regs); diff --git a/trunk/drivers/pcmcia/i82365.c b/trunk/drivers/pcmcia/i82365.c index ea74f98a7350..1cc2682394b1 100644 --- a/trunk/drivers/pcmcia/i82365.c +++ b/trunk/drivers/pcmcia/i82365.c @@ -80,7 +80,7 @@ module_param(pc_debug, int, 0644); #define debug(lvl, fmt, arg...) do { } while (0) #endif -static irqreturn_t i365_count_irq(int, void *); +static irqreturn_t i365_count_irq(int, void *, struct pt_regs *); static inline int _check_irq(int irq, int flags) { if (request_irq(irq, i365_count_irq, flags, "x", i365_count_irq) != 0) @@ -498,7 +498,7 @@ static u_int __init set_bridge_opts(u_short s, u_short ns) static volatile u_int irq_hits; static u_short irq_sock; -static irqreturn_t i365_count_irq(int irq, void *dev) +static irqreturn_t i365_count_irq(int irq, void *dev, struct pt_regs *regs) { i365_get(irq_sock, I365_CSC); irq_hits++; @@ -848,7 +848,8 @@ static void __init isa_probe(void) /*====================================================================*/ -static irqreturn_t pcic_interrupt(int irq, void *dev) +static irqreturn_t pcic_interrupt(int irq, void *dev, + struct pt_regs *regs) { int i, j, csc; u_int events, active; @@ -897,7 +898,7 @@ static irqreturn_t pcic_interrupt(int irq, void *dev) static void pcic_interrupt_wrapper(u_long data) { - pcic_interrupt(0, NULL); + pcic_interrupt(0, NULL, NULL); poll_timer.expires = jiffies + poll_interval; add_timer(&poll_timer); } diff --git a/trunk/drivers/pcmcia/m32r_cfc.c b/trunk/drivers/pcmcia/m32r_cfc.c index 36fdaa58458c..9e768eaef17a 100644 --- a/trunk/drivers/pcmcia/m32r_cfc.c +++ b/trunk/drivers/pcmcia/m32r_cfc.c @@ -254,7 +254,7 @@ static pcc_t pcc[] = { #endif /* CONFIG_PLAT_USRV */ }; -static irqreturn_t pcc_interrupt(int, void *); +static irqreturn_t pcc_interrupt(int, void *, struct pt_regs *); /*====================================================================*/ @@ -372,13 +372,14 @@ static void add_pcc_socket(ulong base, int irq, ulong mapaddr, kio_addr_t ioaddr /*====================================================================*/ -static irqreturn_t pcc_interrupt(int irq, void *dev) +static irqreturn_t pcc_interrupt(int irq, void *dev, struct pt_regs *regs) { int i; u_int events = 0; int handled = 0; - debug(3, "m32r_cfc: pcc_interrupt: irq=%d, dev=%p\n", irq, dev); + debug(3, "m32r_cfc: pcc_interrupt: irq=%d, dev=%p, regs=%p\n", + irq, dev, regs); for (i = 0; i < pcc_sockets; i++) { if (socket[i].cs_irq1 != irq && socket[i].cs_irq2 != irq) continue; diff --git a/trunk/drivers/pcmcia/m32r_pcc.c b/trunk/drivers/pcmcia/m32r_pcc.c index bbf025874d0c..61d50b5620dd 100644 --- a/trunk/drivers/pcmcia/m32r_pcc.c +++ b/trunk/drivers/pcmcia/m32r_pcc.c @@ -267,7 +267,7 @@ static pcc_t pcc[] = { { "xnux2", 0 }, { "xnux2", 0 }, }; -static irqreturn_t pcc_interrupt(int, void *); +static irqreturn_t pcc_interrupt(int, void *, struct pt_regs *); /*====================================================================*/ @@ -352,7 +352,7 @@ static void add_pcc_socket(ulong base, int irq, ulong mapaddr, kio_addr_t ioaddr /*====================================================================*/ -static irqreturn_t pcc_interrupt(int irq, void *dev) +static irqreturn_t pcc_interrupt(int irq, void *dev, struct pt_regs *regs) { int i, j, irc; u_int events, active; @@ -395,7 +395,7 @@ static irqreturn_t pcc_interrupt(int irq, void *dev) static void pcc_interrupt_wrapper(u_long data) { - pcc_interrupt(0, NULL); + pcc_interrupt(0, NULL, NULL); init_timer(&poll_timer); poll_timer.expires = jiffies + poll_interval; add_timer(&poll_timer); diff --git a/trunk/drivers/pcmcia/m8xx_pcmcia.c b/trunk/drivers/pcmcia/m8xx_pcmcia.c index 3b72be880401..d0f68ab8f041 100644 --- a/trunk/drivers/pcmcia/m8xx_pcmcia.c +++ b/trunk/drivers/pcmcia/m8xx_pcmcia.c @@ -266,7 +266,7 @@ static const u32 m8xx_size_to_gray[M8XX_SIZES_NO] = /* ------------------------------------------------------------------------- */ -static irqreturn_t m8xx_interrupt(int irq, void *dev); +static irqreturn_t m8xx_interrupt(int irq, void *dev, struct pt_regs *regs); #define PCMCIA_BMT_LIMIT (15*4) /* Bus Monitor Timeout value */ @@ -427,7 +427,7 @@ static int voltage_set(int slot, int vcc, int vpp) reg |= BCSR1_PCCVCC1; break; default: - goto out_unmap; + return 1; } switch(vpp) { @@ -438,15 +438,15 @@ static int voltage_set(int slot, int vcc, int vpp) if(vcc == vpp) reg |= BCSR1_PCCVPP1; else - goto out_unmap; + return 1; break; case 120: if ((vcc == 33) || (vcc == 50)) reg |= BCSR1_PCCVPP0; else - goto out_unmap; + return 1; default: - goto out_unmap; + return 1; } /* first, turn off all power */ @@ -457,10 +457,6 @@ static int voltage_set(int slot, int vcc, int vpp) iounmap(bcsr_io); return 0; - -out_unmap: - iounmap(bcsr_io); - return 1; } #define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V @@ -650,7 +646,7 @@ static struct platform_device m8xx_device = { static u32 pending_events[PCMCIA_SOCKETS_NO]; static DEFINE_SPINLOCK(pending_event_lock); -static irqreturn_t m8xx_interrupt(int irq, void *dev) +static irqreturn_t m8xx_interrupt(int irq, void *dev, struct pt_regs *regs) { struct socket_info *s; struct event_table *e; diff --git a/trunk/drivers/pcmcia/omap_cf.c b/trunk/drivers/pcmcia/omap_cf.c index 06bf7f48836e..01be47e72730 100644 --- a/trunk/drivers/pcmcia/omap_cf.c +++ b/trunk/drivers/pcmcia/omap_cf.c @@ -102,7 +102,7 @@ static void omap_cf_timer(unsigned long _cf) * claim the card's IRQ. It may also detect some card insertions, but * not removals; it can't always eliminate timer irqs. */ -static irqreturn_t omap_cf_irq(int irq, void *_cf) +static irqreturn_t omap_cf_irq(int irq, void *_cf, struct pt_regs *r) { omap_cf_timer((unsigned long)_cf); return IRQ_HANDLED; @@ -309,10 +309,9 @@ static int __devinit omap_cf_probe(struct device *dev) return 0; fail2: + iounmap((void __iomem *) cf->socket.io_offset); release_mem_region(cf->phys_cf, SZ_8K); fail1: - if (cf->socket.io_offset) - iounmap((void __iomem *) cf->socket.io_offset); free_irq(irq, cf); fail0: kfree(cf); diff --git a/trunk/drivers/pcmcia/pcmcia_ioctl.c b/trunk/drivers/pcmcia/pcmcia_ioctl.c index 310ede575caa..9ad18e62658d 100644 --- a/trunk/drivers/pcmcia/pcmcia_ioctl.c +++ b/trunk/drivers/pcmcia/pcmcia_ioctl.c @@ -128,12 +128,9 @@ static int proc_read_drivers(char *buf, char **start, off_t pos, int count, int *eof, void *data) { char *p = buf; - int rc; - rc = bus_for_each_drv(&pcmcia_bus_type, NULL, - (void *) &p, proc_read_drivers_callback); - if (rc < 0) - return rc; + bus_for_each_drv(&pcmcia_bus_type, NULL, + (void *) &p, proc_read_drivers_callback); return (p - buf); } @@ -272,10 +269,8 @@ static int bind_request(struct pcmcia_socket *s, bind_info_t *bind_info) * Prevent this racing with a card insertion. */ mutex_lock(&s->skt_mutex); - ret = bus_rescan_devices(&pcmcia_bus_type); + bus_rescan_devices(&pcmcia_bus_type); mutex_unlock(&s->skt_mutex); - if (ret) - goto err_put_module; /* check whether the driver indeed matched. I don't care if this * is racy or not, because it can only happen on cardmgr access diff --git a/trunk/drivers/pcmcia/pcmcia_resource.c b/trunk/drivers/pcmcia/pcmcia_resource.c index b9201c2ec38b..c8323399e9e4 100644 --- a/trunk/drivers/pcmcia/pcmcia_resource.c +++ b/trunk/drivers/pcmcia/pcmcia_resource.c @@ -95,7 +95,7 @@ static int alloc_io_space(struct pcmcia_socket *s, u_int attr, ioaddr_t *base, * potential conflicts, just the most obvious ones. */ for (i = 0; i < MAX_IO_WIN; i++) - if ((s->io[i].res) && *base && + if ((s->io[i].res) && ((s->io[i].res->start & (align-1)) == *base)) return 1; for (i = 0; i < MAX_IO_WIN; i++) { @@ -784,7 +784,7 @@ EXPORT_SYMBOL(pcmcia_request_io); */ #ifdef CONFIG_PCMCIA_PROBE -static irqreturn_t test_action(int cpl, void *dev_id) +static irqreturn_t test_action(int cpl, void *dev_id, struct pt_regs *regs) { return IRQ_NONE; } diff --git a/trunk/drivers/pcmcia/pd6729.c b/trunk/drivers/pcmcia/pd6729.c index a70f97fdbbdd..22c5e7427ddd 100644 --- a/trunk/drivers/pcmcia/pd6729.c +++ b/trunk/drivers/pcmcia/pd6729.c @@ -182,7 +182,7 @@ static void indirect_write16(struct pd6729_socket *socket, unsigned short reg, /* Interrupt handler functionality */ -static irqreturn_t pd6729_interrupt(int irq, void *dev) +static irqreturn_t pd6729_interrupt(int irq, void *dev, struct pt_regs *regs) { struct pd6729_socket *socket = (struct pd6729_socket *)dev; int i; @@ -249,7 +249,7 @@ static void pd6729_interrupt_wrapper(unsigned long data) { struct pd6729_socket *socket = (struct pd6729_socket *) data; - pd6729_interrupt(0, (void *)socket); + pd6729_interrupt(0, (void *)socket, NULL); mod_timer(&socket->poll_timer, jiffies + HZ); } @@ -575,7 +575,7 @@ static struct pccard_operations pd6729_operations = { .set_mem_map = pd6729_set_mem_map, }; -static irqreturn_t pd6729_test(int irq, void *dev) +static irqreturn_t pd6729_test(int irq, void *dev, struct pt_regs *regs) { dprintk("-> hit on irq %d\n", irq); return IRQ_HANDLED; @@ -755,7 +755,6 @@ static void __devexit pd6729_pci_remove(struct pci_dev *dev) kfree(socket); } -#ifdef CONFIG_PM static int pd6729_socket_suspend(struct pci_dev *dev, pm_message_t state) { return pcmcia_socket_dev_suspend(&dev->dev, state); @@ -765,7 +764,6 @@ static int pd6729_socket_resume(struct pci_dev *dev) { return pcmcia_socket_dev_resume(&dev->dev); } -#endif static struct pci_device_id pd6729_pci_ids[] = { { @@ -783,10 +781,8 @@ static struct pci_driver pd6729_pci_drv = { .id_table = pd6729_pci_ids, .probe = pd6729_pci_probe, .remove = __devexit_p(pd6729_pci_remove), -#ifdef CONFIG_PM .suspend = pd6729_socket_suspend, .resume = pd6729_socket_resume, -#endif }; static int pd6729_module_init(void) diff --git a/trunk/drivers/pcmcia/pxa2xx_base.c b/trunk/drivers/pcmcia/pxa2xx_base.c index dca9f8549b32..b3518131ea0d 100644 --- a/trunk/drivers/pcmcia/pxa2xx_base.c +++ b/trunk/drivers/pcmcia/pxa2xx_base.c @@ -166,7 +166,7 @@ pxa2xx_pcmcia_frequency_change(struct soc_pcmcia_socket *skt, } #endif -int __pxa2xx_drv_pcmcia_probe(struct device *dev) +int pxa2xx_drv_pcmcia_probe(struct device *dev) { int ret; struct pcmcia_low_level *ops; @@ -203,52 +203,35 @@ int __pxa2xx_drv_pcmcia_probe(struct device *dev) return ret; } -EXPORT_SYMBOL(__pxa2xx_drv_pcmcia_probe); +EXPORT_SYMBOL(pxa2xx_drv_pcmcia_probe); - -static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev) -{ - return __pxa2xx_drv_pcmcia_probe(&dev->dev); -} - -static int pxa2xx_drv_pcmcia_remove(struct platform_device *dev) -{ - return soc_common_drv_pcmcia_remove(&dev->dev); -} - -static int pxa2xx_drv_pcmcia_suspend(struct platform_device *dev, pm_message_t state) -{ - return pcmcia_socket_dev_suspend(&dev->dev, state); -} - -static int pxa2xx_drv_pcmcia_resume(struct platform_device *dev) +static int pxa2xx_drv_pcmcia_resume(struct device *dev) { - struct pcmcia_low_level *ops = dev->dev.platform_data; + struct pcmcia_low_level *ops = dev->platform_data; int nr = ops ? ops->nr : 0; MECR = nr > 1 ? MECR_CIT | MECR_NOS : (nr > 0 ? MECR_CIT : 0); - return pcmcia_socket_dev_resume(&dev->dev); + return pcmcia_socket_dev_resume(dev); } -static struct platform_driver pxa2xx_pcmcia_driver = { +static struct device_driver pxa2xx_pcmcia_driver = { .probe = pxa2xx_drv_pcmcia_probe, - .remove = pxa2xx_drv_pcmcia_remove, - .suspend = pxa2xx_drv_pcmcia_suspend, + .remove = soc_common_drv_pcmcia_remove, + .suspend = pcmcia_socket_dev_suspend, .resume = pxa2xx_drv_pcmcia_resume, - .driver = { - .name = "pxa2xx-pcmcia", - }, + .name = "pxa2xx-pcmcia", + .bus = &platform_bus_type, }; static int __init pxa2xx_pcmcia_init(void) { - return platform_driver_register(&pxa2xx_pcmcia_driver); + return driver_register(&pxa2xx_pcmcia_driver); } static void __exit pxa2xx_pcmcia_exit(void) { - platform_driver_unregister(&pxa2xx_pcmcia_driver); + driver_unregister(&pxa2xx_pcmcia_driver); } fs_initcall(pxa2xx_pcmcia_init); diff --git a/trunk/drivers/pcmcia/pxa2xx_base.h b/trunk/drivers/pcmcia/pxa2xx_base.h index 235d681652c3..e46cff345d47 100644 --- a/trunk/drivers/pcmcia/pxa2xx_base.h +++ b/trunk/drivers/pcmcia/pxa2xx_base.h @@ -1,3 +1,3 @@ /* temporary measure */ -extern int __pxa2xx_drv_pcmcia_probe(struct device *); +extern int pxa2xx_drv_pcmcia_probe(struct device *); diff --git a/trunk/drivers/pcmcia/pxa2xx_lubbock.c b/trunk/drivers/pcmcia/pxa2xx_lubbock.c index a92f11143c43..fd1f691c7c2c 100644 --- a/trunk/drivers/pcmcia/pxa2xx_lubbock.c +++ b/trunk/drivers/pcmcia/pxa2xx_lubbock.c @@ -260,7 +260,7 @@ int __init pcmcia_lubbock_init(struct sa1111_dev *sadev) lubbock_set_misc_wr((1 << 15) | (1 << 14), 0); sadev->dev.platform_data = &lubbock_pcmcia_ops; - ret = __pxa2xx_drv_pcmcia_probe(&sadev->dev); + ret = pxa2xx_drv_pcmcia_probe(&sadev->dev); } return ret; diff --git a/trunk/drivers/pcmcia/soc_common.c b/trunk/drivers/pcmcia/soc_common.c index e433704e026a..ecaa132fa592 100644 --- a/trunk/drivers/pcmcia/soc_common.c +++ b/trunk/drivers/pcmcia/soc_common.c @@ -256,7 +256,7 @@ static void soc_common_pcmcia_poll_event(unsigned long dummy) * handling code performs scheduling operations which cannot be * executed from within an interrupt context. */ -static irqreturn_t soc_common_pcmcia_interrupt(int irq, void *dev) +static irqreturn_t soc_common_pcmcia_interrupt(int irq, void *dev, struct pt_regs *regs) { struct soc_pcmcia_socket *skt = dev; @@ -824,4 +824,3 @@ int soc_common_drv_pcmcia_remove(struct device *dev) return 0; } -EXPORT_SYMBOL(soc_common_drv_pcmcia_remove); diff --git a/trunk/drivers/pcmcia/tcic.c b/trunk/drivers/pcmcia/tcic.c index 2d2f415f80a8..65a60671659f 100644 --- a/trunk/drivers/pcmcia/tcic.c +++ b/trunk/drivers/pcmcia/tcic.c @@ -116,7 +116,7 @@ module_param(cycle_time, int, 0444); /*====================================================================*/ -static irqreturn_t tcic_interrupt(int irq, void *dev); +static irqreturn_t tcic_interrupt(int irq, void *dev, struct pt_regs *regs); static void tcic_timer(u_long data); static struct pccard_operations tcic_operations; @@ -218,7 +218,7 @@ static int to_cycles(int ns) static volatile u_int irq_hits; -static irqreturn_t __init tcic_irq_count(int irq, void *dev) +static irqreturn_t __init tcic_irq_count(int irq, void *dev, struct pt_regs *regs) { irq_hits++; return IRQ_HANDLED; @@ -505,7 +505,7 @@ static int __init init_tcic(void) } /* jump start interrupt handler, if needed */ - tcic_interrupt(0, NULL); + tcic_interrupt(0, NULL, NULL); platform_device_register(&tcic_device); @@ -547,7 +547,7 @@ static void __exit exit_tcic(void) /*====================================================================*/ -static irqreturn_t tcic_interrupt(int irq, void *dev) +static irqreturn_t tcic_interrupt(int irq, void *dev, struct pt_regs *regs) { int i, quick = 0; u_char latch, sstat; @@ -606,7 +606,7 @@ static void tcic_timer(u_long data) { debug(2, "tcic_timer()\n"); tcic_timer_pending = 0; - tcic_interrupt(0, NULL); + tcic_interrupt(0, NULL, NULL); } /* tcic_timer */ /*====================================================================*/ diff --git a/trunk/drivers/pcmcia/vrc4171_card.c b/trunk/drivers/pcmcia/vrc4171_card.c index e90d8e8c5fd6..e076a13db555 100644 --- a/trunk/drivers/pcmcia/vrc4171_card.c +++ b/trunk/drivers/pcmcia/vrc4171_card.c @@ -514,7 +514,7 @@ static inline unsigned int get_events(int slot) return events; } -static irqreturn_t pccard_interrupt(int irq, void *dev_id) +static irqreturn_t pccard_interrupt(int irq, void *dev_id, struct pt_regs *regs) { vrc4171_socket_t *socket; unsigned int events; diff --git a/trunk/drivers/pcmcia/vrc4173_cardu.c b/trunk/drivers/pcmcia/vrc4173_cardu.c index 812f038e9bda..d19a9138135f 100644 --- a/trunk/drivers/pcmcia/vrc4173_cardu.c +++ b/trunk/drivers/pcmcia/vrc4173_cardu.c @@ -440,7 +440,7 @@ static uint16_t get_events(vrc4173_socket_t *socket) return events; } -static void cardu_interrupt(int irq, void *dev_id) +static void cardu_interrupt(int irq, void *dev_id, struct pt_regs *regs) { vrc4173_socket_t *socket = (vrc4173_socket_t *)dev_id; uint16_t events; diff --git a/trunk/drivers/pcmcia/yenta_socket.c b/trunk/drivers/pcmcia/yenta_socket.c index da471bddc972..1344746381e8 100644 --- a/trunk/drivers/pcmcia/yenta_socket.c +++ b/trunk/drivers/pcmcia/yenta_socket.c @@ -442,7 +442,7 @@ static int yenta_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map * -static irqreturn_t yenta_interrupt(int irq, void *dev_id) +static irqreturn_t yenta_interrupt(int irq, void *dev_id, struct pt_regs *regs) { unsigned int events; struct yenta_socket *socket = (struct yenta_socket *) dev_id; @@ -478,7 +478,7 @@ static void yenta_interrupt_wrapper(unsigned long data) { struct yenta_socket *socket = (struct yenta_socket *) data; - yenta_interrupt(0, (void *)socket); + yenta_interrupt(0, (void *)socket, NULL); socket->poll_timer.expires = jiffies + HZ; add_timer(&socket->poll_timer); } @@ -896,7 +896,7 @@ static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mas #ifdef CONFIG_YENTA_TI /* interrupt handler, only used during probing */ -static irqreturn_t yenta_probe_handler(int irq, void *dev_id) +static irqreturn_t yenta_probe_handler(int irq, void *dev_id, struct pt_regs *regs) { struct yenta_socket *socket = (struct yenta_socket *) dev_id; u8 csc; @@ -1197,12 +1197,8 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i ret = pcmcia_register_socket(&socket->socket); if (ret == 0) { /* Add the yenta register attributes */ - ret = device_create_file(&dev->dev, &dev_attr_yenta_registers); - if (ret == 0) - goto out; - - /* error path... */ - pcmcia_unregister_socket(&socket->socket); + device_create_file(&dev->dev, &dev_attr_yenta_registers); + goto out; } unmap: @@ -1217,7 +1213,7 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i return ret; } -#ifdef CONFIG_PM + static int yenta_dev_suspend (struct pci_dev *dev, pm_message_t state) { struct yenta_socket *socket = pci_get_drvdata(dev); @@ -1252,18 +1248,12 @@ static int yenta_dev_resume (struct pci_dev *dev) struct yenta_socket *socket = pci_get_drvdata(dev); if (socket) { - int rc; - pci_set_power_state(dev, 0); /* FIXME: pci_restore_state needs to have a better interface */ pci_restore_state(dev); pci_write_config_dword(dev, 16*4, socket->saved_state[0]); pci_write_config_dword(dev, 17*4, socket->saved_state[1]); - - rc = pci_enable_device(dev); - if (rc) - return rc; - + pci_enable_device(dev); pci_set_master(dev); if (socket->type && socket->type->restore_state) @@ -1272,7 +1262,7 @@ static int yenta_dev_resume (struct pci_dev *dev) return pcmcia_socket_dev_resume(&dev->dev); } -#endif + #define CB_ID(vend,dev,type) \ { \ @@ -1369,10 +1359,8 @@ static struct pci_driver yenta_cardbus_driver = { .id_table = yenta_table, .probe = yenta_probe, .remove = __devexit_p(yenta_close), -#ifdef CONFIG_PM .suspend = yenta_dev_suspend, .resume = yenta_dev_resume, -#endif }; diff --git a/trunk/drivers/pnp/pnpacpi/rsparser.c b/trunk/drivers/pnp/pnpacpi/rsparser.c index 379048fdf05d..dc79b0a0059f 100644 --- a/trunk/drivers/pnp/pnpacpi/rsparser.c +++ b/trunk/drivers/pnp/pnpacpi/rsparser.c @@ -776,32 +776,21 @@ static void pnpacpi_encode_dma(struct acpi_resource *resource, struct resource *p) { /* Note: pnp_assign_dma will copy pnp_dma->flags into p->flags */ - switch (p->flags & IORESOURCE_DMA_SPEED_MASK) { - case IORESOURCE_DMA_TYPEA: - resource->data.dma.type = ACPI_TYPE_A; - break; - case IORESOURCE_DMA_TYPEB: - resource->data.dma.type = ACPI_TYPE_B; - break; - case IORESOURCE_DMA_TYPEF: - resource->data.dma.type = ACPI_TYPE_F; - break; - default: - resource->data.dma.type = ACPI_COMPATIBILITY; - } - - switch (p->flags & IORESOURCE_DMA_TYPE_MASK) { - case IORESOURCE_DMA_8BIT: - resource->data.dma.transfer = ACPI_TRANSFER_8; - break; - case IORESOURCE_DMA_8AND16BIT: - resource->data.dma.transfer = ACPI_TRANSFER_8_16; - break; - default: - resource->data.dma.transfer = ACPI_TRANSFER_16; - } - - resource->data.dma.bus_master = !!(p->flags & IORESOURCE_DMA_MASTER); + if (p->flags & IORESOURCE_DMA_COMPATIBLE) + resource->data.dma.type = ACPI_COMPATIBILITY; + else if (p->flags & IORESOURCE_DMA_TYPEA) + resource->data.dma.type = ACPI_TYPE_A; + else if (p->flags & IORESOURCE_DMA_TYPEB) + resource->data.dma.type = ACPI_TYPE_B; + else if (p->flags & IORESOURCE_DMA_TYPEF) + resource->data.dma.type = ACPI_TYPE_F; + if (p->flags & IORESOURCE_DMA_8BIT) + resource->data.dma.transfer = ACPI_TRANSFER_8; + else if (p->flags & IORESOURCE_DMA_8AND16BIT) + resource->data.dma.transfer = ACPI_TRANSFER_8_16; + else if (p->flags & IORESOURCE_DMA_16BIT) + resource->data.dma.transfer = ACPI_TRANSFER_16; + resource->data.dma.bus_master = p->flags & IORESOURCE_DMA_MASTER; resource->data.dma.channel_count = 1; resource->data.dma.channels[0] = p->start; } diff --git a/trunk/drivers/pnp/resource.c b/trunk/drivers/pnp/resource.c index a685fbec4604..5c8ec21e1086 100644 --- a/trunk/drivers/pnp/resource.c +++ b/trunk/drivers/pnp/resource.c @@ -348,7 +348,7 @@ int pnp_check_mem(struct pnp_dev * dev, int idx) return 1; } -static irqreturn_t pnp_test_handler(int irq, void *dev_id) +static irqreturn_t pnp_test_handler(int irq, void *dev_id, struct pt_regs *regs) { return IRQ_HANDLED; } diff --git a/trunk/drivers/rtc/interface.c b/trunk/drivers/rtc/interface.c index 6f11f6dfdd9d..579cd667b16f 100644 --- a/trunk/drivers/rtc/interface.c +++ b/trunk/drivers/rtc/interface.c @@ -145,13 +145,6 @@ int rtc_set_alarm(struct class_device *class_dev, struct rtc_wkalrm *alarm) } EXPORT_SYMBOL_GPL(rtc_set_alarm); -/** - * rtc_update_irq - report RTC periodic, alarm, and/or update irqs - * @class_dev: the rtc's class device - * @num: how many irqs are being reported (usually one) - * @events: mask of RTC_IRQF with one or more of RTC_PF, RTC_AF, RTC_UF - * Context: in_interrupt(), irqs blocked - */ void rtc_update_irq(struct class_device *class_dev, unsigned long num, unsigned long events) { @@ -208,12 +201,12 @@ int rtc_irq_register(struct class_device *class_dev, struct rtc_task *task) if (task == NULL || task->func == NULL) return -EINVAL; - spin_lock_irq(&rtc->irq_task_lock); + spin_lock(&rtc->irq_task_lock); if (rtc->irq_task == NULL) { rtc->irq_task = task; retval = 0; } - spin_unlock_irq(&rtc->irq_task_lock); + spin_unlock(&rtc->irq_task_lock); return retval; } @@ -223,10 +216,10 @@ void rtc_irq_unregister(struct class_device *class_dev, struct rtc_task *task) { struct rtc_device *rtc = to_rtc_device(class_dev); - spin_lock_irq(&rtc->irq_task_lock); + spin_lock(&rtc->irq_task_lock); if (rtc->irq_task == task) rtc->irq_task = NULL; - spin_unlock_irq(&rtc->irq_task_lock); + spin_unlock(&rtc->irq_task_lock); } EXPORT_SYMBOL_GPL(rtc_irq_unregister); @@ -272,4 +265,3 @@ int rtc_irq_set_freq(struct class_device *class_dev, struct rtc_task *task, int } return err; } -EXPORT_SYMBOL_GPL(rtc_irq_set_freq); diff --git a/trunk/drivers/rtc/rtc-at91.c b/trunk/drivers/rtc/rtc-at91.c index 5c8addcaf1fb..c0714da44920 100644 --- a/trunk/drivers/rtc/rtc-at91.c +++ b/trunk/drivers/rtc/rtc-at91.c @@ -238,7 +238,8 @@ static int at91_rtc_proc(struct device *dev, struct seq_file *seq) /* * IRQ handler for the RTC */ -static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id) +static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { struct platform_device *pdev = dev_id; struct rtc_device *rtc = platform_get_drvdata(pdev); @@ -292,8 +293,7 @@ static int __init at91_rtc_probe(struct platform_device *pdev) AT91_RTC_CALEV); ret = request_irq(AT91_ID_SYS, at91_rtc_interrupt, - IRQF_DISABLED | IRQF_SHARED, - "at91_rtc", pdev); + IRQF_SHARED, "at91_rtc", pdev); if (ret) { printk(KERN_ERR "at91_rtc: IRQ %d already in use.\n", AT91_ID_SYS); diff --git a/trunk/drivers/rtc/rtc-dev.c b/trunk/drivers/rtc/rtc-dev.c index 814b9e1873f5..583789c66cdb 100644 --- a/trunk/drivers/rtc/rtc-dev.c +++ b/trunk/drivers/rtc/rtc-dev.c @@ -61,9 +61,7 @@ static void rtc_uie_task(void *data) int err; err = rtc_read_time(&rtc->class_dev, &tm); - - local_irq_disable(); - spin_lock(&rtc->irq_lock); + spin_lock_irq(&rtc->irq_lock); if (rtc->stop_uie_polling || err) { rtc->uie_task_active = 0; } else if (rtc->oldsecs != tm.tm_sec) { @@ -76,11 +74,11 @@ static void rtc_uie_task(void *data) } else if (schedule_work(&rtc->uie_task) == 0) { rtc->uie_task_active = 0; } - spin_unlock(&rtc->irq_lock); + spin_unlock_irq(&rtc->irq_lock); if (num) rtc_update_irq(&rtc->class_dev, num, RTC_UF | RTC_IRQF); - local_irq_enable(); } + static void rtc_uie_timer(unsigned long data) { struct rtc_device *rtc = (struct rtc_device *)data; @@ -216,7 +214,7 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, struct rtc_wkalrm alarm; void __user *uarg = (void __user *) arg; - /* check that the calling task has appropriate permissions + /* check that the calles has appropriate permissions * for certain ioctls. doing this check here is useful * to avoid duplicate code in each driver. */ @@ -240,10 +238,10 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, /* avoid conflicting IRQ users */ if (cmd == RTC_PIE_ON || cmd == RTC_PIE_OFF || cmd == RTC_IRQP_SET) { - spin_lock_irq(&rtc->irq_task_lock); + spin_lock(&rtc->irq_task_lock); if (rtc->irq_task) err = -EBUSY; - spin_unlock_irq(&rtc->irq_task_lock); + spin_unlock(&rtc->irq_task_lock); if (err < 0) return err; @@ -301,17 +299,6 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, err = rtc_set_time(class_dev, &tm); break; - - case RTC_IRQP_READ: - if (ops->irq_set_freq) - err = put_user(rtc->irq_freq, (unsigned long *) arg); - break; - - case RTC_IRQP_SET: - if (ops->irq_set_freq) - err = rtc_irq_set_freq(class_dev, rtc->irq_task, arg); - break; - #if 0 case RTC_EPOCH_SET: #ifndef rtc_epoch diff --git a/trunk/drivers/rtc/rtc-ds1553.c b/trunk/drivers/rtc/rtc-ds1553.c index 001eb1123a65..9647188fee2c 100644 --- a/trunk/drivers/rtc/rtc-ds1553.c +++ b/trunk/drivers/rtc/rtc-ds1553.c @@ -189,7 +189,8 @@ static int ds1553_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) return 0; } -static irqreturn_t ds1553_rtc_interrupt(int irq, void *dev_id) +static irqreturn_t ds1553_rtc_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { struct platform_device *pdev = dev_id; struct rtc_plat_data *pdata = platform_get_drvdata(pdev); @@ -340,8 +341,7 @@ static int __init ds1553_rtc_probe(struct platform_device *pdev) if (pdata->irq >= 0) { writeb(0, ioaddr + RTC_INTERRUPTS); - if (request_irq(pdata->irq, ds1553_rtc_interrupt, - IRQF_DISABLED | IRQF_SHARED, + if (request_irq(pdata->irq, ds1553_rtc_interrupt, IRQF_SHARED, pdev->name, pdev) < 0) { dev_warn(&pdev->dev, "interrupt not available.\n"); pdata->irq = -1; diff --git a/trunk/drivers/rtc/rtc-max6902.c b/trunk/drivers/rtc/rtc-max6902.c index d94170728075..0b20dfacbf59 100644 --- a/trunk/drivers/rtc/rtc-max6902.c +++ b/trunk/drivers/rtc/rtc-max6902.c @@ -136,7 +136,7 @@ static int max6902_get_datetime(struct device *dev, struct rtc_time *dt) dt->tm_min = BCD2BIN(chip->buf[2]); dt->tm_hour = BCD2BIN(chip->buf[3]); dt->tm_mday = BCD2BIN(chip->buf[4]); - dt->tm_mon = BCD2BIN(chip->buf[5]) - 1; + dt->tm_mon = BCD2BIN(chip->buf[5] - 1); dt->tm_wday = BCD2BIN(chip->buf[6]); dt->tm_year = BCD2BIN(chip->buf[7]); diff --git a/trunk/drivers/rtc/rtc-pl031.c b/trunk/drivers/rtc/rtc-pl031.c index f13daa9fecaa..739d1a6e14eb 100644 --- a/trunk/drivers/rtc/rtc-pl031.c +++ b/trunk/drivers/rtc/rtc-pl031.c @@ -47,7 +47,7 @@ struct pl031_local { void __iomem *base; }; -static irqreturn_t pl031_interrupt(int irq, void *dev_id) +static irqreturn_t pl031_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct rtc_device *rtc = dev_id; diff --git a/trunk/drivers/rtc/rtc-rs5c372.c b/trunk/drivers/rtc/rtc-rs5c372.c index a44fe4efa216..2a86632580f1 100644 --- a/trunk/drivers/rtc/rtc-rs5c372.c +++ b/trunk/drivers/rtc/rtc-rs5c372.c @@ -126,13 +126,13 @@ static int rs5c372_get_trim(struct i2c_client *client, int *osc, int *trim) return -EIO; } + dev_dbg(&client->dev, "%s: raw trim=%x\n", __FUNCTION__, *trim); + if (osc) *osc = (buf & RS5C372_TRIM_XSL) ? 32000 : 32768; - if (trim) { + if (trim) *trim = buf & RS5C372_TRIM_MASK; - dev_dbg(&client->dev, "%s: raw trim=%x\n", __FUNCTION__, *trim); - } return 0; } diff --git a/trunk/drivers/rtc/rtc-s3c.c b/trunk/drivers/rtc/rtc-s3c.c index e301dea57bb3..625dad2eeb4f 100644 --- a/trunk/drivers/rtc/rtc-s3c.c +++ b/trunk/drivers/rtc/rtc-s3c.c @@ -46,7 +46,7 @@ static unsigned int tick_count; /* IRQ Handlers */ -static irqreturn_t s3c_rtc_alarmirq(int irq, void *id) +static irqreturn_t s3c_rtc_alarmirq(int irq, void *id, struct pt_regs *r) { struct rtc_device *rdev = id; @@ -54,7 +54,7 @@ static irqreturn_t s3c_rtc_alarmirq(int irq, void *id) return IRQ_HANDLED; } -static irqreturn_t s3c_rtc_tickirq(int irq, void *id) +static irqreturn_t s3c_rtc_tickirq(int irq, void *id, struct pt_regs *r) { struct rtc_device *rdev = id; diff --git a/trunk/drivers/rtc/rtc-sa1100.c b/trunk/drivers/rtc/rtc-sa1100.c index bd4d7d174ef4..439c41aea31c 100644 --- a/trunk/drivers/rtc/rtc-sa1100.c +++ b/trunk/drivers/rtc/rtc-sa1100.c @@ -68,7 +68,8 @@ static int rtc_update_alarm(struct rtc_time *alrm) return ret; } -static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id) +static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { struct platform_device *pdev = to_platform_device(dev_id); struct rtc_device *rtc = platform_get_drvdata(pdev); @@ -105,7 +106,8 @@ static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id) static int rtc_timer1_count; -static irqreturn_t timer1_interrupt(int irq, void *dev_id) +static irqreturn_t timer1_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { struct platform_device *pdev = to_platform_device(dev_id); struct rtc_device *rtc = platform_get_drvdata(pdev); diff --git a/trunk/drivers/rtc/rtc-sh.c b/trunk/drivers/rtc/rtc-sh.c index 143302a8e79c..d2ce0c8bb8f3 100644 --- a/trunk/drivers/rtc/rtc-sh.c +++ b/trunk/drivers/rtc/rtc-sh.c @@ -73,7 +73,7 @@ struct sh_rtc { spinlock_t lock; }; -static irqreturn_t sh_rtc_interrupt(int irq, void *id) +static irqreturn_t sh_rtc_interrupt(int irq, void *id, struct pt_regs *regs) { struct platform_device *pdev = id; struct sh_rtc *rtc = platform_get_drvdata(pdev); @@ -97,7 +97,7 @@ static irqreturn_t sh_rtc_interrupt(int irq, void *id) return IRQ_HANDLED; } -static irqreturn_t sh_rtc_periodic(int irq, void *id) +static irqreturn_t sh_rtc_periodic(int irq, void *id, struct pt_regs *regs) { struct sh_rtc *rtc = dev_get_drvdata(id); @@ -160,7 +160,7 @@ static int sh_rtc_open(struct device *dev) tmp |= RCR1_CIE; writeb(tmp, rtc->regbase + RCR1); - ret = request_irq(rtc->periodic_irq, sh_rtc_periodic, IRQF_DISABLED, + ret = request_irq(rtc->periodic_irq, sh_rtc_periodic, SA_INTERRUPT, "sh-rtc period", dev); if (unlikely(ret)) { dev_err(dev, "request period IRQ failed with %d, IRQ %d\n", @@ -168,7 +168,7 @@ static int sh_rtc_open(struct device *dev) return ret; } - ret = request_irq(rtc->carry_irq, sh_rtc_interrupt, IRQF_DISABLED, + ret = request_irq(rtc->carry_irq, sh_rtc_interrupt, SA_INTERRUPT, "sh-rtc carry", dev); if (unlikely(ret)) { dev_err(dev, "request carry IRQ failed with %d, IRQ %d\n", @@ -177,7 +177,7 @@ static int sh_rtc_open(struct device *dev) goto err_bad_carry; } - ret = request_irq(rtc->alarm_irq, sh_rtc_interrupt, IRQF_DISABLED, + ret = request_irq(rtc->alarm_irq, sh_rtc_interrupt, SA_INTERRUPT, "sh-rtc alarm", dev); if (unlikely(ret)) { dev_err(dev, "request alarm IRQ failed with %d, IRQ %d\n", diff --git a/trunk/drivers/rtc/rtc-test.c b/trunk/drivers/rtc/rtc-test.c index 6ef9c62d5032..bc4bd24508a2 100644 --- a/trunk/drivers/rtc/rtc-test.c +++ b/trunk/drivers/rtc/rtc-test.c @@ -99,7 +99,6 @@ static ssize_t test_irq_store(struct device *dev, struct rtc_device *rtc = platform_get_drvdata(plat_dev); retval = count; - local_irq_disable(); if (strncmp(buf, "tick", 4) == 0) rtc_update_irq(&rtc->class_dev, 1, RTC_PF | RTC_IRQF); else if (strncmp(buf, "alarm", 5) == 0) @@ -108,7 +107,6 @@ static ssize_t test_irq_store(struct device *dev, rtc_update_irq(&rtc->class_dev, 1, RTC_UF | RTC_IRQF); else retval = -EINVAL; - local_irq_enable(); return retval; } diff --git a/trunk/drivers/rtc/rtc-v3020.c b/trunk/drivers/rtc/rtc-v3020.c index 3b58d3d5d38a..09b714f1cdc3 100644 --- a/trunk/drivers/rtc/rtc-v3020.c +++ b/trunk/drivers/rtc/rtc-v3020.c @@ -195,9 +195,9 @@ static int rtc_probe(struct platform_device *pdev) * are all disabled */ v3020_set_reg(chip, V3020_STATUS_0, 0x0); - dev_info(&pdev->dev, "Chip available at physical address 0x%llx," + dev_info(&pdev->dev, "Chip available at physical address 0x%p," "data connected to D%d\n", - (unsigned long long)pdev->resource[0].start, + (void*)pdev->resource[0].start, chip->leftshift); platform_set_drvdata(pdev, chip); diff --git a/trunk/drivers/rtc/rtc-vr41xx.c b/trunk/drivers/rtc/rtc-vr41xx.c index e40322b71938..58e5ed0aa127 100644 --- a/trunk/drivers/rtc/rtc-vr41xx.c +++ b/trunk/drivers/rtc/rtc-vr41xx.c @@ -268,7 +268,7 @@ static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long return 0; } -static irqreturn_t elapsedtime_interrupt(int irq, void *dev_id) +static irqreturn_t elapsedtime_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct platform_device *pdev = (struct platform_device *)dev_id; struct rtc_device *rtc = platform_get_drvdata(pdev); @@ -280,7 +280,7 @@ static irqreturn_t elapsedtime_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -static irqreturn_t rtclong1_interrupt(int irq, void *dev_id) +static irqreturn_t rtclong1_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct platform_device *pdev = (struct platform_device *)dev_id; struct rtc_device *rtc = platform_get_drvdata(pdev); diff --git a/trunk/drivers/s390/block/dasd.c b/trunk/drivers/s390/block/dasd.c index 79ffef6bfaf8..d0647d116eaa 100644 --- a/trunk/drivers/s390/block/dasd.c +++ b/trunk/drivers/s390/block/dasd.c @@ -203,7 +203,6 @@ dasd_state_basic_to_known(struct dasd_device * device) rc = dasd_flush_ccw_queue(device, 1); if (rc) return rc; - dasd_clear_timer(device); DBF_DEV_EVENT(DBF_EMERG, device, "%p debug area deleted", device); if (device->debug_area != NULL) { diff --git a/trunk/drivers/s390/block/dasd_diag.c b/trunk/drivers/s390/block/dasd_diag.c index 53db58a68617..222a8a71a5e8 100644 --- a/trunk/drivers/s390/block/dasd_diag.c +++ b/trunk/drivers/s390/block/dasd_diag.c @@ -218,7 +218,7 @@ dasd_diag_term_IO(struct dasd_ccw_req * cqr) /* Handle external interruption. */ static void -dasd_ext_handler(__u16 code) +dasd_ext_handler(struct pt_regs *regs, __u16 code) { struct dasd_ccw_req *cqr, *next; struct dasd_device *device; diff --git a/trunk/drivers/s390/char/ctrlchar.c b/trunk/drivers/s390/char/ctrlchar.c index 49e9628d9297..d83eb6358bac 100644 --- a/trunk/drivers/s390/char/ctrlchar.c +++ b/trunk/drivers/s390/char/ctrlchar.c @@ -20,7 +20,7 @@ static int ctrlchar_sysrq_key; static void ctrlchar_handle_sysrq(void *tty) { - handle_sysrq(ctrlchar_sysrq_key, (struct tty_struct *) tty); + handle_sysrq(ctrlchar_sysrq_key, NULL, (struct tty_struct *) tty); } static DECLARE_WORK(ctrlchar_work, ctrlchar_handle_sysrq, NULL); diff --git a/trunk/drivers/s390/char/keyboard.c b/trunk/drivers/s390/char/keyboard.c index e3491a5f5219..3be06569180d 100644 --- a/trunk/drivers/s390/char/keyboard.c +++ b/trunk/drivers/s390/char/keyboard.c @@ -304,7 +304,7 @@ kbd_keycode(struct kbd_data *kbd, unsigned int keycode) if (kbd->sysrq) { if (kbd->sysrq == K(KT_LATIN, '-')) { kbd->sysrq = 0; - handle_sysrq(value, kbd->tty); + handle_sysrq(value, NULL, kbd->tty); return; } if (value == '-') { diff --git a/trunk/drivers/s390/char/monwriter.c b/trunk/drivers/s390/char/monwriter.c index b9b0fc3f812b..1e3939aeb8ab 100644 --- a/trunk/drivers/s390/char/monwriter.c +++ b/trunk/drivers/s390/char/monwriter.c @@ -26,7 +26,6 @@ #define MONWRITE_MAX_DATALEN 4024 static int mon_max_bufs = 255; -static int mon_buf_count; struct mon_buf { struct list_head list; @@ -41,6 +40,7 @@ struct mon_private { size_t hdr_to_read; size_t data_to_read; struct mon_buf *current_buf; + int mon_buf_count; }; /* @@ -73,15 +73,12 @@ static inline struct mon_buf *monwrite_find_hdr(struct mon_private *monpriv, struct mon_buf *entry, *next; list_for_each_entry_safe(entry, next, &monpriv->list, list) - if ((entry->hdr.mon_function == monhdr->mon_function || - monhdr->mon_function == MONWRITE_STOP_INTERVAL) && - entry->hdr.applid == monhdr->applid && + if (entry->hdr.applid == monhdr->applid && entry->hdr.record_num == monhdr->record_num && entry->hdr.version == monhdr->version && entry->hdr.release == monhdr->release && entry->hdr.mod_level == monhdr->mod_level) return entry; - return NULL; } @@ -95,27 +92,25 @@ static int monwrite_new_hdr(struct mon_private *monpriv) monhdr->mon_function > MONWRITE_START_CONFIG || monhdr->hdrlen != sizeof(struct monwrite_hdr)) return -EINVAL; - monbuf = NULL; - if (monhdr->mon_function != MONWRITE_GEN_EVENT) - monbuf = monwrite_find_hdr(monpriv, monhdr); + monbuf = monwrite_find_hdr(monpriv, monhdr); if (monbuf) { if (monhdr->mon_function == MONWRITE_STOP_INTERVAL) { monhdr->datalen = monbuf->hdr.datalen; rc = monwrite_diag(monhdr, monbuf->data, APPLDATA_STOP_REC); list_del(&monbuf->list); - mon_buf_count--; + monpriv->mon_buf_count--; kfree(monbuf->data); kfree(monbuf); monbuf = NULL; } - } else if (monhdr->mon_function != MONWRITE_STOP_INTERVAL) { - if (mon_buf_count >= mon_max_bufs) + } else { + if (monpriv->mon_buf_count >= mon_max_bufs) return -ENOSPC; monbuf = kzalloc(sizeof(struct mon_buf), GFP_KERNEL); if (!monbuf) return -ENOMEM; - monbuf->data = kzalloc(monhdr->datalen, + monbuf->data = kzalloc(monbuf->hdr.datalen, GFP_KERNEL | GFP_DMA); if (!monbuf->data) { kfree(monbuf); @@ -123,8 +118,7 @@ static int monwrite_new_hdr(struct mon_private *monpriv) } monbuf->hdr = *monhdr; list_add_tail(&monbuf->list, &monpriv->list); - if (monhdr->mon_function != MONWRITE_GEN_EVENT) - mon_buf_count++; + monpriv->mon_buf_count++; } monpriv->current_buf = monbuf; return 0; @@ -192,7 +186,7 @@ static int monwrite_close(struct inode *inode, struct file *filp) if (entry->hdr.mon_function != MONWRITE_GEN_EVENT) monwrite_diag(&entry->hdr, entry->data, APPLDATA_STOP_REC); - mon_buf_count--; + monpriv->mon_buf_count--; list_del(&entry->list); kfree(entry->data); kfree(entry); diff --git a/trunk/drivers/s390/char/sclp.c b/trunk/drivers/s390/char/sclp.c index 8a056df09d6b..31e335751d6d 100644 --- a/trunk/drivers/s390/char/sclp.c +++ b/trunk/drivers/s390/char/sclp.c @@ -324,7 +324,7 @@ __sclp_find_req(u32 sccb) * Prepare read event data request if necessary. Start processing of next * request on queue. */ static void -sclp_interrupt_handler(__u16 code) +sclp_interrupt_handler(struct pt_regs *regs, __u16 code) { struct sclp_req *req; u32 finished_sccb; @@ -743,7 +743,7 @@ EXPORT_SYMBOL(sclp_reactivate); /* Handler for external interruption used during initialization. Modify * request state to done. */ static void -sclp_check_handler(__u16 code) +sclp_check_handler(struct pt_regs *regs, __u16 code) { u32 finished_sccb; diff --git a/trunk/drivers/s390/cio/chsc.c b/trunk/drivers/s390/cio/chsc.c index 2d78f0f4a40f..3bb4e472d73d 100644 --- a/trunk/drivers/s390/cio/chsc.c +++ b/trunk/drivers/s390/cio/chsc.c @@ -200,13 +200,11 @@ css_get_ssd_info(struct subchannel *sch) spin_unlock_irq(&sch->lock); free_page((unsigned long)page); if (!ret) { - int j, chpid, mask; + int j, chpid; /* Allocate channel path structures, if needed. */ for (j = 0; j < 8; j++) { - mask = 0x80 >> j; chpid = sch->ssd_info.chpid[j]; - if ((sch->schib.pmcw.pim & mask) && - (get_chp_status(chpid) < 0)) + if (chpid && (get_chp_status(chpid) < 0)) new_channel_path(chpid); } } @@ -224,15 +222,13 @@ s390_subchannel_remove_chpid(struct device *dev, void *data) sch = to_subchannel(dev); chpid = data; - for (j = 0; j < 8; j++) { - mask = 0x80 >> j; - if ((sch->schib.pmcw.pim & mask) && - (sch->schib.pmcw.chpid[j] == chpid->id)) + for (j = 0; j < 8; j++) + if (sch->schib.pmcw.chpid[j] == chpid->id) break; - } if (j >= 8) return 0; + mask = 0x80 >> j; spin_lock_irq(&sch->lock); stsch(sch->schid, &schib); @@ -370,7 +366,7 @@ __s390_process_res_acc(struct subchannel_id schid, void *data) struct res_acc_data *res_data; struct subchannel *sch; - res_data = data; + res_data = (struct res_acc_data *)data; sch = get_subchannel_by_schid(schid); if (!sch) /* Check if a subchannel is newly available. */ @@ -444,7 +440,7 @@ __get_chpid_from_lir(void *data) u32 isinfo[28]; } *lir; - lir = data; + lir = (struct lir*) data; if (!(lir->iq&0x80)) /* NULL link incident record */ return -EINVAL; @@ -624,20 +620,18 @@ __chp_add_new_sch(struct subchannel_id schid) static int __chp_add(struct subchannel_id schid, void *data) { - int i, mask; + int i; struct channel_path *chp; struct subchannel *sch; - chp = data; + chp = (struct channel_path *)data; sch = get_subchannel_by_schid(schid); if (!sch) /* Check if the subchannel is now available. */ return __chp_add_new_sch(schid); spin_lock_irq(&sch->lock); - for (i=0; i<8; i++) { - mask = 0x80 >> i; - if ((sch->schib.pmcw.pim & mask) && - (sch->schib.pmcw.chpid[i] == chp->id)) { + for (i=0; i<8; i++) + if (sch->schib.pmcw.chpid[i] == chp->id) { if (stsch(sch->schid, &sch->schib) != 0) { /* Endgame. */ spin_unlock_irq(&sch->lock); @@ -645,7 +639,6 @@ __chp_add(struct subchannel_id schid, void *data) } break; } - } if (i==8) { spin_unlock_irq(&sch->lock); return 0; @@ -653,7 +646,7 @@ __chp_add(struct subchannel_id schid, void *data) sch->lpm = ((sch->schib.pmcw.pim & sch->schib.pmcw.pam & sch->schib.pmcw.pom) - | mask) & sch->opm; + | 0x80 >> i) & sch->opm; if (sch->driver && sch->driver->verify) sch->driver->verify(&sch->dev); @@ -707,7 +700,8 @@ chp_process_crw(int chpid, int on) return chp_add(chpid); } -static inline int check_for_io_on_path(struct subchannel *sch, int index) +static inline int +__check_for_io_and_kill(struct subchannel *sch, int index) { int cc; @@ -717,8 +711,10 @@ static inline int check_for_io_on_path(struct subchannel *sch, int index) cc = stsch(sch->schid, &sch->schib); if (cc) return 0; - if (sch->schib.scsw.actl && sch->schib.pmcw.lpum == (0x80 >> index)) + if (sch->schib.scsw.actl && sch->schib.pmcw.lpum == (0x80 >> index)) { + device_set_waiting(sch); return 1; + } return 0; } @@ -747,10 +743,12 @@ __s390_subchannel_vary_chpid(struct subchannel *sch, __u8 chpid, int on) } else { sch->opm &= ~(0x80 >> chp); sch->lpm &= ~(0x80 >> chp); - if (check_for_io_on_path(sch, chp)) - /* Path verification is done after killing. */ - device_kill_io(sch); - else if (!sch->lpm) { + /* + * Give running I/O a grace period in which it + * can successfully terminate, even using the + * just varied off path. Then kill it. + */ + if (!__check_for_io_and_kill(sch, chp) && !sch->lpm) { if (css_enqueue_subchannel_slow(sch->schid)) { css_clear_subchannel_slow_list(); need_rescan = 1; diff --git a/trunk/drivers/s390/cio/cio.c b/trunk/drivers/s390/cio/cio.c index 8936e460a807..2e2882daefbb 100644 --- a/trunk/drivers/s390/cio/cio.c +++ b/trunk/drivers/s390/cio/cio.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include "airq.h" #include "cio.h" @@ -607,17 +606,15 @@ do_IRQ (struct pt_regs *regs) struct tpi_info *tpi_info; struct subchannel *sch; struct irb *irb; - struct pt_regs *old_regs; - old_regs = set_irq_regs(regs); - irq_enter(); + irq_enter (); asm volatile ("mc 0,0"); if (S390_lowcore.int_clock >= S390_lowcore.jiffy_timer) /** * Make sure that the i/o interrupt did not "overtake" * the last HZ timer interrupt. */ - account_ticks(); + account_ticks(regs); /* * Get interrupt information from lowcore */ @@ -655,8 +652,7 @@ do_IRQ (struct pt_regs *regs) * out of the sie which costs more cycles than it saves. */ } while (!MACHINE_IS_VM && tpi (NULL) != 0); - irq_exit(); - set_irq_regs(old_regs); + irq_exit (); } #ifdef CONFIG_CCW_CONSOLE diff --git a/trunk/drivers/s390/cio/css.c b/trunk/drivers/s390/cio/css.c index ad7f7e1c0163..7086a74e9871 100644 --- a/trunk/drivers/s390/cio/css.c +++ b/trunk/drivers/s390/cio/css.c @@ -177,7 +177,7 @@ get_subchannel_by_schid(struct subchannel_id schid) struct device *dev; dev = bus_find_device(&css_bus_type, NULL, - &schid, check_subchannel); + (void *)&schid, check_subchannel); return dev ? to_subchannel(dev) : NULL; } @@ -271,6 +271,10 @@ static int css_evaluate_known_subchannel(struct subchannel *sch, int slow) /* Reset intparm to zeroes. */ sch->schib.pmcw.intparm = 0; cio_modify(sch); + + /* Probe if necessary. */ + if (action == UNREGISTER_PROBE) + ret = css_probe_device(sch->schid); break; case REPROBE: device_trigger_reprobe(sch); @@ -279,9 +283,6 @@ static int css_evaluate_known_subchannel(struct subchannel *sch, int slow) break; } spin_unlock_irqrestore(&sch->lock, flags); - /* Probe if necessary. */ - if (action == UNREGISTER_PROBE) - ret = css_probe_device(sch->schid); return ret; } diff --git a/trunk/drivers/s390/cio/css.h b/trunk/drivers/s390/cio/css.h index 4c2ff8336288..8aabb4adeb5f 100644 --- a/trunk/drivers/s390/cio/css.h +++ b/trunk/drivers/s390/cio/css.h @@ -76,8 +76,9 @@ struct ccw_device_private { int state; /* device state */ atomic_t onoff; unsigned long registered; - struct ccw_dev_id dev_id; /* device id */ - struct subchannel_id schid; /* subchannel number */ + __u16 devno; /* device number */ + __u16 sch_no; /* subchannel number */ + __u8 ssid; /* subchannel set id */ __u8 imask; /* lpm mask for SNID/SID/SPGID */ int iretry; /* retry counter SNID/SID/SPGID */ struct { @@ -170,7 +171,7 @@ void device_trigger_reprobe(struct subchannel *); /* Helper functions for vary on/off. */ int device_is_online(struct subchannel *); -void device_kill_io(struct subchannel *); +void device_set_waiting(struct subchannel *); /* Machine check helper function. */ void device_kill_pending_timer(struct subchannel *); diff --git a/trunk/drivers/s390/cio/device.c b/trunk/drivers/s390/cio/device.c index 39c98f940507..688945662c15 100644 --- a/trunk/drivers/s390/cio/device.c +++ b/trunk/drivers/s390/cio/device.c @@ -532,7 +532,8 @@ device_remove_files(struct device *dev) /* this is a simple abstraction for device_register that sets the * correct bus type and adds the bus specific files */ -static int ccw_device_register(struct ccw_device *cdev) +int +ccw_device_register(struct ccw_device *cdev) { struct device *dev = &cdev->dev; int ret; @@ -551,19 +552,21 @@ static int ccw_device_register(struct ccw_device *cdev) } struct match_data { - struct ccw_dev_id dev_id; + unsigned int devno; + unsigned int ssid; struct ccw_device * sibling; }; static int match_devno(struct device * dev, void * data) { - struct match_data * d = data; + struct match_data * d = (struct match_data *)data; struct ccw_device * cdev; cdev = to_ccwdev(dev); if ((cdev->private->state == DEV_STATE_DISCONNECTED) && - ccw_dev_id_is_equal(&cdev->private->dev_id, &d->dev_id) && + (cdev->private->devno == d->devno) && + (cdev->private->ssid == d->ssid) && (cdev != d->sibling)) { cdev->private->state = DEV_STATE_NOT_OPER; return 1; @@ -571,13 +574,15 @@ match_devno(struct device * dev, void * data) return 0; } -static struct ccw_device * get_disc_ccwdev_by_dev_id(struct ccw_dev_id *dev_id, - struct ccw_device *sibling) +static struct ccw_device * +get_disc_ccwdev_by_devno(unsigned int devno, unsigned int ssid, + struct ccw_device *sibling) { struct device *dev; struct match_data data; - data.dev_id = *dev_id; + data.devno = devno; + data.ssid = ssid; data.sibling = sibling; dev = bus_find_device(&ccw_bus_type, NULL, &data, match_devno); @@ -590,7 +595,7 @@ ccw_device_add_changed(void *data) struct ccw_device *cdev; - cdev = data; + cdev = (struct ccw_device *)data; if (device_add(&cdev->dev)) { put_device(&cdev->dev); return; @@ -611,9 +616,9 @@ ccw_device_do_unreg_rereg(void *data) struct subchannel *sch; int need_rename; - cdev = data; + cdev = (struct ccw_device *)data; sch = to_subchannel(cdev->dev.parent); - if (cdev->private->dev_id.devno != sch->schib.pmcw.dev) { + if (cdev->private->devno != sch->schib.pmcw.dev) { /* * The device number has changed. This is usually only when * a device has been detached under VM and then re-appeared @@ -628,12 +633,10 @@ ccw_device_do_unreg_rereg(void *data) * get possibly sick... */ struct ccw_device *other_cdev; - struct ccw_dev_id dev_id; need_rename = 1; - dev_id.devno = sch->schib.pmcw.dev; - dev_id.ssid = sch->schid.ssid; - other_cdev = get_disc_ccwdev_by_dev_id(&dev_id, cdev); + other_cdev = get_disc_ccwdev_by_devno(sch->schib.pmcw.dev, + sch->schid.ssid, cdev); if (other_cdev) { struct subchannel *other_sch; @@ -649,7 +652,7 @@ ccw_device_do_unreg_rereg(void *data) } /* Update ssd info here. */ css_get_ssd_info(sch); - cdev->private->dev_id.devno = sch->schib.pmcw.dev; + cdev->private->devno = sch->schib.pmcw.dev; } else need_rename = 0; device_remove_files(&cdev->dev); @@ -659,7 +662,7 @@ ccw_device_do_unreg_rereg(void *data) snprintf (cdev->dev.bus_id, BUS_ID_SIZE, "0.%x.%04x", sch->schid.ssid, sch->schib.pmcw.dev); PREPARE_WORK(&cdev->private->kick_work, - ccw_device_add_changed, cdev); + ccw_device_add_changed, (void *)cdev); queue_work(ccw_device_work, &cdev->private->kick_work); } @@ -684,7 +687,7 @@ io_subchannel_register(void *data) int ret; unsigned long flags; - cdev = data; + cdev = (struct ccw_device *) data; sch = to_subchannel(cdev->dev.parent); if (klist_node_attached(&cdev->dev.knode_parent)) { @@ -756,7 +759,7 @@ io_subchannel_recog_done(struct ccw_device *cdev) break; sch = to_subchannel(cdev->dev.parent); PREPARE_WORK(&cdev->private->kick_work, - ccw_device_call_sch_unregister, cdev); + ccw_device_call_sch_unregister, (void *) cdev); queue_work(slow_path_wq, &cdev->private->kick_work); if (atomic_dec_and_test(&ccw_device_init_count)) wake_up(&ccw_device_init_wq); @@ -771,7 +774,7 @@ io_subchannel_recog_done(struct ccw_device *cdev) if (!get_device(&cdev->dev)) break; PREPARE_WORK(&cdev->private->kick_work, - io_subchannel_register, cdev); + io_subchannel_register, (void *) cdev); queue_work(slow_path_wq, &cdev->private->kick_work); break; } @@ -789,9 +792,9 @@ io_subchannel_recog(struct ccw_device *cdev, struct subchannel *sch) /* Init private data. */ priv = cdev->private; - priv->dev_id.devno = sch->schib.pmcw.dev; - priv->dev_id.ssid = sch->schid.ssid; - priv->schid = sch->schid; + priv->devno = sch->schib.pmcw.dev; + priv->ssid = sch->schid.ssid; + priv->sch_no = sch->schid.sch_no; priv->state = DEV_STATE_NOT_OPER; INIT_LIST_HEAD(&priv->cmb_list); init_waitqueue_head(&priv->wait_q); @@ -909,7 +912,7 @@ io_subchannel_remove (struct subchannel *sch) */ if (get_device(&cdev->dev)) { PREPARE_WORK(&cdev->private->kick_work, - ccw_device_unregister, cdev); + ccw_device_unregister, (void *) cdev); queue_work(ccw_device_work, &cdev->private->kick_work); } return 0; @@ -1052,7 +1055,7 @@ __ccwdev_check_busid(struct device *dev, void *id) { char *bus_id; - bus_id = id; + bus_id = (char *)id; return (strncmp(bus_id, dev->bus_id, BUS_ID_SIZE) == 0); } diff --git a/trunk/drivers/s390/cio/device.h b/trunk/drivers/s390/cio/device.h index 9233b5c0bcc8..00be9a5b4acd 100644 --- a/trunk/drivers/s390/cio/device.h +++ b/trunk/drivers/s390/cio/device.h @@ -21,6 +21,7 @@ enum dev_state { /* states to wait for i/o completion before doing something */ DEV_STATE_CLEAR_VERIFY, DEV_STATE_TIMEOUT_KILL, + DEV_STATE_WAIT4IO, DEV_STATE_QUIESCE, /* special states for devices gone not operational */ DEV_STATE_DISCONNECTED, @@ -78,6 +79,7 @@ void io_subchannel_recog_done(struct ccw_device *cdev); int ccw_device_cancel_halt_clear(struct ccw_device *); +int ccw_device_register(struct ccw_device *); void ccw_device_do_unreg_rereg(void *); void ccw_device_call_sch_unregister(void *); diff --git a/trunk/drivers/s390/cio/device_fsm.c b/trunk/drivers/s390/cio/device_fsm.c index de3d0857db9f..b67620208f36 100644 --- a/trunk/drivers/s390/cio/device_fsm.c +++ b/trunk/drivers/s390/cio/device_fsm.c @@ -59,6 +59,18 @@ device_set_disconnected(struct subchannel *sch) cdev->private->state = DEV_STATE_DISCONNECTED; } +void +device_set_waiting(struct subchannel *sch) +{ + struct ccw_device *cdev; + + if (!sch->dev.driver_data) + return; + cdev = sch->dev.driver_data; + ccw_device_set_timeout(cdev, 10*HZ); + cdev->private->state = DEV_STATE_WAIT4IO; +} + /* * Timeout function. It just triggers a DEV_EVENT_TIMEOUT. */ @@ -171,9 +183,9 @@ ccw_device_handle_oper(struct ccw_device *cdev) cdev->id.cu_model != cdev->private->senseid.cu_model || cdev->id.dev_type != cdev->private->senseid.dev_type || cdev->id.dev_model != cdev->private->senseid.dev_model || - cdev->private->dev_id.devno != sch->schib.pmcw.dev) { + cdev->private->devno != sch->schib.pmcw.dev) { PREPARE_WORK(&cdev->private->kick_work, - ccw_device_do_unreg_rereg, cdev); + ccw_device_do_unreg_rereg, (void *)cdev); queue_work(ccw_device_work, &cdev->private->kick_work); return 0; } @@ -243,7 +255,7 @@ ccw_device_recog_done(struct ccw_device *cdev, int state) case DEV_STATE_NOT_OPER: CIO_DEBUG(KERN_WARNING, 2, "SenseID : unknown device %04x on subchannel " - "0.%x.%04x\n", cdev->private->dev_id.devno, + "0.%x.%04x\n", cdev->private->devno, sch->schid.ssid, sch->schid.sch_no); break; case DEV_STATE_OFFLINE: @@ -270,15 +282,14 @@ ccw_device_recog_done(struct ccw_device *cdev, int state) CIO_DEBUG(KERN_INFO, 2, "SenseID : device 0.%x.%04x reports: " "CU Type/Mod = %04X/%02X, Dev Type/Mod = " "%04X/%02X\n", - cdev->private->dev_id.ssid, - cdev->private->dev_id.devno, + cdev->private->ssid, cdev->private->devno, cdev->id.cu_type, cdev->id.cu_model, cdev->id.dev_type, cdev->id.dev_model); break; case DEV_STATE_BOXED: CIO_DEBUG(KERN_WARNING, 2, "SenseID : boxed device %04x on subchannel " - "0.%x.%04x\n", cdev->private->dev_id.devno, + "0.%x.%04x\n", cdev->private->devno, sch->schid.ssid, sch->schid.sch_no); break; } @@ -314,13 +325,13 @@ ccw_device_oper_notify(void *data) struct subchannel *sch; int ret; - cdev = data; + cdev = (struct ccw_device *)data; sch = to_subchannel(cdev->dev.parent); ret = (sch->driver && sch->driver->notify) ? sch->driver->notify(&sch->dev, CIO_OPER) : 0; if (!ret) /* Driver doesn't want device back. */ - ccw_device_do_unreg_rereg(cdev); + ccw_device_do_unreg_rereg((void *)cdev); else { /* Reenable channel measurements, if needed. */ cmf_reenable(cdev); @@ -352,12 +363,12 @@ ccw_device_done(struct ccw_device *cdev, int state) if (state == DEV_STATE_BOXED) CIO_DEBUG(KERN_WARNING, 2, "Boxed device %04x on subchannel %04x\n", - cdev->private->dev_id.devno, sch->schid.sch_no); + cdev->private->devno, sch->schid.sch_no); if (cdev->private->flags.donotify) { cdev->private->flags.donotify = 0; PREPARE_WORK(&cdev->private->kick_work, ccw_device_oper_notify, - cdev); + (void *)cdev); queue_work(ccw_device_notify_work, &cdev->private->kick_work); } wake_up(&cdev->private->wait_q); @@ -401,8 +412,7 @@ static void __ccw_device_get_common_pgid(struct ccw_device *cdev) /* PGID mismatch, can't pathgroup. */ CIO_MSG_EVENT(0, "SNID - pgid mismatch for device " "0.%x.%04x, can't pathgroup\n", - cdev->private->dev_id.ssid, - cdev->private->dev_id.devno); + cdev->private->ssid, cdev->private->devno); cdev->private->options.pgroup = 0; return; } @@ -513,7 +523,7 @@ ccw_device_nopath_notify(void *data) struct subchannel *sch; int ret; - cdev = data; + cdev = (struct ccw_device *)data; sch = to_subchannel(cdev->dev.parent); /* Extra sanity. */ if (sch->lpm) @@ -527,7 +537,7 @@ ccw_device_nopath_notify(void *data) if (get_device(&cdev->dev)) { PREPARE_WORK(&cdev->private->kick_work, ccw_device_call_sch_unregister, - cdev); + (void *)cdev); queue_work(ccw_device_work, &cdev->private->kick_work); } else @@ -578,15 +588,11 @@ ccw_device_verify_done(struct ccw_device *cdev, int err) } break; case -ETIME: - /* Reset oper notify indication after verify error. */ - cdev->private->flags.donotify = 0; ccw_device_done(cdev, DEV_STATE_BOXED); break; default: - /* Reset oper notify indication after verify error. */ - cdev->private->flags.donotify = 0; PREPARE_WORK(&cdev->private->kick_work, - ccw_device_nopath_notify, cdev); + ccw_device_nopath_notify, (void *)cdev); queue_work(ccw_device_notify_work, &cdev->private->kick_work); ccw_device_done(cdev, DEV_STATE_NOT_OPER); break; @@ -717,7 +723,7 @@ ccw_device_offline_notoper(struct ccw_device *cdev, enum dev_event dev_event) sch = to_subchannel(cdev->dev.parent); if (get_device(&cdev->dev)) { PREPARE_WORK(&cdev->private->kick_work, - ccw_device_call_sch_unregister, cdev); + ccw_device_call_sch_unregister, (void *)cdev); queue_work(ccw_device_work, &cdev->private->kick_work); } wake_up(&cdev->private->wait_q); @@ -748,7 +754,7 @@ ccw_device_online_notoper(struct ccw_device *cdev, enum dev_event dev_event) } if (get_device(&cdev->dev)) { PREPARE_WORK(&cdev->private->kick_work, - ccw_device_call_sch_unregister, cdev); + ccw_device_call_sch_unregister, (void *)cdev); queue_work(ccw_device_work, &cdev->private->kick_work); } wake_up(&cdev->private->wait_q); @@ -853,7 +859,7 @@ ccw_device_online_timeout(struct ccw_device *cdev, enum dev_event dev_event) sch = to_subchannel(cdev->dev.parent); if (!sch->lpm) { PREPARE_WORK(&cdev->private->kick_work, - ccw_device_nopath_notify, cdev); + ccw_device_nopath_notify, (void *)cdev); queue_work(ccw_device_notify_work, &cdev->private->kick_work); } else @@ -879,8 +885,7 @@ ccw_device_w4sense(struct ccw_device *cdev, enum dev_event dev_event) /* Basic sense hasn't started. Try again. */ ccw_device_do_sense(cdev, irb); else { - printk(KERN_INFO "Huh? %s(%s): unsolicited " - "interrupt...\n", + printk("Huh? %s(%s): unsolicited interrupt...\n", __FUNCTION__, cdev->dev.bus_id); if (cdev->handler) cdev->handler (cdev, 0, irb); @@ -939,10 +944,10 @@ ccw_device_killing_irq(struct ccw_device *cdev, enum dev_event dev_event) cdev->private->state = DEV_STATE_ONLINE; if (cdev->handler) cdev->handler(cdev, cdev->private->intparm, - ERR_PTR(-EIO)); + ERR_PTR(-ETIMEDOUT)); if (!sch->lpm) { PREPARE_WORK(&cdev->private->kick_work, - ccw_device_nopath_notify, cdev); + ccw_device_nopath_notify, (void *)cdev); queue_work(ccw_device_notify_work, &cdev->private->kick_work); } else if (cdev->private->flags.doverify) /* Start delayed path verification. */ @@ -965,7 +970,7 @@ ccw_device_killing_timeout(struct ccw_device *cdev, enum dev_event dev_event) sch = to_subchannel(cdev->dev.parent); if (!sch->lpm) { PREPARE_WORK(&cdev->private->kick_work, - ccw_device_nopath_notify, cdev); + ccw_device_nopath_notify, (void *)cdev); queue_work(ccw_device_notify_work, &cdev->private->kick_work); } else @@ -976,15 +981,51 @@ ccw_device_killing_timeout(struct ccw_device *cdev, enum dev_event dev_event) cdev->private->state = DEV_STATE_ONLINE; if (cdev->handler) cdev->handler(cdev, cdev->private->intparm, - ERR_PTR(-EIO)); + ERR_PTR(-ETIMEDOUT)); +} + +static void +ccw_device_wait4io_irq(struct ccw_device *cdev, enum dev_event dev_event) +{ + struct irb *irb; + struct subchannel *sch; + + irb = (struct irb *) __LC_IRB; + /* + * Accumulate status and find out if a basic sense is needed. + * This is fine since we have already adapted the lpm. + */ + ccw_device_accumulate_irb(cdev, irb); + if (cdev->private->flags.dosense) { + if (ccw_device_do_sense(cdev, irb) == 0) { + cdev->private->state = DEV_STATE_W4SENSE; + } + return; + } + + /* Iff device is idle, reset timeout. */ + sch = to_subchannel(cdev->dev.parent); + if (!stsch(sch->schid, &sch->schib)) + if (sch->schib.scsw.actl == 0) + ccw_device_set_timeout(cdev, 0); + /* Call the handler. */ + ccw_device_call_handler(cdev); + if (!sch->lpm) { + PREPARE_WORK(&cdev->private->kick_work, + ccw_device_nopath_notify, (void *)cdev); + queue_work(ccw_device_notify_work, &cdev->private->kick_work); + } else if (cdev->private->flags.doverify) + ccw_device_online_verify(cdev, 0); } -void device_kill_io(struct subchannel *sch) +static void +ccw_device_wait4io_timeout(struct ccw_device *cdev, enum dev_event dev_event) { int ret; - struct ccw_device *cdev; + struct subchannel *sch; - cdev = sch->dev.driver_data; + sch = to_subchannel(cdev->dev.parent); + ccw_device_set_timeout(cdev, 0); ret = ccw_device_cancel_halt_clear(cdev); if (ret == -EBUSY) { ccw_device_set_timeout(cdev, 3*HZ); @@ -994,7 +1035,7 @@ void device_kill_io(struct subchannel *sch) if (ret == -ENODEV) { if (!sch->lpm) { PREPARE_WORK(&cdev->private->kick_work, - ccw_device_nopath_notify, cdev); + ccw_device_nopath_notify, (void *)cdev); queue_work(ccw_device_notify_work, &cdev->private->kick_work); } else @@ -1003,12 +1044,12 @@ void device_kill_io(struct subchannel *sch) } if (cdev->handler) cdev->handler(cdev, cdev->private->intparm, - ERR_PTR(-EIO)); + ERR_PTR(-ETIMEDOUT)); if (!sch->lpm) { PREPARE_WORK(&cdev->private->kick_work, - ccw_device_nopath_notify, cdev); + ccw_device_nopath_notify, (void *)cdev); queue_work(ccw_device_notify_work, &cdev->private->kick_work); - } else + } else if (cdev->private->flags.doverify) /* Start delayed path verification. */ ccw_device_online_verify(cdev, 0); } @@ -1245,6 +1286,12 @@ fsm_func_t *dev_jumptable[NR_DEV_STATES][NR_DEV_EVENTS] = { [DEV_EVENT_TIMEOUT] = ccw_device_killing_timeout, [DEV_EVENT_VERIFY] = ccw_device_nop, //FIXME }, + [DEV_STATE_WAIT4IO] = { + [DEV_EVENT_NOTOPER] = ccw_device_online_notoper, + [DEV_EVENT_INTERRUPT] = ccw_device_wait4io_irq, + [DEV_EVENT_TIMEOUT] = ccw_device_wait4io_timeout, + [DEV_EVENT_VERIFY] = ccw_device_delay_verify, + }, [DEV_STATE_QUIESCE] = { [DEV_EVENT_NOTOPER] = ccw_device_quiesce_done, [DEV_EVENT_INTERRUPT] = ccw_device_quiesce_done, diff --git a/trunk/drivers/s390/cio/device_id.c b/trunk/drivers/s390/cio/device_id.c index a74785b9e4eb..1398367b5f68 100644 --- a/trunk/drivers/s390/cio/device_id.c +++ b/trunk/drivers/s390/cio/device_id.c @@ -251,7 +251,7 @@ ccw_device_check_sense_id(struct ccw_device *cdev) */ CIO_MSG_EVENT(2, "SenseID : device %04x on Subchannel " "0.%x.%04x reports cmd reject\n", - cdev->private->dev_id.devno, sch->schid.ssid, + cdev->private->devno, sch->schid.ssid, sch->schid.sch_no); return -EOPNOTSUPP; } @@ -259,8 +259,7 @@ ccw_device_check_sense_id(struct ccw_device *cdev) CIO_MSG_EVENT(2, "SenseID : UC on dev 0.%x.%04x, " "lpum %02X, cnt %02d, sns :" " %02X%02X%02X%02X %02X%02X%02X%02X ...\n", - cdev->private->dev_id.ssid, - cdev->private->dev_id.devno, + cdev->private->ssid, cdev->private->devno, irb->esw.esw0.sublog.lpum, irb->esw.esw0.erw.scnt, irb->ecw[0], irb->ecw[1], @@ -275,15 +274,14 @@ ccw_device_check_sense_id(struct ccw_device *cdev) CIO_MSG_EVENT(2, "SenseID : path %02X for device %04x " "on subchannel 0.%x.%04x is " "'not operational'\n", sch->orb.lpm, - cdev->private->dev_id.devno, - sch->schid.ssid, sch->schid.sch_no); + cdev->private->devno, sch->schid.ssid, + sch->schid.sch_no); return -EACCES; } /* Hmm, whatever happened, try again. */ CIO_MSG_EVENT(2, "SenseID : start_IO() for device %04x on " "subchannel 0.%x.%04x returns status %02X%02X\n", - cdev->private->dev_id.devno, sch->schid.ssid, - sch->schid.sch_no, + cdev->private->devno, sch->schid.ssid, sch->schid.sch_no, irb->scsw.dstat, irb->scsw.cstat); return -EAGAIN; } @@ -332,7 +330,7 @@ ccw_device_sense_id_irq(struct ccw_device *cdev, enum dev_event dev_event) /* fall through. */ default: /* Sense ID failed. Try asking VM. */ if (MACHINE_IS_VM) { - VM_virtual_device_info (cdev->private->dev_id.devno, + VM_virtual_device_info (cdev->private->devno, &cdev->private->senseid); if (cdev->private->senseid.cu_type != 0xFFFF) { /* Got the device information from VM. */ diff --git a/trunk/drivers/s390/cio/device_ops.c b/trunk/drivers/s390/cio/device_ops.c index b39c1fa48acd..84b9b18eabc2 100644 --- a/trunk/drivers/s390/cio/device_ops.c +++ b/trunk/drivers/s390/cio/device_ops.c @@ -50,6 +50,7 @@ ccw_device_clear(struct ccw_device *cdev, unsigned long intparm) if (cdev->private->state == DEV_STATE_NOT_OPER) return -ENODEV; if (cdev->private->state != DEV_STATE_ONLINE && + cdev->private->state != DEV_STATE_WAIT4IO && cdev->private->state != DEV_STATE_W4SENSE) return -EINVAL; sch = to_subchannel(cdev->dev.parent); @@ -154,6 +155,7 @@ ccw_device_halt(struct ccw_device *cdev, unsigned long intparm) if (cdev->private->state == DEV_STATE_NOT_OPER) return -ENODEV; if (cdev->private->state != DEV_STATE_ONLINE && + cdev->private->state != DEV_STATE_WAIT4IO && cdev->private->state != DEV_STATE_W4SENSE) return -EINVAL; sch = to_subchannel(cdev->dev.parent); @@ -590,13 +592,13 @@ ccw_device_get_chp_desc(struct ccw_device *cdev, int chp_no) int _ccw_device_get_subchannel_number(struct ccw_device *cdev) { - return cdev->private->schid.sch_no; + return cdev->private->sch_no; } int _ccw_device_get_device_number(struct ccw_device *cdev) { - return cdev->private->dev_id.devno; + return cdev->private->devno; } diff --git a/trunk/drivers/s390/cio/device_pgid.c b/trunk/drivers/s390/cio/device_pgid.c index 2975ce888c19..84917b39de45 100644 --- a/trunk/drivers/s390/cio/device_pgid.c +++ b/trunk/drivers/s390/cio/device_pgid.c @@ -79,8 +79,7 @@ __ccw_device_sense_pgid_start(struct ccw_device *cdev) CIO_MSG_EVENT(2, "SNID - Device %04x on Subchannel " "0.%x.%04x, lpm %02X, became 'not " "operational'\n", - cdev->private->dev_id.devno, - sch->schid.ssid, + cdev->private->devno, sch->schid.ssid, sch->schid.sch_no, cdev->private->imask); } @@ -136,8 +135,7 @@ __ccw_device_check_sense_pgid(struct ccw_device *cdev) CIO_MSG_EVENT(2, "SNID - device 0.%x.%04x, unit check, " "lpum %02X, cnt %02d, sns : " "%02X%02X%02X%02X %02X%02X%02X%02X ...\n", - cdev->private->dev_id.ssid, - cdev->private->dev_id.devno, + cdev->private->ssid, cdev->private->devno, irb->esw.esw0.sublog.lpum, irb->esw.esw0.erw.scnt, irb->ecw[0], irb->ecw[1], @@ -149,7 +147,7 @@ __ccw_device_check_sense_pgid(struct ccw_device *cdev) if (irb->scsw.cc == 3) { CIO_MSG_EVENT(2, "SNID - Device %04x on Subchannel 0.%x.%04x," " lpm %02X, became 'not operational'\n", - cdev->private->dev_id.devno, sch->schid.ssid, + cdev->private->devno, sch->schid.ssid, sch->schid.sch_no, sch->orb.lpm); return -EACCES; } @@ -157,7 +155,7 @@ __ccw_device_check_sense_pgid(struct ccw_device *cdev) if (cdev->private->pgid[i].inf.ps.state2 == SNID_STATE2_RESVD_ELSE) { CIO_MSG_EVENT(2, "SNID - Device %04x on Subchannel 0.%x.%04x " "is reserved by someone else\n", - cdev->private->dev_id.devno, sch->schid.ssid, + cdev->private->devno, sch->schid.ssid, sch->schid.sch_no); return -EUSERS; } @@ -263,7 +261,7 @@ __ccw_device_do_pgid(struct ccw_device *cdev, __u8 func) /* PGID command failed on this path. */ CIO_MSG_EVENT(2, "SPID - Device %04x on Subchannel " "0.%x.%04x, lpm %02X, became 'not operational'\n", - cdev->private->dev_id.devno, sch->schid.ssid, + cdev->private->devno, sch->schid.ssid, sch->schid.sch_no, cdev->private->imask); return ret; } @@ -303,7 +301,7 @@ static int __ccw_device_do_nop(struct ccw_device *cdev) /* nop command failed on this path. */ CIO_MSG_EVENT(2, "NOP - Device %04x on Subchannel " "0.%x.%04x, lpm %02X, became 'not operational'\n", - cdev->private->dev_id.devno, sch->schid.ssid, + cdev->private->devno, sch->schid.ssid, sch->schid.sch_no, cdev->private->imask); return ret; } @@ -330,9 +328,8 @@ __ccw_device_check_pgid(struct ccw_device *cdev) CIO_MSG_EVENT(2, "SPID - device 0.%x.%04x, unit check, " "cnt %02d, " "sns : %02X%02X%02X%02X %02X%02X%02X%02X ...\n", - cdev->private->dev_id.ssid, - cdev->private->dev_id.devno, - irb->esw.esw0.erw.scnt, + cdev->private->ssid, + cdev->private->devno, irb->esw.esw0.erw.scnt, irb->ecw[0], irb->ecw[1], irb->ecw[2], irb->ecw[3], irb->ecw[4], irb->ecw[5], @@ -342,7 +339,7 @@ __ccw_device_check_pgid(struct ccw_device *cdev) if (irb->scsw.cc == 3) { CIO_MSG_EVENT(2, "SPID - Device %04x on Subchannel 0.%x.%04x," " lpm %02X, became 'not operational'\n", - cdev->private->dev_id.devno, sch->schid.ssid, + cdev->private->devno, sch->schid.ssid, sch->schid.sch_no, cdev->private->imask); return -EACCES; } @@ -365,7 +362,7 @@ static int __ccw_device_check_nop(struct ccw_device *cdev) if (irb->scsw.cc == 3) { CIO_MSG_EVENT(2, "NOP - Device %04x on Subchannel 0.%x.%04x," " lpm %02X, became 'not operational'\n", - cdev->private->dev_id.devno, sch->schid.ssid, + cdev->private->devno, sch->schid.ssid, sch->schid.sch_no, cdev->private->imask); return -EACCES; } diff --git a/trunk/drivers/s390/cio/device_status.c b/trunk/drivers/s390/cio/device_status.c index 3f7cbce4cd87..caf148d5caad 100644 --- a/trunk/drivers/s390/cio/device_status.c +++ b/trunk/drivers/s390/cio/device_status.c @@ -32,18 +32,19 @@ ccw_device_msg_control_check(struct ccw_device *cdev, struct irb *irb) SCHN_STAT_CHN_CTRL_CHK | SCHN_STAT_INTF_CTRL_CHK))) return; + CIO_MSG_EVENT(0, "Channel-Check or Interface-Control-Check " "received" " ... device %04x on subchannel 0.%x.%04x, dev_stat " ": %02X sch_stat : %02X\n", - cdev->private->dev_id.devno, cdev->private->schid.ssid, - cdev->private->schid.sch_no, + cdev->private->devno, cdev->private->ssid, + cdev->private->sch_no, irb->scsw.dstat, irb->scsw.cstat); if (irb->scsw.cc != 3) { char dbf_text[15]; - sprintf(dbf_text, "chk%x", cdev->private->schid.sch_no); + sprintf(dbf_text, "chk%x", cdev->private->sch_no); CIO_TRACE_EVENT(0, dbf_text); CIO_HEX_EVENT(0, irb, sizeof (struct irb)); } diff --git a/trunk/drivers/s390/cio/qdio.c b/trunk/drivers/s390/cio/qdio.c index 476aa1da5cbc..cde822d8b5c8 100644 --- a/trunk/drivers/s390/cio/qdio.c +++ b/trunk/drivers/s390/cio/qdio.c @@ -1741,7 +1741,7 @@ qdio_fill_qs(struct qdio_irq *irq_ptr, struct ccw_device *cdev, void *ptr; int available; - sprintf(dbf_text,"qfqs%4x",cdev->private->schid.sch_no); + sprintf(dbf_text,"qfqs%4x",cdev->private->sch_no); QDIO_DBF_TEXT0(0,setup,dbf_text); for (i=0;iinput_qs[i]; @@ -2924,7 +2924,7 @@ qdio_establish_handle_irq(struct ccw_device *cdev, int cstat, int dstat) irq_ptr = cdev->private->qdio_data; - sprintf(dbf_text,"qehi%4x",cdev->private->schid.sch_no); + sprintf(dbf_text,"qehi%4x",cdev->private->sch_no); QDIO_DBF_TEXT0(0,setup,dbf_text); QDIO_DBF_TEXT0(0,trace,dbf_text); @@ -2943,7 +2943,7 @@ qdio_initialize(struct qdio_initialize *init_data) int rc; char dbf_text[15]; - sprintf(dbf_text,"qini%4x",init_data->cdev->private->schid.sch_no); + sprintf(dbf_text,"qini%4x",init_data->cdev->private->sch_no); QDIO_DBF_TEXT0(0,setup,dbf_text); QDIO_DBF_TEXT0(0,trace,dbf_text); @@ -2964,7 +2964,7 @@ qdio_allocate(struct qdio_initialize *init_data) struct qdio_irq *irq_ptr; char dbf_text[15]; - sprintf(dbf_text,"qalc%4x",init_data->cdev->private->schid.sch_no); + sprintf(dbf_text,"qalc%4x",init_data->cdev->private->sch_no); QDIO_DBF_TEXT0(0,setup,dbf_text); QDIO_DBF_TEXT0(0,trace,dbf_text); if ( (init_data->no_input_qs>QDIO_MAX_QUEUES_PER_IRQ) || @@ -3187,7 +3187,7 @@ qdio_establish(struct qdio_initialize *init_data) tiqdio_set_delay_target(irq_ptr,TIQDIO_DELAY_TARGET); } - sprintf(dbf_text,"qest%4x",cdev->private->schid.sch_no); + sprintf(dbf_text,"qest%4x",cdev->private->sch_no); QDIO_DBF_TEXT0(0,setup,dbf_text); QDIO_DBF_TEXT0(0,trace,dbf_text); @@ -3529,7 +3529,7 @@ do_QDIO(struct ccw_device *cdev,unsigned int callflags, #ifdef CONFIG_QDIO_DEBUG char dbf_text[20]; - sprintf(dbf_text,"doQD%04x",cdev->private->schid.sch_no); + sprintf(dbf_text,"doQD%04x",cdev->private->sch_no); QDIO_DBF_TEXT3(0,trace,dbf_text); #endif /* CONFIG_QDIO_DEBUG */ diff --git a/trunk/drivers/s390/crypto/ap_bus.c b/trunk/drivers/s390/crypto/ap_bus.c index 79d89c368919..cd30f37fceae 100644 --- a/trunk/drivers/s390/crypto/ap_bus.c +++ b/trunk/drivers/s390/crypto/ap_bus.c @@ -739,16 +739,11 @@ static void ap_scan_bus(void *data) dev = bus_find_device(&ap_bus_type, NULL, (void *)(unsigned long)qid, __ap_scan_bus); - rc = ap_query_queue(qid, &queue_depth, &device_type); - if (dev && rc) { - put_device(dev); - device_unregister(dev); - continue; - } if (dev) { put_device(dev); continue; } + rc = ap_query_queue(qid, &queue_depth, &device_type); if (rc) continue; rc = ap_init_queue(qid); @@ -1067,7 +1062,7 @@ static int ap_poll_thread(void *data) unsigned long flags; int requests; - set_user_nice(current, 19); + set_user_nice(current, -20); while (1) { if (need_resched()) { schedule(); diff --git a/trunk/drivers/s390/net/claw.h b/trunk/drivers/s390/net/claw.h index 1ee9a6f06541..969be465309c 100644 --- a/trunk/drivers/s390/net/claw.h +++ b/trunk/drivers/s390/net/claw.h @@ -29,7 +29,7 @@ #define CLAW_COMPLETE 0xff /* flag to indicate i/o completed */ /*-----------------------------------------------------* -* CLAW control command code * +* CLAW control comand code * *------------------------------------------------------*/ #define SYSTEM_VALIDATE_REQUEST 0x01 /* System Validate request */ diff --git a/trunk/drivers/s390/net/iucv.c b/trunk/drivers/s390/net/iucv.c index 1476ce2b437c..809dd8d7f47a 100644 --- a/trunk/drivers/s390/net/iucv.c +++ b/trunk/drivers/s390/net/iucv.c @@ -116,7 +116,7 @@ static DEFINE_SPINLOCK(iucv_irq_queue_lock); *Internal function prototypes */ static void iucv_tasklet_handler(unsigned long); -static void iucv_irq_handler(__u16); +static void iucv_irq_handler(struct pt_regs *, __u16); static DECLARE_TASKLET(iucv_tasklet,iucv_tasklet_handler,0); @@ -2251,7 +2251,7 @@ iucv_sever(__u16 pathid, __u8 user_data[16]) * Places the interrupt buffer on a queue and schedules iucv_tasklet_handler(). */ static void -iucv_irq_handler(__u16 code) +iucv_irq_handler(struct pt_regs *regs, __u16 code) { iucv_irqdata *irqdata; diff --git a/trunk/drivers/s390/scsi/zfcp_def.h b/trunk/drivers/s390/scsi/zfcp_def.h index 74c0eac083e4..8f882690994d 100644 --- a/trunk/drivers/s390/scsi/zfcp_def.h +++ b/trunk/drivers/s390/scsi/zfcp_def.h @@ -107,10 +107,6 @@ zfcp_address_to_sg(void *address, struct scatterlist *list) (ZFCP_MAX_SBALS_PER_REQ * ZFCP_MAX_SBALES_PER_SBAL - 2) /* request ID + QTCB in SBALE 0 + 1 of first SBAL in chain */ -#define ZFCP_MAX_SECTORS (ZFCP_MAX_SBALES_PER_REQ * 8) - /* max. number of (data buffer) SBALEs in largest SBAL chain - multiplied with number of sectors per 4k block */ - /* FIXME(tune): free space should be one max. SBAL chain plus what? */ #define ZFCP_QDIO_PCI_INTERVAL (QDIO_MAX_BUFFERS_PER_Q \ - (ZFCP_MAX_SBALS_PER_REQ + 4)) diff --git a/trunk/drivers/s390/scsi/zfcp_erp.c b/trunk/drivers/s390/scsi/zfcp_erp.c index c88babce9bca..862a411a4aa0 100644 --- a/trunk/drivers/s390/scsi/zfcp_erp.c +++ b/trunk/drivers/s390/scsi/zfcp_erp.c @@ -1987,7 +1987,7 @@ zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *erp_action) sbale = &(adapter->response_queue.buffer[i]->element[0]); sbale->length = 0; sbale->flags = SBAL_FLAGS_LAST_ENTRY; - sbale->addr = NULL; + sbale->addr = 0; } ZFCP_LOG_TRACE("calling do_QDIO on adapter %s (flags=0x%x, " diff --git a/trunk/drivers/s390/scsi/zfcp_scsi.c b/trunk/drivers/s390/scsi/zfcp_scsi.c index 452d96f92a14..4d2bc7981324 100644 --- a/trunk/drivers/s390/scsi/zfcp_scsi.c +++ b/trunk/drivers/s390/scsi/zfcp_scsi.c @@ -58,7 +58,6 @@ struct zfcp_data zfcp_data = { .cmd_per_lun = 1, .use_clustering = 1, .sdev_attrs = zfcp_sysfs_sdev_attrs, - .max_sectors = ZFCP_MAX_SECTORS, }, .driver_version = ZFCP_VERSION, }; diff --git a/trunk/drivers/sbus/char/aurora.c b/trunk/drivers/sbus/char/aurora.c index a54b4ac67568..a305d4091547 100644 --- a/trunk/drivers/sbus/char/aurora.c +++ b/trunk/drivers/sbus/char/aurora.c @@ -254,7 +254,7 @@ for(i=0;i #include +#include +#include #include -#include #include #include @@ -195,7 +197,7 @@ static void do_envctrl_shutdown(struct bbc_cpu_temperature *tp) printk(KERN_CRIT "kenvctrld: Shutting down the system now.\n"); shutting_down = 1; - if (call_usermodehelper("/sbin/shutdown", argv, envp, 0) < 0) + if (kernel_execve("/sbin/shutdown", argv, envp) < 0) printk(KERN_CRIT "envctrl: shutdown execution failed\n"); } diff --git a/trunk/drivers/sbus/char/bbc_i2c.c b/trunk/drivers/sbus/char/bbc_i2c.c index 22631f8b9b48..7186235594f9 100644 --- a/trunk/drivers/sbus/char/bbc_i2c.c +++ b/trunk/drivers/sbus/char/bbc_i2c.c @@ -331,7 +331,7 @@ EXPORT_SYMBOL(bbc_i2c_readb); EXPORT_SYMBOL(bbc_i2c_write_buf); EXPORT_SYMBOL(bbc_i2c_read_buf); -static irqreturn_t bbc_i2c_interrupt(int irq, void *dev_id) +static irqreturn_t bbc_i2c_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct bbc_i2c_bus *bp = dev_id; diff --git a/trunk/drivers/sbus/char/cpwatchdog.c b/trunk/drivers/sbus/char/cpwatchdog.c index f5803ecb1999..40b6fc86f6a8 100644 --- a/trunk/drivers/sbus/char/cpwatchdog.c +++ b/trunk/drivers/sbus/char/cpwatchdog.c @@ -185,7 +185,7 @@ MODULE_SUPPORTED_DEVICE #ifdef WD_DEBUG static void wd_dumpregs(void); #endif -static irqreturn_t wd_interrupt(int irq, void *dev_id); +static irqreturn_t wd_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void wd_toggleintr(struct wd_timer* pTimer, int enable); static void wd_pingtimer(struct wd_timer* pTimer); static void wd_starttimer(struct wd_timer* pTimer); @@ -444,7 +444,7 @@ static ssize_t wd_read(struct file * file, char __user *buffer, #endif /* ifdef WD_DEBUG */ } -static irqreturn_t wd_interrupt(int irq, void *dev_id) +static irqreturn_t wd_interrupt(int irq, void *dev_id, struct pt_regs *regs) { /* Only WD0 will interrupt-- others are NMI and we won't * see them here.... diff --git a/trunk/drivers/sbus/char/envctrl.c b/trunk/drivers/sbus/char/envctrl.c index fff4660cdf96..728a133d0fc5 100644 --- a/trunk/drivers/sbus/char/envctrl.c +++ b/trunk/drivers/sbus/char/envctrl.c @@ -20,12 +20,16 @@ */ #include -#include +#include #include +#include #include #include +#include #include -#include +#include +#include +#include #include #include @@ -976,7 +980,7 @@ static void envctrl_do_shutdown(void) inprog = 1; printk(KERN_CRIT "kenvctrld: WARNING: Shutting down the system now.\n"); - ret = call_usermodehelper("/sbin/shutdown", argv, envp, 0); + ret = kernel_execve("/sbin/shutdown", argv, envp); if (ret < 0) { printk(KERN_CRIT "kenvctrld: WARNING: system shutdown failed!\n"); inprog = 0; /* unlikely to succeed, but we could try again */ diff --git a/trunk/drivers/sbus/char/openprom.c b/trunk/drivers/sbus/char/openprom.c index 81ba2d71cee2..2f698763ba5d 100644 --- a/trunk/drivers/sbus/char/openprom.c +++ b/trunk/drivers/sbus/char/openprom.c @@ -630,7 +630,7 @@ static int openprom_ioctl(struct inode * inode, struct file * file, case OPROMPATH2NODE: if ((file->f_mode & FMODE_READ) == 0) return -EPERM; - return openprom_sunos_ioctl(inode, file, cmd, arg, NULL); + return openprom_sunos_ioctl(inode, file, cmd, arg, 0); case OPIOCGET: case OPIOCNEXTPROP: diff --git a/trunk/drivers/sbus/char/uctrl.c b/trunk/drivers/sbus/char/uctrl.c index b30372f17f1c..575b1f7ed410 100644 --- a/trunk/drivers/sbus/char/uctrl.c +++ b/trunk/drivers/sbus/char/uctrl.c @@ -217,7 +217,7 @@ uctrl_open(struct inode *inode, struct file *file) return 0; } -static irqreturn_t uctrl_interrupt(int irq, void *dev_id) +static irqreturn_t uctrl_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct uctrl_driver *driver = (struct uctrl_driver *)dev_id; printk("in uctrl_interrupt\n"); @@ -400,7 +400,7 @@ static int __init ts102_uctrl_init(void) } driver->regs->uctrl_intr = UCTRL_INTR_RXNE_REQ|UCTRL_INTR_RXNE_MSK; - printk("uctrl: 0x%p (irq %d)\n", driver->regs, driver->irq); + printk("uctrl: 0x%x (irq %d)\n", driver->regs, driver->irq); uctrl_get_event_status(); uctrl_get_external_status(); return 0; diff --git a/trunk/drivers/sbus/sbus.c b/trunk/drivers/sbus/sbus.c index 98fcbb3d5560..935952ef88f1 100644 --- a/trunk/drivers/sbus/sbus.c +++ b/trunk/drivers/sbus/sbus.c @@ -61,11 +61,11 @@ static void __init fill_sbus_device(struct device_node *dp, struct sbus_dev *sde else sdev->ofdev.dev.parent = &sdev->bus->ofdev.dev; sdev->ofdev.dev.bus = &sbus_bus_type; - sprintf(sdev->ofdev.dev.bus_id, "sbus[%08x]", dp->node); + strcpy(sdev->ofdev.dev.bus_id, dp->path_component_name); if (of_device_register(&sdev->ofdev) != 0) printk(KERN_DEBUG "sbus: device registration error for %s!\n", - dp->path_component_name); + sdev->ofdev.dev.bus_id); } static void __init sbus_bus_ranges_init(struct device_node *dp, struct sbus_bus *sbus) diff --git a/trunk/drivers/scsi/3w-9xxx.c b/trunk/drivers/scsi/3w-9xxx.c index b091a0fc4eb0..5a9475e56d0e 100644 --- a/trunk/drivers/scsi/3w-9xxx.c +++ b/trunk/drivers/scsi/3w-9xxx.c @@ -66,9 +66,6 @@ 2.26.02.006 - Fix 9550SX pchip reset timeout. Add big endian support. 2.26.02.007 - Disable local interrupts during kmap/unmap_atomic(). - 2.26.02.008 - Free irq handler in __twa_shutdown(). - Serialize reset code. - Add support for 9650SE controllers. */ #include @@ -92,7 +89,7 @@ #include "3w-9xxx.h" /* Globals */ -#define TW_DRIVER_VERSION "2.26.02.008" +#define TW_DRIVER_VERSION "2.26.02.007" static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT]; static unsigned int twa_device_extension_count; static int twa_major = -1; @@ -569,9 +566,9 @@ static int twa_check_srl(TW_Device_Extension *tw_dev, int *flashed) goto out; } - tw_dev->tw_compat_info.working_srl = fw_on_ctlr_srl; - tw_dev->tw_compat_info.working_branch = fw_on_ctlr_branch; - tw_dev->tw_compat_info.working_build = fw_on_ctlr_build; + tw_dev->working_srl = fw_on_ctlr_srl; + tw_dev->working_branch = fw_on_ctlr_branch; + tw_dev->working_build = fw_on_ctlr_build; /* Try base mode compatibility */ if (!(init_connect_result & TW_CTLR_FW_COMPATIBLE)) { @@ -593,23 +590,10 @@ static int twa_check_srl(TW_Device_Extension *tw_dev, int *flashed) } goto out; } - tw_dev->tw_compat_info.working_srl = TW_BASE_FW_SRL; - tw_dev->tw_compat_info.working_branch = TW_BASE_FW_BRANCH; - tw_dev->tw_compat_info.working_build = TW_BASE_FW_BUILD; - } - - /* Load rest of compatibility struct */ - strncpy(tw_dev->tw_compat_info.driver_version, TW_DRIVER_VERSION, strlen(TW_DRIVER_VERSION)); - tw_dev->tw_compat_info.driver_srl_high = TW_CURRENT_DRIVER_SRL; - tw_dev->tw_compat_info.driver_branch_high = TW_CURRENT_DRIVER_BRANCH; - tw_dev->tw_compat_info.driver_build_high = TW_CURRENT_DRIVER_BUILD; - tw_dev->tw_compat_info.driver_srl_low = TW_BASE_FW_SRL; - tw_dev->tw_compat_info.driver_branch_low = TW_BASE_FW_BRANCH; - tw_dev->tw_compat_info.driver_build_low = TW_BASE_FW_BUILD; - tw_dev->tw_compat_info.fw_on_ctlr_srl = fw_on_ctlr_srl; - tw_dev->tw_compat_info.fw_on_ctlr_branch = fw_on_ctlr_branch; - tw_dev->tw_compat_info.fw_on_ctlr_build = fw_on_ctlr_build; - + tw_dev->working_srl = TW_BASE_FW_SRL; + tw_dev->working_branch = TW_BASE_FW_BRANCH; + tw_dev->working_build = TW_BASE_FW_BUILD; + } retval = 0; out: return retval; @@ -647,7 +631,7 @@ static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int goto out2; /* Check data buffer size */ - if (driver_command.buffer_length > TW_MAX_SECTORS * 2048) { + if (driver_command.buffer_length > TW_MAX_SECTORS * 512) { retval = TW_IOCTL_ERROR_OS_EINVAL; goto out2; } @@ -696,6 +680,13 @@ static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int /* Now wait for command to complete */ timeout = wait_event_timeout(tw_dev->ioctl_wqueue, tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FREE, timeout); + /* See if we reset while waiting for the ioctl to complete */ + if (test_bit(TW_IN_RESET, &tw_dev->flags)) { + clear_bit(TW_IN_RESET, &tw_dev->flags); + retval = TW_IOCTL_ERROR_OS_ERESTARTSYS; + goto out3; + } + /* We timed out, and didn't get an interrupt */ if (tw_dev->chrdev_request_id != TW_IOCTL_CHRDEV_FREE) { /* Now we need to reset the board */ @@ -703,6 +694,11 @@ static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int tw_dev->host->host_no, TW_DRIVER, 0xc, cmd); retval = TW_IOCTL_ERROR_OS_EIO; + spin_lock_irqsave(tw_dev->host->host_lock, flags); + tw_dev->state[request_id] = TW_S_COMPLETED; + twa_free_request_id(tw_dev, request_id); + tw_dev->posted_request_count--; + spin_unlock_irqrestore(tw_dev->host->host_lock, flags); twa_reset_device_extension(tw_dev, 1); goto out3; } @@ -721,7 +717,16 @@ static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int tw_ioctl->driver_command.status = 0; /* Copy compatiblity struct into ioctl data buffer */ tw_compat_info = (TW_Compatibility_Info *)tw_ioctl->data_buffer; - memcpy(tw_compat_info, &tw_dev->tw_compat_info, sizeof(TW_Compatibility_Info)); + strncpy(tw_compat_info->driver_version, TW_DRIVER_VERSION, strlen(TW_DRIVER_VERSION)); + tw_compat_info->working_srl = tw_dev->working_srl; + tw_compat_info->working_branch = tw_dev->working_branch; + tw_compat_info->working_build = tw_dev->working_build; + tw_compat_info->driver_srl_high = TW_CURRENT_DRIVER_SRL; + tw_compat_info->driver_branch_high = TW_CURRENT_DRIVER_BRANCH; + tw_compat_info->driver_build_high = TW_CURRENT_DRIVER_BUILD; + tw_compat_info->driver_srl_low = TW_BASE_FW_SRL; + tw_compat_info->driver_branch_low = TW_BASE_FW_BRANCH; + tw_compat_info->driver_build_low = TW_BASE_FW_BUILD; break; case TW_IOCTL_GET_LAST_EVENT: if (tw_dev->event_queue_wrapped) { @@ -890,8 +895,7 @@ static int twa_decode_bits(TW_Device_Extension *tw_dev, u32 status_reg_value) } if (status_reg_value & TW_STATUS_QUEUE_ERROR) { - if ((tw_dev->tw_pci_dev->device != PCI_DEVICE_ID_3WARE_9650SE) || (!test_bit(TW_IN_RESET, &tw_dev->flags))) - TW_PRINTK(tw_dev->host, TW_DRIVER, 0xe, "Controller Queue Error: clearing"); + TW_PRINTK(tw_dev->host, TW_DRIVER, 0xe, "Controller Queue Error: clearing"); writel(TW_CONTROL_CLEAR_QUEUE_ERROR, TW_CONTROL_REG_ADDR(tw_dev)); } @@ -935,12 +939,10 @@ static int twa_empty_response_queue_large(TW_Device_Extension *tw_dev) unsigned long before; int retval = 1; - if ((tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9550SX) || - (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE)) { + if (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9550SX) { before = jiffies; while ((response_que_value & TW_9550SX_DRAIN_COMPLETED) != TW_9550SX_DRAIN_COMPLETED) { response_que_value = readl(TW_RESPONSE_QUEUE_REG_ADDR_LARGE(tw_dev)); - msleep(1); if (time_after(jiffies, before + HZ * 30)) goto out; } @@ -1190,7 +1192,7 @@ static int twa_initialize_device_extension(TW_Device_Extension *tw_dev) } /* End twa_initialize_device_extension() */ /* This function is the interrupt service routine */ -static irqreturn_t twa_interrupt(int irq, void *dev_instance) +static irqreturn_t twa_interrupt(int irq, void *dev_instance, struct pt_regs *regs) { int request_id, error = 0; u32 status_reg_value; @@ -1212,10 +1214,6 @@ static irqreturn_t twa_interrupt(int irq, void *dev_instance) handled = 1; - /* If we are resetting, bail */ - if (test_bit(TW_IN_RESET, &tw_dev->flags)) - goto twa_interrupt_bail; - /* Check controller for errors */ if (twa_check_bits(status_reg_value)) { if (twa_decode_bits(tw_dev, status_reg_value)) { @@ -1357,8 +1355,8 @@ static void twa_load_sgl(TW_Command_Full *full_command_packet, int request_id, d if (TW_OP_OUT(full_command_packet->command.newcommand.opcode__reserved) == TW_OP_EXECUTE_SCSI) { newcommand = &full_command_packet->command.newcommand; - newcommand->request_id__lunl = - cpu_to_le16(TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->request_id__lunl), request_id)); + newcommand->request_id__lunl = + TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->request_id__lunl), request_id); newcommand->sg_list[0].address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1); newcommand->sg_list[0].length = cpu_to_le32(length); newcommand->sgl_entries__lunh = @@ -1533,13 +1531,6 @@ static int twa_post_command_packet(TW_Device_Extension *tw_dev, int request_id, int retval = 1; command_que_value = tw_dev->command_packet_phys[request_id]; - - /* For 9650SE write low 4 bytes first */ - if (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE) { - command_que_value += TW_COMMAND_OFFSET; - writel((u32)command_que_value, TW_COMMAND_QUEUE_REG_ADDR_LARGE(tw_dev)); - } - status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev)); if (twa_check_bits(status_reg_value)) @@ -1566,17 +1557,13 @@ static int twa_post_command_packet(TW_Device_Extension *tw_dev, int request_id, TW_UNMASK_COMMAND_INTERRUPT(tw_dev); goto out; } else { - if (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE) { - /* Now write upper 4 bytes */ - writel((u32)((u64)command_que_value >> 32), TW_COMMAND_QUEUE_REG_ADDR_LARGE(tw_dev) + 0x4); + /* We successfully posted the command packet */ + if (sizeof(dma_addr_t) > 4) { + command_que_value += TW_COMMAND_OFFSET; + writel((u32)command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev)); + writel((u32)((u64)command_que_value >> 32), TW_COMMAND_QUEUE_REG_ADDR(tw_dev) + 0x4); } else { - if (sizeof(dma_addr_t) > 4) { - command_que_value += TW_COMMAND_OFFSET; - writel((u32)command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev)); - writel((u32)((u64)command_que_value >> 32), TW_COMMAND_QUEUE_REG_ADDR(tw_dev) + 0x4); - } else { - writel(TW_COMMAND_OFFSET + command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev)); - } + writel(TW_COMMAND_OFFSET + command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev)); } tw_dev->state[request_id] = TW_S_POSTED; tw_dev->posted_request_count++; @@ -1633,9 +1620,14 @@ static int twa_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_res goto out; TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev); - clear_bit(TW_IN_RESET, &tw_dev->flags); - tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE; + /* Wake up any ioctl that was pending before the reset */ + if ((tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FREE) || (ioctl_reset)) { + clear_bit(TW_IN_RESET, &tw_dev->flags); + } else { + tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE; + wake_up(&tw_dev->ioctl_wqueue); + } retval = 0; out: return retval; @@ -1744,9 +1736,6 @@ static int twa_scsi_eh_reset(struct scsi_cmnd *SCpnt) "WARNING: (0x%02X:0x%04X): Command (0x%x) timed out, resetting card.\n", TW_DRIVER, 0x2c, SCpnt->cmnd[0]); - /* Make sure we are not issuing an ioctl or resetting from ioctl */ - mutex_lock(&tw_dev->ioctl_lock); - /* Now reset the card and some of the device extension data */ if (twa_reset_device_extension(tw_dev, 0)) { TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2b, "Controller reset failed during scsi host reset"); @@ -1755,7 +1744,6 @@ static int twa_scsi_eh_reset(struct scsi_cmnd *SCpnt) retval = SUCCESS; out: - mutex_unlock(&tw_dev->ioctl_lock); return retval; } /* End twa_scsi_eh_reset() */ @@ -1765,14 +1753,8 @@ static int twa_scsi_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd int request_id, retval; TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata; - /* If we are resetting due to timed out ioctl, report as busy */ - if (test_bit(TW_IN_RESET, &tw_dev->flags)) { - retval = SCSI_MLQUEUE_HOST_BUSY; - goto out; - } - /* Check if this FW supports luns */ - if ((SCpnt->device->lun != 0) && (tw_dev->tw_compat_info.working_srl < TW_FW_SRL_LUNS_SUPPORTED)) { + if ((SCpnt->device->lun != 0) && (tw_dev->working_srl < TW_FW_SRL_LUNS_SUPPORTED)) { SCpnt->result = (DID_BAD_TARGET << 16); done(SCpnt); retval = 0; @@ -1978,9 +1960,6 @@ static void __twa_shutdown(TW_Device_Extension *tw_dev) /* Disable interrupts */ TW_DISABLE_INTERRUPTS(tw_dev); - /* Free up the IRQ */ - free_irq(tw_dev->tw_pci_dev->irq, tw_dev); - printk(KERN_WARNING "3w-9xxx: Shutting down host %d.\n", tw_dev->host->host_no); /* Tell the card we are shutting down */ @@ -2112,25 +2091,21 @@ static int __devinit twa_probe(struct pci_dev *pdev, const struct pci_device_id /* Initialize the card */ if (twa_reset_sequence(tw_dev, 0)) - goto out_iounmap; + goto out_release_mem_region; /* Set host specific parameters */ - if (pdev->device == PCI_DEVICE_ID_3WARE_9650SE) - host->max_id = TW_MAX_UNITS_9650SE; - else - host->max_id = TW_MAX_UNITS; - + host->max_id = TW_MAX_UNITS; host->max_cmd_len = TW_MAX_CDB_LEN; /* Channels aren't supported by adapter */ - host->max_lun = TW_MAX_LUNS(tw_dev->tw_compat_info.working_srl); + host->max_lun = TW_MAX_LUNS(tw_dev->working_srl); host->max_channel = 0; /* Register the card with the kernel SCSI layer */ retval = scsi_add_host(host, &pdev->dev); if (retval) { TW_PRINTK(tw_dev->host, TW_DRIVER, 0x27, "scsi add host failed"); - goto out_iounmap; + goto out_release_mem_region; } pci_set_drvdata(pdev, host); @@ -2170,8 +2145,6 @@ static int __devinit twa_probe(struct pci_dev *pdev, const struct pci_device_id out_remove_host: scsi_remove_host(host); -out_iounmap: - iounmap(tw_dev->base_addr); out_release_mem_region: pci_release_regions(pdev); out_free_device_extension: @@ -2197,12 +2170,12 @@ static void twa_remove(struct pci_dev *pdev) twa_major = -1; } + /* Free up the IRQ */ + free_irq(tw_dev->tw_pci_dev->irq, tw_dev); + /* Shutdown the card */ __twa_shutdown(tw_dev); - /* Free IO remapping */ - iounmap(tw_dev->base_addr); - /* Free up the mem region */ pci_release_regions(pdev); @@ -2220,8 +2193,6 @@ static struct pci_device_id twa_pci_tbl[] __devinitdata = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_9550SX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_9650SE, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { } }; MODULE_DEVICE_TABLE(pci, twa_pci_tbl); @@ -2240,7 +2211,7 @@ static int __init twa_init(void) { printk(KERN_WARNING "3ware 9000 Storage Controller device driver for Linux v%s.\n", TW_DRIVER_VERSION); - return pci_register_driver(&twa_driver); + return pci_module_init(&twa_driver); } /* End twa_init() */ /* This function is called on driver exit */ diff --git a/trunk/drivers/scsi/3w-9xxx.h b/trunk/drivers/scsi/3w-9xxx.h index 7901517d4513..e5685be96f45 100644 --- a/trunk/drivers/scsi/3w-9xxx.h +++ b/trunk/drivers/scsi/3w-9xxx.h @@ -289,6 +289,7 @@ static twa_message_type twa_error_table[] = { #define TW_STATUS_VALID_INTERRUPT 0x00DF0000 /* PCI related defines */ +#define TW_NUMDEVICES 1 #define TW_PCI_CLEAR_PARITY_ERRORS 0xc100 #define TW_PCI_CLEAR_PCI_ABORT 0x2000 @@ -334,7 +335,6 @@ static twa_message_type twa_error_table[] = { #define TW_ALIGNMENT_9000 4 /* 4 bytes */ #define TW_ALIGNMENT_9000_SGL 0x3 #define TW_MAX_UNITS 16 -#define TW_MAX_UNITS_9650SE 32 #define TW_INIT_MESSAGE_CREDITS 0x100 #define TW_INIT_COMMAND_PACKET_SIZE 0x3 #define TW_INIT_COMMAND_PACKET_SIZE_EXTENDED 0x6 @@ -354,6 +354,7 @@ static twa_message_type twa_error_table[] = { #define TW_MAX_RESPONSE_DRAIN 256 #define TW_MAX_AEN_DRAIN 40 #define TW_IN_RESET 2 +#define TW_IN_CHRDEV_IOCTL 3 #define TW_IN_ATTENTION_LOOP 4 #define TW_MAX_SECTORS 256 #define TW_AEN_WAIT_TIME 1000 @@ -416,9 +417,6 @@ static twa_message_type twa_error_table[] = { #ifndef PCI_DEVICE_ID_3WARE_9550SX #define PCI_DEVICE_ID_3WARE_9550SX 0x1003 #endif -#ifndef PCI_DEVICE_ID_3WARE_9650SE -#define PCI_DEVICE_ID_3WARE_9650SE 0x1004 -#endif /* Bitmask macros to eliminate bitfields */ @@ -444,7 +442,6 @@ static twa_message_type twa_error_table[] = { #define TW_CONTROL_REG_ADDR(x) (x->base_addr) #define TW_STATUS_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + 0x4) #define TW_COMMAND_QUEUE_REG_ADDR(x) (sizeof(dma_addr_t) > 4 ? ((unsigned char __iomem *)x->base_addr + 0x20) : ((unsigned char __iomem *)x->base_addr + 0x8)) -#define TW_COMMAND_QUEUE_REG_ADDR_LARGE(x) ((unsigned char __iomem *)x->base_addr + 0x20) #define TW_RESPONSE_QUEUE_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + 0xC) #define TW_RESPONSE_QUEUE_REG_ADDR_LARGE(x) ((unsigned char __iomem *)x->base_addr + 0x30) #define TW_CLEAR_ALL_INTERRUPTS(x) (writel(TW_STATUS_VALID_INTERRUPT, TW_CONTROL_REG_ADDR(x))) @@ -629,9 +626,6 @@ typedef struct TAG_TW_Compatibility_Info unsigned short driver_srl_low; unsigned short driver_branch_low; unsigned short driver_build_low; - unsigned short fw_on_ctlr_srl; - unsigned short fw_on_ctlr_branch; - unsigned short fw_on_ctlr_build; } TW_Compatibility_Info; #pragma pack() @@ -674,7 +668,9 @@ typedef struct TAG_TW_Device_Extension { wait_queue_head_t ioctl_wqueue; struct mutex ioctl_lock; char aen_clobber; - TW_Compatibility_Info tw_compat_info; + unsigned short working_srl; + unsigned short working_branch; + unsigned short working_build; } TW_Device_Extension; #endif /* _3W_9XXX_H */ diff --git a/trunk/drivers/scsi/3w-xxxx.c b/trunk/drivers/scsi/3w-xxxx.c index 99a259c5a0c0..f3a5f422a8e4 100644 --- a/trunk/drivers/scsi/3w-xxxx.c +++ b/trunk/drivers/scsi/3w-xxxx.c @@ -2078,7 +2078,8 @@ static int tw_scsi_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd } /* End tw_scsi_queue() */ /* This function is the interrupt service routine */ -static irqreturn_t tw_interrupt(int irq, void *dev_instance) +static irqreturn_t tw_interrupt(int irq, void *dev_instance, + struct pt_regs *regs) { int request_id; u32 status_reg_value; @@ -2485,7 +2486,7 @@ static int __init tw_init(void) { printk(KERN_WARNING "3ware Storage Controller device driver for Linux v%s.\n", TW_DRIVER_VERSION); - return pci_register_driver(&tw_driver); + return pci_module_init(&tw_driver); } /* End tw_init() */ /* This function is called on driver exit */ diff --git a/trunk/drivers/scsi/3w-xxxx.h b/trunk/drivers/scsi/3w-xxxx.h index bbd654a2b9b1..31fe5ea15920 100644 --- a/trunk/drivers/scsi/3w-xxxx.h +++ b/trunk/drivers/scsi/3w-xxxx.h @@ -74,7 +74,7 @@ static char *tw_aen_string[] = { [0x00D] = "ERROR: Logical unit deleted: Unit #", [0x00F] = "WARNING: SMART threshold exceeded: Port #", [0x021] = "WARNING: ATA UDMA downgrade: Port #", - [0x022] = "WARNING: ATA UDMA upgrade: Port #", + [0x021] = "WARNING: ATA UDMA upgrade: Port #", [0x023] = "WARNING: Sector repair occurred: Port #", [0x024] = "ERROR: SBUF integrity check failure", [0x025] = "ERROR: Lost cached write: Port #", diff --git a/trunk/drivers/scsi/53c700.c b/trunk/drivers/scsi/53c700.c index 562432d017b0..15ce40a7053a 100644 --- a/trunk/drivers/scsi/53c700.c +++ b/trunk/drivers/scsi/53c700.c @@ -1462,7 +1462,7 @@ NCR_700_start_command(struct scsi_cmnd *SCp) } irqreturn_t -NCR_700_intr(int irq, void *dev_id) +NCR_700_intr(int irq, void *dev_id, struct pt_regs *regs) { struct Scsi_Host *host = (struct Scsi_Host *)dev_id; struct NCR_700_Host_Parameters *hostdata = diff --git a/trunk/drivers/scsi/53c700.h b/trunk/drivers/scsi/53c700.h index f5c3caf344a7..97ebe71b701b 100644 --- a/trunk/drivers/scsi/53c700.h +++ b/trunk/drivers/scsi/53c700.h @@ -57,7 +57,7 @@ struct NCR_700_Host_Parameters; struct Scsi_Host *NCR_700_detect(struct scsi_host_template *, struct NCR_700_Host_Parameters *, struct device *); int NCR_700_release(struct Scsi_Host *host); -irqreturn_t NCR_700_intr(int, void *); +irqreturn_t NCR_700_intr(int, void *, struct pt_regs *); enum NCR_700_Host_State { diff --git a/trunk/drivers/scsi/53c7xx.c b/trunk/drivers/scsi/53c7xx.c index 640536ef77dc..acf292736b4e 100644 --- a/trunk/drivers/scsi/53c7xx.c +++ b/trunk/drivers/scsi/53c7xx.c @@ -323,7 +323,7 @@ static int shutdown (struct Scsi_Host *host); static void abnormal_finished (struct NCR53c7x0_cmd *cmd, int result); static int disable (struct Scsi_Host *host); static int NCR53c7xx_run_tests (struct Scsi_Host *host); -static irqreturn_t NCR53c7x0_intr(int irq, void *dev_id); +static irqreturn_t NCR53c7x0_intr(int irq, void *dev_id, struct pt_regs * regs); static void NCR53c7x0_intfly (struct Scsi_Host *host); static int ncr_halt (struct Scsi_Host *host); static void intr_phase_mismatch (struct Scsi_Host *host, struct NCR53c7x0_cmd @@ -4227,7 +4227,7 @@ NCR53c7x0_intfly (struct Scsi_Host *host) } /* - * Function : static irqreturn_t NCR53c7x0_intr (int irq, void *dev_id) + * Function : static irqreturn_t NCR53c7x0_intr (int irq, void *dev_id, struct pt_regs * regs) * * Purpose : handle NCR53c7x0 interrupts for all NCR devices sharing * the same IRQ line. @@ -4241,7 +4241,7 @@ NCR53c7x0_intfly (struct Scsi_Host *host) */ static irqreturn_t -NCR53c7x0_intr (int irq, void *dev_id) +NCR53c7x0_intr (int irq, void *dev_id, struct pt_regs * regs) { NCR53c7x0_local_declare(); struct Scsi_Host *host; /* Host we are looking at */ diff --git a/trunk/drivers/scsi/BusLogic.c b/trunk/drivers/scsi/BusLogic.c index cdd033724786..4ea49fd7965e 100644 --- a/trunk/drivers/scsi/BusLogic.c +++ b/trunk/drivers/scsi/BusLogic.c @@ -2653,7 +2653,7 @@ static void BusLogic_ProcessCompletedCCBs(struct BusLogic_HostAdapter *HostAdapt Adapters. */ -static irqreturn_t BusLogic_InterruptHandler(int IRQ_Channel, void *DeviceIdentifier) +static irqreturn_t BusLogic_InterruptHandler(int IRQ_Channel, void *DeviceIdentifier, struct pt_regs *InterruptRegisters) { struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) DeviceIdentifier; unsigned long ProcessorFlags; @@ -3600,16 +3600,5 @@ static void __exit BusLogic_exit(void) __setup("BusLogic=", BusLogic_Setup); -static struct pci_device_id BusLogic_pci_tbl[] __devinitdata = { - { PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { } -}; -MODULE_DEVICE_TABLE(pci, BusLogic_pci_tbl); - module_init(BusLogic_init); module_exit(BusLogic_exit); diff --git a/trunk/drivers/scsi/BusLogic.h b/trunk/drivers/scsi/BusLogic.h index cca6d45eee4d..d6d1d5613c8a 100644 --- a/trunk/drivers/scsi/BusLogic.h +++ b/trunk/drivers/scsi/BusLogic.h @@ -1347,7 +1347,7 @@ static int BusLogic_BIOSDiskParameters(struct scsi_device *, struct block_device static int BusLogic_ProcDirectoryInfo(struct Scsi_Host *, char *, char **, off_t, int, int); static int BusLogic_SlaveConfigure(struct scsi_device *); static void BusLogic_QueueCompletedCCB(struct BusLogic_CCB *); -static irqreturn_t BusLogic_InterruptHandler(int, void *); +static irqreturn_t BusLogic_InterruptHandler(int, void *, struct pt_regs *); static int BusLogic_ResetHostAdapter(struct BusLogic_HostAdapter *, boolean HardReset); static void BusLogic_Message(enum BusLogic_MessageLevel, char *, struct BusLogic_HostAdapter *, ...); static int __init BusLogic_Setup(char *); diff --git a/trunk/drivers/scsi/Kconfig b/trunk/drivers/scsi/Kconfig index 9540eb8efdcb..c6dfb6fa13bf 100644 --- a/trunk/drivers/scsi/Kconfig +++ b/trunk/drivers/scsi/Kconfig @@ -1016,7 +1016,7 @@ config SCSI_SYM53C8XX_MMIO config SCSI_IPR tristate "IBM Power Linux RAID adapter support" - depends on PCI && SCSI && ATA + depends on PCI && SCSI select FW_LOADER ---help--- This driver supports the IBM Power Linux family RAID adapters. @@ -1246,7 +1246,6 @@ config SCSI_QLOGICPTI module will be called qlogicpti. source "drivers/scsi/qla2xxx/Kconfig" -source "drivers/scsi/qla4xxx/Kconfig" config SCSI_LPFC tristate "Emulex LightPulse Fibre Channel Support" @@ -1263,8 +1262,8 @@ config SCSI_SEAGATE These are 8-bit SCSI controllers; the ST-01 is also supported by this driver. It is explained in section 3.9 of the SCSI-HOWTO, available from . If it - doesn't work out of the box, you may have to change some macros at - compiletime, which are described in . + doesn't work out of the box, you may have to change some settings in + . To compile this driver as a module, choose M here: the module will be called seagate. diff --git a/trunk/drivers/scsi/Makefile b/trunk/drivers/scsi/Makefile index bcca39c3bcbf..1ef951be7a5d 100644 --- a/trunk/drivers/scsi/Makefile +++ b/trunk/drivers/scsi/Makefile @@ -84,7 +84,6 @@ obj-$(CONFIG_SCSI_QLOGIC_FAS) += qlogicfas408.o qlogicfas.o obj-$(CONFIG_PCMCIA_QLOGIC) += qlogicfas408.o obj-$(CONFIG_SCSI_QLOGIC_1280) += qla1280.o obj-$(CONFIG_SCSI_QLA_FC) += qla2xxx/ -obj-$(CONFIG_SCSI_QLA_ISCSI) += qla4xxx/ obj-$(CONFIG_SCSI_LPFC) += lpfc/ obj-$(CONFIG_SCSI_PAS16) += pas16.o obj-$(CONFIG_SCSI_SEAGATE) += seagate.o diff --git a/trunk/drivers/scsi/NCR5380.c b/trunk/drivers/scsi/NCR5380.c index a6aa91072880..616810ad17d8 100644 --- a/trunk/drivers/scsi/NCR5380.c +++ b/trunk/drivers/scsi/NCR5380.c @@ -558,7 +558,8 @@ static int probe_irq __initdata = 0; * used by the IRQ probe code. */ -static irqreturn_t __init probe_intr(int irq, void *dev_id) +static irqreturn_t __init probe_intr(int irq, void *dev_id, + struct pt_regs *regs) { probe_irq = irq; return IRQ_HANDLED; @@ -1147,6 +1148,7 @@ static void NCR5380_main(void *p) * NCR5380_intr - generic NCR5380 irq handler * @irq: interrupt number * @dev_id: device info + * @regs: registers (unused) * * Handle interrupts, reestablishing I_T_L or I_T_L_Q nexuses * from the disconnected queue, and restarting NCR5380_main() @@ -1155,7 +1157,7 @@ static void NCR5380_main(void *p) * Locks: takes the needed instance locks */ -static irqreturn_t NCR5380_intr(int irq, void *dev_id) +static irqreturn_t NCR5380_intr(int irq, void *dev_id, struct pt_regs *regs) { NCR5380_local_declare(); struct Scsi_Host *instance = (struct Scsi_Host *)dev_id; diff --git a/trunk/drivers/scsi/NCR5380.h b/trunk/drivers/scsi/NCR5380.h index 1bc73de496b0..c3462e358d1c 100644 --- a/trunk/drivers/scsi/NCR5380.h +++ b/trunk/drivers/scsi/NCR5380.h @@ -296,7 +296,7 @@ static int NCR5380_init(struct Scsi_Host *instance, int flags); static void NCR5380_exit(struct Scsi_Host *instance); static void NCR5380_information_transfer(struct Scsi_Host *instance); #ifndef DONT_USE_INTR -static irqreturn_t NCR5380_intr(int irq, void *dev_id); +static irqreturn_t NCR5380_intr(int irq, void *dev_id, struct pt_regs *regs); #endif static void NCR5380_main(void *ptr); static void NCR5380_print_options(struct Scsi_Host *instance); diff --git a/trunk/drivers/scsi/NCR53C9x.c b/trunk/drivers/scsi/NCR53C9x.c index 3c912ee29da0..bdc6bb262bce 100644 --- a/trunk/drivers/scsi/NCR53C9x.c +++ b/trunk/drivers/scsi/NCR53C9x.c @@ -96,7 +96,7 @@ enum { static struct NCR_ESP *espchain; int nesps = 0, esps_in_use = 0, esps_running = 0; -irqreturn_t esp_intr(int irq, void *dev_id); +irqreturn_t esp_intr(int irq, void *dev_id, struct pt_regs *pregs); /* Debugging routines */ static struct esp_cmdstrings { @@ -3533,7 +3533,7 @@ void esp_handle(struct NCR_ESP *esp) } #ifndef CONFIG_SMP -irqreturn_t esp_intr(int irq, void *dev_id) +irqreturn_t esp_intr(int irq, void *dev_id, struct pt_regs *pregs) { struct NCR_ESP *esp; unsigned long flags; @@ -3570,7 +3570,7 @@ irqreturn_t esp_intr(int irq, void *dev_id) } #else /* For SMP we only service one ESP on the list list at our IRQ level! */ -irqreturn_t esp_intr(int irq, void *dev_id) +irqreturn_t esp_intr(int irq, void *dev_id, struct pt_regs *pregs) { struct NCR_ESP *esp; unsigned long flags; diff --git a/trunk/drivers/scsi/NCR53C9x.h b/trunk/drivers/scsi/NCR53C9x.h index 521e3f842cfd..481653c977cf 100644 --- a/trunk/drivers/scsi/NCR53C9x.h +++ b/trunk/drivers/scsi/NCR53C9x.h @@ -656,7 +656,7 @@ extern struct NCR_ESP *esp_allocate(struct scsi_host_template *, void *); extern void esp_deallocate(struct NCR_ESP *); extern void esp_release(void); extern void esp_initialize(struct NCR_ESP *); -extern irqreturn_t esp_intr(int, void *); +extern irqreturn_t esp_intr(int, void *, struct pt_regs *); extern const char *esp_info(struct Scsi_Host *); extern int esp_queue(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); extern int esp_abort(Scsi_Cmnd *); diff --git a/trunk/drivers/scsi/NCR53c406a.c b/trunk/drivers/scsi/NCR53c406a.c index d4613815f685..8472c5359023 100644 --- a/trunk/drivers/scsi/NCR53c406a.c +++ b/trunk/drivers/scsi/NCR53c406a.c @@ -168,8 +168,8 @@ enum Phase { }; /* Static function prototypes */ -static void NCR53c406a_intr(void *); -static irqreturn_t do_NCR53c406a_intr(int, void *); +static void NCR53c406a_intr(int, void *, struct pt_regs *); +static irqreturn_t do_NCR53c406a_intr(int, void *, struct pt_regs *); static void chip_init(void); static void calc_port_addr(void); #ifndef IRQ_LEV @@ -685,7 +685,7 @@ static void wait_intr(void) return; } - NCR53c406a_intr(NULL); + NCR53c406a_intr(0, NULL, NULL); } #endif @@ -761,18 +761,19 @@ static int NCR53c406a_biosparm(struct scsi_device *disk, return 0; } -static irqreturn_t do_NCR53c406a_intr(int unused, void *dev_id) +static irqreturn_t do_NCR53c406a_intr(int unused, void *dev_id, + struct pt_regs *regs) { unsigned long flags; struct Scsi_Host *dev = dev_id; spin_lock_irqsave(dev->host_lock, flags); - NCR53c406a_intr(dev_id); + NCR53c406a_intr(0, dev_id, regs); spin_unlock_irqrestore(dev->host_lock, flags); return IRQ_HANDLED; } -static void NCR53c406a_intr(void *dev_id) +static void NCR53c406a_intr(int unused, void *dev_id, struct pt_regs *regs) { DEB(unsigned char fifo_size; ) diff --git a/trunk/drivers/scsi/NCR_D700.c b/trunk/drivers/scsi/NCR_D700.c index 9859cd17fc57..d05681f9d81a 100644 --- a/trunk/drivers/scsi/NCR_D700.c +++ b/trunk/drivers/scsi/NCR_D700.c @@ -226,14 +226,14 @@ NCR_D700_probe_one(struct NCR_D700_private *p, int siop, int irq, } static int -NCR_D700_intr(int irq, void *data) +NCR_D700_intr(int irq, void *data, struct pt_regs *regs) { struct NCR_D700_private *p = (struct NCR_D700_private *)data; int i, found = 0; for (i = 0; i < 2; i++) if (p->hosts[i] && - NCR_700_intr(irq, p->hosts[i]) == IRQ_HANDLED) + NCR_700_intr(irq, p->hosts[i], regs) == IRQ_HANDLED) found++; return found ? IRQ_HANDLED : IRQ_NONE; diff --git a/trunk/drivers/scsi/NCR_Q720.c b/trunk/drivers/scsi/NCR_Q720.c index 778844c3544a..c39ffbb86e39 100644 --- a/trunk/drivers/scsi/NCR_Q720.c +++ b/trunk/drivers/scsi/NCR_Q720.c @@ -54,7 +54,7 @@ static struct scsi_host_template NCR_Q720_tpnt = { }; static irqreturn_t -NCR_Q720_intr(int irq, void *data) +NCR_Q720_intr(int irq, void *data, struct pt_regs * regs) { struct NCR_Q720_private *p = (struct NCR_Q720_private *)data; __u8 sir = (readb(p->mem_base + 0x0d) & 0xf0) >> 4; @@ -68,7 +68,7 @@ NCR_Q720_intr(int irq, void *data) while((siop = ffz(sir)) < p->siops) { sir |= 1<hosts[siop]); + ncr53c8xx_intr(irq, p->hosts[siop], regs); } return IRQ_HANDLED; } diff --git a/trunk/drivers/scsi/a100u2w.c b/trunk/drivers/scsi/a100u2w.c index 2650a5d0a161..d7e9fab54c60 100644 --- a/trunk/drivers/scsi/a100u2w.c +++ b/trunk/drivers/scsi/a100u2w.c @@ -1013,7 +1013,7 @@ static void inia100SCBPost(BYTE * pHcb, BYTE * pScb) /* * Interrupt handler (main routine of the driver) */ -static irqreturn_t inia100_intr(int irqno, void *devid) +static irqreturn_t inia100_intr(int irqno, void *devid, struct pt_regs *regs) { struct Scsi_Host *host = (struct Scsi_Host *)devid; ORC_HCS *pHcb = (ORC_HCS *)host->hostdata; @@ -1187,7 +1187,7 @@ static struct pci_driver inia100_pci_driver = { static int __init inia100_init(void) { - return pci_register_driver(&inia100_pci_driver); + return pci_module_init(&inia100_pci_driver); } static void __exit inia100_exit(void) diff --git a/trunk/drivers/scsi/a2091.c b/trunk/drivers/scsi/a2091.c index f77016d31cab..085406928605 100644 --- a/trunk/drivers/scsi/a2091.c +++ b/trunk/drivers/scsi/a2091.c @@ -24,7 +24,7 @@ #define DMA(ptr) ((a2091_scsiregs *)((ptr)->base)) #define HDATA(ptr) ((struct WD33C93_hostdata *)((ptr)->hostdata)) -static irqreturn_t a2091_intr (int irq, void *_instance) +static irqreturn_t a2091_intr (int irq, void *_instance, struct pt_regs *fp) { unsigned long flags; unsigned int status; diff --git a/trunk/drivers/scsi/a3000.c b/trunk/drivers/scsi/a3000.c index 1299bc8edef1..7bf46d40b561 100644 --- a/trunk/drivers/scsi/a3000.c +++ b/trunk/drivers/scsi/a3000.c @@ -26,7 +26,7 @@ static struct Scsi_Host *a3000_host = NULL; -static irqreturn_t a3000_intr (int irq, void *dummy) +static irqreturn_t a3000_intr (int irq, void *dummy, struct pt_regs *fp) { unsigned long flags; unsigned int status = DMA(a3000_host)->ISTR; diff --git a/trunk/drivers/scsi/aacraid/rx.c b/trunk/drivers/scsi/aacraid/rx.c index dcc8b0ea7a9d..a1d214d770eb 100644 --- a/trunk/drivers/scsi/aacraid/rx.c +++ b/trunk/drivers/scsi/aacraid/rx.c @@ -46,11 +46,11 @@ #include "aacraid.h" -static irqreturn_t aac_rx_intr(int irq, void *dev_id) +static irqreturn_t aac_rx_intr(int irq, void *dev_id, struct pt_regs *regs) { struct aac_dev *dev = dev_id; - dprintk((KERN_DEBUG "aac_rx_intr(%d,%p)\n", irq, dev_id)); + dprintk((KERN_DEBUG "aac_rx_intr(%d,%p,%p)\n", irq, dev_id, regs)); if (dev->new_comm_interface) { u32 Index = rx_readl(dev, MUnit.OutboundQueue); if (Index == 0xFFFFFFFFL) diff --git a/trunk/drivers/scsi/aacraid/sa.c b/trunk/drivers/scsi/aacraid/sa.c index 511b0a938fb1..f906ead239dd 100644 --- a/trunk/drivers/scsi/aacraid/sa.c +++ b/trunk/drivers/scsi/aacraid/sa.c @@ -46,7 +46,7 @@ #include "aacraid.h" -static irqreturn_t aac_sa_intr(int irq, void *dev_id) +static irqreturn_t aac_sa_intr(int irq, void *dev_id, struct pt_regs *regs) { struct aac_dev *dev = dev_id; unsigned short intstat, mask; diff --git a/trunk/drivers/scsi/advansys.c b/trunk/drivers/scsi/advansys.c index 2b344356a29e..773f02e3b10b 100644 --- a/trunk/drivers/scsi/advansys.c +++ b/trunk/drivers/scsi/advansys.c @@ -3881,7 +3881,7 @@ typedef struct asc_board { /* * The following fields are used only for Wide Boards. */ - void __iomem *ioremap_addr; /* I/O Memory remap address. */ + void *ioremap_addr; /* I/O Memory remap address. */ ushort ioport; /* I/O Port address. */ ADV_CARR_T *orig_carrp; /* ADV_CARR_T memory block. */ adv_req_t *orig_reqp; /* adv_req_t memory block. */ @@ -3951,7 +3951,7 @@ typedef struct _PCI_CONFIG_SPACE_ /* Number of boards detected in system. */ STATIC int asc_board_count = 0; -STATIC struct Scsi_Host *asc_host[ASC_NUM_BOARD_SUPPORTED] = { NULL }; +STATIC struct Scsi_Host *asc_host[ASC_NUM_BOARD_SUPPORTED] = { 0 }; /* Overrun buffer used by all narrow boards. */ STATIC uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 }; @@ -3999,7 +3999,7 @@ STATIC PortAddr _asc_def_iop_base[]; * advansys.h contains function prototypes for functions global to Linux. */ -STATIC irqreturn_t advansys_interrupt(int, void *); +STATIC irqreturn_t advansys_interrupt(int, void *, struct pt_regs *); STATIC int advansys_slave_configure(struct scsi_device *); STATIC void asc_scsi_done_list(struct scsi_cmnd *); STATIC int asc_execute_scsi_cmnd(struct scsi_cmnd *); @@ -5997,7 +5997,7 @@ static struct scsi_host_template driver_template = { * an AdvanSys adapter. */ STATIC irqreturn_t -advansys_interrupt(int irq, void *dev_id) +advansys_interrupt(int irq, void *dev_id, struct pt_regs *regs) { ulong flags; int i; @@ -6621,7 +6621,7 @@ adv_build_req(asc_board_t *boardp, struct scsi_cmnd *scp, dma_map_single(dev, scp->request_buffer, scp->request_bufflen, scp->sc_data_direction); } else { - scsiqp->vdata_addr = NULL; + scsiqp->vdata_addr = 0; scp->SCp.dma_handle = 0; } scsiqp->data_addr = cpu_to_le32(scp->SCp.dma_handle); diff --git a/trunk/drivers/scsi/aha152x.c b/trunk/drivers/scsi/aha152x.c index 306f46b85a55..fb6a476eb873 100644 --- a/trunk/drivers/scsi/aha152x.c +++ b/trunk/drivers/scsi/aha152x.c @@ -238,7 +238,7 @@ #include #include #include -#include +#include #include #include #include @@ -673,7 +673,7 @@ static struct { }; /* setup & interrupt */ -static irqreturn_t intr(int irq, void *dev_id); +static irqreturn_t intr(int irq, void *dev_id, struct pt_regs *); static void reset_ports(struct Scsi_Host *shpnt); static void aha152x_error(struct Scsi_Host *shpnt, char *msg); static void done(struct Scsi_Host *shpnt, int error); @@ -757,9 +757,14 @@ static inline Scsi_Cmnd *remove_SC(Scsi_Cmnd **SC, Scsi_Cmnd *SCp) return ptr; } -static irqreturn_t swintr(int irqno, void *dev_id) +static irqreturn_t swintr(int irqno, void *dev_id, struct pt_regs *regs) { - struct Scsi_Host *shpnt = dev_id; + struct Scsi_Host *shpnt = (struct Scsi_Host *)dev_id; + + if (!shpnt) { + printk(KERN_ERR "aha152x: catched software interrupt %d for unknown controller.\n", irqno); + return IRQ_NONE; + } HOSTDATA(shpnt)->swint++; @@ -1458,7 +1463,7 @@ static void run(void) * Interrupt handler * */ -static irqreturn_t intr(int irqno, void *dev_id) +static irqreturn_t intr(int irqno, void *dev_id, struct pt_regs *regs) { struct Scsi_Host *shpnt = (struct Scsi_Host *)dev_id; unsigned long flags; diff --git a/trunk/drivers/scsi/aha1542.c b/trunk/drivers/scsi/aha1542.c index d7a61a6bdaae..24f0f5461792 100644 --- a/trunk/drivers/scsi/aha1542.c +++ b/trunk/drivers/scsi/aha1542.c @@ -174,8 +174,9 @@ static DEFINE_SPINLOCK(aha1542_lock); static void setup_mailboxes(int base_io, struct Scsi_Host *shpnt); static int aha1542_restart(struct Scsi_Host *shost); -static void aha1542_intr_handle(struct Scsi_Host *shost, void *dev_id); -static irqreturn_t do_aha1542_intr_handle(int irq, void *dev_id); +static void aha1542_intr_handle(struct Scsi_Host *shost, void *dev_id, struct pt_regs *regs); +static irqreturn_t do_aha1542_intr_handle(int irq, void *dev_id, + struct pt_regs *regs); #define aha1542_intr_reset(base) outb(IRST, CONTROL(base)) @@ -415,7 +416,8 @@ static int __init aha1542_test_port(int bse, struct Scsi_Host *shpnt) } /* A quick wrapper for do_aha1542_intr_handle to grab the spin lock */ -static irqreturn_t do_aha1542_intr_handle(int irq, void *dev_id) +static irqreturn_t do_aha1542_intr_handle(int irq, void *dev_id, + struct pt_regs *regs) { unsigned long flags; struct Scsi_Host *shost; @@ -425,13 +427,13 @@ static irqreturn_t do_aha1542_intr_handle(int irq, void *dev_id) panic("Splunge!"); spin_lock_irqsave(shost->host_lock, flags); - aha1542_intr_handle(shost, dev_id); + aha1542_intr_handle(shost, dev_id, regs); spin_unlock_irqrestore(shost->host_lock, flags); return IRQ_HANDLED; } /* A "high" level interrupt handler */ -static void aha1542_intr_handle(struct Scsi_Host *shost, void *dev_id) +static void aha1542_intr_handle(struct Scsi_Host *shost, void *dev_id, struct pt_regs *regs) { void (*my_done) (Scsi_Cmnd *) = NULL; int errstatus, mbi, mbo, mbistatus; diff --git a/trunk/drivers/scsi/aha1740.c b/trunk/drivers/scsi/aha1740.c index c3c38a7e8d32..6b35ed8301e0 100644 --- a/trunk/drivers/scsi/aha1740.c +++ b/trunk/drivers/scsi/aha1740.c @@ -223,7 +223,8 @@ static int aha1740_test_port(unsigned int base) } /* A "high" level interrupt handler */ -static irqreturn_t aha1740_intr_handle(int irq, void *dev_id) +static irqreturn_t aha1740_intr_handle(int irq, void *dev_id, + struct pt_regs *regs) { struct Scsi_Host *host = (struct Scsi_Host *) dev_id; void (*my_done)(Scsi_Cmnd *); diff --git a/trunk/drivers/scsi/aic7xxx/aic79xx.h b/trunk/drivers/scsi/aic7xxx/aic79xx.h index 170a4344cbb2..df3346b5caf8 100644 --- a/trunk/drivers/scsi/aic7xxx/aic79xx.h +++ b/trunk/drivers/scsi/aic7xxx/aic79xx.h @@ -53,6 +53,14 @@ struct ahd_platform_data; struct scb_platform_data; /****************************** Useful Macros *********************************/ +#ifndef MAX +#define MAX(a,b) (((a) > (b)) ? (a) : (b)) +#endif + +#ifndef MIN +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) +#endif + #ifndef TRUE #define TRUE 1 #endif @@ -964,6 +972,8 @@ int ahd_read_seeprom(struct ahd_softc *ahd, uint16_t *buf, int ahd_write_seeprom(struct ahd_softc *ahd, uint16_t *buf, u_int start_addr, u_int count); +int ahd_wait_seeprom(struct ahd_softc *ahd); +int ahd_verify_vpd_cksum(struct vpd_config *vpd); int ahd_verify_cksum(struct seeprom_config *sc); int ahd_acquire_seeprom(struct ahd_softc *ahd); void ahd_release_seeprom(struct ahd_softc *ahd); @@ -1310,6 +1320,8 @@ struct ahd_pci_identity { char *name; ahd_device_setup_t *setup; }; +extern struct ahd_pci_identity ahd_pci_ident_table []; +extern const u_int ahd_num_pci_devs; /***************************** VL/EISA Declarations ***************************/ struct aic7770_identity { @@ -1327,6 +1339,15 @@ extern const int ahd_num_aic7770_devs; /*************************** Function Declarations ****************************/ /******************************************************************************/ void ahd_reset_cmds_pending(struct ahd_softc *ahd); +u_int ahd_find_busy_tcl(struct ahd_softc *ahd, u_int tcl); +void ahd_busy_tcl(struct ahd_softc *ahd, + u_int tcl, u_int busyid); +static __inline void ahd_unbusy_tcl(struct ahd_softc *ahd, u_int tcl); +static __inline void +ahd_unbusy_tcl(struct ahd_softc *ahd, u_int tcl) +{ + ahd_busy_tcl(ahd, tcl, SCB_LIST_NULL); +} /***************************** PCI Front End *********************************/ struct ahd_pci_identity *ahd_find_pci_device(ahd_dev_softc_t); @@ -1335,6 +1356,7 @@ int ahd_pci_config(struct ahd_softc *, int ahd_pci_test_register_access(struct ahd_softc *); /************************** SCB and SCB queue management **********************/ +int ahd_probe_scbs(struct ahd_softc *); void ahd_qinfifo_requeue_tail(struct ahd_softc *ahd, struct scb *scb); int ahd_match_scb(struct ahd_softc *ahd, struct scb *scb, @@ -1352,20 +1374,33 @@ int ahd_parse_vpddata(struct ahd_softc *ahd, int ahd_parse_cfgdata(struct ahd_softc *ahd, struct seeprom_config *sc); void ahd_intr_enable(struct ahd_softc *ahd, int enable); +void ahd_update_coalescing_values(struct ahd_softc *ahd, + u_int timer, + u_int maxcmds, + u_int mincmds); +void ahd_enable_coalescing(struct ahd_softc *ahd, + int enable); void ahd_pause_and_flushwork(struct ahd_softc *ahd); int ahd_suspend(struct ahd_softc *ahd); +int ahd_resume(struct ahd_softc *ahd); void ahd_set_unit(struct ahd_softc *, int); void ahd_set_name(struct ahd_softc *, char *); struct scb *ahd_get_scb(struct ahd_softc *ahd, u_int col_idx); void ahd_free_scb(struct ahd_softc *ahd, struct scb *scb); +void ahd_alloc_scbs(struct ahd_softc *ahd); void ahd_free(struct ahd_softc *ahd); int ahd_reset(struct ahd_softc *ahd, int reinit); +void ahd_shutdown(void *arg); int ahd_write_flexport(struct ahd_softc *ahd, u_int addr, u_int value); int ahd_read_flexport(struct ahd_softc *ahd, u_int addr, uint8_t *value); +int ahd_wait_flexport(struct ahd_softc *ahd); /*************************** Interrupt Services *******************************/ +void ahd_pci_intr(struct ahd_softc *ahd); +void ahd_clear_intstat(struct ahd_softc *ahd); +void ahd_flush_qoutfifo(struct ahd_softc *ahd); void ahd_run_qoutfifo(struct ahd_softc *ahd); #ifdef AHD_TARGET_MODE void ahd_run_tqinfifo(struct ahd_softc *ahd, int paused); @@ -1374,6 +1409,7 @@ void ahd_handle_hwerrint(struct ahd_softc *ahd); void ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat); void ahd_handle_scsiint(struct ahd_softc *ahd, u_int intstat); +void ahd_clear_critical_section(struct ahd_softc *ahd); /***************************** Error Recovery *********************************/ typedef enum { @@ -1390,9 +1426,23 @@ int ahd_search_disc_list(struct ahd_softc *ahd, int target, char channel, int lun, u_int tag, int stop_on_first, int remove, int save_state); +void ahd_freeze_devq(struct ahd_softc *ahd, struct scb *scb); int ahd_reset_channel(struct ahd_softc *ahd, char channel, int initiate_reset); +int ahd_abort_scbs(struct ahd_softc *ahd, int target, + char channel, int lun, u_int tag, + role_t role, uint32_t status); +void ahd_restart(struct ahd_softc *ahd); +void ahd_clear_fifo(struct ahd_softc *ahd, u_int fifo); +void ahd_handle_scb_status(struct ahd_softc *ahd, + struct scb *scb); +void ahd_handle_scsi_status(struct ahd_softc *ahd, + struct scb *scb); +void ahd_calc_residual(struct ahd_softc *ahd, + struct scb *scb); /*************************** Utility Functions ********************************/ +struct ahd_phase_table_entry* + ahd_lookup_phase_entry(int phase); void ahd_compile_devinfo(struct ahd_devinfo *devinfo, u_int our_id, u_int target, u_int lun, char channel, @@ -1400,6 +1450,14 @@ void ahd_compile_devinfo(struct ahd_devinfo *devinfo, /************************** Transfer Negotiation ******************************/ void ahd_find_syncrate(struct ahd_softc *ahd, u_int *period, u_int *ppr_options, u_int maxsync); +void ahd_validate_offset(struct ahd_softc *ahd, + struct ahd_initiator_tinfo *tinfo, + u_int period, u_int *offset, + int wide, role_t role); +void ahd_validate_width(struct ahd_softc *ahd, + struct ahd_initiator_tinfo *tinfo, + u_int *bus_width, + role_t role); /* * Negotiation types. These are used to qualify if we should renegotiate * even if our goal and current transport parameters are identical. @@ -1428,6 +1486,11 @@ typedef enum { AHD_QUEUE_TAGGED } ahd_queue_alg; +void ahd_set_tags(struct ahd_softc *ahd, + struct scsi_cmnd *cmd, + struct ahd_devinfo *devinfo, + ahd_queue_alg alg); + /**************************** Target Mode *************************************/ #ifdef AHD_TARGET_MODE void ahd_send_lstate_events(struct ahd_softc *, @@ -1465,8 +1528,10 @@ extern uint32_t ahd_debug; #define AHD_SHOW_INT_COALESCING 0x10000 #define AHD_DEBUG_SEQUENCER 0x20000 #endif +void ahd_print_scb(struct scb *scb); void ahd_print_devinfo(struct ahd_softc *ahd, struct ahd_devinfo *devinfo); +void ahd_dump_sglist(struct scb *scb); void ahd_dump_card_state(struct ahd_softc *ahd); int ahd_print_register(ahd_reg_parse_entry_t *table, u_int num_entries, @@ -1475,4 +1540,5 @@ int ahd_print_register(ahd_reg_parse_entry_t *table, u_int value, u_int *cur_column, u_int wrap_point); +void ahd_dump_scbs(struct ahd_softc *ahd); #endif /* _AIC79XX_H_ */ diff --git a/trunk/drivers/scsi/aic7xxx/aic79xx_core.c b/trunk/drivers/scsi/aic7xxx/aic79xx_core.c index 07a86a30f676..653818d2f802 100644 --- a/trunk/drivers/scsi/aic7xxx/aic79xx_core.c +++ b/trunk/drivers/scsi/aic7xxx/aic79xx_core.c @@ -52,7 +52,7 @@ /***************************** Lookup Tables **********************************/ -static char *ahd_chip_names[] = +char *ahd_chip_names[] = { "NONE", "aic7901", @@ -237,33 +237,10 @@ static int ahd_handle_target_cmd(struct ahd_softc *ahd, struct target_cmd *cmd); #endif -static int ahd_abort_scbs(struct ahd_softc *ahd, int target, - char channel, int lun, u_int tag, - role_t role, uint32_t status); -static void ahd_alloc_scbs(struct ahd_softc *ahd); -static void ahd_busy_tcl(struct ahd_softc *ahd, u_int tcl, - u_int scbid); -static void ahd_calc_residual(struct ahd_softc *ahd, - struct scb *scb); -static void ahd_clear_critical_section(struct ahd_softc *ahd); -static void ahd_clear_intstat(struct ahd_softc *ahd); -static void ahd_enable_coalescing(struct ahd_softc *ahd, - int enable); -static u_int ahd_find_busy_tcl(struct ahd_softc *ahd, u_int tcl); -static void ahd_freeze_devq(struct ahd_softc *ahd, - struct scb *scb); -static void ahd_handle_scb_status(struct ahd_softc *ahd, - struct scb *scb); -static struct ahd_phase_table_entry* ahd_lookup_phase_entry(int phase); -static void ahd_shutdown(void *arg); -static void ahd_update_coalescing_values(struct ahd_softc *ahd, - u_int timer, - u_int maxcmds, - u_int mincmds); -static int ahd_verify_vpd_cksum(struct vpd_config *vpd); -static int ahd_wait_seeprom(struct ahd_softc *ahd); - /******************************** Private Inlines *****************************/ +static __inline void ahd_assert_atn(struct ahd_softc *ahd); +static __inline int ahd_currently_packetized(struct ahd_softc *ahd); +static __inline int ahd_set_active_fifo(struct ahd_softc *ahd); static __inline void ahd_assert_atn(struct ahd_softc *ahd) @@ -317,44 +294,11 @@ ahd_set_active_fifo(struct ahd_softc *ahd) } } -static __inline void -ahd_unbusy_tcl(struct ahd_softc *ahd, u_int tcl) -{ - ahd_busy_tcl(ahd, tcl, SCB_LIST_NULL); -} - -/* - * Determine whether the sequencer reported a residual - * for this SCB/transaction. - */ -static __inline void -ahd_update_residual(struct ahd_softc *ahd, struct scb *scb) -{ - uint32_t sgptr; - - sgptr = ahd_le32toh(scb->hscb->sgptr); - if ((sgptr & SG_STATUS_VALID) != 0) - ahd_calc_residual(ahd, scb); -} - -static __inline void -ahd_complete_scb(struct ahd_softc *ahd, struct scb *scb) -{ - uint32_t sgptr; - - sgptr = ahd_le32toh(scb->hscb->sgptr); - if ((sgptr & SG_STATUS_VALID) != 0) - ahd_handle_scb_status(ahd, scb); - else - ahd_done(ahd, scb); -} - - /************************* Sequencer Execution Control ************************/ /* * Restart the sequencer program from address zero */ -static void +void ahd_restart(struct ahd_softc *ahd) { @@ -398,7 +342,7 @@ ahd_restart(struct ahd_softc *ahd) ahd_unpause(ahd); } -static void +void ahd_clear_fifo(struct ahd_softc *ahd, u_int fifo) { ahd_mode_state saved_modes; @@ -422,7 +366,7 @@ ahd_clear_fifo(struct ahd_softc *ahd, u_int fifo) * Flush and completed commands that are sitting in the command * complete queues down on the chip but have yet to be dma'ed back up. */ -static void +void ahd_flush_qoutfifo(struct ahd_softc *ahd) { struct scb *scb; @@ -961,51 +905,6 @@ ahd_handle_hwerrint(struct ahd_softc *ahd) ahd_free(ahd); } -#ifdef AHD_DEBUG -static void -ahd_dump_sglist(struct scb *scb) -{ - int i; - - if (scb->sg_count > 0) { - if ((scb->ahd_softc->flags & AHD_64BIT_ADDRESSING) != 0) { - struct ahd_dma64_seg *sg_list; - - sg_list = (struct ahd_dma64_seg*)scb->sg_list; - for (i = 0; i < scb->sg_count; i++) { - uint64_t addr; - uint32_t len; - - addr = ahd_le64toh(sg_list[i].addr); - len = ahd_le32toh(sg_list[i].len); - printf("sg[%d] - Addr 0x%x%x : Length %d%s\n", - i, - (uint32_t)((addr >> 32) & 0xFFFFFFFF), - (uint32_t)(addr & 0xFFFFFFFF), - sg_list[i].len & AHD_SG_LEN_MASK, - (sg_list[i].len & AHD_DMA_LAST_SEG) - ? " Last" : ""); - } - } else { - struct ahd_dma_seg *sg_list; - - sg_list = (struct ahd_dma_seg*)scb->sg_list; - for (i = 0; i < scb->sg_count; i++) { - uint32_t len; - - len = ahd_le32toh(sg_list[i].len); - printf("sg[%d] - Addr 0x%x%x : Length %d%s\n", - i, - (len & AHD_SG_HIGH_ADDR_MASK) >> 24, - ahd_le32toh(sg_list[i].addr), - len & AHD_SG_LEN_MASK, - len & AHD_DMA_LAST_SEG ? " Last" : ""); - } - } - } -} -#endif /* AHD_DEBUG */ - void ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat) { @@ -1154,12 +1053,10 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat) * If a target takes us into the command phase * assume that it has been externally reset and * has thus lost our previous packetized negotiation - * agreement. Since we have not sent an identify - * message and may not have fully qualified the - * connection, we change our command to TUR, assert - * ATN and ABORT the task when we go to message in - * phase. The OSM will see the REQUEUE_REQUEST - * status and retry the command. + * agreement. + * Revert to async/narrow transfers until we + * can renegotiate with the device and notify + * the OSM about the reset. */ scbid = ahd_get_scbptr(ahd); scb = ahd_lookup_scb(ahd, scbid); @@ -1186,28 +1083,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat) ahd_set_syncrate(ahd, &devinfo, /*period*/0, /*offset*/0, /*ppr_options*/0, AHD_TRANS_ACTIVE, /*paused*/TRUE); - /* Hand-craft TUR command */ - ahd_outb(ahd, SCB_CDB_STORE, 0); - ahd_outb(ahd, SCB_CDB_STORE+1, 0); - ahd_outb(ahd, SCB_CDB_STORE+2, 0); - ahd_outb(ahd, SCB_CDB_STORE+3, 0); - ahd_outb(ahd, SCB_CDB_STORE+4, 0); - ahd_outb(ahd, SCB_CDB_STORE+5, 0); - ahd_outb(ahd, SCB_CDB_LEN, 6); - scb->hscb->control &= ~(TAG_ENB|SCB_TAG_TYPE); - scb->hscb->control |= MK_MESSAGE; - ahd_outb(ahd, SCB_CONTROL, scb->hscb->control); - ahd_outb(ahd, MSG_OUT, HOST_MSG); - ahd_outb(ahd, SAVED_SCSIID, scb->hscb->scsiid); - /* - * The lun is 0, regardless of the SCB's lun - * as we have not sent an identify message. - */ - ahd_outb(ahd, SAVED_LUN, 0); - ahd_outb(ahd, SEQ_FLAGS, 0); - ahd_assert_atn(ahd); - scb->flags &= ~SCB_PACKETIZED; - scb->flags |= SCB_ABORT|SCB_EXTERNAL_RESET; + scb->flags |= SCB_EXTERNAL_RESET; ahd_freeze_devq(ahd, scb); ahd_set_transaction_status(scb, CAM_REQUEUE_REQ); ahd_freeze_scb(scb); @@ -1643,10 +1519,8 @@ ahd_handle_scsiint(struct ahd_softc *ahd, u_int intstat) /* * Ignore external resets after a bus reset. */ - if (((status & SCSIRSTI) != 0) && (ahd->flags & AHD_BUS_RESET_ACTIVE)) { - ahd_outb(ahd, CLRSINT1, CLRSCSIRSTI); + if (((status & SCSIRSTI) != 0) && (ahd->flags & AHD_BUS_RESET_ACTIVE)) return; - } /* * Clear bus reset flag @@ -2326,22 +2200,6 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd) if (sent_msg == MSG_ABORT_TAG) tag = SCB_GET_TAG(scb); - if ((scb->flags & SCB_EXTERNAL_RESET) != 0) { - /* - * This abort is in response to an - * unexpected switch to command phase - * for a packetized connection. Since - * the identify message was never sent, - * "saved lun" is 0. We really want to - * abort only the SCB that encountered - * this error, which could have a different - * lun. The SCB will be retried so the OS - * will see the UA after renegotiating to - * packetized. - */ - tag = SCB_GET_TAG(scb); - saved_lun = scb->hscb->lun; - } found = ahd_abort_scbs(ahd, target, 'A', saved_lun, tag, ROLE_INITIATOR, CAM_REQ_ABORTED); @@ -2665,7 +2523,7 @@ ahd_force_renegotiation(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) } #define AHD_MAX_STEPS 2000 -static void +void ahd_clear_critical_section(struct ahd_softc *ahd) { ahd_mode_state saved_modes; @@ -2788,7 +2646,7 @@ ahd_clear_critical_section(struct ahd_softc *ahd) /* * Clear any pending interrupt status. */ -static void +void ahd_clear_intstat(struct ahd_softc *ahd) { AHD_ASSERT_MODES(ahd, ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK), @@ -2819,8 +2677,6 @@ ahd_clear_intstat(struct ahd_softc *ahd) #ifdef AHD_DEBUG uint32_t ahd_debug = AHD_DEBUG_OPTS; #endif - -#if 0 void ahd_print_scb(struct scb *scb) { @@ -2845,7 +2701,49 @@ ahd_print_scb(struct scb *scb) SCB_GET_TAG(scb)); ahd_dump_sglist(scb); } -#endif /* 0 */ + +void +ahd_dump_sglist(struct scb *scb) +{ + int i; + + if (scb->sg_count > 0) { + if ((scb->ahd_softc->flags & AHD_64BIT_ADDRESSING) != 0) { + struct ahd_dma64_seg *sg_list; + + sg_list = (struct ahd_dma64_seg*)scb->sg_list; + for (i = 0; i < scb->sg_count; i++) { + uint64_t addr; + uint32_t len; + + addr = ahd_le64toh(sg_list[i].addr); + len = ahd_le32toh(sg_list[i].len); + printf("sg[%d] - Addr 0x%x%x : Length %d%s\n", + i, + (uint32_t)((addr >> 32) & 0xFFFFFFFF), + (uint32_t)(addr & 0xFFFFFFFF), + sg_list[i].len & AHD_SG_LEN_MASK, + (sg_list[i].len & AHD_DMA_LAST_SEG) + ? " Last" : ""); + } + } else { + struct ahd_dma_seg *sg_list; + + sg_list = (struct ahd_dma_seg*)scb->sg_list; + for (i = 0; i < scb->sg_count; i++) { + uint32_t len; + + len = ahd_le32toh(sg_list[i].len); + printf("sg[%d] - Addr 0x%x%x : Length %d%s\n", + i, + (len & AHD_SG_HIGH_ADDR_MASK) >> 24, + ahd_le32toh(sg_list[i].addr), + len & AHD_SG_LEN_MASK, + len & AHD_DMA_LAST_SEG ? " Last" : ""); + } + } + } +} /************************* Transfer Negotiation *******************************/ /* @@ -2952,14 +2850,14 @@ ahd_devlimited_syncrate(struct ahd_softc *ahd, transinfo = &tinfo->goal; *ppr_options &= (transinfo->ppr_options|MSG_EXT_PPR_PCOMP_EN); if (transinfo->width == MSG_EXT_WDTR_BUS_8_BIT) { - maxsync = max(maxsync, (u_int)AHD_SYNCRATE_ULTRA2); + maxsync = MAX(maxsync, AHD_SYNCRATE_ULTRA2); *ppr_options &= ~MSG_EXT_PPR_DT_REQ; } if (transinfo->period == 0) { *period = 0; *ppr_options = 0; } else { - *period = max(*period, (u_int)transinfo->period); + *period = MAX(*period, transinfo->period); ahd_find_syncrate(ahd, period, ppr_options, maxsync); } } @@ -3008,7 +2906,7 @@ ahd_find_syncrate(struct ahd_softc *ahd, u_int *period, * Truncate the given synchronous offset to a value the * current adapter type and syncrate are capable of. */ -static void +void ahd_validate_offset(struct ahd_softc *ahd, struct ahd_initiator_tinfo *tinfo, u_int period, u_int *offset, int wide, @@ -3026,12 +2924,12 @@ ahd_validate_offset(struct ahd_softc *ahd, maxoffset = MAX_OFFSET_PACED; } else maxoffset = MAX_OFFSET_NON_PACED; - *offset = min(*offset, maxoffset); + *offset = MIN(*offset, maxoffset); if (tinfo != NULL) { if (role == ROLE_TARGET) - *offset = min(*offset, (u_int)tinfo->user.offset); + *offset = MIN(*offset, tinfo->user.offset); else - *offset = min(*offset, (u_int)tinfo->goal.offset); + *offset = MIN(*offset, tinfo->goal.offset); } } @@ -3039,7 +2937,7 @@ ahd_validate_offset(struct ahd_softc *ahd, * Truncate the given transfer width parameter to a value the * current adapter type is capable of. */ -static void +void ahd_validate_width(struct ahd_softc *ahd, struct ahd_initiator_tinfo *tinfo, u_int *bus_width, role_t role) { @@ -3057,9 +2955,9 @@ ahd_validate_width(struct ahd_softc *ahd, struct ahd_initiator_tinfo *tinfo, } if (tinfo != NULL) { if (role == ROLE_TARGET) - *bus_width = min((u_int)tinfo->user.width, *bus_width); + *bus_width = MIN(tinfo->user.width, *bus_width); else - *bus_width = min((u_int)tinfo->goal.width, *bus_width); + *bus_width = MIN(tinfo->goal.width, *bus_width); } } @@ -3312,7 +3210,7 @@ ahd_set_width(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, /* * Update the current state of tagged queuing for a given target. */ -static void +void ahd_set_tags(struct ahd_softc *ahd, struct scsi_cmnd *cmd, struct ahd_devinfo *devinfo, ahd_queue_alg alg) { @@ -3568,7 +3466,7 @@ ahd_print_devinfo(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) devinfo->target, devinfo->lun); } -static struct ahd_phase_table_entry* +struct ahd_phase_table_entry* ahd_lookup_phase_entry(int phase) { struct ahd_phase_table_entry *entry; @@ -5453,7 +5351,7 @@ ahd_free(struct ahd_softc *ahd) return; } -static void +void ahd_shutdown(void *arg) { struct ahd_softc *ahd; @@ -5582,7 +5480,7 @@ ahd_reset(struct ahd_softc *ahd, int reinit) /* * Determine the number of SCBs available on the controller */ -static int +int ahd_probe_scbs(struct ahd_softc *ahd) { int i; @@ -6031,7 +5929,7 @@ ahd_free_scb(struct ahd_softc *ahd, struct scb *scb) ahd_platform_scb_free(ahd, scb); } -static void +void ahd_alloc_scbs(struct ahd_softc *ahd) { struct scb_data *scb_data; @@ -6159,9 +6057,9 @@ ahd_alloc_scbs(struct ahd_softc *ahd) #endif } - newcount = min(scb_data->sense_left, scb_data->scbs_left); - newcount = min(newcount, scb_data->sgs_left); - newcount = min(newcount, (AHD_SCB_MAX_ALLOC - scb_data->numscbs)); + newcount = MIN(scb_data->sense_left, scb_data->scbs_left); + newcount = MIN(newcount, scb_data->sgs_left); + newcount = MIN(newcount, (AHD_SCB_MAX_ALLOC - scb_data->numscbs)); for (i = 0; i < newcount; i++) { struct scb_platform_data *pdata; u_int col_tag; @@ -7084,7 +6982,7 @@ ahd_intr_enable(struct ahd_softc *ahd, int enable) ahd_outb(ahd, HCNTRL, hcntrl); } -static void +void ahd_update_coalescing_values(struct ahd_softc *ahd, u_int timer, u_int maxcmds, u_int mincmds) { @@ -7102,7 +7000,7 @@ ahd_update_coalescing_values(struct ahd_softc *ahd, u_int timer, u_int maxcmds, ahd_outb(ahd, INT_COALESCING_MINCMDS, -mincmds); } -static void +void ahd_enable_coalescing(struct ahd_softc *ahd, int enable) { @@ -7172,7 +7070,6 @@ ahd_pause_and_flushwork(struct ahd_softc *ahd) ahd->flags &= ~AHD_ALL_INTERRUPTS; } -#if 0 int ahd_suspend(struct ahd_softc *ahd) { @@ -7186,9 +7083,7 @@ ahd_suspend(struct ahd_softc *ahd) ahd_shutdown(ahd); return (0); } -#endif /* 0 */ -#if 0 int ahd_resume(struct ahd_softc *ahd) { @@ -7198,7 +7093,6 @@ ahd_resume(struct ahd_softc *ahd) ahd_restart(ahd); return (0); } -#endif /* 0 */ /************************** Busy Target Table *********************************/ /* @@ -7231,7 +7125,7 @@ ahd_index_busy_tcl(struct ahd_softc *ahd, u_int *saved_scbid, u_int tcl) /* * Return the untagged transaction id for a given target/channel lun. */ -static u_int +u_int ahd_find_busy_tcl(struct ahd_softc *ahd, u_int tcl) { u_int scbid; @@ -7244,7 +7138,7 @@ ahd_find_busy_tcl(struct ahd_softc *ahd, u_int tcl) return (scbid); } -static void +void ahd_busy_tcl(struct ahd_softc *ahd, u_int tcl, u_int scbid) { u_int scb_offset; @@ -7292,7 +7186,7 @@ ahd_match_scb(struct ahd_softc *ahd, struct scb *scb, int target, return match; } -static void +void ahd_freeze_devq(struct ahd_softc *ahd, struct scb *scb) { int target; @@ -7796,7 +7690,7 @@ ahd_add_scb_to_free_list(struct ahd_softc *ahd, u_int scbid) * been modified from CAM_REQ_INPROG. This routine assumes that the sequencer * is paused before it is called. */ -static int +int ahd_abort_scbs(struct ahd_softc *ahd, int target, char channel, int lun, u_int tag, role_t role, uint32_t status) { @@ -8025,11 +7919,6 @@ ahd_reset_channel(struct ahd_softc *ahd, char channel, int initiate_reset) ahd_clear_fifo(ahd, 0); ahd_clear_fifo(ahd, 1); - /* - * Clear SCSI interrupt status - */ - ahd_outb(ahd, CLRSINT1, CLRSCSIRSTI); - /* * Reenable selections */ @@ -8063,6 +7952,10 @@ ahd_reset_channel(struct ahd_softc *ahd, char channel, int initiate_reset) } } #endif + /* Notify the XPT that a bus reset occurred */ + ahd_send_async(ahd, devinfo.channel, CAM_TARGET_WILDCARD, + CAM_LUN_WILDCARD, AC_BUS_RESET); + /* * Revert to async/narrow transfers until we renegotiate. */ @@ -8084,10 +7977,6 @@ ahd_reset_channel(struct ahd_softc *ahd, char channel, int initiate_reset) } } - /* Notify the XPT that a bus reset occurred */ - ahd_send_async(ahd, devinfo.channel, CAM_TARGET_WILDCARD, - CAM_LUN_WILDCARD, AC_BUS_RESET); - ahd_restart(ahd); return (found); @@ -8130,8 +8019,18 @@ ahd_stat_timer(void *arg) } /****************************** Status Processing *****************************/ +void +ahd_handle_scb_status(struct ahd_softc *ahd, struct scb *scb) +{ + if (scb->hscb->shared_data.istatus.scsi_status != 0) { + ahd_handle_scsi_status(ahd, scb); + } else { + ahd_calc_residual(ahd, scb); + ahd_done(ahd, scb); + } +} -static void +void ahd_handle_scsi_status(struct ahd_softc *ahd, struct scb *scb) { struct hardware_scb *hscb; @@ -8339,21 +8238,10 @@ ahd_handle_scsi_status(struct ahd_softc *ahd, struct scb *scb) } } -static void -ahd_handle_scb_status(struct ahd_softc *ahd, struct scb *scb) -{ - if (scb->hscb->shared_data.istatus.scsi_status != 0) { - ahd_handle_scsi_status(ahd, scb); - } else { - ahd_calc_residual(ahd, scb); - ahd_done(ahd, scb); - } -} - /* * Calculate the residual for a just completed SCB. */ -static void +void ahd_calc_residual(struct ahd_softc *ahd, struct scb *scb) { struct hardware_scb *hscb; @@ -8780,7 +8668,7 @@ ahd_resolve_seqaddr(struct ahd_softc *ahd, u_int address) if (skip_addr > i) { int end_addr; - end_addr = min(address, skip_addr); + end_addr = MIN(address, skip_addr); address_offset += end_addr - i; i = skip_addr; } else { @@ -9204,7 +9092,6 @@ ahd_dump_card_state(struct ahd_softc *ahd) ahd_unpause(ahd); } -#if 0 void ahd_dump_scbs(struct ahd_softc *ahd) { @@ -9230,7 +9117,6 @@ ahd_dump_scbs(struct ahd_softc *ahd) ahd_set_scbptr(ahd, saved_scb_index); ahd_restore_modes(ahd, saved_modes); } -#endif /* 0 */ /**************************** Flexport Logic **********************************/ /* @@ -9333,7 +9219,7 @@ ahd_write_seeprom(struct ahd_softc *ahd, uint16_t *buf, /* * Wait ~100us for the serial eeprom to satisfy our request. */ -static int +int ahd_wait_seeprom(struct ahd_softc *ahd) { int cnt; @@ -9351,7 +9237,7 @@ ahd_wait_seeprom(struct ahd_softc *ahd) * Validate the two checksums in the per_channel * vital product data struct. */ -static int +int ahd_verify_vpd_cksum(struct vpd_config *vpd) { int i; @@ -9430,24 +9316,6 @@ ahd_release_seeprom(struct ahd_softc *ahd) /* Currently a no-op */ } -/* - * Wait at most 2 seconds for flexport arbitration to succeed. - */ -static int -ahd_wait_flexport(struct ahd_softc *ahd) -{ - int cnt; - - AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK); - cnt = 1000000 * 2 / 5; - while ((ahd_inb(ahd, BRDCTL) & FLXARBACK) == 0 && --cnt) - ahd_delay(5); - - if (cnt == 0) - return (ETIMEDOUT); - return (0); -} - int ahd_write_flexport(struct ahd_softc *ahd, u_int addr, u_int value) { @@ -9489,6 +9357,24 @@ ahd_read_flexport(struct ahd_softc *ahd, u_int addr, uint8_t *value) return (0); } +/* + * Wait at most 2 seconds for flexport arbitration to succeed. + */ +int +ahd_wait_flexport(struct ahd_softc *ahd) +{ + int cnt; + + AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK); + cnt = 1000000 * 2 / 5; + while ((ahd_inb(ahd, BRDCTL) & FLXARBACK) == 0 && --cnt) + ahd_delay(5); + + if (cnt == 0) + return (ETIMEDOUT); + return (0); +} + /************************* Target Mode ****************************************/ #ifdef AHD_TARGET_MODE cam_status diff --git a/trunk/drivers/scsi/aic7xxx/aic79xx_inline.h b/trunk/drivers/scsi/aic7xxx/aic79xx_inline.h index 2ceb67f4af2a..8ad3ce945b9e 100644 --- a/trunk/drivers/scsi/aic7xxx/aic79xx_inline.h +++ b/trunk/drivers/scsi/aic7xxx/aic79xx_inline.h @@ -418,6 +418,10 @@ ahd_targetcmd_offset(struct ahd_softc *ahd, u_int index) } /*********************** Miscelaneous Support Functions ***********************/ +static __inline void ahd_complete_scb(struct ahd_softc *ahd, + struct scb *scb); +static __inline void ahd_update_residual(struct ahd_softc *ahd, + struct scb *scb); static __inline struct ahd_initiator_tinfo * ahd_fetch_transinfo(struct ahd_softc *ahd, char channel, u_int our_id, @@ -463,6 +467,32 @@ static __inline uint32_t ahd_get_sense_bufaddr(struct ahd_softc *ahd, struct scb *scb); +static __inline void +ahd_complete_scb(struct ahd_softc *ahd, struct scb *scb) +{ + uint32_t sgptr; + + sgptr = ahd_le32toh(scb->hscb->sgptr); + if ((sgptr & SG_STATUS_VALID) != 0) + ahd_handle_scb_status(ahd, scb); + else + ahd_done(ahd, scb); +} + +/* + * Determine whether the sequencer reported a residual + * for this SCB/transaction. + */ +static __inline void +ahd_update_residual(struct ahd_softc *ahd, struct scb *scb) +{ + uint32_t sgptr; + + sgptr = ahd_le32toh(scb->hscb->sgptr); + if ((sgptr & SG_STATUS_VALID) != 0) + ahd_calc_residual(ahd, scb); +} + /* * Return pointers to the transfer negotiation information * for the specified our_id/remote_id pair. @@ -497,8 +527,7 @@ ahd_inw(struct ahd_softc *ahd, u_int port) * or have other side effects when the low byte is * read. */ - uint16_t r = ahd_inb(ahd, port+1) << 8; - return r | ahd_inb(ahd, port); + return ((ahd_inb(ahd, port+1) << 8) | ahd_inb(ahd, port)); } static __inline void diff --git a/trunk/drivers/scsi/aic7xxx/aic79xx_osm.c b/trunk/drivers/scsi/aic7xxx/aic79xx_osm.c index 9bfcca5ede08..1faa008b5b81 100644 --- a/trunk/drivers/scsi/aic7xxx/aic79xx_osm.c +++ b/trunk/drivers/scsi/aic7xxx/aic79xx_osm.c @@ -293,7 +293,7 @@ static uint32_t aic79xx_seltime; * force all outstanding transactions to be serviced prior to a new * transaction. */ -static uint32_t aic79xx_periodic_otag; +uint32_t aic79xx_periodic_otag; /* Some storage boxes are using an LSI chip which has a bug making it * impossible to use aic79xx Rev B chip in 320 speeds. The following @@ -773,7 +773,6 @@ struct scsi_host_template aic79xx_driver_template = { #endif .can_queue = AHD_MAX_QUEUE, .this_id = -1, - .max_sectors = 8192, .cmd_per_lun = 2, .use_clustering = ENABLE_CLUSTERING, .slave_alloc = ahd_linux_slave_alloc, @@ -1558,7 +1557,7 @@ ahd_linux_run_command(struct ahd_softc *ahd, struct ahd_linux_device *dev, * SCSI controller interrupt handler. */ irqreturn_t -ahd_linux_isr(int irq, void *dev_id) +ahd_linux_isr(int irq, void *dev_id, struct pt_regs * regs) { struct ahd_softc *ahd; u_long flags; @@ -1814,9 +1813,9 @@ ahd_linux_handle_scsi_status(struct ahd_softc *ahd, u_int sense_offset; if (scb->flags & SCB_SENSE) { - sense_size = min(sizeof(struct scsi_sense_data) + sense_size = MIN(sizeof(struct scsi_sense_data) - ahd_get_sense_residual(scb), - (u_long)sizeof(cmd->sense_buffer)); + sizeof(cmd->sense_buffer)); sense_offset = 0; } else { /* @@ -1825,8 +1824,7 @@ ahd_linux_handle_scsi_status(struct ahd_softc *ahd, */ siu = (struct scsi_status_iu_header *) scb->sense_data; - sense_size = min_t(size_t, - scsi_4btoul(siu->sense_length), + sense_size = MIN(scsi_4btoul(siu->sense_length), sizeof(cmd->sense_buffer)); sense_offset = SIU_SENSE_OFFSET(siu); } @@ -2636,22 +2634,8 @@ static void ahd_linux_set_pcomp_en(struct scsi_target *starget, int pcomp) pcomp ? "Enable" : "Disable"); #endif - if (pcomp) { - uint8_t precomp; - - if (ahd->unit < ARRAY_SIZE(aic79xx_iocell_info)) { - struct ahd_linux_iocell_opts *iocell_opts; - - iocell_opts = &aic79xx_iocell_info[ahd->unit]; - precomp = iocell_opts->precomp; - } else { - precomp = AIC79XX_DEFAULT_PRECOMP; - } + if (pcomp) ppr_options |= MSG_EXT_PPR_PCOMP_EN; - AHD_SET_PRECOMP(ahd, precomp); - } else { - AHD_SET_PRECOMP(ahd, 0); - } ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0, starget->channel + 'A', ROLE_INITIATOR); @@ -2694,25 +2678,7 @@ static void ahd_linux_set_hold_mcs(struct scsi_target *starget, int hold) ahd_unlock(ahd, &flags); } -static void ahd_linux_get_signalling(struct Scsi_Host *shost) -{ - struct ahd_softc *ahd = *(struct ahd_softc **)shost->hostdata; - unsigned long flags; - u8 mode; - - ahd_lock(ahd, &flags); - ahd_pause(ahd); - mode = ahd_inb(ahd, SBLKCTL); - ahd_unpause(ahd); - ahd_unlock(ahd, &flags); - if (mode & ENAB40) - spi_signalling(shost) = SPI_SIGNAL_LVD; - else if (mode & ENAB20) - spi_signalling(shost) = SPI_SIGNAL_SE; - else - spi_signalling(shost) = SPI_SIGNAL_UNKNOWN; -} static struct spi_function_template ahd_linux_transport_functions = { .set_offset = ahd_linux_set_offset, @@ -2737,7 +2703,6 @@ static struct spi_function_template ahd_linux_transport_functions = { .show_pcomp_en = 1, .set_hold_mcs = ahd_linux_set_hold_mcs, .show_hold_mcs = 1, - .get_signalling = ahd_linux_get_signalling, }; static int __init diff --git a/trunk/drivers/scsi/aic7xxx/aic79xx_osm.h b/trunk/drivers/scsi/aic7xxx/aic79xx_osm.h index 3a67fc578d78..601340d84410 100644 --- a/trunk/drivers/scsi/aic7xxx/aic79xx_osm.h +++ b/trunk/drivers/scsi/aic7xxx/aic79xx_osm.h @@ -506,6 +506,9 @@ struct info_str { int pos; }; +void ahd_format_transinfo(struct info_str *info, + struct ahd_transinfo *tinfo); + /******************************** Locking *************************************/ static __inline void ahd_lockinit(struct ahd_softc *ahd) @@ -579,6 +582,8 @@ ahd_unlock(struct ahd_softc *ahd, unsigned long *flags) #define PCIXM_STATUS_MAXCRDS 0x1C00 /* Maximum Cumulative Read Size */ #define PCIXM_STATUS_RCVDSCEM 0x2000 /* Received a Split Comp w/Error msg */ +extern struct pci_driver aic79xx_pci_driver; + typedef enum { AHD_POWER_STATE_D0, @@ -857,7 +862,7 @@ int ahd_platform_abort_scbs(struct ahd_softc *ahd, int target, char channel, int lun, u_int tag, role_t role, uint32_t status); irqreturn_t - ahd_linux_isr(int irq, void *dev_id); + ahd_linux_isr(int irq, void *dev_id, struct pt_regs * regs); void ahd_done(struct ahd_softc*, struct scb*); void ahd_send_async(struct ahd_softc *, char channel, u_int target, u_int lun, ac_code); diff --git a/trunk/drivers/scsi/aic7xxx/aic79xx_osm_pci.c b/trunk/drivers/scsi/aic7xxx/aic79xx_osm_pci.c index 2001fe890e71..50a41eda580e 100644 --- a/trunk/drivers/scsi/aic7xxx/aic79xx_osm_pci.c +++ b/trunk/drivers/scsi/aic7xxx/aic79xx_osm_pci.c @@ -82,7 +82,7 @@ static struct pci_device_id ahd_linux_pci_id_table[] = { MODULE_DEVICE_TABLE(pci, ahd_linux_pci_id_table); -static struct pci_driver aic79xx_pci_driver = { +struct pci_driver aic79xx_pci_driver = { .name = "aic79xx", .probe = ahd_linux_pci_dev_probe, .remove = ahd_linux_pci_dev_remove, @@ -198,7 +198,7 @@ ahd_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent) int ahd_linux_pci_init(void) { - return pci_register_driver(&aic79xx_pci_driver); + return (pci_module_init(&aic79xx_pci_driver)); } void diff --git a/trunk/drivers/scsi/aic7xxx/aic79xx_pci.c b/trunk/drivers/scsi/aic7xxx/aic79xx_pci.c index c07735819cd1..14850f31aafa 100644 --- a/trunk/drivers/scsi/aic7xxx/aic79xx_pci.c +++ b/trunk/drivers/scsi/aic7xxx/aic79xx_pci.c @@ -97,7 +97,7 @@ static ahd_device_setup_t ahd_aic7901A_setup; static ahd_device_setup_t ahd_aic7902_setup; static ahd_device_setup_t ahd_aic790X_setup; -static struct ahd_pci_identity ahd_pci_ident_table [] = +struct ahd_pci_identity ahd_pci_ident_table [] = { /* aic7901 based controllers */ { @@ -201,7 +201,7 @@ static struct ahd_pci_identity ahd_pci_ident_table [] = } }; -static const u_int ahd_num_pci_devs = ARRAY_SIZE(ahd_pci_ident_table); +const u_int ahd_num_pci_devs = ARRAY_SIZE(ahd_pci_ident_table); #define DEVCONFIG 0x40 #define PCIXINITPAT 0x0000E000ul @@ -245,7 +245,6 @@ static int ahd_check_extport(struct ahd_softc *ahd); static void ahd_configure_termination(struct ahd_softc *ahd, u_int adapter_control); static void ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat); -static void ahd_pci_intr(struct ahd_softc *ahd); struct ahd_pci_identity * ahd_find_pci_device(ahd_dev_softc_t pci) @@ -758,7 +757,7 @@ static const char *pci_status_strings[] = "%s: Address or Write Phase Parity Error Detected in %s.\n" }; -static void +void ahd_pci_intr(struct ahd_softc *ahd) { uint8_t pci_status[8]; diff --git a/trunk/drivers/scsi/aic7xxx/aic79xx_proc.c b/trunk/drivers/scsi/aic7xxx/aic79xx_proc.c index 6b28bebcbca0..c5f0ee591509 100644 --- a/trunk/drivers/scsi/aic7xxx/aic79xx_proc.c +++ b/trunk/drivers/scsi/aic7xxx/aic79xx_proc.c @@ -136,7 +136,7 @@ copy_info(struct info_str *info, char *fmt, ...) return (len); } -static void +void ahd_format_transinfo(struct info_str *info, struct ahd_transinfo *tinfo) { u_int speed; diff --git a/trunk/drivers/scsi/aic7xxx/aic7xxx.h b/trunk/drivers/scsi/aic7xxx/aic7xxx.h index 954c7c24501d..62ff8c3dc2bb 100644 --- a/trunk/drivers/scsi/aic7xxx/aic7xxx.h +++ b/trunk/drivers/scsi/aic7xxx/aic7xxx.h @@ -54,6 +54,14 @@ struct scb_platform_data; struct seeprom_descriptor; /****************************** Useful Macros *********************************/ +#ifndef MAX +#define MAX(a,b) (((a) > (b)) ? (a) : (b)) +#endif + +#ifndef MIN +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) +#endif + #ifndef TRUE #define TRUE 1 #endif @@ -1127,6 +1135,8 @@ struct ahc_pci_identity { char *name; ahc_device_setup_t *setup; }; +extern struct ahc_pci_identity ahc_pci_ident_table[]; +extern const u_int ahc_num_pci_devs; /***************************** VL/EISA Declarations ***************************/ struct aic7770_identity { @@ -1279,7 +1289,6 @@ typedef enum { } ahc_queue_alg; void ahc_set_tags(struct ahc_softc *ahc, - struct scsi_cmnd *cmd, struct ahc_devinfo *devinfo, ahc_queue_alg alg); diff --git a/trunk/drivers/scsi/aic7xxx/aic7xxx_core.c b/trunk/drivers/scsi/aic7xxx/aic7xxx_core.c index 50ef785224de..93e4e40944b6 100644 --- a/trunk/drivers/scsi/aic7xxx/aic7xxx_core.c +++ b/trunk/drivers/scsi/aic7xxx/aic7xxx_core.c @@ -1671,7 +1671,7 @@ ahc_devlimited_syncrate(struct ahc_softc *ahc, transinfo = &tinfo->goal; *ppr_options &= transinfo->ppr_options; if (transinfo->width == MSG_EXT_WDTR_BUS_8_BIT) { - maxsync = max(maxsync, (u_int)AHC_SYNCRATE_ULTRA2); + maxsync = MAX(maxsync, AHC_SYNCRATE_ULTRA2); *ppr_options &= ~MSG_EXT_PPR_DT_REQ; } if (transinfo->period == 0) { @@ -1679,7 +1679,7 @@ ahc_devlimited_syncrate(struct ahc_softc *ahc, *ppr_options = 0; return (NULL); } - *period = max(*period, (u_int)transinfo->period); + *period = MAX(*period, transinfo->period); return (ahc_find_syncrate(ahc, period, ppr_options, maxsync)); } @@ -1804,12 +1804,12 @@ ahc_validate_offset(struct ahc_softc *ahc, else maxoffset = MAX_OFFSET_8BIT; } - *offset = min(*offset, maxoffset); + *offset = MIN(*offset, maxoffset); if (tinfo != NULL) { if (role == ROLE_TARGET) - *offset = min(*offset, (u_int)tinfo->user.offset); + *offset = MIN(*offset, tinfo->user.offset); else - *offset = min(*offset, (u_int)tinfo->goal.offset); + *offset = MIN(*offset, tinfo->goal.offset); } } @@ -1835,9 +1835,9 @@ ahc_validate_width(struct ahc_softc *ahc, struct ahc_initiator_tinfo *tinfo, } if (tinfo != NULL) { if (role == ROLE_TARGET) - *bus_width = min((u_int)tinfo->user.width, *bus_width); + *bus_width = MIN(tinfo->user.width, *bus_width); else - *bus_width = min((u_int)tinfo->goal.width, *bus_width); + *bus_width = MIN(tinfo->goal.width, *bus_width); } } @@ -1986,7 +1986,7 @@ ahc_set_syncrate(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, tinfo->curr.ppr_options = ppr_options; ahc_send_async(ahc, devinfo->channel, devinfo->target, - CAM_LUN_WILDCARD, AC_TRANSFER_NEG); + CAM_LUN_WILDCARD, AC_TRANSFER_NEG, NULL); if (bootverbose) { if (offset != 0) { printf("%s: target %d synchronous at %sMHz%s, " @@ -2056,7 +2056,7 @@ ahc_set_width(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, tinfo->curr.width = width; ahc_send_async(ahc, devinfo->channel, devinfo->target, - CAM_LUN_WILDCARD, AC_TRANSFER_NEG); + CAM_LUN_WILDCARD, AC_TRANSFER_NEG, NULL); if (bootverbose) { printf("%s: target %d using %dbit transfers\n", ahc_name(ahc), devinfo->target, @@ -2074,14 +2074,12 @@ ahc_set_width(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, * Update the current state of tagged queuing for a given target. */ void -ahc_set_tags(struct ahc_softc *ahc, struct scsi_cmnd *cmd, - struct ahc_devinfo *devinfo, ahc_queue_alg alg) +ahc_set_tags(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, + ahc_queue_alg alg) { - struct scsi_device *sdev = cmd->device; - - ahc_platform_set_tags(ahc, sdev, devinfo, alg); + ahc_platform_set_tags(ahc, devinfo, alg); ahc_send_async(ahc, devinfo->channel, devinfo->target, - devinfo->lun, AC_TRANSFER_NEG); + devinfo->lun, AC_TRANSFER_NEG, &alg); } /* @@ -3491,7 +3489,7 @@ ahc_handle_msg_reject(struct ahc_softc *ahc, struct ahc_devinfo *devinfo) printf("(%s:%c:%d:%d): refuses tagged commands. " "Performing non-tagged I/O\n", ahc_name(ahc), devinfo->channel, devinfo->target, devinfo->lun); - ahc_set_tags(ahc, scb->io_ctx, devinfo, AHC_QUEUE_NONE); + ahc_set_tags(ahc, devinfo, AHC_QUEUE_NONE); mask = ~0x23; } else { printf("(%s:%c:%d:%d): refuses %s tagged commands. " @@ -3499,7 +3497,7 @@ ahc_handle_msg_reject(struct ahc_softc *ahc, struct ahc_devinfo *devinfo) ahc_name(ahc), devinfo->channel, devinfo->target, devinfo->lun, tag_type == MSG_ORDERED_TASK ? "ordered" : "head of queue"); - ahc_set_tags(ahc, scb->io_ctx, devinfo, AHC_QUEUE_BASIC); + ahc_set_tags(ahc, devinfo, AHC_QUEUE_BASIC); mask = ~0x03; } @@ -3765,7 +3763,7 @@ ahc_handle_devreset(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, if (status != CAM_SEL_TIMEOUT) ahc_send_async(ahc, devinfo->channel, devinfo->target, - CAM_LUN_WILDCARD, AC_SENT_BDR); + CAM_LUN_WILDCARD, AC_SENT_BDR, NULL); if (message != NULL && (verbose_level <= bootverbose)) @@ -4408,7 +4406,7 @@ ahc_alloc_scbs(struct ahc_softc *ahc) physaddr = sg_map->sg_physaddr; newcount = (PAGE_SIZE / (AHC_NSEG * sizeof(struct ahc_dma_seg))); - newcount = min(newcount, (AHC_SCB_MAX_ALLOC - scb_data->numscbs)); + newcount = MIN(newcount, (AHC_SCB_MAX_ALLOC - scb_data->numscbs)); for (i = 0; i < newcount; i++) { struct scb_platform_data *pdata; #ifndef __linux__ @@ -6020,7 +6018,7 @@ ahc_reset_channel(struct ahc_softc *ahc, char channel, int initiate_reset) #endif /* Notify the XPT that a bus reset occurred */ ahc_send_async(ahc, devinfo.channel, CAM_TARGET_WILDCARD, - CAM_LUN_WILDCARD, AC_BUS_RESET); + CAM_LUN_WILDCARD, AC_BUS_RESET, NULL); /* * Revert to async/narrow transfers until we renegotiate. @@ -6444,7 +6442,7 @@ ahc_download_instr(struct ahc_softc *ahc, u_int instrptr, uint8_t *dconsts) if (skip_addr > i) { int end_addr; - end_addr = min(address, skip_addr); + end_addr = MIN(address, skip_addr); address_offset += end_addr - i; i = skip_addr; } else { diff --git a/trunk/drivers/scsi/aic7xxx/aic7xxx_inline.h b/trunk/drivers/scsi/aic7xxx/aic7xxx_inline.h index 8e1954cdd84f..2cc8a17ed8b4 100644 --- a/trunk/drivers/scsi/aic7xxx/aic7xxx_inline.h +++ b/trunk/drivers/scsi/aic7xxx/aic7xxx_inline.h @@ -300,8 +300,7 @@ ahc_fetch_transinfo(struct ahc_softc *ahc, char channel, u_int our_id, static __inline uint16_t ahc_inw(struct ahc_softc *ahc, u_int port) { - uint16_t r = ahc_inb(ahc, port+1) << 8; - return r | ahc_inb(ahc, port); + return ((ahc_inb(ahc, port+1) << 8) | ahc_inb(ahc, port)); } static __inline void diff --git a/trunk/drivers/scsi/aic7xxx/aic7xxx_osm.c b/trunk/drivers/scsi/aic7xxx/aic7xxx_osm.c index 660f26e23a38..339b85cb61cd 100644 --- a/trunk/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/trunk/drivers/scsi/aic7xxx/aic7xxx_osm.c @@ -328,7 +328,7 @@ static uint32_t aic7xxx_seltime; * force all outstanding transactions to be serviced prior to a new * transaction. */ -static uint32_t aic7xxx_periodic_otag; +uint32_t aic7xxx_periodic_otag; /* * Module information and settable options. @@ -512,6 +512,7 @@ ahc_linux_target_alloc(struct scsi_target *starget) struct seeprom_config *sc = ahc->seep_config; unsigned long flags; struct scsi_target **ahc_targp = ahc_linux_target_in_softc(starget); + struct ahc_linux_target *targ = scsi_transport_target_data(starget); unsigned short scsirate; struct ahc_devinfo devinfo; struct ahc_initiator_tinfo *tinfo; @@ -532,6 +533,7 @@ ahc_linux_target_alloc(struct scsi_target *starget) BUG_ON(*ahc_targp != NULL); *ahc_targp = starget; + memset(targ, 0, sizeof(*targ)); if (sc) { int maxsync = AHC_SYNCRATE_DT; @@ -592,11 +594,14 @@ ahc_linux_slave_alloc(struct scsi_device *sdev) struct ahc_softc *ahc = *((struct ahc_softc **)sdev->host->hostdata); struct scsi_target *starget = sdev->sdev_target; + struct ahc_linux_target *targ = scsi_transport_target_data(starget); struct ahc_linux_device *dev; if (bootverbose) printf("%s: Slave Alloc %d\n", ahc_name(ahc), sdev->id); + BUG_ON(targ->sdev[sdev->lun] != NULL); + dev = scsi_transport_device_data(sdev); memset(dev, 0, sizeof(*dev)); @@ -613,6 +618,8 @@ ahc_linux_slave_alloc(struct scsi_device *sdev) */ dev->maxtags = 0; + targ->sdev[sdev->lun] = sdev; + spi_period(starget) = 0; return 0; @@ -637,6 +644,22 @@ ahc_linux_slave_configure(struct scsi_device *sdev) return 0; } +static void +ahc_linux_slave_destroy(struct scsi_device *sdev) +{ + struct ahc_softc *ahc; + struct ahc_linux_device *dev = scsi_transport_device_data(sdev); + struct ahc_linux_target *targ = scsi_transport_target_data(sdev->sdev_target); + + ahc = *((struct ahc_softc **)sdev->host->hostdata); + if (bootverbose) + printf("%s: Slave Destroy %d\n", ahc_name(ahc), sdev->id); + + BUG_ON(dev->active); + + targ->sdev[sdev->lun] = NULL; +} + #if defined(__i386__) /* * Return the disk geometry for the given SCSI device. @@ -754,11 +777,11 @@ struct scsi_host_template aic7xxx_driver_template = { #endif .can_queue = AHC_MAX_QUEUE, .this_id = -1, - .max_sectors = 8192, .cmd_per_lun = 2, .use_clustering = ENABLE_CLUSTERING, .slave_alloc = ahc_linux_slave_alloc, .slave_configure = ahc_linux_slave_configure, + .slave_destroy = ahc_linux_slave_destroy, .target_alloc = ahc_linux_target_alloc, .target_destroy = ahc_linux_target_destroy, }; @@ -1180,13 +1203,21 @@ void ahc_platform_free(struct ahc_softc *ahc) { struct scsi_target *starget; - int i; + int i, j; if (ahc->platform_data != NULL) { /* destroy all of the device and target objects */ for (i = 0; i < AHC_NUM_TARGETS; i++) { starget = ahc->platform_data->starget[i]; if (starget != NULL) { + for (j = 0; j < AHC_NUM_LUNS; j++) { + struct ahc_linux_target *targ = + scsi_transport_target_data(starget); + + if (targ->sdev[j] == NULL) + continue; + targ->sdev[j] = NULL; + } ahc->platform_data->starget[i] = NULL; } } @@ -1220,13 +1251,24 @@ ahc_platform_freeze_devq(struct ahc_softc *ahc, struct scb *scb) } void -ahc_platform_set_tags(struct ahc_softc *ahc, struct scsi_device *sdev, - struct ahc_devinfo *devinfo, ahc_queue_alg alg) +ahc_platform_set_tags(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, + ahc_queue_alg alg) { + struct scsi_target *starget; + struct ahc_linux_target *targ; struct ahc_linux_device *dev; + struct scsi_device *sdev; + u_int target_offset; int was_queuing; int now_queuing; + target_offset = devinfo->target; + if (devinfo->channel != 'A') + target_offset += 8; + starget = ahc->platform_data->starget[target_offset]; + targ = scsi_transport_target_data(starget); + BUG_ON(targ == NULL); + sdev = targ->sdev[devinfo->lun]; if (sdev == NULL) return; dev = scsi_transport_device_data(sdev); @@ -1359,15 +1401,11 @@ ahc_linux_device_queue_depth(struct scsi_device *sdev) tags = ahc_linux_user_tagdepth(ahc, &devinfo); if (tags != 0 && sdev->tagged_supported != 0) { - ahc_platform_set_tags(ahc, sdev, &devinfo, AHC_QUEUE_TAGGED); - ahc_send_async(ahc, devinfo.channel, devinfo.target, - devinfo.lun, AC_TRANSFER_NEG); + ahc_set_tags(ahc, &devinfo, AHC_QUEUE_TAGGED); ahc_print_devinfo(ahc, &devinfo); printf("Tagged Queuing enabled. Depth %d\n", tags); } else { - ahc_platform_set_tags(ahc, sdev, &devinfo, AHC_QUEUE_NONE); - ahc_send_async(ahc, devinfo.channel, devinfo.target, - devinfo.lun, AC_TRANSFER_NEG); + ahc_set_tags(ahc, &devinfo, AHC_QUEUE_NONE); } } @@ -1570,7 +1608,7 @@ ahc_linux_run_command(struct ahc_softc *ahc, struct ahc_linux_device *dev, * SCSI controller interrupt handler. */ irqreturn_t -ahc_linux_isr(int irq, void *dev_id) +ahc_linux_isr(int irq, void *dev_id, struct pt_regs * regs) { struct ahc_softc *ahc; u_long flags; @@ -1591,7 +1629,7 @@ ahc_platform_flushwork(struct ahc_softc *ahc) void ahc_send_async(struct ahc_softc *ahc, char channel, - u_int target, u_int lun, ac_code code) + u_int target, u_int lun, ac_code code, void *arg) { switch (code) { case AC_TRANSFER_NEG: @@ -1837,9 +1875,9 @@ ahc_linux_handle_scsi_status(struct ahc_softc *ahc, if (scb->flags & SCB_SENSE) { u_int sense_size; - sense_size = min(sizeof(struct scsi_sense_data) + sense_size = MIN(sizeof(struct scsi_sense_data) - ahc_get_sense_residual(scb), - (u_long)sizeof(cmd->sense_buffer)); + sizeof(cmd->sense_buffer)); memcpy(cmd->sense_buffer, ahc_get_sense_buf(ahc, scb), sense_size); if (sense_size < sizeof(cmd->sense_buffer)) @@ -1908,7 +1946,7 @@ ahc_linux_handle_scsi_status(struct ahc_softc *ahc, } ahc_set_transaction_status(scb, CAM_REQUEUE_REQ); ahc_set_scsi_status(scb, SCSI_STATUS_OK); - ahc_platform_set_tags(ahc, sdev, &devinfo, + ahc_platform_set_tags(ahc, &devinfo, (dev->flags & AHC_DEV_Q_BASIC) ? AHC_QUEUE_BASIC : AHC_QUEUE_TAGGED); break; @@ -1919,7 +1957,7 @@ ahc_linux_handle_scsi_status(struct ahc_softc *ahc, */ dev->openings = 1; ahc_set_scsi_status(scb, SCSI_STATUS_BUSY); - ahc_platform_set_tags(ahc, sdev, &devinfo, + ahc_platform_set_tags(ahc, &devinfo, (dev->flags & AHC_DEV_Q_BASIC) ? AHC_QUEUE_BASIC : AHC_QUEUE_TAGGED); break; @@ -2561,6 +2599,8 @@ ahc_linux_init(void) if (!ahc_linux_transport_template) return -ENODEV; + scsi_transport_reserve_target(ahc_linux_transport_template, + sizeof(struct ahc_linux_target)); scsi_transport_reserve_device(ahc_linux_transport_template, sizeof(struct ahc_linux_device)); diff --git a/trunk/drivers/scsi/aic7xxx/aic7xxx_osm.h b/trunk/drivers/scsi/aic7xxx/aic7xxx_osm.h index 85ae5d836fa4..d42a71ee076d 100644 --- a/trunk/drivers/scsi/aic7xxx/aic7xxx_osm.h +++ b/trunk/drivers/scsi/aic7xxx/aic7xxx_osm.h @@ -256,6 +256,7 @@ typedef enum { AHC_DEV_PERIODIC_OTAG = 0x40, /* Send OTAG to prevent starvation */ } ahc_linux_dev_flags; +struct ahc_linux_target; struct ahc_linux_device { /* * The number of transactions currently @@ -328,6 +329,12 @@ struct ahc_linux_device { #define AHC_OTAG_THRESH 500 }; +struct ahc_linux_target { + struct scsi_device *sdev[AHC_NUM_LUNS]; + struct ahc_transinfo last_tinfo; + struct ahc_softc *ahc; +}; + /********************* Definitions Required by the Core ***********************/ /* * Number of SG segments we require. So long as the S/G segments for @@ -526,6 +533,8 @@ ahc_unlock(struct ahc_softc *ahc, unsigned long *flags) #define PCIR_SUBVEND_0 0x2c #define PCIR_SUBDEV_0 0x2e +extern struct pci_driver aic7xxx_pci_driver; + typedef enum { AHC_POWER_STATE_D0, @@ -815,17 +824,17 @@ ahc_freeze_scb(struct scb *scb) } } -void ahc_platform_set_tags(struct ahc_softc *ahc, struct scsi_device *sdev, +void ahc_platform_set_tags(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, ahc_queue_alg); int ahc_platform_abort_scbs(struct ahc_softc *ahc, int target, char channel, int lun, u_int tag, role_t role, uint32_t status); irqreturn_t - ahc_linux_isr(int irq, void *dev_id); + ahc_linux_isr(int irq, void *dev_id, struct pt_regs * regs); void ahc_platform_flushwork(struct ahc_softc *ahc); void ahc_done(struct ahc_softc*, struct scb*); void ahc_send_async(struct ahc_softc *, char channel, - u_int target, u_int lun, ac_code); + u_int target, u_int lun, ac_code, void *); void ahc_print_path(struct ahc_softc *, struct scb *); void ahc_platform_dump_card_state(struct ahc_softc *ahc); diff --git a/trunk/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c b/trunk/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c index ea5687df732d..7e42f07a27f3 100644 --- a/trunk/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c +++ b/trunk/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c @@ -130,7 +130,7 @@ static struct pci_device_id ahc_linux_pci_id_table[] = { MODULE_DEVICE_TABLE(pci, ahc_linux_pci_id_table); -static struct pci_driver aic7xxx_pci_driver = { +struct pci_driver aic7xxx_pci_driver = { .name = "aic7xxx", .probe = ahc_linux_pci_dev_probe, .remove = ahc_linux_pci_dev_remove, @@ -246,7 +246,8 @@ ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent) int ahc_linux_pci_init(void) { - return pci_register_driver(&aic7xxx_pci_driver); + /* Translate error or zero return into zero or one */ + return pci_module_init(&aic7xxx_pci_driver) ? 0 : 1; } void diff --git a/trunk/drivers/scsi/aic7xxx/aic7xxx_pci.c b/trunk/drivers/scsi/aic7xxx/aic7xxx_pci.c index 09c8172c9e5e..63cab2d74552 100644 --- a/trunk/drivers/scsi/aic7xxx/aic7xxx_pci.c +++ b/trunk/drivers/scsi/aic7xxx/aic7xxx_pci.c @@ -168,7 +168,7 @@ static ahc_device_setup_t ahc_aha394XX_setup; static ahc_device_setup_t ahc_aha494XX_setup; static ahc_device_setup_t ahc_aha398XX_setup; -static struct ahc_pci_identity ahc_pci_ident_table [] = +struct ahc_pci_identity ahc_pci_ident_table [] = { /* aic7850 based controllers */ { @@ -559,7 +559,7 @@ static struct ahc_pci_identity ahc_pci_ident_table [] = } }; -static const u_int ahc_num_pci_devs = ARRAY_SIZE(ahc_pci_ident_table); +const u_int ahc_num_pci_devs = ARRAY_SIZE(ahc_pci_ident_table); #define AHC_394X_SLOT_CHANNEL_A 4 #define AHC_394X_SLOT_CHANNEL_B 5 diff --git a/trunk/drivers/scsi/aic7xxx/aic7xxx_proc.c b/trunk/drivers/scsi/aic7xxx/aic7xxx_proc.c index 99e5443e7535..5914b4aa4a8f 100644 --- a/trunk/drivers/scsi/aic7xxx/aic7xxx_proc.c +++ b/trunk/drivers/scsi/aic7xxx/aic7xxx_proc.c @@ -182,6 +182,7 @@ ahc_dump_target_state(struct ahc_softc *ahc, struct info_str *info, u_int our_id, char channel, u_int target_id, u_int target_offset) { + struct ahc_linux_target *targ; struct scsi_target *starget; struct ahc_initiator_tinfo *tinfo; struct ahc_tmode_tstate *tstate; @@ -197,6 +198,7 @@ ahc_dump_target_state(struct ahc_softc *ahc, struct info_str *info, starget = ahc->platform_data->starget[target_offset]; if (!starget) return; + targ = scsi_transport_target_data(starget); copy_info(info, "\tGoal: "); ahc_format_transinfo(info, &tinfo->goal); @@ -206,7 +208,7 @@ ahc_dump_target_state(struct ahc_softc *ahc, struct info_str *info, for (lun = 0; lun < AHC_NUM_LUNS; lun++) { struct scsi_device *sdev; - sdev = scsi_device_lookup_by_target(starget, lun); + sdev = targ->sdev[lun]; if (sdev == NULL) continue; @@ -381,11 +383,11 @@ ahc_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start, } copy_info(&info, "\n"); - max_targ = 16; + max_targ = 15; if ((ahc->features & (AHC_WIDE|AHC_TWIN)) == 0) - max_targ = 8; + max_targ = 7; - for (i = 0; i < max_targ; i++) { + for (i = 0; i <= max_targ; i++) { u_int our_id; u_int target_id; char channel; diff --git a/trunk/drivers/scsi/aic7xxx_old.c b/trunk/drivers/scsi/aic7xxx_old.c index 46eed10b25d9..10353379a074 100644 --- a/trunk/drivers/scsi/aic7xxx_old.c +++ b/trunk/drivers/scsi/aic7xxx_old.c @@ -780,26 +780,24 @@ typedef enum { } ahc_bugs; struct aic7xxx_scb { - struct aic7xxx_hwscb *hscb; /* corresponding hardware scb */ - struct scsi_cmnd *cmd; /* scsi_cmnd for this scb */ - struct aic7xxx_scb *q_next; /* next scb in queue */ - volatile scb_flag_type flags; /* current state of scb */ - struct hw_scatterlist *sg_list; /* SG list in adapter format */ - unsigned char tag_action; - unsigned char sg_count; - unsigned char *sense_cmd; /* - * Allocate 6 characters for - * sense command. - */ - unsigned char *cmnd; - unsigned int sg_length; /* - * We init this during - * buildscb so we don't have - * to calculate anything during - * underflow/overflow/stat code - */ - void *kmalloc_ptr; - struct aic7xxx_scb_dma *scb_dma; + struct aic7xxx_hwscb *hscb; /* corresponding hardware scb */ + Scsi_Cmnd *cmd; /* Scsi_Cmnd for this scb */ + struct aic7xxx_scb *q_next; /* next scb in queue */ + volatile scb_flag_type flags; /* current state of scb */ + struct hw_scatterlist *sg_list; /* SG list in adapter format */ + unsigned char tag_action; + unsigned char sg_count; + unsigned char *sense_cmd; /* + * Allocate 6 characters for + * sense command. + */ + unsigned char *cmnd; + unsigned int sg_length; /* We init this during buildscb so we + * don't have to calculate anything + * during underflow/overflow/stat code + */ + void *kmalloc_ptr; + struct aic7xxx_scb_dma *scb_dma; }; /* @@ -920,77 +918,79 @@ struct aic7xxx_host { * We are grouping things here....first, items that get either read or * written with nearly every interrupt */ - volatile long flags; - ahc_feature features; /* chip features */ - unsigned long base; /* card base address */ - volatile unsigned char __iomem *maddr; /* memory mapped address */ - unsigned long isr_count; /* Interrupt count */ - unsigned long spurious_int; - scb_data_type *scb_data; - struct aic7xxx_cmd_queue { - struct scsi_cmnd *head; - struct scsi_cmnd *tail; - } completeq; + volatile long flags; + ahc_feature features; /* chip features */ + unsigned long base; /* card base address */ + volatile unsigned char __iomem *maddr; /* memory mapped address */ + unsigned long isr_count; /* Interrupt count */ + unsigned long spurious_int; + scb_data_type *scb_data; + struct aic7xxx_cmd_queue { + Scsi_Cmnd *head; + Scsi_Cmnd *tail; + } completeq; - /* - * Things read/written on nearly every entry into aic7xxx_queue() - */ - volatile scb_queue_type waiting_scbs; - unsigned char unpause; /* unpause value for HCNTRL */ - unsigned char pause; /* pause value for HCNTRL */ - volatile unsigned char qoutfifonext; - volatile unsigned char activescbs; /* active scbs */ - volatile unsigned char max_activescbs; - volatile unsigned char qinfifonext; - volatile unsigned char *untagged_scbs; - volatile unsigned char *qoutfifo; - volatile unsigned char *qinfifo; - - unsigned char dev_last_queue_full[MAX_TARGETS]; - unsigned char dev_last_queue_full_count[MAX_TARGETS]; - unsigned short ultraenb; /* Gets downloaded to card as a bitmap */ - unsigned short discenable; /* Gets downloaded to card as a bitmap */ - transinfo_type user[MAX_TARGETS]; - - unsigned char msg_buf[13]; /* The message for the target */ - unsigned char msg_type; + /* + * Things read/written on nearly every entry into aic7xxx_queue() + */ + volatile scb_queue_type waiting_scbs; + unsigned char unpause; /* unpause value for HCNTRL */ + unsigned char pause; /* pause value for HCNTRL */ + volatile unsigned char qoutfifonext; + volatile unsigned char activescbs; /* active scbs */ + volatile unsigned char max_activescbs; + volatile unsigned char qinfifonext; + volatile unsigned char *untagged_scbs; + volatile unsigned char *qoutfifo; + volatile unsigned char *qinfifo; + + unsigned char dev_last_queue_full[MAX_TARGETS]; + unsigned char dev_last_queue_full_count[MAX_TARGETS]; + unsigned short ultraenb; /* Gets downloaded to card as a + bitmap */ + unsigned short discenable; /* Gets downloaded to card as a + bitmap */ + transinfo_type user[MAX_TARGETS]; + + unsigned char msg_buf[13]; /* The message for the target */ + unsigned char msg_type; #define MSG_TYPE_NONE 0x00 #define MSG_TYPE_INITIATOR_MSGOUT 0x01 #define MSG_TYPE_INITIATOR_MSGIN 0x02 - unsigned char msg_len; /* Length of message */ - unsigned char msg_index; /* Index into msg_buf array */ + unsigned char msg_len; /* Length of message */ + unsigned char msg_index; /* Index into msg_buf array */ - /* - * We put the less frequently used host structure items - * after the more frequently used items to try and ease - * the burden on the cache subsystem. - * These entries are not *commonly* accessed, whereas - * the preceding entries are accessed very often. - */ + /* + * We put the less frequently used host structure items after the more + * frequently used items to try and ease the burden on the cache subsystem. + * These entries are not *commonly* accessed, whereas the preceding entries + * are accessed very often. + */ + + unsigned int irq; /* IRQ for this adapter */ + int instance; /* aic7xxx instance number */ + int scsi_id; /* host adapter SCSI ID */ + int scsi_id_b; /* channel B for twin adapters */ + unsigned int bios_address; + int board_name_index; + unsigned short bios_control; /* bios control - SEEPROM */ + unsigned short adapter_control; /* adapter control - SEEPROM */ + struct pci_dev *pdev; + unsigned char pci_bus; + unsigned char pci_device_fn; + struct seeprom_config sc; + unsigned short sc_type; + unsigned short sc_size; + struct aic7xxx_host *next; /* allow for multiple IRQs */ + struct Scsi_Host *host; /* pointer to scsi host */ + struct list_head aic_devs; /* all aic_dev structs on host */ + int host_no; /* SCSI host number */ + unsigned long mbase; /* I/O memory address */ + ahc_chip chip; /* chip type */ + ahc_bugs bugs; + dma_addr_t fifo_dma; /* DMA handle for fifo arrays */ - unsigned int irq; /* IRQ for this adapter */ - int instance; /* aic7xxx instance number */ - int scsi_id; /* host adapter SCSI ID */ - int scsi_id_b; /* channel B for twin adapters */ - unsigned int bios_address; - int board_name_index; - unsigned short bios_control; /* bios control - SEEPROM */ - unsigned short adapter_control; /* adapter control - SEEPROM */ - struct pci_dev *pdev; - unsigned char pci_bus; - unsigned char pci_device_fn; - struct seeprom_config sc; - unsigned short sc_type; - unsigned short sc_size; - struct aic7xxx_host *next; /* allow for multiple IRQs */ - struct Scsi_Host *host; /* pointer to scsi host */ - struct list_head aic_devs; /* all aic_dev structs on host */ - int host_no; /* SCSI host number */ - unsigned long mbase; /* I/O memory address */ - ahc_chip chip; /* chip type */ - ahc_bugs bugs; - dma_addr_t fifo_dma; /* DMA handle for fifo arrays */ }; /* @@ -1271,7 +1271,7 @@ static void aic7xxx_set_syncrate(struct aic7xxx_host *p, static void aic7xxx_set_width(struct aic7xxx_host *p, int target, int channel, int lun, unsigned int width, unsigned int type, struct aic_dev_data *aic_dev); -static void aic7xxx_panic_abort(struct aic7xxx_host *p, struct scsi_cmnd *cmd); +static void aic7xxx_panic_abort(struct aic7xxx_host *p, Scsi_Cmnd *cmd); static void aic7xxx_print_card(struct aic7xxx_host *p); static void aic7xxx_print_scratch_ram(struct aic7xxx_host *p); static void aic7xxx_print_sequencer(struct aic7xxx_host *p, int downloaded); @@ -2626,7 +2626,7 @@ aic7xxx_allocate_scb(struct aic7xxx_host *p) * we're finished. This function queues the completed commands. *-F*************************************************************************/ static void -aic7xxx_queue_cmd_complete(struct aic7xxx_host *p, struct scsi_cmnd *cmd) +aic7xxx_queue_cmd_complete(struct aic7xxx_host *p, Scsi_Cmnd *cmd) { aic7xxx_position(cmd) = SCB_LIST_NULL; cmd->host_scribble = (char *)p->completeq.head; @@ -2640,16 +2640,18 @@ aic7xxx_queue_cmd_complete(struct aic7xxx_host *p, struct scsi_cmnd *cmd) * Description: * Process the completed command queue. *-F*************************************************************************/ -static void aic7xxx_done_cmds_complete(struct aic7xxx_host *p) +static void +aic7xxx_done_cmds_complete(struct aic7xxx_host *p) { - struct scsi_cmnd *cmd; - - while (p->completeq.head != NULL) { - cmd = p->completeq.head; - p->completeq.head = (struct scsi_cmnd *) cmd->host_scribble; - cmd->host_scribble = NULL; - cmd->scsi_done(cmd); - } + Scsi_Cmnd *cmd; + + while (p->completeq.head != NULL) + { + cmd = p->completeq.head; + p->completeq.head = (Scsi_Cmnd *)cmd->host_scribble; + cmd->host_scribble = NULL; + cmd->scsi_done(cmd); + } } /*+F************************************************************************* @@ -2685,11 +2687,11 @@ aic7xxx_free_scb(struct aic7xxx_host *p, struct aic7xxx_scb *scb) static void aic7xxx_done(struct aic7xxx_host *p, struct aic7xxx_scb *scb) { - struct scsi_cmnd *cmd = scb->cmd; - struct aic_dev_data *aic_dev = cmd->device->hostdata; - int tindex = TARGET_INDEX(cmd); - struct aic7xxx_scb *scbp; - unsigned char queue_depth; + Scsi_Cmnd *cmd = scb->cmd; + struct aic_dev_data *aic_dev = cmd->device->hostdata; + int tindex = TARGET_INDEX(cmd); + struct aic7xxx_scb *scbp; + unsigned char queue_depth; if (cmd->use_sg > 1) { @@ -2889,7 +2891,7 @@ aic7xxx_done(struct aic7xxx_host *p, struct aic7xxx_scb *scb) * aic7xxx_run_done_queue * * Description: - * Calls the aic7xxx_done() for the scsi_cmnd of each scb in the + * Calls the aic7xxx_done() for the Scsi_Cmnd of each scb in the * aborted list, and adds each scb to the free list. If complete * is TRUE, we also process the commands complete list. *-F*************************************************************************/ @@ -3824,9 +3826,9 @@ aic7xxx_construct_wdtr(struct aic7xxx_host *p, unsigned char bus_width) static void aic7xxx_calculate_residual (struct aic7xxx_host *p, struct aic7xxx_scb *scb) { - struct aic7xxx_hwscb *hscb; - struct scsi_cmnd *cmd; - int actual, i; + struct aic7xxx_hwscb *hscb; + Scsi_Cmnd *cmd; + int actual, i; cmd = scb->cmd; hscb = scb->hscb; @@ -4217,20 +4219,20 @@ aic7xxx_handle_seqint(struct aic7xxx_host *p, unsigned char intstat) case BAD_STATUS: { - unsigned char scb_index; - struct aic7xxx_hwscb *hscb; - struct scsi_cmnd *cmd; - - /* The sequencer will notify us when a command has an error that - * would be of interest to the kernel. This allows us to leave - * the sequencer running in the common case of command completes - * without error. The sequencer will have DMA'd the SCB back - * up to us, so we can reference the drivers SCB array. - * - * Set the default return value to 0 indicating not to send - * sense. The sense code will change this if needed and this - * reduces code duplication. - */ + unsigned char scb_index; + struct aic7xxx_hwscb *hscb; + Scsi_Cmnd *cmd; + + /* The sequencer will notify us when a command has an error that + * would be of interest to the kernel. This allows us to leave + * the sequencer running in the common case of command completes + * without error. The sequencer will have DMA'd the SCB back + * up to us, so we can reference the drivers SCB array. + * + * Set the default return value to 0 indicating not to send + * sense. The sense code will change this if needed and this + * reduces code duplication. + */ aic_outb(p, 0, RETURN_1); scb_index = aic_inb(p, SCB_TAG); if (scb_index > p->scb_data->numscbs) @@ -5798,9 +5800,9 @@ aic7xxx_handle_scsiint(struct aic7xxx_host *p, unsigned char intstat) } else if ((status & SELTO) != 0) { - unsigned char scbptr; - unsigned char nextscb; - struct scsi_cmnd *cmd; + unsigned char scbptr; + unsigned char nextscb; + Scsi_Cmnd *cmd; scbptr = aic_inb(p, WAITING_SCBH); if (scbptr > p->scb_data->maxhscbs) @@ -5939,11 +5941,11 @@ aic7xxx_handle_scsiint(struct aic7xxx_host *p, unsigned char intstat) /* * Determine the bus phase and queue an appropriate message. */ - char *phase; - struct scsi_cmnd *cmd; - unsigned char mesg_out = MSG_NOOP; - unsigned char lastphase = aic_inb(p, LASTPHASE); - unsigned char sstat2 = aic_inb(p, SSTAT2); + char *phase; + Scsi_Cmnd *cmd; + unsigned char mesg_out = MSG_NOOP; + unsigned char lastphase = aic_inb(p, LASTPHASE); + unsigned char sstat2 = aic_inb(p, SSTAT2); cmd = scb->cmd; switch (lastphase) @@ -6246,10 +6248,10 @@ aic7xxx_check_scbs(struct aic7xxx_host *p, char *buffer) static void aic7xxx_handle_command_completion_intr(struct aic7xxx_host *p) { - struct aic7xxx_scb *scb = NULL; - struct aic_dev_data *aic_dev; - struct scsi_cmnd *cmd; - unsigned char scb_index, tindex; + struct aic7xxx_scb *scb = NULL; + struct aic_dev_data *aic_dev; + Scsi_Cmnd *cmd; + unsigned char scb_index, tindex; #ifdef AIC7XXX_VERBOSE_DEBUGGING if( (p->isr_count < 16) && (aic7xxx_verbose > 0xffff) ) @@ -6345,12 +6347,12 @@ aic7xxx_handle_command_completion_intr(struct aic7xxx_host *p) * SCSI controller interrupt handler. *-F*************************************************************************/ static void -aic7xxx_isr(void *dev_id) +aic7xxx_isr(int irq, void *dev_id, struct pt_regs *regs) { struct aic7xxx_host *p; unsigned char intstat; - p = dev_id; + p = (struct aic7xxx_host *)dev_id; /* * Just a few sanity checks. Make sure that we have an int pending. @@ -6477,7 +6479,7 @@ aic7xxx_isr(void *dev_id) * anything like it, please inform the Gross Hack Police immediately *-F*************************************************************************/ static irqreturn_t -do_aic7xxx_isr(int irq, void *dev_id) +do_aic7xxx_isr(int irq, void *dev_id, struct pt_regs *regs) { unsigned long cpu_flags; struct aic7xxx_host *p; @@ -6489,7 +6491,7 @@ do_aic7xxx_isr(int irq, void *dev_id) p->flags |= AHC_IN_ISR; do { - aic7xxx_isr(dev_id); + aic7xxx_isr(irq, dev_id, regs); } while ( (aic_inb(p, INTSTAT) & INT_PEND) ); aic7xxx_done_cmds_complete(p); aic7xxx_run_waiting_queues(p); @@ -10129,8 +10131,9 @@ aic7xxx_detect(struct scsi_host_template *template) * Description: * Build a SCB. *-F*************************************************************************/ -static void aic7xxx_buildscb(struct aic7xxx_host *p, struct scsi_cmnd *cmd, - struct aic7xxx_scb *scb) +static void +aic7xxx_buildscb(struct aic7xxx_host *p, Scsi_Cmnd *cmd, + struct aic7xxx_scb *scb) { unsigned short mask; struct aic7xxx_hwscb *hscb; @@ -10282,7 +10285,8 @@ static void aic7xxx_buildscb(struct aic7xxx_host *p, struct scsi_cmnd *cmd, * Description: * Queue a SCB to the controller. *-F*************************************************************************/ -static int aic7xxx_queue(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *)) +static int +aic7xxx_queue(Scsi_Cmnd *cmd, void (*fn)(Scsi_Cmnd *)) { struct aic7xxx_host *p; struct aic7xxx_scb *scb; @@ -10315,11 +10319,11 @@ static int aic7xxx_queue(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *)) } scb->cmd = cmd; - /* - * Make sure the scsi_cmnd pointer is saved, the struct it points to - * is set up properly, and the parity error flag is reset, then send - * the SCB to the sequencer and watch the fun begin. - */ + /* + * Make sure the Scsi_Cmnd pointer is saved, the struct it points to + * is set up properly, and the parity error flag is reset, then send + * the SCB to the sequencer and watch the fun begin. + */ aic7xxx_position(cmd) = scb->hscb->tag; cmd->scsi_done = fn; cmd->result = DID_OK; @@ -10352,7 +10356,8 @@ static int aic7xxx_queue(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *)) * aborted, then we will reset the channel and have all devices renegotiate. * Returns an enumerated type that indicates the status of the operation. *-F*************************************************************************/ -static int __aic7xxx_bus_device_reset(struct scsi_cmnd *cmd) +static int +__aic7xxx_bus_device_reset(Scsi_Cmnd *cmd) { struct aic7xxx_host *p; struct aic7xxx_scb *scb; @@ -10377,7 +10382,7 @@ static int __aic7xxx_bus_device_reset(struct scsi_cmnd *cmd) hscb = scb->hscb; - aic7xxx_isr(p); + aic7xxx_isr(p->irq, (void *)p, NULL); aic7xxx_done_cmds_complete(p); /* If the command was already complete or just completed, then we didn't * do a reset, return FAILED */ @@ -10545,7 +10550,8 @@ static int __aic7xxx_bus_device_reset(struct scsi_cmnd *cmd) return SUCCESS; } -static int aic7xxx_bus_device_reset(struct scsi_cmnd *cmd) +static int +aic7xxx_bus_device_reset(Scsi_Cmnd *cmd) { int rc; @@ -10564,7 +10570,8 @@ static int aic7xxx_bus_device_reset(struct scsi_cmnd *cmd) * Description: * Abort the current SCSI command(s). *-F*************************************************************************/ -static void aic7xxx_panic_abort(struct aic7xxx_host *p, struct scsi_cmnd *cmd) +static void +aic7xxx_panic_abort(struct aic7xxx_host *p, Scsi_Cmnd *cmd) { printk("aic7xxx driver version %s\n", AIC7XXX_C_VERSION); @@ -10588,7 +10595,8 @@ static void aic7xxx_panic_abort(struct aic7xxx_host *p, struct scsi_cmnd *cmd) * Description: * Abort the current SCSI command(s). *-F*************************************************************************/ -static int __aic7xxx_abort(struct scsi_cmnd *cmd) +static int +__aic7xxx_abort(Scsi_Cmnd *cmd) { struct aic7xxx_scb *scb = NULL; struct aic7xxx_host *p; @@ -10608,7 +10616,7 @@ static int __aic7xxx_abort(struct scsi_cmnd *cmd) else return FAILED; - aic7xxx_isr(p); + aic7xxx_isr(p->irq, (void *)p, NULL); aic7xxx_done_cmds_complete(p); /* If the command was already complete or just completed, then we didn't * do a reset, return FAILED */ @@ -10805,7 +10813,8 @@ static int __aic7xxx_abort(struct scsi_cmnd *cmd) return SUCCESS; } -static int aic7xxx_abort(struct scsi_cmnd *cmd) +static int +aic7xxx_abort(Scsi_Cmnd *cmd) { int rc; @@ -10827,7 +10836,8 @@ static int aic7xxx_abort(struct scsi_cmnd *cmd) * DEVICE RESET message - on the offending target before pulling * the SCSI bus reset line. *-F*************************************************************************/ -static int aic7xxx_reset(struct scsi_cmnd *cmd) +static int +aic7xxx_reset(Scsi_Cmnd *cmd) { struct aic7xxx_scb *scb; struct aic7xxx_host *p; @@ -10863,7 +10873,7 @@ static int aic7xxx_reset(struct scsi_cmnd *cmd) while((aic_inb(p, INTSTAT) & INT_PEND) && !(p->flags & AHC_IN_ISR)) { - aic7xxx_isr(p); + aic7xxx_isr(p->irq, p, (void *)NULL ); pause_sequencer(p); } aic7xxx_done_cmds_complete(p); diff --git a/trunk/drivers/scsi/aic94xx/Kconfig b/trunk/drivers/scsi/aic94xx/Kconfig index c83fe751d0bb..0ed391d8ee84 100644 --- a/trunk/drivers/scsi/aic94xx/Kconfig +++ b/trunk/drivers/scsi/aic94xx/Kconfig @@ -28,7 +28,6 @@ config SCSI_AIC94XX tristate "Adaptec AIC94xx SAS/SATA support" depends on PCI select SCSI_SAS_LIBSAS - select FW_LOADER help This driver supports Adaptec's SAS/SATA 3Gb/s 64 bit PCI-X AIC94xx chip based host adapters. diff --git a/trunk/drivers/scsi/aic94xx/aic94xx_hwi.c b/trunk/drivers/scsi/aic94xx/aic94xx_hwi.c index af7e01134364..1d8c5e5f442e 100644 --- a/trunk/drivers/scsi/aic94xx/aic94xx_hwi.c +++ b/trunk/drivers/scsi/aic94xx/aic94xx_hwi.c @@ -112,21 +112,6 @@ static int asd_init_phy(struct asd_phy *phy) return 0; } -static void asd_init_ports(struct asd_ha_struct *asd_ha) -{ - int i; - - spin_lock_init(&asd_ha->asd_ports_lock); - for (i = 0; i < ASD_MAX_PHYS; i++) { - struct asd_port *asd_port = &asd_ha->asd_ports[i]; - - memset(asd_port->sas_addr, 0, SAS_ADDR_SIZE); - memset(asd_port->attached_sas_addr, 0, SAS_ADDR_SIZE); - asd_port->phy_mask = 0; - asd_port->num_phys = 0; - } -} - static int asd_init_phys(struct asd_ha_struct *asd_ha) { u8 i; @@ -136,7 +121,6 @@ static int asd_init_phys(struct asd_ha_struct *asd_ha) struct asd_phy *phy = &asd_ha->phys[i]; phy->phy_desc = &asd_ha->hw_prof.phy_desc[i]; - phy->asd_port = NULL; phy->sas_phy.enabled = 0; phy->sas_phy.id = i; @@ -674,8 +658,6 @@ int asd_init_hw(struct asd_ha_struct *asd_ha) goto Out; } - asd_init_ports(asd_ha); - err = asd_init_scbs(asd_ha); if (err) { asd_printk("couldn't initialize scbs for %s\n", @@ -1014,10 +996,11 @@ static inline void asd_hst_pcix_isr(struct asd_ha_struct *asd_ha) * asd_hw_isr -- host adapter interrupt service routine * @irq: ignored * @dev_id: pointer to host adapter structure + * @regs: ignored * * The ISR processes done list entries and level 3 error handling. */ -irqreturn_t asd_hw_isr(int irq, void *dev_id) +irqreturn_t asd_hw_isr(int irq, void *dev_id, struct pt_regs *regs) { struct asd_ha_struct *asd_ha = dev_id; u32 chimint = asd_read_reg_dword(asd_ha, CHIMINT); diff --git a/trunk/drivers/scsi/aic94xx/aic94xx_hwi.h b/trunk/drivers/scsi/aic94xx/aic94xx_hwi.h index c6c3d18222fa..8498144aa5e1 100644 --- a/trunk/drivers/scsi/aic94xx/aic94xx_hwi.h +++ b/trunk/drivers/scsi/aic94xx/aic94xx_hwi.h @@ -46,7 +46,6 @@ #define PCI_DEVICE_ID_ADAPTEC2_RAZOR10 0x410 #define PCI_DEVICE_ID_ADAPTEC2_RAZOR12 0x412 #define PCI_DEVICE_ID_ADAPTEC2_RAZOR1E 0x41E -#define PCI_DEVICE_ID_ADAPTEC2_RAZOR1F 0x41F #define PCI_DEVICE_ID_ADAPTEC2_RAZOR30 0x430 #define PCI_DEVICE_ID_ADAPTEC2_RAZOR32 0x432 #define PCI_DEVICE_ID_ADAPTEC2_RAZOR3E 0x43E @@ -193,16 +192,6 @@ struct asd_seq_data { struct asd_ascb **escb_arr; /* array of pointers to escbs */ }; -/* This is an internal port structure. These are used to get accurate - * phy_mask for updating DDB 0. - */ -struct asd_port { - u8 sas_addr[SAS_ADDR_SIZE]; - u8 attached_sas_addr[SAS_ADDR_SIZE]; - u32 phy_mask; - int num_phys; -}; - /* This is the Host Adapter structure. It describes the hardware * SAS adapter. */ @@ -221,8 +210,6 @@ struct asd_ha_struct { struct hw_profile hw_prof; struct asd_phy phys[ASD_MAX_PHYS]; - spinlock_t asd_ports_lock; - struct asd_port asd_ports[ASD_MAX_PHYS]; struct asd_sas_port ports[ASD_MAX_PHYS]; struct dma_pool *scb_pool; @@ -384,7 +371,7 @@ static inline void asd_ascb_free_list(struct asd_ascb *ascb_list) /* ---------- Function declarations ---------- */ int asd_init_hw(struct asd_ha_struct *asd_ha); -irqreturn_t asd_hw_isr(int irq, void *dev_id); +irqreturn_t asd_hw_isr(int irq, void *dev_id, struct pt_regs *regs); struct asd_ascb *asd_ascb_alloc_list(struct asd_ha_struct diff --git a/trunk/drivers/scsi/aic94xx/aic94xx_init.c b/trunk/drivers/scsi/aic94xx/aic94xx_init.c index 57c5ba4043f2..734adc9d5206 100644 --- a/trunk/drivers/scsi/aic94xx/aic94xx_init.c +++ b/trunk/drivers/scsi/aic94xx/aic94xx_init.c @@ -309,29 +309,11 @@ static ssize_t asd_show_dev_pcba_sn(struct device *dev, } static DEVICE_ATTR(pcba_sn, S_IRUGO, asd_show_dev_pcba_sn, NULL); -static int asd_create_dev_attrs(struct asd_ha_struct *asd_ha) +static void asd_create_dev_attrs(struct asd_ha_struct *asd_ha) { - int err; - - err = device_create_file(&asd_ha->pcidev->dev, &dev_attr_revision); - if (err) - return err; - - err = device_create_file(&asd_ha->pcidev->dev, &dev_attr_bios_build); - if (err) - goto err_rev; - - err = device_create_file(&asd_ha->pcidev->dev, &dev_attr_pcba_sn); - if (err) - goto err_biosb; - - return 0; - -err_biosb: - device_remove_file(&asd_ha->pcidev->dev, &dev_attr_bios_build); -err_rev: - device_remove_file(&asd_ha->pcidev->dev, &dev_attr_revision); - return err; + device_create_file(&asd_ha->pcidev->dev, &dev_attr_revision); + device_create_file(&asd_ha->pcidev->dev, &dev_attr_bios_build); + device_create_file(&asd_ha->pcidev->dev, &dev_attr_pcba_sn); } static void asd_remove_dev_attrs(struct asd_ha_struct *asd_ha) @@ -663,9 +645,7 @@ static int __devinit asd_pci_probe(struct pci_dev *dev, } ASD_DPRINTK("escbs posted\n"); - err = asd_create_dev_attrs(asd_ha); - if (err) - goto Err_dev_attrs; + asd_create_dev_attrs(asd_ha); err = asd_register_sas_ha(asd_ha); if (err) @@ -688,7 +668,6 @@ static int __devinit asd_pci_probe(struct pci_dev *dev, asd_unregister_sas_ha(asd_ha); Err_reg_sas: asd_remove_dev_attrs(asd_ha); -Err_dev_attrs: Err_escbs: asd_disable_ints(asd_ha); free_irq(dev->irq, asd_ha); @@ -775,9 +754,9 @@ static ssize_t asd_version_show(struct device_driver *driver, char *buf) } static DRIVER_ATTR(version, S_IRUGO, asd_version_show, NULL); -static int asd_create_driver_attrs(struct device_driver *driver) +static void asd_create_driver_attrs(struct device_driver *driver) { - return driver_create_file(driver, &driver_attr_version); + driver_create_file(driver, &driver_attr_version); } static void asd_remove_driver_attrs(struct device_driver *driver) @@ -786,6 +765,8 @@ static void asd_remove_driver_attrs(struct device_driver *driver) } static struct sas_domain_function_template aic94xx_transport_functions = { + .lldd_port_formed = asd_update_port_links, + .lldd_dev_found = asd_dev_found, .lldd_dev_gone = asd_dev_gone, @@ -812,8 +793,6 @@ static const struct pci_device_id aic94xx_pci_table[] __devinitdata = { 0, 0, 1}, {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR1E), 0, 0, 1}, - {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR1F), - 0, 0, 1}, {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR30), 0, 0, 2}, {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR32), @@ -855,14 +834,10 @@ static int __init aic94xx_init(void) if (err) goto out_release_transport; - err = asd_create_driver_attrs(&aic94xx_pci_driver.driver); - if (err) - goto out_unregister_pcidrv; + asd_create_driver_attrs(&aic94xx_pci_driver.driver); return err; - out_unregister_pcidrv: - pci_unregister_driver(&aic94xx_pci_driver); out_release_transport: sas_release_transport(aic94xx_transport_template); out_destroy_caches: diff --git a/trunk/drivers/scsi/aic94xx/aic94xx_reg_def.h b/trunk/drivers/scsi/aic94xx/aic94xx_reg_def.h index a11f4e6d8bd9..b79f45f3ad47 100644 --- a/trunk/drivers/scsi/aic94xx/aic94xx_reg_def.h +++ b/trunk/drivers/scsi/aic94xx/aic94xx_reg_def.h @@ -2000,7 +2000,7 @@ * The host accesses this scratch in a different manner from the * central sequencer. The sequencer has to use CSEQ registers CSCRPAGE * and CMnSCRPAGE to access the scratch memory. A flat mapping of the - * scratch memory is available for software convenience and to prevent + * scratch memory is avaliable for software convenience and to prevent * corruption while the sequencer is running. This memory is mapped * onto addresses 800h - BFFh, total of 400h bytes. * diff --git a/trunk/drivers/scsi/aic94xx/aic94xx_sas.h b/trunk/drivers/scsi/aic94xx/aic94xx_sas.h index 9050e93bfd5e..64d231712345 100644 --- a/trunk/drivers/scsi/aic94xx/aic94xx_sas.h +++ b/trunk/drivers/scsi/aic94xx/aic94xx_sas.h @@ -733,7 +733,6 @@ struct asd_phy { struct sas_identify_frame *identify_frame; struct asd_dma_tok *id_frm_tok; - struct asd_port *asd_port; u8 frame_rcvd[ASD_EDB_SIZE]; }; diff --git a/trunk/drivers/scsi/aic94xx/aic94xx_scb.c b/trunk/drivers/scsi/aic94xx/aic94xx_scb.c index b15caf1c8fa2..7ee49b51b724 100644 --- a/trunk/drivers/scsi/aic94xx/aic94xx_scb.c +++ b/trunk/drivers/scsi/aic94xx/aic94xx_scb.c @@ -168,70 +168,6 @@ static inline void asd_get_attached_sas_addr(struct asd_phy *phy, u8 *sas_addr) } } -static void asd_form_port(struct asd_ha_struct *asd_ha, struct asd_phy *phy) -{ - int i; - struct asd_port *free_port = NULL; - struct asd_port *port; - struct asd_sas_phy *sas_phy = &phy->sas_phy; - unsigned long flags; - - spin_lock_irqsave(&asd_ha->asd_ports_lock, flags); - if (!phy->asd_port) { - for (i = 0; i < ASD_MAX_PHYS; i++) { - port = &asd_ha->asd_ports[i]; - - /* Check for wide port */ - if (port->num_phys > 0 && - memcmp(port->sas_addr, sas_phy->sas_addr, - SAS_ADDR_SIZE) == 0 && - memcmp(port->attached_sas_addr, - sas_phy->attached_sas_addr, - SAS_ADDR_SIZE) == 0) { - break; - } - - /* Find a free port */ - if (port->num_phys == 0 && free_port == NULL) { - free_port = port; - } - } - - /* Use a free port if this doesn't form a wide port */ - if (i >= ASD_MAX_PHYS) { - port = free_port; - BUG_ON(!port); - memcpy(port->sas_addr, sas_phy->sas_addr, - SAS_ADDR_SIZE); - memcpy(port->attached_sas_addr, - sas_phy->attached_sas_addr, - SAS_ADDR_SIZE); - } - port->num_phys++; - port->phy_mask |= (1U << sas_phy->id); - phy->asd_port = port; - } - ASD_DPRINTK("%s: updating phy_mask 0x%x for phy%d\n", - __FUNCTION__, phy->asd_port->phy_mask, sas_phy->id); - asd_update_port_links(asd_ha, phy); - spin_unlock_irqrestore(&asd_ha->asd_ports_lock, flags); -} - -static void asd_deform_port(struct asd_ha_struct *asd_ha, struct asd_phy *phy) -{ - struct asd_port *port = phy->asd_port; - struct asd_sas_phy *sas_phy = &phy->sas_phy; - unsigned long flags; - - spin_lock_irqsave(&asd_ha->asd_ports_lock, flags); - if (port) { - port->num_phys--; - port->phy_mask &= ~(1U << sas_phy->id); - phy->asd_port = NULL; - } - spin_unlock_irqrestore(&asd_ha->asd_ports_lock, flags); -} - static inline void asd_bytes_dmaed_tasklet(struct asd_ascb *ascb, struct done_list_struct *dl, int edb_id, int phy_id) @@ -251,7 +187,6 @@ static inline void asd_bytes_dmaed_tasklet(struct asd_ascb *ascb, asd_get_attached_sas_addr(phy, phy->sas_phy.attached_sas_addr); spin_unlock_irqrestore(&phy->sas_phy.frame_rcvd_lock, flags); asd_dump_frame_rcvd(phy, dl); - asd_form_port(ascb->ha, phy); sas_ha->notify_port_event(&phy->sas_phy, PORTE_BYTES_DMAED); } @@ -262,7 +197,6 @@ static inline void asd_link_reset_err_tasklet(struct asd_ascb *ascb, struct asd_ha_struct *asd_ha = ascb->ha; struct sas_ha_struct *sas_ha = &asd_ha->sas_ha; struct asd_sas_phy *sas_phy = sas_ha->sas_phy[phy_id]; - struct asd_phy *phy = &asd_ha->phys[phy_id]; u8 lr_error = dl->status_block[1]; u8 retries_left = dl->status_block[2]; @@ -287,7 +221,6 @@ static inline void asd_link_reset_err_tasklet(struct asd_ascb *ascb, asd_turn_led(asd_ha, phy_id, 0); sas_phy_disconnected(sas_phy); - asd_deform_port(asd_ha, phy); sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); if (retries_left == 0) { @@ -315,8 +248,6 @@ static inline void asd_primitive_rcvd_tasklet(struct asd_ascb *ascb, unsigned long flags; struct sas_ha_struct *sas_ha = &ascb->ha->sas_ha; struct asd_sas_phy *sas_phy = sas_ha->sas_phy[phy_id]; - struct asd_ha_struct *asd_ha = ascb->ha; - struct asd_phy *phy = &asd_ha->phys[phy_id]; u8 reg = dl->status_block[1]; u32 cont = dl->status_block[2] << ((reg & 3)*8); @@ -353,7 +284,6 @@ static inline void asd_primitive_rcvd_tasklet(struct asd_ascb *ascb, phy_id); /* The sequencer disables all phys on that port. * We have to re-enable the phys ourselves. */ - asd_deform_port(asd_ha, phy); sas_ha->notify_port_event(sas_phy, PORTE_HARD_RESET); break; @@ -421,7 +351,6 @@ static void escb_tasklet_complete(struct asd_ascb *ascb, u8 sb_opcode = dl->status_block[0]; int phy_id = sb_opcode & DL_PHY_MASK; struct asd_sas_phy *sas_phy = sas_ha->sas_phy[phy_id]; - struct asd_phy *phy = &asd_ha->phys[phy_id]; if (edb > 6 || edb < 0) { ASD_DPRINTK("edb is 0x%x! dl->opcode is 0x%x\n", @@ -466,7 +395,6 @@ static void escb_tasklet_complete(struct asd_ascb *ascb, asd_turn_led(asd_ha, phy_id, 0); /* the device is gone */ sas_phy_disconnected(sas_phy); - asd_deform_port(asd_ha, phy); sas_ha->notify_port_event(sas_phy, PORTE_TIMER_EVENT); break; case REQ_TASK_ABORT: diff --git a/trunk/drivers/scsi/aic94xx/aic94xx_sds.c b/trunk/drivers/scsi/aic94xx/aic94xx_sds.c index e5a0ec37e954..83574b5b4e69 100644 --- a/trunk/drivers/scsi/aic94xx/aic94xx_sds.c +++ b/trunk/drivers/scsi/aic94xx/aic94xx_sds.c @@ -64,7 +64,7 @@ struct asd_ocm_dir { #define OCM_INIT_DIR_ENTRIES 5 /*************************************************************************** -* OCM directory default +* OCM dircetory default ***************************************************************************/ static struct asd_ocm_dir OCMDirInit = { @@ -73,7 +73,7 @@ static struct asd_ocm_dir OCMDirInit = }; /*************************************************************************** -* OCM directory Entries default +* OCM dircetory Entries default ***************************************************************************/ static struct asd_ocm_dir_ent OCMDirEntriesInit[OCM_INIT_DIR_ENTRIES] = { @@ -630,6 +630,10 @@ static int asd_flash_getid(struct asd_ha_struct *asd_ha) reg = asd_read_reg_dword(asd_ha, EXSICNFGR); + if (!(reg & FLASHEX)) { + ASD_DPRINTK("flash doesn't exist\n"); + return -ENOENT; + } if (pci_read_config_dword(asd_ha->pcidev, PCI_CONF_FLSH_BAR, &asd_ha->hw_prof.flash.bar)) { asd_printk("couldn't read PCI_CONF_FLSH_BAR of %s\n", diff --git a/trunk/drivers/scsi/aic94xx/aic94xx_seq.c b/trunk/drivers/scsi/aic94xx/aic94xx_seq.c index 845112539d05..56e4b3ba6a08 100644 --- a/trunk/drivers/scsi/aic94xx/aic94xx_seq.c +++ b/trunk/drivers/scsi/aic94xx/aic94xx_seq.c @@ -1369,9 +1369,10 @@ int asd_start_seqs(struct asd_ha_struct *asd_ha) * port_map_by_links is also used as the conn_mask byte in the * initiator/target port DDB. */ -void asd_update_port_links(struct asd_ha_struct *asd_ha, struct asd_phy *phy) +void asd_update_port_links(struct asd_sas_phy *sas_phy) { - const u8 phy_mask = (u8) phy->asd_port->phy_mask; + struct asd_ha_struct *asd_ha = sas_phy->ha->lldd_ha; + const u8 phy_mask = (u8) sas_phy->port->phy_mask; u8 phy_is_up; u8 mask; int i, err; diff --git a/trunk/drivers/scsi/aic94xx/aic94xx_seq.h b/trunk/drivers/scsi/aic94xx/aic94xx_seq.h index 9e715e5496af..42281c36153b 100644 --- a/trunk/drivers/scsi/aic94xx/aic94xx_seq.h +++ b/trunk/drivers/scsi/aic94xx/aic94xx_seq.h @@ -64,7 +64,7 @@ int asd_unpause_lseq(struct asd_ha_struct *asd_ha, u8 lseq_mask); int asd_init_seqs(struct asd_ha_struct *asd_ha); int asd_start_seqs(struct asd_ha_struct *asd_ha); -void asd_update_port_links(struct asd_ha_struct *asd_ha, struct asd_phy *phy); +void asd_update_port_links(struct asd_sas_phy *phy); #endif #endif diff --git a/trunk/drivers/scsi/amiga7xx.h b/trunk/drivers/scsi/amiga7xx.h index 7cd63a996886..1b637592d5ae 100644 --- a/trunk/drivers/scsi/amiga7xx.h +++ b/trunk/drivers/scsi/amiga7xx.h @@ -8,7 +8,7 @@ int NCR53c7xx_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); int NCR53c7xx_abort(Scsi_Cmnd *); int NCR53c7x0_release (struct Scsi_Host *); int NCR53c7xx_reset(Scsi_Cmnd *, unsigned int); -void NCR53c7x0_intr(int irq, void *dev_id); +void NCR53c7x0_intr(int irq, void *dev_id, struct pt_regs * regs); #ifndef CMD_PER_LUN #define CMD_PER_LUN 3 diff --git a/trunk/drivers/scsi/arcmsr/arcmsr_hba.c b/trunk/drivers/scsi/arcmsr/arcmsr_hba.c index 086cc97eee8c..475f978ff8f0 100644 --- a/trunk/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/trunk/drivers/scsi/arcmsr/arcmsr_hba.c @@ -147,7 +147,8 @@ static struct pci_driver arcmsr_pci_driver = { .shutdown = arcmsr_shutdown }; -static irqreturn_t arcmsr_do_interrupt(int irq, void *dev_id) +static irqreturn_t arcmsr_do_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { irqreturn_t handle_state; struct AdapterControlBlock *acb; diff --git a/trunk/drivers/scsi/arm/acornscsi.c b/trunk/drivers/scsi/arm/acornscsi.c index 9cf902b7a126..7621e3fa37b1 100644 --- a/trunk/drivers/scsi/arm/acornscsi.c +++ b/trunk/drivers/scsi/arm/acornscsi.c @@ -194,8 +194,7 @@ unsigned int sdtr_period = SDTR_PERIOD; unsigned int sdtr_size = SDTR_SIZE; -static void acornscsi_done(AS_Host *host, struct scsi_cmnd **SCpntp, - unsigned int result); +static void acornscsi_done(AS_Host *host, Scsi_Cmnd **SCpntp, unsigned int result); static int acornscsi_reconnect_finish(AS_Host *host); static void acornscsi_dma_cleanup(AS_Host *host); static void acornscsi_abortcmd(AS_Host *host, unsigned char tag); @@ -713,7 +712,7 @@ static intr_ret_t acornscsi_kick(AS_Host *host) { int from_queue = 0; - struct scsi_cmnd *SCpnt; + Scsi_Cmnd *SCpnt; /* first check to see if a command is waiting to be executed */ SCpnt = host->origSCpnt; @@ -797,15 +796,15 @@ intr_ret_t acornscsi_kick(AS_Host *host) } /* - * Function: void acornscsi_done(AS_Host *host, struct scsi_cmnd **SCpntp, unsigned int result) + * Function: void acornscsi_done(AS_Host *host, Scsi_Cmnd **SCpntp, unsigned int result) * Purpose : complete processing for command * Params : host - interface that completed * result - driver byte of result */ -static void acornscsi_done(AS_Host *host, struct scsi_cmnd **SCpntp, - unsigned int result) +static +void acornscsi_done(AS_Host *host, Scsi_Cmnd **SCpntp, unsigned int result) { - struct scsi_cmnd *SCpnt = *SCpntp; + Scsi_Cmnd *SCpnt = *SCpntp; /* clean up */ sbic_arm_write(host->scsi.io_port, SBIC_SOURCEID, SOURCEID_ER | SOURCEID_DSP); @@ -1319,7 +1318,7 @@ acornscsi_write_pio(AS_Host *host, char *bytes, int *ptr, int len, unsigned int static void acornscsi_sendcommand(AS_Host *host) { - struct scsi_cmnd *SCpnt = host->SCpnt; + Scsi_Cmnd *SCpnt = host->SCpnt; sbic_arm_write(host->scsi.io_port, SBIC_TRANSCNTH, 0); sbic_arm_writenext(host->scsi.io_port, 0); @@ -1694,7 +1693,7 @@ void acornscsi_message(AS_Host *host) acornscsi_sbic_issuecmd(host, CMND_ASSERTATN); msgqueue_addmsg(&host->scsi.msgs, 1, ABORT); } else { - struct scsi_cmnd *SCpnt = host->SCpnt; + Scsi_Cmnd *SCpnt = host->SCpnt; acornscsi_dma_cleanup(host); @@ -2461,13 +2460,14 @@ intr_ret_t acornscsi_sbicintr(AS_Host *host, int in_irq) } /* - * Prototype: void acornscsi_intr(int irq, void *dev_id) + * Prototype: void acornscsi_intr(int irq, void *dev_id, struct pt_regs *regs) * Purpose : handle interrupts from Acorn SCSI card * Params : irq - interrupt number * dev_id - device specific data (AS_Host structure) + * regs - processor registers when interrupt occurred */ static irqreturn_t -acornscsi_intr(int irq, void *dev_id) +acornscsi_intr(int irq, void *dev_id, struct pt_regs *regs) { AS_Host *host = (AS_Host *)dev_id; intr_ret_t ret; @@ -2509,14 +2509,13 @@ acornscsi_intr(int irq, void *dev_id) */ /* - * Function : acornscsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) + * Function : acornscsi_queuecmd(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *)) * Purpose : queues a SCSI command * Params : cmd - SCSI command * done - function called on completion, with pointer to command descriptor * Returns : 0, or < 0 on error. */ -int acornscsi_queuecmd(struct scsi_cmnd *SCpnt, - void (*done)(struct scsi_cmnd *)) +int acornscsi_queuecmd(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) { AS_Host *host = (AS_Host *)SCpnt->device->host->hostdata; @@ -2566,18 +2565,17 @@ int acornscsi_queuecmd(struct scsi_cmnd *SCpnt, } /* - * Prototype: void acornscsi_reportstatus(struct scsi_cmnd **SCpntp1, struct scsi_cmnd **SCpntp2, int result) + * Prototype: void acornscsi_reportstatus(Scsi_Cmnd **SCpntp1, Scsi_Cmnd **SCpntp2, int result) * Purpose : pass a result to *SCpntp1, and check if *SCpntp1 = *SCpntp2 * Params : SCpntp1 - pointer to command to return * SCpntp2 - pointer to command to check * result - result to pass back to mid-level done function * Returns : *SCpntp2 = NULL if *SCpntp1 is the same command structure as *SCpntp2. */ -static inline void acornscsi_reportstatus(struct scsi_cmnd **SCpntp1, - struct scsi_cmnd **SCpntp2, - int result) +static inline +void acornscsi_reportstatus(Scsi_Cmnd **SCpntp1, Scsi_Cmnd **SCpntp2, int result) { - struct scsi_cmnd *SCpnt = *SCpntp1; + Scsi_Cmnd *SCpnt = *SCpntp1; if (SCpnt) { *SCpntp1 = NULL; @@ -2593,12 +2591,13 @@ static inline void acornscsi_reportstatus(struct scsi_cmnd **SCpntp1, enum res_abort { res_not_running, res_success, res_success_clear, res_snooze }; /* - * Prototype: enum res acornscsi_do_abort(struct scsi_cmnd *SCpnt) + * Prototype: enum res acornscsi_do_abort(Scsi_Cmnd *SCpnt) * Purpose : abort a command on this host * Params : SCpnt - command to abort * Returns : our abort status */ -static enum res_abort acornscsi_do_abort(AS_Host *host, struct scsi_cmnd *SCpnt) +static enum res_abort +acornscsi_do_abort(AS_Host *host, Scsi_Cmnd *SCpnt) { enum res_abort res = res_not_running; @@ -2685,12 +2684,12 @@ static enum res_abort acornscsi_do_abort(AS_Host *host, struct scsi_cmnd *SCpnt) } /* - * Prototype: int acornscsi_abort(struct scsi_cmnd *SCpnt) + * Prototype: int acornscsi_abort(Scsi_Cmnd *SCpnt) * Purpose : abort a command on this host * Params : SCpnt - command to abort * Returns : one of SCSI_ABORT_ macros */ -int acornscsi_abort(struct scsi_cmnd *SCpnt) +int acornscsi_abort(Scsi_Cmnd *SCpnt) { AS_Host *host = (AS_Host *) SCpnt->device->host->hostdata; int result; @@ -2771,16 +2770,16 @@ int acornscsi_abort(struct scsi_cmnd *SCpnt) } /* - * Prototype: int acornscsi_reset(struct scsi_cmnd *SCpnt, unsigned int reset_flags) + * Prototype: int acornscsi_reset(Scsi_Cmnd *SCpnt, unsigned int reset_flags) * Purpose : reset a command on this host/reset this host * Params : SCpnt - command causing reset * result - what type of reset to perform * Returns : one of SCSI_RESET_ macros */ -int acornscsi_reset(struct scsi_cmnd *SCpnt, unsigned int reset_flags) +int acornscsi_reset(Scsi_Cmnd *SCpnt, unsigned int reset_flags) { - AS_Host *host = (AS_Host *)SCpnt->device->host->hostdata; - struct scsi_cmnd *SCptr; + AS_Host *host = (AS_Host *)SCpnt->device->host->hostdata; + Scsi_Cmnd *SCptr; host->stats.resets += 1; diff --git a/trunk/drivers/scsi/arm/acornscsi.h b/trunk/drivers/scsi/arm/acornscsi.h index d11424b89f42..2142290f8404 100644 --- a/trunk/drivers/scsi/arm/acornscsi.h +++ b/trunk/drivers/scsi/arm/acornscsi.h @@ -277,8 +277,8 @@ struct status_entry { typedef struct acornscsi_hostdata { /* miscellaneous */ struct Scsi_Host *host; /* host */ - struct scsi_cmnd *SCpnt; /* currently processing command */ - struct scsi_cmnd *origSCpnt; /* original connecting command */ + Scsi_Cmnd *SCpnt; /* currently processing command */ + Scsi_Cmnd *origSCpnt; /* original connecting command */ /* driver information */ struct { diff --git a/trunk/drivers/scsi/arm/cumana_2.c b/trunk/drivers/scsi/arm/cumana_2.c index 19edd9c853d9..719af0dcc0e5 100644 --- a/trunk/drivers/scsi/arm/cumana_2.c +++ b/trunk/drivers/scsi/arm/cumana_2.c @@ -137,9 +137,10 @@ cumanascsi_2_terminator_ctl(struct Scsi_Host *host, int on_off) * Purpose : handle interrupts from Cumana SCSI 2 card * Params : irq - interrupt number * dev_id - user-defined (Scsi_Host structure) + * regs - processor registers at interrupt */ static irqreturn_t -cumanascsi_2_intr(int irq, void *dev_id) +cumanascsi_2_intr(int irq, void *dev_id, struct pt_regs *regs) { struct cumanascsi2_info *info = dev_id; diff --git a/trunk/drivers/scsi/arm/eesox.c b/trunk/drivers/scsi/arm/eesox.c index 3f876fb75469..dcbb4b2b3fe0 100644 --- a/trunk/drivers/scsi/arm/eesox.c +++ b/trunk/drivers/scsi/arm/eesox.c @@ -138,9 +138,10 @@ eesoxscsi_terminator_ctl(struct Scsi_Host *host, int on_off) * Purpose : handle interrupts from EESOX SCSI card * Params : irq - interrupt number * dev_id - user-defined (Scsi_Host structure) + * regs - processor registers at interrupt */ static irqreturn_t -eesoxscsi_intr(int irq, void *dev_id) +eesoxscsi_intr(int irq, void *dev_id, struct pt_regs *regs) { struct eesoxscsi_info *info = dev_id; diff --git a/trunk/drivers/scsi/arm/fas216.c b/trunk/drivers/scsi/arm/fas216.c index e05f0c2fc912..4cf7afc31cc7 100644 --- a/trunk/drivers/scsi/arm/fas216.c +++ b/trunk/drivers/scsi/arm/fas216.c @@ -297,8 +297,8 @@ fas216_do_log(FAS216_Info *info, char target, char *fmt, va_list ap) printk("scsi%d.%c: %s", info->host->host_no, target, buf); } -static void fas216_log_command(FAS216_Info *info, int level, - struct scsi_cmnd *SCpnt, char *fmt, ...) +static void +fas216_log_command(FAS216_Info *info, int level, Scsi_Cmnd *SCpnt, char *fmt, ...) { va_list args; @@ -1662,7 +1662,7 @@ irqreturn_t fas216_intr(FAS216_Info *info) return handled; } -static void __fas216_start_command(FAS216_Info *info, struct scsi_cmnd *SCpnt) +static void __fas216_start_command(FAS216_Info *info, Scsi_Cmnd *SCpnt) { int tot_msglen; @@ -1754,7 +1754,7 @@ static int parity_test(FAS216_Info *info, int target) return info->device[target].parity_check; } -static void fas216_start_command(FAS216_Info *info, struct scsi_cmnd *SCpnt) +static void fas216_start_command(FAS216_Info *info, Scsi_Cmnd *SCpnt) { int disconnect_ok; @@ -1808,7 +1808,7 @@ static void fas216_start_command(FAS216_Info *info, struct scsi_cmnd *SCpnt) __fas216_start_command(info, SCpnt); } -static void fas216_allocate_tag(FAS216_Info *info, struct scsi_cmnd *SCpnt) +static void fas216_allocate_tag(FAS216_Info *info, Scsi_Cmnd *SCpnt) { #ifdef SCSI2_TAG /* @@ -1842,8 +1842,7 @@ static void fas216_allocate_tag(FAS216_Info *info, struct scsi_cmnd *SCpnt) } } -static void fas216_do_bus_device_reset(FAS216_Info *info, - struct scsi_cmnd *SCpnt) +static void fas216_do_bus_device_reset(FAS216_Info *info, Scsi_Cmnd *SCpnt) { struct message *msg; @@ -1891,7 +1890,7 @@ static void fas216_do_bus_device_reset(FAS216_Info *info, */ static void fas216_kick(FAS216_Info *info) { - struct scsi_cmnd *SCpnt = NULL; + Scsi_Cmnd *SCpnt = NULL; #define TYPE_OTHER 0 #define TYPE_RESET 1 #define TYPE_QUEUE 2 @@ -1979,8 +1978,8 @@ static void fas216_kick(FAS216_Info *info) /* * Clean up from issuing a BUS DEVICE RESET message to a device. */ -static void fas216_devicereset_done(FAS216_Info *info, struct scsi_cmnd *SCpnt, - unsigned int result) +static void +fas216_devicereset_done(FAS216_Info *info, Scsi_Cmnd *SCpnt, unsigned int result) { fas216_log(info, LOG_ERROR, "fas216 device reset complete"); @@ -1997,8 +1996,8 @@ static void fas216_devicereset_done(FAS216_Info *info, struct scsi_cmnd *SCpnt, * * Finish processing automatic request sense command */ -static void fas216_rq_sns_done(FAS216_Info *info, struct scsi_cmnd *SCpnt, - unsigned int result) +static void +fas216_rq_sns_done(FAS216_Info *info, Scsi_Cmnd *SCpnt, unsigned int result) { fas216_log_target(info, LOG_CONNECT, SCpnt->device->id, "request sense complete, result=0x%04x%02x%02x", @@ -2031,7 +2030,7 @@ static void fas216_rq_sns_done(FAS216_Info *info, struct scsi_cmnd *SCpnt, * Finish processing of standard command */ static void -fas216_std_done(FAS216_Info *info, struct scsi_cmnd *SCpnt, unsigned int result) +fas216_std_done(FAS216_Info *info, Scsi_Cmnd *SCpnt, unsigned int result) { info->stats.fins += 1; @@ -2143,8 +2142,8 @@ fas216_std_done(FAS216_Info *info, struct scsi_cmnd *SCpnt, unsigned int result) */ static void fas216_done(FAS216_Info *info, unsigned int result) { - void (*fn)(FAS216_Info *, struct scsi_cmnd *, unsigned int); - struct scsi_cmnd *SCpnt; + void (*fn)(FAS216_Info *, Scsi_Cmnd *, unsigned int); + Scsi_Cmnd *SCpnt; unsigned long flags; fas216_checkmagic(info); @@ -2183,7 +2182,7 @@ static void fas216_done(FAS216_Info *info, unsigned int result) info->device[SCpnt->device->id].parity_check = 0; clear_bit(SCpnt->device->id * 8 + SCpnt->device->lun, info->busyluns); - fn = (void (*)(FAS216_Info *, struct scsi_cmnd *, unsigned int))SCpnt->host_scribble; + fn = (void (*)(FAS216_Info *, Scsi_Cmnd *, unsigned int))SCpnt->host_scribble; fn(info, SCpnt, result); if (info->scsi.irq != NO_IRQ) { @@ -2208,8 +2207,7 @@ static void fas216_done(FAS216_Info *info, unsigned int result) * Returns: 0 on success, else error. * Notes: io_request_lock is held, interrupts are disabled. */ -int fas216_queue_command(struct scsi_cmnd *SCpnt, - void (*done)(struct scsi_cmnd *)) +int fas216_queue_command(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) { FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata; int result; @@ -2256,7 +2254,7 @@ int fas216_queue_command(struct scsi_cmnd *SCpnt, * * Trigger restart of a waiting thread in fas216_command */ -static void fas216_internal_done(struct scsi_cmnd *SCpnt) +static void fas216_internal_done(Scsi_Cmnd *SCpnt) { FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata; @@ -2273,8 +2271,7 @@ static void fas216_internal_done(struct scsi_cmnd *SCpnt) * Returns: scsi result code. * Notes: io_request_lock is held, interrupts are disabled. */ -int fas216_noqueue_command(struct scsi_cmnd *SCpnt, - void (*done)(struct scsi_cmnd *)) +int fas216_noqueue_command(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) { FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata; @@ -2353,8 +2350,7 @@ enum res_find { * Decide how to abort a command. * Returns: abort status */ -static enum res_find fas216_find_command(FAS216_Info *info, - struct scsi_cmnd *SCpnt) +static enum res_find fas216_find_command(FAS216_Info *info, Scsi_Cmnd *SCpnt) { enum res_find res = res_failed; @@ -2421,7 +2417,7 @@ static enum res_find fas216_find_command(FAS216_Info *info, * Returns: FAILED if unable to abort * Notes: io_request_lock is taken, and irqs are disabled */ -int fas216_eh_abort(struct scsi_cmnd *SCpnt) +int fas216_eh_abort(Scsi_Cmnd *SCpnt) { FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata; int result = FAILED; @@ -2478,7 +2474,7 @@ int fas216_eh_abort(struct scsi_cmnd *SCpnt) * Notes: We won't be re-entered, so we'll only have one device * reset on the go at one time. */ -int fas216_eh_device_reset(struct scsi_cmnd *SCpnt) +int fas216_eh_device_reset(Scsi_Cmnd *SCpnt) { FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata; unsigned long flags; @@ -2559,7 +2555,7 @@ int fas216_eh_device_reset(struct scsi_cmnd *SCpnt) * Returns: FAILED if unable to reset. * Notes: Further commands are blocked. */ -int fas216_eh_bus_reset(struct scsi_cmnd *SCpnt) +int fas216_eh_bus_reset(Scsi_Cmnd *SCpnt) { FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata; unsigned long flags; @@ -2659,7 +2655,7 @@ static void fas216_init_chip(FAS216_Info *info) * Returns: FAILED if unable to reset. * Notes: io_request_lock is taken, and irqs are disabled */ -int fas216_eh_host_reset(struct scsi_cmnd *SCpnt) +int fas216_eh_host_reset(Scsi_Cmnd *SCpnt) { FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata; diff --git a/trunk/drivers/scsi/arm/fas216.h b/trunk/drivers/scsi/arm/fas216.h index 00e5f055afdc..540914d6fd32 100644 --- a/trunk/drivers/scsi/arm/fas216.h +++ b/trunk/drivers/scsi/arm/fas216.h @@ -218,11 +218,11 @@ typedef struct { unsigned long magic_start; spinlock_t host_lock; struct Scsi_Host *host; /* host */ - struct scsi_cmnd *SCpnt; /* currently processing command */ - struct scsi_cmnd *origSCpnt; /* original connecting command */ - struct scsi_cmnd *reqSCpnt; /* request sense command */ - struct scsi_cmnd *rstSCpnt; /* reset command */ - struct scsi_cmnd *pending_SCpnt[8]; /* per-device pending commands */ + Scsi_Cmnd *SCpnt; /* currently processing command */ + Scsi_Cmnd *origSCpnt; /* original connecting command */ + Scsi_Cmnd *reqSCpnt; /* request sense command */ + Scsi_Cmnd *rstSCpnt; /* reset command */ + Scsi_Cmnd *pending_SCpnt[8]; /* per-device pending commands */ int next_pending; /* next pending device */ /* @@ -328,23 +328,21 @@ extern int fas216_init (struct Scsi_Host *instance); */ extern int fas216_add (struct Scsi_Host *instance, struct device *dev); -/* Function: int fas216_queue_command(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) +/* Function: int fas216_queue_command (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) * Purpose : queue a command for adapter to process. * Params : SCpnt - Command to queue * done - done function to call once command is complete * Returns : 0 - success, else error */ -extern int fas216_queue_command(struct scsi_cmnd *, - void (*done)(struct scsi_cmnd *)); +extern int fas216_queue_command (Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); -/* Function: int fas216_noqueue_command(istruct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) +/* Function: int fas216_noqueue_command (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) * Purpose : queue a command for adapter to process, and process it to completion. * Params : SCpnt - Command to queue * done - done function to call once command is complete * Returns : 0 - success, else error */ -extern int fas216_noqueue_command(struct scsi_cmnd *, - void (*done)(struct scsi_cmnd *)); +extern int fas216_noqueue_command (Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); /* Function: irqreturn_t fas216_intr (FAS216_Info *info) * Purpose : handle interrupts from the interface to progress a command @@ -365,32 +363,32 @@ extern int fas216_print_host(FAS216_Info *info, char *buffer); extern int fas216_print_stats(FAS216_Info *info, char *buffer); extern int fas216_print_devices(FAS216_Info *info, char *buffer); -/* Function: int fas216_eh_abort(struct scsi_cmnd *SCpnt) +/* Function: int fas216_eh_abort(Scsi_Cmnd *SCpnt) * Purpose : abort this command * Params : SCpnt - command to abort * Returns : FAILED if unable to abort */ -extern int fas216_eh_abort(struct scsi_cmnd *SCpnt); +extern int fas216_eh_abort(Scsi_Cmnd *SCpnt); -/* Function: int fas216_eh_device_reset(struct scsi_cmnd *SCpnt) +/* Function: int fas216_eh_device_reset(Scsi_Cmnd *SCpnt) * Purpose : Reset the device associated with this command * Params : SCpnt - command specifing device to reset * Returns : FAILED if unable to reset */ -extern int fas216_eh_device_reset(struct scsi_cmnd *SCpnt); +extern int fas216_eh_device_reset(Scsi_Cmnd *SCpnt); -/* Function: int fas216_eh_bus_reset(struct scsi_cmnd *SCpnt) +/* Function: int fas216_eh_bus_reset(Scsi_Cmnd *SCpnt) * Purpose : Reset the complete bus associated with this command * Params : SCpnt - command specifing bus to reset * Returns : FAILED if unable to reset */ -extern int fas216_eh_bus_reset(struct scsi_cmnd *SCpnt); +extern int fas216_eh_bus_reset(Scsi_Cmnd *SCpnt); -/* Function: int fas216_eh_host_reset(struct scsi_cmnd *SCpnt) +/* Function: int fas216_eh_host_reset(Scsi_Cmnd *SCpnt) * Purpose : Reset the host associated with this command * Params : SCpnt - command specifing host to reset * Returns : FAILED if unable to reset */ -extern int fas216_eh_host_reset(struct scsi_cmnd *SCpnt); +extern int fas216_eh_host_reset(Scsi_Cmnd *SCpnt); #endif /* FAS216_H */ diff --git a/trunk/drivers/scsi/arm/powertec.c b/trunk/drivers/scsi/arm/powertec.c index ce159c15bc86..b2c346a47052 100644 --- a/trunk/drivers/scsi/arm/powertec.c +++ b/trunk/drivers/scsi/arm/powertec.c @@ -112,8 +112,10 @@ powertecscsi_terminator_ctl(struct Scsi_Host *host, int on_off) * Purpose : handle interrupts from Powertec SCSI card * Params : irq - interrupt number * dev_id - user-defined (Scsi_Host structure) + * regs - processor registers at interrupt */ -static irqreturn_t powertecscsi_intr(int irq, void *dev_id) +static irqreturn_t +powertecscsi_intr(int irq, void *dev_id, struct pt_regs *regs) { struct powertec_info *info = dev_id; diff --git a/trunk/drivers/scsi/arm/queue.c b/trunk/drivers/scsi/arm/queue.c index cb11ccef54e5..8caa5903ce38 100644 --- a/trunk/drivers/scsi/arm/queue.c +++ b/trunk/drivers/scsi/arm/queue.c @@ -29,7 +29,7 @@ typedef struct queue_entry { struct list_head list; - struct scsi_cmnd *SCpnt; + Scsi_Cmnd *SCpnt; #ifdef DEBUG unsigned long magic; #endif @@ -96,14 +96,14 @@ void queue_free (Queue_t *queue) /* - * Function: int __queue_add(Queue_t *queue, struct scsi_cmnd *SCpnt, int head) + * Function: int queue_add_cmd(Queue_t *queue, Scsi_Cmnd *SCpnt, int head) * Purpose : Add a new command onto a queue, adding REQUEST_SENSE to head. * Params : queue - destination queue * SCpnt - command to add * head - add command to head of queue * Returns : 0 on error, !0 on success */ -int __queue_add(Queue_t *queue, struct scsi_cmnd *SCpnt, int head) +int __queue_add(Queue_t *queue, Scsi_Cmnd *SCpnt, int head) { unsigned long flags; struct list_head *l; @@ -134,7 +134,7 @@ int __queue_add(Queue_t *queue, struct scsi_cmnd *SCpnt, int head) return ret; } -static struct scsi_cmnd *__queue_remove(Queue_t *queue, struct list_head *ent) +static Scsi_Cmnd *__queue_remove(Queue_t *queue, struct list_head *ent) { QE_t *q; @@ -152,17 +152,17 @@ static struct scsi_cmnd *__queue_remove(Queue_t *queue, struct list_head *ent) } /* - * Function: struct scsi_cmnd *queue_remove_exclude (queue, exclude) + * Function: Scsi_Cmnd *queue_remove_exclude (queue, exclude) * Purpose : remove a SCSI command from a queue * Params : queue - queue to remove command from * exclude - bit array of target&lun which is busy - * Returns : struct scsi_cmnd if successful (and a reference), or NULL if no command available + * Returns : Scsi_Cmnd if successful (and a reference), or NULL if no command available */ -struct scsi_cmnd *queue_remove_exclude(Queue_t *queue, unsigned long *exclude) +Scsi_Cmnd *queue_remove_exclude(Queue_t *queue, unsigned long *exclude) { unsigned long flags; struct list_head *l; - struct scsi_cmnd *SCpnt = NULL; + Scsi_Cmnd *SCpnt = NULL; spin_lock_irqsave(&queue->queue_lock, flags); list_for_each(l, &queue->head) { @@ -178,15 +178,15 @@ struct scsi_cmnd *queue_remove_exclude(Queue_t *queue, unsigned long *exclude) } /* - * Function: struct scsi_cmnd *queue_remove (queue) + * Function: Scsi_Cmnd *queue_remove (queue) * Purpose : removes first SCSI command from a queue * Params : queue - queue to remove command from - * Returns : struct scsi_cmnd if successful (and a reference), or NULL if no command available + * Returns : Scsi_Cmnd if successful (and a reference), or NULL if no command available */ -struct scsi_cmnd *queue_remove(Queue_t *queue) +Scsi_Cmnd *queue_remove(Queue_t *queue) { unsigned long flags; - struct scsi_cmnd *SCpnt = NULL; + Scsi_Cmnd *SCpnt = NULL; spin_lock_irqsave(&queue->queue_lock, flags); if (!list_empty(&queue->head)) @@ -197,20 +197,19 @@ struct scsi_cmnd *queue_remove(Queue_t *queue) } /* - * Function: struct scsi_cmnd *queue_remove_tgtluntag (queue, target, lun, tag) + * Function: Scsi_Cmnd *queue_remove_tgtluntag (queue, target, lun, tag) * Purpose : remove a SCSI command from the queue for a specified target/lun/tag * Params : queue - queue to remove command from * target - target that we want * lun - lun on device * tag - tag on device - * Returns : struct scsi_cmnd if successful, or NULL if no command satisfies requirements + * Returns : Scsi_Cmnd if successful, or NULL if no command satisfies requirements */ -struct scsi_cmnd *queue_remove_tgtluntag(Queue_t *queue, int target, int lun, - int tag) +Scsi_Cmnd *queue_remove_tgtluntag (Queue_t *queue, int target, int lun, int tag) { unsigned long flags; struct list_head *l; - struct scsi_cmnd *SCpnt = NULL; + Scsi_Cmnd *SCpnt = NULL; spin_lock_irqsave(&queue->queue_lock, flags); list_for_each(l, &queue->head) { @@ -276,13 +275,13 @@ int queue_probetgtlun (Queue_t *queue, int target, int lun) } /* - * Function: int queue_remove_cmd(Queue_t *queue, struct scsi_cmnd *SCpnt) + * Function: int queue_remove_cmd(Queue_t *queue, Scsi_Cmnd *SCpnt) * Purpose : remove a specific command from the queues * Params : queue - queue to look in * SCpnt - command to find * Returns : 0 if not found */ -int queue_remove_cmd(Queue_t *queue, struct scsi_cmnd *SCpnt) +int queue_remove_cmd(Queue_t *queue, Scsi_Cmnd *SCpnt) { unsigned long flags; struct list_head *l; diff --git a/trunk/drivers/scsi/arm/queue.h b/trunk/drivers/scsi/arm/queue.h index 3c519c9237b2..0c9dec4c1716 100644 --- a/trunk/drivers/scsi/arm/queue.h +++ b/trunk/drivers/scsi/arm/queue.h @@ -32,48 +32,46 @@ extern int queue_initialise (Queue_t *queue); extern void queue_free (Queue_t *queue); /* - * Function: struct scsi_cmnd *queue_remove (queue) + * Function: Scsi_Cmnd *queue_remove (queue) * Purpose : removes first SCSI command from a queue * Params : queue - queue to remove command from - * Returns : struct scsi_cmnd if successful (and a reference), or NULL if no command available + * Returns : Scsi_Cmnd if successful (and a reference), or NULL if no command available */ -extern struct scsi_cmnd *queue_remove (Queue_t *queue); +extern Scsi_Cmnd *queue_remove (Queue_t *queue); /* - * Function: struct scsi_cmnd *queue_remove_exclude_ref (queue, exclude) + * Function: Scsi_Cmnd *queue_remove_exclude_ref (queue, exclude) * Purpose : remove a SCSI command from a queue * Params : queue - queue to remove command from * exclude - array of busy LUNs - * Returns : struct scsi_cmnd if successful (and a reference), or NULL if no command available + * Returns : Scsi_Cmnd if successful (and a reference), or NULL if no command available */ -extern struct scsi_cmnd *queue_remove_exclude(Queue_t *queue, - unsigned long *exclude); +extern Scsi_Cmnd *queue_remove_exclude (Queue_t *queue, unsigned long *exclude); #define queue_add_cmd_ordered(queue,SCpnt) \ __queue_add(queue,SCpnt,(SCpnt)->cmnd[0] == REQUEST_SENSE) #define queue_add_cmd_tail(queue,SCpnt) \ __queue_add(queue,SCpnt,0) /* - * Function: int __queue_add(Queue_t *queue, struct scsi_cmnd *SCpnt, int head) + * Function: int __queue_add(Queue_t *queue, Scsi_Cmnd *SCpnt, int head) * Purpose : Add a new command onto a queue * Params : queue - destination queue * SCpnt - command to add * head - add command to head of queue * Returns : 0 on error, !0 on success */ -extern int __queue_add(Queue_t *queue, struct scsi_cmnd *SCpnt, int head); +extern int __queue_add(Queue_t *queue, Scsi_Cmnd *SCpnt, int head); /* - * Function: struct scsi_cmnd *queue_remove_tgtluntag (queue, target, lun, tag) + * Function: Scsi_Cmnd *queue_remove_tgtluntag (queue, target, lun, tag) * Purpose : remove a SCSI command from the queue for a specified target/lun/tag * Params : queue - queue to remove command from * target - target that we want * lun - lun on device * tag - tag on device - * Returns : struct scsi_cmnd if successful, or NULL if no command satisfies requirements + * Returns : Scsi_Cmnd if successful, or NULL if no command satisfies requirements */ -extern struct scsi_cmnd *queue_remove_tgtluntag(Queue_t *queue, int target, - int lun, int tag); +extern Scsi_Cmnd *queue_remove_tgtluntag (Queue_t *queue, int target, int lun, int tag); /* * Function: queue_remove_all_target(queue, target) @@ -96,12 +94,12 @@ extern void queue_remove_all_target(Queue_t *queue, int target); extern int queue_probetgtlun (Queue_t *queue, int target, int lun); /* - * Function: int queue_remove_cmd (Queue_t *queue, struct scsi_cmnd *SCpnt) + * Function: int queue_remove_cmd (Queue_t *queue, Scsi_Cmnd *SCpnt) * Purpose : remove a specific command from the queues * Params : queue - queue to look in * SCpnt - command to find * Returns : 0 if not found */ -int queue_remove_cmd(Queue_t *queue, struct scsi_cmnd *SCpnt); +int queue_remove_cmd(Queue_t *queue, Scsi_Cmnd *SCpnt); #endif /* QUEUE_H */ diff --git a/trunk/drivers/scsi/arm/scsi.h b/trunk/drivers/scsi/arm/scsi.h index 3a39579bd08e..8c2600ffc6af 100644 --- a/trunk/drivers/scsi/arm/scsi.h +++ b/trunk/drivers/scsi/arm/scsi.h @@ -66,7 +66,7 @@ static inline void put_next_SCp_byte(struct scsi_pointer *SCp, unsigned char c) SCp->this_residual -= 1; } -static inline void init_SCp(struct scsi_cmnd *SCpnt) +static inline void init_SCp(Scsi_Cmnd *SCpnt) { memset(&SCpnt->SCp, 0, sizeof(struct scsi_pointer)); diff --git a/trunk/drivers/scsi/atari_NCR5380.c b/trunk/drivers/scsi/atari_NCR5380.c index 0f920c84ac0f..e397129c90d1 100644 --- a/trunk/drivers/scsi/atari_NCR5380.c +++ b/trunk/drivers/scsi/atari_NCR5380.c @@ -1262,7 +1262,7 @@ static void NCR5380_dma_complete( struct Scsi_Host *instance ) * */ -static irqreturn_t NCR5380_intr (int irq, void *dev_id) +static irqreturn_t NCR5380_intr (int irq, void *dev_id, struct pt_regs *regs) { struct Scsi_Host *instance = first_instance; int done = 1, handled = 0; diff --git a/trunk/drivers/scsi/atari_dma_emul.c b/trunk/drivers/scsi/atari_dma_emul.c index cdc710ea00fa..8d5d2a5da961 100644 --- a/trunk/drivers/scsi/atari_dma_emul.c +++ b/trunk/drivers/scsi/atari_dma_emul.c @@ -110,7 +110,7 @@ static inline void set_restdata_reg(unsigned char *cur_addr) } /* - * void hades_dma_emulator(int irq, void *dummy) + * void hades_dma_emulator(int irq, void *dummy, struct pt_regs *fp) * * This code emulates TT SCSI DMA on the Hades. * @@ -140,7 +140,7 @@ static inline void set_restdata_reg(unsigned char *cur_addr) * increased with one. */ -static irqreturn_t hades_dma_emulator(int irq, void *dummy) +static irqreturn_t hades_dma_emulator(int irq, void *dummy, struct pt_regs *fp) { unsigned long dma_base; register unsigned long dma_cnt asm ("d3"); diff --git a/trunk/drivers/scsi/atari_scsi.c b/trunk/drivers/scsi/atari_scsi.c index dfb1bcfae82e..e1be4a4387cd 100644 --- a/trunk/drivers/scsi/atari_scsi.c +++ b/trunk/drivers/scsi/atari_scsi.c @@ -194,8 +194,8 @@ static int falcon_classify_cmd( Scsi_Cmnd *cmd ); static unsigned long atari_dma_xfer_len( unsigned long wanted_len, Scsi_Cmnd *cmd, int write_flag ); #endif -static irqreturn_t scsi_tt_intr( int irq, void *dummy); -static irqreturn_t scsi_falcon_intr( int irq, void *dummy); +static irqreturn_t scsi_tt_intr( int irq, void *dummy, struct pt_regs *fp); +static irqreturn_t scsi_falcon_intr( int irq, void *dummy, struct pt_regs *fp); static void falcon_release_lock_if_possible( struct NCR5380_hostdata * hostdata ); static void falcon_get_lock( void ); @@ -285,7 +285,7 @@ static int scsi_dma_is_ignored_buserr( unsigned char dma_stat ) * end-of-DMA, both SCSI ints are triggered simultaneously, so the NCR int has * to clear the DMA int pending bit before it allows other level 6 interrupts. */ -static void scsi_dma_buserr (int irq, void *dummy) +static void scsi_dma_buserr (int irq, void *dummy, struct pt_regs *fp) { unsigned char dma_stat = tt_scsi_dma.dma_ctrl; @@ -314,7 +314,7 @@ static void scsi_dma_buserr (int irq, void *dummy) #endif -static irqreturn_t scsi_tt_intr (int irq, void *dummy) +static irqreturn_t scsi_tt_intr (int irq, void *dummy, struct pt_regs *fp) { #ifdef REAL_DMA int dma_stat; @@ -406,7 +406,7 @@ static irqreturn_t scsi_tt_intr (int irq, void *dummy) } -static irqreturn_t scsi_falcon_intr (int irq, void *dummy) +static irqreturn_t scsi_falcon_intr (int irq, void *dummy, struct pt_regs *fp) { #ifdef REAL_DMA int dma_stat; diff --git a/trunk/drivers/scsi/atp870u.c b/trunk/drivers/scsi/atp870u.c index fec58cc47f1c..0ec41f34f462 100644 --- a/trunk/drivers/scsi/atp870u.c +++ b/trunk/drivers/scsi/atp870u.c @@ -44,7 +44,7 @@ static void send_s870(struct atp_unit *dev,unsigned char c); static void is885(struct atp_unit *dev, unsigned int wkport,unsigned char c); static void tscam_885(void); -static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) +static irqreturn_t atp870u_intr_handle(int irq, void *dev_id, struct pt_regs *regs) { unsigned long flags; unsigned short int tmpcip, id; diff --git a/trunk/drivers/scsi/bvme6000.h b/trunk/drivers/scsi/bvme6000.h index ea3e4b2b9220..7c9c0366cc08 100644 --- a/trunk/drivers/scsi/bvme6000.h +++ b/trunk/drivers/scsi/bvme6000.h @@ -9,7 +9,7 @@ int NCR53c7xx_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); int NCR53c7xx_abort(Scsi_Cmnd *); int NCR53c7x0_release (struct Scsi_Host *); int NCR53c7xx_reset(Scsi_Cmnd *, unsigned int); -void NCR53c7x0_intr(int irq, void *dev_id); +void NCR53c7x0_intr(int irq, void *dev_id, struct pt_regs * regs); #ifndef CMD_PER_LUN #define CMD_PER_LUN 3 diff --git a/trunk/drivers/scsi/dc395x.c b/trunk/drivers/scsi/dc395x.c index e95b367d09ed..ff2b1796fa34 100644 --- a/trunk/drivers/scsi/dc395x.c +++ b/trunk/drivers/scsi/dc395x.c @@ -1219,7 +1219,7 @@ static void dump_register_info(struct AdapterCtlBlk *acb, srb, srb->cmd, srb->cmd->pid, srb->cmd->cmnd[0], srb->cmd->device->id, srb->cmd->device->lun); - printk(" sglist=%p cnt=%i idx=%i len=%zu\n", + printk(" sglist=%p cnt=%i idx=%i len=%i\n", srb->segment_x, srb->sg_count, srb->sg_index, srb->total_xfer_length); printk(" state=0x%04x status=0x%02x phase=0x%02x (%sconn.)\n", @@ -1813,9 +1813,10 @@ static void dc395x_handle_interrupt(struct AdapterCtlBlk *acb, } -static irqreturn_t dc395x_interrupt(int irq, void *dev_id) +static irqreturn_t dc395x_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { - struct AdapterCtlBlk *acb = dev_id; + struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *)dev_id; u16 scsi_status; u8 dma_status; irqreturn_t handled = IRQ_NONE; @@ -4948,7 +4949,7 @@ static struct pci_driver dc395x_driver = { **/ static int __init dc395x_module_init(void) { - return pci_register_driver(&dc395x_driver); + return pci_module_init(&dc395x_driver); } diff --git a/trunk/drivers/scsi/dec_esp.c b/trunk/drivers/scsi/dec_esp.c index c29ccbc44693..eb32062f7e68 100644 --- a/trunk/drivers/scsi/dec_esp.c +++ b/trunk/drivers/scsi/dec_esp.c @@ -94,9 +94,9 @@ volatile unsigned char pmaz_cmd_buffer[16]; * via PIO. */ -static irqreturn_t scsi_dma_merr_int(int, void *); -static irqreturn_t scsi_dma_err_int(int, void *); -static irqreturn_t scsi_dma_int(int, void *); +static irqreturn_t scsi_dma_merr_int(int, void *, struct pt_regs *); +static irqreturn_t scsi_dma_err_int(int, void *, struct pt_regs *); +static irqreturn_t scsi_dma_int(int, void *, struct pt_regs *); static int dec_esp_detect(struct scsi_host_template * tpnt); @@ -307,7 +307,7 @@ static int dec_esp_detect(struct scsi_host_template * tpnt) } /************************************************************* DMA Functions */ -static irqreturn_t scsi_dma_merr_int(int irq, void *dev_id) +static irqreturn_t scsi_dma_merr_int(int irq, void *dev_id, struct pt_regs *regs) { printk("Got unexpected SCSI DMA Interrupt! < "); printk("SCSI_DMA_MEMRDERR "); @@ -316,14 +316,14 @@ static irqreturn_t scsi_dma_merr_int(int irq, void *dev_id) return IRQ_HANDLED; } -static irqreturn_t scsi_dma_err_int(int irq, void *dev_id) +static irqreturn_t scsi_dma_err_int(int irq, void *dev_id, struct pt_regs *regs) { /* empty */ return IRQ_HANDLED; } -static irqreturn_t scsi_dma_int(int irq, void *dev_id) +static irqreturn_t scsi_dma_int(int irq, void *dev_id, struct pt_regs *regs) { u32 scsi_next_ptr; diff --git a/trunk/drivers/scsi/dmx3191d.c b/trunk/drivers/scsi/dmx3191d.c index fa738ec8692a..879a26657676 100644 --- a/trunk/drivers/scsi/dmx3191d.c +++ b/trunk/drivers/scsi/dmx3191d.c @@ -155,7 +155,7 @@ static struct pci_driver dmx3191d_pci_driver = { static int __init dmx3191d_init(void) { - return pci_register_driver(&dmx3191d_pci_driver); + return pci_module_init(&dmx3191d_pci_driver); } static void __exit dmx3191d_exit(void) diff --git a/trunk/drivers/scsi/dpt/dpti_i2o.h b/trunk/drivers/scsi/dpt/dpti_i2o.h index 5a49216fe4cf..d84a281ad944 100644 --- a/trunk/drivers/scsi/dpt/dpti_i2o.h +++ b/trunk/drivers/scsi/dpt/dpti_i2o.h @@ -47,11 +47,21 @@ * I2O Interface Objects */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) + +#define DECLARE_MUTEX(name) struct semaphore name=MUTEX + +typedef struct wait_queue *adpt_wait_queue_head_t; +#define ADPT_DECLARE_WAIT_QUEUE_HEAD(wait) adpt_wait_queue_head_t wait = NULL +typedef struct wait_queue adpt_wait_queue_t; +#else + #include typedef wait_queue_head_t adpt_wait_queue_head_t; -#define ADPT_DECLARE_WAIT_QUEUE_HEAD(wait) DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wait) +#define ADPT_DECLARE_WAIT_QUEUE_HEAD(wait) DECLARE_WAIT_QUEUE_HEAD(wait) typedef wait_queue_t adpt_wait_queue_t; +#endif /* * message structures */ diff --git a/trunk/drivers/scsi/dpt_i2o.c b/trunk/drivers/scsi/dpt_i2o.c index 60b1b434eba7..7b3bd34faf47 100644 --- a/trunk/drivers/scsi/dpt_i2o.c +++ b/trunk/drivers/scsi/dpt_i2o.c @@ -1989,7 +1989,7 @@ static int adpt_ioctl(struct inode *inode, struct file *file, uint cmd, } -static irqreturn_t adpt_isr(int irq, void *dev_id) +static irqreturn_t adpt_isr(int irq, void *dev_id, struct pt_regs *regs) { struct scsi_cmnd* cmd; adpt_hba* pHba = dev_id; @@ -2212,7 +2212,7 @@ static s32 adpt_scsi_register(adpt_hba* pHba,struct scsi_host_template * sht) */ host->io_port = 0; host->n_io_port = 0; - /* see comments in scsi_host.h */ + /* see comments in hosts.h */ host->max_id = 16; host->max_lun = 256; host->max_channel = pHba->top_scsi_channel + 1; diff --git a/trunk/drivers/scsi/dpti.h b/trunk/drivers/scsi/dpti.h index fd79068c5869..2ad2a89b5db4 100644 --- a/trunk/drivers/scsi/dpti.h +++ b/trunk/drivers/scsi/dpti.h @@ -44,7 +44,7 @@ static int adpt_device_reset(struct scsi_cmnd* cmd); /* - * struct scsi_host_template (see scsi/scsi_host.h) + * struct scsi_host_template (see hosts.h) */ #define DPT_DRIVER_NAME "Adaptec I2O RAID" @@ -263,7 +263,7 @@ struct sg_simple_element { static void adpt_i2o_sys_shutdown(void); static int adpt_init(void); static int adpt_i2o_build_sys_table(void); -static irqreturn_t adpt_isr(int irq, void *dev_id); +static irqreturn_t adpt_isr(int irq, void *dev_id, struct pt_regs *regs); #ifdef REBOOT_NOTIFIER static int adpt_reboot_event(struct notifier_block *n, ulong code, void *p); #endif diff --git a/trunk/drivers/scsi/dtc.c b/trunk/drivers/scsi/dtc.c index 54756722dd5f..0d5713dfa204 100644 --- a/trunk/drivers/scsi/dtc.c +++ b/trunk/drivers/scsi/dtc.c @@ -82,7 +82,7 @@ #include #include #include -#include +#include #include "scsi.h" #include #include "dtc.h" diff --git a/trunk/drivers/scsi/eata.c b/trunk/drivers/scsi/eata.c index 2d38025861a5..a5ff43b1b263 100644 --- a/trunk/drivers/scsi/eata.c +++ b/trunk/drivers/scsi/eata.c @@ -875,7 +875,7 @@ static unsigned long io_port[] = { /* But transfer orientation from the 16 bit data register is Little Endian */ #define REG2H(x) le16_to_cpu(x) -static irqreturn_t do_interrupt_handler(int, void *); +static irqreturn_t do_interrupt_handler(int, void *, struct pt_regs *); static void flush_dev(struct scsi_device *, unsigned long, struct hostdata *, unsigned int); static int do_trace = 0; @@ -2555,7 +2555,8 @@ static irqreturn_t ihdlr(int irq, struct Scsi_Host *shost) return IRQ_NONE; } -static irqreturn_t do_interrupt_handler(int irq, void *shap) +static irqreturn_t do_interrupt_handler(int irq, void *shap, + struct pt_regs *regs) { struct Scsi_Host *shost; unsigned int j; diff --git a/trunk/drivers/scsi/eata_pio.c b/trunk/drivers/scsi/eata_pio.c index 2dbb66d2f0a7..d312633db92b 100644 --- a/trunk/drivers/scsi/eata_pio.c +++ b/trunk/drivers/scsi/eata_pio.c @@ -194,21 +194,22 @@ static void IncStat(struct scsi_pointer *SCp, unsigned int Increment) } } -static irqreturn_t eata_pio_int_handler(int irq, void *dev_id); +static irqreturn_t eata_pio_int_handler(int irq, void *dev_id, struct pt_regs *regs); -static irqreturn_t do_eata_pio_int_handler(int irq, void *dev_id) +static irqreturn_t do_eata_pio_int_handler(int irq, void *dev_id, + struct pt_regs *regs) { unsigned long flags; struct Scsi_Host *dev = dev_id; irqreturn_t ret; spin_lock_irqsave(dev->host_lock, flags); - ret = eata_pio_int_handler(irq, dev_id); + ret = eata_pio_int_handler(irq, dev_id, regs); spin_unlock_irqrestore(dev->host_lock, flags); return ret; } -static irqreturn_t eata_pio_int_handler(int irq, void *dev_id) +static irqreturn_t eata_pio_int_handler(int irq, void *dev_id, struct pt_regs *regs) { unsigned int eata_stat = 0xfffff; struct scsi_cmnd *cmd; diff --git a/trunk/drivers/scsi/esp.c b/trunk/drivers/scsi/esp.c index 2c2fe80bc42a..5630868c1b25 100644 --- a/trunk/drivers/scsi/esp.c +++ b/trunk/drivers/scsi/esp.c @@ -184,7 +184,7 @@ enum { }; /* Forward declarations. */ -static irqreturn_t esp_intr(int irq, void *dev_id); +static irqreturn_t esp_intr(int irq, void *dev_id, struct pt_regs *pregs); /* Debugging routines */ struct esp_cmdstrings { @@ -4282,7 +4282,7 @@ static void esp_handle(struct esp *esp) } /* Service only the ESP described by dev_id. */ -static irqreturn_t esp_intr(int irq, void *dev_id) +static irqreturn_t esp_intr(int irq, void *dev_id, struct pt_regs *pregs) { struct esp *esp = dev_id; unsigned long flags; diff --git a/trunk/drivers/scsi/fd_mcs.c b/trunk/drivers/scsi/fd_mcs.c index ef8285c326e4..dde3edf35c03 100644 --- a/trunk/drivers/scsi/fd_mcs.c +++ b/trunk/drivers/scsi/fd_mcs.c @@ -281,7 +281,7 @@ static struct fd_mcs_adapters_struct fd_mcs_adapters[] = { #define FD_BRDS ARRAY_SIZE(fd_mcs_adapters) -static irqreturn_t fd_mcs_intr(int irq, void *dev_id); +static irqreturn_t fd_mcs_intr(int irq, void *dev_id, struct pt_regs *regs); static unsigned long addresses[] = { 0xc8000, 0xca000, 0xce000, 0xde000 }; static unsigned short ports[] = { 0x140, 0x150, 0x160, 0x170 }; @@ -617,7 +617,7 @@ static void my_done(struct Scsi_Host *shpnt, int error) } /* only my_done needs to be protected */ -static irqreturn_t fd_mcs_intr(int irq, void *dev_id) +static irqreturn_t fd_mcs_intr(int irq, void *dev_id, struct pt_regs *regs) { unsigned long flags; int status; diff --git a/trunk/drivers/scsi/fdomain.c b/trunk/drivers/scsi/fdomain.c index 5d4ea6f77953..b0694dcce246 100644 --- a/trunk/drivers/scsi/fdomain.c +++ b/trunk/drivers/scsi/fdomain.c @@ -278,9 +278,9 @@ #include #include #include -#include #include +#include #include #include @@ -387,7 +387,6 @@ static void __iomem * bios_mem; static int bios_major; static int bios_minor; static int PCI_bus; -static struct pci_dev *PCI_dev; static int Quantum; /* Quantum board variant */ static int interrupt_level; static volatile int in_command; @@ -404,7 +403,8 @@ static volatile int in_interrupt_flag; static int FIFO_Size = 0x2000; /* 8k FIFO for pre-tmc18c30 chips */ -static irqreturn_t do_fdomain_16x0_intr( int irq, void *dev_id ); +static irqreturn_t do_fdomain_16x0_intr( int irq, void *dev_id, + struct pt_regs * regs ); /* Allow insmod parameters to be like LILO parameters. For example: insmod fdomain fdomain=0x140,11 */ static char * fdomain = NULL; @@ -813,10 +813,9 @@ static int fdomain_pci_bios_detect( int *irq, int *iobase, struct pci_dev **ret_ PCI_DEVICE_ID_FD_36C70 ); #endif - if ((pdev = pci_get_device(PCI_VENDOR_ID_FD, PCI_DEVICE_ID_FD_36C70, pdev)) == NULL) + if ((pdev = pci_find_device(PCI_VENDOR_ID_FD, PCI_DEVICE_ID_FD_36C70, pdev)) == NULL) return 0; - if (pci_enable_device(pdev)) - goto fail; + if (pci_enable_device(pdev)) return 0; #if DEBUG_DETECT printk( "scsi: TMC-3260 detect:" @@ -833,7 +832,7 @@ static int fdomain_pci_bios_detect( int *irq, int *iobase, struct pci_dev **ret_ pci_irq = pdev->irq; if (!request_region( pci_base, 0x10, "fdomain" )) - goto fail; + return 0; /* Now we have the I/O base address and interrupt from the PCI configuration registers. */ @@ -850,22 +849,17 @@ static int fdomain_pci_bios_detect( int *irq, int *iobase, struct pci_dev **ret_ if (!fdomain_is_valid_port(pci_base)) { printk(KERN_ERR "scsi: PCI card detected, but driver not loaded (invalid port)\n" ); release_region(pci_base, 0x10); - goto fail; + return 0; } /* Fill in a few global variables. Ugh. */ bios_major = bios_minor = -1; PCI_bus = 1; - PCI_dev = pdev; Quantum = 0; bios_base = 0; return 1; -fail: - pci_dev_put(pdev); - return 0; } - #endif struct Scsi_Host *__fdomain_16x0_detect(struct scsi_host_template *tpnt ) @@ -916,7 +910,8 @@ struct Scsi_Host *__fdomain_16x0_detect(struct scsi_host_template *tpnt ) if (setup_called) { printk(KERN_ERR "scsi: Bad LILO/INSMOD parameters?\n"); } - goto fail; + release_region(port_base, 0x10); + return NULL; } if (this_id) { @@ -948,7 +943,8 @@ struct Scsi_Host *__fdomain_16x0_detect(struct scsi_host_template *tpnt ) /* Log IRQ with kernel */ if (!interrupt_level) { printk(KERN_ERR "scsi: Card Detected, but driver not loaded (no IRQ)\n" ); - goto fail; + release_region(port_base, 0x10); + return NULL; } else { /* Register the IRQ with the kernel */ @@ -969,14 +965,11 @@ struct Scsi_Host *__fdomain_16x0_detect(struct scsi_host_template *tpnt ) printk(KERN_ERR " Send mail to faith@acm.org\n" ); } printk(KERN_ERR "scsi: Detected, but driver not loaded (IRQ)\n" ); - goto fail; + release_region(port_base, 0x10); + return NULL; } } return shpnt; -fail: - pci_dev_put(pdev); - release_region(port_base, 0x10); - return NULL; } static int fdomain_16x0_detect(struct scsi_host_template *tpnt) @@ -1101,7 +1094,8 @@ static void my_done(int error) #endif } -static irqreturn_t do_fdomain_16x0_intr(int irq, void *dev_id) +static irqreturn_t do_fdomain_16x0_intr(int irq, void *dev_id, + struct pt_regs * regs ) { unsigned long flags; int status; @@ -1722,8 +1716,6 @@ static int fdomain_16x0_release(struct Scsi_Host *shpnt) free_irq(shpnt->irq, shpnt); if (shpnt->io_port && shpnt->n_io_port) release_region(shpnt->io_port, shpnt->n_io_port); - if (PCI_bus) - pci_dev_put(PCI_dev); return 0; } @@ -1746,15 +1738,6 @@ struct scsi_host_template fdomain_driver_template = { }; #ifndef PCMCIA - -static struct pci_device_id fdomain_pci_tbl[] __devinitdata = { - { PCI_VENDOR_ID_FD, PCI_DEVICE_ID_FD_36C70, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, - { } -}; -MODULE_DEVICE_TABLE(pci, fdomain_pci_tbl); - #define driver_template fdomain_driver_template #include "scsi_module.c" - #endif diff --git a/trunk/drivers/scsi/gdth.c b/trunk/drivers/scsi/gdth.c index 4c698a71f66f..0f3eb22b979a 100644 --- a/trunk/drivers/scsi/gdth.c +++ b/trunk/drivers/scsi/gdth.c @@ -424,7 +424,7 @@ static void gdth_delay(int milliseconds); static void gdth_eval_mapping(ulong32 size, ulong32 *cyls, int *heads, int *secs); -static irqreturn_t gdth_interrupt(int irq, void *dev_id); +static irqreturn_t gdth_interrupt(int irq, void *dev_id, struct pt_regs *regs); static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp); static int gdth_async_event(int hanum); static void gdth_log_event(gdth_evt_data *dvr, char *buffer); @@ -1804,7 +1804,7 @@ static int gdth_wait(int hanum,int index,ulong32 time) gdth_from_wait = TRUE; do { - gdth_interrupt((int)ha->irq,ha); + gdth_interrupt((int)ha->irq,ha,NULL); if (wait_hanum==hanum && wait_index==index) { answer_found = TRUE; break; @@ -3406,7 +3406,7 @@ static void gdth_clear_events(void) /* SCSI interface functions */ -static irqreturn_t gdth_interrupt(int irq,void *dev_id) +static irqreturn_t gdth_interrupt(int irq,void *dev_id,struct pt_regs *regs) { gdth_ha_str *ha2 = (gdth_ha_str *)dev_id; register gdth_ha_str *ha; @@ -3531,7 +3531,7 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id) IStatus &= ~0x80; #ifdef INT_COAL if (coalesced) - ha->status = pcs->ext_status & 0xffff; + ha->status = pcs->ext_status && 0xffff; else #endif ha->status = gdth_readw(&dp6m_ptr->i960r.status); @@ -3543,7 +3543,7 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id) if (coalesced) { ha->info = pcs->info0; ha->info2 = pcs->info1; - ha->service = (pcs->ext_status >> 16) & 0xffff; + ha->service = (pcs->ext_status >> 16) && 0xffff; } else #endif { diff --git a/trunk/drivers/scsi/gdth.h b/trunk/drivers/scsi/gdth.h index 8c29eafd51c5..47eae0299750 100644 --- a/trunk/drivers/scsi/gdth.h +++ b/trunk/drivers/scsi/gdth.h @@ -936,12 +936,18 @@ typedef struct { gdth_binfo_str binfo; /* controller info */ gdth_evt_data dvr; /* event structure */ spinlock_t smp_lock; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) struct pci_dev *pdev; +#endif char oem_name[8]; #ifdef GDTH_DMA_STATISTICS ulong dma32_cnt, dma64_cnt; /* statistics: DMA buffer */ #endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) struct scsi_device *sdev; +#else + struct scsi_device sdev; +#endif } gdth_ha_str; /* structure for scsi_register(), SCSI bus != 0 */ @@ -1023,6 +1029,10 @@ typedef struct { /* function prototyping */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) int gdth_proc_info(struct Scsi_Host *, char *,char **,off_t,int,int); +#else +int gdth_proc_info(char *,char **,off_t,int,int,int); +#endif #endif diff --git a/trunk/drivers/scsi/gvp11.c b/trunk/drivers/scsi/gvp11.c index 2f6c1137a6e5..18dbe5c27dac 100644 --- a/trunk/drivers/scsi/gvp11.c +++ b/trunk/drivers/scsi/gvp11.c @@ -24,7 +24,7 @@ #define DMA(ptr) ((gvp11_scsiregs *)((ptr)->base)) #define HDATA(ptr) ((struct WD33C93_hostdata *)((ptr)->hostdata)) -static irqreturn_t gvp11_intr (int irq, void *_instance) +static irqreturn_t gvp11_intr (int irq, void *_instance, struct pt_regs *fp) { unsigned long flags; unsigned int status; diff --git a/trunk/drivers/scsi/hosts.h b/trunk/drivers/scsi/hosts.h new file mode 100644 index 000000000000..c27264bed5d4 --- /dev/null +++ b/trunk/drivers/scsi/hosts.h @@ -0,0 +1,2 @@ +#warning "This file is obsolete, please use instead" +#include diff --git a/trunk/drivers/scsi/hptiop.c b/trunk/drivers/scsi/hptiop.c index bec83cbee59a..28bfb8f9f81d 100644 --- a/trunk/drivers/scsi/hptiop.c +++ b/trunk/drivers/scsi/hptiop.c @@ -431,7 +431,7 @@ void hptiop_iop_request_callback(struct hptiop_hba *hba, u32 tag) writel(tag, &hba->iop->outbound_queue); } -static irqreturn_t hptiop_intr(int irq, void *dev_id) +static irqreturn_t hptiop_intr(int irq, void *dev_id, struct pt_regs *regs) { struct hptiop_hba *hba = dev_id; int handled; diff --git a/trunk/drivers/scsi/ibmmca.c b/trunk/drivers/scsi/ibmmca.c index 0e57fb6964d5..2be1dc5d852a 100644 --- a/trunk/drivers/scsi/ibmmca.c +++ b/trunk/drivers/scsi/ibmmca.c @@ -497,7 +497,8 @@ static int option_setup(char *); static int ldn_access_load(int, int); static int ldn_access_total_read_write(int); -static irqreturn_t interrupt_handler(int irq, void *dev_id) +static irqreturn_t interrupt_handler(int irq, void *dev_id, + struct pt_regs *regs) { int host_index, ihost_index; unsigned int intr_reg; diff --git a/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c b/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c index fbc1d5c3b0a7..669ea4fff166 100644 --- a/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -1213,7 +1213,7 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq, "ibmvscsi: Re-enabling adapter!\n"); purge_requests(hostdata, DID_REQUEUE); if ((ibmvscsi_reenable_crq_queue(&hostdata->queue, - hostdata)) || + hostdata) == 0) || (ibmvscsi_send_crq(hostdata, 0xC001000000000000LL, 0))) { atomic_set(&hostdata->request_limit, diff --git a/trunk/drivers/scsi/ibmvscsi/rpa_vscsi.c b/trunk/drivers/scsi/ibmvscsi/rpa_vscsi.c index 227c0f2f4d74..01b8ac641eb8 100644 --- a/trunk/drivers/scsi/ibmvscsi/rpa_vscsi.c +++ b/trunk/drivers/scsi/ibmvscsi/rpa_vscsi.c @@ -45,11 +45,14 @@ static unsigned int partition_number = -1; * ibmvscsi_handle_event: - Interrupt handler for crq events * @irq: number of irq to handle, not used * @dev_instance: ibmvscsi_host_data of host that received interrupt + * @regs: pt_regs with registers * * Disables interrupts and schedules srp_task * Always returns IRQ_HANDLED */ -static irqreturn_t ibmvscsi_handle_event(int irq, void *dev_instance) +static irqreturn_t ibmvscsi_handle_event(int irq, + void *dev_instance, + struct pt_regs *regs) { struct ibmvscsi_host_data *hostdata = (struct ibmvscsi_host_data *)dev_instance; diff --git a/trunk/drivers/scsi/imm.c b/trunk/drivers/scsi/imm.c index e31f6122106f..2d95ac9c32c1 100644 --- a/trunk/drivers/scsi/imm.c +++ b/trunk/drivers/scsi/imm.c @@ -1153,7 +1153,7 @@ static int __imm_attach(struct parport *pb) { struct Scsi_Host *host; imm_struct *dev; - DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waiting); + DECLARE_WAIT_QUEUE_HEAD(waiting); DEFINE_WAIT(wait); int ports; int modes, ppb; diff --git a/trunk/drivers/scsi/in2000.c b/trunk/drivers/scsi/in2000.c index 312190a69389..59a4097f1254 100644 --- a/trunk/drivers/scsi/in2000.c +++ b/trunk/drivers/scsi/in2000.c @@ -829,7 +829,7 @@ static void transfer_bytes(Scsi_Cmnd * cmd, int data_in_dir) * but it _does_ need to be able to compile and run in an SMP kernel.) */ -static irqreturn_t in2000_intr(int irqnum, void *dev_id) +static irqreturn_t in2000_intr(int irqnum, void *dev_id, struct pt_regs *ptregs) { struct Scsi_Host *instance = dev_id; struct IN2000_hostdata *hostdata; diff --git a/trunk/drivers/scsi/initio.c b/trunk/drivers/scsi/initio.c index afed293dd7b9..9e10dac61cfd 100644 --- a/trunk/drivers/scsi/initio.c +++ b/trunk/drivers/scsi/initio.c @@ -142,6 +142,8 @@ #define i91u_MAXQUEUE 2 #define i91u_REVID "Initio INI-9X00U/UW SCSI device driver; Revision: 1.04a" +#define INI_VENDOR_ID 0x1101 /* Initio's PCI vendor ID */ +#define DMX_VENDOR_ID 0x134a /* Domex's PCI vendor ID */ #define I950_DEVICE_ID 0x9500 /* Initio's inic-950 product ID */ #define I940_DEVICE_ID 0x9400 /* Initio's inic-940 product ID */ #define I935_DEVICE_ID 0x9401 /* Initio's inic-935 product ID */ @@ -169,16 +171,13 @@ static int setup_debug = 0; static void i91uSCBPost(BYTE * pHcb, BYTE * pScb); -/* PCI Devices supported by this driver */ -static struct pci_device_id i91u_pci_devices[] __devinitdata = { - { PCI_VENDOR_ID_INIT, I950_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { PCI_VENDOR_ID_INIT, I940_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { PCI_VENDOR_ID_INIT, I935_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { PCI_VENDOR_ID_INIT, I920_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { PCI_VENDOR_ID_DOMEX, I920_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { } +static const PCI_ID i91u_pci_devices[] = { + { INI_VENDOR_ID, I950_DEVICE_ID }, + { INI_VENDOR_ID, I940_DEVICE_ID }, + { INI_VENDOR_ID, I935_DEVICE_ID }, + { INI_VENDOR_ID, I920_DEVICE_ID }, + { DMX_VENDOR_ID, I920_DEVICE_ID }, }; -MODULE_DEVICE_TABLE(pci, i91u_pci_devices); #define DEBUG_INTERRUPT 0 #define DEBUG_QUEUE 0 @@ -2749,7 +2748,7 @@ int tul_wait_done_disc(HCS * pCurHcb) return (tul_bad_seq(pCurHcb)); } -static irqreturn_t i91u_intr(int irqno, void *dev_id) +static irqreturn_t i91u_intr(int irqno, void *dev_id, struct pt_regs *regs) { struct Scsi_Host *dev = dev_id; unsigned long flags; @@ -2772,7 +2771,7 @@ static int tul_NewReturnNumberOfAdapters(void) for (i = 0; i < ARRAY_SIZE(i91u_pci_devices); i++) { - while ((pDev = pci_find_device(i91u_pci_devices[i].vendor, i91u_pci_devices[i].device, pDev)) != NULL) { + while ((pDev = pci_find_device(i91u_pci_devices[i].vendor_id, i91u_pci_devices[i].device_id, pDev)) != NULL) { if (pci_enable_device(pDev)) continue; pci_read_config_dword(pDev, 0x44, (u32 *) & dRegValue); diff --git a/trunk/drivers/scsi/ipr.c b/trunk/drivers/scsi/ipr.c index 2dde821025f3..7ed4eef8347b 100644 --- a/trunk/drivers/scsi/ipr.c +++ b/trunk/drivers/scsi/ipr.c @@ -70,7 +70,6 @@ #include #include #include -#include #include #include #include @@ -79,7 +78,6 @@ #include #include #include -#include #include "ipr.h" /* @@ -201,8 +199,6 @@ struct ipr_error_table_t ipr_error_table[] = { "FFFA: Undefined device response recovered by the IOA"}, {0x014A0000, 1, 1, "FFF6: Device bus error, message or command phase"}, - {0x014A8000, 0, 1, - "FFFE: Task Management Function failed"}, {0x015D0000, 0, 1, "FFF6: Failure prediction threshold exceeded"}, {0x015D9200, 0, 1, @@ -265,8 +261,6 @@ struct ipr_error_table_t ipr_error_table[] = { "Device bus status error"}, {0x04448600, 0, 1, "8157: IOA error requiring IOA reset to recover"}, - {0x04448700, 0, 0, - "ATA device status error"}, {0x04490000, 0, 0, "Message reject received from the device"}, {0x04449200, 0, 1, @@ -279,8 +273,6 @@ struct ipr_error_table_t ipr_error_table[] = { "9082: IOA detected device error"}, {0x044A0000, 1, 1, "3110: Device bus error, message or command phase"}, - {0x044A8000, 1, 1, - "3110: SAS Command / Task Management Function failed"}, {0x04670400, 0, 1, "9091: Incorrect hardware configuration change has been detected"}, {0x04678000, 0, 1, @@ -461,8 +453,7 @@ static void ipr_trc_hook(struct ipr_cmnd *ipr_cmd, trace_entry->time = jiffies; trace_entry->op_code = ipr_cmd->ioarcb.cmd_pkt.cdb[0]; trace_entry->type = type; - trace_entry->ata_op_code = ipr_cmd->ioarcb.add_data.u.regs.command; - trace_entry->cmd_index = ipr_cmd->cmd_index & 0xff; + trace_entry->cmd_index = ipr_cmd->cmd_index; trace_entry->res_handle = ipr_cmd->ioarcb.res_handle; trace_entry->u.add_data = add_data; } @@ -489,10 +480,8 @@ static void ipr_reinit_ipr_cmnd(struct ipr_cmnd *ipr_cmd) ioarcb->read_ioadl_len = 0; ioasa->ioasc = 0; ioasa->residual_data_len = 0; - ioasa->u.gata.status = 0; ipr_cmd->scsi_cmd = NULL; - ipr_cmd->qc = NULL; ipr_cmd->sense_buffer[0] = 0; ipr_cmd->dma_use_sg = 0; } @@ -636,28 +625,6 @@ static int ipr_set_pcix_cmd_reg(struct ipr_ioa_cfg *ioa_cfg) return 0; } -/** - * ipr_sata_eh_done - done function for aborted SATA commands - * @ipr_cmd: ipr command struct - * - * This function is invoked for ops generated to SATA - * devices which are being aborted. - * - * Return value: - * none - **/ -static void ipr_sata_eh_done(struct ipr_cmnd *ipr_cmd) -{ - struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; - struct ata_queued_cmd *qc = ipr_cmd->qc; - struct ipr_sata_port *sata_port = qc->ap->private_data; - - qc->err_mask |= AC_ERR_OTHER; - sata_port->ioasa.status |= ATA_BUSY; - list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q); - ata_qc_complete(qc); -} - /** * ipr_scsi_eh_done - mid-layer done function for aborted ops * @ipr_cmd: ipr command struct @@ -702,8 +669,6 @@ static void ipr_fail_all_ops(struct ipr_ioa_cfg *ioa_cfg) if (ipr_cmd->scsi_cmd) ipr_cmd->done = ipr_scsi_eh_done; - else if (ipr_cmd->qc) - ipr_cmd->done = ipr_sata_eh_done; ipr_trc_hook(ipr_cmd, IPR_TRACE_FINISH, IPR_IOASC_IOA_WAS_RESET); del_timer(&ipr_cmd->timer); @@ -860,7 +825,6 @@ static void ipr_init_res_entry(struct ipr_resource_entry *res) res->del_from_ml = 0; res->resetting_device = 0; res->sdev = NULL; - res->sata_port = NULL; } /** @@ -1352,7 +1316,7 @@ static u32 ipr_get_error(u32 ioasc) int i; for (i = 0; i < ARRAY_SIZE(ipr_error_table); i++) - if (ipr_error_table[i].ioasc == (ioasc & IPR_IOASC_IOASC_MASK)) + if (ipr_error_table[i].ioasc == ioasc) return i; return 0; @@ -3087,17 +3051,6 @@ static int ipr_free_dump(struct ipr_ioa_cfg *ioa_cfg) { return 0; }; **/ static int ipr_change_queue_depth(struct scsi_device *sdev, int qdepth) { - struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)sdev->host->hostdata; - struct ipr_resource_entry *res; - unsigned long lock_flags = 0; - - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); - res = (struct ipr_resource_entry *)sdev->hostdata; - - if (res && ipr_is_gata(res) && qdepth > IPR_MAX_CMD_PER_ATA_LUN) - qdepth = IPR_MAX_CMD_PER_ATA_LUN; - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); - scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth); return sdev->queue_depth; } @@ -3212,122 +3165,6 @@ static int ipr_biosparam(struct scsi_device *sdev, return 0; } -/** - * ipr_find_starget - Find target based on bus/target. - * @starget: scsi target struct - * - * Return value: - * resource entry pointer if found / NULL if not found - **/ -static struct ipr_resource_entry *ipr_find_starget(struct scsi_target *starget) -{ - struct Scsi_Host *shost = dev_to_shost(&starget->dev); - struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *) shost->hostdata; - struct ipr_resource_entry *res; - - list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { - if ((res->cfgte.res_addr.bus == starget->channel) && - (res->cfgte.res_addr.target == starget->id) && - (res->cfgte.res_addr.lun == 0)) { - return res; - } - } - - return NULL; -} - -static struct ata_port_info sata_port_info; - -/** - * ipr_target_alloc - Prepare for commands to a SCSI target - * @starget: scsi target struct - * - * If the device is a SATA device, this function allocates an - * ATA port with libata, else it does nothing. - * - * Return value: - * 0 on success / non-0 on failure - **/ -static int ipr_target_alloc(struct scsi_target *starget) -{ - struct Scsi_Host *shost = dev_to_shost(&starget->dev); - struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *) shost->hostdata; - struct ipr_sata_port *sata_port; - struct ata_port *ap; - struct ipr_resource_entry *res; - unsigned long lock_flags; - - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); - res = ipr_find_starget(starget); - starget->hostdata = NULL; - - if (res && ipr_is_gata(res)) { - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); - sata_port = kzalloc(sizeof(*sata_port), GFP_KERNEL); - if (!sata_port) - return -ENOMEM; - - ap = ata_sas_port_alloc(&ioa_cfg->ata_host, &sata_port_info, shost); - if (ap) { - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); - sata_port->ioa_cfg = ioa_cfg; - sata_port->ap = ap; - sata_port->res = res; - - res->sata_port = sata_port; - ap->private_data = sata_port; - starget->hostdata = sata_port; - } else { - kfree(sata_port); - return -ENOMEM; - } - } - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); - - return 0; -} - -/** - * ipr_target_destroy - Destroy a SCSI target - * @starget: scsi target struct - * - * If the device was a SATA device, this function frees the libata - * ATA port, else it does nothing. - * - **/ -static void ipr_target_destroy(struct scsi_target *starget) -{ - struct ipr_sata_port *sata_port = starget->hostdata; - - if (sata_port) { - starget->hostdata = NULL; - ata_sas_port_destroy(sata_port->ap); - kfree(sata_port); - } -} - -/** - * ipr_find_sdev - Find device based on bus/target/lun. - * @sdev: scsi device struct - * - * Return value: - * resource entry pointer if found / NULL if not found - **/ -static struct ipr_resource_entry *ipr_find_sdev(struct scsi_device *sdev) -{ - struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *) sdev->host->hostdata; - struct ipr_resource_entry *res; - - list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { - if ((res->cfgte.res_addr.bus == sdev->channel) && - (res->cfgte.res_addr.target == sdev->id) && - (res->cfgte.res_addr.lun == sdev->lun)) - return res; - } - - return NULL; -} - /** * ipr_slave_destroy - Unconfigure a SCSI device * @sdev: scsi device struct @@ -3346,11 +3183,8 @@ static void ipr_slave_destroy(struct scsi_device *sdev) spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); res = (struct ipr_resource_entry *) sdev->hostdata; if (res) { - if (res->sata_port) - ata_port_disable(res->sata_port->ap); sdev->hostdata = NULL; res->sdev = NULL; - res->sata_port = NULL; } spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); } @@ -3385,44 +3219,12 @@ static int ipr_slave_configure(struct scsi_device *sdev) } if (ipr_is_vset_device(res) || ipr_is_scsi_disk(res)) sdev->allow_restart = 1; - if (ipr_is_gata(res) && res->sata_port) { - scsi_adjust_queue_depth(sdev, 0, IPR_MAX_CMD_PER_ATA_LUN); - ata_sas_slave_configure(sdev, res->sata_port->ap); - } else { - scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun); - } + scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun); } spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); return 0; } -/** - * ipr_ata_slave_alloc - Prepare for commands to a SATA device - * @sdev: scsi device struct - * - * This function initializes an ATA port so that future commands - * sent through queuecommand will work. - * - * Return value: - * 0 on success - **/ -static int ipr_ata_slave_alloc(struct scsi_device *sdev) -{ - struct ipr_sata_port *sata_port = NULL; - int rc = -ENXIO; - - ENTER; - if (sdev->sdev_target) - sata_port = sdev->sdev_target->hostdata; - if (sata_port) - rc = ata_sas_port_init(sata_port->ap); - if (rc) - ipr_slave_destroy(sdev); - - LEAVE; - return rc; -} - /** * ipr_slave_alloc - Prepare for commands to a device. * @sdev: scsi device struct @@ -3446,18 +3248,18 @@ static int ipr_slave_alloc(struct scsi_device *sdev) spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); - res = ipr_find_sdev(sdev); - if (res) { - res->sdev = sdev; - res->add_to_ml = 0; - res->in_erp = 0; - sdev->hostdata = res; - if (!ipr_is_naca_model(res)) - res->needs_sync_complete = 1; - rc = 0; - if (ipr_is_gata(res)) { - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); - return ipr_ata_slave_alloc(sdev); + list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { + if ((res->cfgte.res_addr.bus == sdev->channel) && + (res->cfgte.res_addr.target == sdev->id) && + (res->cfgte.res_addr.lun == sdev->lun)) { + res->sdev = sdev; + res->add_to_ml = 0; + res->in_erp = 0; + sdev->hostdata = res; + if (!ipr_is_naca_model(res)) + res->needs_sync_complete = 1; + rc = 0; + break; } } @@ -3512,8 +3314,7 @@ static int ipr_eh_host_reset(struct scsi_cmnd * cmd) * This function issues a device reset to the affected device. * If the device is a SCSI device, a LUN reset will be sent * to the device first. If that does not work, a target reset - * will be sent. If the device is a SATA device, a PHY reset will - * be sent. + * will be sent. * * Return value: * 0 on success / non-zero on failure @@ -3524,78 +3325,25 @@ static int ipr_device_reset(struct ipr_ioa_cfg *ioa_cfg, struct ipr_cmnd *ipr_cmd; struct ipr_ioarcb *ioarcb; struct ipr_cmd_pkt *cmd_pkt; - struct ipr_ioarcb_ata_regs *regs; u32 ioasc; ENTER; ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg); ioarcb = &ipr_cmd->ioarcb; cmd_pkt = &ioarcb->cmd_pkt; - regs = &ioarcb->add_data.u.regs; ioarcb->res_handle = res->cfgte.res_handle; cmd_pkt->request_type = IPR_RQTYPE_IOACMD; cmd_pkt->cdb[0] = IPR_RESET_DEVICE; - if (ipr_is_gata(res)) { - cmd_pkt->cdb[2] = IPR_ATA_PHY_RESET; - ioarcb->add_cmd_parms_len = cpu_to_be32(sizeof(regs->flags)); - regs->flags |= IPR_ATA_FLAG_STATUS_ON_GOOD_COMPLETION; - } ipr_send_blocking_cmd(ipr_cmd, ipr_timeout, IPR_DEVICE_RESET_TIMEOUT); ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q); - if (ipr_is_gata(res) && res->sata_port && ioasc != IPR_IOASC_IOA_WAS_RESET) - memcpy(&res->sata_port->ioasa, &ipr_cmd->ioasa.u.gata, - sizeof(struct ipr_ioasa_gata)); LEAVE; return (IPR_IOASC_SENSE_KEY(ioasc) ? -EIO : 0); } -/** - * ipr_sata_reset - Reset the SATA port - * @ap: SATA port to reset - * @classes: class of the attached device - * - * This function issues a SATA phy reset to the affected ATA port. - * - * Return value: - * 0 on success / non-zero on failure - **/ -static int ipr_sata_reset(struct ata_port *ap, unsigned int *classes) -{ - struct ipr_sata_port *sata_port = ap->private_data; - struct ipr_ioa_cfg *ioa_cfg = sata_port->ioa_cfg; - struct ipr_resource_entry *res; - unsigned long lock_flags = 0; - int rc = -ENXIO; - - ENTER; - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); - res = sata_port->res; - if (res) { - rc = ipr_device_reset(ioa_cfg, res); - switch(res->cfgte.proto) { - case IPR_PROTO_SATA: - case IPR_PROTO_SAS_STP: - *classes = ATA_DEV_ATA; - break; - case IPR_PROTO_SATA_ATAPI: - case IPR_PROTO_SAS_STP_ATAPI: - *classes = ATA_DEV_ATAPI; - break; - default: - *classes = ATA_DEV_UNKNOWN; - break; - }; - } - - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); - LEAVE; - return rc; -} - /** * ipr_eh_dev_reset - Reset the device * @scsi_cmd: scsi command struct @@ -3612,8 +3360,7 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd * scsi_cmd) struct ipr_cmnd *ipr_cmd; struct ipr_ioa_cfg *ioa_cfg; struct ipr_resource_entry *res; - struct ata_port *ap; - int rc = 0; + int rc; ENTER; ioa_cfg = (struct ipr_ioa_cfg *) scsi_cmd->device->host->hostdata; @@ -3641,14 +3388,7 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd * scsi_cmd) res->resetting_device = 1; scmd_printk(KERN_ERR, scsi_cmd, "Resetting device\n"); - - if (ipr_is_gata(res) && res->sata_port) { - ap = res->sata_port->ap; - spin_unlock_irq(scsi_cmd->device->host->host_lock); - ata_do_eh(ap, NULL, NULL, ipr_sata_reset, NULL); - spin_lock_irq(scsi_cmd->device->host->host_lock); - } else - rc = ipr_device_reset(ioa_cfg, res); + rc = ipr_device_reset(ioa_cfg, res); res->resetting_device = 0; LEAVE; @@ -3880,11 +3620,12 @@ static irqreturn_t ipr_handle_other_interrupt(struct ipr_ioa_cfg *ioa_cfg, * ipr_isr - Interrupt service routine * @irq: irq number * @devp: pointer to ioa config struct + * @regs: pt_regs struct * * Return value: * IRQ_NONE / IRQ_HANDLED **/ -static irqreturn_t ipr_isr(int irq, void *devp) +static irqreturn_t ipr_isr(int irq, void *devp, struct pt_regs *regs) { struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)devp; unsigned long lock_flags = 0; @@ -4559,9 +4300,6 @@ static int ipr_queuecommand(struct scsi_cmnd *scsi_cmd, return 0; } - if (ipr_is_gata(res) && res->sata_port) - return ata_sas_queuecmd(scsi_cmd, done, res->sata_port->ap); - ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg); ioarcb = &ipr_cmd->ioarcb; list_add_tail(&ipr_cmd->queue, &ioa_cfg->pending_q); @@ -4606,26 +4344,6 @@ static int ipr_queuecommand(struct scsi_cmnd *scsi_cmd, return 0; } -/** - * ipr_ioctl - IOCTL handler - * @sdev: scsi device struct - * @cmd: IOCTL cmd - * @arg: IOCTL arg - * - * Return value: - * 0 on success / other on failure - **/ -int ipr_ioctl(struct scsi_device *sdev, int cmd, void __user *arg) -{ - struct ipr_resource_entry *res; - - res = (struct ipr_resource_entry *)sdev->hostdata; - if (res && ipr_is_gata(res)) - return ata_scsi_ioctl(sdev, cmd, arg); - - return -EINVAL; -} - /** * ipr_info - Get information about the card/driver * @scsi_host: scsi host struct @@ -4648,45 +4366,10 @@ static const char * ipr_ioa_info(struct Scsi_Host *host) return buffer; } -/** - * ipr_scsi_timed_out - Handle scsi command timeout - * @scsi_cmd: scsi command struct - * - * Return value: - * EH_NOT_HANDLED - **/ -enum scsi_eh_timer_return ipr_scsi_timed_out(struct scsi_cmnd *scsi_cmd) -{ - struct ipr_ioa_cfg *ioa_cfg; - struct ipr_cmnd *ipr_cmd; - unsigned long flags; - - ENTER; - spin_lock_irqsave(scsi_cmd->device->host->host_lock, flags); - ioa_cfg = (struct ipr_ioa_cfg *)scsi_cmd->device->host->hostdata; - - list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) { - if (ipr_cmd->qc && ipr_cmd->qc->scsicmd == scsi_cmd) { - ipr_cmd->qc->err_mask |= AC_ERR_TIMEOUT; - ipr_cmd->qc->flags |= ATA_QCFLAG_FAILED; - break; - } - } - - spin_unlock_irqrestore(scsi_cmd->device->host->host_lock, flags); - LEAVE; - return EH_NOT_HANDLED; -} - -static struct scsi_transport_template ipr_transport_template = { - .eh_timed_out = ipr_scsi_timed_out -}; - static struct scsi_host_template driver_template = { .module = THIS_MODULE, .name = "IPR", .info = ipr_ioa_info, - .ioctl = ipr_ioctl, .queuecommand = ipr_queuecommand, .eh_abort_handler = ipr_eh_abort, .eh_device_reset_handler = ipr_eh_dev_reset, @@ -4694,8 +4377,6 @@ static struct scsi_host_template driver_template = { .slave_alloc = ipr_slave_alloc, .slave_configure = ipr_slave_configure, .slave_destroy = ipr_slave_destroy, - .target_alloc = ipr_target_alloc, - .target_destroy = ipr_target_destroy, .change_queue_depth = ipr_change_queue_depth, .change_queue_type = ipr_change_queue_type, .bios_param = ipr_biosparam, @@ -4710,330 +4391,6 @@ static struct scsi_host_template driver_template = { .proc_name = IPR_NAME }; -/** - * ipr_ata_phy_reset - libata phy_reset handler - * @ap: ata port to reset - * - **/ -static void ipr_ata_phy_reset(struct ata_port *ap) -{ - unsigned long flags; - struct ipr_sata_port *sata_port = ap->private_data; - struct ipr_resource_entry *res = sata_port->res; - struct ipr_ioa_cfg *ioa_cfg = sata_port->ioa_cfg; - int rc; - - ENTER; - spin_lock_irqsave(ioa_cfg->host->host_lock, flags); - while(ioa_cfg->in_reset_reload) { - spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags); - wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload); - spin_lock_irqsave(ioa_cfg->host->host_lock, flags); - } - - if (!ioa_cfg->allow_cmds) - goto out_unlock; - - rc = ipr_device_reset(ioa_cfg, res); - - if (rc) { - ap->ops->port_disable(ap); - goto out_unlock; - } - - switch(res->cfgte.proto) { - case IPR_PROTO_SATA: - case IPR_PROTO_SAS_STP: - ap->device[0].class = ATA_DEV_ATA; - break; - case IPR_PROTO_SATA_ATAPI: - case IPR_PROTO_SAS_STP_ATAPI: - ap->device[0].class = ATA_DEV_ATAPI; - break; - default: - ap->device[0].class = ATA_DEV_UNKNOWN; - ap->ops->port_disable(ap); - break; - }; - -out_unlock: - spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags); - LEAVE; -} - -/** - * ipr_ata_post_internal - Cleanup after an internal command - * @qc: ATA queued command - * - * Return value: - * none - **/ -static void ipr_ata_post_internal(struct ata_queued_cmd *qc) -{ - struct ipr_sata_port *sata_port = qc->ap->private_data; - struct ipr_ioa_cfg *ioa_cfg = sata_port->ioa_cfg; - struct ipr_cmnd *ipr_cmd; - unsigned long flags; - - spin_lock_irqsave(ioa_cfg->host->host_lock, flags); - list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) { - if (ipr_cmd->qc == qc) { - ipr_device_reset(ioa_cfg, sata_port->res); - break; - } - } - spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags); -} - -/** - * ipr_tf_read - Read the current ATA taskfile for the ATA port - * @ap: ATA port - * @tf: destination ATA taskfile - * - * Return value: - * none - **/ -static void ipr_tf_read(struct ata_port *ap, struct ata_taskfile *tf) -{ - struct ipr_sata_port *sata_port = ap->private_data; - struct ipr_ioasa_gata *g = &sata_port->ioasa; - - tf->feature = g->error; - tf->nsect = g->nsect; - tf->lbal = g->lbal; - tf->lbam = g->lbam; - tf->lbah = g->lbah; - tf->device = g->device; - tf->command = g->status; - tf->hob_nsect = g->hob_nsect; - tf->hob_lbal = g->hob_lbal; - tf->hob_lbam = g->hob_lbam; - tf->hob_lbah = g->hob_lbah; - tf->ctl = g->alt_status; -} - -/** - * ipr_copy_sata_tf - Copy a SATA taskfile to an IOA data structure - * @regs: destination - * @tf: source ATA taskfile - * - * Return value: - * none - **/ -static void ipr_copy_sata_tf(struct ipr_ioarcb_ata_regs *regs, - struct ata_taskfile *tf) -{ - regs->feature = tf->feature; - regs->nsect = tf->nsect; - regs->lbal = tf->lbal; - regs->lbam = tf->lbam; - regs->lbah = tf->lbah; - regs->device = tf->device; - regs->command = tf->command; - regs->hob_feature = tf->hob_feature; - regs->hob_nsect = tf->hob_nsect; - regs->hob_lbal = tf->hob_lbal; - regs->hob_lbam = tf->hob_lbam; - regs->hob_lbah = tf->hob_lbah; - regs->ctl = tf->ctl; -} - -/** - * ipr_sata_done - done function for SATA commands - * @ipr_cmd: ipr command struct - * - * This function is invoked by the interrupt handler for - * ops generated by the SCSI mid-layer to SATA devices - * - * Return value: - * none - **/ -static void ipr_sata_done(struct ipr_cmnd *ipr_cmd) -{ - struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; - struct ata_queued_cmd *qc = ipr_cmd->qc; - struct ipr_sata_port *sata_port = qc->ap->private_data; - struct ipr_resource_entry *res = sata_port->res; - u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); - - memcpy(&sata_port->ioasa, &ipr_cmd->ioasa.u.gata, - sizeof(struct ipr_ioasa_gata)); - ipr_dump_ioasa(ioa_cfg, ipr_cmd, res); - - if (be32_to_cpu(ipr_cmd->ioasa.ioasc_specific) & IPR_ATA_DEVICE_WAS_RESET) - scsi_report_device_reset(ioa_cfg->host, res->cfgte.res_addr.bus, - res->cfgte.res_addr.target); - - if (IPR_IOASC_SENSE_KEY(ioasc) > RECOVERED_ERROR) - qc->err_mask |= __ac_err_mask(ipr_cmd->ioasa.u.gata.status); - else - qc->err_mask |= ac_err_mask(ipr_cmd->ioasa.u.gata.status); - list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q); - ata_qc_complete(qc); -} - -/** - * ipr_build_ata_ioadl - Build an ATA scatter/gather list - * @ipr_cmd: ipr command struct - * @qc: ATA queued command - * - **/ -static void ipr_build_ata_ioadl(struct ipr_cmnd *ipr_cmd, - struct ata_queued_cmd *qc) -{ - u32 ioadl_flags = 0; - struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; - struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl; - int len = qc->nbytes + qc->pad_len; - struct scatterlist *sg; - - if (len == 0) - return; - - if (qc->dma_dir == DMA_TO_DEVICE) { - ioadl_flags = IPR_IOADL_FLAGS_WRITE; - ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ; - ioarcb->write_data_transfer_length = cpu_to_be32(len); - ioarcb->write_ioadl_len = - cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg); - } else if (qc->dma_dir == DMA_FROM_DEVICE) { - ioadl_flags = IPR_IOADL_FLAGS_READ; - ioarcb->read_data_transfer_length = cpu_to_be32(len); - ioarcb->read_ioadl_len = - cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg); - } - - ata_for_each_sg(sg, qc) { - ioadl->flags_and_data_len = cpu_to_be32(ioadl_flags | sg_dma_len(sg)); - ioadl->address = cpu_to_be32(sg_dma_address(sg)); - if (ata_sg_is_last(sg, qc)) - ioadl->flags_and_data_len |= cpu_to_be32(IPR_IOADL_FLAGS_LAST); - else - ioadl++; - } -} - -/** - * ipr_qc_issue - Issue a SATA qc to a device - * @qc: queued command - * - * Return value: - * 0 if success - **/ -static unsigned int ipr_qc_issue(struct ata_queued_cmd *qc) -{ - struct ata_port *ap = qc->ap; - struct ipr_sata_port *sata_port = ap->private_data; - struct ipr_resource_entry *res = sata_port->res; - struct ipr_ioa_cfg *ioa_cfg = sata_port->ioa_cfg; - struct ipr_cmnd *ipr_cmd; - struct ipr_ioarcb *ioarcb; - struct ipr_ioarcb_ata_regs *regs; - - if (unlikely(!ioa_cfg->allow_cmds || ioa_cfg->ioa_is_dead)) - return -EIO; - - ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg); - ioarcb = &ipr_cmd->ioarcb; - regs = &ioarcb->add_data.u.regs; - - memset(&ioarcb->add_data, 0, sizeof(ioarcb->add_data)); - ioarcb->add_cmd_parms_len = cpu_to_be32(sizeof(ioarcb->add_data.u.regs)); - - list_add_tail(&ipr_cmd->queue, &ioa_cfg->pending_q); - ipr_cmd->qc = qc; - ipr_cmd->done = ipr_sata_done; - ipr_cmd->ioarcb.res_handle = res->cfgte.res_handle; - ioarcb->cmd_pkt.request_type = IPR_RQTYPE_ATA_PASSTHRU; - ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_LINK_DESC; - ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_ULEN_CHK; - ipr_cmd->dma_use_sg = qc->pad_len ? qc->n_elem + 1 : qc->n_elem; - - ipr_build_ata_ioadl(ipr_cmd, qc); - regs->flags |= IPR_ATA_FLAG_STATUS_ON_GOOD_COMPLETION; - ipr_copy_sata_tf(regs, &qc->tf); - memcpy(ioarcb->cmd_pkt.cdb, qc->cdb, IPR_MAX_CDB_LEN); - ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_GET_PHYS_LOC(res->cfgte.res_addr)); - - switch (qc->tf.protocol) { - case ATA_PROT_NODATA: - case ATA_PROT_PIO: - break; - - case ATA_PROT_DMA: - regs->flags |= IPR_ATA_FLAG_XFER_TYPE_DMA; - break; - - case ATA_PROT_ATAPI: - case ATA_PROT_ATAPI_NODATA: - regs->flags |= IPR_ATA_FLAG_PACKET_CMD; - break; - - case ATA_PROT_ATAPI_DMA: - regs->flags |= IPR_ATA_FLAG_PACKET_CMD; - regs->flags |= IPR_ATA_FLAG_XFER_TYPE_DMA; - break; - - default: - WARN_ON(1); - return -1; - } - - mb(); - writel(be32_to_cpu(ioarcb->ioarcb_host_pci_addr), - ioa_cfg->regs.ioarrin_reg); - return 0; -} - -/** - * ipr_ata_check_status - Return last ATA status - * @ap: ATA port - * - * Return value: - * ATA status - **/ -static u8 ipr_ata_check_status(struct ata_port *ap) -{ - struct ipr_sata_port *sata_port = ap->private_data; - return sata_port->ioasa.status; -} - -/** - * ipr_ata_check_altstatus - Return last ATA altstatus - * @ap: ATA port - * - * Return value: - * Alt ATA status - **/ -static u8 ipr_ata_check_altstatus(struct ata_port *ap) -{ - struct ipr_sata_port *sata_port = ap->private_data; - return sata_port->ioasa.alt_status; -} - -static struct ata_port_operations ipr_sata_ops = { - .port_disable = ata_port_disable, - .check_status = ipr_ata_check_status, - .check_altstatus = ipr_ata_check_altstatus, - .dev_select = ata_noop_dev_select, - .phy_reset = ipr_ata_phy_reset, - .post_internal_cmd = ipr_ata_post_internal, - .tf_read = ipr_tf_read, - .qc_prep = ata_noop_qc_prep, - .qc_issue = ipr_qc_issue, - .port_start = ata_sas_port_start, - .port_stop = ata_sas_port_stop -}; - -static struct ata_port_info sata_port_info = { - .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | ATA_FLAG_SATA_RESET | - ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA, - .pio_mask = 0x10, /* pio4 */ - .mwdma_mask = 0x07, - .udma_mask = 0x7f, /* udma0-6 */ - .port_ops = &ipr_sata_ops -}; - #ifdef CONFIG_PPC_PSERIES static const u16 ipr_blocked_processors[] = { PV_NORTHSTAR, @@ -6995,7 +6352,7 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev, struct Scsi_Host *host; unsigned long ipr_regs_pci; void __iomem *ipr_regs; - int rc = PCIBIOS_SUCCESSFUL; + u32 rc = PCIBIOS_SUCCESSFUL; volatile u32 mask, uproc; ENTER; @@ -7017,9 +6374,6 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev, ioa_cfg = (struct ipr_ioa_cfg *)host->hostdata; memset(ioa_cfg, 0, sizeof(struct ipr_ioa_cfg)); - host->transportt = &ipr_transport_template; - ata_host_init(&ioa_cfg->ata_host, &pdev->dev, - sata_port_info.flags, &ipr_sata_ops); ioa_cfg->chip_cfg = ipr_get_chip_cfg(dev_id); @@ -7395,7 +6749,7 @@ static int __init ipr_init(void) ipr_info("IBM Power RAID SCSI Device Driver version: %s %s\n", IPR_DRIVER_VERSION, IPR_DRIVER_DATE); - return pci_register_driver(&ipr_driver); + return pci_module_init(&ipr_driver); } /** diff --git a/trunk/drivers/scsi/ipr.h b/trunk/drivers/scsi/ipr.h index 6d035283af08..11eaff524327 100644 --- a/trunk/drivers/scsi/ipr.h +++ b/trunk/drivers/scsi/ipr.h @@ -28,7 +28,6 @@ #include #include -#include #include #include #include @@ -37,8 +36,8 @@ /* * Literals */ -#define IPR_DRIVER_VERSION "2.2.0" -#define IPR_DRIVER_DATE "(September 25, 2006)" +#define IPR_DRIVER_VERSION "2.1.4" +#define IPR_DRIVER_DATE "(August 2, 2006)" /* * IPR_MAX_CMD_PER_LUN: This defines the maximum number of outstanding @@ -850,13 +849,6 @@ struct ipr_bus_attributes { u32 max_xfer_rate; }; -struct ipr_sata_port { - struct ipr_ioa_cfg *ioa_cfg; - struct ata_port *ap; - struct ipr_resource_entry *res; - struct ipr_ioasa_gata ioasa; -}; - struct ipr_resource_entry { struct ipr_config_table_entry cfgte; u8 needs_sync_complete:1; @@ -866,7 +858,6 @@ struct ipr_resource_entry { u8 resetting_device:1; struct scsi_device *sdev; - struct ipr_sata_port *sata_port; struct list_head queue; }; @@ -937,11 +928,10 @@ struct ipr_trace_entry { u32 time; u8 op_code; - u8 ata_op_code; u8 type; #define IPR_TRACE_START 0x00 #define IPR_TRACE_FINISH 0xff - u8 cmd_index; + u16 cmd_index; __be32 res_handle; union { @@ -1083,7 +1073,6 @@ struct ipr_ioa_cfg { struct ipr_cmnd *reset_cmd; - struct ata_host ata_host; char ipr_cmd_label[8]; #define IPR_CMD_LABEL "ipr_cmnd" struct ipr_cmnd *ipr_cmnd_list[IPR_NUM_CMD_BLKS]; @@ -1096,7 +1085,6 @@ struct ipr_cmnd { struct ipr_ioadl_desc ioadl[IPR_NUM_IOADL_ENTRIES]; struct list_head queue; struct scsi_cmnd *scsi_cmd; - struct ata_queued_cmd *qc; struct completion completion; struct timer_list timer; void (*done) (struct ipr_cmnd *); diff --git a/trunk/drivers/scsi/ips.c b/trunk/drivers/scsi/ips.c index f06a06ae6092..3c639286ec1e 100644 --- a/trunk/drivers/scsi/ips.c +++ b/trunk/drivers/scsi/ips.c @@ -182,8 +182,14 @@ #include #include + #include "scsi.h" + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0) +#include "hosts.h" +#else #include +#endif #include "ips.h" @@ -244,11 +250,11 @@ module_param(ips, charp, 0); */ static int ips_detect(struct scsi_host_template *); static int ips_release(struct Scsi_Host *); -static int ips_eh_abort(struct scsi_cmnd *); -static int ips_eh_reset(struct scsi_cmnd *); -static int ips_queue(struct scsi_cmnd *, void (*)(struct scsi_cmnd *)); +static int ips_eh_abort(Scsi_Cmnd *); +static int ips_eh_reset(Scsi_Cmnd *); +static int ips_queue(Scsi_Cmnd *, void (*)(Scsi_Cmnd *)); static const char *ips_info(struct Scsi_Host *); -static irqreturn_t do_ipsintr(int, void *); +static irqreturn_t do_ipsintr(int, void *, struct pt_regs *); static int ips_hainit(ips_ha_t *); static int ips_map_status(ips_ha_t *, ips_scb_t *, ips_stat_t *); static int ips_send_wait(ips_ha_t *, ips_scb_t *, int, int); @@ -319,26 +325,24 @@ static uint32_t ips_statupd_copperhead_memio(ips_ha_t *); static uint32_t ips_statupd_morpheus(ips_ha_t *); static ips_scb_t *ips_getscb(ips_ha_t *); static void ips_putq_scb_head(ips_scb_queue_t *, ips_scb_t *); -static void ips_putq_wait_tail(ips_wait_queue_t *, struct scsi_cmnd *); +static void ips_putq_wait_tail(ips_wait_queue_t *, Scsi_Cmnd *); static void ips_putq_copp_tail(ips_copp_queue_t *, ips_copp_wait_item_t *); static ips_scb_t *ips_removeq_scb_head(ips_scb_queue_t *); static ips_scb_t *ips_removeq_scb(ips_scb_queue_t *, ips_scb_t *); -static struct scsi_cmnd *ips_removeq_wait_head(ips_wait_queue_t *); -static struct scsi_cmnd *ips_removeq_wait(ips_wait_queue_t *, - struct scsi_cmnd *); +static Scsi_Cmnd *ips_removeq_wait_head(ips_wait_queue_t *); +static Scsi_Cmnd *ips_removeq_wait(ips_wait_queue_t *, Scsi_Cmnd *); static ips_copp_wait_item_t *ips_removeq_copp(ips_copp_queue_t *, ips_copp_wait_item_t *); static ips_copp_wait_item_t *ips_removeq_copp_head(ips_copp_queue_t *); -static int ips_is_passthru(struct scsi_cmnd *); -static int ips_make_passthru(ips_ha_t *, struct scsi_cmnd *, ips_scb_t *, int); +static int ips_is_passthru(Scsi_Cmnd *); +static int ips_make_passthru(ips_ha_t *, Scsi_Cmnd *, ips_scb_t *, int); static int ips_usrcmd(ips_ha_t *, ips_passthru_t *, ips_scb_t *); static void ips_cleanup_passthru(ips_ha_t *, ips_scb_t *); -static void ips_scmd_buf_write(struct scsi_cmnd * scmd, void *data, +static void ips_scmd_buf_write(Scsi_Cmnd * scmd, void *data, unsigned int count); -static void ips_scmd_buf_read(struct scsi_cmnd * scmd, void *data, - unsigned int count); +static void ips_scmd_buf_read(Scsi_Cmnd * scmd, void *data, unsigned int count); static int ips_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int); static int ips_host_info(ips_ha_t *, char *, off_t, int); @@ -808,7 +812,8 @@ ips_halt(struct notifier_block *nb, ulong event, void *buf) /* Abort a command (using the new error code stuff) */ /* Note: this routine is called under the io_request_lock */ /****************************************************************************/ -int ips_eh_abort(struct scsi_cmnd *SC) +int +ips_eh_abort(Scsi_Cmnd * SC) { ips_ha_t *ha; ips_copp_wait_item_t *item; @@ -866,7 +871,8 @@ int ips_eh_abort(struct scsi_cmnd *SC) /* NOTE: this routine is called under the io_request_lock spinlock */ /* */ /****************************************************************************/ -static int __ips_eh_reset(struct scsi_cmnd *SC) +static int +__ips_eh_reset(Scsi_Cmnd * SC) { int ret; int i; @@ -962,7 +968,7 @@ static int __ips_eh_reset(struct scsi_cmnd *SC) ret = (*ha->func.reset) (ha); if (!ret) { - struct scsi_cmnd *scsi_cmd; + Scsi_Cmnd *scsi_cmd; IPS_PRINTK(KERN_NOTICE, ha->pcidev, "Controller reset failed - controller now offline.\n"); @@ -991,7 +997,7 @@ static int __ips_eh_reset(struct scsi_cmnd *SC) } if (!ips_clear_adapter(ha, IPS_INTR_IORL)) { - struct scsi_cmnd *scsi_cmd; + Scsi_Cmnd *scsi_cmd; IPS_PRINTK(KERN_NOTICE, ha->pcidev, "Controller reset failed - controller now offline.\n"); @@ -1053,7 +1059,8 @@ static int __ips_eh_reset(struct scsi_cmnd *SC) } -static int ips_eh_reset(struct scsi_cmnd *SC) +static int +ips_eh_reset(Scsi_Cmnd * SC) { int rc; @@ -1076,7 +1083,8 @@ static int ips_eh_reset(struct scsi_cmnd *SC) /* Linux obtains io_request_lock before calling this function */ /* */ /****************************************************************************/ -static int ips_queue(struct scsi_cmnd *SC, void (*done) (struct scsi_cmnd *)) +static int +ips_queue(Scsi_Cmnd * SC, void (*done) (Scsi_Cmnd *)) { ips_ha_t *ha; ips_passthru_t *pt; @@ -1328,7 +1336,7 @@ ips_slave_configure(struct scsi_device * SDptr) /* */ /****************************************************************************/ static irqreturn_t -do_ipsintr(int irq, void *dev_id) +do_ipsintr(int irq, void *dev_id, struct pt_regs * regs) { ips_ha_t *ha; unsigned long cpu_flags; @@ -1594,7 +1602,8 @@ ips_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, /* Determine if the specified SCSI command is really a passthru command */ /* */ /****************************************************************************/ -static int ips_is_passthru(struct scsi_cmnd *SC) +static int +ips_is_passthru(Scsi_Cmnd * SC) { unsigned long flags; @@ -1676,7 +1685,7 @@ ips_alloc_passthru_buffer(ips_ha_t * ha, int length) /* */ /****************************************************************************/ static int -ips_make_passthru(ips_ha_t *ha, struct scsi_cmnd *SC, ips_scb_t *scb, int intr) +ips_make_passthru(ips_ha_t * ha, Scsi_Cmnd * SC, ips_scb_t * scb, int intr) { ips_passthru_t *pt; int length = 0; @@ -2725,9 +2734,9 @@ static void ips_next(ips_ha_t * ha, int intr) { ips_scb_t *scb; - struct scsi_cmnd *SC; - struct scsi_cmnd *p; - struct scsi_cmnd *q; + Scsi_Cmnd *SC; + Scsi_Cmnd *p; + Scsi_Cmnd *q; ips_copp_wait_item_t *item; int ret; unsigned long cpu_flags = 0; @@ -2838,7 +2847,7 @@ ips_next(ips_ha_t * ha, int intr) dcdb_active[scmd_channel(p) - 1] & (1 << scmd_id(p)))) { ips_freescb(ha, scb); - p = (struct scsi_cmnd *) p->host_scribble; + p = (Scsi_Cmnd *) p->host_scribble; continue; } @@ -2953,7 +2962,7 @@ ips_next(ips_ha_t * ha, int intr) break; } /* end case */ - p = (struct scsi_cmnd *) p->host_scribble; + p = (Scsi_Cmnd *) p->host_scribble; } /* end while */ @@ -3081,7 +3090,8 @@ ips_removeq_scb(ips_scb_queue_t * queue, ips_scb_t * item) /* ASSUMED to be called from within the HA lock */ /* */ /****************************************************************************/ -static void ips_putq_wait_tail(ips_wait_queue_t *queue, struct scsi_cmnd *item) +static void +ips_putq_wait_tail(ips_wait_queue_t * queue, Scsi_Cmnd * item) { METHOD_TRACE("ips_putq_wait_tail", 1); @@ -3112,9 +3122,10 @@ static void ips_putq_wait_tail(ips_wait_queue_t *queue, struct scsi_cmnd *item) /* ASSUMED to be called from within the HA lock */ /* */ /****************************************************************************/ -static struct scsi_cmnd *ips_removeq_wait_head(ips_wait_queue_t *queue) +static Scsi_Cmnd * +ips_removeq_wait_head(ips_wait_queue_t * queue) { - struct scsi_cmnd *item; + Scsi_Cmnd *item; METHOD_TRACE("ips_removeq_wait_head", 1); @@ -3124,7 +3135,7 @@ static struct scsi_cmnd *ips_removeq_wait_head(ips_wait_queue_t *queue) return (NULL); } - queue->head = (struct scsi_cmnd *) item->host_scribble; + queue->head = (Scsi_Cmnd *) item->host_scribble; item->host_scribble = NULL; if (queue->tail == item) @@ -3146,10 +3157,10 @@ static struct scsi_cmnd *ips_removeq_wait_head(ips_wait_queue_t *queue) /* ASSUMED to be called from within the HA lock */ /* */ /****************************************************************************/ -static struct scsi_cmnd *ips_removeq_wait(ips_wait_queue_t *queue, - struct scsi_cmnd *item) +static Scsi_Cmnd * +ips_removeq_wait(ips_wait_queue_t * queue, Scsi_Cmnd * item) { - struct scsi_cmnd *p; + Scsi_Cmnd *p; METHOD_TRACE("ips_removeq_wait", 1); @@ -3162,8 +3173,8 @@ static struct scsi_cmnd *ips_removeq_wait(ips_wait_queue_t *queue, p = queue->head; - while ((p) && (item != (struct scsi_cmnd *) p->host_scribble)) - p = (struct scsi_cmnd *) p->host_scribble; + while ((p) && (item != (Scsi_Cmnd *) p->host_scribble)) + p = (Scsi_Cmnd *) p->host_scribble; if (p) { /* found a match */ @@ -3648,10 +3659,11 @@ ips_send_wait(ips_ha_t * ha, ips_scb_t * scb, int timeout, int intr) /* Routine Name: ips_scmd_buf_write */ /* */ /* Routine Description: */ -/* Write data to struct scsi_cmnd request_buffer at proper offsets */ +/* Write data to Scsi_Cmnd request_buffer at proper offsets */ /****************************************************************************/ static void -ips_scmd_buf_write(struct scsi_cmnd *scmd, void *data, unsigned int count) +ips_scmd_buf_write(Scsi_Cmnd * scmd, void *data, unsigned + int count) { if (scmd->use_sg) { int i; @@ -3686,10 +3698,11 @@ ips_scmd_buf_write(struct scsi_cmnd *scmd, void *data, unsigned int count) /* Routine Name: ips_scmd_buf_read */ /* */ /* Routine Description: */ -/* Copy data from a struct scsi_cmnd to a new, linear buffer */ +/* Copy data from a Scsi_Cmnd to a new, linear buffer */ /****************************************************************************/ static void -ips_scmd_buf_read(struct scsi_cmnd *scmd, void *data, unsigned int count) +ips_scmd_buf_read(Scsi_Cmnd * scmd, void *data, unsigned + int count) { if (scmd->use_sg) { int i; @@ -7065,7 +7078,7 @@ ips_remove_device(struct pci_dev *pci_dev) static int __init ips_module_init(void) { - if (pci_register_driver(&ips_pci_driver) < 0) + if (pci_module_init(&ips_pci_driver) < 0) return -ENODEV; ips_driver_template.module = THIS_MODULE; ips_order_controllers(); diff --git a/trunk/drivers/scsi/ips.h b/trunk/drivers/scsi/ips.h index 34680f3dd452..f46c382e5599 100644 --- a/trunk/drivers/scsi/ips.h +++ b/trunk/drivers/scsi/ips.h @@ -6,7 +6,7 @@ /* David Jeffery, Adaptec, Inc. */ /* */ /* Copyright (C) 1999 IBM Corporation */ -/* Copyright (C) 2003 Adaptec, Inc. */ +/* Copyright (C) 2003 Adaptec, Inc. */ /* */ /* 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 */ @@ -1033,14 +1033,14 @@ typedef struct ips_scb_queue { * Wait queue_format */ typedef struct ips_wait_queue { - struct scsi_cmnd *head; - struct scsi_cmnd *tail; - int count; + Scsi_Cmnd *head; + Scsi_Cmnd *tail; + int count; } ips_wait_queue_t; typedef struct ips_copp_wait_item { - struct scsi_cmnd *scsi_cmd; - struct ips_copp_wait_item *next; + Scsi_Cmnd *scsi_cmd; + struct ips_copp_wait_item *next; } ips_copp_wait_item_t; typedef struct ips_copp_queue { @@ -1149,7 +1149,7 @@ typedef struct ips_scb { uint32_t flags; uint32_t op_code; IPS_SG_LIST sg_list; - struct scsi_cmnd *scsi_cmd; + Scsi_Cmnd *scsi_cmd; struct ips_scb *q_next; ips_scb_callback callback; uint32_t sg_busaddr; @@ -1175,7 +1175,7 @@ typedef struct ips_scb_pt { uint32_t flags; uint32_t op_code; IPS_SG_LIST *sg_list; - struct scsi_cmnd *scsi_cmd; + Scsi_Cmnd *scsi_cmd; struct ips_scb *q_next; ips_scb_callback callback; } ips_scb_pt_t; diff --git a/trunk/drivers/scsi/iscsi_tcp.c b/trunk/drivers/scsi/iscsi_tcp.c index d0b139cccbbc..0a9dbc59663f 100644 --- a/trunk/drivers/scsi/iscsi_tcp.c +++ b/trunk/drivers/scsi/iscsi_tcp.c @@ -415,8 +415,8 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) iscsi_solicit_data_init(conn, ctask, r2t); tcp_ctask->exp_r2tsn = r2tsn + 1; - __kfifo_put(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*)); tcp_ctask->xmstate |= XMSTATE_SOL_HDR; + __kfifo_put(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*)); list_move_tail(&ctask->running, &conn->xmitqueue); scsi_queue_work(session->host, &conn->xmitwork); @@ -1627,12 +1627,9 @@ static int iscsi_send_sol_pdu(struct iscsi_conn *conn, if (tcp_ctask->xmstate & XMSTATE_SOL_HDR) { tcp_ctask->xmstate &= ~XMSTATE_SOL_HDR; tcp_ctask->xmstate |= XMSTATE_SOL_DATA; - if (!tcp_ctask->r2t) { - spin_lock_bh(&session->lock); + if (!tcp_ctask->r2t) __kfifo_get(tcp_ctask->r2tqueue, (void*)&tcp_ctask->r2t, sizeof(void*)); - spin_unlock_bh(&session->lock); - } send_hdr: r2t = tcp_ctask->r2t; dtask = &r2t->dtask; @@ -1819,14 +1816,21 @@ iscsi_tcp_conn_destroy(struct iscsi_cls_conn *cls_conn) { struct iscsi_conn *conn = cls_conn->dd_data; struct iscsi_tcp_conn *tcp_conn = conn->dd_data; + int digest = 0; + + if (conn->hdrdgst_en || conn->datadgst_en) + digest = 1; iscsi_tcp_release_conn(conn); iscsi_conn_teardown(cls_conn); - if (tcp_conn->tx_hash.tfm) - crypto_free_hash(tcp_conn->tx_hash.tfm); - if (tcp_conn->rx_hash.tfm) - crypto_free_hash(tcp_conn->rx_hash.tfm); + /* now free tcp_conn */ + if (digest) { + if (tcp_conn->tx_hash.tfm) + crypto_free_hash(tcp_conn->tx_hash.tfm); + if (tcp_conn->rx_hash.tfm) + crypto_free_hash(tcp_conn->rx_hash.tfm); + } kfree(tcp_conn); } diff --git a/trunk/drivers/scsi/libiscsi.c b/trunk/drivers/scsi/libiscsi.c index 5d8862189485..c542d0e95e68 100644 --- a/trunk/drivers/scsi/libiscsi.c +++ b/trunk/drivers/scsi/libiscsi.c @@ -481,8 +481,8 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, break; case ISCSI_OP_ASYNC_EVENT: conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; - if (iscsi_recv_pdu(conn->cls_conn, hdr, data, datalen)) - rc = ISCSI_ERR_CONN_FAILED; + /* we need sth like iscsi_async_event_rsp() */ + rc = ISCSI_ERR_BAD_OPCODE; break; default: rc = ISCSI_ERR_BAD_OPCODE; @@ -578,27 +578,6 @@ void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err) } EXPORT_SYMBOL_GPL(iscsi_conn_failure); -static int iscsi_xmit_imm_task(struct iscsi_conn *conn) -{ - struct iscsi_hdr *hdr = conn->mtask->hdr; - int rc, was_logout = 0; - - if ((hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGOUT) { - conn->session->state = ISCSI_STATE_IN_RECOVERY; - iscsi_block_session(session_to_cls(conn->session)); - was_logout = 1; - } - rc = conn->session->tt->xmit_mgmt_task(conn, conn->mtask); - if (rc) - return rc; - - if (was_logout) { - set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); - return -ENODATA; - } - return 0; -} - /** * iscsi_data_xmit - xmit any command into the scheduled connection * @conn: iscsi connection @@ -644,7 +623,7 @@ static int iscsi_data_xmit(struct iscsi_conn *conn) conn->ctask = NULL; } if (conn->mtask) { - rc = iscsi_xmit_imm_task(conn); + rc = tt->xmit_mgmt_task(conn, conn->mtask); if (rc) goto again; /* done with this in-progress mtask */ @@ -659,7 +638,7 @@ static int iscsi_data_xmit(struct iscsi_conn *conn) list_add_tail(&conn->mtask->running, &conn->mgmt_run_list); spin_unlock_bh(&conn->session->lock); - rc = iscsi_xmit_imm_task(conn); + rc = tt->xmit_mgmt_task(conn, conn->mtask); if (rc) goto again; } @@ -682,6 +661,8 @@ static int iscsi_data_xmit(struct iscsi_conn *conn) spin_unlock_bh(&conn->session->lock); rc = tt->xmit_cmd_task(conn, conn->ctask); + if (rc) + goto again; spin_lock_bh(&conn->session->lock); __iscsi_put_ctask(conn->ctask); @@ -797,10 +778,6 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) } conn = session->leadconn; - if (!conn) { - reason = FAILURE_SESSION_FREED; - goto fault; - } if (!__kfifo_get(session->cmdpool.queue, (void*)&ctask, sizeof(void*))) { @@ -975,13 +952,13 @@ int iscsi_eh_host_reset(struct scsi_cmnd *sc) if (session->state == ISCSI_STATE_TERMINATE) { failed: debug_scsi("failing host reset: session terminated " - "[CID %d age %d]\n", conn->id, session->age); + "[CID %d age %d]", conn->id, session->age); spin_unlock_bh(&session->lock); return FAILED; } if (sc->SCp.phase == session->age) { - debug_scsi("failing connection CID %d due to SCSI host reset\n", + debug_scsi("failing connection CID %d due to SCSI host reset", conn->id); fail_session = 1; } @@ -1054,8 +1031,7 @@ static int iscsi_exec_abort_task(struct scsi_cmnd *sc, NULL, 0); if (rc) { iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); - debug_scsi("abort sent failure [itt 0x%x] %d\n", ctask->itt, - rc); + debug_scsi("abort sent failure [itt 0x%x] %d", ctask->itt, rc); return rc; } @@ -1072,7 +1048,7 @@ static int iscsi_exec_abort_task(struct scsi_cmnd *sc, conn->tmabort_timer.function = iscsi_tmabort_timedout; conn->tmabort_timer.data = (unsigned long)ctask; add_timer(&conn->tmabort_timer); - debug_scsi("abort set timeout [itt 0x%x]\n", ctask->itt); + debug_scsi("abort set timeout [itt 0x%x]", ctask->itt); } spin_unlock_bh(&session->lock); mutex_unlock(&conn->xmitmutex); @@ -1401,6 +1377,7 @@ iscsi_session_setup(struct iscsi_transport *iscsit, } spin_lock_init(&session->lock); + INIT_LIST_HEAD(&session->connections); /* initialize immediate command pool */ if (iscsi_pool_init(&session->mgmtpool, session->mgmtpool_max, @@ -1603,11 +1580,16 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn) kfree(conn->persistent_address); __kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask, sizeof(void*)); - if (session->leadconn == conn) { + list_del(&conn->item); + if (list_empty(&session->connections)) session->leadconn = NULL; + if (session->leadconn && session->leadconn == conn) + session->leadconn = container_of(session->connections.next, + struct iscsi_conn, item); + + if (session->leadconn == NULL) /* no connections exits.. reset sequencing */ session->cmdsn = session->max_cmdsn = session->exp_cmdsn = 1; - } spin_unlock_bh(&session->lock); kfifo_free(conn->immqueue); @@ -1795,12 +1777,32 @@ int iscsi_conn_bind(struct iscsi_cls_session *cls_session, struct iscsi_cls_conn *cls_conn, int is_leading) { struct iscsi_session *session = class_to_transport_session(cls_session); - struct iscsi_conn *conn = cls_conn->dd_data; + struct iscsi_conn *tmp = ERR_PTR(-EEXIST), *conn = cls_conn->dd_data; + /* lookup for existing connection */ spin_lock_bh(&session->lock); + list_for_each_entry(tmp, &session->connections, item) { + if (tmp == conn) { + if (conn->c_stage != ISCSI_CONN_STOPPED || + conn->stop_stage == STOP_CONN_TERM) { + printk(KERN_ERR "iscsi: can't bind " + "non-stopped connection (%d:%d)\n", + conn->c_stage, conn->stop_stage); + spin_unlock_bh(&session->lock); + return -EIO; + } + break; + } + } + if (tmp != conn) { + /* bind new iSCSI connection to session */ + conn->session = session; + list_add(&conn->item, &session->connections); + } + spin_unlock_bh(&session->lock); + if (is_leading) session->leadconn = conn; - spin_unlock_bh(&session->lock); /* * Unblock xmitworker(), Login Phase will pass through. diff --git a/trunk/drivers/scsi/libsas/sas_expander.c b/trunk/drivers/scsi/libsas/sas_expander.c index e34a93435497..30b8014bcc7a 100644 --- a/trunk/drivers/scsi/libsas/sas_expander.c +++ b/trunk/drivers/scsi/libsas/sas_expander.c @@ -71,65 +71,55 @@ static void smp_task_done(struct sas_task *task) static int smp_execute_task(struct domain_device *dev, void *req, int req_size, void *resp, int resp_size) { - int res, retry; - struct sas_task *task = NULL; + int res; + struct sas_task *task = sas_alloc_task(GFP_KERNEL); struct sas_internal *i = to_sas_internal(dev->port->ha->core.shost->transportt); - for (retry = 0; retry < 3; retry++) { - task = sas_alloc_task(GFP_KERNEL); - if (!task) - return -ENOMEM; + if (!task) + return -ENOMEM; - task->dev = dev; - task->task_proto = dev->tproto; - sg_init_one(&task->smp_task.smp_req, req, req_size); - sg_init_one(&task->smp_task.smp_resp, resp, resp_size); + task->dev = dev; + task->task_proto = dev->tproto; + sg_init_one(&task->smp_task.smp_req, req, req_size); + sg_init_one(&task->smp_task.smp_resp, resp, resp_size); - task->task_done = smp_task_done; + task->task_done = smp_task_done; - task->timer.data = (unsigned long) task; - task->timer.function = smp_task_timedout; - task->timer.expires = jiffies + SMP_TIMEOUT*HZ; - add_timer(&task->timer); + task->timer.data = (unsigned long) task; + task->timer.function = smp_task_timedout; + task->timer.expires = jiffies + SMP_TIMEOUT*HZ; + add_timer(&task->timer); - res = i->dft->lldd_execute_task(task, 1, GFP_KERNEL); + res = i->dft->lldd_execute_task(task, 1, GFP_KERNEL); - if (res) { - del_timer(&task->timer); - SAS_DPRINTK("executing SMP task failed:%d\n", res); - goto ex_err; - } + if (res) { + del_timer(&task->timer); + SAS_DPRINTK("executing SMP task failed:%d\n", res); + goto ex_err; + } - wait_for_completion(&task->completion); - res = -ETASK; - if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) { - SAS_DPRINTK("smp task timed out or aborted\n"); - i->dft->lldd_abort_task(task); - if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) { - SAS_DPRINTK("SMP task aborted and not done\n"); - goto ex_err; - } - } - if (task->task_status.resp == SAS_TASK_COMPLETE && - task->task_status.stat == SAM_GOOD) { - res = 0; - break; - } else { - SAS_DPRINTK("%s: task to dev %016llx response: 0x%x " - "status 0x%x\n", __FUNCTION__, - SAS_ADDR(dev->sas_addr), - task->task_status.resp, - task->task_status.stat); - sas_free_task(task); - task = NULL; + wait_for_completion(&task->completion); + res = -ETASK; + if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) { + SAS_DPRINTK("smp task timed out or aborted\n"); + i->dft->lldd_abort_task(task); + if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) { + SAS_DPRINTK("SMP task aborted and not done\n"); + goto ex_err; } } + if (task->task_status.resp == SAS_TASK_COMPLETE && + task->task_status.stat == SAM_GOOD) + res = 0; + else + SAS_DPRINTK("%s: task to dev %016llx response: 0x%x " + "status 0x%x\n", __FUNCTION__, + SAS_ADDR(dev->sas_addr), + task->task_status.resp, + task->task_status.stat); ex_err: - BUG_ON(retry == 3 && task != NULL); - if (task != NULL) { - sas_free_task(task); - } + sas_free_task(task); return res; } diff --git a/trunk/drivers/scsi/lpfc/lpfc_attr.c b/trunk/drivers/scsi/lpfc/lpfc_attr.c index 2a4e02e7a392..9496e87c135e 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_attr.c +++ b/trunk/drivers/scsi/lpfc/lpfc_attr.c @@ -594,8 +594,7 @@ lpfc_soft_wwpn_show(struct class_device *cdev, char *buf) { struct Scsi_Host *host = class_to_shost(cdev); struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; - return snprintf(buf, PAGE_SIZE, "0x%llx\n", - (unsigned long long)phba->cfg_soft_wwpn); + return snprintf(buf, PAGE_SIZE, "0x%llx\n", phba->cfg_soft_wwpn); } diff --git a/trunk/drivers/scsi/lpfc/lpfc_crtn.h b/trunk/drivers/scsi/lpfc/lpfc_crtn.h index 1251788ce2a3..3d684496acde 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_crtn.h +++ b/trunk/drivers/scsi/lpfc/lpfc_crtn.h @@ -120,7 +120,7 @@ int lpfc_sli_queue_setup(struct lpfc_hba *); void lpfc_handle_eratt(struct lpfc_hba *); void lpfc_handle_latt(struct lpfc_hba *); -irqreturn_t lpfc_intr_handler(int, void *); +irqreturn_t lpfc_intr_handler(int, void *, struct pt_regs *); void lpfc_read_rev(struct lpfc_hba *, LPFC_MBOXQ_t *); void lpfc_config_ring(struct lpfc_hba *, int, LPFC_MBOXQ_t *); diff --git a/trunk/drivers/scsi/lpfc/lpfc_ct.c b/trunk/drivers/scsi/lpfc/lpfc_ct.c index 3add7c237859..1b53afb1cb57 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_ct.c +++ b/trunk/drivers/scsi/lpfc/lpfc_ct.c @@ -188,8 +188,7 @@ lpfc_alloc_ct_rsp(struct lpfc_hba * phba, int cmdcode, struct ulp_bde64 * bpl, if (!mp->virt) { kfree(mp); - if (mlist) - lpfc_free_ct_rsp(phba, mlist); + lpfc_free_ct_rsp(phba, mlist); return NULL; } diff --git a/trunk/drivers/scsi/lpfc/lpfc_hbadisc.c b/trunk/drivers/scsi/lpfc/lpfc_hbadisc.c index 19c79a0549a7..d586c3d3b0d0 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/trunk/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -305,7 +305,7 @@ lpfc_do_work(void *p) { struct lpfc_hba *phba = p; int rc; - DECLARE_WAIT_QUEUE_HEAD_ONSTACK(work_waitq); + DECLARE_WAIT_QUEUE_HEAD(work_waitq); set_user_nice(current, -20); phba->work_wait = &work_waitq; diff --git a/trunk/drivers/scsi/lpfc/lpfc_init.c b/trunk/drivers/scsi/lpfc/lpfc_init.c index a5723ad0a099..4cdf3464267f 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_init.c +++ b/trunk/drivers/scsi/lpfc/lpfc_init.c @@ -389,8 +389,7 @@ lpfc_config_port_post(struct lpfc_hba * phba) lpfc_init_link(phba, pmb, phba->cfg_topology, phba->cfg_link_speed); pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; - rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT); - if (rc != MBX_SUCCESS) { + if (lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT) != MBX_SUCCESS) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, @@ -407,8 +406,7 @@ lpfc_config_port_post(struct lpfc_hba * phba) readl(phba->HAregaddr); /* flush */ phba->hba_state = LPFC_HBA_ERROR; - if (rc != MBX_BUSY) - mempool_free(pmb, phba->mbox_mem_pool); + mempool_free(pmb, phba->mbox_mem_pool); return -EIO; } /* MBOX buffer will be freed in mbox compl */ diff --git a/trunk/drivers/scsi/lpfc/lpfc_sli.c b/trunk/drivers/scsi/lpfc/lpfc_sli.c index 582f5ea4e84e..70f4d5a1348e 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_sli.c +++ b/trunk/drivers/scsi/lpfc/lpfc_sli.c @@ -2983,7 +2983,7 @@ lpfc_sli_issue_iocb_wait(struct lpfc_hba * phba, struct lpfc_iocbq * prspiocbq, uint32_t timeout) { - DECLARE_WAIT_QUEUE_HEAD_ONSTACK(done_q); + DECLARE_WAIT_QUEUE_HEAD(done_q); long timeleft, timeout_req = 0; int retval = IOCB_SUCCESS; uint32_t creg_val; @@ -3061,7 +3061,7 @@ int lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq, uint32_t timeout) { - DECLARE_WAIT_QUEUE_HEAD_ONSTACK(done_q); + DECLARE_WAIT_QUEUE_HEAD(done_q); DECLARE_WAITQUEUE(wq_entry, current); uint32_t timeleft = 0; int retval; @@ -3119,7 +3119,7 @@ lpfc_sli_flush_mbox_queue(struct lpfc_hba * phba) } irqreturn_t -lpfc_intr_handler(int irq, void *dev_id) +lpfc_intr_handler(int irq, void *dev_id, struct pt_regs * regs) { struct lpfc_hba *phba; uint32_t ha_copy; diff --git a/trunk/drivers/scsi/mac53c94.c b/trunk/drivers/scsi/mac53c94.c index 753d88306cd1..6422de72bf43 100644 --- a/trunk/drivers/scsi/mac53c94.c +++ b/trunk/drivers/scsi/mac53c94.c @@ -60,8 +60,8 @@ struct fsc_state { static void mac53c94_init(struct fsc_state *); static void mac53c94_start(struct fsc_state *); -static void mac53c94_interrupt(int, void *); -static irqreturn_t do_mac53c94_interrupt(int, void *); +static void mac53c94_interrupt(int, void *, struct pt_regs *); +static irqreturn_t do_mac53c94_interrupt(int, void *, struct pt_regs *); static void cmd_done(struct fsc_state *, int result); static void set_dma_cmds(struct fsc_state *, struct scsi_cmnd *); @@ -177,18 +177,18 @@ static void mac53c94_start(struct fsc_state *state) set_dma_cmds(state, cmd); } -static irqreturn_t do_mac53c94_interrupt(int irq, void *dev_id) +static irqreturn_t do_mac53c94_interrupt(int irq, void *dev_id, struct pt_regs *ptregs) { unsigned long flags; struct Scsi_Host *dev = ((struct fsc_state *) dev_id)->current_req->device->host; spin_lock_irqsave(dev->host_lock, flags); - mac53c94_interrupt(irq, dev_id); + mac53c94_interrupt(irq, dev_id, ptregs); spin_unlock_irqrestore(dev->host_lock, flags); return IRQ_HANDLED; } -static void mac53c94_interrupt(int irq, void *dev_id) +static void mac53c94_interrupt(int irq, void *dev_id, struct pt_regs *ptregs) { struct fsc_state *state = (struct fsc_state *) dev_id; struct mac53c94_regs __iomem *regs = state->regs; diff --git a/trunk/drivers/scsi/mac_esp.c b/trunk/drivers/scsi/mac_esp.c index 3586fac9be9a..118206d68c6c 100644 --- a/trunk/drivers/scsi/mac_esp.c +++ b/trunk/drivers/scsi/mac_esp.c @@ -44,7 +44,7 @@ /* #define DEBUG_MAC_ESP */ extern void esp_handle(struct NCR_ESP *esp); -extern void mac_esp_intr(int irq, void *dev_id); +extern void mac_esp_intr(int irq, void *dev_id, struct pt_regs *pregs); static int dma_bytes_sent(struct NCR_ESP * esp, int fifo_count); static int dma_can_transfer(struct NCR_ESP * esp, Scsi_Cmnd *sp); @@ -88,7 +88,7 @@ static int setup_hostid = -1; * set up properly! */ -void mac_esp_intr(int irq, void *dev_id) +void mac_esp_intr(int irq, void *dev_id, struct pt_regs *pregs) { struct NCR_ESP *esp = (struct NCR_ESP *) dev_id; int irq_p = 0; @@ -122,24 +122,24 @@ void mac_esp_intr(int irq, void *dev_id) * acknowledge on the various machines */ -void scsi_esp_polled(int irq, void *dev_id) +void scsi_esp_polled(int irq, void *dev_id, struct pt_regs *pregs) { if (esp_initialized == 0) return; - mac_esp_intr(irq, dev_id); + mac_esp_intr(irq, dev_id, pregs); } -void fake_intr(int irq, void *dev_id) +void fake_intr(int irq, void *dev_id, struct pt_regs *pregs) { #ifdef DEBUG_MAC_ESP printk("mac_esp: got irq\n"); #endif - mac_esp_intr(irq, dev_id); + mac_esp_intr(irq, dev_id, pregs); } -irqreturn_t fake_drq(int irq, void *dev_id) +irqreturn_t fake_drq(int irq, void *dev_id, struct pt_regs *pregs) { printk("mac_esp: got drq\n"); return IRQ_HANDLED; diff --git a/trunk/drivers/scsi/megaraid.c b/trunk/drivers/scsi/megaraid.c index 86099fde1b2a..b87bef69ba0f 100644 --- a/trunk/drivers/scsi/megaraid.c +++ b/trunk/drivers/scsi/megaraid.c @@ -1256,13 +1256,14 @@ issue_scb_block(adapter_t *adapter, u_char *raw_mbox) * megaraid_isr_iomapped() * @irq - irq * @devp - pointer to our soft state + * @regs - unused * * Interrupt service routine for io-mapped controllers. * Find out if our device is interrupting. If yes, acknowledge the interrupt * and service the completed commands. */ static irqreturn_t -megaraid_isr_iomapped(int irq, void *devp) +megaraid_isr_iomapped(int irq, void *devp, struct pt_regs *regs) { adapter_t *adapter = devp; unsigned long flags; @@ -1332,13 +1333,14 @@ megaraid_isr_iomapped(int irq, void *devp) * megaraid_isr_memmapped() * @irq - irq * @devp - pointer to our soft state + * @regs - unused * * Interrupt service routine for memory-mapped controllers. * Find out if our device is interrupting. If yes, acknowledge the interrupt * and service the completed commands. */ static irqreturn_t -megaraid_isr_memmapped(int irq, void *devp) +megaraid_isr_memmapped(int irq, void *devp, struct pt_regs *regs) { adapter_t *adapter = devp; unsigned long flags; diff --git a/trunk/drivers/scsi/megaraid.h b/trunk/drivers/scsi/megaraid.h index 66529f11d23c..4b75fe619d9c 100644 --- a/trunk/drivers/scsi/megaraid.h +++ b/trunk/drivers/scsi/megaraid.h @@ -991,8 +991,8 @@ static scb_t * mega_build_cmd(adapter_t *, Scsi_Cmnd *, int *); static void __mega_runpendq(adapter_t *); static int issue_scb_block(adapter_t *, u_char *); -static irqreturn_t megaraid_isr_memmapped(int, void *); -static irqreturn_t megaraid_isr_iomapped(int, void *); +static irqreturn_t megaraid_isr_memmapped(int, void *, struct pt_regs *); +static irqreturn_t megaraid_isr_iomapped(int, void *, struct pt_regs *); static void mega_free_scb(adapter_t *, scb_t *); diff --git a/trunk/drivers/scsi/megaraid/mega_common.h b/trunk/drivers/scsi/megaraid/mega_common.h index b50e27e66024..8cd0bd1d0f7c 100644 --- a/trunk/drivers/scsi/megaraid/mega_common.h +++ b/trunk/drivers/scsi/megaraid/mega_common.h @@ -175,7 +175,7 @@ typedef struct { uint8_t max_lun; uint32_t unique_id; - int irq; + uint8_t irq; uint8_t ito; caddr_t ibuf; dma_addr_t ibuf_dma_h; diff --git a/trunk/drivers/scsi/megaraid/megaraid_mbox.c b/trunk/drivers/scsi/megaraid/megaraid_mbox.c index 7bac86dda88f..266b3910846b 100644 --- a/trunk/drivers/scsi/megaraid/megaraid_mbox.c +++ b/trunk/drivers/scsi/megaraid/megaraid_mbox.c @@ -120,7 +120,7 @@ static void megaraid_mbox_prepare_pthru(adapter_t *, scb_t *, static void megaraid_mbox_prepare_epthru(adapter_t *, scb_t *, struct scsi_cmnd *); -static irqreturn_t megaraid_isr(int, void *); +static irqreturn_t megaraid_isr(int, void *, struct pt_regs *); static void megaraid_mbox_dpc(unsigned long); @@ -884,7 +884,7 @@ megaraid_init_mbox(adapter_t *adapter) if (((magic64 == HBA_SIGNATURE_64_BIT) && ((adapter->pdev->subsystem_device != - PCI_SUBSYS_ID_MEGARAID_SATA_150_6) && + PCI_SUBSYS_ID_MEGARAID_SATA_150_6) || (adapter->pdev->subsystem_device != PCI_SUBSYS_ID_MEGARAID_SATA_150_4))) || (adapter->pdev->vendor == PCI_VENDOR_ID_LSI_LOGIC && @@ -2231,7 +2231,7 @@ megaraid_ack_sequence(adapter_t *adapter) * Interrupt service routine for memory-mapped mailbox controllers. */ static irqreturn_t -megaraid_isr(int irq, void *devp) +megaraid_isr(int irq, void *devp, struct pt_regs *regs) { adapter_t *adapter = devp; int handled; diff --git a/trunk/drivers/scsi/megaraid/megaraid_sas.c b/trunk/drivers/scsi/megaraid/megaraid_sas.c index 7e4262f2af96..4cab5b534b25 100644 --- a/trunk/drivers/scsi/megaraid/megaraid_sas.c +++ b/trunk/drivers/scsi/megaraid/megaraid_sas.c @@ -10,7 +10,7 @@ * 2 of the License, or (at your option) any later version. * * FILE : megaraid_sas.c - * Version : v00.00.03.05 + * Version : v00.00.03.01 * * Authors: * Sreenivas Bagalkote @@ -71,8 +71,6 @@ static struct megasas_mgmt_info megasas_mgmt_info; static struct fasync_struct *megasas_async_queue; static DEFINE_MUTEX(megasas_async_queue_mutex); -static u32 megasas_dbg_lvl; - /** * megasas_get_cmd - Get a command from the free pool * @instance: Adapter soft state @@ -136,19 +134,6 @@ megasas_enable_intr_xscale(struct megasas_register_set __iomem * regs) readl(®s->outbound_intr_mask); } -/** - * megasas_disable_intr_xscale -Disables interrupt - * @regs: MFI register set - */ -static inline void -megasas_disable_intr_xscale(struct megasas_register_set __iomem * regs) -{ - u32 mask = 0x1f; - writel(mask, ®s->outbound_intr_mask); - /* Dummy readl to force pci flush */ - readl(®s->outbound_intr_mask); -} - /** * megasas_read_fw_status_reg_xscale - returns the current FW status value * @regs: MFI register set @@ -200,7 +185,6 @@ static struct megasas_instance_template megasas_instance_template_xscale = { .fire_cmd = megasas_fire_cmd_xscale, .enable_intr = megasas_enable_intr_xscale, - .disable_intr = megasas_disable_intr_xscale, .clear_intr = megasas_clear_intr_xscale, .read_fw_status_reg = megasas_read_fw_status_reg_xscale, }; @@ -230,19 +214,6 @@ megasas_enable_intr_ppc(struct megasas_register_set __iomem * regs) readl(®s->outbound_intr_mask); } -/** - * megasas_disable_intr_ppc - Disable interrupt - * @regs: MFI register set - */ -static inline void -megasas_disable_intr_ppc(struct megasas_register_set __iomem * regs) -{ - u32 mask = 0xFFFFFFFF; - writel(mask, ®s->outbound_intr_mask); - /* Dummy readl to force pci flush */ - readl(®s->outbound_intr_mask); -} - /** * megasas_read_fw_status_reg_ppc - returns the current FW status value * @regs: MFI register set @@ -294,7 +265,6 @@ static struct megasas_instance_template megasas_instance_template_ppc = { .fire_cmd = megasas_fire_cmd_ppc, .enable_intr = megasas_enable_intr_ppc, - .disable_intr = megasas_disable_intr_ppc, .clear_intr = megasas_clear_intr_ppc, .read_fw_status_reg = megasas_read_fw_status_reg_ppc, }; @@ -304,6 +274,25 @@ static struct megasas_instance_template megasas_instance_template_ppc = { * specific to ppc (deviceid : 0x60) controllers */ +/** + * megasas_disable_intr - Disables interrupts + * @regs: MFI register set + */ +static inline void +megasas_disable_intr(struct megasas_instance *instance) +{ + u32 mask = 0x1f; + struct megasas_register_set __iomem *regs = instance->reg_set; + + if(instance->pdev->device == PCI_DEVICE_ID_LSI_SAS1078R) + mask = 0xffffffff; + + writel(mask, ®s->outbound_intr_mask); + + /* Dummy readl to force pci flush */ + readl(®s->outbound_intr_mask); +} + /** * megasas_issue_polled - Issues a polling command * @instance: Adapter soft state @@ -347,7 +336,6 @@ megasas_issue_polled(struct megasas_instance *instance, struct megasas_cmd *cmd) * @cmd: Command to be issued * * This function waits on an event for the command to be returned from ISR. - * Max wait time is MEGASAS_INTERNAL_CMD_WAIT_TIME secs * Used to issue ioctl commands. */ static int @@ -358,8 +346,7 @@ megasas_issue_blocked_cmd(struct megasas_instance *instance, instance->instancet->fire_cmd(cmd->frame_phys_addr ,0,instance->reg_set); - wait_event_timeout(instance->int_cmd_wait_q, (cmd->cmd_status != ENODATA), - MEGASAS_INTERNAL_CMD_WAIT_TIME*HZ); + wait_event(instance->int_cmd_wait_q, (cmd->cmd_status != ENODATA)); return 0; } @@ -371,8 +358,7 @@ megasas_issue_blocked_cmd(struct megasas_instance *instance, * * MFI firmware can abort previously issued AEN comamnd (automatic event * notification). The megasas_issue_blocked_abort_cmd() issues such abort - * cmd and waits for return status. - * Max wait time is MEGASAS_INTERNAL_CMD_WAIT_TIME secs + * cmd and blocks till it is completed. */ static int megasas_issue_blocked_abort_cmd(struct megasas_instance *instance, @@ -406,8 +392,7 @@ megasas_issue_blocked_abort_cmd(struct megasas_instance *instance, /* * Wait for this cmd to complete */ - wait_event_timeout(instance->abort_cmd_wait_q, (cmd->cmd_status != 0xFF), - MEGASAS_INTERNAL_CMD_WAIT_TIME*HZ); + wait_event(instance->abort_cmd_wait_q, (cmd->cmd_status != 0xFF)); megasas_return_cmd(instance, cmd); return 0; @@ -510,46 +495,6 @@ megasas_make_sgl64(struct megasas_instance *instance, struct scsi_cmnd *scp, return sge_count; } - /** - * megasas_get_frame_count - Computes the number of frames - * @sge_count : number of sg elements - * - * Returns the number of frames required for numnber of sge's (sge_count) - */ - -u32 megasas_get_frame_count(u8 sge_count) -{ - int num_cnt; - int sge_bytes; - u32 sge_sz; - u32 frame_count=0; - - sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) : - sizeof(struct megasas_sge32); - - /* - * Main frame can contain 2 SGEs for 64-bit SGLs and - * 3 SGEs for 32-bit SGLs - */ - if (IS_DMA64) - num_cnt = sge_count - 2; - else - num_cnt = sge_count - 3; - - if(num_cnt>0){ - sge_bytes = sge_sz * num_cnt; - - frame_count = (sge_bytes / MEGAMFI_FRAME_SIZE) + - ((sge_bytes % MEGAMFI_FRAME_SIZE) ? 1 : 0) ; - } - /* Main frame */ - frame_count +=1; - - if (frame_count > 7) - frame_count = 8; - return frame_count; -} - /** * megasas_build_dcdb - Prepares a direct cdb (DCDB) command * @instance: Adapter soft state @@ -563,6 +508,8 @@ static int megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp, struct megasas_cmd *cmd) { + u32 sge_sz; + int sge_bytes; u32 is_logical; u32 device_id; u16 flags = 0; @@ -597,6 +544,9 @@ megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp, /* * Construct SGL */ + sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) : + sizeof(struct megasas_sge32); + if (IS_DMA64) { pthru->flags |= MFI_FRAME_SGL64; pthru->sge_count = megasas_make_sgl64(instance, scp, @@ -612,11 +562,17 @@ megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp, pthru->sense_buf_phys_addr_hi = 0; pthru->sense_buf_phys_addr_lo = cmd->sense_phys_addr; + sge_bytes = sge_sz * pthru->sge_count; + /* * Compute the total number of frames this command consumes. FW uses * this number to pull sufficient number of frames from host memory. */ - cmd->frame_count = megasas_get_frame_count(pthru->sge_count); + cmd->frame_count = (sge_bytes / MEGAMFI_FRAME_SIZE) + + ((sge_bytes % MEGAMFI_FRAME_SIZE) ? 1 : 0) + 1; + + if (cmd->frame_count > 7) + cmd->frame_count = 8; return cmd->frame_count; } @@ -633,6 +589,8 @@ static int megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp, struct megasas_cmd *cmd) { + u32 sge_sz; + int sge_bytes; u32 device_id; u8 sc = scp->cmnd[0]; u16 flags = 0; @@ -647,7 +605,7 @@ megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp, flags = MFI_FRAME_DIR_READ; /* - * Prepare the Logical IO frame: 2nd bit is zero for all read cmds + * Preare the Logical IO frame: 2nd bit is zero for all read cmds */ ldio->cmd = (sc & 0x02) ? MFI_CMD_LD_WRITE : MFI_CMD_LD_READ; ldio->cmd_status = 0x0; @@ -716,6 +674,9 @@ megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp, /* * Construct SGL */ + sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) : + sizeof(struct megasas_sge32); + if (IS_DMA64) { ldio->flags |= MFI_FRAME_SGL64; ldio->sge_count = megasas_make_sgl64(instance, scp, &ldio->sgl); @@ -729,11 +690,13 @@ megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp, ldio->sense_buf_phys_addr_hi = 0; ldio->sense_buf_phys_addr_lo = cmd->sense_phys_addr; - /* - * Compute the total number of frames this command consumes. FW uses - * this number to pull sufficient number of frames from host memory. - */ - cmd->frame_count = megasas_get_frame_count(ldio->sge_count); + sge_bytes = sge_sz * ldio->sge_count; + + cmd->frame_count = (sge_bytes / MEGAMFI_FRAME_SIZE) + + ((sge_bytes % MEGAMFI_FRAME_SIZE) ? 1 : 0) + 1; + + if (cmd->frame_count > 7) + cmd->frame_count = 8; return cmd->frame_count; } @@ -764,69 +727,6 @@ static inline int megasas_is_ldio(struct scsi_cmnd *cmd) } } - /** - * megasas_dump_pending_frames - Dumps the frame address of all pending cmds - * in FW - * @instance: Adapter soft state - */ -static inline void -megasas_dump_pending_frames(struct megasas_instance *instance) -{ - struct megasas_cmd *cmd; - int i,n; - union megasas_sgl *mfi_sgl; - struct megasas_io_frame *ldio; - struct megasas_pthru_frame *pthru; - u32 sgcount; - u32 max_cmd = instance->max_fw_cmds; - - printk(KERN_ERR "\nmegasas[%d]: Dumping Frame Phys Address of all pending cmds in FW\n",instance->host->host_no); - printk(KERN_ERR "megasas[%d]: Total OS Pending cmds : %d\n",instance->host->host_no,atomic_read(&instance->fw_outstanding)); - if (IS_DMA64) - printk(KERN_ERR "\nmegasas[%d]: 64 bit SGLs were sent to FW\n",instance->host->host_no); - else - printk(KERN_ERR "\nmegasas[%d]: 32 bit SGLs were sent to FW\n",instance->host->host_no); - - printk(KERN_ERR "megasas[%d]: Pending OS cmds in FW : \n",instance->host->host_no); - for (i = 0; i < max_cmd; i++) { - cmd = instance->cmd_list[i]; - if(!cmd->scmd) - continue; - printk(KERN_ERR "megasas[%d]: Frame addr :0x%08lx : ",instance->host->host_no,(unsigned long)cmd->frame_phys_addr); - if (megasas_is_ldio(cmd->scmd)){ - ldio = (struct megasas_io_frame *)cmd->frame; - mfi_sgl = &ldio->sgl; - sgcount = ldio->sge_count; - printk(KERN_ERR "megasas[%d]: frame count : 0x%x, Cmd : 0x%x, Tgt id : 0x%x, lba lo : 0x%x, lba_hi : 0x%x, sense_buf addr : 0x%x,sge count : 0x%x\n",instance->host->host_no, cmd->frame_count,ldio->cmd,ldio->target_id, ldio->start_lba_lo,ldio->start_lba_hi,ldio->sense_buf_phys_addr_lo,sgcount); - } - else { - pthru = (struct megasas_pthru_frame *) cmd->frame; - mfi_sgl = &pthru->sgl; - sgcount = pthru->sge_count; - printk(KERN_ERR "megasas[%d]: frame count : 0x%x, Cmd : 0x%x, Tgt id : 0x%x, lun : 0x%x, cdb_len : 0x%x, data xfer len : 0x%x, sense_buf addr : 0x%x,sge count : 0x%x\n",instance->host->host_no,cmd->frame_count,pthru->cmd,pthru->target_id,pthru->lun,pthru->cdb_len , pthru->data_xfer_len,pthru->sense_buf_phys_addr_lo,sgcount); - } - if(megasas_dbg_lvl & MEGASAS_DBG_LVL){ - for (n = 0; n < sgcount; n++){ - if (IS_DMA64) - printk(KERN_ERR "megasas: sgl len : 0x%x, sgl addr : 0x%08lx ",mfi_sgl->sge64[n].length , (unsigned long)mfi_sgl->sge64[n].phys_addr) ; - else - printk(KERN_ERR "megasas: sgl len : 0x%x, sgl addr : 0x%x ",mfi_sgl->sge32[n].length , mfi_sgl->sge32[n].phys_addr) ; - } - } - printk(KERN_ERR "\n"); - } /*for max_cmd*/ - printk(KERN_ERR "\nmegasas[%d]: Pending Internal cmds in FW : \n",instance->host->host_no); - for (i = 0; i < max_cmd; i++) { - - cmd = instance->cmd_list[i]; - - if(cmd->sync_cmd == 1){ - printk(KERN_ERR "0x%08lx : ", (unsigned long)cmd->frame_phys_addr); - } - } - printk(KERN_ERR "megasas[%d]: Dumping Done.\n\n",instance->host->host_no); -} - /** * megasas_queue_command - Queue entry point * @scmd: SCSI command to be queued @@ -932,13 +832,6 @@ static int megasas_wait_for_outstanding(struct megasas_instance *instance) } if (atomic_read(&instance->fw_outstanding)) { - /* - * Send signal to FW to stop processing any pending cmds. - * The controller will be taken offline by the OS now. - */ - writel(MFI_STOP_ADP, - &instance->reg_set->inbound_doorbell); - megasas_dump_pending_frames(instance); instance->hw_crit_error = 1; return FAILED; } @@ -1275,6 +1168,11 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, static int megasas_deplete_reply_queue(struct megasas_instance *instance, u8 alt_status) { + u32 producer; + u32 consumer; + u32 context; + struct megasas_cmd *cmd; + /* * Check if it is our interrupt * Clear the interrupt @@ -1282,10 +1180,23 @@ megasas_deplete_reply_queue(struct megasas_instance *instance, u8 alt_status) if(instance->instancet->clear_intr(instance->reg_set)) return IRQ_NONE; - /* - * Schedule the tasklet for cmd completion - */ - tasklet_schedule(&instance->isr_tasklet); + producer = *instance->producer; + consumer = *instance->consumer; + + while (consumer != producer) { + context = instance->reply_queue[consumer]; + + cmd = instance->cmd_list[context]; + + megasas_complete_cmd(instance, cmd, alt_status); + + consumer++; + if (consumer == (instance->max_fw_cmds + 1)) { + consumer = 0; + } + } + + *instance->consumer = producer; return IRQ_HANDLED; } @@ -1293,7 +1204,7 @@ megasas_deplete_reply_queue(struct megasas_instance *instance, u8 alt_status) /** * megasas_isr - isr entry point */ -static irqreturn_t megasas_isr(int irq, void *devp) +static irqreturn_t megasas_isr(int irq, void *devp, struct pt_regs *regs) { return megasas_deplete_reply_queue((struct megasas_instance *)devp, DID_OK); @@ -1318,12 +1229,10 @@ megasas_transition_to_ready(struct megasas_instance* instance) fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) & MFI_STATE_MASK; - if (fw_state != MFI_STATE_READY) - printk(KERN_INFO "megasas: Waiting for FW to come to ready" - " state\n"); - while (fw_state != MFI_STATE_READY) { + printk(KERN_INFO "megasas: Waiting for FW to come to ready" + " state\n"); switch (fw_state) { case MFI_STATE_FAULT: @@ -1335,27 +1244,19 @@ megasas_transition_to_ready(struct megasas_instance* instance) /* * Set the CLR bit in inbound doorbell */ - writel(MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG, + writel(MFI_INIT_CLEAR_HANDSHAKE, &instance->reg_set->inbound_doorbell); max_wait = 2; cur_state = MFI_STATE_WAIT_HANDSHAKE; break; - case MFI_STATE_BOOT_MESSAGE_PENDING: - writel(MFI_INIT_HOTPLUG, - &instance->reg_set->inbound_doorbell); - - max_wait = 10; - cur_state = MFI_STATE_BOOT_MESSAGE_PENDING; - break; - case MFI_STATE_OPERATIONAL: /* - * Bring it to READY state; assuming max wait 10 secs + * Bring it to READY state; assuming max wait 2 secs */ - instance->instancet->disable_intr(instance->reg_set); - writel(MFI_RESET_FLAGS, &instance->reg_set->inbound_doorbell); + megasas_disable_intr(instance); + writel(MFI_INIT_READY, &instance->reg_set->inbound_doorbell); max_wait = 10; cur_state = MFI_STATE_OPERATIONAL; @@ -1422,7 +1323,6 @@ megasas_transition_to_ready(struct megasas_instance* instance) return -ENODEV; } }; - printk(KERN_INFO "megasas: FW now in Ready state\n"); return 0; } @@ -1452,7 +1352,7 @@ static void megasas_teardown_frame_pool(struct megasas_instance *instance) cmd->frame_phys_addr); if (cmd->sense) - pci_pool_free(instance->sense_dma_pool, cmd->sense, + pci_pool_free(instance->sense_dma_pool, cmd->frame, cmd->sense_phys_addr); } @@ -1727,39 +1627,6 @@ megasas_get_ctrl_info(struct megasas_instance *instance, return ret; } -/** - * megasas_complete_cmd_dpc - Returns FW's controller structure - * @instance_addr: Address of adapter soft state - * - * Tasklet to complete cmds - */ -void megasas_complete_cmd_dpc(unsigned long instance_addr) -{ - u32 producer; - u32 consumer; - u32 context; - struct megasas_cmd *cmd; - struct megasas_instance *instance = (struct megasas_instance *)instance_addr; - - producer = *instance->producer; - consumer = *instance->consumer; - - while (consumer != producer) { - context = instance->reply_queue[consumer]; - - cmd = instance->cmd_list[context]; - - megasas_complete_cmd(instance, cmd, DID_OK); - - consumer++; - if (consumer == (instance->max_fw_cmds + 1)) { - consumer = 0; - } - } - - *instance->consumer = producer; -} - /** * megasas_init_mfi - Initializes the FW * @instance: Adapter soft state @@ -1823,12 +1690,6 @@ static int megasas_init_mfi(struct megasas_instance *instance) * Get various operational parameters from status register */ instance->max_fw_cmds = instance->instancet->read_fw_status_reg(reg_set) & 0x00FFFF; - /* - * Reduce the max supported cmds by 1. This is to ensure that the - * reply_q_sz (1 more than the max cmd that driver may send) - * does not exceed max cmds that the FW can support - */ - instance->max_fw_cmds = instance->max_fw_cmds-1; instance->max_num_sge = (instance->instancet->read_fw_status_reg(reg_set) & 0xFF0000) >> 0x10; /* @@ -1893,7 +1754,7 @@ static int megasas_init_mfi(struct megasas_instance *instance) /* * disable the intr before firing the init frame to FW */ - instance->instancet->disable_intr(instance->reg_set); + megasas_disable_intr(instance); /* * Issue the init frame in polled mode @@ -1930,12 +1791,6 @@ static int megasas_init_mfi(struct megasas_instance *instance) kfree(ctrl_info); - /* - * Setup tasklet for cmd completion - */ - - tasklet_init(&instance->isr_tasklet, megasas_complete_cmd_dpc, - (unsigned long)instance); return 0; fail_fw_init: @@ -2327,8 +2182,6 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) instance->unique_id = pdev->bus->number << 8 | pdev->devfn; instance->init_id = MEGASAS_DEFAULT_INIT_ID; - megasas_dbg_lvl = 0; - /* * Initialize MFI Firmware */ @@ -2381,7 +2234,7 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) megasas_mgmt_info.max_index--; pci_set_drvdata(pdev, NULL); - instance->instancet->disable_intr(instance->reg_set); + megasas_disable_intr(instance); free_irq(instance->pdev->irq, instance); megasas_release_mfi(instance); @@ -2495,7 +2348,6 @@ static void megasas_detach_one(struct pci_dev *pdev) scsi_remove_host(instance->host); megasas_flush_cache(instance); megasas_shutdown_controller(instance); - tasklet_kill(&instance->isr_tasklet); /* * Take the instance off the instance array. Note that we will not @@ -2512,7 +2364,7 @@ static void megasas_detach_one(struct pci_dev *pdev) pci_set_drvdata(instance->pdev, NULL); - instance->instancet->disable_intr(instance->reg_set); + megasas_disable_intr(instance); free_irq(instance->pdev->irq, instance); @@ -2864,8 +2716,7 @@ static int megasas_mgmt_compat_ioctl_fw(struct file *file, unsigned long arg) int i; int error = 0; - if (clear_user(ioc, sizeof(*ioc))) - return -EFAULT; + clear_user(ioc, sizeof(*ioc)); if (copy_in_user(&ioc->host_no, &cioc->host_no, sizeof(u16)) || copy_in_user(&ioc->sgl_off, &cioc->sgl_off, sizeof(u32)) || @@ -2957,26 +2808,6 @@ megasas_sysfs_show_release_date(struct device_driver *dd, char *buf) static DRIVER_ATTR(release_date, S_IRUGO, megasas_sysfs_show_release_date, NULL); -static ssize_t -megasas_sysfs_show_dbg_lvl(struct device_driver *dd, char *buf) -{ - return sprintf(buf,"%u",megasas_dbg_lvl); -} - -static ssize_t -megasas_sysfs_set_dbg_lvl(struct device_driver *dd, const char *buf, size_t count) -{ - int retval = count; - if(sscanf(buf,"%u",&megasas_dbg_lvl)<1){ - printk(KERN_ERR "megasas: could not set dbg_lvl\n"); - retval = -EINVAL; - } - return retval; -} - -static DRIVER_ATTR(dbg_lvl, S_IRUGO|S_IWUGO, megasas_sysfs_show_dbg_lvl, - megasas_sysfs_set_dbg_lvl); - /** * megasas_init - Driver load entry point */ @@ -3011,33 +2842,14 @@ static int __init megasas_init(void) if (rval) { printk(KERN_DEBUG "megasas: PCI hotplug regisration failed \n"); - goto err_pcidrv; - } - - rval = driver_create_file(&megasas_pci_driver.driver, - &driver_attr_version); - if (rval) - goto err_dcf_attr_ver; - rval = driver_create_file(&megasas_pci_driver.driver, - &driver_attr_release_date); - if (rval) - goto err_dcf_rel_date; - rval = driver_create_file(&megasas_pci_driver.driver, - &driver_attr_dbg_lvl); - if (rval) - goto err_dcf_dbg_lvl; + unregister_chrdev(megasas_mgmt_majorno, "megaraid_sas_ioctl"); + } - return rval; -err_dcf_dbg_lvl: - driver_remove_file(&megasas_pci_driver.driver, + driver_create_file(&megasas_pci_driver.driver, &driver_attr_version); + driver_create_file(&megasas_pci_driver.driver, &driver_attr_release_date); -err_dcf_rel_date: - driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version); -err_dcf_attr_ver: - pci_unregister_driver(&megasas_pci_driver); -err_pcidrv: - unregister_chrdev(megasas_mgmt_majorno, "megaraid_sas_ioctl"); - return rval; + + return rval; } /** @@ -3045,11 +2857,9 @@ static int __init megasas_init(void) */ static void __exit megasas_exit(void) { - driver_remove_file(&megasas_pci_driver.driver, - &driver_attr_dbg_lvl); + driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version); driver_remove_file(&megasas_pci_driver.driver, &driver_attr_release_date); - driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version); pci_unregister_driver(&megasas_pci_driver); unregister_chrdev(megasas_mgmt_majorno, "megaraid_sas_ioctl"); diff --git a/trunk/drivers/scsi/megaraid/megaraid_sas.h b/trunk/drivers/scsi/megaraid/megaraid_sas.h index 55eddcf8eb15..3531a14222a7 100644 --- a/trunk/drivers/scsi/megaraid/megaraid_sas.h +++ b/trunk/drivers/scsi/megaraid/megaraid_sas.h @@ -18,9 +18,9 @@ /** * MegaRAID SAS Driver meta data */ -#define MEGASAS_VERSION "00.00.03.05" -#define MEGASAS_RELDATE "Oct 02, 2006" -#define MEGASAS_EXT_VERSION "Mon Oct 02 11:21:32 PDT 2006" +#define MEGASAS_VERSION "00.00.03.01" +#define MEGASAS_RELDATE "May 14, 2006" +#define MEGASAS_EXT_VERSION "Sun May 14 22:49:52 PDT 2006" /* * Device IDs @@ -50,7 +50,6 @@ #define MFI_STATE_WAIT_HANDSHAKE 0x60000000 #define MFI_STATE_FW_INIT_2 0x70000000 #define MFI_STATE_DEVICE_SCAN 0x80000000 -#define MFI_STATE_BOOT_MESSAGE_PENDING 0x90000000 #define MFI_STATE_FLUSH_CACHE 0xA0000000 #define MFI_STATE_READY 0xB0000000 #define MFI_STATE_OPERATIONAL 0xC0000000 @@ -65,18 +64,12 @@ * READY : Move from OPERATIONAL to READY state; discard queue info * MFIMODE : Discard (possible) low MFA posted in 64-bit mode (??) * CLR_HANDSHAKE: FW is waiting for HANDSHAKE from BIOS or Driver - * HOTPLUG : Resume from Hotplug - * MFI_STOP_ADP : Send signal to FW to stop processing */ -#define MFI_INIT_ABORT 0x00000001 +#define MFI_INIT_ABORT 0x00000000 #define MFI_INIT_READY 0x00000002 #define MFI_INIT_MFIMODE 0x00000004 #define MFI_INIT_CLEAR_HANDSHAKE 0x00000008 -#define MFI_INIT_HOTPLUG 0x00000010 -#define MFI_STOP_ADP 0x00000020 -#define MFI_RESET_FLAGS MFI_INIT_READY| \ - MFI_INIT_MFIMODE| \ - MFI_INIT_ABORT +#define MFI_RESET_FLAGS MFI_INIT_READY|MFI_INIT_MFIMODE /** * MFI frame flags @@ -537,8 +530,6 @@ struct megasas_ctrl_info { #define MEGASAS_MAX_LUN 8 #define MEGASAS_MAX_LD 64 -#define MEGASAS_DBG_LVL 1 - /* * When SCSI mid-layer calls driver's reset routine, driver waits for * MEGASAS_RESET_WAIT_TIME seconds for all outstanding IO to complete. Note @@ -547,7 +538,6 @@ struct megasas_ctrl_info { * every MEGASAS_RESET_NOTICE_INTERVAL seconds */ #define MEGASAS_RESET_WAIT_TIME 180 -#define MEGASAS_INTERNAL_CMD_WAIT_TIME 180 #define MEGASAS_RESET_NOTICE_INTERVAL 5 #define MEGASAS_IOCTL_CMD 0 @@ -1052,7 +1042,6 @@ struct megasas_evt_detail { void (*fire_cmd)(dma_addr_t ,u32 ,struct megasas_register_set __iomem *); void (*enable_intr)(struct megasas_register_set __iomem *) ; - void (*disable_intr)(struct megasas_register_set __iomem *); int (*clear_intr)(struct megasas_register_set __iomem *); @@ -1103,7 +1092,6 @@ struct megasas_instance { u32 hw_crit_error; struct megasas_instance_template *instancet; - struct tasklet_struct isr_tasklet; }; #define MEGASAS_IS_LOGICAL(scp) \ diff --git a/trunk/drivers/scsi/mesh.c b/trunk/drivers/scsi/mesh.c index 1fd3c7590d31..683fc7ae4b8f 100644 --- a/trunk/drivers/scsi/mesh.c +++ b/trunk/drivers/scsi/mesh.c @@ -185,7 +185,7 @@ struct mesh_state { * Driver is too messy, we need a few prototypes... */ static void mesh_done(struct mesh_state *ms, int start_next); -static void mesh_interrupt(int irq, void *dev_id); +static void mesh_interrupt(int irq, void *dev_id, struct pt_regs *ptregs); static void cmd_complete(struct mesh_state *ms); static void set_dma_cmds(struct mesh_state *ms, struct scsi_cmnd *cmd); static void halt_dma(struct mesh_state *ms); @@ -466,7 +466,7 @@ static void mesh_start_cmd(struct mesh_state *ms, struct scsi_cmnd *cmd) dlog(ms, "intr b4 arb, intr/exc/err/fc=%.8x", MKWORD(mr->interrupt, mr->exception, mr->error, mr->fifo_count)); - mesh_interrupt(0, (void *)ms); + mesh_interrupt(0, (void *)ms, NULL); if (ms->phase != arbitrating) return; } @@ -504,7 +504,7 @@ static void mesh_start_cmd(struct mesh_state *ms, struct scsi_cmnd *cmd) dlog(ms, "intr after disresel, intr/exc/err/fc=%.8x", MKWORD(mr->interrupt, mr->exception, mr->error, mr->fifo_count)); - mesh_interrupt(0, (void *)ms); + mesh_interrupt(0, (void *)ms, NULL); if (ms->phase != arbitrating) return; dlog(ms, "after intr after disresel, intr/exc/err/fc=%.8x", @@ -1015,13 +1015,13 @@ static void handle_reset(struct mesh_state *ms) out_8(&mr->sequence, SEQ_ENBRESEL); } -static irqreturn_t do_mesh_interrupt(int irq, void *dev_id) +static irqreturn_t do_mesh_interrupt(int irq, void *dev_id, struct pt_regs *ptregs) { unsigned long flags; struct Scsi_Host *dev = ((struct mesh_state *)dev_id)->host; spin_lock_irqsave(dev->host_lock, flags); - mesh_interrupt(irq, dev_id); + mesh_interrupt(irq, dev_id, ptregs); spin_unlock_irqrestore(dev->host_lock, flags); return IRQ_HANDLED; } @@ -1661,7 +1661,7 @@ static int mesh_queue(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) * handler (do_mesh_interrupt) or by other functions in * exceptional circumstances */ -static void mesh_interrupt(int irq, void *dev_id) +static void mesh_interrupt(int irq, void *dev_id, struct pt_regs *ptregs) { struct mesh_state *ms = (struct mesh_state *) dev_id; volatile struct mesh_regs __iomem *mr = ms->mesh; diff --git a/trunk/drivers/scsi/mvme147.c b/trunk/drivers/scsi/mvme147.c index 1ddd7a11a958..9b991b746d1e 100644 --- a/trunk/drivers/scsi/mvme147.c +++ b/trunk/drivers/scsi/mvme147.c @@ -20,7 +20,7 @@ static struct Scsi_Host *mvme147_host = NULL; -static irqreturn_t mvme147_intr (int irq, void *dummy) +static irqreturn_t mvme147_intr (int irq, void *dummy, struct pt_regs *fp) { if (irq == MVME147_IRQ_SCSI_PORT) wd33c93_intr (mvme147_host); diff --git a/trunk/drivers/scsi/mvme16x.h b/trunk/drivers/scsi/mvme16x.h index 73e33b37a3f8..c7a12533fb2c 100644 --- a/trunk/drivers/scsi/mvme16x.h +++ b/trunk/drivers/scsi/mvme16x.h @@ -9,7 +9,7 @@ int NCR53c7xx_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); int NCR53c7xx_abort(Scsi_Cmnd *); int NCR53c7x0_release (struct Scsi_Host *); int NCR53c7xx_reset(Scsi_Cmnd *, unsigned int); -void NCR53c7x0_intr(int irq, void *dev_id); +void NCR53c7x0_intr(int irq, void *dev_id, struct pt_regs * regs); #ifndef CMD_PER_LUN #define CMD_PER_LUN 3 diff --git a/trunk/drivers/scsi/ncr53c8xx.c b/trunk/drivers/scsi/ncr53c8xx.c index adb8eb4f5fd1..b28712df0b77 100644 --- a/trunk/drivers/scsi/ncr53c8xx.c +++ b/trunk/drivers/scsi/ncr53c8xx.c @@ -185,7 +185,7 @@ static inline struct list_head *ncr_list_pop(struct list_head *head) ** power of 2 cache line size. ** Enhanced in linux-2.3.44 to provide a memory pool ** per pcidev to support dynamic dma mapping. (I would -** have preferred a real bus abstraction, btw). +** have preferred a real bus astraction, btw). ** **========================================================== */ @@ -1438,7 +1438,7 @@ struct head { ** The first four bytes (scr_st[4]) are used inside the script by ** "COPY" commands. ** Because source and destination must have the same alignment -** in a DWORD, the fields HAVE to be at the chosen offsets. +** in a DWORD, the fields HAVE to be at the choosen offsets. ** xerr_st 0 (0x34) scratcha ** sync_st 1 (0x05) sxfer ** wide_st 3 (0x03) scntl3 @@ -1498,7 +1498,7 @@ struct head { ** the DSA (data structure address) register points ** to this substructure of the ccb. ** This substructure contains the header with -** the script-processor-changeable data and +** the script-processor-changable data and ** data blocks for the indirect move commands. ** **---------------------------------------------------------- @@ -5107,7 +5107,7 @@ void ncr_complete (struct ncb *np, struct ccb *cp) /* ** This CCB has been skipped by the NCR. -** Queue it in the corresponding unit queue. +** Queue it in the correponding unit queue. */ static void ncr_ccb_skipped(struct ncb *np, struct ccb *cp) { @@ -5896,8 +5896,8 @@ static void ncr_log_hard_error(struct ncb *np, u16 sist, u_char dstat) ** ** In normal cases, interrupt conditions occur one at a ** time. The ncr is able to stack in some extra registers -** other interrupts that will occur after the first one. -** But, several interrupts may occur at the same time. +** other interrupts that will occurs after the first one. +** But severall interrupts may occur at the same time. ** ** We probably should only try to deal with the normal ** case, but it seems that multiple interrupts occur in @@ -6796,7 +6796,7 @@ void ncr_int_sir (struct ncb *np) ** The host status field is set to HS_NEGOTIATE to mark this ** situation. ** -** If the target doesn't answer this message immediately +** If the target doesn't answer this message immidiately ** (as required by the standard), the SIR_NEGO_FAIL interrupt ** will be raised eventually. ** The handler removes the HS_NEGOTIATE status, and sets the @@ -8111,7 +8111,7 @@ printk("ncr53c8xx : command successfully queued\n"); return sts; } -irqreturn_t ncr53c8xx_intr(int irq, void *dev_id) +irqreturn_t ncr53c8xx_intr(int irq, void *dev_id, struct pt_regs * regs) { unsigned long flags; struct Scsi_Host *shost = (struct Scsi_Host *)dev_id; diff --git a/trunk/drivers/scsi/ncr53c8xx.h b/trunk/drivers/scsi/ncr53c8xx.h index b39357d9af8d..78818b6684f8 100644 --- a/trunk/drivers/scsi/ncr53c8xx.h +++ b/trunk/drivers/scsi/ncr53c8xx.h @@ -218,7 +218,7 @@ ** Same as option 1, but also deal with ** misconfigured interrupts. ** -** - Edge triggered instead of level sensitive. +** - Edge triggerred instead of level sensitive. ** - No interrupt line connected. ** - IRQ number misconfigured. ** @@ -549,7 +549,7 @@ struct ncr_driver_setup { /* ** Initial setup. -** Can be overridden at startup by a command line. +** Can be overriden at startup by a command line. */ #define SCSI_NCR_DRIVER_SETUP \ { \ @@ -1093,7 +1093,7 @@ struct scr_tblsel { **----------------------------------------------------------- ** On 810A, 860, 825A, 875, 895 and 896 chips the content ** of SFBR register can be used as data (SCR_SFBR_DATA). -** The 896 has additional IO registers starting at +** The 896 has additionnal IO registers starting at ** offset 0x80. Bit 7 of register offset is stored in ** bit 7 of the SCRIPTS instruction first DWORD. **----------------------------------------------------------- @@ -1322,7 +1322,7 @@ struct ncr_device { extern struct Scsi_Host *ncr_attach(struct scsi_host_template *tpnt, int unit, struct ncr_device *device); extern int ncr53c8xx_release(struct Scsi_Host *host); -irqreturn_t ncr53c8xx_intr(int irq, void *dev_id); +irqreturn_t ncr53c8xx_intr(int irq, void *dev_id, struct pt_regs * regs); extern int ncr53c8xx_init(void); extern void ncr53c8xx_exit(void); diff --git a/trunk/drivers/scsi/nsp32.c b/trunk/drivers/scsi/nsp32.c index 7c13f6f4a4c6..bfb4f49e125d 100644 --- a/trunk/drivers/scsi/nsp32.c +++ b/trunk/drivers/scsi/nsp32.c @@ -256,7 +256,7 @@ static void nsp32_sack_negate (nsp32_hw_data *); static void nsp32_do_bus_reset(nsp32_hw_data *); /* hardware interrupt handler */ -static irqreturn_t do_nsp32_isr(int, void *); +static irqreturn_t do_nsp32_isr(int, void *, struct pt_regs *); /* initialize hardware */ static int nsp32hw_init(nsp32_hw_data *); @@ -1201,7 +1201,7 @@ static int nsp32hw_init(nsp32_hw_data *data) /* interrupt routine */ -static irqreturn_t do_nsp32_isr(int irq, void *dev_id) +static irqreturn_t do_nsp32_isr(int irq, void *dev_id, struct pt_regs *regs) { nsp32_hw_data *data = dev_id; unsigned int base = data->BaseAddress; @@ -3581,7 +3581,7 @@ static struct pci_driver nsp32_driver = { */ static int __init init_nsp32(void) { nsp32_msg(KERN_INFO, "loading..."); - return pci_register_driver(&nsp32_driver); + return pci_module_init(&nsp32_driver); } static void __exit exit_nsp32(void) { diff --git a/trunk/drivers/scsi/nsp32.h b/trunk/drivers/scsi/nsp32.h index a976e8193d16..5addf9fb1e15 100644 --- a/trunk/drivers/scsi/nsp32.h +++ b/trunk/drivers/scsi/nsp32.h @@ -619,5 +619,47 @@ typedef struct _nsp32_hw_data { #define REQSACK_TIMEOUT_TIME 10000 /* max wait time for REQ/SACK assertion or negation, 10000us == 10ms */ +/************************************************************************** + * Compatibility functions + */ + +/* for Kernel 2.4 */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) +# define scsi_register_host(template) scsi_register_module(MODULE_SCSI_HA, template) +# define scsi_unregister_host(template) scsi_unregister_module(MODULE_SCSI_HA, template) +# define scsi_host_put(host) scsi_unregister(host) +# define pci_name(pci_dev) ((pci_dev)->slot_name) + +typedef void irqreturn_t; +# define IRQ_NONE /* */ +# define IRQ_HANDLED /* */ +# define IRQ_RETVAL(x) /* */ + +/* This is ad-hoc version of scsi_host_get_next() */ +static inline struct Scsi_Host *scsi_host_get_next(struct Scsi_Host *host) +{ + if (host == NULL) { + return scsi_hostlist; + } else { + return host->next; + } +} + +/* This is ad-hoc version of scsi_host_hn_get() */ +static inline struct Scsi_Host *scsi_host_hn_get(unsigned short hostno) +{ + struct Scsi_Host *host; + + for (host = scsi_host_get_next(NULL); host != NULL; + host = scsi_host_get_next(host)) { + if (host->host_no == hostno) { + break; + } + } + + return host; +} +#endif + #endif /* _NSP32_H */ /* end */ diff --git a/trunk/drivers/scsi/osst.c b/trunk/drivers/scsi/osst.c index 824fe080d1dc..4a2fed350d4e 100644 --- a/trunk/drivers/scsi/osst.c +++ b/trunk/drivers/scsi/osst.c @@ -4843,7 +4843,8 @@ static int os_scsi_tape_close(struct inode * inode, struct file * filp) static int osst_ioctl(struct inode * inode,struct file * file, unsigned int cmd_in, unsigned long arg) { - int i, cmd_nr, cmd_type, blk, retval = 0; + int i, cmd_nr, cmd_type, retval = 0; + unsigned int blk; struct st_modedef * STm; struct st_partstat * STps; struct osst_request * SRpnt = NULL; @@ -5206,12 +5207,12 @@ static struct osst_buffer * new_tape_buffer( int from_initialization, int need_d priority = GFP_KERNEL; i = sizeof(struct osst_buffer) + (osst_max_sg_segs - 1) * sizeof(struct scatterlist); - tb = kzalloc(i, priority); + tb = (struct osst_buffer *)kmalloc(i, priority); if (!tb) { printk(KERN_NOTICE "osst :I: Can't allocate new tape buffer.\n"); return NULL; } - + memset(tb, 0, i); tb->sg_segs = tb->orig_sg_segs = 0; tb->use_sg = max_sg; tb->in_use = 1; @@ -5574,9 +5575,9 @@ static ssize_t osst_version_show(struct device_driver *ddd, char *buf) static DRIVER_ATTR(version, S_IRUGO, osst_version_show, NULL); -static int osst_create_driverfs_files(struct device_driver *driverfs) +static void osst_create_driverfs_files(struct device_driver *driverfs) { - return driver_create_file(driverfs, &driver_attr_version); + driver_create_file(driverfs, &driver_attr_version); } static void osst_remove_driverfs_files(struct device_driver *driverfs) @@ -5662,70 +5663,50 @@ CLASS_DEVICE_ATTR(file_count, S_IRUGO, osst_filemark_cnt_show, NULL); static struct class *osst_sysfs_class; -static int osst_sysfs_init(void) -{ - osst_sysfs_class = class_create(THIS_MODULE, "onstream_tape"); - if (IS_ERR(osst_sysfs_class)) { - printk(KERN_ERR "osst :W: Unable to register sysfs class\n"); - return PTR_ERR(osst_sysfs_class); - } - - return 0; -} +static int osst_sysfs_valid = 0; -static void osst_sysfs_destroy(dev_t dev) +static void osst_sysfs_init(void) { - class_device_destroy(osst_sysfs_class, dev); + osst_sysfs_class = class_create(THIS_MODULE, "onstream_tape"); + if ( IS_ERR(osst_sysfs_class) ) + printk(KERN_WARNING "osst :W: Unable to register sysfs class\n"); + else + osst_sysfs_valid = 1; } -static int osst_sysfs_add(dev_t dev, struct device *device, struct osst_tape * STp, char * name) +static void osst_sysfs_add(dev_t dev, struct device *device, struct osst_tape * STp, char * name) { struct class_device *osst_class_member; - int err; - osst_class_member = class_device_create(osst_sysfs_class, NULL, dev, - device, "%s", name); + if (!osst_sysfs_valid) return; + + osst_class_member = class_device_create(osst_sysfs_class, NULL, dev, device, "%s", name); if (IS_ERR(osst_class_member)) { printk(KERN_WARNING "osst :W: Unable to add sysfs class member %s\n", name); - return PTR_ERR(osst_class_member); + return; } - class_set_devdata(osst_class_member, STp); - err = class_device_create_file(osst_class_member, - &class_device_attr_ADR_rev); - if (err) - goto err_out; - err = class_device_create_file(osst_class_member, - &class_device_attr_media_version); - if (err) - goto err_out; - err = class_device_create_file(osst_class_member, - &class_device_attr_capacity); - if (err) - goto err_out; - err = class_device_create_file(osst_class_member, - &class_device_attr_BOT_frame); - if (err) - goto err_out; - err = class_device_create_file(osst_class_member, - &class_device_attr_EOD_frame); - if (err) - goto err_out; - err = class_device_create_file(osst_class_member, - &class_device_attr_file_count); - if (err) - goto err_out; + class_device_create_file(osst_class_member, &class_device_attr_ADR_rev); + class_device_create_file(osst_class_member, &class_device_attr_media_version); + class_device_create_file(osst_class_member, &class_device_attr_capacity); + class_device_create_file(osst_class_member, &class_device_attr_BOT_frame); + class_device_create_file(osst_class_member, &class_device_attr_EOD_frame); + class_device_create_file(osst_class_member, &class_device_attr_file_count); +} - return 0; +static void osst_sysfs_destroy(dev_t dev) +{ + if (!osst_sysfs_valid) return; -err_out: - osst_sysfs_destroy(dev); - return err; + class_device_destroy(osst_sysfs_class, dev); } static void osst_sysfs_cleanup(void) { - class_destroy(osst_sysfs_class); + if (osst_sysfs_valid) { + class_destroy(osst_sysfs_class); + osst_sysfs_valid = 0; + } } /* @@ -5740,7 +5721,7 @@ static int osst_probe(struct device *dev) struct st_partstat * STps; struct osst_buffer * buffer; struct gendisk * drive; - int i, dev_num, err = -ENODEV; + int i, dev_num; if (SDp->type != TYPE_TAPE || !osst_supports(SDp)) return -ENODEV; @@ -5868,20 +5849,13 @@ static int osst_probe(struct device *dev) init_MUTEX(&tpnt->lock); osst_nr_dev++; write_unlock(&os_scsi_tapes_lock); - { char name[8]; - /* Rewind entry */ - err = osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num), dev, tpnt, tape_name(tpnt)); - if (err) - goto out_free_buffer; - + osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num), dev, tpnt, tape_name(tpnt)); /* No-rewind entry */ snprintf(name, 8, "%s%s", "n", tape_name(tpnt)); - err = osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num + 128), dev, tpnt, name); - if (err) - goto out_free_sysfs1; + osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num + 128), dev, tpnt, name); } sdev_printk(KERN_INFO, SDp, @@ -5890,13 +5864,9 @@ static int osst_probe(struct device *dev) return 0; -out_free_sysfs1: - osst_sysfs_destroy(MKDEV(OSST_MAJOR, dev_num)); -out_free_buffer: - kfree(buffer); out_put_disk: put_disk(drive); - return err; + return -ENODEV; }; static int osst_remove(struct device *dev) @@ -5933,39 +5903,19 @@ static int osst_remove(struct device *dev) static int __init init_osst(void) { - int err; - printk(KERN_INFO "osst :I: Tape driver with OnStream support version %s\nosst :I: %s\n", osst_version, cvsid); validate_options(); + osst_sysfs_init(); - err = osst_sysfs_init(); - if (err) - return err; - - err = register_chrdev(OSST_MAJOR, "osst", &osst_fops); - if (err < 0) { + if ((register_chrdev(OSST_MAJOR,"osst", &osst_fops) < 0) || scsi_register_driver(&osst_template.gendrv)) { printk(KERN_ERR "osst :E: Unable to register major %d for OnStream tapes\n", OSST_MAJOR); - goto err_out; + osst_sysfs_cleanup(); + return 1; } - - err = scsi_register_driver(&osst_template.gendrv); - if (err) - goto err_out_chrdev; - - err = osst_create_driverfs_files(&osst_template.gendrv); - if (err) - goto err_out_scsidrv; + osst_create_driverfs_files(&osst_template.gendrv); return 0; - -err_out_scsidrv: - scsi_unregister_driver(&osst_template.gendrv); -err_out_chrdev: - unregister_chrdev(OSST_MAJOR, "osst"); -err_out: - osst_sysfs_cleanup(); - return err; } static void __exit exit_osst (void) diff --git a/trunk/drivers/scsi/pcmcia/nsp_cs.c b/trunk/drivers/scsi/pcmcia/nsp_cs.c index f2d79c3f0b8e..0d4c04e1f3de 100644 --- a/trunk/drivers/scsi/pcmcia/nsp_cs.c +++ b/trunk/drivers/scsi/pcmcia/nsp_cs.c @@ -80,6 +80,7 @@ static int free_ports = 0; module_param(free_ports, bool, 0); MODULE_PARM_DESC(free_ports, "Release IO ports after configuration? (default: 0 (=no))"); +/* /usr/src/linux/drivers/scsi/hosts.h */ static struct scsi_host_template nsp_driver_template = { .proc_name = "nsp_cs", .proc_info = nsp_proc_info, @@ -183,7 +184,7 @@ static void nsp_cs_dmessage(const char *func, int line, int mask, char *fmt, ... * Clenaup parameters and call done() functions. * You must be set SCpnt->result before call this function. */ -static void nsp_scsi_done(struct scsi_cmnd *SCpnt) +static void nsp_scsi_done(Scsi_Cmnd *SCpnt) { nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; @@ -192,8 +193,7 @@ static void nsp_scsi_done(struct scsi_cmnd *SCpnt) SCpnt->scsi_done(SCpnt); } -static int nsp_queuecommand(struct scsi_cmnd *SCpnt, - void (*done)(struct scsi_cmnd *)) +static int nsp_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) { #ifdef NSP_DEBUG /*unsigned int host_id = SCpnt->device->host->this_id;*/ @@ -366,7 +366,7 @@ static int nsphw_init(nsp_hw_data *data) /* * Start selection phase */ -static int nsphw_start_selection(struct scsi_cmnd *SCpnt) +static int nsphw_start_selection(Scsi_Cmnd *SCpnt) { unsigned int host_id = SCpnt->device->host->this_id; unsigned int base = SCpnt->device->host->io_port; @@ -447,7 +447,7 @@ static struct nsp_sync_table nsp_sync_table_20M[] = { /* * setup synchronous data transfer mode */ -static int nsp_analyze_sdtr(struct scsi_cmnd *SCpnt) +static int nsp_analyze_sdtr(Scsi_Cmnd *SCpnt) { unsigned char target = scmd_id(SCpnt); // unsigned char lun = SCpnt->device->lun; @@ -505,7 +505,7 @@ static int nsp_analyze_sdtr(struct scsi_cmnd *SCpnt) /* * start ninja hardware timer */ -static void nsp_start_timer(struct scsi_cmnd *SCpnt, int time) +static void nsp_start_timer(Scsi_Cmnd *SCpnt, int time) { unsigned int base = SCpnt->device->host->io_port; nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; @@ -518,8 +518,7 @@ static void nsp_start_timer(struct scsi_cmnd *SCpnt, int time) /* * wait for bus phase change */ -static int nsp_negate_signal(struct scsi_cmnd *SCpnt, unsigned char mask, - char *str) +static int nsp_negate_signal(Scsi_Cmnd *SCpnt, unsigned char mask, char *str) { unsigned int base = SCpnt->device->host->io_port; unsigned char reg; @@ -546,9 +545,9 @@ static int nsp_negate_signal(struct scsi_cmnd *SCpnt, unsigned char mask, /* * expect Ninja Irq */ -static int nsp_expect_signal(struct scsi_cmnd *SCpnt, - unsigned char current_phase, - unsigned char mask) +static int nsp_expect_signal(Scsi_Cmnd *SCpnt, + unsigned char current_phase, + unsigned char mask) { unsigned int base = SCpnt->device->host->io_port; int time_out; @@ -581,7 +580,7 @@ static int nsp_expect_signal(struct scsi_cmnd *SCpnt, /* * transfer SCSI message */ -static int nsp_xfer(struct scsi_cmnd *SCpnt, int phase) +static int nsp_xfer(Scsi_Cmnd *SCpnt, int phase) { unsigned int base = SCpnt->device->host->io_port; nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; @@ -621,7 +620,7 @@ static int nsp_xfer(struct scsi_cmnd *SCpnt, int phase) /* * get extra SCSI data from fifo */ -static int nsp_dataphase_bypass(struct scsi_cmnd *SCpnt) +static int nsp_dataphase_bypass(Scsi_Cmnd *SCpnt) { nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; unsigned int count; @@ -653,7 +652,7 @@ static int nsp_dataphase_bypass(struct scsi_cmnd *SCpnt) /* * accept reselection */ -static int nsp_reselected(struct scsi_cmnd *SCpnt) +static int nsp_reselected(Scsi_Cmnd *SCpnt) { unsigned int base = SCpnt->device->host->io_port; unsigned int host_id = SCpnt->device->host->this_id; @@ -692,7 +691,7 @@ static int nsp_reselected(struct scsi_cmnd *SCpnt) /* * count how many data transferd */ -static int nsp_fifo_count(struct scsi_cmnd *SCpnt) +static int nsp_fifo_count(Scsi_Cmnd *SCpnt) { unsigned int base = SCpnt->device->host->io_port; unsigned int count; @@ -719,7 +718,7 @@ static int nsp_fifo_count(struct scsi_cmnd *SCpnt) /* * read data in DATA IN phase */ -static void nsp_pio_read(struct scsi_cmnd *SCpnt) +static void nsp_pio_read(Scsi_Cmnd *SCpnt) { unsigned int base = SCpnt->device->host->io_port; unsigned long mmio_base = SCpnt->device->host->base; @@ -814,7 +813,7 @@ static void nsp_pio_read(struct scsi_cmnd *SCpnt) /* * write data in DATA OUT phase */ -static void nsp_pio_write(struct scsi_cmnd *SCpnt) +static void nsp_pio_write(Scsi_Cmnd *SCpnt) { unsigned int base = SCpnt->device->host->io_port; unsigned long mmio_base = SCpnt->device->host->base; @@ -907,7 +906,7 @@ static void nsp_pio_write(struct scsi_cmnd *SCpnt) /* * setup synchronous/asynchronous data transfer mode */ -static int nsp_nexus(struct scsi_cmnd *SCpnt) +static int nsp_nexus(Scsi_Cmnd *SCpnt) { unsigned int base = SCpnt->device->host->io_port; unsigned char target = scmd_id(SCpnt); @@ -950,11 +949,11 @@ static int nsp_nexus(struct scsi_cmnd *SCpnt) /* * interrupt handler */ -static irqreturn_t nspintr(int irq, void *dev_id) +static irqreturn_t nspintr(int irq, void *dev_id, struct pt_regs *regs) { unsigned int base; unsigned char irq_status, irq_phase, phase; - struct scsi_cmnd *tmpSC; + Scsi_Cmnd *tmpSC; unsigned char target, lun; unsigned int *sync_neg; int i, tmp; @@ -1532,7 +1531,7 @@ nsp_proc_info( /*---------------------------------------------------------------*/ /* -static int nsp_eh_abort(struct scsi_cmnd *SCpnt) +static int nsp_eh_abort(Scsi_Cmnd *SCpnt) { nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt); @@ -1560,7 +1559,7 @@ static int nsp_bus_reset(nsp_hw_data *data) return SUCCESS; } -static int nsp_eh_bus_reset(struct scsi_cmnd *SCpnt) +static int nsp_eh_bus_reset(Scsi_Cmnd *SCpnt) { nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; @@ -1569,7 +1568,7 @@ static int nsp_eh_bus_reset(struct scsi_cmnd *SCpnt) return nsp_bus_reset(data); } -static int nsp_eh_host_reset(struct scsi_cmnd *SCpnt) +static int nsp_eh_host_reset(Scsi_Cmnd *SCpnt) { nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; diff --git a/trunk/drivers/scsi/pcmcia/nsp_cs.h b/trunk/drivers/scsi/pcmcia/nsp_cs.h index 625ca97da52d..8908b8e5b78a 100644 --- a/trunk/drivers/scsi/pcmcia/nsp_cs.h +++ b/trunk/drivers/scsi/pcmcia/nsp_cs.h @@ -266,7 +266,7 @@ typedef struct _nsp_hw_data { int TimerCount; int SelectionTimeOut; - struct scsi_cmnd *CurrentSC; + Scsi_Cmnd *CurrentSC; //int CurrnetTarget; int FifoCount; @@ -319,38 +319,34 @@ static int nsp_proc_info ( int hostno, #endif int inout); -static int nsp_queuecommand(struct scsi_cmnd *SCpnt, - void (* done)(struct scsi_cmnd *SCpnt)); +static int nsp_queuecommand(Scsi_Cmnd *SCpnt, void (* done)(Scsi_Cmnd *SCpnt)); /* Error handler */ -/*static int nsp_eh_abort (struct scsi_cmnd *SCpnt);*/ -/*static int nsp_eh_device_reset(struct scsi_cmnd *SCpnt);*/ -static int nsp_eh_bus_reset (struct scsi_cmnd *SCpnt); -static int nsp_eh_host_reset (struct scsi_cmnd *SCpnt); +/*static int nsp_eh_abort (Scsi_Cmnd *SCpnt);*/ +/*static int nsp_eh_device_reset(Scsi_Cmnd *SCpnt);*/ +static int nsp_eh_bus_reset (Scsi_Cmnd *SCpnt); +static int nsp_eh_host_reset (Scsi_Cmnd *SCpnt); static int nsp_bus_reset (nsp_hw_data *data); /* */ static int nsphw_init (nsp_hw_data *data); -static int nsphw_start_selection(struct scsi_cmnd *SCpnt); -static void nsp_start_timer (struct scsi_cmnd *SCpnt, int time); -static int nsp_fifo_count (struct scsi_cmnd *SCpnt); -static void nsp_pio_read (struct scsi_cmnd *SCpnt); -static void nsp_pio_write (struct scsi_cmnd *SCpnt); -static int nsp_nexus (struct scsi_cmnd *SCpnt); -static void nsp_scsi_done (struct scsi_cmnd *SCpnt); -static int nsp_analyze_sdtr (struct scsi_cmnd *SCpnt); -static int nsp_negate_signal (struct scsi_cmnd *SCpnt, - unsigned char mask, char *str); -static int nsp_expect_signal (struct scsi_cmnd *SCpnt, - unsigned char current_phase, - unsigned char mask); -static int nsp_xfer (struct scsi_cmnd *SCpnt, int phase); -static int nsp_dataphase_bypass (struct scsi_cmnd *SCpnt); -static int nsp_reselected (struct scsi_cmnd *SCpnt); +static int nsphw_start_selection(Scsi_Cmnd *SCpnt); +static void nsp_start_timer (Scsi_Cmnd *SCpnt, int time); +static int nsp_fifo_count (Scsi_Cmnd *SCpnt); +static void nsp_pio_read (Scsi_Cmnd *SCpnt); +static void nsp_pio_write (Scsi_Cmnd *SCpnt); +static int nsp_nexus (Scsi_Cmnd *SCpnt); +static void nsp_scsi_done (Scsi_Cmnd *SCpnt); +static int nsp_analyze_sdtr (Scsi_Cmnd *SCpnt); +static int nsp_negate_signal (Scsi_Cmnd *SCpnt, unsigned char mask, char *str); +static int nsp_expect_signal (Scsi_Cmnd *SCpnt, unsigned char current_phase, unsigned char mask); +static int nsp_xfer (Scsi_Cmnd *SCpnt, int phase); +static int nsp_dataphase_bypass (Scsi_Cmnd *SCpnt); +static int nsp_reselected (Scsi_Cmnd *SCpnt); static struct Scsi_Host *nsp_detect(struct scsi_host_template *sht); /* Interrupt handler */ -//static irqreturn_t nspintr(int irq, void *dev_id); +//static irqreturn_t nspintr(int irq, void *dev_id, struct pt_regs *regs); /* Module entry point*/ static int __init nsp_cs_init(void); @@ -359,8 +355,8 @@ static void __exit nsp_cs_exit(void); /* Debug */ #ifdef NSP_DEBUG -static void show_command (struct scsi_cmnd *SCpnt); -static void show_phase (struct scsi_cmnd *SCpnt); +static void show_command (Scsi_Cmnd *SCpnt); +static void show_phase (Scsi_Cmnd *SCpnt); static void show_busphase(unsigned char stat); static void show_message (nsp_hw_data *data); #else diff --git a/trunk/drivers/scsi/pcmcia/nsp_debug.c b/trunk/drivers/scsi/pcmcia/nsp_debug.c index 2f75fe6e35a7..62e5c60067fd 100644 --- a/trunk/drivers/scsi/pcmcia/nsp_debug.c +++ b/trunk/drivers/scsi/pcmcia/nsp_debug.c @@ -138,12 +138,12 @@ static void print_commandk (unsigned char *command) printk("\n"); } -static void show_command(struct scsi_cmnd *SCpnt) +static void show_command(Scsi_Cmnd *SCpnt) { print_commandk(SCpnt->cmnd); } -static void show_phase(struct scsi_cmnd *SCpnt) +static void show_phase(Scsi_Cmnd *SCpnt) { int i = SCpnt->SCp.phase; diff --git a/trunk/drivers/scsi/pcmcia/nsp_message.c b/trunk/drivers/scsi/pcmcia/nsp_message.c index ef593b70d0f0..d7057737ff34 100644 --- a/trunk/drivers/scsi/pcmcia/nsp_message.c +++ b/trunk/drivers/scsi/pcmcia/nsp_message.c @@ -8,7 +8,7 @@ /* $Id: nsp_message.c,v 1.6 2003/07/26 14:21:09 elca Exp $ */ -static void nsp_message_in(struct scsi_cmnd *SCpnt) +static void nsp_message_in(Scsi_Cmnd *SCpnt) { unsigned int base = SCpnt->device->host->io_port; nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; @@ -50,7 +50,7 @@ static void nsp_message_in(struct scsi_cmnd *SCpnt) } -static void nsp_message_out(struct scsi_cmnd *SCpnt) +static void nsp_message_out(Scsi_Cmnd *SCpnt) { nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; int ret = 1; diff --git a/trunk/drivers/scsi/pcmcia/sym53c500_cs.c b/trunk/drivers/scsi/pcmcia/sym53c500_cs.c index 72fe5d055de1..0b65099acb1a 100644 --- a/trunk/drivers/scsi/pcmcia/sym53c500_cs.c +++ b/trunk/drivers/scsi/pcmcia/sym53c500_cs.c @@ -363,7 +363,7 @@ SYM53C500_pio_write(int fast_pio, int base, unsigned char *request, unsigned int } static irqreturn_t -SYM53C500_intr(int irq, void *dev_id) +SYM53C500_intr(int irq, void *dev_id, struct pt_regs *regs) { unsigned long flags; struct Scsi_Host *dev = dev_id; diff --git a/trunk/drivers/scsi/ppa.c b/trunk/drivers/scsi/ppa.c index 89a2a9f11e41..b0eba39f208a 100644 --- a/trunk/drivers/scsi/ppa.c +++ b/trunk/drivers/scsi/ppa.c @@ -1012,7 +1012,7 @@ static LIST_HEAD(ppa_hosts); static int __ppa_attach(struct parport *pb) { struct Scsi_Host *host; - DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waiting); + DECLARE_WAIT_QUEUE_HEAD(waiting); DEFINE_WAIT(wait); ppa_struct *dev; int ports; diff --git a/trunk/drivers/scsi/psi240i.c b/trunk/drivers/scsi/psi240i.c index 899e89d6fe67..5c2cdf523c3b 100644 --- a/trunk/drivers/scsi/psi240i.c +++ b/trunk/drivers/scsi/psi240i.c @@ -87,11 +87,11 @@ typedef struct { USHORT ports[13]; OUR_DEVICE device[8]; - struct scsi_cmnd *pSCmnd; + Scsi_Cmnd *pSCmnd; IDE_STRUCT ide; ULONG startSector; USHORT sectorCount; - struct scsi_cmnd *SCpnt; + Scsi_Cmnd *SCpnt; VOID *buffer; USHORT expectingIRQ; } ADAPTER240I, *PADAPTER240I; @@ -247,18 +247,19 @@ static ULONG DecodeError (struct Scsi_Host *pshost, UCHAR status) * * Parameters: irq - Hardware IRQ number. * dev_id - + * regs - * * Returns: TRUE if drive is not ready in time. * ****************************************************************/ -static void Irq_Handler (int irq, void *dev_id) +static void Irq_Handler (int irq, void *dev_id, struct pt_regs *regs) { - struct Scsi_Host *shost; // Pointer to host data block - PADAPTER240I padapter; // Pointer to adapter control structure - USHORT *pports; // I/O port array - struct scsi_cmnd *SCpnt; - UCHAR status; - int z; + struct Scsi_Host *shost; // Pointer to host data block + PADAPTER240I padapter; // Pointer to adapter control structure + USHORT *pports; // I/O port array + Scsi_Cmnd *SCpnt; + UCHAR status; + int z; DEB(printk ("\npsi240i received interrupt\n")); @@ -328,7 +329,7 @@ static void Irq_Handler (int irq, void *dev_id) pinquiryData->AdditionalLength = 35 - 4; // Fill in vendor identification fields. - for ( z = 0; z < 8; z += 2 ) + for ( z = 0; z < 20; z += 2 ) { pinquiryData->VendorId[z] = ((UCHAR *)identifyData.ModelNumber)[z + 1]; pinquiryData->VendorId[z + 1] = ((UCHAR *)identifyData.ModelNumber)[z]; @@ -367,13 +368,13 @@ irqerror:; SCpnt->scsi_done (SCpnt); } -static irqreturn_t do_Irq_Handler (int irq, void *dev_id) +static irqreturn_t do_Irq_Handler (int irq, void *dev_id, struct pt_regs *regs) { unsigned long flags; struct Scsi_Host *dev = dev_id; spin_lock_irqsave(dev->host_lock, flags); - Irq_Handler(irq, dev_id); + Irq_Handler(irq, dev_id, regs); spin_unlock_irqrestore(dev->host_lock, flags); return IRQ_HANDLED; } @@ -389,17 +390,12 @@ static irqreturn_t do_Irq_Handler (int irq, void *dev_id) * Returns: Status code. * ****************************************************************/ -static int Psi240i_QueueCommand(struct scsi_cmnd *SCpnt, - void (*done)(struct scsi_cmnd *)) +static int Psi240i_QueueCommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) { - UCHAR *cdb = (UCHAR *)SCpnt->cmnd; - // Pointer to SCSI CDB - PADAPTER240I padapter = HOSTDATA (SCpnt->device->host); - // Pointer to adapter control structure - POUR_DEVICE pdev = &padapter->device [SCpnt->device->id]; - // Pointer to device information - UCHAR rc; - // command return code + UCHAR *cdb = (UCHAR *)SCpnt->cmnd; // Pointer to SCSI CDB + PADAPTER240I padapter = HOSTDATA (SCpnt->device->host); // Pointer to adapter control structure + POUR_DEVICE pdev = &padapter->device [SCpnt->device->id];// Pointer to device information + UCHAR rc; // command return code SCpnt->scsi_done = done; padapter->ide.ide.ides.spigot = pdev->spigot; diff --git a/trunk/drivers/scsi/psi240i.h b/trunk/drivers/scsi/psi240i.h index 21ebb9214004..6a598766df51 100644 --- a/trunk/drivers/scsi/psi240i.h +++ b/trunk/drivers/scsi/psi240i.h @@ -309,7 +309,7 @@ typedef struct _IDENTIFY_DATA2 { #endif // PSI_EIDE_SCSIOP // function prototypes -int Psi240i_Command(struct scsi_cmnd *SCpnt); -int Psi240i_Abort(struct scsi_cmnd *SCpnt); -int Psi240i_Reset(struct scsi_cmnd *SCpnt, unsigned int flags); +int Psi240i_Command (Scsi_Cmnd *SCpnt); +int Psi240i_Abort (Scsi_Cmnd *SCpnt); +int Psi240i_Reset (Scsi_Cmnd *SCpnt, unsigned int flags); #endif diff --git a/trunk/drivers/scsi/qla1280.c b/trunk/drivers/scsi/qla1280.c index 16af5b79e587..332151e2a018 100644 --- a/trunk/drivers/scsi/qla1280.c +++ b/trunk/drivers/scsi/qla1280.c @@ -931,10 +931,11 @@ qla1280_error_action(struct scsi_cmnd *cmd, enum action action) case BUS_RESET: if (qla1280_verbose) - printk(KERN_INFO "qla1280(%ld:%d): Issued bus " - "reset.\n", ha->host_no, bus); - if (qla1280_bus_reset(ha, bus) == 0) + printk(KERN_INFO "qla1280(%ld:%d): Issuing BUS " + "DEVICE RESET\n", ha->host_no, bus); + if (qla1280_bus_reset(ha, bus == 0)) result = SUCCESS; + break; case ADAPTER_RESET: @@ -1112,7 +1113,7 @@ qla1280_enable_intrs(struct scsi_qla_host *ha) * Handles the H/W interrupt **************************************************************************/ static irqreturn_t -qla1280_intr_handler(int irq, void *dev_id) +qla1280_intr_handler(int irq, void *dev_id, struct pt_regs *regs) { struct scsi_qla_host *ha; struct device_reg __iomem *reg; @@ -2861,7 +2862,7 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp) memset(((char *)pkt + 8), 0, (REQUEST_ENTRY_SIZE - 8)); /* Set ISP command timeout. */ - pkt->timeout = cpu_to_le16(cmd->timeout_per_command/HZ); + pkt->timeout = cpu_to_le16(30); /* Set device target ID and LUN */ pkt->lun = SCSI_LUN_32(cmd); @@ -3160,7 +3161,7 @@ qla1280_32bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp) memset(((char *)pkt + 8), 0, (REQUEST_ENTRY_SIZE - 8)); /* Set ISP command timeout. */ - pkt->timeout = cpu_to_le16(cmd->timeout_per_command/HZ); + pkt->timeout = cpu_to_le16(30); /* Set device target ID and LUN */ pkt->lun = SCSI_LUN_32(cmd); @@ -4483,7 +4484,7 @@ qla1280_init(void) qla1280_setup(qla1280); #endif - return pci_register_driver(&qla1280_pci_driver); + return pci_module_init(&qla1280_pci_driver); } static void __exit diff --git a/trunk/drivers/scsi/qla2xxx/qla_attr.c b/trunk/drivers/scsi/qla2xxx/qla_attr.c index 285c8e8ff1a0..87f90c4f08e9 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_attr.c +++ b/trunk/drivers/scsi/qla2xxx/qla_attr.c @@ -379,37 +379,21 @@ static struct bin_attribute sysfs_sfp_attr = { .read = qla2x00_sysfs_read_sfp, }; -static struct sysfs_entry { - char *name; - struct bin_attribute *attr; - int is4GBp_only; -} bin_file_entries[] = { - { "fw_dump", &sysfs_fw_dump_attr, }, - { "nvram", &sysfs_nvram_attr, }, - { "optrom", &sysfs_optrom_attr, }, - { "optrom_ctl", &sysfs_optrom_ctl_attr, }, - { "vpd", &sysfs_vpd_attr, 1 }, - { "sfp", &sysfs_sfp_attr, 1 }, - { 0 }, -}; - void qla2x00_alloc_sysfs_attr(scsi_qla_host_t *ha) { struct Scsi_Host *host = ha->host; - struct sysfs_entry *iter; - int ret; - - for (iter = bin_file_entries; iter->name; iter++) { - if (iter->is4GBp_only && (!IS_QLA24XX(ha) && !IS_QLA54XX(ha))) - continue; - ret = sysfs_create_bin_file(&host->shost_gendev.kobj, - iter->attr); - if (ret) - qla_printk(KERN_INFO, ha, - "Unable to create sysfs %s binary attribute " - "(%d).\n", iter->name, ret); + sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_fw_dump_attr); + sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_nvram_attr); + sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_optrom_attr); + sysfs_create_bin_file(&host->shost_gendev.kobj, + &sysfs_optrom_ctl_attr); + if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { + sysfs_create_bin_file(&host->shost_gendev.kobj, + &sysfs_vpd_attr); + sysfs_create_bin_file(&host->shost_gendev.kobj, + &sysfs_sfp_attr); } } @@ -417,14 +401,17 @@ void qla2x00_free_sysfs_attr(scsi_qla_host_t *ha) { struct Scsi_Host *host = ha->host; - struct sysfs_entry *iter; - - for (iter = bin_file_entries; iter->name; iter++) { - if (iter->is4GBp_only && (!IS_QLA24XX(ha) && !IS_QLA54XX(ha))) - continue; + sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_fw_dump_attr); + sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_nvram_attr); + sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_optrom_attr); + sysfs_remove_bin_file(&host->shost_gendev.kobj, + &sysfs_optrom_ctl_attr); + if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { sysfs_remove_bin_file(&host->shost_gendev.kobj, - iter->attr); + &sysfs_vpd_attr); + sysfs_remove_bin_file(&host->shost_gendev.kobj, + &sysfs_sfp_attr); } if (ha->beacon_blink_led == 1) @@ -704,13 +691,13 @@ qla2x00_get_host_speed(struct Scsi_Host *shost) uint32_t speed = 0; switch (ha->link_data_rate) { - case PORT_SPEED_1GB: + case LDR_1GB: speed = 1; break; - case PORT_SPEED_2GB: + case LDR_2GB: speed = 2; break; - case PORT_SPEED_4GB: + case LDR_4GB: speed = 4; break; } @@ -862,49 +849,6 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost) return pfc_host_stat; } -static void -qla2x00_get_host_symbolic_name(struct Scsi_Host *shost) -{ - scsi_qla_host_t *ha = to_qla_host(shost); - - qla2x00_get_sym_node_name(ha, fc_host_symbolic_name(shost)); -} - -static void -qla2x00_set_host_system_hostname(struct Scsi_Host *shost) -{ - scsi_qla_host_t *ha = to_qla_host(shost); - - set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags); -} - -static void -qla2x00_get_host_fabric_name(struct Scsi_Host *shost) -{ - scsi_qla_host_t *ha = to_qla_host(shost); - u64 node_name; - - if (ha->device_flags & SWITCH_FOUND) - node_name = wwn_to_u64(ha->fabric_node_name); - else - node_name = wwn_to_u64(ha->node_name); - - fc_host_fabric_name(shost) = node_name; -} - -static void -qla2x00_get_host_port_state(struct Scsi_Host *shost) -{ - scsi_qla_host_t *ha = to_qla_host(shost); - - if (!ha->flags.online) - fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE; - else if (atomic_read(&ha->loop_state) == LOOP_TIMEOUT) - fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN; - else - fc_host_port_state(shost) = FC_PORTSTATE_ONLINE; -} - struct fc_function_template qla2xxx_transport_functions = { .show_host_node_name = 1, @@ -917,14 +861,6 @@ struct fc_function_template qla2xxx_transport_functions = { .show_host_speed = 1, .get_host_port_type = qla2x00_get_host_port_type, .show_host_port_type = 1, - .get_host_symbolic_name = qla2x00_get_host_symbolic_name, - .show_host_symbolic_name = 1, - .set_host_system_hostname = qla2x00_set_host_system_hostname, - .show_host_system_hostname = 1, - .get_host_fabric_name = qla2x00_get_host_fabric_name, - .show_host_fabric_name = 1, - .get_host_port_state = qla2x00_get_host_port_state, - .show_host_port_state = 1, .dd_fcrport_size = sizeof(struct fc_port *), .show_rport_supported_classes = 1, diff --git a/trunk/drivers/scsi/qla2xxx/qla_dbg.h b/trunk/drivers/scsi/qla2xxx/qla_dbg.h index 5b12278968e0..533425338e05 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_dbg.h +++ b/trunk/drivers/scsi/qla2xxx/qla_dbg.h @@ -38,7 +38,7 @@ * Macros use for debugging the driver. */ -#define DEBUG(x) do { if (ql2xextended_error_logging) { x; } } while (0) +#define DEBUG(x) do { if (extended_error_logging) { x; } } while (0) #if defined(QL_DEBUG_LEVEL_1) #define DEBUG1(x) do {x;} while (0) @@ -46,12 +46,12 @@ #define DEBUG1(x) do {} while (0) #endif -#define DEBUG2(x) do { if (ql2xextended_error_logging) { x; } } while (0) -#define DEBUG2_3(x) do { if (ql2xextended_error_logging) { x; } } while (0) -#define DEBUG2_3_11(x) do { if (ql2xextended_error_logging) { x; } } while (0) -#define DEBUG2_9_10(x) do { if (ql2xextended_error_logging) { x; } } while (0) -#define DEBUG2_11(x) do { if (ql2xextended_error_logging) { x; } } while (0) -#define DEBUG2_13(x) do { if (ql2xextended_error_logging) { x; } } while (0) +#define DEBUG2(x) do { if (extended_error_logging) { x; } } while (0) +#define DEBUG2_3(x) do { if (extended_error_logging) { x; } } while (0) +#define DEBUG2_3_11(x) do { if (extended_error_logging) { x; } } while (0) +#define DEBUG2_9_10(x) do { if (extended_error_logging) { x; } } while (0) +#define DEBUG2_11(x) do { if (extended_error_logging) { x; } } while (0) +#define DEBUG2_13(x) do { if (extended_error_logging) { x; } } while (0) #if defined(QL_DEBUG_LEVEL_3) #define DEBUG3(x) do {x;} while (0) diff --git a/trunk/drivers/scsi/qla2xxx/qla_def.h b/trunk/drivers/scsi/qla2xxx/qla_def.h index c4fc40f8e8ca..0930260aec2c 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_def.h +++ b/trunk/drivers/scsi/qla2xxx/qla_def.h @@ -608,7 +608,6 @@ typedef struct { */ #define MBC_SERDES_PARAMS 0x10 /* Serdes Tx Parameters. */ #define MBC_GET_IOCB_STATUS 0x12 /* Get IOCB status command. */ -#define MBC_PORT_PARAMS 0x1A /* Port iDMA Parameters. */ #define MBC_GET_TIMEOUT_PARAMS 0x22 /* Get FW timeouts. */ #define MBC_TRACE_CONTROL 0x27 /* Trace control command. */ #define MBC_GEN_SYSTEM_ERROR 0x2a /* Generate System Error. */ @@ -1498,9 +1497,6 @@ typedef struct { port_id_t d_id; uint8_t node_name[WWN_SIZE]; uint8_t port_name[WWN_SIZE]; - uint8_t fabric_port_name[WWN_SIZE]; - uint16_t fp_speeds; - uint16_t fp_speed; } sw_info_t; /* @@ -1528,9 +1524,6 @@ typedef struct fc_port { uint16_t loop_id; uint16_t old_loop_id; - uint8_t fabric_port_name[WWN_SIZE]; - uint16_t fp_speed; - fc_port_type_t port_type; atomic_t state; @@ -1545,9 +1538,6 @@ typedef struct fc_port { spinlock_t rport_lock; struct fc_rport *rport, *drport; u32 supported_classes; - - unsigned long last_queue_full; - unsigned long last_ramp_up; } fc_port_t; /* @@ -1645,15 +1635,6 @@ typedef struct fc_port { #define RSNN_NN_REQ_SIZE (16 + 8 + 1 + 255) #define RSNN_NN_RSP_SIZE 16 -#define GFPN_ID_CMD 0x11C -#define GFPN_ID_REQ_SIZE (16 + 4) -#define GFPN_ID_RSP_SIZE (16 + 8) - -#define GPSC_CMD 0x127 -#define GPSC_REQ_SIZE (16 + 8) -#define GPSC_RSP_SIZE (16 + 2 + 2) - - /* * HBA attribute types. */ @@ -1767,7 +1748,7 @@ struct ct_sns_req { uint8_t reserved[3]; union { - /* GA_NXT, GPN_ID, GNN_ID, GFT_ID, GFPN_ID */ + /* GA_NXT, GPN_ID, GNN_ID, GFT_ID */ struct { uint8_t reserved; uint8_t port_id[3]; @@ -1842,10 +1823,6 @@ struct ct_sns_req { struct { uint8_t port_name[8]; } dpa; - - struct { - uint8_t port_name[8]; - } gpsc; } req; }; @@ -1909,15 +1886,6 @@ struct ct_sns_rsp { uint8_t port_name[8]; struct ct_fdmi_hba_attributes attrs; } ghat; - - struct { - uint8_t port_name[8]; - } gfpn_id; - - struct { - uint16_t speeds; - uint16_t speed; - } gpsc; } rsp; }; @@ -2012,7 +1980,7 @@ struct isp_operations { char * (*pci_info_str) (struct scsi_qla_host *, char *); char * (*fw_version_str) (struct scsi_qla_host *, char *); - irq_handler_t intr_handler; + irqreturn_t (*intr_handler) (int, void *, struct pt_regs *); void (*enable_intrs) (struct scsi_qla_host *); void (*disable_intrs) (struct scsi_qla_host *); @@ -2214,11 +2182,11 @@ typedef struct scsi_qla_host { uint16_t max_public_loop_ids; uint16_t min_external_loopid; /* First external loop Id */ -#define PORT_SPEED_UNKNOWN 0xFFFF -#define PORT_SPEED_1GB 0x00 -#define PORT_SPEED_2GB 0x01 -#define PORT_SPEED_4GB 0x03 uint16_t link_data_rate; /* F/W operating speed */ +#define LDR_1GB 0 +#define LDR_2GB 1 +#define LDR_4GB 3 +#define LDR_UNKNOWN 0xFFFF uint8_t current_topology; uint8_t prev_topology; @@ -2258,7 +2226,6 @@ typedef struct scsi_qla_host { uint16_t mgmt_svr_loop_id; uint32_t login_retry_count; - int max_q_depth; /* Fibre Channel Device List. */ struct list_head fcports; @@ -2366,7 +2333,6 @@ typedef struct scsi_qla_host { uint8_t *node_name; uint8_t *port_name; - uint8_t fabric_node_name[WWN_SIZE]; uint32_t isp_abort_cnt; /* Option ROM information. */ diff --git a/trunk/drivers/scsi/qla2xxx/qla_gbl.h b/trunk/drivers/scsi/qla2xxx/qla_gbl.h index 32ebeec45ff0..8311ac2b93a8 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_gbl.h +++ b/trunk/drivers/scsi/qla2xxx/qla_gbl.h @@ -48,7 +48,6 @@ extern void qla2x00_update_fcport(scsi_qla_host_t *, fc_port_t *); extern void qla2x00_reg_remote_port(scsi_qla_host_t *, fc_port_t *); extern void qla2x00_alloc_fw_dump(scsi_qla_host_t *); -extern void qla2x00_try_to_stop_firmware(scsi_qla_host_t *); /* * Global Data in qla_os.c source file. @@ -61,8 +60,7 @@ extern int ql2xplogiabsentdevice; extern int ql2xloginretrycount; extern int ql2xfdmienable; extern int ql2xallocfwdump; -extern int ql2xextended_error_logging; -extern int ql2xqfullrampup; +extern int extended_error_logging; extern void qla2x00_sp_compl(scsi_qla_host_t *, srb_t *); @@ -210,18 +208,12 @@ qla2x00_trace_control(scsi_qla_host_t *, uint16_t, dma_addr_t, uint16_t); extern int qla2x00_read_sfp(scsi_qla_host_t *, dma_addr_t, uint16_t, uint16_t, uint16_t); -extern int -qla2x00_get_idma_speed(scsi_qla_host_t *, uint16_t, uint16_t *, uint16_t *); - -extern int -qla2x00_set_idma_speed(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t *); - /* * Global Function Prototypes in qla_isr.c source file. */ -extern irqreturn_t qla2100_intr_handler(int, void *); -extern irqreturn_t qla2300_intr_handler(int, void *); -extern irqreturn_t qla24xx_intr_handler(int, void *); +extern irqreturn_t qla2100_intr_handler(int, void *, struct pt_regs *); +extern irqreturn_t qla2300_intr_handler(int, void *, struct pt_regs *); +extern irqreturn_t qla24xx_intr_handler(int, void *, struct pt_regs *); extern void qla2x00_process_response_queue(struct scsi_qla_host *); extern void qla24xx_process_response_queue(struct scsi_qla_host *); @@ -287,9 +279,6 @@ extern int qla2x00_rsnn_nn(scsi_qla_host_t *); extern void *qla2x00_prep_ms_fdmi_iocb(scsi_qla_host_t *, uint32_t, uint32_t); extern void *qla24xx_prep_ms_fdmi_iocb(scsi_qla_host_t *, uint32_t, uint32_t); extern int qla2x00_fdmi_register(scsi_qla_host_t *); -extern int qla2x00_gfpn_id(scsi_qla_host_t *, sw_info_t *); -extern int qla2x00_gpsc(scsi_qla_host_t *, sw_info_t *); -extern void qla2x00_get_sym_node_name(scsi_qla_host_t *, uint8_t *); /* * Global Function Prototypes in qla_attr.c source file. diff --git a/trunk/drivers/scsi/qla2xxx/qla_gs.c b/trunk/drivers/scsi/qla2xxx/qla_gs.c index 97fbc62ec669..2ebf259fccb2 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_gs.c +++ b/trunk/drivers/scsi/qla2xxx/qla_gs.c @@ -612,14 +612,6 @@ qla2x00_rnn_id(scsi_qla_host_t *ha) return (rval); } -void -qla2x00_get_sym_node_name(scsi_qla_host_t *ha, uint8_t *snn) -{ - sprintf(snn, "%s FW:v%d.%02d.%02d DVR:v%s",ha->model_number, - ha->fw_major_version, ha->fw_minor_version, - ha->fw_subminor_version, qla2x00_version_str); -} - /** * qla2x00_rsnn_nn() - SNS Register Symbolic Node Name (RSNN_NN) of the HBA. * @ha: HA context @@ -630,6 +622,9 @@ int qla2x00_rsnn_nn(scsi_qla_host_t *ha) { int rval; + uint8_t *snn; + uint8_t version[20]; + ms_iocb_entry_t *ms_pkt; struct ct_sns_req *ct_req; struct ct_sns_rsp *ct_rsp; @@ -654,11 +649,20 @@ qla2x00_rsnn_nn(scsi_qla_host_t *ha) memcpy(ct_req->req.rsnn_nn.node_name, ha->node_name, WWN_SIZE); /* Prepare the Symbolic Node Name */ - qla2x00_get_sym_node_name(ha, ct_req->req.rsnn_nn.sym_node_name); + /* Board type */ + snn = ct_req->req.rsnn_nn.sym_node_name; + strcpy(snn, ha->model_number); + /* Firmware version */ + strcat(snn, " FW:v"); + sprintf(version, "%d.%02d.%02d", ha->fw_major_version, + ha->fw_minor_version, ha->fw_subminor_version); + strcat(snn, version); + /* Driver version */ + strcat(snn, " DVR:v"); + strcat(snn, qla2x00_version_str); /* Calculate SNN length */ - ct_req->req.rsnn_nn.name_len = - (uint8_t)strlen(ct_req->req.rsnn_nn.sym_node_name); + ct_req->req.rsnn_nn.name_len = (uint8_t)strlen(snn); /* Update MS IOCB request */ ms_pkt->req_bytecount = @@ -683,6 +687,7 @@ qla2x00_rsnn_nn(scsi_qla_host_t *ha) return (rval); } + /** * qla2x00_prep_sns_cmd() - Prepare common SNS command request fields for query. * @ha: HA context @@ -1580,21 +1585,6 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *ha) DEBUG13(printk("%s(%ld): OS_DEVICE_NAME=%s.\n", __func__, ha->host_no, eiter->a.os_dev_name)); - /* Hostname. */ - if (strlen(fc_host_system_hostname(ha->host))) { - eiter = (struct ct_fdmi_port_attr *) (entries + size); - eiter->type = __constant_cpu_to_be16(FDMI_PORT_HOST_NAME); - snprintf(eiter->a.host_name, sizeof(eiter->a.host_name), - "%s", fc_host_system_hostname(ha->host)); - alen = strlen(eiter->a.host_name); - alen += (alen & 3) ? (4 - (alen & 3)) : 4; - eiter->len = cpu_to_be16(4 + alen); - size += 4 + alen; - - DEBUG13(printk("%s(%ld): HOSTNAME=%s.\n", __func__, - ha->host_no, eiter->a.host_name)); - } - /* Update MS request size. */ qla2x00_update_ms_fdmi_iocb(ha, size + 16); @@ -1657,189 +1647,3 @@ qla2x00_fdmi_register(scsi_qla_host_t *ha) return rval; } - -/** - * qla2x00_gfpn_id() - SNS Get Fabric Port Name (GFPN_ID) query. - * @ha: HA context - * @list: switch info entries to populate - * - * Returns 0 on success. - */ -int -qla2x00_gfpn_id(scsi_qla_host_t *ha, sw_info_t *list) -{ - int rval; - uint16_t i; - - ms_iocb_entry_t *ms_pkt; - struct ct_sns_req *ct_req; - struct ct_sns_rsp *ct_rsp; - - if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)) - return QLA_FUNCTION_FAILED; - - for (i = 0; i < MAX_FIBRE_DEVICES; i++) { - /* Issue GFPN_ID */ - memset(list[i].fabric_port_name, 0, WWN_SIZE); - - /* Prepare common MS IOCB */ - ms_pkt = qla2x00_prep_ms_iocb(ha, GFPN_ID_REQ_SIZE, - GFPN_ID_RSP_SIZE); - - /* Prepare CT request */ - ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GFPN_ID_CMD, - GFPN_ID_RSP_SIZE); - ct_rsp = &ha->ct_sns->p.rsp; - - /* Prepare CT arguments -- port_id */ - ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain; - ct_req->req.port_id.port_id[1] = list[i].d_id.b.area; - ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa; - - /* Execute MS IOCB */ - rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma, - sizeof(ms_iocb_entry_t)); - if (rval != QLA_SUCCESS) { - /*EMPTY*/ - DEBUG2_3(printk("scsi(%ld): GFPN_ID issue IOCB " - "failed (%d).\n", ha->host_no, rval)); - } else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp, - "GFPN_ID") != QLA_SUCCESS) { - rval = QLA_FUNCTION_FAILED; - } else { - /* Save fabric portname */ - memcpy(list[i].fabric_port_name, - ct_rsp->rsp.gfpn_id.port_name, WWN_SIZE); - } - - /* Last device exit. */ - if (list[i].d_id.b.rsvd_1 != 0) - break; - } - - return (rval); -} - -static inline void * -qla24xx_prep_ms_fm_iocb(scsi_qla_host_t *ha, uint32_t req_size, - uint32_t rsp_size) -{ - struct ct_entry_24xx *ct_pkt; - - ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb; - memset(ct_pkt, 0, sizeof(struct ct_entry_24xx)); - - ct_pkt->entry_type = CT_IOCB_TYPE; - ct_pkt->entry_count = 1; - ct_pkt->nport_handle = cpu_to_le16(ha->mgmt_svr_loop_id); - ct_pkt->timeout = __constant_cpu_to_le16(59); - ct_pkt->cmd_dsd_count = __constant_cpu_to_le16(1); - ct_pkt->rsp_dsd_count = __constant_cpu_to_le16(1); - ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size); - ct_pkt->cmd_byte_count = cpu_to_le32(req_size); - - ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); - ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); - ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count; - - ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); - ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); - ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count; - - return ct_pkt; -} - - -static inline struct ct_sns_req * -qla24xx_prep_ct_fm_req(struct ct_sns_req *ct_req, uint16_t cmd, - uint16_t rsp_size) -{ - memset(ct_req, 0, sizeof(struct ct_sns_pkt)); - - ct_req->header.revision = 0x01; - ct_req->header.gs_type = 0xFA; - ct_req->header.gs_subtype = 0x01; - ct_req->command = cpu_to_be16(cmd); - ct_req->max_rsp_size = cpu_to_be16((rsp_size - 16) / 4); - - return ct_req; -} - -/** - * qla2x00_gpsc() - FCS Get Port Speed Capabilities (GPSC) query. - * @ha: HA context - * @list: switch info entries to populate - * - * Returns 0 on success. - */ -int -qla2x00_gpsc(scsi_qla_host_t *ha, sw_info_t *list) -{ - int rval; - uint16_t i; - - ms_iocb_entry_t *ms_pkt; - struct ct_sns_req *ct_req; - struct ct_sns_rsp *ct_rsp; - - if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)) - return QLA_FUNCTION_FAILED; - - rval = qla2x00_mgmt_svr_login(ha); - if (rval) - return rval; - - for (i = 0; i < MAX_FIBRE_DEVICES; i++) { - /* Issue GFPN_ID */ - list[i].fp_speeds = list[i].fp_speed = 0; - - /* Prepare common MS IOCB */ - ms_pkt = qla24xx_prep_ms_fm_iocb(ha, GPSC_REQ_SIZE, - GPSC_RSP_SIZE); - - /* Prepare CT request */ - ct_req = qla24xx_prep_ct_fm_req(&ha->ct_sns->p.req, - GPSC_CMD, GPSC_RSP_SIZE); - ct_rsp = &ha->ct_sns->p.rsp; - - /* Prepare CT arguments -- port_name */ - memcpy(ct_req->req.gpsc.port_name, list[i].fabric_port_name, - WWN_SIZE); - - /* Execute MS IOCB */ - rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma, - sizeof(ms_iocb_entry_t)); - if (rval != QLA_SUCCESS) { - /*EMPTY*/ - DEBUG2_3(printk("scsi(%ld): GPSC issue IOCB " - "failed (%d).\n", ha->host_no, rval)); - } else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp, - "GPSC") != QLA_SUCCESS) { - rval = QLA_FUNCTION_FAILED; - } else { - /* Save portname */ - list[i].fp_speeds = ct_rsp->rsp.gpsc.speeds; - list[i].fp_speed = ct_rsp->rsp.gpsc.speed; - - DEBUG2_3(printk("scsi(%ld): GPSC ext entry - " - "fpn %02x%02x%02x%02x%02x%02x%02x%02x speeds=%04x " - "speed=%04x.\n", ha->host_no, - list[i].fabric_port_name[0], - list[i].fabric_port_name[1], - list[i].fabric_port_name[2], - list[i].fabric_port_name[3], - list[i].fabric_port_name[4], - list[i].fabric_port_name[5], - list[i].fabric_port_name[6], - list[i].fabric_port_name[7], - be16_to_cpu(list[i].fp_speeds), - be16_to_cpu(list[i].fp_speed))); - } - - /* Last device exit. */ - if (list[i].d_id.b.rsvd_1 != 0) - break; - } - - return (rval); -} diff --git a/trunk/drivers/scsi/qla2xxx/qla_init.c b/trunk/drivers/scsi/qla2xxx/qla_init.c index 08cb5e3fb553..859649160caa 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_init.c +++ b/trunk/drivers/scsi/qla2xxx/qla_init.c @@ -1644,7 +1644,7 @@ qla2x00_nvram_config(scsi_qla_host_t *ha) * Set host adapter parameters. */ if (nv->host_p[0] & BIT_7) - ql2xextended_error_logging = 1; + extended_error_logging = 1; ha->flags.disable_risc_code_load = ((nv->host_p[0] & BIT_4) ? 1 : 0); /* Always load RISC code on non ISP2[12]00 chips. */ if (!IS_QLA2100(ha) && !IS_QLA2200(ha)) @@ -2074,19 +2074,6 @@ qla2x00_configure_local_loop(scsi_qla_host_t *ha) new_fcport->flags &= ~FCF_FABRIC_DEVICE; } - /* Base iIDMA settings on HBA port speed. */ - switch (ha->link_data_rate) { - case PORT_SPEED_1GB: - fcport->fp_speed = cpu_to_be16(BIT_15); - break; - case PORT_SPEED_2GB: - fcport->fp_speed = cpu_to_be16(BIT_14); - break; - case PORT_SPEED_4GB: - fcport->fp_speed = cpu_to_be16(BIT_13); - break; - } - qla2x00_update_fcport(ha, fcport); found_devs++; @@ -2122,62 +2109,6 @@ qla2x00_probe_for_all_luns(scsi_qla_host_t *ha) } } -static void -qla2x00_iidma_fcport(scsi_qla_host_t *ha, fc_port_t *fcport) -{ -#define LS_UNKNOWN 2 - static char *link_speeds[5] = { "1", "2", "?", "4" }; - int rval; - uint16_t port_speed, mb[6]; - - if (!IS_QLA24XX(ha)) - return; - - switch (be16_to_cpu(fcport->fp_speed)) { - case BIT_15: - port_speed = PORT_SPEED_1GB; - break; - case BIT_14: - port_speed = PORT_SPEED_2GB; - break; - case BIT_13: - port_speed = PORT_SPEED_4GB; - break; - default: - DEBUG2(printk("scsi(%ld): %02x%02x%02x%02x%02x%02x%02x%02x -- " - "unsupported FM port operating speed (%04x).\n", - ha->host_no, fcport->port_name[0], fcport->port_name[1], - fcport->port_name[2], fcport->port_name[3], - fcport->port_name[4], fcport->port_name[5], - fcport->port_name[6], fcport->port_name[7], - be16_to_cpu(fcport->fp_speed))); - port_speed = PORT_SPEED_UNKNOWN; - break; - } - if (port_speed == PORT_SPEED_UNKNOWN) - return; - - rval = qla2x00_set_idma_speed(ha, fcport->loop_id, port_speed, mb); - if (rval != QLA_SUCCESS) { - DEBUG2(printk("scsi(%ld): Unable to adjust iIDMA " - "%02x%02x%02x%02x%02x%02x%02x%02x -- %04x %x %04x %04x.\n", - ha->host_no, fcport->port_name[0], fcport->port_name[1], - fcport->port_name[2], fcport->port_name[3], - fcport->port_name[4], fcport->port_name[5], - fcport->port_name[6], fcport->port_name[7], rval, - port_speed, mb[0], mb[1])); - } else { - DEBUG2(qla_printk(KERN_INFO, ha, - "iIDMA adjusted to %s GB/s on " - "%02x%02x%02x%02x%02x%02x%02x%02x.\n", - link_speeds[port_speed], fcport->port_name[0], - fcport->port_name[1], fcport->port_name[2], - fcport->port_name[3], fcport->port_name[4], - fcport->port_name[5], fcport->port_name[6], - fcport->port_name[7])); - } -} - /* * qla2x00_update_fcport * Updates device on list. @@ -2204,8 +2135,6 @@ qla2x00_update_fcport(scsi_qla_host_t *ha, fc_port_t *fcport) PORT_RETRY_TIME); fcport->flags &= ~FCF_LOGIN_NEEDED; - qla2x00_iidma_fcport(ha, fcport); - atomic_set(&fcport->state, FCS_ONLINE); if (ha->flags.init_done) @@ -2280,7 +2209,7 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha) loop_id = NPH_F_PORT; else loop_id = SNS_FL_PORT; - rval = qla2x00_get_port_name(ha, loop_id, ha->fabric_node_name, 1); + rval = qla2x00_get_port_name(ha, loop_id, NULL, 0); if (rval != QLA_SUCCESS) { DEBUG2(printk("scsi(%ld): MBC_GET_PORT_NAME Failed, No FL " "Port\n", ha->host_no)); @@ -2288,7 +2217,6 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha) ha->device_flags &= ~SWITCH_FOUND; return (QLA_SUCCESS); } - ha->device_flags |= SWITCH_FOUND; /* Mark devices that need re-synchronization. */ rval2 = qla2x00_device_resync(ha); @@ -2488,8 +2416,6 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports) } else if (qla2x00_gnn_id(ha, swl) != QLA_SUCCESS) { kfree(swl); swl = NULL; - } else if (qla2x00_gfpn_id(ha, swl) == QLA_SUCCESS) { - qla2x00_gpsc(ha, swl); } } swl_idx = 0; @@ -2524,9 +2450,6 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports) swl[swl_idx].node_name, WWN_SIZE); memcpy(new_fcport->port_name, swl[swl_idx].port_name, WWN_SIZE); - memcpy(new_fcport->fabric_port_name, - swl[swl_idx].fabric_port_name, WWN_SIZE); - new_fcport->fp_speed = swl[swl_idx].fp_speed; if (swl[swl_idx].d_id.b.rsvd_1 != 0) { last_dev = 1; @@ -2584,11 +2507,6 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports) found++; - /* Update port state. */ - memcpy(fcport->fabric_port_name, - new_fcport->fabric_port_name, WWN_SIZE); - fcport->fp_speed = new_fcport->fp_speed; - /* * If address the same and state FCS_ONLINE, nothing * changed. @@ -3948,24 +3866,3 @@ qla24xx_load_risc(scsi_qla_host_t *ha, uint32_t *srisc_addr) fail_fw_integrity: return QLA_FUNCTION_FAILED; } - -void -qla2x00_try_to_stop_firmware(scsi_qla_host_t *ha) -{ - int ret, retries; - - if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)) - return; - - ret = qla2x00_stop_firmware(ha); - for (retries = 5; ret != QLA_SUCCESS && retries ; retries--) { - qla2x00_reset_chip(ha); - if (qla2x00_chip_diag(ha) != QLA_SUCCESS) - continue; - if (qla2x00_setup_chip(ha) != QLA_SUCCESS) - continue; - qla_printk(KERN_INFO, ha, - "Attempting retry of stop-firmware command...\n"); - ret = qla2x00_stop_firmware(ha); - } -} diff --git a/trunk/drivers/scsi/qla2xxx/qla_inline.h b/trunk/drivers/scsi/qla2xxx/qla_inline.h index d3023338628f..45007ee58067 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_inline.h +++ b/trunk/drivers/scsi/qla2xxx/qla_inline.h @@ -104,7 +104,7 @@ static __inline__ void qla2x00_poll(scsi_qla_host_t *); static inline void qla2x00_poll(scsi_qla_host_t *ha) { - ha->isp_ops.intr_handler(0, ha); + ha->isp_ops.intr_handler(0, ha, NULL); } static __inline__ void qla2x00_check_fabric_devices(scsi_qla_host_t *); diff --git a/trunk/drivers/scsi/qla2xxx/qla_isr.c b/trunk/drivers/scsi/qla2xxx/qla_isr.c index d3b6df4d55c8..de0613135f70 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_isr.c +++ b/trunk/drivers/scsi/qla2xxx/qla_isr.c @@ -6,8 +6,6 @@ */ #include "qla_def.h" -#include - static void qla2x00_mbx_completion(scsi_qla_host_t *, uint16_t); static void qla2x00_async_event(scsi_qla_host_t *, uint16_t *); static void qla2x00_process_completed_request(struct scsi_qla_host *, uint32_t); @@ -22,13 +20,14 @@ static void qla24xx_ms_entry(scsi_qla_host_t *, struct ct_entry_24xx *); * qla2100_intr_handler() - Process interrupts for the ISP2100 and ISP2200. * @irq: * @dev_id: SCSI driver HA context + * @regs: * * Called by system whenever the host adapter generates an interrupt. * * Returns handled flag. */ irqreturn_t -qla2100_intr_handler(int irq, void *dev_id) +qla2100_intr_handler(int irq, void *dev_id, struct pt_regs *regs) { scsi_qla_host_t *ha; struct device_reg_2xxx __iomem *reg; @@ -101,13 +100,14 @@ qla2100_intr_handler(int irq, void *dev_id) * qla2300_intr_handler() - Process interrupts for the ISP23xx and ISP63xx. * @irq: * @dev_id: SCSI driver HA context + * @regs: * * Called by system whenever the host adapter generates an interrupt. * * Returns handled flag. */ irqreturn_t -qla2300_intr_handler(int irq, void *dev_id) +qla2300_intr_handler(int irq, void *dev_id, struct pt_regs *regs) { scsi_qla_host_t *ha; struct device_reg_2xxx __iomem *reg; @@ -400,7 +400,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) case MBA_LOOP_UP: /* Loop Up Event */ if (IS_QLA2100(ha) || IS_QLA2200(ha)) { link_speed = link_speeds[0]; - ha->link_data_rate = PORT_SPEED_1GB; + ha->link_data_rate = LDR_1GB; } else { link_speed = link_speeds[LS_UNKNOWN]; if (mb[1] < 5) @@ -429,7 +429,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) } ha->flags.management_server_logged_in = 0; - ha->link_data_rate = PORT_SPEED_UNKNOWN; + ha->link_data_rate = LDR_UNKNOWN; if (ql2xfdmienable) set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags); break; @@ -595,67 +595,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) } } -static void -qla2x00_adjust_sdev_qdepth_up(struct scsi_device *sdev, void *data) -{ - fc_port_t *fcport = data; - - if (fcport->ha->max_q_depth <= sdev->queue_depth) - return; - - if (sdev->ordered_tags) - scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, - sdev->queue_depth + 1); - else - scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, - sdev->queue_depth + 1); - - fcport->last_ramp_up = jiffies; - - DEBUG2(qla_printk(KERN_INFO, fcport->ha, - "scsi(%ld:%d:%d:%d): Queue depth adjusted-up to %d.\n", - fcport->ha->host_no, sdev->channel, sdev->id, sdev->lun, - sdev->queue_depth)); -} - -static void -qla2x00_adjust_sdev_qdepth_down(struct scsi_device *sdev, void *data) -{ - fc_port_t *fcport = data; - - if (!scsi_track_queue_full(sdev, sdev->queue_depth - 1)) - return; - - DEBUG2(qla_printk(KERN_INFO, fcport->ha, - "scsi(%ld:%d:%d:%d): Queue depth adjusted-down to %d.\n", - fcport->ha->host_no, sdev->channel, sdev->id, sdev->lun, - sdev->queue_depth)); -} - -static inline void -qla2x00_ramp_up_queue_depth(scsi_qla_host_t *ha, srb_t *sp) -{ - fc_port_t *fcport; - struct scsi_device *sdev; - - sdev = sp->cmd->device; - if (sdev->queue_depth >= ha->max_q_depth) - return; - - fcport = sp->fcport; - if (time_before(jiffies, - fcport->last_ramp_up + ql2xqfullrampup * HZ)) - return; - if (time_before(jiffies, - fcport->last_queue_full + ql2xqfullrampup * HZ)) - return; - - spin_unlock_irq(&ha->hardware_lock); - starget_for_each_device(sdev->sdev_target, fcport, - qla2x00_adjust_sdev_qdepth_up); - spin_lock_irq(&ha->hardware_lock); -} - /** * qla2x00_process_completed_request() - Process a Fast Post response. * @ha: SCSI driver HA context @@ -687,8 +626,6 @@ qla2x00_process_completed_request(struct scsi_qla_host *ha, uint32_t index) /* Save ISP completion status */ sp->cmd->result = DID_OK << 16; - - qla2x00_ramp_up_queue_depth(ha, sp); qla2x00_sp_compl(ha, sp); } else { DEBUG2(printk("scsi(%ld): Invalid ISP SCSI completion handle\n", @@ -888,7 +825,6 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) */ switch (comp_status) { case CS_COMPLETE: - case CS_QUEUE_FULL: if (scsi_status == 0) { cp->result = DID_OK << 16; break; @@ -915,20 +851,6 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) } cp->result = DID_OK << 16 | lscsi_status; - if (lscsi_status == SAM_STAT_TASK_SET_FULL) { - DEBUG2(printk(KERN_INFO - "scsi(%ld): QUEUE FULL status detected " - "0x%x-0x%x.\n", ha->host_no, comp_status, - scsi_status)); - - /* Adjust queue depth for all luns on the port. */ - fcport->last_queue_full = jiffies; - spin_unlock_irq(&ha->hardware_lock); - starget_for_each_device(cp->device->sdev_target, - fcport, qla2x00_adjust_sdev_qdepth_down); - spin_lock_irq(&ha->hardware_lock); - break; - } if (lscsi_status != SS_CHECK_CONDITION) break; @@ -1146,6 +1068,17 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) qla2x00_mark_device_lost(ha, fcport, 1, 1); break; + case CS_QUEUE_FULL: + DEBUG2(printk(KERN_INFO + "scsi(%ld): QUEUE FULL status detected 0x%x-0x%x.\n", + ha->host_no, comp_status, scsi_status)); + + /* SCSI Mid-Layer handles device queue full */ + + cp->result = DID_OK << 16 | lscsi_status; + + break; + default: DEBUG3(printk("scsi(%ld): Error detected (unknown status) " "0x%x-0x%x.\n", ha->host_no, comp_status, scsi_status)); @@ -1405,13 +1338,14 @@ qla24xx_process_response_queue(struct scsi_qla_host *ha) * qla24xx_intr_handler() - Process interrupts for the ISP23xx and ISP63xx. * @irq: * @dev_id: SCSI driver HA context + * @regs: * * Called by system whenever the host adapter generates an interrupt. * * Returns handled flag. */ irqreturn_t -qla24xx_intr_handler(int irq, void *dev_id) +qla24xx_intr_handler(int irq, void *dev_id, struct pt_regs *regs) { scsi_qla_host_t *ha; struct device_reg_24xx __iomem *reg; diff --git a/trunk/drivers/scsi/qla2xxx/qla_mbx.c b/trunk/drivers/scsi/qla2xxx/qla_mbx.c index 4cde76c85cb3..879f281e2ea2 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_mbx.c +++ b/trunk/drivers/scsi/qla2xxx/qla_mbx.c @@ -2540,89 +2540,3 @@ qla2x00_read_sfp(scsi_qla_host_t *ha, dma_addr_t sfp_dma, uint16_t addr, return rval; } - -int -qla2x00_get_idma_speed(scsi_qla_host_t *ha, uint16_t loop_id, - uint16_t *port_speed, uint16_t *mb) -{ - int rval; - mbx_cmd_t mc; - mbx_cmd_t *mcp = &mc; - - if (!IS_QLA24XX(ha)) - return QLA_FUNCTION_FAILED; - - DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); - - mcp->mb[0] = MBC_PORT_PARAMS; - mcp->mb[1] = loop_id; - mcp->mb[2] = mcp->mb[3] = mcp->mb[4] = mcp->mb[5] = 0; - mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; - mcp->in_mb = MBX_5|MBX_4|MBX_3|MBX_1|MBX_0; - mcp->tov = 30; - mcp->flags = 0; - rval = qla2x00_mailbox_command(ha, mcp); - - /* Return mailbox statuses. */ - if (mb != NULL) { - mb[0] = mcp->mb[0]; - mb[1] = mcp->mb[1]; - mb[3] = mcp->mb[3]; - mb[4] = mcp->mb[4]; - mb[5] = mcp->mb[5]; - } - - if (rval != QLA_SUCCESS) { - DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__, - ha->host_no, rval)); - } else { - DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); - if (port_speed) - *port_speed = mcp->mb[3]; - } - - return rval; -} - -int -qla2x00_set_idma_speed(scsi_qla_host_t *ha, uint16_t loop_id, - uint16_t port_speed, uint16_t *mb) -{ - int rval; - mbx_cmd_t mc; - mbx_cmd_t *mcp = &mc; - - if (!IS_QLA24XX(ha)) - return QLA_FUNCTION_FAILED; - - DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); - - mcp->mb[0] = MBC_PORT_PARAMS; - mcp->mb[1] = loop_id; - mcp->mb[2] = BIT_0; - mcp->mb[3] = port_speed & (BIT_2|BIT_1|BIT_0); - mcp->mb[4] = mcp->mb[5] = 0; - mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; - mcp->in_mb = MBX_5|MBX_4|MBX_3|MBX_1|MBX_0; - mcp->tov = 30; - mcp->flags = 0; - rval = qla2x00_mailbox_command(ha, mcp); - - /* Return mailbox statuses. */ - if (mb != NULL) { - mb[0] = mcp->mb[0]; - mb[1] = mcp->mb[1]; - mb[3] = mcp->mb[3]; - mb[4] = mcp->mb[4]; - mb[5] = mcp->mb[5]; - } - - if (rval != QLA_SUCCESS) { - DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__, - ha->host_no, rval)); - } else { - DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); - } - - return rval; -} diff --git a/trunk/drivers/scsi/qla2xxx/qla_os.c b/trunk/drivers/scsi/qla2xxx/qla_os.c index 208607be78c7..65cbe2f5eea2 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_os.c +++ b/trunk/drivers/scsi/qla2xxx/qla_os.c @@ -61,9 +61,9 @@ MODULE_PARM_DESC(ql2xallocfwdump, "during HBA initialization. Memory allocation requirements " "vary by ISP type. Default is 1 - allocate memory."); -int ql2xextended_error_logging; -module_param(ql2xextended_error_logging, int, S_IRUGO|S_IRUSR); -MODULE_PARM_DESC(ql2xextended_error_logging, +int extended_error_logging; +module_param(extended_error_logging, int, S_IRUGO|S_IRUSR); +MODULE_PARM_DESC(extended_error_logging, "Option to enable extended error logging, " "Default is 0 - no logging. 1 - log errors."); @@ -77,19 +77,6 @@ MODULE_PARM_DESC(ql2xfdmienable, "Enables FDMI registratons " "Default is 0 - no FDMI. 1 - perfom FDMI."); -#define MAX_Q_DEPTH 32 -static int ql2xmaxqdepth = MAX_Q_DEPTH; -module_param(ql2xmaxqdepth, int, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(ql2xmaxqdepth, - "Maximum queue depth to report for target devices."); - -int ql2xqfullrampup = 120; -module_param(ql2xqfullrampup, int, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(ql2xqfullrampup, - "Number of seconds to wait to begin to ramp-up the queue " - "depth for a device after a queue-full condition has been " - "detected. Default is 120 seconds."); - /* * SCSI host template entry points */ @@ -602,23 +589,6 @@ qla2x00_wait_for_loop_ready(scsi_qla_host_t *ha) return (return_status); } -static void -qla2x00_block_error_handler(struct scsi_cmnd *cmnd) -{ - struct Scsi_Host *shost = cmnd->device->host; - struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device)); - unsigned long flags; - - spin_lock_irqsave(shost->host_lock, flags); - while (rport->port_state == FC_PORTSTATE_BLOCKED) { - spin_unlock_irqrestore(shost->host_lock, flags); - msleep(1000); - spin_lock_irqsave(shost->host_lock, flags); - } - spin_unlock_irqrestore(shost->host_lock, flags); - return; -} - /************************************************************************** * qla2xxx_eh_abort * @@ -645,8 +615,6 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) unsigned long flags; int wait = 0; - qla2x00_block_error_handler(cmd); - if (!CMD_SP(cmd)) return SUCCESS; @@ -780,8 +748,6 @@ qla2xxx_eh_device_reset(struct scsi_cmnd *cmd) unsigned int id, lun; unsigned long serial; - qla2x00_block_error_handler(cmd); - ret = FAILED; id = cmd->device->id; @@ -911,8 +877,6 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd) unsigned int id, lun; unsigned long serial; - qla2x00_block_error_handler(cmd); - ret = FAILED; id = cmd->device->id; @@ -972,8 +936,6 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd) unsigned int id, lun; unsigned long serial; - qla2x00_block_error_handler(cmd); - ret = FAILED; id = cmd->device->id; @@ -1117,9 +1079,9 @@ qla2xxx_slave_configure(struct scsi_device *sdev) struct fc_rport *rport = starget_to_rport(sdev->sdev_target); if (sdev->tagged_supported) - scsi_activate_tcq(sdev, ha->max_q_depth); + scsi_activate_tcq(sdev, 32); else - scsi_deactivate_tcq(sdev, ha->max_q_depth); + scsi_deactivate_tcq(sdev, 32); rport->dev_loss_tmo = ha->port_down_retry_count + 5; @@ -1423,13 +1385,9 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) ha->prev_topology = 0; ha->init_cb_size = sizeof(init_cb_t); ha->mgmt_svr_loop_id = MANAGEMENT_SERVER; - ha->link_data_rate = PORT_SPEED_UNKNOWN; + ha->link_data_rate = LDR_UNKNOWN; ha->optrom_size = OPTROM_SIZE_2300; - ha->max_q_depth = MAX_Q_DEPTH; - if (ql2xmaxqdepth != 0 && ql2xmaxqdepth <= 0xffffU) - ha->max_q_depth = ql2xmaxqdepth; - /* Assign ISP specific operations. */ ha->isp_ops.pci_config = qla2100_pci_config; ha->isp_ops.reset_chip = qla2x00_reset_chip; @@ -1729,10 +1687,8 @@ qla2x00_free_device(scsi_qla_host_t *ha) if (ha->eft) qla2x00_trace_control(ha, TC_DISABLE, 0, 0); - ha->flags.online = 0; - /* Stop currently executing firmware. */ - qla2x00_try_to_stop_firmware(ha); + qla2x00_stop_firmware(ha); /* turn-off interrupts on the card */ if (ha->interrupts_on) @@ -1740,6 +1696,8 @@ qla2x00_free_device(scsi_qla_host_t *ha) qla2x00_mem_free(ha); + ha->flags.online = 0; + /* Detach interrupts */ if (ha->host->irq) free_irq(ha->host->irq, ha); @@ -2606,20 +2564,14 @@ qla2x00_down_timeout(struct semaphore *sema, unsigned long timeout) #define FW_ISP2322 3 #define FW_ISP24XX 4 -#define FW_FILE_ISP21XX "ql2100_fw.bin" -#define FW_FILE_ISP22XX "ql2200_fw.bin" -#define FW_FILE_ISP2300 "ql2300_fw.bin" -#define FW_FILE_ISP2322 "ql2322_fw.bin" -#define FW_FILE_ISP24XX "ql2400_fw.bin" - static DECLARE_MUTEX(qla_fw_lock); static struct fw_blob qla_fw_blobs[FW_BLOBS] = { - { .name = FW_FILE_ISP21XX, .segs = { 0x1000, 0 }, }, - { .name = FW_FILE_ISP22XX, .segs = { 0x1000, 0 }, }, - { .name = FW_FILE_ISP2300, .segs = { 0x800, 0 }, }, - { .name = FW_FILE_ISP2322, .segs = { 0x800, 0x1c000, 0x1e000, 0 }, }, - { .name = FW_FILE_ISP24XX, }, + { .name = "ql2100_fw.bin", .segs = { 0x1000, 0 }, }, + { .name = "ql2200_fw.bin", .segs = { 0x1000, 0 }, }, + { .name = "ql2300_fw.bin", .segs = { 0x800, 0 }, }, + { .name = "ql2322_fw.bin", .segs = { 0x800, 0x1c000, 0x1e000, 0 }, }, + { .name = "ql2400_fw.bin", }, }; struct fw_blob * @@ -2714,7 +2666,7 @@ qla2x00_module_init(void) /* Derive version string. */ strcpy(qla2x00_version_str, QLA2XXX_VERSION); - if (ql2xextended_error_logging) + if (extended_error_logging) strcat(qla2x00_version_str, "-debug"); qla2xxx_transport_template = @@ -2750,8 +2702,3 @@ MODULE_AUTHOR("QLogic Corporation"); MODULE_DESCRIPTION("QLogic Fibre Channel HBA Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(QLA2XXX_VERSION); -MODULE_FIRMWARE(FW_FILE_ISP21XX); -MODULE_FIRMWARE(FW_FILE_ISP22XX); -MODULE_FIRMWARE(FW_FILE_ISP2300); -MODULE_FIRMWARE(FW_FILE_ISP2322); -MODULE_FIRMWARE(FW_FILE_ISP24XX); diff --git a/trunk/drivers/scsi/qla2xxx/qla_version.h b/trunk/drivers/scsi/qla2xxx/qla_version.h index 1fa0bce6b24e..971259032ef7 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_version.h +++ b/trunk/drivers/scsi/qla2xxx/qla_version.h @@ -7,7 +7,7 @@ /* * Driver version */ -#define QLA2XXX_VERSION "8.01.07-k3" +#define QLA2XXX_VERSION "8.01.07-k1" #define QLA_DRIVER_MAJOR_VER 8 #define QLA_DRIVER_MINOR_VER 1 diff --git a/trunk/drivers/scsi/qla4xxx/Kconfig b/trunk/drivers/scsi/qla4xxx/Kconfig deleted file mode 100644 index 69cbff3f57cf..000000000000 --- a/trunk/drivers/scsi/qla4xxx/Kconfig +++ /dev/null @@ -1,7 +0,0 @@ -config SCSI_QLA_ISCSI - tristate "QLogic ISP4XXX host adapter family support" - depends on PCI && SCSI && NET - select SCSI_ISCSI_ATTRS - ---help--- - This driver supports the QLogic 40xx (ISP4XXX) iSCSI host - adapter family. diff --git a/trunk/drivers/scsi/qla4xxx/Makefile b/trunk/drivers/scsi/qla4xxx/Makefile deleted file mode 100644 index 86ea37baa0fc..000000000000 --- a/trunk/drivers/scsi/qla4xxx/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -qla4xxx-y := ql4_os.o ql4_init.o ql4_mbx.o ql4_iocb.o ql4_isr.o \ - ql4_nvram.o ql4_dbg.o - -obj-$(CONFIG_SCSI_QLA_ISCSI) += qla4xxx.o - diff --git a/trunk/drivers/scsi/qla4xxx/ql4_dbg.c b/trunk/drivers/scsi/qla4xxx/ql4_dbg.c deleted file mode 100644 index 752031fadfef..000000000000 --- a/trunk/drivers/scsi/qla4xxx/ql4_dbg.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - * QLogic iSCSI HBA Driver - * Copyright (c) 2003-2006 QLogic Corporation - * - * See LICENSE.qla4xxx for copyright and licensing details. - */ - -#include "ql4_def.h" -#include - -static void qla4xxx_print_srb_info(struct srb * srb) -{ - printk("%s: srb = 0x%p, flags=0x%02x\n", __func__, srb, srb->flags); - printk("%s: cmd = 0x%p, saved_dma_handle = 0x%lx\n", - __func__, srb->cmd, (unsigned long) srb->dma_handle); - printk("%s: fw_ddb_index = %d, lun = %d\n", - __func__, srb->fw_ddb_index, srb->cmd->device->lun); - printk("%s: iocb_tov = %d\n", - __func__, srb->iocb_tov); - printk("%s: cc_stat = 0x%x, r_start = 0x%lx, u_start = 0x%lx\n\n", - __func__, srb->cc_stat, srb->r_start, srb->u_start); -} - -void qla4xxx_print_scsi_cmd(struct scsi_cmnd *cmd) -{ - printk("SCSI Command = 0x%p, Handle=0x%p\n", cmd, cmd->host_scribble); - printk(" b=%d, t=%02xh, l=%02xh, cmd_len = %02xh\n", - cmd->device->channel, cmd->device->id, cmd->device->lun, - cmd->cmd_len); - scsi_print_command(cmd); - printk(" seg_cnt = %d\n", cmd->use_sg); - printk(" request buffer = 0x%p, request buffer len = 0x%x\n", - cmd->request_buffer, cmd->request_bufflen); - if (cmd->use_sg) { - struct scatterlist *sg; - sg = (struct scatterlist *)cmd->request_buffer; - printk(" SG buffer: \n"); - qla4xxx_dump_buffer((caddr_t) sg, - (cmd->use_sg * sizeof(*sg))); - } - printk(" tag = %d, transfersize = 0x%x \n", cmd->tag, - cmd->transfersize); - printk(" Pid = %d, SP = 0x%p\n", (int)cmd->pid, cmd->SCp.ptr); - printk(" underflow size = 0x%x, direction=0x%x\n", cmd->underflow, - cmd->sc_data_direction); - printk(" Current time (jiffies) = 0x%lx, " - "timeout expires = 0x%lx\n", jiffies, cmd->eh_timeout.expires); - qla4xxx_print_srb_info((struct srb *) cmd->SCp.ptr); -} - -void __dump_registers(struct scsi_qla_host *ha) -{ - uint8_t i; - for (i = 0; i < MBOX_REG_COUNT; i++) { - printk(KERN_INFO "0x%02X mailbox[%d] = 0x%08X\n", - (uint8_t) offsetof(struct isp_reg, mailbox[i]), i, - readw(&ha->reg->mailbox[i])); - } - printk(KERN_INFO "0x%02X flash_address = 0x%08X\n", - (uint8_t) offsetof(struct isp_reg, flash_address), - readw(&ha->reg->flash_address)); - printk(KERN_INFO "0x%02X flash_data = 0x%08X\n", - (uint8_t) offsetof(struct isp_reg, flash_data), - readw(&ha->reg->flash_data)); - printk(KERN_INFO "0x%02X ctrl_status = 0x%08X\n", - (uint8_t) offsetof(struct isp_reg, ctrl_status), - readw(&ha->reg->ctrl_status)); - if (is_qla4010(ha)) { - printk(KERN_INFO "0x%02X nvram = 0x%08X\n", - (uint8_t) offsetof(struct isp_reg, u1.isp4010.nvram), - readw(&ha->reg->u1.isp4010.nvram)); - } - - else if (is_qla4022(ha)) { - printk(KERN_INFO "0x%02X intr_mask = 0x%08X\n", - (uint8_t) offsetof(struct isp_reg, - u1.isp4022.intr_mask), - readw(&ha->reg->u1.isp4022.intr_mask)); - printk(KERN_INFO "0x%02X nvram = 0x%08X\n", - (uint8_t) offsetof(struct isp_reg, u1.isp4022.nvram), - readw(&ha->reg->u1.isp4022.nvram)); - printk(KERN_INFO "0x%02X semaphore = 0x%08X\n", - (uint8_t) offsetof(struct isp_reg, - u1.isp4022.semaphore), - readw(&ha->reg->u1.isp4022.semaphore)); - } - printk(KERN_INFO "0x%02X req_q_in = 0x%08X\n", - (uint8_t) offsetof(struct isp_reg, req_q_in), - readw(&ha->reg->req_q_in)); - printk(KERN_INFO "0x%02X rsp_q_out = 0x%08X\n", - (uint8_t) offsetof(struct isp_reg, rsp_q_out), - readw(&ha->reg->rsp_q_out)); - if (is_qla4010(ha)) { - printk(KERN_INFO "0x%02X ext_hw_conf = 0x%08X\n", - (uint8_t) offsetof(struct isp_reg, - u2.isp4010.ext_hw_conf), - readw(&ha->reg->u2.isp4010.ext_hw_conf)); - printk(KERN_INFO "0x%02X port_ctrl = 0x%08X\n", - (uint8_t) offsetof(struct isp_reg, - u2.isp4010.port_ctrl), - readw(&ha->reg->u2.isp4010.port_ctrl)); - printk(KERN_INFO "0x%02X port_status = 0x%08X\n", - (uint8_t) offsetof(struct isp_reg, - u2.isp4010.port_status), - readw(&ha->reg->u2.isp4010.port_status)); - printk(KERN_INFO "0x%02X req_q_out = 0x%08X\n", - (uint8_t) offsetof(struct isp_reg, - u2.isp4010.req_q_out), - readw(&ha->reg->u2.isp4010.req_q_out)); - printk(KERN_INFO "0x%02X gp_out = 0x%08X\n", - (uint8_t) offsetof(struct isp_reg, u2.isp4010.gp_out), - readw(&ha->reg->u2.isp4010.gp_out)); - printk(KERN_INFO "0x%02X gp_in = 0x%08X\n", - (uint8_t) offsetof(struct isp_reg, u2.isp4010.gp_in), - readw(&ha->reg->u2.isp4010.gp_in)); - printk(KERN_INFO "0x%02X port_err_status = 0x%08X\n", - (uint8_t) offsetof(struct isp_reg, - u2.isp4010.port_err_status), - readw(&ha->reg->u2.isp4010.port_err_status)); - } - - else if (is_qla4022(ha)) { - printk(KERN_INFO "Page 0 Registers:\n"); - printk(KERN_INFO "0x%02X ext_hw_conf = 0x%08X\n", - (uint8_t) offsetof(struct isp_reg, - u2.isp4022.p0.ext_hw_conf), - readw(&ha->reg->u2.isp4022.p0.ext_hw_conf)); - printk(KERN_INFO "0x%02X port_ctrl = 0x%08X\n", - (uint8_t) offsetof(struct isp_reg, - u2.isp4022.p0.port_ctrl), - readw(&ha->reg->u2.isp4022.p0.port_ctrl)); - printk(KERN_INFO "0x%02X port_status = 0x%08X\n", - (uint8_t) offsetof(struct isp_reg, - u2.isp4022.p0.port_status), - readw(&ha->reg->u2.isp4022.p0.port_status)); - printk(KERN_INFO "0x%02X gp_out = 0x%08X\n", - (uint8_t) offsetof(struct isp_reg, - u2.isp4022.p0.gp_out), - readw(&ha->reg->u2.isp4022.p0.gp_out)); - printk(KERN_INFO "0x%02X gp_in = 0x%08X\n", - (uint8_t) offsetof(struct isp_reg, u2.isp4022.p0.gp_in), - readw(&ha->reg->u2.isp4022.p0.gp_in)); - printk(KERN_INFO "0x%02X port_err_status = 0x%08X\n", - (uint8_t) offsetof(struct isp_reg, - u2.isp4022.p0.port_err_status), - readw(&ha->reg->u2.isp4022.p0.port_err_status)); - printk(KERN_INFO "Page 1 Registers:\n"); - writel(HOST_MEM_CFG_PAGE & set_rmask(CSR_SCSI_PAGE_SELECT), - &ha->reg->ctrl_status); - printk(KERN_INFO "0x%02X req_q_out = 0x%08X\n", - (uint8_t) offsetof(struct isp_reg, - u2.isp4022.p1.req_q_out), - readw(&ha->reg->u2.isp4022.p1.req_q_out)); - writel(PORT_CTRL_STAT_PAGE & set_rmask(CSR_SCSI_PAGE_SELECT), - &ha->reg->ctrl_status); - } -} - -void qla4xxx_dump_mbox_registers(struct scsi_qla_host *ha) -{ - unsigned long flags = 0; - int i = 0; - spin_lock_irqsave(&ha->hardware_lock, flags); - for (i = 1; i < MBOX_REG_COUNT; i++) - printk(KERN_INFO " Mailbox[%d] = %08x\n", i, - readw(&ha->reg->mailbox[i])); - spin_unlock_irqrestore(&ha->hardware_lock, flags); -} - -void qla4xxx_dump_registers(struct scsi_qla_host *ha) -{ - unsigned long flags = 0; - spin_lock_irqsave(&ha->hardware_lock, flags); - __dump_registers(ha); - spin_unlock_irqrestore(&ha->hardware_lock, flags); -} - -void qla4xxx_dump_buffer(void *b, uint32_t size) -{ - uint32_t cnt; - uint8_t *c = b; - - printk(" 0 1 2 3 4 5 6 7 8 9 Ah Bh Ch Dh Eh " - "Fh\n"); - printk("------------------------------------------------------------" - "--\n"); - for (cnt = 0; cnt < size; cnt++, c++) { - printk(KERN_DEBUG "%02x", *c); - if (!(cnt % 16)) - printk(KERN_DEBUG "\n"); - - else - printk(KERN_DEBUG " "); - } - if (cnt % 16) - printk(KERN_DEBUG "\n"); -} diff --git a/trunk/drivers/scsi/qla4xxx/ql4_dbg.h b/trunk/drivers/scsi/qla4xxx/ql4_dbg.h deleted file mode 100644 index d861c3b411c8..000000000000 --- a/trunk/drivers/scsi/qla4xxx/ql4_dbg.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * QLogic iSCSI HBA Driver - * Copyright (c) 2003-2006 QLogic Corporation - * - * See LICENSE.qla4xxx for copyright and licensing details. - */ - -/* - * Driver debug definitions. - */ -/* #define QL_DEBUG */ /* DEBUG messages */ -/* #define QL_DEBUG_LEVEL_3 */ /* Output function tracing */ -/* #define QL_DEBUG_LEVEL_4 */ -/* #define QL_DEBUG_LEVEL_5 */ -/* #define QL_DEBUG_LEVEL_9 */ - -#define QL_DEBUG_LEVEL_2 /* ALways enable error messagess */ -#if defined(QL_DEBUG) -#define DEBUG(x) do {x;} while (0); -#else -#define DEBUG(x) do {} while (0); -#endif - -#if defined(QL_DEBUG_LEVEL_2) -#define DEBUG2(x) do {if(ql4xextended_error_logging == 2) x;} while (0); -#define DEBUG2_3(x) do {x;} while (0); -#else /* */ -#define DEBUG2(x) do {} while (0); -#endif /* */ - -#if defined(QL_DEBUG_LEVEL_3) -#define DEBUG3(x) do {if(ql4xextended_error_logging == 3) x;} while (0); -#else /* */ -#define DEBUG3(x) do {} while (0); -#if !defined(QL_DEBUG_LEVEL_2) -#define DEBUG2_3(x) do {} while (0); -#endif /* */ -#endif /* */ -#if defined(QL_DEBUG_LEVEL_4) -#define DEBUG4(x) do {x;} while (0); -#else /* */ -#define DEBUG4(x) do {} while (0); -#endif /* */ - -#if defined(QL_DEBUG_LEVEL_5) -#define DEBUG5(x) do {x;} while (0); -#else /* */ -#define DEBUG5(x) do {} while (0); -#endif /* */ - -#if defined(QL_DEBUG_LEVEL_9) -#define DEBUG9(x) do {x;} while (0); -#else /* */ -#define DEBUG9(x) do {} while (0); -#endif /* */ diff --git a/trunk/drivers/scsi/qla4xxx/ql4_def.h b/trunk/drivers/scsi/qla4xxx/ql4_def.h deleted file mode 100644 index a7f6c7b1c590..000000000000 --- a/trunk/drivers/scsi/qla4xxx/ql4_def.h +++ /dev/null @@ -1,586 +0,0 @@ -/* - * QLogic iSCSI HBA Driver - * Copyright (c) 2003-2006 QLogic Corporation - * - * See LICENSE.qla4xxx for copyright and licensing details. - */ - -#ifndef __QL4_DEF_H -#define __QL4_DEF_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - - -#ifndef PCI_DEVICE_ID_QLOGIC_ISP4010 -#define PCI_DEVICE_ID_QLOGIC_ISP4010 0x4010 -#endif - -#ifndef PCI_DEVICE_ID_QLOGIC_ISP4022 -#define PCI_DEVICE_ID_QLOGIC_ISP4022 0x4022 -#endif /* */ - -#define QLA_SUCCESS 0 -#define QLA_ERROR 1 - -/* - * Data bit definitions - */ -#define BIT_0 0x1 -#define BIT_1 0x2 -#define BIT_2 0x4 -#define BIT_3 0x8 -#define BIT_4 0x10 -#define BIT_5 0x20 -#define BIT_6 0x40 -#define BIT_7 0x80 -#define BIT_8 0x100 -#define BIT_9 0x200 -#define BIT_10 0x400 -#define BIT_11 0x800 -#define BIT_12 0x1000 -#define BIT_13 0x2000 -#define BIT_14 0x4000 -#define BIT_15 0x8000 -#define BIT_16 0x10000 -#define BIT_17 0x20000 -#define BIT_18 0x40000 -#define BIT_19 0x80000 -#define BIT_20 0x100000 -#define BIT_21 0x200000 -#define BIT_22 0x400000 -#define BIT_23 0x800000 -#define BIT_24 0x1000000 -#define BIT_25 0x2000000 -#define BIT_26 0x4000000 -#define BIT_27 0x8000000 -#define BIT_28 0x10000000 -#define BIT_29 0x20000000 -#define BIT_30 0x40000000 -#define BIT_31 0x80000000 - -/* - * Host adapter default definitions - ***********************************/ -#define MAX_HBAS 16 -#define MAX_BUSES 1 -#define MAX_TARGETS (MAX_PRST_DEV_DB_ENTRIES + MAX_DEV_DB_ENTRIES) -#define MAX_LUNS 0xffff -#define MAX_AEN_ENTRIES 256 /* should be > EXT_DEF_MAX_AEN_QUEUE */ -#define MAX_DDB_ENTRIES (MAX_PRST_DEV_DB_ENTRIES + MAX_DEV_DB_ENTRIES) -#define MAX_PDU_ENTRIES 32 -#define INVALID_ENTRY 0xFFFF -#define MAX_CMDS_TO_RISC 1024 -#define MAX_SRBS MAX_CMDS_TO_RISC -#define MBOX_AEN_REG_COUNT 5 -#define MAX_INIT_RETRIES 5 -#define IOCB_HIWAT_CUSHION 16 - -/* - * Buffer sizes - */ -#define REQUEST_QUEUE_DEPTH MAX_CMDS_TO_RISC -#define RESPONSE_QUEUE_DEPTH 64 -#define QUEUE_SIZE 64 -#define DMA_BUFFER_SIZE 512 - -/* - * Misc - */ -#define MAC_ADDR_LEN 6 /* in bytes */ -#define IP_ADDR_LEN 4 /* in bytes */ -#define DRIVER_NAME "qla4xxx" - -#define MAX_LINKED_CMDS_PER_LUN 3 -#define MAX_REQS_SERVICED_PER_INTR 16 - -#define ISCSI_IPADDR_SIZE 4 /* IP address size */ -#define ISCSI_ALIAS_SIZE 32 /* ISCSI Alais name size */ -#define ISCSI_NAME_SIZE 255 /* ISCSI Name size - - * usually a string */ - -#define LSDW(x) ((u32)((u64)(x))) -#define MSDW(x) ((u32)((((u64)(x)) >> 16) >> 16)) - -/* - * Retry & Timeout Values - */ -#define MBOX_TOV 60 -#define SOFT_RESET_TOV 30 -#define RESET_INTR_TOV 3 -#define SEMAPHORE_TOV 10 -#define ADAPTER_INIT_TOV 120 -#define ADAPTER_RESET_TOV 180 -#define EXTEND_CMD_TOV 60 -#define WAIT_CMD_TOV 30 -#define EH_WAIT_CMD_TOV 120 -#define FIRMWARE_UP_TOV 60 -#define RESET_FIRMWARE_TOV 30 -#define LOGOUT_TOV 10 -#define IOCB_TOV_MARGIN 10 -#define RELOGIN_TOV 18 -#define ISNS_DEREG_TOV 5 - -#define MAX_RESET_HA_RETRIES 2 - -/* - * SCSI Request Block structure (srb) that is placed - * on cmd->SCp location of every I/O [We have 22 bytes available] - */ -struct srb { - struct list_head list; /* (8) */ - struct scsi_qla_host *ha; /* HA the SP is queued on */ - struct ddb_entry *ddb; - uint16_t flags; /* (1) Status flags. */ - -#define SRB_DMA_VALID BIT_3 /* DMA Buffer mapped. */ -#define SRB_GOT_SENSE BIT_4 /* sense data recieved. */ - uint8_t state; /* (1) Status flags. */ - -#define SRB_NO_QUEUE_STATE 0 /* Request is in between states */ -#define SRB_FREE_STATE 1 -#define SRB_ACTIVE_STATE 3 -#define SRB_ACTIVE_TIMEOUT_STATE 4 -#define SRB_SUSPENDED_STATE 7 /* Request in suspended state */ - - struct scsi_cmnd *cmd; /* (4) SCSI command block */ - dma_addr_t dma_handle; /* (4) for unmap of single transfers */ - atomic_t ref_count; /* reference count for this srb */ - uint32_t fw_ddb_index; - uint8_t err_id; /* error id */ -#define SRB_ERR_PORT 1 /* Request failed because "port down" */ -#define SRB_ERR_LOOP 2 /* Request failed because "loop down" */ -#define SRB_ERR_DEVICE 3 /* Request failed because "device error" */ -#define SRB_ERR_OTHER 4 - - uint16_t reserved; - uint16_t iocb_tov; - uint16_t iocb_cnt; /* Number of used iocbs */ - uint16_t cc_stat; - u_long r_start; /* Time we recieve a cmd from OS */ - u_long u_start; /* Time when we handed the cmd to F/W */ -}; - - /* - * Device Database (DDB) structure - */ -struct ddb_entry { - struct list_head list; /* ddb list */ - struct scsi_qla_host *ha; - struct iscsi_cls_session *sess; - struct iscsi_cls_conn *conn; - - atomic_t state; /* DDB State */ - - unsigned long flags; /* DDB Flags */ - - unsigned long dev_scan_wait_to_start_relogin; - unsigned long dev_scan_wait_to_complete_relogin; - - uint16_t os_target_id; /* Target ID */ - uint16_t fw_ddb_index; /* DDB firmware index */ - uint8_t reserved[2]; - uint32_t fw_ddb_device_state; /* F/W Device State -- see ql4_fw.h */ - - uint32_t CmdSn; - uint16_t target_session_id; - uint16_t connection_id; - uint16_t exe_throttle; /* Max mumber of cmds outstanding - * simultaneously */ - uint16_t task_mgmt_timeout; /* Min time for task mgmt cmds to - * complete */ - uint16_t default_relogin_timeout; /* Max time to wait for - * relogin to complete */ - uint16_t tcp_source_port_num; - uint32_t default_time2wait; /* Default Min time between - * relogins (+aens) */ - - atomic_t port_down_timer; /* Device connection timer */ - atomic_t retry_relogin_timer; /* Min Time between relogins - * (4000 only) */ - atomic_t relogin_timer; /* Max Time to wait for relogin to complete */ - atomic_t relogin_retry_count; /* Num of times relogin has been - * retried */ - - uint16_t port; - uint32_t tpgt; - uint8_t ip_addr[ISCSI_IPADDR_SIZE]; - uint8_t iscsi_name[ISCSI_NAME_SIZE]; /* 72 x48 */ - uint8_t iscsi_alias[0x20]; -}; - -/* - * DDB states. - */ -#define DDB_STATE_DEAD 0 /* We can no longer talk to - * this device */ -#define DDB_STATE_ONLINE 1 /* Device ready to accept - * commands */ -#define DDB_STATE_MISSING 2 /* Device logged off, trying - * to re-login */ - -/* - * DDB flags. - */ -#define DF_RELOGIN 0 /* Relogin to device */ -#define DF_NO_RELOGIN 1 /* Do not relogin if IOCTL - * logged it out */ -#define DF_ISNS_DISCOVERED 2 /* Device was discovered via iSNS */ -#define DF_FO_MASKED 3 - -/* - * Asynchronous Event Queue structure - */ -struct aen { - uint32_t mbox_sts[MBOX_AEN_REG_COUNT]; -}; - - -#include "ql4_fw.h" -#include "ql4_nvram.h" - -/* - * Linux Host Adapter structure - */ -struct scsi_qla_host { - /* Linux adapter configuration data */ - struct Scsi_Host *host; /* pointer to host data */ - uint32_t tot_ddbs; - unsigned long flags; - -#define AF_ONLINE 0 /* 0x00000001 */ -#define AF_INIT_DONE 1 /* 0x00000002 */ -#define AF_MBOX_COMMAND 2 /* 0x00000004 */ -#define AF_MBOX_COMMAND_DONE 3 /* 0x00000008 */ -#define AF_INTERRUPTS_ON 6 /* 0x00000040 Not Used */ -#define AF_GET_CRASH_RECORD 7 /* 0x00000080 */ -#define AF_LINK_UP 8 /* 0x00000100 */ -#define AF_TOPCAT_CHIP_PRESENT 9 /* 0x00000200 */ -#define AF_IRQ_ATTACHED 10 /* 0x00000400 */ -#define AF_ISNS_CMD_IN_PROCESS 12 /* 0x00001000 */ -#define AF_ISNS_CMD_DONE 13 /* 0x00002000 */ - - unsigned long dpc_flags; - -#define DPC_RESET_HA 1 /* 0x00000002 */ -#define DPC_RETRY_RESET_HA 2 /* 0x00000004 */ -#define DPC_RELOGIN_DEVICE 3 /* 0x00000008 */ -#define DPC_RESET_HA_DESTROY_DDB_LIST 4 /* 0x00000010 */ -#define DPC_RESET_HA_INTR 5 /* 0x00000020 */ -#define DPC_ISNS_RESTART 7 /* 0x00000080 */ -#define DPC_AEN 9 /* 0x00000200 */ -#define DPC_GET_DHCP_IP_ADDR 15 /* 0x00008000 */ - - uint16_t iocb_cnt; - uint16_t iocb_hiwat; - - /* SRB cache. */ -#define SRB_MIN_REQ 128 - mempool_t *srb_mempool; - - /* pci information */ - struct pci_dev *pdev; - - struct isp_reg __iomem *reg; /* Base I/O address */ - unsigned long pio_address; - unsigned long pio_length; -#define MIN_IOBASE_LEN 0x100 - - uint16_t req_q_count; - uint8_t marker_needed; - uint8_t rsvd1; - - unsigned long host_no; - - /* NVRAM registers */ - struct eeprom_data *nvram; - spinlock_t hardware_lock ____cacheline_aligned; - spinlock_t list_lock; - uint32_t eeprom_cmd_data; - - /* Counters for general statistics */ - uint64_t adapter_error_count; - uint64_t device_error_count; - uint64_t total_io_count; - uint64_t total_mbytes_xferred; - uint64_t link_failure_count; - uint64_t invalid_crc_count; - uint32_t spurious_int_count; - uint32_t aborted_io_count; - uint32_t io_timeout_count; - uint32_t mailbox_timeout_count; - uint32_t seconds_since_last_intr; - uint32_t seconds_since_last_heartbeat; - uint32_t mac_index; - - /* Info Needed for Management App */ - /* --- From GetFwVersion --- */ - uint32_t firmware_version[2]; - uint32_t patch_number; - uint32_t build_number; - - /* --- From Init_FW --- */ - /* init_cb_t *init_cb; */ - uint16_t firmware_options; - uint16_t tcp_options; - uint8_t ip_address[IP_ADDR_LEN]; - uint8_t subnet_mask[IP_ADDR_LEN]; - uint8_t gateway[IP_ADDR_LEN]; - uint8_t alias[32]; - uint8_t name_string[256]; - uint8_t heartbeat_interval; - uint8_t rsvd; - - /* --- From FlashSysInfo --- */ - uint8_t my_mac[MAC_ADDR_LEN]; - uint8_t serial_number[16]; - - /* --- From GetFwState --- */ - uint32_t firmware_state; - uint32_t board_id; - uint32_t addl_fw_state; - - /* Linux kernel thread */ - struct workqueue_struct *dpc_thread; - struct work_struct dpc_work; - - /* Linux timer thread */ - struct timer_list timer; - uint32_t timer_active; - - /* Recovery Timers */ - uint32_t port_down_retry_count; - uint32_t discovery_wait; - atomic_t check_relogin_timeouts; - uint32_t retry_reset_ha_cnt; - uint32_t isp_reset_timer; /* reset test timer */ - uint32_t nic_reset_timer; /* simulated nic reset test timer */ - int eh_start; - struct list_head free_srb_q; - uint16_t free_srb_q_count; - uint16_t num_srbs_allocated; - - /* DMA Memory Block */ - void *queues; - dma_addr_t queues_dma; - unsigned long queues_len; - -#define MEM_ALIGN_VALUE \ - ((max(REQUEST_QUEUE_DEPTH, RESPONSE_QUEUE_DEPTH)) * \ - sizeof(struct queue_entry)) - /* request and response queue variables */ - dma_addr_t request_dma; - struct queue_entry *request_ring; - struct queue_entry *request_ptr; - dma_addr_t response_dma; - struct queue_entry *response_ring; - struct queue_entry *response_ptr; - dma_addr_t shadow_regs_dma; - struct shadow_regs *shadow_regs; - uint16_t request_in; /* Current indexes. */ - uint16_t request_out; - uint16_t response_in; - uint16_t response_out; - - /* aen queue variables */ - uint16_t aen_q_count; /* Number of available aen_q entries */ - uint16_t aen_in; /* Current indexes */ - uint16_t aen_out; - struct aen aen_q[MAX_AEN_ENTRIES]; - - /* This mutex protects several threads to do mailbox commands - * concurrently. - */ - struct mutex mbox_sem; - wait_queue_head_t mailbox_wait_queue; - - /* temporary mailbox status registers */ - volatile uint8_t mbox_status_count; - volatile uint32_t mbox_status[MBOX_REG_COUNT]; - - /* local device database list (contains internal ddb entries) */ - struct list_head ddb_list; - - /* Map ddb_list entry by FW ddb index */ - struct ddb_entry *fw_ddb_index_map[MAX_DDB_ENTRIES]; - -}; - -static inline int is_qla4010(struct scsi_qla_host *ha) -{ - return ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP4010; -} - -static inline int is_qla4022(struct scsi_qla_host *ha) -{ - return ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP4022; -} - -static inline int adapter_up(struct scsi_qla_host *ha) -{ - return (test_bit(AF_ONLINE, &ha->flags) != 0) && - (test_bit(AF_LINK_UP, &ha->flags) != 0); -} - -static inline struct scsi_qla_host* to_qla_host(struct Scsi_Host *shost) -{ - return (struct scsi_qla_host *)shost->hostdata; -} - -static inline void __iomem* isp_semaphore(struct scsi_qla_host *ha) -{ - return (is_qla4022(ha) ? - &ha->reg->u1.isp4022.semaphore : - &ha->reg->u1.isp4010.nvram); -} - -static inline void __iomem* isp_nvram(struct scsi_qla_host *ha) -{ - return (is_qla4022(ha) ? - &ha->reg->u1.isp4022.nvram : - &ha->reg->u1.isp4010.nvram); -} - -static inline void __iomem* isp_ext_hw_conf(struct scsi_qla_host *ha) -{ - return (is_qla4022(ha) ? - &ha->reg->u2.isp4022.p0.ext_hw_conf : - &ha->reg->u2.isp4010.ext_hw_conf); -} - -static inline void __iomem* isp_port_status(struct scsi_qla_host *ha) -{ - return (is_qla4022(ha) ? - &ha->reg->u2.isp4022.p0.port_status : - &ha->reg->u2.isp4010.port_status); -} - -static inline void __iomem* isp_port_ctrl(struct scsi_qla_host *ha) -{ - return (is_qla4022(ha) ? - &ha->reg->u2.isp4022.p0.port_ctrl : - &ha->reg->u2.isp4010.port_ctrl); -} - -static inline void __iomem* isp_port_error_status(struct scsi_qla_host *ha) -{ - return (is_qla4022(ha) ? - &ha->reg->u2.isp4022.p0.port_err_status : - &ha->reg->u2.isp4010.port_err_status); -} - -static inline void __iomem * isp_gp_out(struct scsi_qla_host *ha) -{ - return (is_qla4022(ha) ? - &ha->reg->u2.isp4022.p0.gp_out : - &ha->reg->u2.isp4010.gp_out); -} - -static inline int eeprom_ext_hw_conf_offset(struct scsi_qla_host *ha) -{ - return (is_qla4022(ha) ? - offsetof(struct eeprom_data, isp4022.ext_hw_conf) / 2 : - offsetof(struct eeprom_data, isp4010.ext_hw_conf) / 2); -} - -int ql4xxx_sem_spinlock(struct scsi_qla_host * ha, u32 sem_mask, u32 sem_bits); -void ql4xxx_sem_unlock(struct scsi_qla_host * ha, u32 sem_mask); -int ql4xxx_sem_lock(struct scsi_qla_host * ha, u32 sem_mask, u32 sem_bits); - -static inline int ql4xxx_lock_flash(struct scsi_qla_host *a) -{ - if (is_qla4022(a)) - return ql4xxx_sem_spinlock(a, QL4022_FLASH_SEM_MASK, - (QL4022_RESOURCE_BITS_BASE_CODE | - (a->mac_index)) << 13); - else - return ql4xxx_sem_spinlock(a, QL4010_FLASH_SEM_MASK, - QL4010_FLASH_SEM_BITS); -} - -static inline void ql4xxx_unlock_flash(struct scsi_qla_host *a) -{ - if (is_qla4022(a)) - ql4xxx_sem_unlock(a, QL4022_FLASH_SEM_MASK); - else - ql4xxx_sem_unlock(a, QL4010_FLASH_SEM_MASK); -} - -static inline int ql4xxx_lock_nvram(struct scsi_qla_host *a) -{ - if (is_qla4022(a)) - return ql4xxx_sem_spinlock(a, QL4022_NVRAM_SEM_MASK, - (QL4022_RESOURCE_BITS_BASE_CODE | - (a->mac_index)) << 10); - else - return ql4xxx_sem_spinlock(a, QL4010_NVRAM_SEM_MASK, - QL4010_NVRAM_SEM_BITS); -} - -static inline void ql4xxx_unlock_nvram(struct scsi_qla_host *a) -{ - if (is_qla4022(a)) - ql4xxx_sem_unlock(a, QL4022_NVRAM_SEM_MASK); - else - ql4xxx_sem_unlock(a, QL4010_NVRAM_SEM_MASK); -} - -static inline int ql4xxx_lock_drvr(struct scsi_qla_host *a) -{ - if (is_qla4022(a)) - return ql4xxx_sem_lock(a, QL4022_DRVR_SEM_MASK, - (QL4022_RESOURCE_BITS_BASE_CODE | - (a->mac_index)) << 1); - else - return ql4xxx_sem_lock(a, QL4010_DRVR_SEM_MASK, - QL4010_DRVR_SEM_BITS); -} - -static inline void ql4xxx_unlock_drvr(struct scsi_qla_host *a) -{ - if (is_qla4022(a)) - ql4xxx_sem_unlock(a, QL4022_DRVR_SEM_MASK); - else - ql4xxx_sem_unlock(a, QL4010_DRVR_SEM_MASK); -} - -/*---------------------------------------------------------------------------*/ - -/* Defines for qla4xxx_initialize_adapter() and qla4xxx_recover_adapter() */ -#define PRESERVE_DDB_LIST 0 -#define REBUILD_DDB_LIST 1 - -/* Defines for process_aen() */ -#define PROCESS_ALL_AENS 0 -#define FLUSH_DDB_CHANGED_AENS 1 -#define RELOGIN_DDB_CHANGED_AENS 2 - -#include "ql4_version.h" -#include "ql4_glbl.h" -#include "ql4_dbg.h" -#include "ql4_inline.h" - - -#endif /*_QLA4XXX_H */ diff --git a/trunk/drivers/scsi/qla4xxx/ql4_fw.h b/trunk/drivers/scsi/qla4xxx/ql4_fw.h deleted file mode 100644 index 427489de64bc..000000000000 --- a/trunk/drivers/scsi/qla4xxx/ql4_fw.h +++ /dev/null @@ -1,843 +0,0 @@ -/* - * QLogic iSCSI HBA Driver - * Copyright (c) 2003-2006 QLogic Corporation - * - * See LICENSE.qla4xxx for copyright and licensing details. - */ - -#ifndef _QLA4X_FW_H -#define _QLA4X_FW_H - - -#define MAX_PRST_DEV_DB_ENTRIES 64 -#define MIN_DISC_DEV_DB_ENTRY MAX_PRST_DEV_DB_ENTRIES -#define MAX_DEV_DB_ENTRIES 512 - -/************************************************************************* - * - * ISP 4010 I/O Register Set Structure and Definitions - * - *************************************************************************/ - -struct port_ctrl_stat_regs { - __le32 ext_hw_conf; /* 80 x50 R/W */ - __le32 intChipConfiguration; /* 84 x54 */ - __le32 port_ctrl; /* 88 x58 */ - __le32 port_status; /* 92 x5c */ - __le32 HostPrimMACHi; /* 96 x60 */ - __le32 HostPrimMACLow; /* 100 x64 */ - __le32 HostSecMACHi; /* 104 x68 */ - __le32 HostSecMACLow; /* 108 x6c */ - __le32 EPPrimMACHi; /* 112 x70 */ - __le32 EPPrimMACLow; /* 116 x74 */ - __le32 EPSecMACHi; /* 120 x78 */ - __le32 EPSecMACLow; /* 124 x7c */ - __le32 HostPrimIPHi; /* 128 x80 */ - __le32 HostPrimIPMidHi; /* 132 x84 */ - __le32 HostPrimIPMidLow; /* 136 x88 */ - __le32 HostPrimIPLow; /* 140 x8c */ - __le32 HostSecIPHi; /* 144 x90 */ - __le32 HostSecIPMidHi; /* 148 x94 */ - __le32 HostSecIPMidLow; /* 152 x98 */ - __le32 HostSecIPLow; /* 156 x9c */ - __le32 EPPrimIPHi; /* 160 xa0 */ - __le32 EPPrimIPMidHi; /* 164 xa4 */ - __le32 EPPrimIPMidLow; /* 168 xa8 */ - __le32 EPPrimIPLow; /* 172 xac */ - __le32 EPSecIPHi; /* 176 xb0 */ - __le32 EPSecIPMidHi; /* 180 xb4 */ - __le32 EPSecIPMidLow; /* 184 xb8 */ - __le32 EPSecIPLow; /* 188 xbc */ - __le32 IPReassemblyTimeout; /* 192 xc0 */ - __le32 EthMaxFramePayload; /* 196 xc4 */ - __le32 TCPMaxWindowSize; /* 200 xc8 */ - __le32 TCPCurrentTimestampHi; /* 204 xcc */ - __le32 TCPCurrentTimestampLow; /* 208 xd0 */ - __le32 LocalRAMAddress; /* 212 xd4 */ - __le32 LocalRAMData; /* 216 xd8 */ - __le32 PCSReserved1; /* 220 xdc */ - __le32 gp_out; /* 224 xe0 */ - __le32 gp_in; /* 228 xe4 */ - __le32 ProbeMuxAddr; /* 232 xe8 */ - __le32 ProbeMuxData; /* 236 xec */ - __le32 ERMQueueBaseAddr0; /* 240 xf0 */ - __le32 ERMQueueBaseAddr1; /* 244 xf4 */ - __le32 MACConfiguration; /* 248 xf8 */ - __le32 port_err_status; /* 252 xfc COR */ -}; - -struct host_mem_cfg_regs { - __le32 NetRequestQueueOut; /* 80 x50 */ - __le32 NetRequestQueueOutAddrHi; /* 84 x54 */ - __le32 NetRequestQueueOutAddrLow; /* 88 x58 */ - __le32 NetRequestQueueBaseAddrHi; /* 92 x5c */ - __le32 NetRequestQueueBaseAddrLow; /* 96 x60 */ - __le32 NetRequestQueueLength; /* 100 x64 */ - __le32 NetResponseQueueIn; /* 104 x68 */ - __le32 NetResponseQueueInAddrHi; /* 108 x6c */ - __le32 NetResponseQueueInAddrLow; /* 112 x70 */ - __le32 NetResponseQueueBaseAddrHi; /* 116 x74 */ - __le32 NetResponseQueueBaseAddrLow; /* 120 x78 */ - __le32 NetResponseQueueLength; /* 124 x7c */ - __le32 req_q_out; /* 128 x80 */ - __le32 RequestQueueOutAddrHi; /* 132 x84 */ - __le32 RequestQueueOutAddrLow; /* 136 x88 */ - __le32 RequestQueueBaseAddrHi; /* 140 x8c */ - __le32 RequestQueueBaseAddrLow; /* 144 x90 */ - __le32 RequestQueueLength; /* 148 x94 */ - __le32 ResponseQueueIn; /* 152 x98 */ - __le32 ResponseQueueInAddrHi; /* 156 x9c */ - __le32 ResponseQueueInAddrLow; /* 160 xa0 */ - __le32 ResponseQueueBaseAddrHi; /* 164 xa4 */ - __le32 ResponseQueueBaseAddrLow; /* 168 xa8 */ - __le32 ResponseQueueLength; /* 172 xac */ - __le32 NetRxLargeBufferQueueOut; /* 176 xb0 */ - __le32 NetRxLargeBufferQueueBaseAddrHi; /* 180 xb4 */ - __le32 NetRxLargeBufferQueueBaseAddrLow; /* 184 xb8 */ - __le32 NetRxLargeBufferQueueLength; /* 188 xbc */ - __le32 NetRxLargeBufferLength; /* 192 xc0 */ - __le32 NetRxSmallBufferQueueOut; /* 196 xc4 */ - __le32 NetRxSmallBufferQueueBaseAddrHi; /* 200 xc8 */ - __le32 NetRxSmallBufferQueueBaseAddrLow; /* 204 xcc */ - __le32 NetRxSmallBufferQueueLength; /* 208 xd0 */ - __le32 NetRxSmallBufferLength; /* 212 xd4 */ - __le32 HMCReserved0[10]; /* 216 xd8 */ -}; - -struct local_ram_cfg_regs { - __le32 BufletSize; /* 80 x50 */ - __le32 BufletMaxCount; /* 84 x54 */ - __le32 BufletCurrCount; /* 88 x58 */ - __le32 BufletPauseThresholdCount; /* 92 x5c */ - __le32 BufletTCPWinThresholdHi; /* 96 x60 */ - __le32 BufletTCPWinThresholdLow; /* 100 x64 */ - __le32 IPHashTableBaseAddr; /* 104 x68 */ - __le32 IPHashTableSize; /* 108 x6c */ - __le32 TCPHashTableBaseAddr; /* 112 x70 */ - __le32 TCPHashTableSize; /* 116 x74 */ - __le32 NCBAreaBaseAddr; /* 120 x78 */ - __le32 NCBMaxCount; /* 124 x7c */ - __le32 NCBCurrCount; /* 128 x80 */ - __le32 DRBAreaBaseAddr; /* 132 x84 */ - __le32 DRBMaxCount; /* 136 x88 */ - __le32 DRBCurrCount; /* 140 x8c */ - __le32 LRCReserved[28]; /* 144 x90 */ -}; - -struct prot_stat_regs { - __le32 MACTxFrameCount; /* 80 x50 R */ - __le32 MACTxByteCount; /* 84 x54 R */ - __le32 MACRxFrameCount; /* 88 x58 R */ - __le32 MACRxByteCount; /* 92 x5c R */ - __le32 MACCRCErrCount; /* 96 x60 R */ - __le32 MACEncErrCount; /* 100 x64 R */ - __le32 MACRxLengthErrCount; /* 104 x68 R */ - __le32 IPTxPacketCount; /* 108 x6c R */ - __le32 IPTxByteCount; /* 112 x70 R */ - __le32 IPTxFragmentCount; /* 116 x74 R */ - __le32 IPRxPacketCount; /* 120 x78 R */ - __le32 IPRxByteCount; /* 124 x7c R */ - __le32 IPRxFragmentCount; /* 128 x80 R */ - __le32 IPDatagramReassemblyCount; /* 132 x84 R */ - __le32 IPV6RxPacketCount; /* 136 x88 R */ - __le32 IPErrPacketCount; /* 140 x8c R */ - __le32 IPReassemblyErrCount; /* 144 x90 R */ - __le32 TCPTxSegmentCount; /* 148 x94 R */ - __le32 TCPTxByteCount; /* 152 x98 R */ - __le32 TCPRxSegmentCount; /* 156 x9c R */ - __le32 TCPRxByteCount; /* 160 xa0 R */ - __le32 TCPTimerExpCount; /* 164 xa4 R */ - __le32 TCPRxAckCount; /* 168 xa8 R */ - __le32 TCPTxAckCount; /* 172 xac R */ - __le32 TCPRxErrOOOCount; /* 176 xb0 R */ - __le32 PSReserved0; /* 180 xb4 */ - __le32 TCPRxWindowProbeUpdateCount; /* 184 xb8 R */ - __le32 ECCErrCorrectionCount; /* 188 xbc R */ - __le32 PSReserved1[16]; /* 192 xc0 */ -}; - - -/* remote register set (access via PCI memory read/write) */ -struct isp_reg { -#define MBOX_REG_COUNT 8 - __le32 mailbox[MBOX_REG_COUNT]; - - __le32 flash_address; /* 0x20 */ - __le32 flash_data; - __le32 ctrl_status; - - union { - struct { - __le32 nvram; - __le32 reserved1[2]; /* 0x30 */ - } __attribute__ ((packed)) isp4010; - struct { - __le32 intr_mask; - __le32 nvram; /* 0x30 */ - __le32 semaphore; - } __attribute__ ((packed)) isp4022; - } u1; - - __le32 req_q_in; /* SCSI Request Queue Producer Index */ - __le32 rsp_q_out; /* SCSI Completion Queue Consumer Index */ - - __le32 reserved2[4]; /* 0x40 */ - - union { - struct { - __le32 ext_hw_conf; /* 0x50 */ - __le32 flow_ctrl; - __le32 port_ctrl; - __le32 port_status; - - __le32 reserved3[8]; /* 0x60 */ - - __le32 req_q_out; /* 0x80 */ - - __le32 reserved4[23]; /* 0x84 */ - - __le32 gp_out; /* 0xe0 */ - __le32 gp_in; - - __le32 reserved5[5]; - - __le32 port_err_status; /* 0xfc */ - } __attribute__ ((packed)) isp4010; - struct { - union { - struct port_ctrl_stat_regs p0; - struct host_mem_cfg_regs p1; - struct local_ram_cfg_regs p2; - struct prot_stat_regs p3; - __le32 r_union[44]; - }; - - } __attribute__ ((packed)) isp4022; - } u2; -}; /* 256 x100 */ - - -/* Semaphore Defines for 4010 */ -#define QL4010_DRVR_SEM_BITS 0x00000030 -#define QL4010_GPIO_SEM_BITS 0x000000c0 -#define QL4010_SDRAM_SEM_BITS 0x00000300 -#define QL4010_PHY_SEM_BITS 0x00000c00 -#define QL4010_NVRAM_SEM_BITS 0x00003000 -#define QL4010_FLASH_SEM_BITS 0x0000c000 - -#define QL4010_DRVR_SEM_MASK 0x00300000 -#define QL4010_GPIO_SEM_MASK 0x00c00000 -#define QL4010_SDRAM_SEM_MASK 0x03000000 -#define QL4010_PHY_SEM_MASK 0x0c000000 -#define QL4010_NVRAM_SEM_MASK 0x30000000 -#define QL4010_FLASH_SEM_MASK 0xc0000000 - -/* Semaphore Defines for 4022 */ -#define QL4022_RESOURCE_MASK_BASE_CODE 0x7 -#define QL4022_RESOURCE_BITS_BASE_CODE 0x4 - - -#define QL4022_DRVR_SEM_MASK (QL4022_RESOURCE_MASK_BASE_CODE << (1+16)) -#define QL4022_DDR_RAM_SEM_MASK (QL4022_RESOURCE_MASK_BASE_CODE << (4+16)) -#define QL4022_PHY_GIO_SEM_MASK (QL4022_RESOURCE_MASK_BASE_CODE << (7+16)) -#define QL4022_NVRAM_SEM_MASK (QL4022_RESOURCE_MASK_BASE_CODE << (10+16)) -#define QL4022_FLASH_SEM_MASK (QL4022_RESOURCE_MASK_BASE_CODE << (13+16)) - - - -/* Page # defines for 4022 */ -#define PORT_CTRL_STAT_PAGE 0 /* 4022 */ -#define HOST_MEM_CFG_PAGE 1 /* 4022 */ -#define LOCAL_RAM_CFG_PAGE 2 /* 4022 */ -#define PROT_STAT_PAGE 3 /* 4022 */ - -/* Register Mask - sets corresponding mask bits in the upper word */ -static inline uint32_t set_rmask(uint32_t val) -{ - return (val & 0xffff) | (val << 16); -} - - -static inline uint32_t clr_rmask(uint32_t val) -{ - return 0 | (val << 16); -} - -/* ctrl_status definitions */ -#define CSR_SCSI_PAGE_SELECT 0x00000003 -#define CSR_SCSI_INTR_ENABLE 0x00000004 /* 4010 */ -#define CSR_SCSI_RESET_INTR 0x00000008 -#define CSR_SCSI_COMPLETION_INTR 0x00000010 -#define CSR_SCSI_PROCESSOR_INTR 0x00000020 -#define CSR_INTR_RISC 0x00000040 -#define CSR_BOOT_ENABLE 0x00000080 -#define CSR_NET_PAGE_SELECT 0x00000300 /* 4010 */ -#define CSR_FUNC_NUM 0x00000700 /* 4022 */ -#define CSR_NET_RESET_INTR 0x00000800 /* 4010 */ -#define CSR_FORCE_SOFT_RESET 0x00002000 /* 4022 */ -#define CSR_FATAL_ERROR 0x00004000 -#define CSR_SOFT_RESET 0x00008000 -#define ISP_CONTROL_FN_MASK CSR_FUNC_NUM -#define ISP_CONTROL_FN0_SCSI 0x0500 -#define ISP_CONTROL_FN1_SCSI 0x0700 - -#define INTR_PENDING (CSR_SCSI_COMPLETION_INTR |\ - CSR_SCSI_PROCESSOR_INTR |\ - CSR_SCSI_RESET_INTR) - -/* ISP InterruptMask definitions */ -#define IMR_SCSI_INTR_ENABLE 0x00000004 /* 4022 */ - -/* ISP 4022 nvram definitions */ -#define NVR_WRITE_ENABLE 0x00000010 /* 4022 */ - -/* ISP port_status definitions */ - -/* ISP Semaphore definitions */ - -/* ISP General Purpose Output definitions */ -#define GPOR_TOPCAT_RESET 0x00000004 - -/* shadow registers (DMA'd from HA to system memory. read only) */ -struct shadow_regs { - /* SCSI Request Queue Consumer Index */ - __le32 req_q_out; /* 0 x0 R */ - - /* SCSI Completion Queue Producer Index */ - __le32 rsp_q_in; /* 4 x4 R */ -}; /* 8 x8 */ - - -/* External hardware configuration register */ -union external_hw_config_reg { - struct { - /* FIXME: Do we even need this? All values are - * referred to by 16 bit quantities. Platform and - * endianess issues. */ - __le32 bReserved0:1; - __le32 bSDRAMProtectionMethod:2; - __le32 bSDRAMBanks:1; - __le32 bSDRAMChipWidth:1; - __le32 bSDRAMChipSize:2; - __le32 bParityDisable:1; - __le32 bExternalMemoryType:1; - __le32 bFlashBIOSWriteEnable:1; - __le32 bFlashUpperBankSelect:1; - __le32 bWriteBurst:2; - __le32 bReserved1:3; - __le32 bMask:16; - }; - uint32_t Asuint32_t; -}; - -/************************************************************************* - * - * Mailbox Commands Structures and Definitions - * - *************************************************************************/ - -/* Mailbox command definitions */ -#define MBOX_CMD_ABOUT_FW 0x0009 -#define MBOX_CMD_LUN_RESET 0x0016 -#define MBOX_CMD_GET_FW_STATUS 0x001F -#define MBOX_CMD_SET_ISNS_SERVICE 0x0021 -#define ISNS_DISABLE 0 -#define ISNS_ENABLE 1 -#define MBOX_CMD_READ_FLASH 0x0026 -#define MBOX_CMD_CLEAR_DATABASE_ENTRY 0x0031 -#define MBOX_CMD_CONN_CLOSE_SESS_LOGOUT 0x0056 -#define LOGOUT_OPTION_CLOSE_SESSION 0x01 -#define LOGOUT_OPTION_RELOGIN 0x02 -#define MBOX_CMD_EXECUTE_IOCB_A64 0x005A -#define MBOX_CMD_INITIALIZE_FIRMWARE 0x0060 -#define MBOX_CMD_GET_INIT_FW_CTRL_BLOCK 0x0061 -#define MBOX_CMD_REQUEST_DATABASE_ENTRY 0x0062 -#define MBOX_CMD_SET_DATABASE_ENTRY 0x0063 -#define MBOX_CMD_GET_DATABASE_ENTRY 0x0064 -#define DDB_DS_UNASSIGNED 0x00 -#define DDB_DS_NO_CONNECTION_ACTIVE 0x01 -#define DDB_DS_SESSION_ACTIVE 0x04 -#define DDB_DS_SESSION_FAILED 0x06 -#define DDB_DS_LOGIN_IN_PROCESS 0x07 -#define MBOX_CMD_GET_FW_STATE 0x0069 - -/* Mailbox 1 */ -#define FW_STATE_READY 0x0000 -#define FW_STATE_CONFIG_WAIT 0x0001 -#define FW_STATE_ERROR 0x0004 -#define FW_STATE_DHCP_IN_PROGRESS 0x0008 - -/* Mailbox 3 */ -#define FW_ADDSTATE_OPTICAL_MEDIA 0x0001 -#define FW_ADDSTATE_DHCP_ENABLED 0x0002 -#define FW_ADDSTATE_LINK_UP 0x0010 -#define FW_ADDSTATE_ISNS_SVC_ENABLED 0x0020 -#define MBOX_CMD_GET_DATABASE_ENTRY_DEFAULTS 0x006B -#define MBOX_CMD_CONN_OPEN_SESS_LOGIN 0x0074 -#define MBOX_CMD_GET_CRASH_RECORD 0x0076 /* 4010 only */ -#define MBOX_CMD_GET_CONN_EVENT_LOG 0x0077 - -/* Mailbox status definitions */ -#define MBOX_COMPLETION_STATUS 4 -#define MBOX_STS_BUSY 0x0007 -#define MBOX_STS_INTERMEDIATE_COMPLETION 0x1000 -#define MBOX_STS_COMMAND_COMPLETE 0x4000 -#define MBOX_STS_COMMAND_ERROR 0x4005 - -#define MBOX_ASYNC_EVENT_STATUS 8 -#define MBOX_ASTS_SYSTEM_ERROR 0x8002 -#define MBOX_ASTS_REQUEST_TRANSFER_ERROR 0x8003 -#define MBOX_ASTS_RESPONSE_TRANSFER_ERROR 0x8004 -#define MBOX_ASTS_PROTOCOL_STATISTIC_ALARM 0x8005 -#define MBOX_ASTS_SCSI_COMMAND_PDU_REJECTED 0x8006 -#define MBOX_ASTS_LINK_UP 0x8010 -#define MBOX_ASTS_LINK_DOWN 0x8011 -#define MBOX_ASTS_DATABASE_CHANGED 0x8014 -#define MBOX_ASTS_UNSOLICITED_PDU_RECEIVED 0x8015 -#define MBOX_ASTS_SELF_TEST_FAILED 0x8016 -#define MBOX_ASTS_LOGIN_FAILED 0x8017 -#define MBOX_ASTS_DNS 0x8018 -#define MBOX_ASTS_HEARTBEAT 0x8019 -#define MBOX_ASTS_NVRAM_INVALID 0x801A -#define MBOX_ASTS_MAC_ADDRESS_CHANGED 0x801B -#define MBOX_ASTS_IP_ADDRESS_CHANGED 0x801C -#define MBOX_ASTS_DHCP_LEASE_EXPIRED 0x801D -#define MBOX_ASTS_DHCP_LEASE_ACQUIRED 0x801F -#define MBOX_ASTS_ISNS_UNSOLICITED_PDU_RECEIVED 0x8021 -#define ISNS_EVENT_DATA_RECEIVED 0x0000 -#define ISNS_EVENT_CONNECTION_OPENED 0x0001 -#define ISNS_EVENT_CONNECTION_FAILED 0x0002 -#define MBOX_ASTS_IPSEC_SYSTEM_FATAL_ERROR 0x8022 -#define MBOX_ASTS_SUBNET_STATE_CHANGE 0x8027 - -/*************************************************************************/ - -/* Host Adapter Initialization Control Block (from host) */ -struct init_fw_ctrl_blk { - uint8_t Version; /* 00 */ - uint8_t Control; /* 01 */ - - uint16_t FwOptions; /* 02-03 */ -#define FWOPT_HEARTBEAT_ENABLE 0x1000 -#define FWOPT_SESSION_MODE 0x0040 -#define FWOPT_INITIATOR_MODE 0x0020 -#define FWOPT_TARGET_MODE 0x0010 - - uint16_t ExecThrottle; /* 04-05 */ - uint8_t RetryCount; /* 06 */ - uint8_t RetryDelay; /* 07 */ - uint16_t MaxEthFrPayloadSize; /* 08-09 */ - uint16_t AddFwOptions; /* 0A-0B */ - - uint8_t HeartbeatInterval; /* 0C */ - uint8_t InstanceNumber; /* 0D */ - uint16_t RES2; /* 0E-0F */ - uint16_t ReqQConsumerIndex; /* 10-11 */ - uint16_t ComplQProducerIndex; /* 12-13 */ - uint16_t ReqQLen; /* 14-15 */ - uint16_t ComplQLen; /* 16-17 */ - uint32_t ReqQAddrLo; /* 18-1B */ - uint32_t ReqQAddrHi; /* 1C-1F */ - uint32_t ComplQAddrLo; /* 20-23 */ - uint32_t ComplQAddrHi; /* 24-27 */ - uint32_t ShadowRegBufAddrLo; /* 28-2B */ - uint32_t ShadowRegBufAddrHi; /* 2C-2F */ - - uint16_t iSCSIOptions; /* 30-31 */ - - uint16_t TCPOptions; /* 32-33 */ - - uint16_t IPOptions; /* 34-35 */ - - uint16_t MaxPDUSize; /* 36-37 */ - uint16_t RcvMarkerInt; /* 38-39 */ - uint16_t SndMarkerInt; /* 3A-3B */ - uint16_t InitMarkerlessInt; /* 3C-3D */ - uint16_t FirstBurstSize; /* 3E-3F */ - uint16_t DefaultTime2Wait; /* 40-41 */ - uint16_t DefaultTime2Retain; /* 42-43 */ - uint16_t MaxOutStndngR2T; /* 44-45 */ - uint16_t KeepAliveTimeout; /* 46-47 */ - uint16_t PortNumber; /* 48-49 */ - uint16_t MaxBurstSize; /* 4A-4B */ - uint32_t RES4; /* 4C-4F */ - uint8_t IPAddr[4]; /* 50-53 */ - uint8_t RES5[12]; /* 54-5F */ - uint8_t SubnetMask[4]; /* 60-63 */ - uint8_t RES6[12]; /* 64-6F */ - uint8_t GatewayIPAddr[4]; /* 70-73 */ - uint8_t RES7[12]; /* 74-7F */ - uint8_t PriDNSIPAddr[4]; /* 80-83 */ - uint8_t SecDNSIPAddr[4]; /* 84-87 */ - uint8_t RES8[8]; /* 88-8F */ - uint8_t Alias[32]; /* 90-AF */ - uint8_t TargAddr[8]; /* B0-B7 *//* /FIXME: Remove?? */ - uint8_t CHAPNameSecretsTable[8]; /* B8-BF */ - uint8_t EthernetMACAddr[6]; /* C0-C5 */ - uint16_t TargetPortalGroup; /* C6-C7 */ - uint8_t SendScale; /* C8 */ - uint8_t RecvScale; /* C9 */ - uint8_t TypeOfService; /* CA */ - uint8_t Time2Live; /* CB */ - uint16_t VLANPriority; /* CC-CD */ - uint16_t Reserved8; /* CE-CF */ - uint8_t SecIPAddr[4]; /* D0-D3 */ - uint8_t Reserved9[12]; /* D4-DF */ - uint8_t iSNSIPAddr[4]; /* E0-E3 */ - uint16_t iSNSServerPortNumber; /* E4-E5 */ - uint8_t Reserved10[10]; /* E6-EF */ - uint8_t SLPDAIPAddr[4]; /* F0-F3 */ - uint8_t Reserved11[12]; /* F4-FF */ - uint8_t iSCSINameString[256]; /* 100-1FF */ -}; - -/*************************************************************************/ - -struct dev_db_entry { - uint8_t options; /* 00 */ -#define DDB_OPT_DISC_SESSION 0x10 -#define DDB_OPT_TARGET 0x02 /* device is a target */ - - uint8_t control; /* 01 */ - - uint16_t exeThrottle; /* 02-03 */ - uint16_t exeCount; /* 04-05 */ - uint8_t retryCount; /* 06 */ - uint8_t retryDelay; /* 07 */ - uint16_t iSCSIOptions; /* 08-09 */ - - uint16_t TCPOptions; /* 0A-0B */ - - uint16_t IPOptions; /* 0C-0D */ - - uint16_t maxPDUSize; /* 0E-0F */ - uint16_t rcvMarkerInt; /* 10-11 */ - uint16_t sndMarkerInt; /* 12-13 */ - uint16_t iSCSIMaxSndDataSegLen; /* 14-15 */ - uint16_t firstBurstSize; /* 16-17 */ - uint16_t minTime2Wait; /* 18-19 : RA :default_time2wait */ - uint16_t maxTime2Retain; /* 1A-1B */ - uint16_t maxOutstndngR2T; /* 1C-1D */ - uint16_t keepAliveTimeout; /* 1E-1F */ - uint8_t ISID[6]; /* 20-25 big-endian, must be converted - * to little-endian */ - uint16_t TSID; /* 26-27 */ - uint16_t portNumber; /* 28-29 */ - uint16_t maxBurstSize; /* 2A-2B */ - uint16_t taskMngmntTimeout; /* 2C-2D */ - uint16_t reserved1; /* 2E-2F */ - uint8_t ipAddr[0x10]; /* 30-3F */ - uint8_t iSCSIAlias[0x20]; /* 40-5F */ - uint8_t targetAddr[0x20]; /* 60-7F */ - uint8_t userID[0x20]; /* 80-9F */ - uint8_t password[0x20]; /* A0-BF */ - uint8_t iscsiName[0x100]; /* C0-1BF : xxzzy Make this a - * pointer to a string so we - * don't have to reserve soooo - * much RAM */ - uint16_t ddbLink; /* 1C0-1C1 */ - uint16_t CHAPTableIndex; /* 1C2-1C3 */ - uint16_t TargetPortalGroup; /* 1C4-1C5 */ - uint16_t reserved2[2]; /* 1C6-1C7 */ - uint32_t statSN; /* 1C8-1CB */ - uint32_t expStatSN; /* 1CC-1CF */ - uint16_t reserved3[0x2C]; /* 1D0-1FB */ - uint16_t ddbValidCookie; /* 1FC-1FD */ - uint16_t ddbValidSize; /* 1FE-1FF */ -}; - -/*************************************************************************/ - -/* Flash definitions */ - -#define FLASH_OFFSET_SYS_INFO 0x02000000 -#define FLASH_DEFAULTBLOCKSIZE 0x20000 -#define FLASH_EOF_OFFSET (FLASH_DEFAULTBLOCKSIZE-8) /* 4 bytes - * for EOF - * signature */ - -struct sys_info_phys_addr { - uint8_t address[6]; /* 00-05 */ - uint8_t filler[2]; /* 06-07 */ -}; - -struct flash_sys_info { - uint32_t cookie; /* 00-03 */ - uint32_t physAddrCount; /* 04-07 */ - struct sys_info_phys_addr physAddr[4]; /* 08-27 */ - uint8_t vendorId[128]; /* 28-A7 */ - uint8_t productId[128]; /* A8-127 */ - uint32_t serialNumber; /* 128-12B */ - - /* PCI Configuration values */ - uint32_t pciDeviceVendor; /* 12C-12F */ - uint32_t pciDeviceId; /* 130-133 */ - uint32_t pciSubsysVendor; /* 134-137 */ - uint32_t pciSubsysId; /* 138-13B */ - - /* This validates version 1. */ - uint32_t crumbs; /* 13C-13F */ - - uint32_t enterpriseNumber; /* 140-143 */ - - uint32_t mtu; /* 144-147 */ - uint32_t reserved0; /* 148-14b */ - uint32_t crumbs2; /* 14c-14f */ - uint8_t acSerialNumber[16]; /* 150-15f */ - uint32_t crumbs3; /* 160-16f */ - - /* Leave this last in the struct so it is declared invalid if - * any new items are added. - */ - uint32_t reserved1[39]; /* 170-1ff */ -}; /* 200 */ - -struct crash_record { - uint16_t fw_major_version; /* 00 - 01 */ - uint16_t fw_minor_version; /* 02 - 03 */ - uint16_t fw_patch_version; /* 04 - 05 */ - uint16_t fw_build_version; /* 06 - 07 */ - - uint8_t build_date[16]; /* 08 - 17 */ - uint8_t build_time[16]; /* 18 - 27 */ - uint8_t build_user[16]; /* 28 - 37 */ - uint8_t card_serial_num[16]; /* 38 - 47 */ - - uint32_t time_of_crash_in_secs; /* 48 - 4B */ - uint32_t time_of_crash_in_ms; /* 4C - 4F */ - - uint16_t out_RISC_sd_num_frames; /* 50 - 51 */ - uint16_t OAP_sd_num_words; /* 52 - 53 */ - uint16_t IAP_sd_num_frames; /* 54 - 55 */ - uint16_t in_RISC_sd_num_words; /* 56 - 57 */ - - uint8_t reserved1[28]; /* 58 - 7F */ - - uint8_t out_RISC_reg_dump[256]; /* 80 -17F */ - uint8_t in_RISC_reg_dump[256]; /*180 -27F */ - uint8_t in_out_RISC_stack_dump[0]; /*280 - ??? */ -}; - -struct conn_event_log_entry { -#define MAX_CONN_EVENT_LOG_ENTRIES 100 - uint32_t timestamp_sec; /* 00 - 03 seconds since boot */ - uint32_t timestamp_ms; /* 04 - 07 milliseconds since boot */ - uint16_t device_index; /* 08 - 09 */ - uint16_t fw_conn_state; /* 0A - 0B */ - uint8_t event_type; /* 0C - 0C */ - uint8_t error_code; /* 0D - 0D */ - uint16_t error_code_detail; /* 0E - 0F */ - uint8_t num_consecutive_events; /* 10 - 10 */ - uint8_t rsvd[3]; /* 11 - 13 */ -}; - -/************************************************************************* - * - * IOCB Commands Structures and Definitions - * - *************************************************************************/ -#define IOCB_MAX_CDB_LEN 16 /* Bytes in a CBD */ -#define IOCB_MAX_SENSEDATA_LEN 32 /* Bytes of sense data */ - -/* IOCB header structure */ -struct qla4_header { - uint8_t entryType; -#define ET_STATUS 0x03 -#define ET_MARKER 0x04 -#define ET_CONT_T1 0x0A -#define ET_STATUS_CONTINUATION 0x10 -#define ET_CMND_T3 0x19 -#define ET_PASSTHRU0 0x3A -#define ET_PASSTHRU_STATUS 0x3C - - uint8_t entryStatus; - uint8_t systemDefined; - uint8_t entryCount; - - /* SyetemDefined definition */ -}; - -/* Generic queue entry structure*/ -struct queue_entry { - uint8_t data[60]; - uint32_t signature; - -}; - -/* 64 bit addressing segment counts*/ - -#define COMMAND_SEG_A64 1 -#define CONTINUE_SEG_A64 5 - -/* 64 bit addressing segment definition*/ - -struct data_seg_a64 { - struct { - uint32_t addrLow; - uint32_t addrHigh; - - } base; - - uint32_t count; - -}; - -/* Command Type 3 entry structure*/ - -struct command_t3_entry { - struct qla4_header hdr; /* 00-03 */ - - uint32_t handle; /* 04-07 */ - uint16_t target; /* 08-09 */ - uint16_t connection_id; /* 0A-0B */ - - uint8_t control_flags; /* 0C */ - - /* data direction (bits 5-6) */ -#define CF_WRITE 0x20 -#define CF_READ 0x40 -#define CF_NO_DATA 0x00 - - /* task attributes (bits 2-0) */ -#define CF_HEAD_TAG 0x03 -#define CF_ORDERED_TAG 0x02 -#define CF_SIMPLE_TAG 0x01 - - /* STATE FLAGS FIELD IS A PLACE HOLDER. THE FW WILL SET BITS - * IN THIS FIELD AS THE COMMAND IS PROCESSED. WHEN THE IOCB IS - * CHANGED TO AN IOSB THIS FIELD WILL HAVE THE STATE FLAGS SET - * PROPERLY. - */ - uint8_t state_flags; /* 0D */ - uint8_t cmdRefNum; /* 0E */ - uint8_t reserved1; /* 0F */ - uint8_t cdb[IOCB_MAX_CDB_LEN]; /* 10-1F */ - struct scsi_lun lun; /* FCP LUN (BE). */ - uint32_t cmdSeqNum; /* 28-2B */ - uint16_t timeout; /* 2C-2D */ - uint16_t dataSegCnt; /* 2E-2F */ - uint32_t ttlByteCnt; /* 30-33 */ - struct data_seg_a64 dataseg[COMMAND_SEG_A64]; /* 34-3F */ - -}; - - -/* Continuation Type 1 entry structure*/ -struct continuation_t1_entry { - struct qla4_header hdr; - - struct data_seg_a64 dataseg[CONTINUE_SEG_A64]; - -}; - -/* Parameterize for 64 or 32 bits */ -#define COMMAND_SEG COMMAND_SEG_A64 -#define CONTINUE_SEG CONTINUE_SEG_A64 - -#define ET_COMMAND ET_CMND_T3 -#define ET_CONTINUE ET_CONT_T1 - -/* Marker entry structure*/ -struct marker_entry { - struct qla4_header hdr; /* 00-03 */ - - uint32_t system_defined; /* 04-07 */ - uint16_t target; /* 08-09 */ - uint16_t modifier; /* 0A-0B */ -#define MM_LUN_RESET 0 - - uint16_t flags; /* 0C-0D */ - uint16_t reserved1; /* 0E-0F */ - struct scsi_lun lun; /* FCP LUN (BE). */ - uint64_t reserved2; /* 18-1F */ - uint64_t reserved3; /* 20-27 */ - uint64_t reserved4; /* 28-2F */ - uint64_t reserved5; /* 30-37 */ - uint64_t reserved6; /* 38-3F */ -}; - -/* Status entry structure*/ -struct status_entry { - struct qla4_header hdr; /* 00-03 */ - - uint32_t handle; /* 04-07 */ - - uint8_t scsiStatus; /* 08 */ -#define SCSI_CHECK_CONDITION 0x02 - - uint8_t iscsiFlags; /* 09 */ -#define ISCSI_FLAG_RESIDUAL_UNDER 0x02 -#define ISCSI_FLAG_RESIDUAL_OVER 0x04 - - uint8_t iscsiResponse; /* 0A */ - - uint8_t completionStatus; /* 0B */ -#define SCS_COMPLETE 0x00 -#define SCS_INCOMPLETE 0x01 -#define SCS_RESET_OCCURRED 0x04 -#define SCS_ABORTED 0x05 -#define SCS_TIMEOUT 0x06 -#define SCS_DATA_OVERRUN 0x07 -#define SCS_DATA_UNDERRUN 0x15 -#define SCS_QUEUE_FULL 0x1C -#define SCS_DEVICE_UNAVAILABLE 0x28 -#define SCS_DEVICE_LOGGED_OUT 0x29 - - uint8_t reserved1; /* 0C */ - - /* state_flags MUST be at the same location as state_flags in - * the Command_T3/4_Entry */ - uint8_t state_flags; /* 0D */ - - uint16_t senseDataByteCnt; /* 0E-0F */ - uint32_t residualByteCnt; /* 10-13 */ - uint32_t bidiResidualByteCnt; /* 14-17 */ - uint32_t expSeqNum; /* 18-1B */ - uint32_t maxCmdSeqNum; /* 1C-1F */ - uint8_t senseData[IOCB_MAX_SENSEDATA_LEN]; /* 20-3F */ - -}; - -struct passthru0 { - struct qla4_header hdr; /* 00-03 */ - uint32_t handle; /* 04-07 */ - uint16_t target; /* 08-09 */ - uint16_t connectionID; /* 0A-0B */ -#define ISNS_DEFAULT_SERVER_CONN_ID ((uint16_t)0x8000) - - uint16_t controlFlags; /* 0C-0D */ -#define PT_FLAG_ETHERNET_FRAME 0x8000 -#define PT_FLAG_ISNS_PDU 0x8000 -#define PT_FLAG_SEND_BUFFER 0x0200 -#define PT_FLAG_WAIT_4_RESPONSE 0x0100 - - uint16_t timeout; /* 0E-0F */ -#define PT_DEFAULT_TIMEOUT 30 /* seconds */ - - struct data_seg_a64 outDataSeg64; /* 10-1B */ - uint32_t res1; /* 1C-1F */ - struct data_seg_a64 inDataSeg64; /* 20-2B */ - uint8_t res2[20]; /* 2C-3F */ -}; - -struct passthru_status { - struct qla4_header hdr; /* 00-03 */ - uint32_t handle; /* 04-07 */ - uint16_t target; /* 08-09 */ - uint16_t connectionID; /* 0A-0B */ - - uint8_t completionStatus; /* 0C */ -#define PASSTHRU_STATUS_COMPLETE 0x01 - - uint8_t residualFlags; /* 0D */ - - uint16_t timeout; /* 0E-0F */ - uint16_t portNumber; /* 10-11 */ - uint8_t res1[10]; /* 12-1B */ - uint32_t outResidual; /* 1C-1F */ - uint8_t res2[12]; /* 20-2B */ - uint32_t inResidual; /* 2C-2F */ - uint8_t res4[16]; /* 30-3F */ -}; - -#endif /* _QLA4X_FW_H */ diff --git a/trunk/drivers/scsi/qla4xxx/ql4_glbl.h b/trunk/drivers/scsi/qla4xxx/ql4_glbl.h deleted file mode 100644 index 1b221ff0f6f7..000000000000 --- a/trunk/drivers/scsi/qla4xxx/ql4_glbl.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * QLogic iSCSI HBA Driver - * Copyright (c) 2003-2006 QLogic Corporation - * - * See LICENSE.qla4xxx for copyright and licensing details. - */ - -#ifndef __QLA4x_GBL_H -#define __QLA4x_GBL_H - -int qla4xxx_send_tgts(struct scsi_qla_host *ha, char *ip, uint16_t port); -int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb * srb); -int qla4xxx_initialize_adapter(struct scsi_qla_host * ha, - uint8_t renew_ddb_list); -int qla4xxx_soft_reset(struct scsi_qla_host *ha); -irqreturn_t qla4xxx_intr_handler(int irq, void *dev_id); - -void qla4xxx_free_ddb_list(struct scsi_qla_host * ha); -void qla4xxx_process_aen(struct scsi_qla_host * ha, uint8_t process_aen); - -int qla4xxx_get_dhcp_ip_address(struct scsi_qla_host * ha); -int qla4xxx_relogin_device(struct scsi_qla_host * ha, - struct ddb_entry * ddb_entry); -int qla4xxx_reset_lun(struct scsi_qla_host * ha, struct ddb_entry * ddb_entry, - int lun); -int qla4xxx_get_flash(struct scsi_qla_host * ha, dma_addr_t dma_addr, - uint32_t offset, uint32_t len); -int qla4xxx_get_firmware_status(struct scsi_qla_host * ha); -int qla4xxx_get_firmware_state(struct scsi_qla_host * ha); -int qla4xxx_initialize_fw_cb(struct scsi_qla_host * ha); - -/* FIXME: Goodness! this really wants a small struct to hold the - * parameters. On x86 the args will get passed on the stack! */ -int qla4xxx_get_fwddb_entry(struct scsi_qla_host *ha, - uint16_t fw_ddb_index, - struct dev_db_entry *fw_ddb_entry, - dma_addr_t fw_ddb_entry_dma, - uint32_t *num_valid_ddb_entries, - uint32_t *next_ddb_index, - uint32_t *fw_ddb_device_state, - uint32_t *conn_err_detail, - uint16_t *tcp_source_port_num, - uint16_t *connection_id); - -struct ddb_entry * qla4xxx_alloc_ddb(struct scsi_qla_host * ha, - uint32_t fw_ddb_index); -int qla4xxx_set_ddb_entry(struct scsi_qla_host * ha, uint16_t fw_ddb_index, - dma_addr_t fw_ddb_entry_dma); - -void qla4xxx_mark_device_missing(struct scsi_qla_host *ha, - struct ddb_entry *ddb_entry); -u16 rd_nvram_word(struct scsi_qla_host * ha, int offset); -void qla4xxx_get_crash_record(struct scsi_qla_host * ha); -struct ddb_entry *qla4xxx_alloc_sess(struct scsi_qla_host *ha); -int qla4xxx_add_sess(struct ddb_entry *); -void qla4xxx_destroy_sess(struct ddb_entry *ddb_entry); -int qla4xxx_conn_close_sess_logout(struct scsi_qla_host * ha, - uint16_t fw_ddb_index, - uint16_t connection_id, - uint16_t option); -int qla4xxx_clear_database_entry(struct scsi_qla_host * ha, - uint16_t fw_ddb_index); -int qla4xxx_is_nvram_configuration_valid(struct scsi_qla_host * ha); -int qla4xxx_get_fw_version(struct scsi_qla_host * ha); -void qla4xxx_interrupt_service_routine(struct scsi_qla_host * ha, - uint32_t intr_status); -int qla4xxx_init_rings(struct scsi_qla_host * ha); -void qla4xxx_dump_buffer(void *b, uint32_t size); -struct srb * qla4xxx_del_from_active_array(struct scsi_qla_host *ha, uint32_t index); -void qla4xxx_srb_compl(struct scsi_qla_host *ha, struct srb *srb); -int qla4xxx_reinitialize_ddb_list(struct scsi_qla_host * ha); -int qla4xxx_process_ddb_changed(struct scsi_qla_host * ha, - uint32_t fw_ddb_index, uint32_t state); - -extern int ql4xextended_error_logging; -extern int ql4xdiscoverywait; -extern int ql4xdontresethba; -#endif /* _QLA4x_GBL_H */ diff --git a/trunk/drivers/scsi/qla4xxx/ql4_init.c b/trunk/drivers/scsi/qla4xxx/ql4_init.c deleted file mode 100644 index bb3a1c11f44c..000000000000 --- a/trunk/drivers/scsi/qla4xxx/ql4_init.c +++ /dev/null @@ -1,1340 +0,0 @@ -/* - * QLogic iSCSI HBA Driver - * Copyright (c) 2003-2006 QLogic Corporation - * - * See LICENSE.qla4xxx for copyright and licensing details. - */ - -#include "ql4_def.h" - -/* - * QLogic ISP4xxx Hardware Support Function Prototypes. - */ - -static void ql4xxx_set_mac_number(struct scsi_qla_host *ha) -{ - uint32_t value; - uint8_t func_number; - unsigned long flags; - - /* Get the function number */ - spin_lock_irqsave(&ha->hardware_lock, flags); - value = readw(&ha->reg->ctrl_status); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - func_number = (uint8_t) ((value >> 4) & 0x30); - switch (value & ISP_CONTROL_FN_MASK) { - case ISP_CONTROL_FN0_SCSI: - ha->mac_index = 1; - break; - case ISP_CONTROL_FN1_SCSI: - ha->mac_index = 3; - break; - default: - DEBUG2(printk("scsi%ld: %s: Invalid function number, " - "ispControlStatus = 0x%x\n", ha->host_no, - __func__, value)); - break; - } - DEBUG2(printk("scsi%ld: %s: mac_index %d.\n", ha->host_no, __func__, - ha->mac_index)); -} - -/** - * qla4xxx_free_ddb - deallocate ddb - * @ha: pointer to host adapter structure. - * @ddb_entry: pointer to device database entry - * - * This routine deallocates and unlinks the specified ddb_entry from the - * adapter's - **/ -void qla4xxx_free_ddb(struct scsi_qla_host *ha, struct ddb_entry *ddb_entry) -{ - /* Remove device entry from list */ - list_del_init(&ddb_entry->list); - - /* Remove device pointer from index mapping arrays */ - ha->fw_ddb_index_map[ddb_entry->fw_ddb_index] = - (struct ddb_entry *) INVALID_ENTRY; - ha->tot_ddbs--; - - /* Free memory and scsi-ml struct for device entry */ - qla4xxx_destroy_sess(ddb_entry); -} - -/** - * qla4xxx_free_ddb_list - deallocate all ddbs - * @ha: pointer to host adapter structure. - * - * This routine deallocates and removes all devices on the sppecified adapter. - **/ -void qla4xxx_free_ddb_list(struct scsi_qla_host *ha) -{ - struct list_head *ptr; - struct ddb_entry *ddb_entry; - - while (!list_empty(&ha->ddb_list)) { - ptr = ha->ddb_list.next; - /* Free memory for device entry and remove */ - ddb_entry = list_entry(ptr, struct ddb_entry, list); - qla4xxx_free_ddb(ha, ddb_entry); - } -} - -/** - * qla4xxx_init_rings - initialize hw queues - * @ha: pointer to host adapter structure. - * - * This routine initializes the internal queues for the specified adapter. - * The QLA4010 requires us to restart the queues at index 0. - * The QLA4000 doesn't care, so just default to QLA4010's requirement. - **/ -int qla4xxx_init_rings(struct scsi_qla_host *ha) -{ - unsigned long flags = 0; - - /* Initialize request queue. */ - spin_lock_irqsave(&ha->hardware_lock, flags); - ha->request_out = 0; - ha->request_in = 0; - ha->request_ptr = &ha->request_ring[ha->request_in]; - ha->req_q_count = REQUEST_QUEUE_DEPTH; - - /* Initialize response queue. */ - ha->response_in = 0; - ha->response_out = 0; - ha->response_ptr = &ha->response_ring[ha->response_out]; - - /* - * Initialize DMA Shadow registers. The firmware is really supposed to - * take care of this, but on some uniprocessor systems, the shadow - * registers aren't cleared-- causing the interrupt_handler to think - * there are responses to be processed when there aren't. - */ - ha->shadow_regs->req_q_out = __constant_cpu_to_le32(0); - ha->shadow_regs->rsp_q_in = __constant_cpu_to_le32(0); - wmb(); - - writel(0, &ha->reg->req_q_in); - writel(0, &ha->reg->rsp_q_out); - readl(&ha->reg->rsp_q_out); - - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - return QLA_SUCCESS; -} - -/** - * qla4xxx_validate_mac_address - validate adapter MAC address(es) - * @ha: pointer to host adapter structure. - * - **/ -static int qla4xxx_validate_mac_address(struct scsi_qla_host *ha) -{ - struct flash_sys_info *sys_info; - dma_addr_t sys_info_dma; - int status = QLA_ERROR; - - sys_info = dma_alloc_coherent(&ha->pdev->dev, sizeof(*sys_info), - &sys_info_dma, GFP_KERNEL); - if (sys_info == NULL) { - DEBUG2(printk("scsi%ld: %s: Unable to allocate dma buffer.\n", - ha->host_no, __func__)); - - goto exit_validate_mac_no_free; - } - memset(sys_info, 0, sizeof(*sys_info)); - - /* Get flash sys info */ - if (qla4xxx_get_flash(ha, sys_info_dma, FLASH_OFFSET_SYS_INFO, - sizeof(*sys_info)) != QLA_SUCCESS) { - DEBUG2(printk("scsi%ld: %s: get_flash FLASH_OFFSET_SYS_INFO " - "failed\n", ha->host_no, __func__)); - - goto exit_validate_mac; - } - - /* Save M.A.C. address & serial_number */ - memcpy(ha->my_mac, &sys_info->physAddr[0].address[0], - min(sizeof(ha->my_mac), - sizeof(sys_info->physAddr[0].address))); - memcpy(ha->serial_number, &sys_info->acSerialNumber, - min(sizeof(ha->serial_number), - sizeof(sys_info->acSerialNumber))); - - status = QLA_SUCCESS; - - exit_validate_mac: - dma_free_coherent(&ha->pdev->dev, sizeof(*sys_info), sys_info, - sys_info_dma); - - exit_validate_mac_no_free: - return status; -} - -/** - * qla4xxx_init_local_data - initialize adapter specific local data - * @ha: pointer to host adapter structure. - * - **/ -static int qla4xxx_init_local_data(struct scsi_qla_host *ha) -{ - /* Initilize aen queue */ - ha->aen_q_count = MAX_AEN_ENTRIES; - - return qla4xxx_get_firmware_status(ha); -} - -static int qla4xxx_fw_ready(struct scsi_qla_host *ha) -{ - uint32_t timeout_count; - int ready = 0; - - DEBUG2(dev_info(&ha->pdev->dev, "Waiting for Firmware Ready..\n")); - for (timeout_count = ADAPTER_INIT_TOV; timeout_count > 0; - timeout_count--) { - if (test_and_clear_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags)) - qla4xxx_get_dhcp_ip_address(ha); - - /* Get firmware state. */ - if (qla4xxx_get_firmware_state(ha) != QLA_SUCCESS) { - DEBUG2(printk("scsi%ld: %s: unable to get firmware " - "state\n", ha->host_no, __func__)); - break; - - } - - if (ha->firmware_state & FW_STATE_ERROR) { - DEBUG2(printk("scsi%ld: %s: an unrecoverable error has" - " occurred\n", ha->host_no, __func__)); - break; - - } - if (ha->firmware_state & FW_STATE_CONFIG_WAIT) { - /* - * The firmware has not yet been issued an Initialize - * Firmware command, so issue it now. - */ - if (qla4xxx_initialize_fw_cb(ha) == QLA_ERROR) - break; - - /* Go back and test for ready state - no wait. */ - continue; - } - - if (ha->firmware_state == FW_STATE_READY) { - DEBUG2(dev_info(&ha->pdev->dev, "Firmware Ready..\n")); - /* The firmware is ready to process SCSI commands. */ - DEBUG2(dev_info(&ha->pdev->dev, - "scsi%ld: %s: MEDIA TYPE - %s\n", - ha->host_no, - __func__, (ha->addl_fw_state & - FW_ADDSTATE_OPTICAL_MEDIA) - != 0 ? "OPTICAL" : "COPPER")); - DEBUG2(dev_info(&ha->pdev->dev, - "scsi%ld: %s: DHCP STATE Enabled " - "%s\n", - ha->host_no, __func__, - (ha->addl_fw_state & - FW_ADDSTATE_DHCP_ENABLED) != 0 ? - "YES" : "NO")); - DEBUG2(dev_info(&ha->pdev->dev, - "scsi%ld: %s: LINK %s\n", - ha->host_no, __func__, - (ha->addl_fw_state & - FW_ADDSTATE_LINK_UP) != 0 ? - "UP" : "DOWN")); - DEBUG2(dev_info(&ha->pdev->dev, - "scsi%ld: %s: iSNS Service " - "Started %s\n", - ha->host_no, __func__, - (ha->addl_fw_state & - FW_ADDSTATE_ISNS_SVC_ENABLED) != 0 ? - "YES" : "NO")); - - ready = 1; - break; - } - DEBUG2(printk("scsi%ld: %s: waiting on fw, state=%x:%x - " - "seconds expired= %d\n", ha->host_no, __func__, - ha->firmware_state, ha->addl_fw_state, - timeout_count)); - msleep(1000); - } /* end of for */ - - if (timeout_count <= 0) - DEBUG2(printk("scsi%ld: %s: FW Initialization timed out!\n", - ha->host_no, __func__)); - - if (ha->firmware_state & FW_STATE_DHCP_IN_PROGRESS) { - DEBUG2(printk("scsi%ld: %s: FW is reporting its waiting to" - " grab an IP address from DHCP server\n", - ha->host_no, __func__)); - ready = 1; - } - - return ready; -} - -/** - * qla4xxx_init_firmware - initializes the firmware. - * @ha: pointer to host adapter structure. - * - **/ -static int qla4xxx_init_firmware(struct scsi_qla_host *ha) -{ - int status = QLA_ERROR; - - dev_info(&ha->pdev->dev, "Initializing firmware..\n"); - if (qla4xxx_initialize_fw_cb(ha) == QLA_ERROR) { - DEBUG2(printk("scsi%ld: %s: Failed to initialize firmware " - "control block\n", ha->host_no, __func__)); - return status; - } - if (!qla4xxx_fw_ready(ha)) - return status; - - set_bit(AF_ONLINE, &ha->flags); - return qla4xxx_get_firmware_status(ha); -} - -static struct ddb_entry* qla4xxx_get_ddb_entry(struct scsi_qla_host *ha, - uint32_t fw_ddb_index) -{ - struct dev_db_entry *fw_ddb_entry = NULL; - dma_addr_t fw_ddb_entry_dma; - struct ddb_entry *ddb_entry = NULL; - int found = 0; - uint32_t device_state; - - /* Make sure the dma buffer is valid */ - fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, - sizeof(*fw_ddb_entry), - &fw_ddb_entry_dma, GFP_KERNEL); - if (fw_ddb_entry == NULL) { - DEBUG2(printk("scsi%ld: %s: Unable to allocate dma buffer.\n", - ha->host_no, __func__)); - return NULL; - } - - if (qla4xxx_get_fwddb_entry(ha, fw_ddb_index, fw_ddb_entry, - fw_ddb_entry_dma, NULL, NULL, - &device_state, NULL, NULL, NULL) == - QLA_ERROR) { - DEBUG2(printk("scsi%ld: %s: failed get_ddb_entry for " - "fw_ddb_index %d\n", ha->host_no, __func__, - fw_ddb_index)); - return NULL; - } - - /* Allocate DDB if not already allocated. */ - DEBUG2(printk("scsi%ld: %s: Looking for ddb[%d]\n", ha->host_no, - __func__, fw_ddb_index)); - list_for_each_entry(ddb_entry, &ha->ddb_list, list) { - if (memcmp(ddb_entry->iscsi_name, fw_ddb_entry->iscsiName, - ISCSI_NAME_SIZE) == 0) { - found++; - break; - } - } - - if (!found) { - DEBUG2(printk("scsi%ld: %s: ddb[%d] not found - allocating " - "new ddb\n", ha->host_no, __func__, - fw_ddb_index)); - ddb_entry = qla4xxx_alloc_ddb(ha, fw_ddb_index); - } - - /* if not found allocate new ddb */ - dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), fw_ddb_entry, - fw_ddb_entry_dma); - - return ddb_entry; -} - -/** - * qla4xxx_update_ddb_entry - update driver's internal ddb - * @ha: pointer to host adapter structure. - * @ddb_entry: pointer to device database structure to be filled - * @fw_ddb_index: index of the ddb entry in fw ddb table - * - * This routine updates the driver's internal device database entry - * with information retrieved from the firmware's device database - * entry for the specified device. The ddb_entry->fw_ddb_index field - * must be initialized prior to calling this routine - * - **/ -int qla4xxx_update_ddb_entry(struct scsi_qla_host *ha, - struct ddb_entry *ddb_entry, - uint32_t fw_ddb_index) -{ - struct dev_db_entry *fw_ddb_entry = NULL; - dma_addr_t fw_ddb_entry_dma; - int status = QLA_ERROR; - - if (ddb_entry == NULL) { - DEBUG2(printk("scsi%ld: %s: ddb_entry is NULL\n", ha->host_no, - __func__)); - goto exit_update_ddb; - } - - /* Make sure the dma buffer is valid */ - fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, - sizeof(*fw_ddb_entry), - &fw_ddb_entry_dma, GFP_KERNEL); - if (fw_ddb_entry == NULL) { - DEBUG2(printk("scsi%ld: %s: Unable to allocate dma buffer.\n", - ha->host_no, __func__)); - - goto exit_update_ddb; - } - - if (qla4xxx_get_fwddb_entry(ha, fw_ddb_index, fw_ddb_entry, - fw_ddb_entry_dma, NULL, NULL, - &ddb_entry->fw_ddb_device_state, NULL, - &ddb_entry->tcp_source_port_num, - &ddb_entry->connection_id) == - QLA_ERROR) { - DEBUG2(printk("scsi%ld: %s: failed get_ddb_entry for " - "fw_ddb_index %d\n", ha->host_no, __func__, - fw_ddb_index)); - - goto exit_update_ddb; - } - - status = QLA_SUCCESS; - ddb_entry->target_session_id = le16_to_cpu(fw_ddb_entry->TSID); - ddb_entry->task_mgmt_timeout = - le16_to_cpu(fw_ddb_entry->taskMngmntTimeout); - ddb_entry->CmdSn = 0; - ddb_entry->exe_throttle = le16_to_cpu(fw_ddb_entry->exeThrottle); - ddb_entry->default_relogin_timeout = - le16_to_cpu(fw_ddb_entry->taskMngmntTimeout); - ddb_entry->default_time2wait = le16_to_cpu(fw_ddb_entry->minTime2Wait); - - /* Update index in case it changed */ - ddb_entry->fw_ddb_index = fw_ddb_index; - ha->fw_ddb_index_map[fw_ddb_index] = ddb_entry; - - ddb_entry->port = le16_to_cpu(fw_ddb_entry->portNumber); - ddb_entry->tpgt = le32_to_cpu(fw_ddb_entry->TargetPortalGroup); - memcpy(&ddb_entry->iscsi_name[0], &fw_ddb_entry->iscsiName[0], - min(sizeof(ddb_entry->iscsi_name), - sizeof(fw_ddb_entry->iscsiName))); - memcpy(&ddb_entry->ip_addr[0], &fw_ddb_entry->ipAddr[0], - min(sizeof(ddb_entry->ip_addr), sizeof(fw_ddb_entry->ipAddr))); - - DEBUG2(printk("scsi%ld: %s: ddb[%d] - State= %x status= %d.\n", - ha->host_no, __func__, fw_ddb_index, - ddb_entry->fw_ddb_device_state, status)); - - exit_update_ddb: - if (fw_ddb_entry) - dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), - fw_ddb_entry, fw_ddb_entry_dma); - - return status; -} - -/** - * qla4xxx_alloc_ddb - allocate device database entry - * @ha: Pointer to host adapter structure. - * @fw_ddb_index: Firmware's device database index - * - * This routine allocates a ddb_entry, ititializes some values, and - * inserts it into the ddb list. - **/ -struct ddb_entry * qla4xxx_alloc_ddb(struct scsi_qla_host *ha, - uint32_t fw_ddb_index) -{ - struct ddb_entry *ddb_entry; - - DEBUG2(printk("scsi%ld: %s: fw_ddb_index [%d]\n", ha->host_no, - __func__, fw_ddb_index)); - - ddb_entry = qla4xxx_alloc_sess(ha); - if (ddb_entry == NULL) { - DEBUG2(printk("scsi%ld: %s: Unable to allocate memory " - "to add fw_ddb_index [%d]\n", - ha->host_no, __func__, fw_ddb_index)); - return ddb_entry; - } - - ddb_entry->fw_ddb_index = fw_ddb_index; - atomic_set(&ddb_entry->port_down_timer, ha->port_down_retry_count); - atomic_set(&ddb_entry->retry_relogin_timer, INVALID_ENTRY); - atomic_set(&ddb_entry->relogin_timer, 0); - atomic_set(&ddb_entry->relogin_retry_count, 0); - atomic_set(&ddb_entry->state, DDB_STATE_ONLINE); - list_add_tail(&ddb_entry->list, &ha->ddb_list); - ha->fw_ddb_index_map[fw_ddb_index] = ddb_entry; - ha->tot_ddbs++; - - return ddb_entry; -} - -/** - * qla4xxx_configure_ddbs - builds driver ddb list - * @ha: Pointer to host adapter structure. - * - * This routine searches for all valid firmware ddb entries and builds - * an internal ddb list. Ddbs that are considered valid are those with - * a device state of SESSION_ACTIVE. - **/ -static int qla4xxx_build_ddb_list(struct scsi_qla_host *ha) -{ - int status = QLA_SUCCESS; - uint32_t fw_ddb_index = 0; - uint32_t next_fw_ddb_index = 0; - uint32_t ddb_state; - uint32_t conn_err, err_code; - struct ddb_entry *ddb_entry; - - dev_info(&ha->pdev->dev, "Initializing DDBs ...\n"); - for (fw_ddb_index = 0; fw_ddb_index < MAX_DDB_ENTRIES; - fw_ddb_index = next_fw_ddb_index) { - /* First, let's see if a device exists here */ - if (qla4xxx_get_fwddb_entry(ha, fw_ddb_index, NULL, 0, NULL, - &next_fw_ddb_index, &ddb_state, - &conn_err, NULL, NULL) == - QLA_ERROR) { - DEBUG2(printk("scsi%ld: %s: get_ddb_entry, " - "fw_ddb_index %d failed", ha->host_no, - __func__, fw_ddb_index)); - return QLA_ERROR; - } - - DEBUG2(printk("scsi%ld: %s: Getting DDB[%d] ddbstate=0x%x, " - "next_fw_ddb_index=%d.\n", ha->host_no, __func__, - fw_ddb_index, ddb_state, next_fw_ddb_index)); - - /* Issue relogin, if necessary. */ - if (ddb_state == DDB_DS_SESSION_FAILED || - ddb_state == DDB_DS_NO_CONNECTION_ACTIVE) { - /* Try and login to device */ - DEBUG2(printk("scsi%ld: %s: Login to DDB[%d]\n", - ha->host_no, __func__, fw_ddb_index)); - err_code = ((conn_err & 0x00ff0000) >> 16); - if (err_code == 0x1c || err_code == 0x06) { - DEBUG2(printk("scsi%ld: %s send target " - "completed " - "or access denied failure\n", - ha->host_no, __func__)); - } else - qla4xxx_set_ddb_entry(ha, fw_ddb_index, 0); - } - - if (ddb_state != DDB_DS_SESSION_ACTIVE) - goto next_one; - /* - * if fw_ddb with session active state found, - * add to ddb_list - */ - DEBUG2(printk("scsi%ld: %s: DDB[%d] added to list\n", - ha->host_no, __func__, fw_ddb_index)); - - /* Add DDB to internal our ddb list. */ - ddb_entry = qla4xxx_get_ddb_entry(ha, fw_ddb_index); - if (ddb_entry == NULL) { - DEBUG2(printk("scsi%ld: %s: Unable to allocate memory " - "for device at fw_ddb_index %d\n", - ha->host_no, __func__, fw_ddb_index)); - return QLA_ERROR; - } - /* Fill in the device structure */ - if (qla4xxx_update_ddb_entry(ha, ddb_entry, fw_ddb_index) == - QLA_ERROR) { - ha->fw_ddb_index_map[fw_ddb_index] = - (struct ddb_entry *)INVALID_ENTRY; - - - DEBUG2(printk("scsi%ld: %s: update_ddb_entry failed " - "for fw_ddb_index %d.\n", - ha->host_no, __func__, fw_ddb_index)); - return QLA_ERROR; - } - -next_one: - /* We know we've reached the last device when - * next_fw_ddb_index is 0 */ - if (next_fw_ddb_index == 0) - break; - } - - dev_info(&ha->pdev->dev, "DDB list done..\n"); - - return status; -} - -struct qla4_relog_scan { - int halt_wait; - uint32_t conn_err; - uint32_t err_code; - uint32_t fw_ddb_index; - uint32_t next_fw_ddb_index; - uint32_t fw_ddb_device_state; -}; - -static int qla4_test_rdy(struct scsi_qla_host *ha, struct qla4_relog_scan *rs) -{ - struct ddb_entry *ddb_entry; - - /* - * Don't want to do a relogin if connection - * error is 0x1c. - */ - rs->err_code = ((rs->conn_err & 0x00ff0000) >> 16); - if (rs->err_code == 0x1c || rs->err_code == 0x06) { - DEBUG2(printk( - "scsi%ld: %s send target" - " completed or " - "access denied failure\n", - ha->host_no, __func__)); - } else { - /* We either have a device that is in - * the process of relogging in or a - * device that is waiting to be - * relogged in */ - rs->halt_wait = 0; - - ddb_entry = qla4xxx_lookup_ddb_by_fw_index(ha, - rs->fw_ddb_index); - if (ddb_entry == NULL) - return QLA_ERROR; - - if (ddb_entry->dev_scan_wait_to_start_relogin != 0 - && time_after_eq(jiffies, - ddb_entry-> - dev_scan_wait_to_start_relogin)) - { - ddb_entry->dev_scan_wait_to_start_relogin = 0; - qla4xxx_set_ddb_entry(ha, rs->fw_ddb_index, 0); - } - } - return QLA_SUCCESS; -} - -static int qla4_scan_for_relogin(struct scsi_qla_host *ha, - struct qla4_relog_scan *rs) -{ - int error; - - /* scan for relogins - * ----------------- */ - for (rs->fw_ddb_index = 0; rs->fw_ddb_index < MAX_DDB_ENTRIES; - rs->fw_ddb_index = rs->next_fw_ddb_index) { - if (qla4xxx_get_fwddb_entry(ha, rs->fw_ddb_index, NULL, 0, - NULL, &rs->next_fw_ddb_index, - &rs->fw_ddb_device_state, - &rs->conn_err, NULL, NULL) - == QLA_ERROR) - return QLA_ERROR; - - if (rs->fw_ddb_device_state == DDB_DS_LOGIN_IN_PROCESS) - rs->halt_wait = 0; - - if (rs->fw_ddb_device_state == DDB_DS_SESSION_FAILED || - rs->fw_ddb_device_state == DDB_DS_NO_CONNECTION_ACTIVE) { - error = qla4_test_rdy(ha, rs); - if (error) - return error; - } - - /* We know we've reached the last device when - * next_fw_ddb_index is 0 */ - if (rs->next_fw_ddb_index == 0) - break; - } - return QLA_SUCCESS; -} - -/** - * qla4xxx_devices_ready - wait for target devices to be logged in - * @ha: pointer to adapter structure - * - * This routine waits up to ql4xdiscoverywait seconds - * F/W database during driver load time. - **/ -static int qla4xxx_devices_ready(struct scsi_qla_host *ha) -{ - int error; - unsigned long discovery_wtime; - struct qla4_relog_scan rs; - - discovery_wtime = jiffies + (ql4xdiscoverywait * HZ); - - DEBUG(printk("Waiting (%d) for devices ...\n", ql4xdiscoverywait)); - do { - /* poll for AEN. */ - qla4xxx_get_firmware_state(ha); - if (test_and_clear_bit(DPC_AEN, &ha->dpc_flags)) { - /* Set time-between-relogin timer */ - qla4xxx_process_aen(ha, RELOGIN_DDB_CHANGED_AENS); - } - - /* if no relogins active or needed, halt discvery wait */ - rs.halt_wait = 1; - - error = qla4_scan_for_relogin(ha, &rs); - - if (rs.halt_wait) { - DEBUG2(printk("scsi%ld: %s: Delay halted. Devices " - "Ready.\n", ha->host_no, __func__)); - return QLA_SUCCESS; - } - - msleep(2000); - } while (!time_after_eq(jiffies, discovery_wtime)); - - DEBUG3(qla4xxx_get_conn_event_log(ha)); - - return QLA_SUCCESS; -} - -static void qla4xxx_flush_AENS(struct scsi_qla_host *ha) -{ - unsigned long wtime; - - /* Flush the 0x8014 AEN from the firmware as a result of - * Auto connect. We are basically doing get_firmware_ddb() - * to determine whether we need to log back in or not. - * Trying to do a set ddb before we have processed 0x8014 - * will result in another set_ddb() for the same ddb. In other - * words there will be stale entries in the aen_q. - */ - wtime = jiffies + (2 * HZ); - do { - if (qla4xxx_get_firmware_state(ha) == QLA_SUCCESS) - if (ha->firmware_state & (BIT_2 | BIT_0)) - return; - - if (test_and_clear_bit(DPC_AEN, &ha->dpc_flags)) - qla4xxx_process_aen(ha, FLUSH_DDB_CHANGED_AENS); - - msleep(1000); - } while (!time_after_eq(jiffies, wtime)); - -} - -static int qla4xxx_initialize_ddb_list(struct scsi_qla_host *ha) -{ - uint16_t fw_ddb_index; - int status = QLA_SUCCESS; - - /* free the ddb list if is not empty */ - if (!list_empty(&ha->ddb_list)) - qla4xxx_free_ddb_list(ha); - - for (fw_ddb_index = 0; fw_ddb_index < MAX_DDB_ENTRIES; fw_ddb_index++) - ha->fw_ddb_index_map[fw_ddb_index] = - (struct ddb_entry *)INVALID_ENTRY; - - ha->tot_ddbs = 0; - - qla4xxx_flush_AENS(ha); - - /* - * First perform device discovery for active - * fw ddb indexes and build - * ddb list. - */ - if ((status = qla4xxx_build_ddb_list(ha)) == QLA_ERROR) - return status; - - /* Wait for an AEN */ - qla4xxx_devices_ready(ha); - - /* - * Targets can come online after the inital discovery, so processing - * the aens here will catch them. - */ - if (test_and_clear_bit(DPC_AEN, &ha->dpc_flags)) - qla4xxx_process_aen(ha, PROCESS_ALL_AENS); - - return status; -} - -/** - * qla4xxx_update_ddb_list - update the driver ddb list - * @ha: pointer to host adapter structure. - * - * This routine obtains device information from the F/W database after - * firmware or adapter resets. The device table is preserved. - **/ -int qla4xxx_reinitialize_ddb_list(struct scsi_qla_host *ha) -{ - int status = QLA_SUCCESS; - struct ddb_entry *ddb_entry, *detemp; - - /* Update the device information for all devices. */ - list_for_each_entry_safe(ddb_entry, detemp, &ha->ddb_list, list) { - qla4xxx_update_ddb_entry(ha, ddb_entry, - ddb_entry->fw_ddb_index); - if (ddb_entry->fw_ddb_device_state == DDB_DS_SESSION_ACTIVE) { - atomic_set(&ddb_entry->state, DDB_STATE_ONLINE); - DEBUG2(printk ("scsi%ld: %s: ddb index [%d] marked " - "ONLINE\n", ha->host_no, __func__, - ddb_entry->fw_ddb_index)); - } else if (atomic_read(&ddb_entry->state) == DDB_STATE_ONLINE) - qla4xxx_mark_device_missing(ha, ddb_entry); - } - return status; -} - -/** - * qla4xxx_relogin_device - re-establish session - * @ha: Pointer to host adapter structure. - * @ddb_entry: Pointer to device database entry - * - * This routine does a session relogin with the specified device. - * The ddb entry must be assigned prior to making this call. - **/ -int qla4xxx_relogin_device(struct scsi_qla_host *ha, - struct ddb_entry * ddb_entry) -{ - uint16_t relogin_timer; - - relogin_timer = max(ddb_entry->default_relogin_timeout, - (uint16_t)RELOGIN_TOV); - atomic_set(&ddb_entry->relogin_timer, relogin_timer); - - DEBUG2(printk("scsi%ld: Relogin index [%d]. TOV=%d\n", ha->host_no, - ddb_entry->fw_ddb_index, relogin_timer)); - - qla4xxx_set_ddb_entry(ha, ddb_entry->fw_ddb_index, 0); - - return QLA_SUCCESS; -} - -/** - * qla4010_get_topcat_presence - check if it is QLA4040 TopCat Chip - * @ha: Pointer to host adapter structure. - * - **/ -static int qla4010_get_topcat_presence(struct scsi_qla_host *ha) -{ - unsigned long flags; - uint16_t topcat; - - if (ql4xxx_lock_nvram(ha) != QLA_SUCCESS) - return QLA_ERROR; - spin_lock_irqsave(&ha->hardware_lock, flags); - topcat = rd_nvram_word(ha, offsetof(struct eeprom_data, - isp4010.topcat)); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - if ((topcat & TOPCAT_MASK) == TOPCAT_PRESENT) - set_bit(AF_TOPCAT_CHIP_PRESENT, &ha->flags); - else - clear_bit(AF_TOPCAT_CHIP_PRESENT, &ha->flags); - ql4xxx_unlock_nvram(ha); - return QLA_SUCCESS; -} - - -static int qla4xxx_config_nvram(struct scsi_qla_host *ha) -{ - unsigned long flags; - union external_hw_config_reg extHwConfig; - - DEBUG2(printk("scsi%ld: %s: Get EEProm parameters \n", ha->host_no, - __func__)); - if (ql4xxx_lock_flash(ha) != QLA_SUCCESS) - return (QLA_ERROR); - if (ql4xxx_lock_nvram(ha) != QLA_SUCCESS) { - ql4xxx_unlock_flash(ha); - return (QLA_ERROR); - } - - /* Get EEPRom Parameters from NVRAM and validate */ - dev_info(&ha->pdev->dev, "Configuring NVRAM ...\n"); - if (qla4xxx_is_nvram_configuration_valid(ha) == QLA_SUCCESS) { - spin_lock_irqsave(&ha->hardware_lock, flags); - extHwConfig.Asuint32_t = - rd_nvram_word(ha, eeprom_ext_hw_conf_offset(ha)); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - } else { - /* - * QLogic adapters should always have a valid NVRAM. - * If not valid, do not load. - */ - dev_warn(&ha->pdev->dev, - "scsi%ld: %s: EEProm checksum invalid. " - "Please update your EEPROM\n", ha->host_no, - __func__); - - /* set defaults */ - if (is_qla4010(ha)) - extHwConfig.Asuint32_t = 0x1912; - else if (is_qla4022(ha)) - extHwConfig.Asuint32_t = 0x0023; - } - DEBUG(printk("scsi%ld: %s: Setting extHwConfig to 0xFFFF%04x\n", - ha->host_no, __func__, extHwConfig.Asuint32_t)); - - spin_lock_irqsave(&ha->hardware_lock, flags); - writel((0xFFFF << 16) | extHwConfig.Asuint32_t, isp_ext_hw_conf(ha)); - readl(isp_ext_hw_conf(ha)); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - ql4xxx_unlock_nvram(ha); - ql4xxx_unlock_flash(ha); - - return (QLA_SUCCESS); -} - -static void qla4x00_pci_config(struct scsi_qla_host *ha) -{ - uint16_t w, mwi; - - dev_info(&ha->pdev->dev, "Configuring PCI space...\n"); - - pci_set_master(ha->pdev); - mwi = 0; - if (pci_set_mwi(ha->pdev)) - mwi = PCI_COMMAND_INVALIDATE; - /* - * We want to respect framework's setting of PCI configuration space - * command register and also want to make sure that all bits of - * interest to us are properly set in command register. - */ - pci_read_config_word(ha->pdev, PCI_COMMAND, &w); - w |= mwi | (PCI_COMMAND_PARITY | PCI_COMMAND_SERR); - w &= ~PCI_COMMAND_INTX_DISABLE; - pci_write_config_word(ha->pdev, PCI_COMMAND, w); -} - -static int qla4xxx_start_firmware_from_flash(struct scsi_qla_host *ha) -{ - int status = QLA_ERROR; - uint32_t max_wait_time; - unsigned long flags; - uint32_t mbox_status; - - dev_info(&ha->pdev->dev, "Starting firmware ...\n"); - - /* - * Start firmware from flash ROM - * - * WORKAROUND: Stuff a non-constant value that the firmware can - * use as a seed for a random number generator in MB7 prior to - * setting BOOT_ENABLE. Fixes problem where the TCP - * connections use the same TCP ports after each reboot, - * causing some connections to not get re-established. - */ - DEBUG(printk("scsi%d: %s: Start firmware from flash ROM\n", - ha->host_no, __func__)); - - spin_lock_irqsave(&ha->hardware_lock, flags); - writel(jiffies, &ha->reg->mailbox[7]); - if (is_qla4022(ha)) - writel(set_rmask(NVR_WRITE_ENABLE), - &ha->reg->u1.isp4022.nvram); - - writel(set_rmask(CSR_BOOT_ENABLE), &ha->reg->ctrl_status); - readl(&ha->reg->ctrl_status); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - /* Wait for firmware to come UP. */ - max_wait_time = FIRMWARE_UP_TOV * 4; - do { - uint32_t ctrl_status; - - spin_lock_irqsave(&ha->hardware_lock, flags); - ctrl_status = readw(&ha->reg->ctrl_status); - mbox_status = readw(&ha->reg->mailbox[0]); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - if (ctrl_status & set_rmask(CSR_SCSI_PROCESSOR_INTR)) - break; - if (mbox_status == MBOX_STS_COMMAND_COMPLETE) - break; - - DEBUG2(printk("scsi%ld: %s: Waiting for boot firmware to " - "complete... ctrl_sts=0x%x, remaining=%d\n", - ha->host_no, __func__, ctrl_status, - max_wait_time)); - - msleep(250); - } while ((max_wait_time--)); - - if (mbox_status == MBOX_STS_COMMAND_COMPLETE) { - DEBUG(printk("scsi%ld: %s: Firmware has started\n", - ha->host_no, __func__)); - - spin_lock_irqsave(&ha->hardware_lock, flags); - writel(set_rmask(CSR_SCSI_PROCESSOR_INTR), - &ha->reg->ctrl_status); - readl(&ha->reg->ctrl_status); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - status = QLA_SUCCESS; - } else { - printk(KERN_INFO "scsi%ld: %s: Boot firmware failed " - "- mbox status 0x%x\n", ha->host_no, __func__, - mbox_status); - status = QLA_ERROR; - } - return status; -} - -static int ql4xxx_lock_drvr_wait(struct scsi_qla_host *a) -{ -#define QL4_LOCK_DRVR_WAIT 300 -#define QL4_LOCK_DRVR_SLEEP 100 - - int drvr_wait = QL4_LOCK_DRVR_WAIT; - while (drvr_wait) { - if (ql4xxx_lock_drvr(a) == 0) { - msleep(QL4_LOCK_DRVR_SLEEP); - if (drvr_wait) { - DEBUG2(printk("scsi%ld: %s: Waiting for " - "Global Init Semaphore...n", - a->host_no, - __func__)); - } - drvr_wait -= QL4_LOCK_DRVR_SLEEP; - } else { - DEBUG2(printk("scsi%ld: %s: Global Init Semaphore " - "acquired.n", a->host_no, __func__)); - return QLA_SUCCESS; - } - } - return QLA_ERROR; -} - -/** - * qla4xxx_start_firmware - starts qla4xxx firmware - * @ha: Pointer to host adapter structure. - * - * This routine performs the neccessary steps to start the firmware for - * the QLA4010 adapter. - **/ -static int qla4xxx_start_firmware(struct scsi_qla_host *ha) -{ - unsigned long flags = 0; - uint32_t mbox_status; - int status = QLA_ERROR; - int soft_reset = 1; - int config_chip = 0; - - if (is_qla4010(ha)){ - if (qla4010_get_topcat_presence(ha) != QLA_SUCCESS) - return QLA_ERROR; - } - - if (is_qla4022(ha)) - ql4xxx_set_mac_number(ha); - - if (ql4xxx_lock_drvr_wait(ha) != QLA_SUCCESS) - return QLA_ERROR; - - spin_lock_irqsave(&ha->hardware_lock, flags); - - DEBUG2(printk("scsi%ld: %s: port_ctrl = 0x%08X\n", ha->host_no, - __func__, readw(isp_port_ctrl(ha)))); - DEBUG(printk("scsi%ld: %s: port_status = 0x%08X\n", ha->host_no, - __func__, readw(isp_port_status(ha)))); - - /* Is Hardware already initialized? */ - if ((readw(isp_port_ctrl(ha)) & 0x8000) != 0) { - DEBUG(printk("scsi%ld: %s: Hardware has already been " - "initialized\n", ha->host_no, __func__)); - - /* Receive firmware boot acknowledgement */ - mbox_status = readw(&ha->reg->mailbox[0]); - - DEBUG2(printk("scsi%ld: %s: H/W Config complete - mbox[0]= " - "0x%x\n", ha->host_no, __func__, mbox_status)); - - /* Is firmware already booted? */ - if (mbox_status == 0) { - /* F/W not running, must be config by net driver */ - config_chip = 1; - soft_reset = 0; - } else { - writel(set_rmask(CSR_SCSI_PROCESSOR_INTR), - &ha->reg->ctrl_status); - readl(&ha->reg->ctrl_status); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - if (qla4xxx_get_firmware_state(ha) == QLA_SUCCESS) { - DEBUG2(printk("scsi%ld: %s: Get firmware " - "state -- state = 0x%x\n", - ha->host_no, - __func__, ha->firmware_state)); - /* F/W is running */ - if (ha->firmware_state & - FW_STATE_CONFIG_WAIT) { - DEBUG2(printk("scsi%ld: %s: Firmware " - "in known state -- " - "config and " - "boot, state = 0x%x\n", - ha->host_no, __func__, - ha->firmware_state)); - config_chip = 1; - soft_reset = 0; - } - } else { - DEBUG2(printk("scsi%ld: %s: Firmware in " - "unknown state -- resetting," - " state = " - "0x%x\n", ha->host_no, __func__, - ha->firmware_state)); - } - spin_lock_irqsave(&ha->hardware_lock, flags); - } - } else { - DEBUG(printk("scsi%ld: %s: H/W initialization hasn't been " - "started - resetting\n", ha->host_no, __func__)); - } - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - DEBUG(printk("scsi%ld: %s: Flags soft_rest=%d, config= %d\n ", - ha->host_no, __func__, soft_reset, config_chip)); - if (soft_reset) { - DEBUG(printk("scsi%ld: %s: Issue Soft Reset\n", ha->host_no, - __func__)); - status = qla4xxx_soft_reset(ha); - if (status == QLA_ERROR) { - DEBUG(printk("scsi%d: %s: Soft Reset failed!\n", - ha->host_no, __func__)); - ql4xxx_unlock_drvr(ha); - return QLA_ERROR; - } - config_chip = 1; - - /* Reset clears the semaphore, so aquire again */ - if (ql4xxx_lock_drvr_wait(ha) != QLA_SUCCESS) - return QLA_ERROR; - } - - if (config_chip) { - if ((status = qla4xxx_config_nvram(ha)) == QLA_SUCCESS) - status = qla4xxx_start_firmware_from_flash(ha); - } - - ql4xxx_unlock_drvr(ha); - if (status == QLA_SUCCESS) { - qla4xxx_get_fw_version(ha); - if (test_and_clear_bit(AF_GET_CRASH_RECORD, &ha->flags)) - qla4xxx_get_crash_record(ha); - } else { - DEBUG(printk("scsi%ld: %s: Firmware has NOT started\n", - ha->host_no, __func__)); - } - return status; -} - - -/** - * qla4xxx_initialize_adapter - initiailizes hba - * @ha: Pointer to host adapter structure. - * @renew_ddb_list: Indicates what to do with the adapter's ddb list - * after adapter recovery has completed. - * 0=preserve ddb list, 1=destroy and rebuild ddb list - * - * This routine parforms all of the steps necessary to initialize the adapter. - * - **/ -int qla4xxx_initialize_adapter(struct scsi_qla_host *ha, - uint8_t renew_ddb_list) -{ - int status = QLA_ERROR; - int8_t ip_address[IP_ADDR_LEN] = {0} ; - - ha->eeprom_cmd_data = 0; - - qla4x00_pci_config(ha); - - qla4xxx_disable_intrs(ha); - - /* Initialize the Host adapter request/response queues and firmware */ - if (qla4xxx_start_firmware(ha) == QLA_ERROR) - return status; - - if (qla4xxx_validate_mac_address(ha) == QLA_ERROR) - return status; - - if (qla4xxx_init_local_data(ha) == QLA_ERROR) - return status; - - status = qla4xxx_init_firmware(ha); - if (status == QLA_ERROR) - return status; - - /* - * FW is waiting to get an IP address from DHCP server: Skip building - * the ddb_list and wait for DHCP lease acquired aen to come in - * followed by 0x8014 aen" to trigger the tgt discovery process. - */ - if (ha->firmware_state & FW_STATE_DHCP_IN_PROGRESS) - return status; - - /* Skip device discovery if ip and subnet is zero */ - if (memcmp(ha->ip_address, ip_address, IP_ADDR_LEN) == 0 || - memcmp(ha->subnet_mask, ip_address, IP_ADDR_LEN) == 0) - return status; - - if (renew_ddb_list == PRESERVE_DDB_LIST) { - /* - * We want to preserve lun states (i.e. suspended, etc.) - * for recovery initiated by the driver. So just update - * the device states for the existing ddb_list. - */ - qla4xxx_reinitialize_ddb_list(ha); - } else if (renew_ddb_list == REBUILD_DDB_LIST) { - /* - * We want to build the ddb_list from scratch during - * driver initialization and recovery initiated by the - * INT_HBA_RESET IOCTL. - */ - status = qla4xxx_initialize_ddb_list(ha); - if (status == QLA_ERROR) { - DEBUG2(printk("%s(%ld) Error occurred during build" - "ddb list\n", __func__, ha->host_no)); - goto exit_init_hba; - } - - } - if (!ha->tot_ddbs) { - DEBUG2(printk("scsi%ld: Failed to initialize devices or none " - "present in Firmware device database\n", - ha->host_no)); - } - - exit_init_hba: - return status; - -} - -/** - * qla4xxx_add_device_dynamically - ddb addition due to an AEN - * @ha: Pointer to host adapter structure. - * @fw_ddb_index: Firmware's device database index - * - * This routine processes adds a device as a result of an 8014h AEN. - **/ -static void qla4xxx_add_device_dynamically(struct scsi_qla_host *ha, - uint32_t fw_ddb_index) -{ - struct ddb_entry * ddb_entry; - - /* First allocate a device structure */ - ddb_entry = qla4xxx_get_ddb_entry(ha, fw_ddb_index); - if (ddb_entry == NULL) { - DEBUG2(printk(KERN_WARNING - "scsi%ld: Unable to allocate memory to add " - "fw_ddb_index %d\n", ha->host_no, fw_ddb_index)); - return; - } - - if (qla4xxx_update_ddb_entry(ha, ddb_entry, fw_ddb_index) == - QLA_ERROR) { - ha->fw_ddb_index_map[fw_ddb_index] = - (struct ddb_entry *)INVALID_ENTRY; - DEBUG2(printk(KERN_WARNING - "scsi%ld: failed to add new device at index " - "[%d]\n Unable to retrieve fw ddb entry\n", - ha->host_no, fw_ddb_index)); - qla4xxx_free_ddb(ha, ddb_entry); - return; - } - - if (qla4xxx_add_sess(ddb_entry)) { - DEBUG2(printk(KERN_WARNING - "scsi%ld: failed to add new device at index " - "[%d]\n Unable to add connection and session\n", - ha->host_no, fw_ddb_index)); - qla4xxx_free_ddb(ha, ddb_entry); - } -} - -/** - * qla4xxx_process_ddb_changed - process ddb state change - * @ha - Pointer to host adapter structure. - * @fw_ddb_index - Firmware's device database index - * @state - Device state - * - * This routine processes a Decive Database Changed AEN Event. - **/ -int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha, - uint32_t fw_ddb_index, uint32_t state) -{ - struct ddb_entry * ddb_entry; - uint32_t old_fw_ddb_device_state; - - /* check for out of range index */ - if (fw_ddb_index >= MAX_DDB_ENTRIES) - return QLA_ERROR; - - /* Get the corresponging ddb entry */ - ddb_entry = qla4xxx_lookup_ddb_by_fw_index(ha, fw_ddb_index); - /* Device does not currently exist in our database. */ - if (ddb_entry == NULL) { - if (state == DDB_DS_SESSION_ACTIVE) - qla4xxx_add_device_dynamically(ha, fw_ddb_index); - return QLA_SUCCESS; - } - - /* Device already exists in our database. */ - old_fw_ddb_device_state = ddb_entry->fw_ddb_device_state; - DEBUG2(printk("scsi%ld: %s DDB - old state= 0x%x, new state=0x%x for " - "index [%d]\n", ha->host_no, __func__, - ddb_entry->fw_ddb_device_state, state, fw_ddb_index)); - if (old_fw_ddb_device_state == state && - state == DDB_DS_SESSION_ACTIVE) { - /* Do nothing, state not changed. */ - return QLA_SUCCESS; - } - - ddb_entry->fw_ddb_device_state = state; - /* Device is back online. */ - if (ddb_entry->fw_ddb_device_state == DDB_DS_SESSION_ACTIVE) { - atomic_set(&ddb_entry->port_down_timer, - ha->port_down_retry_count); - atomic_set(&ddb_entry->state, DDB_STATE_ONLINE); - atomic_set(&ddb_entry->relogin_retry_count, 0); - atomic_set(&ddb_entry->relogin_timer, 0); - clear_bit(DF_RELOGIN, &ddb_entry->flags); - clear_bit(DF_NO_RELOGIN, &ddb_entry->flags); - iscsi_if_create_session_done(ddb_entry->conn); - /* - * Change the lun state to READY in case the lun TIMEOUT before - * the device came back. - */ - } else { - /* Device went away, try to relogin. */ - /* Mark device missing */ - if (atomic_read(&ddb_entry->state) == DDB_STATE_ONLINE) - qla4xxx_mark_device_missing(ha, ddb_entry); - /* - * Relogin if device state changed to a not active state. - * However, do not relogin if this aen is a result of an IOCTL - * logout (DF_NO_RELOGIN) or if this is a discovered device. - */ - if (ddb_entry->fw_ddb_device_state == DDB_DS_SESSION_FAILED && - !test_bit(DF_RELOGIN, &ddb_entry->flags) && - !test_bit(DF_NO_RELOGIN, &ddb_entry->flags) && - !test_bit(DF_ISNS_DISCOVERED, &ddb_entry->flags)) { - /* - * This triggers a relogin. After the relogin_timer - * expires, the relogin gets scheduled. We must wait a - * minimum amount of time since receiving an 0x8014 AEN - * with failed device_state or a logout response before - * we can issue another relogin. - */ - /* Firmware padds this timeout: (time2wait +1). - * Driver retry to login should be longer than F/W. - * Otherwise F/W will fail - * set_ddb() mbx cmd with 0x4005 since it still - * counting down its time2wait. - */ - atomic_set(&ddb_entry->relogin_timer, 0); - atomic_set(&ddb_entry->retry_relogin_timer, - ddb_entry->default_time2wait + 4); - } - } - - return QLA_SUCCESS; -} - diff --git a/trunk/drivers/scsi/qla4xxx/ql4_inline.h b/trunk/drivers/scsi/qla4xxx/ql4_inline.h deleted file mode 100644 index 0d61797af7da..000000000000 --- a/trunk/drivers/scsi/qla4xxx/ql4_inline.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * QLogic iSCSI HBA Driver - * Copyright (c) 2003-2006 QLogic Corporation - * - * See LICENSE.qla4xxx for copyright and licensing details. - */ - -/* - * - * qla4xxx_lookup_ddb_by_fw_index - * This routine locates a device handle given the firmware device - * database index. If device doesn't exist, returns NULL. - * - * Input: - * ha - Pointer to host adapter structure. - * fw_ddb_index - Firmware's device database index - * - * Returns: - * Pointer to the corresponding internal device database structure - */ -static inline struct ddb_entry * -qla4xxx_lookup_ddb_by_fw_index(struct scsi_qla_host *ha, uint32_t fw_ddb_index) -{ - struct ddb_entry *ddb_entry = NULL; - - if ((fw_ddb_index < MAX_DDB_ENTRIES) && - (ha->fw_ddb_index_map[fw_ddb_index] != - (struct ddb_entry *) INVALID_ENTRY)) { - ddb_entry = ha->fw_ddb_index_map[fw_ddb_index]; - } - - DEBUG3(printk("scsi%d: %s: index [%d], ddb_entry = %p\n", - ha->host_no, __func__, fw_ddb_index, ddb_entry)); - - return ddb_entry; -} - -static inline void -__qla4xxx_enable_intrs(struct scsi_qla_host *ha) -{ - if (is_qla4022(ha)) { - writel(set_rmask(IMR_SCSI_INTR_ENABLE), - &ha->reg->u1.isp4022.intr_mask); - readl(&ha->reg->u1.isp4022.intr_mask); - } else { - writel(set_rmask(CSR_SCSI_INTR_ENABLE), &ha->reg->ctrl_status); - readl(&ha->reg->ctrl_status); - } - set_bit(AF_INTERRUPTS_ON, &ha->flags); -} - -static inline void -__qla4xxx_disable_intrs(struct scsi_qla_host *ha) -{ - if (is_qla4022(ha)) { - writel(clr_rmask(IMR_SCSI_INTR_ENABLE), - &ha->reg->u1.isp4022.intr_mask); - readl(&ha->reg->u1.isp4022.intr_mask); - } else { - writel(clr_rmask(CSR_SCSI_INTR_ENABLE), &ha->reg->ctrl_status); - readl(&ha->reg->ctrl_status); - } - clear_bit(AF_INTERRUPTS_ON, &ha->flags); -} - -static inline void -qla4xxx_enable_intrs(struct scsi_qla_host *ha) -{ - unsigned long flags; - - spin_lock_irqsave(&ha->hardware_lock, flags); - __qla4xxx_enable_intrs(ha); - spin_unlock_irqrestore(&ha->hardware_lock, flags); -} - -static inline void -qla4xxx_disable_intrs(struct scsi_qla_host *ha) -{ - unsigned long flags; - - spin_lock_irqsave(&ha->hardware_lock, flags); - __qla4xxx_disable_intrs(ha); - spin_unlock_irqrestore(&ha->hardware_lock, flags); -} diff --git a/trunk/drivers/scsi/qla4xxx/ql4_iocb.c b/trunk/drivers/scsi/qla4xxx/ql4_iocb.c deleted file mode 100644 index c0a254b89a30..000000000000 --- a/trunk/drivers/scsi/qla4xxx/ql4_iocb.c +++ /dev/null @@ -1,368 +0,0 @@ -/* - * QLogic iSCSI HBA Driver - * Copyright (c) 2003-2006 QLogic Corporation - * - * See LICENSE.qla4xxx for copyright and licensing details. - */ - -#include "ql4_def.h" - -#include - -/** - * qla4xxx_get_req_pkt - returns a valid entry in request queue. - * @ha: Pointer to host adapter structure. - * @queue_entry: Pointer to pointer to queue entry structure - * - * This routine performs the following tasks: - * - returns the current request_in pointer (if queue not full) - * - advances the request_in pointer - * - checks for queue full - **/ -int qla4xxx_get_req_pkt(struct scsi_qla_host *ha, - struct queue_entry **queue_entry) -{ - uint16_t request_in; - uint8_t status = QLA_SUCCESS; - - *queue_entry = ha->request_ptr; - - /* get the latest request_in and request_out index */ - request_in = ha->request_in; - ha->request_out = (uint16_t) le32_to_cpu(ha->shadow_regs->req_q_out); - - /* Advance request queue pointer and check for queue full */ - if (request_in == (REQUEST_QUEUE_DEPTH - 1)) { - request_in = 0; - ha->request_ptr = ha->request_ring; - } else { - request_in++; - ha->request_ptr++; - } - - /* request queue is full, try again later */ - if ((ha->iocb_cnt + 1) >= ha->iocb_hiwat) { - /* restore request pointer */ - ha->request_ptr = *queue_entry; - status = QLA_ERROR; - } else { - ha->request_in = request_in; - memset(*queue_entry, 0, sizeof(**queue_entry)); - } - - return status; -} - -/** - * qla4xxx_send_marker_iocb - issues marker iocb to HBA - * @ha: Pointer to host adapter structure. - * @ddb_entry: Pointer to device database entry - * @lun: SCSI LUN - * @marker_type: marker identifier - * - * This routine issues a marker IOCB. - **/ -int qla4xxx_send_marker_iocb(struct scsi_qla_host *ha, - struct ddb_entry *ddb_entry, int lun) -{ - struct marker_entry *marker_entry; - unsigned long flags = 0; - uint8_t status = QLA_SUCCESS; - - /* Acquire hardware specific lock */ - spin_lock_irqsave(&ha->hardware_lock, flags); - - /* Get pointer to the queue entry for the marker */ - if (qla4xxx_get_req_pkt(ha, (struct queue_entry **) &marker_entry) != - QLA_SUCCESS) { - status = QLA_ERROR; - goto exit_send_marker; - } - - /* Put the marker in the request queue */ - marker_entry->hdr.entryType = ET_MARKER; - marker_entry->hdr.entryCount = 1; - marker_entry->target = cpu_to_le16(ddb_entry->fw_ddb_index); - marker_entry->modifier = cpu_to_le16(MM_LUN_RESET); - int_to_scsilun(lun, &marker_entry->lun); - wmb(); - - /* Tell ISP it's got a new I/O request */ - writel(ha->request_in, &ha->reg->req_q_in); - readl(&ha->reg->req_q_in); - -exit_send_marker: - spin_unlock_irqrestore(&ha->hardware_lock, flags); - return status; -} - -struct continuation_t1_entry* qla4xxx_alloc_cont_entry( - struct scsi_qla_host *ha) -{ - struct continuation_t1_entry *cont_entry; - - cont_entry = (struct continuation_t1_entry *)ha->request_ptr; - - /* Advance request queue pointer */ - if (ha->request_in == (REQUEST_QUEUE_DEPTH - 1)) { - ha->request_in = 0; - ha->request_ptr = ha->request_ring; - } else { - ha->request_in++; - ha->request_ptr++; - } - - /* Load packet defaults */ - cont_entry->hdr.entryType = ET_CONTINUE; - cont_entry->hdr.entryCount = 1; - cont_entry->hdr.systemDefined = (uint8_t) cpu_to_le16(ha->request_in); - - return cont_entry; -} - -uint16_t qla4xxx_calc_request_entries(uint16_t dsds) -{ - uint16_t iocbs; - - iocbs = 1; - if (dsds > COMMAND_SEG) { - iocbs += (dsds - COMMAND_SEG) / CONTINUE_SEG; - if ((dsds - COMMAND_SEG) % CONTINUE_SEG) - iocbs++; - } - return iocbs; -} - -void qla4xxx_build_scsi_iocbs(struct srb *srb, - struct command_t3_entry *cmd_entry, - uint16_t tot_dsds) -{ - struct scsi_qla_host *ha; - uint16_t avail_dsds; - struct data_seg_a64 *cur_dsd; - struct scsi_cmnd *cmd; - - cmd = srb->cmd; - ha = srb->ha; - - if (cmd->request_bufflen == 0 || cmd->sc_data_direction == DMA_NONE) { - /* No data being transferred */ - cmd_entry->ttlByteCnt = __constant_cpu_to_le32(0); - return; - } - - avail_dsds = COMMAND_SEG; - cur_dsd = (struct data_seg_a64 *) & (cmd_entry->dataseg[0]); - - /* Load data segments */ - if (cmd->use_sg) { - struct scatterlist *cur_seg; - struct scatterlist *end_seg; - - cur_seg = (struct scatterlist *)cmd->request_buffer; - end_seg = cur_seg + tot_dsds; - while (cur_seg < end_seg) { - dma_addr_t sle_dma; - - /* Allocate additional continuation packets? */ - if (avail_dsds == 0) { - struct continuation_t1_entry *cont_entry; - - cont_entry = qla4xxx_alloc_cont_entry(ha); - cur_dsd = - (struct data_seg_a64 *) - &cont_entry->dataseg[0]; - avail_dsds = CONTINUE_SEG; - } - - sle_dma = sg_dma_address(cur_seg); - cur_dsd->base.addrLow = cpu_to_le32(LSDW(sle_dma)); - cur_dsd->base.addrHigh = cpu_to_le32(MSDW(sle_dma)); - cur_dsd->count = cpu_to_le32(sg_dma_len(cur_seg)); - avail_dsds--; - - cur_dsd++; - cur_seg++; - } - } else { - cur_dsd->base.addrLow = cpu_to_le32(LSDW(srb->dma_handle)); - cur_dsd->base.addrHigh = cpu_to_le32(MSDW(srb->dma_handle)); - cur_dsd->count = cpu_to_le32(cmd->request_bufflen); - } -} - -/** - * qla4xxx_send_command_to_isp - issues command to HBA - * @ha: pointer to host adapter structure. - * @srb: pointer to SCSI Request Block to be sent to ISP - * - * This routine is called by qla4xxx_queuecommand to build an ISP - * command and pass it to the ISP for execution. - **/ -int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb * srb) -{ - struct scsi_cmnd *cmd = srb->cmd; - struct ddb_entry *ddb_entry; - struct command_t3_entry *cmd_entry; - struct scatterlist *sg = NULL; - - uint16_t tot_dsds; - uint16_t req_cnt; - - unsigned long flags; - uint16_t cnt; - uint32_t index; - char tag[2]; - - /* Get real lun and adapter */ - ddb_entry = srb->ddb; - - /* Send marker(s) if needed. */ - if (ha->marker_needed == 1) { - if (qla4xxx_send_marker_iocb(ha, ddb_entry, - cmd->device->lun) != QLA_SUCCESS) - return QLA_ERROR; - - ha->marker_needed = 0; - } - tot_dsds = 0; - - /* Acquire hardware specific lock */ - spin_lock_irqsave(&ha->hardware_lock, flags); - - index = (uint32_t)cmd->request->tag; - - /* Calculate the number of request entries needed. */ - if (cmd->use_sg) { - sg = (struct scatterlist *)cmd->request_buffer; - tot_dsds = pci_map_sg(ha->pdev, sg, cmd->use_sg, - cmd->sc_data_direction); - if (tot_dsds == 0) - goto queuing_error; - } else if (cmd->request_bufflen) { - dma_addr_t req_dma; - - req_dma = pci_map_single(ha->pdev, cmd->request_buffer, - cmd->request_bufflen, - cmd->sc_data_direction); - if (dma_mapping_error(req_dma)) - goto queuing_error; - - srb->dma_handle = req_dma; - tot_dsds = 1; - } - req_cnt = qla4xxx_calc_request_entries(tot_dsds); - - if (ha->req_q_count < (req_cnt + 2)) { - cnt = (uint16_t) le32_to_cpu(ha->shadow_regs->req_q_out); - if (ha->request_in < cnt) - ha->req_q_count = cnt - ha->request_in; - else - ha->req_q_count = REQUEST_QUEUE_DEPTH - - (ha->request_in - cnt); - } - - if (ha->req_q_count < (req_cnt + 2)) - goto queuing_error; - - /* total iocbs active */ - if ((ha->iocb_cnt + req_cnt) >= REQUEST_QUEUE_DEPTH) - goto queuing_error; - - /* Build command packet */ - cmd_entry = (struct command_t3_entry *) ha->request_ptr; - memset(cmd_entry, 0, sizeof(struct command_t3_entry)); - cmd_entry->hdr.entryType = ET_COMMAND; - cmd_entry->handle = cpu_to_le32(index); - cmd_entry->target = cpu_to_le16(ddb_entry->fw_ddb_index); - cmd_entry->connection_id = cpu_to_le16(ddb_entry->connection_id); - - int_to_scsilun(cmd->device->lun, &cmd_entry->lun); - cmd_entry->cmdSeqNum = cpu_to_le32(ddb_entry->CmdSn); - cmd_entry->ttlByteCnt = cpu_to_le32(cmd->request_bufflen); - memcpy(cmd_entry->cdb, cmd->cmnd, cmd->cmd_len); - cmd_entry->dataSegCnt = cpu_to_le16(tot_dsds); - cmd_entry->hdr.entryCount = req_cnt; - - /* Set data transfer direction control flags - * NOTE: Look at data_direction bits iff there is data to be - * transferred, as the data direction bit is sometimed filled - * in when there is no data to be transferred */ - cmd_entry->control_flags = CF_NO_DATA; - if (cmd->request_bufflen) { - if (cmd->sc_data_direction == DMA_TO_DEVICE) - cmd_entry->control_flags = CF_WRITE; - else if (cmd->sc_data_direction == DMA_FROM_DEVICE) - cmd_entry->control_flags = CF_READ; - } - - /* Set tagged queueing control flags */ - cmd_entry->control_flags |= CF_SIMPLE_TAG; - if (scsi_populate_tag_msg(cmd, tag)) - switch (tag[0]) { - case MSG_HEAD_TAG: - cmd_entry->control_flags |= CF_HEAD_TAG; - break; - case MSG_ORDERED_TAG: - cmd_entry->control_flags |= CF_ORDERED_TAG; - break; - } - - - /* Advance request queue pointer */ - ha->request_in++; - if (ha->request_in == REQUEST_QUEUE_DEPTH) { - ha->request_in = 0; - ha->request_ptr = ha->request_ring; - } else - ha->request_ptr++; - - - qla4xxx_build_scsi_iocbs(srb, cmd_entry, tot_dsds); - wmb(); - - /* - * Check to see if adapter is online before placing request on - * request queue. If a reset occurs and a request is in the queue, - * the firmware will still attempt to process the request, retrieving - * garbage for pointers. - */ - if (!test_bit(AF_ONLINE, &ha->flags)) { - DEBUG2(printk("scsi%ld: %s: Adapter OFFLINE! " - "Do not issue command.\n", - ha->host_no, __func__)); - goto queuing_error; - } - - srb->cmd->host_scribble = (unsigned char *)srb; - - /* update counters */ - srb->state = SRB_ACTIVE_STATE; - srb->flags |= SRB_DMA_VALID; - - /* Track IOCB used */ - ha->iocb_cnt += req_cnt; - srb->iocb_cnt = req_cnt; - ha->req_q_count -= req_cnt; - - /* Debug print statements */ - writel(ha->request_in, &ha->reg->req_q_in); - readl(&ha->reg->req_q_in); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - return QLA_SUCCESS; - -queuing_error: - - if (cmd->use_sg && tot_dsds) { - sg = (struct scatterlist *) cmd->request_buffer; - pci_unmap_sg(ha->pdev, sg, cmd->use_sg, - cmd->sc_data_direction); - } else if (tot_dsds) - pci_unmap_single(ha->pdev, srb->dma_handle, - cmd->request_bufflen, cmd->sc_data_direction); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - return QLA_ERROR; -} - diff --git a/trunk/drivers/scsi/qla4xxx/ql4_isr.c b/trunk/drivers/scsi/qla4xxx/ql4_isr.c deleted file mode 100644 index 1e283321a59d..000000000000 --- a/trunk/drivers/scsi/qla4xxx/ql4_isr.c +++ /dev/null @@ -1,796 +0,0 @@ -/* - * QLogic iSCSI HBA Driver - * Copyright (c) 2003-2006 QLogic Corporation - * - * See LICENSE.qla4xxx for copyright and licensing details. - */ - -#include "ql4_def.h" - -/** - * qla2x00_process_completed_request() - Process a Fast Post response. - * @ha: SCSI driver HA context - * @index: SRB index - **/ -static void qla4xxx_process_completed_request(struct scsi_qla_host *ha, - uint32_t index) -{ - struct srb *srb; - - srb = qla4xxx_del_from_active_array(ha, index); - if (srb) { - /* Save ISP completion status */ - srb->cmd->result = DID_OK << 16; - qla4xxx_srb_compl(ha, srb); - } else { - DEBUG2(printk("scsi%ld: Invalid ISP SCSI completion handle = " - "%d\n", ha->host_no, index)); - set_bit(DPC_RESET_HA, &ha->dpc_flags); - } -} - -/** - * qla4xxx_status_entry - processes status IOCBs - * @ha: Pointer to host adapter structure. - * @sts_entry: Pointer to status entry structure. - **/ -static void qla4xxx_status_entry(struct scsi_qla_host *ha, - struct status_entry *sts_entry) -{ - uint8_t scsi_status; - struct scsi_cmnd *cmd; - struct srb *srb; - struct ddb_entry *ddb_entry; - uint32_t residual; - uint16_t sensebytecnt; - - if (sts_entry->completionStatus == SCS_COMPLETE && - sts_entry->scsiStatus == 0) { - qla4xxx_process_completed_request(ha, - le32_to_cpu(sts_entry-> - handle)); - return; - } - - srb = qla4xxx_del_from_active_array(ha, le32_to_cpu(sts_entry->handle)); - if (!srb) { - /* FIXMEdg: Don't we need to reset ISP in this case??? */ - DEBUG2(printk(KERN_WARNING "scsi%ld: %s: Status Entry invalid " - "handle 0x%x, sp=%p. This cmd may have already " - "been completed.\n", ha->host_no, __func__, - le32_to_cpu(sts_entry->handle), srb)); - return; - } - - cmd = srb->cmd; - if (cmd == NULL) { - DEBUG2(printk("scsi%ld: %s: Command already returned back to " - "OS pkt->handle=%d srb=%p srb->state:%d\n", - ha->host_no, __func__, sts_entry->handle, - srb, srb->state)); - dev_warn(&ha->pdev->dev, "Command is NULL:" - " already returned to OS (srb=%p)\n", srb); - return; - } - - ddb_entry = srb->ddb; - if (ddb_entry == NULL) { - cmd->result = DID_NO_CONNECT << 16; - goto status_entry_exit; - } - - residual = le32_to_cpu(sts_entry->residualByteCnt); - - /* Translate ISP error to a Linux SCSI error. */ - scsi_status = sts_entry->scsiStatus; - switch (sts_entry->completionStatus) { - case SCS_COMPLETE: - if (scsi_status == 0) { - cmd->result = DID_OK << 16; - break; - } - - if (sts_entry->iscsiFlags & - (ISCSI_FLAG_RESIDUAL_OVER|ISCSI_FLAG_RESIDUAL_UNDER)) - cmd->resid = residual; - - cmd->result = DID_OK << 16 | scsi_status; - - if (scsi_status != SCSI_CHECK_CONDITION) - break; - - /* Copy Sense Data into sense buffer. */ - memset(cmd->sense_buffer, 0, sizeof(cmd->sense_buffer)); - - sensebytecnt = le16_to_cpu(sts_entry->senseDataByteCnt); - if (sensebytecnt == 0) - break; - - memcpy(cmd->sense_buffer, sts_entry->senseData, - min(sensebytecnt, - (uint16_t) sizeof(cmd->sense_buffer))); - - DEBUG2(printk("scsi%ld:%d:%d:%d: %s: sense key = %x, " - "ASC/ASCQ = %02x/%02x\n", ha->host_no, - cmd->device->channel, cmd->device->id, - cmd->device->lun, __func__, - sts_entry->senseData[2] & 0x0f, - sts_entry->senseData[12], - sts_entry->senseData[13])); - - srb->flags |= SRB_GOT_SENSE; - break; - - case SCS_INCOMPLETE: - /* Always set the status to DID_ERROR, since - * all conditions result in that status anyway */ - cmd->result = DID_ERROR << 16; - break; - - case SCS_RESET_OCCURRED: - DEBUG2(printk("scsi%ld:%d:%d:%d: %s: Device RESET occurred\n", - ha->host_no, cmd->device->channel, - cmd->device->id, cmd->device->lun, __func__)); - - cmd->result = DID_RESET << 16; - break; - - case SCS_ABORTED: - DEBUG2(printk("scsi%ld:%d:%d:%d: %s: Abort occurred\n", - ha->host_no, cmd->device->channel, - cmd->device->id, cmd->device->lun, __func__)); - - cmd->result = DID_RESET << 16; - break; - - case SCS_TIMEOUT: - DEBUG2(printk(KERN_INFO "scsi%ld:%d:%d:%d: Timeout\n", - ha->host_no, cmd->device->channel, - cmd->device->id, cmd->device->lun)); - - cmd->result = DID_BUS_BUSY << 16; - - /* - * Mark device missing so that we won't continue to send - * I/O to this device. We should get a ddb state change - * AEN soon. - */ - if (atomic_read(&ddb_entry->state) == DDB_STATE_ONLINE) - qla4xxx_mark_device_missing(ha, ddb_entry); - break; - - case SCS_DATA_UNDERRUN: - case SCS_DATA_OVERRUN: - if (sts_entry->iscsiFlags & ISCSI_FLAG_RESIDUAL_OVER) { - DEBUG2(printk("scsi%ld:%d:%d:%d: %s: " "Data overrun, " - "residual = 0x%x\n", ha->host_no, - cmd->device->channel, cmd->device->id, - cmd->device->lun, __func__, residual)); - - cmd->result = DID_ERROR << 16; - break; - } - - if ((sts_entry->iscsiFlags & ISCSI_FLAG_RESIDUAL_UNDER) == 0) { - /* - * Firmware detected a SCSI transport underrun - * condition - */ - cmd->resid = residual; - DEBUG2(printk("scsi%ld:%d:%d:%d: %s: UNDERRUN status " - "detected, xferlen = 0x%x, residual = " - "0x%x\n", - ha->host_no, cmd->device->channel, - cmd->device->id, - cmd->device->lun, __func__, - cmd->request_bufflen, - residual)); - } - - /* - * If there is scsi_status, it takes precedense over - * underflow condition. - */ - if (scsi_status != 0) { - cmd->result = DID_OK << 16 | scsi_status; - - if (scsi_status != SCSI_CHECK_CONDITION) - break; - - /* Copy Sense Data into sense buffer. */ - memset(cmd->sense_buffer, 0, - sizeof(cmd->sense_buffer)); - - sensebytecnt = - le16_to_cpu(sts_entry->senseDataByteCnt); - if (sensebytecnt == 0) - break; - - memcpy(cmd->sense_buffer, sts_entry->senseData, - min(sensebytecnt, - (uint16_t) sizeof(cmd->sense_buffer))); - - DEBUG2(printk("scsi%ld:%d:%d:%d: %s: sense key = %x, " - "ASC/ASCQ = %02x/%02x\n", ha->host_no, - cmd->device->channel, cmd->device->id, - cmd->device->lun, __func__, - sts_entry->senseData[2] & 0x0f, - sts_entry->senseData[12], - sts_entry->senseData[13])); - } else { - /* - * If RISC reports underrun and target does not - * report it then we must have a lost frame, so - * tell upper layer to retry it by reporting a - * bus busy. - */ - if ((sts_entry->iscsiFlags & - ISCSI_FLAG_RESIDUAL_UNDER) == 0) { - cmd->result = DID_BUS_BUSY << 16; - } else if ((cmd->request_bufflen - residual) < - cmd->underflow) { - /* - * Handle mid-layer underflow??? - * - * For kernels less than 2.4, the driver must - * return an error if an underflow is detected. - * For kernels equal-to and above 2.4, the - * mid-layer will appearantly handle the - * underflow by detecting the residual count -- - * unfortunately, we do not see where this is - * actually being done. In the interim, we - * will return DID_ERROR. - */ - DEBUG2(printk("scsi%ld:%d:%d:%d: %s: " - "Mid-layer Data underrun, " - "xferlen = 0x%x, " - "residual = 0x%x\n", ha->host_no, - cmd->device->channel, - cmd->device->id, - cmd->device->lun, __func__, - cmd->request_bufflen, residual)); - - cmd->result = DID_ERROR << 16; - } else { - cmd->result = DID_OK << 16; - } - } - break; - - case SCS_DEVICE_LOGGED_OUT: - case SCS_DEVICE_UNAVAILABLE: - /* - * Mark device missing so that we won't continue to - * send I/O to this device. We should get a ddb - * state change AEN soon. - */ - if (atomic_read(&ddb_entry->state) == DDB_STATE_ONLINE) - qla4xxx_mark_device_missing(ha, ddb_entry); - - cmd->result = DID_BUS_BUSY << 16; - break; - - case SCS_QUEUE_FULL: - /* - * SCSI Mid-Layer handles device queue full - */ - cmd->result = DID_OK << 16 | sts_entry->scsiStatus; - DEBUG2(printk("scsi%ld:%d:%d: %s: QUEUE FULL detected " - "compl=%02x, scsi=%02x, state=%02x, iFlags=%02x," - " iResp=%02x\n", ha->host_no, cmd->device->id, - cmd->device->lun, __func__, - sts_entry->completionStatus, - sts_entry->scsiStatus, sts_entry->state_flags, - sts_entry->iscsiFlags, - sts_entry->iscsiResponse)); - break; - - default: - cmd->result = DID_ERROR << 16; - break; - } - -status_entry_exit: - - /* complete the request */ - srb->cc_stat = sts_entry->completionStatus; - qla4xxx_srb_compl(ha, srb); -} - -/** - * qla4xxx_process_response_queue - process response queue completions - * @ha: Pointer to host adapter structure. - * - * This routine process response queue completions in interrupt context. - * Hardware_lock locked upon entry - **/ -static void qla4xxx_process_response_queue(struct scsi_qla_host * ha) -{ - uint32_t count = 0; - struct srb *srb = NULL; - struct status_entry *sts_entry; - - /* Process all responses from response queue */ - while ((ha->response_in = - (uint16_t)le32_to_cpu(ha->shadow_regs->rsp_q_in)) != - ha->response_out) { - sts_entry = (struct status_entry *) ha->response_ptr; - count++; - - /* Advance pointers for next entry */ - if (ha->response_out == (RESPONSE_QUEUE_DEPTH - 1)) { - ha->response_out = 0; - ha->response_ptr = ha->response_ring; - } else { - ha->response_out++; - ha->response_ptr++; - } - - /* process entry */ - switch (sts_entry->hdr.entryType) { - case ET_STATUS: - /* - * Common status - Single completion posted in single - * IOSB. - */ - qla4xxx_status_entry(ha, sts_entry); - break; - - case ET_PASSTHRU_STATUS: - break; - - case ET_STATUS_CONTINUATION: - /* Just throw away the status continuation entries */ - DEBUG2(printk("scsi%ld: %s: Status Continuation entry " - "- ignoring\n", ha->host_no, __func__)); - break; - - case ET_COMMAND: - /* ISP device queue is full. Command not - * accepted by ISP. Queue command for - * later */ - - srb = qla4xxx_del_from_active_array(ha, - le32_to_cpu(sts_entry-> - handle)); - if (srb == NULL) - goto exit_prq_invalid_handle; - - DEBUG2(printk("scsi%ld: %s: FW device queue full, " - "srb %p\n", ha->host_no, __func__, srb)); - - /* ETRY normally by sending it back with - * DID_BUS_BUSY */ - srb->cmd->result = DID_BUS_BUSY << 16; - qla4xxx_srb_compl(ha, srb); - break; - - case ET_CONTINUE: - /* Just throw away the continuation entries */ - DEBUG2(printk("scsi%ld: %s: Continuation entry - " - "ignoring\n", ha->host_no, __func__)); - break; - - default: - /* - * Invalid entry in response queue, reset RISC - * firmware. - */ - DEBUG2(printk("scsi%ld: %s: Invalid entry %x in " - "response queue \n", ha->host_no, - __func__, - sts_entry->hdr.entryType)); - goto exit_prq_error; - } - } - - /* - * Done with responses, update the ISP For QLA4010, this also clears - * the interrupt. - */ - writel(ha->response_out, &ha->reg->rsp_q_out); - readl(&ha->reg->rsp_q_out); - - return; - -exit_prq_invalid_handle: - DEBUG2(printk("scsi%ld: %s: Invalid handle(srb)=%p type=%x IOCS=%x\n", - ha->host_no, __func__, srb, sts_entry->hdr.entryType, - sts_entry->completionStatus)); - -exit_prq_error: - writel(ha->response_out, &ha->reg->rsp_q_out); - readl(&ha->reg->rsp_q_out); - - set_bit(DPC_RESET_HA, &ha->dpc_flags); -} - -/** - * qla4xxx_isr_decode_mailbox - decodes mailbox status - * @ha: Pointer to host adapter structure. - * @mailbox_status: Mailbox status. - * - * This routine decodes the mailbox status during the ISR. - * Hardware_lock locked upon entry. runs in interrupt context. - **/ -static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha, - uint32_t mbox_status) -{ - int i; - - if ((mbox_status == MBOX_STS_BUSY) || - (mbox_status == MBOX_STS_INTERMEDIATE_COMPLETION) || - (mbox_status >> 12 == MBOX_COMPLETION_STATUS)) { - ha->mbox_status[0] = mbox_status; - - if (test_bit(AF_MBOX_COMMAND, &ha->flags)) { - /* - * Copy all mailbox registers to a temporary - * location and set mailbox command done flag - */ - for (i = 1; i < ha->mbox_status_count; i++) - ha->mbox_status[i] = - readl(&ha->reg->mailbox[i]); - - set_bit(AF_MBOX_COMMAND_DONE, &ha->flags); - wake_up(&ha->mailbox_wait_queue); - } - } else if (mbox_status >> 12 == MBOX_ASYNC_EVENT_STATUS) { - /* Immediately process the AENs that don't require much work. - * Only queue the database_changed AENs */ - switch (mbox_status) { - case MBOX_ASTS_SYSTEM_ERROR: - /* Log Mailbox registers */ - if (ql4xdontresethba) { - DEBUG2(printk("%s:Dont Reset HBA\n", - __func__)); - } else { - set_bit(AF_GET_CRASH_RECORD, &ha->flags); - set_bit(DPC_RESET_HA, &ha->dpc_flags); - } - break; - - case MBOX_ASTS_REQUEST_TRANSFER_ERROR: - case MBOX_ASTS_RESPONSE_TRANSFER_ERROR: - case MBOX_ASTS_NVRAM_INVALID: - case MBOX_ASTS_IP_ADDRESS_CHANGED: - case MBOX_ASTS_DHCP_LEASE_EXPIRED: - DEBUG2(printk("scsi%ld: AEN %04x, ERROR Status, " - "Reset HA\n", ha->host_no, mbox_status)); - set_bit(DPC_RESET_HA, &ha->dpc_flags); - break; - - case MBOX_ASTS_LINK_UP: - DEBUG2(printk("scsi%ld: AEN %04x Adapter LINK UP\n", - ha->host_no, mbox_status)); - set_bit(AF_LINK_UP, &ha->flags); - break; - - case MBOX_ASTS_LINK_DOWN: - DEBUG2(printk("scsi%ld: AEN %04x Adapter LINK DOWN\n", - ha->host_no, mbox_status)); - clear_bit(AF_LINK_UP, &ha->flags); - break; - - case MBOX_ASTS_HEARTBEAT: - ha->seconds_since_last_heartbeat = 0; - break; - - case MBOX_ASTS_DHCP_LEASE_ACQUIRED: - DEBUG2(printk("scsi%ld: AEN %04x DHCP LEASE " - "ACQUIRED\n", ha->host_no, mbox_status)); - set_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags); - break; - - case MBOX_ASTS_PROTOCOL_STATISTIC_ALARM: - case MBOX_ASTS_SCSI_COMMAND_PDU_REJECTED: /* Target - * mode - * only */ - case MBOX_ASTS_UNSOLICITED_PDU_RECEIVED: /* Connection mode */ - case MBOX_ASTS_IPSEC_SYSTEM_FATAL_ERROR: - case MBOX_ASTS_SUBNET_STATE_CHANGE: - /* No action */ - DEBUG2(printk("scsi%ld: AEN %04x\n", ha->host_no, - mbox_status)); - break; - - case MBOX_ASTS_MAC_ADDRESS_CHANGED: - case MBOX_ASTS_DNS: - /* No action */ - DEBUG2(printk(KERN_INFO "scsi%ld: AEN %04x, " - "mbox_sts[1]=%04x, mbox_sts[2]=%04x\n", - ha->host_no, mbox_status, - readl(&ha->reg->mailbox[1]), - readl(&ha->reg->mailbox[2]))); - break; - - case MBOX_ASTS_SELF_TEST_FAILED: - case MBOX_ASTS_LOGIN_FAILED: - /* No action */ - DEBUG2(printk("scsi%ld: AEN %04x, mbox_sts[1]=%04x, " - "mbox_sts[2]=%04x, mbox_sts[3]=%04x\n", - ha->host_no, mbox_status, - readl(&ha->reg->mailbox[1]), - readl(&ha->reg->mailbox[2]), - readl(&ha->reg->mailbox[3]))); - break; - - case MBOX_ASTS_DATABASE_CHANGED: - /* Queue AEN information and process it in the DPC - * routine */ - if (ha->aen_q_count > 0) { - /* advance pointer */ - if (ha->aen_in == (MAX_AEN_ENTRIES - 1)) - ha->aen_in = 0; - else - ha->aen_in++; - - /* decrement available counter */ - ha->aen_q_count--; - - for (i = 1; i < MBOX_AEN_REG_COUNT; i++) - ha->aen_q[ha->aen_in].mbox_sts[i] = - readl(&ha->reg->mailbox[i]); - - ha->aen_q[ha->aen_in].mbox_sts[0] = mbox_status; - - /* print debug message */ - DEBUG2(printk("scsi%ld: AEN[%d] %04x queued" - " mb1:0x%x mb2:0x%x mb3:0x%x mb4:0x%x\n", - ha->host_no, ha->aen_in, - mbox_status, - ha->aen_q[ha->aen_in].mbox_sts[1], - ha->aen_q[ha->aen_in].mbox_sts[2], - ha->aen_q[ha->aen_in].mbox_sts[3], - ha->aen_q[ha->aen_in]. mbox_sts[4])); - - /* The DPC routine will process the aen */ - set_bit(DPC_AEN, &ha->dpc_flags); - } else { - DEBUG2(printk("scsi%ld: %s: aen %04x, queue " - "overflowed! AEN LOST!!\n", - ha->host_no, __func__, - mbox_status)); - - DEBUG2(printk("scsi%ld: DUMP AEN QUEUE\n", - ha->host_no)); - - for (i = 0; i < MAX_AEN_ENTRIES; i++) { - DEBUG2(printk("AEN[%d] %04x %04x %04x " - "%04x\n", i, - ha->aen_q[i].mbox_sts[0], - ha->aen_q[i].mbox_sts[1], - ha->aen_q[i].mbox_sts[2], - ha->aen_q[i].mbox_sts[3])); - } - } - break; - - default: - DEBUG2(printk(KERN_WARNING - "scsi%ld: AEN %04x UNKNOWN\n", - ha->host_no, mbox_status)); - break; - } - } else { - DEBUG2(printk("scsi%ld: Unknown mailbox status %08X\n", - ha->host_no, mbox_status)); - - ha->mbox_status[0] = mbox_status; - } -} - -/** - * qla4xxx_interrupt_service_routine - isr - * @ha: pointer to host adapter structure. - * - * This is the main interrupt service routine. - * hardware_lock locked upon entry. runs in interrupt context. - **/ -void qla4xxx_interrupt_service_routine(struct scsi_qla_host * ha, - uint32_t intr_status) -{ - /* Process response queue interrupt. */ - if (intr_status & CSR_SCSI_COMPLETION_INTR) - qla4xxx_process_response_queue(ha); - - /* Process mailbox/asynch event interrupt.*/ - if (intr_status & CSR_SCSI_PROCESSOR_INTR) { - qla4xxx_isr_decode_mailbox(ha, - readl(&ha->reg->mailbox[0])); - - /* Clear Mailbox Interrupt */ - writel(set_rmask(CSR_SCSI_PROCESSOR_INTR), - &ha->reg->ctrl_status); - readl(&ha->reg->ctrl_status); - } -} - -/** - * qla4xxx_intr_handler - hardware interrupt handler. - * @irq: Unused - * @dev_id: Pointer to host adapter structure - **/ -irqreturn_t qla4xxx_intr_handler(int irq, void *dev_id) -{ - struct scsi_qla_host *ha; - uint32_t intr_status; - unsigned long flags = 0; - uint8_t reqs_count = 0; - - ha = (struct scsi_qla_host *) dev_id; - if (!ha) { - DEBUG2(printk(KERN_INFO - "qla4xxx: Interrupt with NULL host ptr\n")); - return IRQ_NONE; - } - - spin_lock_irqsave(&ha->hardware_lock, flags); - - /* - * Repeatedly service interrupts up to a maximum of - * MAX_REQS_SERVICED_PER_INTR - */ - while (1) { - /* - * Read interrupt status - */ - if (le32_to_cpu(ha->shadow_regs->rsp_q_in) != - ha->response_out) - intr_status = CSR_SCSI_COMPLETION_INTR; - else - intr_status = readl(&ha->reg->ctrl_status); - - if ((intr_status & - (CSR_SCSI_RESET_INTR|CSR_FATAL_ERROR|INTR_PENDING)) == - 0) { - if (reqs_count == 0) - ha->spurious_int_count++; - break; - } - - if (intr_status & CSR_FATAL_ERROR) { - DEBUG2(printk(KERN_INFO "scsi%ld: Fatal Error, " - "Status 0x%04x\n", ha->host_no, - readl(isp_port_error_status (ha)))); - - /* Issue Soft Reset to clear this error condition. - * This will prevent the RISC from repeatedly - * interrupting the driver; thus, allowing the DPC to - * get scheduled to continue error recovery. - * NOTE: Disabling RISC interrupts does not work in - * this case, as CSR_FATAL_ERROR overrides - * CSR_SCSI_INTR_ENABLE */ - if ((readl(&ha->reg->ctrl_status) & - CSR_SCSI_RESET_INTR) == 0) { - writel(set_rmask(CSR_SOFT_RESET), - &ha->reg->ctrl_status); - readl(&ha->reg->ctrl_status); - } - - writel(set_rmask(CSR_FATAL_ERROR), - &ha->reg->ctrl_status); - readl(&ha->reg->ctrl_status); - - __qla4xxx_disable_intrs(ha); - - set_bit(DPC_RESET_HA, &ha->dpc_flags); - - break; - } else if (intr_status & CSR_SCSI_RESET_INTR) { - clear_bit(AF_ONLINE, &ha->flags); - __qla4xxx_disable_intrs(ha); - - writel(set_rmask(CSR_SCSI_RESET_INTR), - &ha->reg->ctrl_status); - readl(&ha->reg->ctrl_status); - - set_bit(DPC_RESET_HA_INTR, &ha->dpc_flags); - - break; - } else if (intr_status & INTR_PENDING) { - qla4xxx_interrupt_service_routine(ha, intr_status); - ha->total_io_count++; - if (++reqs_count == MAX_REQS_SERVICED_PER_INTR) - break; - - intr_status = 0; - } - } - - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - return IRQ_HANDLED; -} - -/** - * qla4xxx_process_aen - processes AENs generated by firmware - * @ha: pointer to host adapter structure. - * @process_aen: type of AENs to process - * - * Processes specific types of Asynchronous Events generated by firmware. - * The type of AENs to process is specified by process_aen and can be - * PROCESS_ALL_AENS 0 - * FLUSH_DDB_CHANGED_AENS 1 - * RELOGIN_DDB_CHANGED_AENS 2 - **/ -void qla4xxx_process_aen(struct scsi_qla_host * ha, uint8_t process_aen) -{ - uint32_t mbox_sts[MBOX_AEN_REG_COUNT]; - struct aen *aen; - int i; - unsigned long flags; - - spin_lock_irqsave(&ha->hardware_lock, flags); - while (ha->aen_out != ha->aen_in) { - /* Advance pointers for next entry */ - if (ha->aen_out == (MAX_AEN_ENTRIES - 1)) - ha->aen_out = 0; - else - ha->aen_out++; - - ha->aen_q_count++; - aen = &ha->aen_q[ha->aen_out]; - - /* copy aen information to local structure */ - for (i = 0; i < MBOX_AEN_REG_COUNT; i++) - mbox_sts[i] = aen->mbox_sts[i]; - - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - DEBUG(printk("scsi%ld: AEN[%d] %04x, index [%d] state=%04x " - "mod=%x conerr=%08x \n", ha->host_no, ha->aen_out, - mbox_sts[0], mbox_sts[2], mbox_sts[3], - mbox_sts[1], mbox_sts[4])); - - switch (mbox_sts[0]) { - case MBOX_ASTS_DATABASE_CHANGED: - if (process_aen == FLUSH_DDB_CHANGED_AENS) { - DEBUG2(printk("scsi%ld: AEN[%d] %04x, index " - "[%d] state=%04x FLUSHED!\n", - ha->host_no, ha->aen_out, - mbox_sts[0], mbox_sts[2], - mbox_sts[3])); - break; - } else if (process_aen == RELOGIN_DDB_CHANGED_AENS) { - /* for use during init time, we only want to - * relogin non-active ddbs */ - struct ddb_entry *ddb_entry; - - ddb_entry = - /* FIXME: name length? */ - qla4xxx_lookup_ddb_by_fw_index(ha, - mbox_sts[2]); - if (!ddb_entry) - break; - - ddb_entry->dev_scan_wait_to_complete_relogin = - 0; - ddb_entry->dev_scan_wait_to_start_relogin = - jiffies + - ((ddb_entry->default_time2wait + - 4) * HZ); - - DEBUG2(printk("scsi%ld: ddb index [%d] initate" - " RELOGIN after %d seconds\n", - ha->host_no, - ddb_entry->fw_ddb_index, - ddb_entry->default_time2wait + - 4)); - break; - } - - if (mbox_sts[1] == 0) { /* Global DB change. */ - qla4xxx_reinitialize_ddb_list(ha); - } else if (mbox_sts[1] == 1) { /* Specific device. */ - qla4xxx_process_ddb_changed(ha, mbox_sts[2], - mbox_sts[3]); - } - break; - } - spin_lock_irqsave(&ha->hardware_lock, flags); - } - spin_unlock_irqrestore(&ha->hardware_lock, flags); - -} - diff --git a/trunk/drivers/scsi/qla4xxx/ql4_mbx.c b/trunk/drivers/scsi/qla4xxx/ql4_mbx.c deleted file mode 100644 index b721dc5dd711..000000000000 --- a/trunk/drivers/scsi/qla4xxx/ql4_mbx.c +++ /dev/null @@ -1,930 +0,0 @@ -/* - * QLogic iSCSI HBA Driver - * Copyright (c) 2003-2006 QLogic Corporation - * - * See LICENSE.qla4xxx for copyright and licensing details. - */ - -#include "ql4_def.h" - - -/** - * qla4xxx_mailbox_command - issues mailbox commands - * @ha: Pointer to host adapter structure. - * @inCount: number of mailbox registers to load. - * @outCount: number of mailbox registers to return. - * @mbx_cmd: data pointer for mailbox in registers. - * @mbx_sts: data pointer for mailbox out registers. - * - * This routine sssue mailbox commands and waits for completion. - * If outCount is 0, this routine completes successfully WITHOUT waiting - * for the mailbox command to complete. - **/ -int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount, - uint8_t outCount, uint32_t *mbx_cmd, - uint32_t *mbx_sts) -{ - int status = QLA_ERROR; - uint8_t i; - u_long wait_count; - uint32_t intr_status; - unsigned long flags = 0; - DECLARE_WAITQUEUE(wait, current); - - mutex_lock(&ha->mbox_sem); - - /* Mailbox code active */ - set_bit(AF_MBOX_COMMAND, &ha->flags); - - /* Make sure that pointers are valid */ - if (!mbx_cmd || !mbx_sts) { - DEBUG2(printk("scsi%ld: %s: Invalid mbx_cmd or mbx_sts " - "pointer\n", ha->host_no, __func__)); - goto mbox_exit; - } - - /* To prevent overwriting mailbox registers for a command that has - * not yet been serviced, check to see if a previously issued - * mailbox command is interrupting. - * ----------------------------------------------------------------- - */ - spin_lock_irqsave(&ha->hardware_lock, flags); - intr_status = readl(&ha->reg->ctrl_status); - if (intr_status & CSR_SCSI_PROCESSOR_INTR) { - /* Service existing interrupt */ - qla4xxx_interrupt_service_routine(ha, intr_status); - clear_bit(AF_MBOX_COMMAND_DONE, &ha->flags); - } - - /* Send the mailbox command to the firmware */ - ha->mbox_status_count = outCount; - for (i = 0; i < outCount; i++) - ha->mbox_status[i] = 0; - - /* Load all mailbox registers, except mailbox 0. */ - for (i = 1; i < inCount; i++) - writel(mbx_cmd[i], &ha->reg->mailbox[i]); - - /* Wakeup firmware */ - writel(mbx_cmd[0], &ha->reg->mailbox[0]); - readl(&ha->reg->mailbox[0]); - writel(set_rmask(CSR_INTR_RISC), &ha->reg->ctrl_status); - readl(&ha->reg->ctrl_status); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - /* Wait for completion */ - set_current_state(TASK_UNINTERRUPTIBLE); - add_wait_queue(&ha->mailbox_wait_queue, &wait); - - /* - * If we don't want status, don't wait for the mailbox command to - * complete. For example, MBOX_CMD_RESET_FW doesn't return status, - * you must poll the inbound Interrupt Mask for completion. - */ - if (outCount == 0) { - status = QLA_SUCCESS; - set_current_state(TASK_RUNNING); - remove_wait_queue(&ha->mailbox_wait_queue, &wait); - goto mbox_exit; - } - /* Wait for command to complete */ - wait_count = jiffies + MBOX_TOV * HZ; - while (test_bit(AF_MBOX_COMMAND_DONE, &ha->flags) == 0) { - if (time_after_eq(jiffies, wait_count)) - break; - - spin_lock_irqsave(&ha->hardware_lock, flags); - intr_status = readl(&ha->reg->ctrl_status); - if (intr_status & INTR_PENDING) { - /* - * Service the interrupt. - * The ISR will save the mailbox status registers - * to a temporary storage location in the adapter - * structure. - */ - ha->mbox_status_count = outCount; - qla4xxx_interrupt_service_routine(ha, intr_status); - } - spin_unlock_irqrestore(&ha->hardware_lock, flags); - msleep(10); - } - set_current_state(TASK_RUNNING); - remove_wait_queue(&ha->mailbox_wait_queue, &wait); - - /* Check for mailbox timeout. */ - if (!test_bit(AF_MBOX_COMMAND_DONE, &ha->flags)) { - DEBUG2(printk("scsi%ld: Mailbox Cmd 0x%08X timed out ...," - " Scheduling Adapter Reset\n", ha->host_no, - mbx_cmd[0])); - ha->mailbox_timeout_count++; - mbx_sts[0] = (-1); - set_bit(DPC_RESET_HA, &ha->dpc_flags); - goto mbox_exit; - } - - /* - * Copy the mailbox out registers to the caller's mailbox in/out - * structure. - */ - spin_lock_irqsave(&ha->hardware_lock, flags); - for (i = 0; i < outCount; i++) - mbx_sts[i] = ha->mbox_status[i]; - - /* Set return status and error flags (if applicable). */ - switch (ha->mbox_status[0]) { - case MBOX_STS_COMMAND_COMPLETE: - status = QLA_SUCCESS; - break; - - case MBOX_STS_INTERMEDIATE_COMPLETION: - status = QLA_SUCCESS; - break; - - case MBOX_STS_BUSY: - DEBUG2( printk("scsi%ld: %s: Cmd = %08X, ISP BUSY\n", - ha->host_no, __func__, mbx_cmd[0])); - ha->mailbox_timeout_count++; - break; - - default: - DEBUG2(printk("scsi%ld: %s: **** FAILED, cmd = %08X, " - "sts = %08X ****\n", ha->host_no, __func__, - mbx_cmd[0], mbx_sts[0])); - break; - } - spin_unlock_irqrestore(&ha->hardware_lock, flags); - -mbox_exit: - clear_bit(AF_MBOX_COMMAND, &ha->flags); - clear_bit(AF_MBOX_COMMAND_DONE, &ha->flags); - mutex_unlock(&ha->mbox_sem); - - return status; -} - - -/** - * qla4xxx_issue_iocb - issue mailbox iocb command - * @ha: adapter state pointer. - * @buffer: buffer pointer. - * @phys_addr: physical address of buffer. - * @size: size of buffer. - * - * Issues iocbs via mailbox commands. - * TARGET_QUEUE_LOCK must be released. - * ADAPTER_STATE_LOCK must be released. - **/ -int -qla4xxx_issue_iocb(struct scsi_qla_host * ha, void *buffer, - dma_addr_t phys_addr, size_t size) -{ - uint32_t mbox_cmd[MBOX_REG_COUNT]; - uint32_t mbox_sts[MBOX_REG_COUNT]; - int status; - - memset(&mbox_cmd, 0, sizeof(mbox_cmd)); - memset(&mbox_sts, 0, sizeof(mbox_sts)); - mbox_cmd[0] = MBOX_CMD_EXECUTE_IOCB_A64; - mbox_cmd[1] = 0; - mbox_cmd[2] = LSDW(phys_addr); - mbox_cmd[3] = MSDW(phys_addr); - status = qla4xxx_mailbox_command(ha, 4, 1, &mbox_cmd[0], &mbox_sts[0]); - return status; -} - -int qla4xxx_conn_close_sess_logout(struct scsi_qla_host * ha, - uint16_t fw_ddb_index, - uint16_t connection_id, - uint16_t option) -{ - uint32_t mbox_cmd[MBOX_REG_COUNT]; - uint32_t mbox_sts[MBOX_REG_COUNT]; - - memset(&mbox_cmd, 0, sizeof(mbox_cmd)); - memset(&mbox_sts, 0, sizeof(mbox_sts)); - mbox_cmd[0] = MBOX_CMD_CONN_CLOSE_SESS_LOGOUT; - mbox_cmd[1] = fw_ddb_index; - mbox_cmd[2] = connection_id; - mbox_cmd[3] = LOGOUT_OPTION_RELOGIN; - if (qla4xxx_mailbox_command(ha, 4, 2, &mbox_cmd[0], &mbox_sts[0]) != - QLA_SUCCESS) { - DEBUG2(printk("scsi%ld: %s: MBOX_CMD_CONN_CLOSE_SESS_LOGOUT " - "option %04x failed sts %04X %04X", - ha->host_no, __func__, - option, mbox_sts[0], mbox_sts[1])); - if (mbox_sts[0] == 0x4005) - DEBUG2(printk("%s reason %04X\n", __func__, - mbox_sts[1])); - } - return QLA_SUCCESS; -} - -int qla4xxx_clear_database_entry(struct scsi_qla_host * ha, - uint16_t fw_ddb_index) -{ - uint32_t mbox_cmd[MBOX_REG_COUNT]; - uint32_t mbox_sts[MBOX_REG_COUNT]; - - memset(&mbox_cmd, 0, sizeof(mbox_cmd)); - memset(&mbox_sts, 0, sizeof(mbox_sts)); - mbox_cmd[0] = MBOX_CMD_CLEAR_DATABASE_ENTRY; - mbox_cmd[1] = fw_ddb_index; - if (qla4xxx_mailbox_command(ha, 2, 5, &mbox_cmd[0], &mbox_sts[0]) != - QLA_SUCCESS) - return QLA_ERROR; - - return QLA_SUCCESS; -} - -/** - * qla4xxx_initialize_fw_cb - initializes firmware control block. - * @ha: Pointer to host adapter structure. - **/ -int qla4xxx_initialize_fw_cb(struct scsi_qla_host * ha) -{ - struct init_fw_ctrl_blk *init_fw_cb; - dma_addr_t init_fw_cb_dma; - uint32_t mbox_cmd[MBOX_REG_COUNT]; - uint32_t mbox_sts[MBOX_REG_COUNT]; - int status = QLA_ERROR; - - init_fw_cb = dma_alloc_coherent(&ha->pdev->dev, - sizeof(struct init_fw_ctrl_blk), - &init_fw_cb_dma, GFP_KERNEL); - if (init_fw_cb == NULL) { - DEBUG2(printk("scsi%ld: %s: Unable to alloc init_cb\n", - ha->host_no, __func__)); - return 10; - } - memset(init_fw_cb, 0, sizeof(struct init_fw_ctrl_blk)); - - /* Get Initialize Firmware Control Block. */ - memset(&mbox_cmd, 0, sizeof(mbox_cmd)); - memset(&mbox_sts, 0, sizeof(mbox_sts)); - mbox_cmd[0] = MBOX_CMD_GET_INIT_FW_CTRL_BLOCK; - mbox_cmd[2] = LSDW(init_fw_cb_dma); - mbox_cmd[3] = MSDW(init_fw_cb_dma); - if (qla4xxx_mailbox_command(ha, 4, 1, &mbox_cmd[0], &mbox_sts[0]) != - QLA_SUCCESS) { - dma_free_coherent(&ha->pdev->dev, - sizeof(struct init_fw_ctrl_blk), - init_fw_cb, init_fw_cb_dma); - return status; - } - - /* Initialize request and response queues. */ - qla4xxx_init_rings(ha); - - /* Fill in the request and response queue information. */ - init_fw_cb->ReqQConsumerIndex = cpu_to_le16(ha->request_out); - init_fw_cb->ComplQProducerIndex = cpu_to_le16(ha->response_in); - init_fw_cb->ReqQLen = __constant_cpu_to_le16(REQUEST_QUEUE_DEPTH); - init_fw_cb->ComplQLen = __constant_cpu_to_le16(RESPONSE_QUEUE_DEPTH); - init_fw_cb->ReqQAddrLo = cpu_to_le32(LSDW(ha->request_dma)); - init_fw_cb->ReqQAddrHi = cpu_to_le32(MSDW(ha->request_dma)); - init_fw_cb->ComplQAddrLo = cpu_to_le32(LSDW(ha->response_dma)); - init_fw_cb->ComplQAddrHi = cpu_to_le32(MSDW(ha->response_dma)); - init_fw_cb->ShadowRegBufAddrLo = - cpu_to_le32(LSDW(ha->shadow_regs_dma)); - init_fw_cb->ShadowRegBufAddrHi = - cpu_to_le32(MSDW(ha->shadow_regs_dma)); - - /* Set up required options. */ - init_fw_cb->FwOptions |= - __constant_cpu_to_le16(FWOPT_SESSION_MODE | - FWOPT_INITIATOR_MODE); - init_fw_cb->FwOptions &= __constant_cpu_to_le16(~FWOPT_TARGET_MODE); - - /* Save some info in adapter structure. */ - ha->firmware_options = le16_to_cpu(init_fw_cb->FwOptions); - ha->tcp_options = le16_to_cpu(init_fw_cb->TCPOptions); - ha->heartbeat_interval = init_fw_cb->HeartbeatInterval; - memcpy(ha->ip_address, init_fw_cb->IPAddr, - min(sizeof(ha->ip_address), sizeof(init_fw_cb->IPAddr))); - memcpy(ha->subnet_mask, init_fw_cb->SubnetMask, - min(sizeof(ha->subnet_mask), sizeof(init_fw_cb->SubnetMask))); - memcpy(ha->gateway, init_fw_cb->GatewayIPAddr, - min(sizeof(ha->gateway), sizeof(init_fw_cb->GatewayIPAddr))); - memcpy(ha->name_string, init_fw_cb->iSCSINameString, - min(sizeof(ha->name_string), - sizeof(init_fw_cb->iSCSINameString))); - memcpy(ha->alias, init_fw_cb->Alias, - min(sizeof(ha->alias), sizeof(init_fw_cb->Alias))); - - /* Save Command Line Paramater info */ - ha->port_down_retry_count = le16_to_cpu(init_fw_cb->KeepAliveTimeout); - ha->discovery_wait = ql4xdiscoverywait; - - /* Send Initialize Firmware Control Block. */ - mbox_cmd[0] = MBOX_CMD_INITIALIZE_FIRMWARE; - mbox_cmd[1] = 0; - mbox_cmd[2] = LSDW(init_fw_cb_dma); - mbox_cmd[3] = MSDW(init_fw_cb_dma); - if (qla4xxx_mailbox_command(ha, 4, 1, &mbox_cmd[0], &mbox_sts[0]) == - QLA_SUCCESS) - status = QLA_SUCCESS; - else { - DEBUG2(printk("scsi%ld: %s: MBOX_CMD_INITIALIZE_FIRMWARE " - "failed w/ status %04X\n", ha->host_no, __func__, - mbox_sts[0])); - } - dma_free_coherent(&ha->pdev->dev, sizeof(struct init_fw_ctrl_blk), - init_fw_cb, init_fw_cb_dma); - - return status; -} - -/** - * qla4xxx_get_dhcp_ip_address - gets HBA ip address via DHCP - * @ha: Pointer to host adapter structure. - **/ -int qla4xxx_get_dhcp_ip_address(struct scsi_qla_host * ha) -{ - struct init_fw_ctrl_blk *init_fw_cb; - dma_addr_t init_fw_cb_dma; - uint32_t mbox_cmd[MBOX_REG_COUNT]; - uint32_t mbox_sts[MBOX_REG_COUNT]; - - init_fw_cb = dma_alloc_coherent(&ha->pdev->dev, - sizeof(struct init_fw_ctrl_blk), - &init_fw_cb_dma, GFP_KERNEL); - if (init_fw_cb == NULL) { - printk("scsi%ld: %s: Unable to alloc init_cb\n", ha->host_no, - __func__); - return 10; - } - - /* Get Initialize Firmware Control Block. */ - memset(&mbox_cmd, 0, sizeof(mbox_cmd)); - memset(&mbox_sts, 0, sizeof(mbox_sts)); - memset(init_fw_cb, 0, sizeof(struct init_fw_ctrl_blk)); - mbox_cmd[0] = MBOX_CMD_GET_INIT_FW_CTRL_BLOCK; - mbox_cmd[2] = LSDW(init_fw_cb_dma); - mbox_cmd[3] = MSDW(init_fw_cb_dma); - - if (qla4xxx_mailbox_command(ha, 4, 1, &mbox_cmd[0], &mbox_sts[0]) != - QLA_SUCCESS) { - DEBUG2(printk("scsi%ld: %s: Failed to get init_fw_ctrl_blk\n", - ha->host_no, __func__)); - dma_free_coherent(&ha->pdev->dev, - sizeof(struct init_fw_ctrl_blk), - init_fw_cb, init_fw_cb_dma); - return QLA_ERROR; - } - - /* Save IP Address. */ - memcpy(ha->ip_address, init_fw_cb->IPAddr, - min(sizeof(ha->ip_address), sizeof(init_fw_cb->IPAddr))); - memcpy(ha->subnet_mask, init_fw_cb->SubnetMask, - min(sizeof(ha->subnet_mask), sizeof(init_fw_cb->SubnetMask))); - memcpy(ha->gateway, init_fw_cb->GatewayIPAddr, - min(sizeof(ha->gateway), sizeof(init_fw_cb->GatewayIPAddr))); - - dma_free_coherent(&ha->pdev->dev, sizeof(struct init_fw_ctrl_blk), - init_fw_cb, init_fw_cb_dma); - - return QLA_SUCCESS; -} - -/** - * qla4xxx_get_firmware_state - gets firmware state of HBA - * @ha: Pointer to host adapter structure. - **/ -int qla4xxx_get_firmware_state(struct scsi_qla_host * ha) -{ - uint32_t mbox_cmd[MBOX_REG_COUNT]; - uint32_t mbox_sts[MBOX_REG_COUNT]; - - /* Get firmware version */ - memset(&mbox_cmd, 0, sizeof(mbox_cmd)); - memset(&mbox_sts, 0, sizeof(mbox_sts)); - mbox_cmd[0] = MBOX_CMD_GET_FW_STATE; - if (qla4xxx_mailbox_command(ha, 1, 4, &mbox_cmd[0], &mbox_sts[0]) != - QLA_SUCCESS) { - DEBUG2(printk("scsi%ld: %s: MBOX_CMD_GET_FW_STATE failed w/ " - "status %04X\n", ha->host_no, __func__, - mbox_sts[0])); - return QLA_ERROR; - } - ha->firmware_state = mbox_sts[1]; - ha->board_id = mbox_sts[2]; - ha->addl_fw_state = mbox_sts[3]; - DEBUG2(printk("scsi%ld: %s firmware_state=0x%x\n", - ha->host_no, __func__, ha->firmware_state);) - - return QLA_SUCCESS; -} - -/** - * qla4xxx_get_firmware_status - retrieves firmware status - * @ha: Pointer to host adapter structure. - **/ -int qla4xxx_get_firmware_status(struct scsi_qla_host * ha) -{ - uint32_t mbox_cmd[MBOX_REG_COUNT]; - uint32_t mbox_sts[MBOX_REG_COUNT]; - - /* Get firmware version */ - memset(&mbox_cmd, 0, sizeof(mbox_cmd)); - memset(&mbox_sts, 0, sizeof(mbox_sts)); - mbox_cmd[0] = MBOX_CMD_GET_FW_STATUS; - if (qla4xxx_mailbox_command(ha, 1, 3, &mbox_cmd[0], &mbox_sts[0]) != - QLA_SUCCESS) { - DEBUG2(printk("scsi%ld: %s: MBOX_CMD_GET_FW_STATUS failed w/ " - "status %04X\n", ha->host_no, __func__, - mbox_sts[0])); - return QLA_ERROR; - } - - /* High-water mark of IOCBs */ - ha->iocb_hiwat = mbox_sts[2]; - if (ha->iocb_hiwat > IOCB_HIWAT_CUSHION) - ha->iocb_hiwat -= IOCB_HIWAT_CUSHION; - else - dev_info(&ha->pdev->dev, "WARNING!!! You have less than %d " - "firmare IOCBs available (%d).\n", - IOCB_HIWAT_CUSHION, ha->iocb_hiwat); - - return QLA_SUCCESS; -} - -/** - * qla4xxx_get_fwddb_entry - retrieves firmware ddb entry - * @ha: Pointer to host adapter structure. - * @fw_ddb_index: Firmware's device database index - * @fw_ddb_entry: Pointer to firmware's device database entry structure - * @num_valid_ddb_entries: Pointer to number of valid ddb entries - * @next_ddb_index: Pointer to next valid device database index - * @fw_ddb_device_state: Pointer to device state - **/ -int qla4xxx_get_fwddb_entry(struct scsi_qla_host *ha, - uint16_t fw_ddb_index, - struct dev_db_entry *fw_ddb_entry, - dma_addr_t fw_ddb_entry_dma, - uint32_t *num_valid_ddb_entries, - uint32_t *next_ddb_index, - uint32_t *fw_ddb_device_state, - uint32_t *conn_err_detail, - uint16_t *tcp_source_port_num, - uint16_t *connection_id) -{ - int status = QLA_ERROR; - uint32_t mbox_cmd[MBOX_REG_COUNT]; - uint32_t mbox_sts[MBOX_REG_COUNT]; - - /* Make sure the device index is valid */ - if (fw_ddb_index >= MAX_DDB_ENTRIES) { - DEBUG2(printk("scsi%ld: %s: index [%d] out of range.\n", - ha->host_no, __func__, fw_ddb_index)); - goto exit_get_fwddb; - } - memset(&mbox_cmd, 0, sizeof(mbox_cmd)); - memset(&mbox_sts, 0, sizeof(mbox_sts)); - mbox_cmd[0] = MBOX_CMD_GET_DATABASE_ENTRY; - mbox_cmd[1] = (uint32_t) fw_ddb_index; - mbox_cmd[2] = LSDW(fw_ddb_entry_dma); - mbox_cmd[3] = MSDW(fw_ddb_entry_dma); - if (qla4xxx_mailbox_command(ha, 4, 7, &mbox_cmd[0], &mbox_sts[0]) == - QLA_ERROR) { - DEBUG2(printk("scsi%ld: %s: MBOX_CMD_GET_DATABASE_ENTRY failed" - " with status 0x%04X\n", ha->host_no, __func__, - mbox_sts[0])); - goto exit_get_fwddb; - } - if (fw_ddb_index != mbox_sts[1]) { - DEBUG2(printk("scsi%ld: %s: index mismatch [%d] != [%d].\n", - ha->host_no, __func__, fw_ddb_index, - mbox_sts[1])); - goto exit_get_fwddb; - } - if (fw_ddb_entry) { - dev_info(&ha->pdev->dev, "DDB[%d] MB0 %04x Tot %d Next %d " - "State %04x ConnErr %08x %d.%d.%d.%d:%04d \"%s\"\n", - fw_ddb_index, mbox_sts[0], mbox_sts[2], mbox_sts[3], - mbox_sts[4], mbox_sts[5], fw_ddb_entry->ipAddr[0], - fw_ddb_entry->ipAddr[1], fw_ddb_entry->ipAddr[2], - fw_ddb_entry->ipAddr[3], - le16_to_cpu(fw_ddb_entry->portNumber), - fw_ddb_entry->iscsiName); - } - if (num_valid_ddb_entries) - *num_valid_ddb_entries = mbox_sts[2]; - if (next_ddb_index) - *next_ddb_index = mbox_sts[3]; - if (fw_ddb_device_state) - *fw_ddb_device_state = mbox_sts[4]; - - /* - * RA: This mailbox has been changed to pass connection error and - * details. Its true for ISP4010 as per Version E - Not sure when it - * was changed. Get the time2wait from the fw_dd_entry field : - * default_time2wait which we call it as minTime2Wait DEV_DB_ENTRY - * struct. - */ - if (conn_err_detail) - *conn_err_detail = mbox_sts[5]; - if (tcp_source_port_num) - *tcp_source_port_num = (uint16_t) mbox_sts[6] >> 16; - if (connection_id) - *connection_id = (uint16_t) mbox_sts[6] & 0x00FF; - status = QLA_SUCCESS; - -exit_get_fwddb: - return status; -} - -/** - * qla4xxx_set_fwddb_entry - sets a ddb entry. - * @ha: Pointer to host adapter structure. - * @fw_ddb_index: Firmware's device database index - * @fw_ddb_entry: Pointer to firmware's ddb entry structure, or NULL. - * - * This routine initializes or updates the adapter's device database - * entry for the specified device. It also triggers a login for the - * specified device. Therefore, it may also be used as a secondary - * login routine when a NULL pointer is specified for the fw_ddb_entry. - **/ -int qla4xxx_set_ddb_entry(struct scsi_qla_host * ha, uint16_t fw_ddb_index, - dma_addr_t fw_ddb_entry_dma) -{ - uint32_t mbox_cmd[MBOX_REG_COUNT]; - uint32_t mbox_sts[MBOX_REG_COUNT]; - - /* Do not wait for completion. The firmware will send us an - * ASTS_DATABASE_CHANGED (0x8014) to notify us of the login status. - */ - memset(&mbox_cmd, 0, sizeof(mbox_cmd)); - memset(&mbox_sts, 0, sizeof(mbox_sts)); - - mbox_cmd[0] = MBOX_CMD_SET_DATABASE_ENTRY; - mbox_cmd[1] = (uint32_t) fw_ddb_index; - mbox_cmd[2] = LSDW(fw_ddb_entry_dma); - mbox_cmd[3] = MSDW(fw_ddb_entry_dma); - return qla4xxx_mailbox_command(ha, 4, 1, &mbox_cmd[0], &mbox_sts[0]); -} - -int qla4xxx_conn_open_session_login(struct scsi_qla_host * ha, - uint16_t fw_ddb_index) -{ - int status = QLA_ERROR; - uint32_t mbox_cmd[MBOX_REG_COUNT]; - uint32_t mbox_sts[MBOX_REG_COUNT]; - - /* Do not wait for completion. The firmware will send us an - * ASTS_DATABASE_CHANGED (0x8014) to notify us of the login status. - */ - memset(&mbox_cmd, 0, sizeof(mbox_cmd)); - memset(&mbox_sts, 0, sizeof(mbox_sts)); - mbox_cmd[0] = MBOX_CMD_CONN_OPEN_SESS_LOGIN; - mbox_cmd[1] = (uint32_t) fw_ddb_index; - mbox_cmd[2] = 0; - mbox_cmd[3] = 0; - mbox_cmd[4] = 0; - status = qla4xxx_mailbox_command(ha, 4, 0, &mbox_cmd[0], &mbox_sts[0]); - DEBUG2(printk("%s fw_ddb_index=%d status=%d mbx0_1=0x%x :0x%x\n", - __func__, fw_ddb_index, status, mbox_sts[0], - mbox_sts[1]);) - - return status; -} - -/** - * qla4xxx_get_crash_record - retrieves crash record. - * @ha: Pointer to host adapter structure. - * - * This routine retrieves a crash record from the QLA4010 after an 8002h aen. - **/ -void qla4xxx_get_crash_record(struct scsi_qla_host * ha) -{ - uint32_t mbox_cmd[MBOX_REG_COUNT]; - uint32_t mbox_sts[MBOX_REG_COUNT]; - struct crash_record *crash_record = NULL; - dma_addr_t crash_record_dma = 0; - uint32_t crash_record_size = 0; - memset(&mbox_cmd, 0, sizeof(mbox_cmd)); - memset(&mbox_sts, 0, sizeof(mbox_cmd)); - - /* Get size of crash record. */ - mbox_cmd[0] = MBOX_CMD_GET_CRASH_RECORD; - if (qla4xxx_mailbox_command(ha, 5, 5, &mbox_cmd[0], &mbox_sts[0]) != - QLA_SUCCESS) { - DEBUG2(printk("scsi%ld: %s: ERROR: Unable to retrieve size!\n", - ha->host_no, __func__)); - goto exit_get_crash_record; - } - crash_record_size = mbox_sts[4]; - if (crash_record_size == 0) { - DEBUG2(printk("scsi%ld: %s: ERROR: Crash record size is 0!\n", - ha->host_no, __func__)); - goto exit_get_crash_record; - } - - /* Alloc Memory for Crash Record. */ - crash_record = dma_alloc_coherent(&ha->pdev->dev, crash_record_size, - &crash_record_dma, GFP_KERNEL); - if (crash_record == NULL) - goto exit_get_crash_record; - - /* Get Crash Record. */ - mbox_cmd[0] = MBOX_CMD_GET_CRASH_RECORD; - mbox_cmd[2] = LSDW(crash_record_dma); - mbox_cmd[3] = MSDW(crash_record_dma); - mbox_cmd[4] = crash_record_size; - if (qla4xxx_mailbox_command(ha, 5, 5, &mbox_cmd[0], &mbox_sts[0]) != - QLA_SUCCESS) - goto exit_get_crash_record; - - /* Dump Crash Record. */ - -exit_get_crash_record: - if (crash_record) - dma_free_coherent(&ha->pdev->dev, crash_record_size, - crash_record, crash_record_dma); -} - -/** - * qla4xxx_get_conn_event_log - retrieves connection event log - * @ha: Pointer to host adapter structure. - **/ -void qla4xxx_get_conn_event_log(struct scsi_qla_host * ha) -{ - uint32_t mbox_cmd[MBOX_REG_COUNT]; - uint32_t mbox_sts[MBOX_REG_COUNT]; - struct conn_event_log_entry *event_log = NULL; - dma_addr_t event_log_dma = 0; - uint32_t event_log_size = 0; - uint32_t num_valid_entries; - uint32_t oldest_entry = 0; - uint32_t max_event_log_entries; - uint8_t i; - - - memset(&mbox_cmd, 0, sizeof(mbox_cmd)); - memset(&mbox_sts, 0, sizeof(mbox_cmd)); - - /* Get size of crash record. */ - mbox_cmd[0] = MBOX_CMD_GET_CONN_EVENT_LOG; - if (qla4xxx_mailbox_command(ha, 4, 5, &mbox_cmd[0], &mbox_sts[0]) != - QLA_SUCCESS) - goto exit_get_event_log; - - event_log_size = mbox_sts[4]; - if (event_log_size == 0) - goto exit_get_event_log; - - /* Alloc Memory for Crash Record. */ - event_log = dma_alloc_coherent(&ha->pdev->dev, event_log_size, - &event_log_dma, GFP_KERNEL); - if (event_log == NULL) - goto exit_get_event_log; - - /* Get Crash Record. */ - mbox_cmd[0] = MBOX_CMD_GET_CONN_EVENT_LOG; - mbox_cmd[2] = LSDW(event_log_dma); - mbox_cmd[3] = MSDW(event_log_dma); - if (qla4xxx_mailbox_command(ha, 4, 5, &mbox_cmd[0], &mbox_sts[0]) != - QLA_SUCCESS) { - DEBUG2(printk("scsi%ld: %s: ERROR: Unable to retrieve event " - "log!\n", ha->host_no, __func__)); - goto exit_get_event_log; - } - - /* Dump Event Log. */ - num_valid_entries = mbox_sts[1]; - - max_event_log_entries = event_log_size / - sizeof(struct conn_event_log_entry); - - if (num_valid_entries > max_event_log_entries) - oldest_entry = num_valid_entries % max_event_log_entries; - - DEBUG3(printk("scsi%ld: Connection Event Log Dump (%d entries):\n", - ha->host_no, num_valid_entries)); - - if (ql4xextended_error_logging == 3) { - if (oldest_entry == 0) { - /* Circular Buffer has not wrapped around */ - for (i=0; i < num_valid_entries; i++) { - qla4xxx_dump_buffer((uint8_t *)event_log+ - (i*sizeof(*event_log)), - sizeof(*event_log)); - } - } - else { - /* Circular Buffer has wrapped around - - * display accordingly*/ - for (i=oldest_entry; i < max_event_log_entries; i++) { - qla4xxx_dump_buffer((uint8_t *)event_log+ - (i*sizeof(*event_log)), - sizeof(*event_log)); - } - for (i=0; i < oldest_entry; i++) { - qla4xxx_dump_buffer((uint8_t *)event_log+ - (i*sizeof(*event_log)), - sizeof(*event_log)); - } - } - } - -exit_get_event_log: - if (event_log) - dma_free_coherent(&ha->pdev->dev, event_log_size, event_log, - event_log_dma); -} - -/** - * qla4xxx_reset_lun - issues LUN Reset - * @ha: Pointer to host adapter structure. - * @db_entry: Pointer to device database entry - * @un_entry: Pointer to lun entry structure - * - * This routine performs a LUN RESET on the specified target/lun. - * The caller must ensure that the ddb_entry and lun_entry pointers - * are valid before calling this routine. - **/ -int qla4xxx_reset_lun(struct scsi_qla_host * ha, struct ddb_entry * ddb_entry, - int lun) -{ - uint32_t mbox_cmd[MBOX_REG_COUNT]; - uint32_t mbox_sts[MBOX_REG_COUNT]; - int status = QLA_SUCCESS; - - DEBUG2(printk("scsi%ld:%d:%d: lun reset issued\n", ha->host_no, - ddb_entry->os_target_id, lun)); - - /* - * Send lun reset command to ISP, so that the ISP will return all - * outstanding requests with RESET status - */ - memset(&mbox_cmd, 0, sizeof(mbox_cmd)); - memset(&mbox_sts, 0, sizeof(mbox_sts)); - mbox_cmd[0] = MBOX_CMD_LUN_RESET; - mbox_cmd[1] = ddb_entry->fw_ddb_index; - mbox_cmd[2] = lun << 8; - mbox_cmd[5] = 0x01; /* Immediate Command Enable */ - qla4xxx_mailbox_command(ha, 6, 1, &mbox_cmd[0], &mbox_sts[0]); - if (mbox_sts[0] != MBOX_STS_COMMAND_COMPLETE && - mbox_sts[0] != MBOX_STS_COMMAND_ERROR) - status = QLA_ERROR; - - return status; -} - - -int qla4xxx_get_flash(struct scsi_qla_host * ha, dma_addr_t dma_addr, - uint32_t offset, uint32_t len) -{ - uint32_t mbox_cmd[MBOX_REG_COUNT]; - uint32_t mbox_sts[MBOX_REG_COUNT]; - - memset(&mbox_cmd, 0, sizeof(mbox_cmd)); - memset(&mbox_sts, 0, sizeof(mbox_sts)); - mbox_cmd[0] = MBOX_CMD_READ_FLASH; - mbox_cmd[1] = LSDW(dma_addr); - mbox_cmd[2] = MSDW(dma_addr); - mbox_cmd[3] = offset; - mbox_cmd[4] = len; - if (qla4xxx_mailbox_command(ha, 5, 2, &mbox_cmd[0], &mbox_sts[0]) != - QLA_SUCCESS) { - DEBUG2(printk("scsi%ld: %s: MBOX_CMD_READ_FLASH, failed w/ " - "status %04X %04X, offset %08x, len %08x\n", ha->host_no, - __func__, mbox_sts[0], mbox_sts[1], offset, len)); - return QLA_ERROR; - } - return QLA_SUCCESS; -} - -/** - * qla4xxx_get_fw_version - gets firmware version - * @ha: Pointer to host adapter structure. - * - * Retrieves the firmware version on HBA. In QLA4010, mailboxes 2 & 3 may - * hold an address for data. Make sure that we write 0 to those mailboxes, - * if unused. - **/ -int qla4xxx_get_fw_version(struct scsi_qla_host * ha) -{ - uint32_t mbox_cmd[MBOX_REG_COUNT]; - uint32_t mbox_sts[MBOX_REG_COUNT]; - - /* Get firmware version. */ - memset(&mbox_cmd, 0, sizeof(mbox_cmd)); - memset(&mbox_sts, 0, sizeof(mbox_sts)); - mbox_cmd[0] = MBOX_CMD_ABOUT_FW; - if (qla4xxx_mailbox_command(ha, 4, 5, &mbox_cmd[0], &mbox_sts[0]) != - QLA_SUCCESS) { - DEBUG2(printk("scsi%ld: %s: MBOX_CMD_ABOUT_FW failed w/ " - "status %04X\n", ha->host_no, __func__, mbox_sts[0])); - return QLA_ERROR; - } - - /* Save firmware version information. */ - ha->firmware_version[0] = mbox_sts[1]; - ha->firmware_version[1] = mbox_sts[2]; - ha->patch_number = mbox_sts[3]; - ha->build_number = mbox_sts[4]; - - return QLA_SUCCESS; -} - -int qla4xxx_get_default_ddb(struct scsi_qla_host *ha, dma_addr_t dma_addr) -{ - uint32_t mbox_cmd[MBOX_REG_COUNT]; - uint32_t mbox_sts[MBOX_REG_COUNT]; - - memset(&mbox_cmd, 0, sizeof(mbox_cmd)); - memset(&mbox_sts, 0, sizeof(mbox_sts)); - - mbox_cmd[0] = MBOX_CMD_GET_DATABASE_ENTRY_DEFAULTS; - mbox_cmd[2] = LSDW(dma_addr); - mbox_cmd[3] = MSDW(dma_addr); - - if (qla4xxx_mailbox_command(ha, 4, 1, &mbox_cmd[0], &mbox_sts[0]) != - QLA_SUCCESS) { - DEBUG2(printk("scsi%ld: %s: failed status %04X\n", - ha->host_no, __func__, mbox_sts[0])); - return QLA_ERROR; - } - return QLA_SUCCESS; -} - -int qla4xxx_req_ddb_entry(struct scsi_qla_host *ha, uint32_t *ddb_index) -{ - uint32_t mbox_cmd[MBOX_REG_COUNT]; - uint32_t mbox_sts[MBOX_REG_COUNT]; - - memset(&mbox_cmd, 0, sizeof(mbox_cmd)); - memset(&mbox_sts, 0, sizeof(mbox_sts)); - - mbox_cmd[0] = MBOX_CMD_REQUEST_DATABASE_ENTRY; - mbox_cmd[1] = MAX_PRST_DEV_DB_ENTRIES; - - if (qla4xxx_mailbox_command(ha, 2, 3, &mbox_cmd[0], &mbox_sts[0]) != - QLA_SUCCESS) { - if (mbox_sts[0] == MBOX_STS_COMMAND_ERROR) { - *ddb_index = mbox_sts[2]; - } else { - DEBUG2(printk("scsi%ld: %s: failed status %04X\n", - ha->host_no, __func__, mbox_sts[0])); - return QLA_ERROR; - } - } else { - *ddb_index = MAX_PRST_DEV_DB_ENTRIES; - } - - return QLA_SUCCESS; -} - - -int qla4xxx_send_tgts(struct scsi_qla_host *ha, char *ip, uint16_t port) -{ - struct dev_db_entry *fw_ddb_entry; - dma_addr_t fw_ddb_entry_dma; - uint32_t ddb_index; - int ret_val = QLA_SUCCESS; - - - fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, - sizeof(*fw_ddb_entry), - &fw_ddb_entry_dma, GFP_KERNEL); - if (!fw_ddb_entry) { - DEBUG2(printk("scsi%ld: %s: Unable to allocate dma buffer.\n", - ha->host_no, __func__)); - ret_val = QLA_ERROR; - goto qla4xxx_send_tgts_exit; - } - - ret_val = qla4xxx_get_default_ddb(ha, fw_ddb_entry_dma); - if (ret_val != QLA_SUCCESS) - goto qla4xxx_send_tgts_exit; - - ret_val = qla4xxx_req_ddb_entry(ha, &ddb_index); - if (ret_val != QLA_SUCCESS) - goto qla4xxx_send_tgts_exit; - - memset((void *)fw_ddb_entry->iSCSIAlias, 0, - sizeof(fw_ddb_entry->iSCSIAlias)); - - memset((void *)fw_ddb_entry->iscsiName, 0, - sizeof(fw_ddb_entry->iscsiName)); - - memset((void *)fw_ddb_entry->ipAddr, 0, sizeof(fw_ddb_entry->ipAddr)); - memset((void *)fw_ddb_entry->targetAddr, 0, - sizeof(fw_ddb_entry->targetAddr)); - - fw_ddb_entry->options = (DDB_OPT_DISC_SESSION | DDB_OPT_TARGET); - fw_ddb_entry->portNumber = cpu_to_le16(ntohs(port)); - - fw_ddb_entry->ipAddr[0] = *ip; - fw_ddb_entry->ipAddr[1] = *(ip + 1); - fw_ddb_entry->ipAddr[2] = *(ip + 2); - fw_ddb_entry->ipAddr[3] = *(ip + 3); - - ret_val = qla4xxx_set_ddb_entry(ha, ddb_index, fw_ddb_entry_dma); - -qla4xxx_send_tgts_exit: - dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), - fw_ddb_entry, fw_ddb_entry_dma); - return ret_val; -} - diff --git a/trunk/drivers/scsi/qla4xxx/ql4_nvram.c b/trunk/drivers/scsi/qla4xxx/ql4_nvram.c deleted file mode 100644 index e3957ca5b645..000000000000 --- a/trunk/drivers/scsi/qla4xxx/ql4_nvram.c +++ /dev/null @@ -1,224 +0,0 @@ -/* - * QLogic iSCSI HBA Driver - * Copyright (c) 2003-2006 QLogic Corporation - * - * See LICENSE.qla4xxx for copyright and licensing details. - */ - -#include "ql4_def.h" - -static inline int eeprom_size(struct scsi_qla_host *ha) -{ - return is_qla4022(ha) ? FM93C86A_SIZE_16 : FM93C66A_SIZE_16; -} - -static inline int eeprom_no_addr_bits(struct scsi_qla_host *ha) -{ - return is_qla4022(ha) ? FM93C86A_NO_ADDR_BITS_16 : - FM93C56A_NO_ADDR_BITS_16; -} - -static inline int eeprom_no_data_bits(struct scsi_qla_host *ha) -{ - return FM93C56A_DATA_BITS_16; -} - -static int fm93c56a_select(struct scsi_qla_host * ha) -{ - DEBUG5(printk(KERN_ERR "fm93c56a_select:\n")); - - ha->eeprom_cmd_data = AUBURN_EEPROM_CS_1 | 0x000f0000; - writel(ha->eeprom_cmd_data, isp_nvram(ha)); - readl(isp_nvram(ha)); - return 1; -} - -static int fm93c56a_cmd(struct scsi_qla_host * ha, int cmd, int addr) -{ - int i; - int mask; - int dataBit; - int previousBit; - - /* Clock in a zero, then do the start bit. */ - writel(ha->eeprom_cmd_data | AUBURN_EEPROM_DO_1, isp_nvram(ha)); - writel(ha->eeprom_cmd_data | AUBURN_EEPROM_DO_1 | - AUBURN_EEPROM_CLK_RISE, isp_nvram(ha)); - writel(ha->eeprom_cmd_data | AUBURN_EEPROM_DO_1 | - AUBURN_EEPROM_CLK_FALL, isp_nvram(ha)); - readl(isp_nvram(ha)); - mask = 1 << (FM93C56A_CMD_BITS - 1); - - /* Force the previous data bit to be different. */ - previousBit = 0xffff; - for (i = 0; i < FM93C56A_CMD_BITS; i++) { - dataBit = - (cmd & mask) ? AUBURN_EEPROM_DO_1 : AUBURN_EEPROM_DO_0; - if (previousBit != dataBit) { - - /* - * If the bit changed, then change the DO state to - * match. - */ - writel(ha->eeprom_cmd_data | dataBit, isp_nvram(ha)); - previousBit = dataBit; - } - writel(ha->eeprom_cmd_data | dataBit | - AUBURN_EEPROM_CLK_RISE, isp_nvram(ha)); - writel(ha->eeprom_cmd_data | dataBit | - AUBURN_EEPROM_CLK_FALL, isp_nvram(ha)); - readl(isp_nvram(ha)); - cmd = cmd << 1; - } - mask = 1 << (eeprom_no_addr_bits(ha) - 1); - - /* Force the previous data bit to be different. */ - previousBit = 0xffff; - for (i = 0; i < eeprom_no_addr_bits(ha); i++) { - dataBit = addr & mask ? AUBURN_EEPROM_DO_1 : - AUBURN_EEPROM_DO_0; - if (previousBit != dataBit) { - /* - * If the bit changed, then change the DO state to - * match. - */ - writel(ha->eeprom_cmd_data | dataBit, isp_nvram(ha)); - previousBit = dataBit; - } - writel(ha->eeprom_cmd_data | dataBit | - AUBURN_EEPROM_CLK_RISE, isp_nvram(ha)); - writel(ha->eeprom_cmd_data | dataBit | - AUBURN_EEPROM_CLK_FALL, isp_nvram(ha)); - readl(isp_nvram(ha)); - addr = addr << 1; - } - return 1; -} - -static int fm93c56a_deselect(struct scsi_qla_host * ha) -{ - ha->eeprom_cmd_data = AUBURN_EEPROM_CS_0 | 0x000f0000; - writel(ha->eeprom_cmd_data, isp_nvram(ha)); - readl(isp_nvram(ha)); - return 1; -} - -static int fm93c56a_datain(struct scsi_qla_host * ha, unsigned short *value) -{ - int i; - int data = 0; - int dataBit; - - /* Read the data bits - * The first bit is a dummy. Clock right over it. */ - for (i = 0; i < eeprom_no_data_bits(ha); i++) { - writel(ha->eeprom_cmd_data | - AUBURN_EEPROM_CLK_RISE, isp_nvram(ha)); - writel(ha->eeprom_cmd_data | - AUBURN_EEPROM_CLK_FALL, isp_nvram(ha)); - dataBit = - (readw(isp_nvram(ha)) & AUBURN_EEPROM_DI_1) ? 1 : 0; - data = (data << 1) | dataBit; - } - - *value = data; - return 1; -} - -static int eeprom_readword(int eepromAddr, u16 * value, - struct scsi_qla_host * ha) -{ - fm93c56a_select(ha); - fm93c56a_cmd(ha, FM93C56A_READ, eepromAddr); - fm93c56a_datain(ha, value); - fm93c56a_deselect(ha); - return 1; -} - -/* Hardware_lock must be set before calling */ -u16 rd_nvram_word(struct scsi_qla_host * ha, int offset) -{ - u16 val; - - /* NOTE: NVRAM uses half-word addresses */ - eeprom_readword(offset, &val, ha); - return val; -} - -int qla4xxx_is_nvram_configuration_valid(struct scsi_qla_host * ha) -{ - int status = QLA_ERROR; - uint16_t checksum = 0; - uint32_t index; - unsigned long flags; - - spin_lock_irqsave(&ha->hardware_lock, flags); - for (index = 0; index < eeprom_size(ha); index++) - checksum += rd_nvram_word(ha, index); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - if (checksum == 0) - status = QLA_SUCCESS; - - return status; -} - -/************************************************************************* - * - * Hardware Semaphore routines - * - *************************************************************************/ -int ql4xxx_sem_spinlock(struct scsi_qla_host * ha, u32 sem_mask, u32 sem_bits) -{ - uint32_t value; - unsigned long flags; - unsigned int seconds = 30; - - DEBUG2(printk("scsi%ld : Trying to get SEM lock - mask= 0x%x, code = " - "0x%x\n", ha->host_no, sem_mask, sem_bits)); - do { - spin_lock_irqsave(&ha->hardware_lock, flags); - writel((sem_mask | sem_bits), isp_semaphore(ha)); - value = readw(isp_semaphore(ha)); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - if ((value & (sem_mask >> 16)) == sem_bits) { - DEBUG2(printk("scsi%ld : Got SEM LOCK - mask= 0x%x, " - "code = 0x%x\n", ha->host_no, - sem_mask, sem_bits)); - return QLA_SUCCESS; - } - ssleep(1); - } while (--seconds); - return QLA_ERROR; -} - -void ql4xxx_sem_unlock(struct scsi_qla_host * ha, u32 sem_mask) -{ - unsigned long flags; - - spin_lock_irqsave(&ha->hardware_lock, flags); - writel(sem_mask, isp_semaphore(ha)); - readl(isp_semaphore(ha)); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - DEBUG2(printk("scsi%ld : UNLOCK SEM - mask= 0x%x\n", ha->host_no, - sem_mask)); -} - -int ql4xxx_sem_lock(struct scsi_qla_host * ha, u32 sem_mask, u32 sem_bits) -{ - uint32_t value; - unsigned long flags; - - spin_lock_irqsave(&ha->hardware_lock, flags); - writel((sem_mask | sem_bits), isp_semaphore(ha)); - value = readw(isp_semaphore(ha)); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - if ((value & (sem_mask >> 16)) == sem_bits) { - DEBUG2(printk("scsi%ld : Got SEM LOCK - mask= 0x%x, code = " - "0x%x, sema code=0x%x\n", ha->host_no, - sem_mask, sem_bits, value)); - return 1; - } - return 0; -} diff --git a/trunk/drivers/scsi/qla4xxx/ql4_nvram.h b/trunk/drivers/scsi/qla4xxx/ql4_nvram.h deleted file mode 100644 index 08e2aed8c6cc..000000000000 --- a/trunk/drivers/scsi/qla4xxx/ql4_nvram.h +++ /dev/null @@ -1,256 +0,0 @@ -/* - * QLogic iSCSI HBA Driver - * Copyright (c) 2003-2006 QLogic Corporation - * - * See LICENSE.qla4xxx for copyright and licensing details. - */ - -#ifndef _QL4XNVRM_H_ -#define _QL4XNVRM_H_ - -/* - * AM29LV Flash definitions - */ -#define FM93C56A_SIZE_8 0x100 -#define FM93C56A_SIZE_16 0x80 -#define FM93C66A_SIZE_8 0x200 -#define FM93C66A_SIZE_16 0x100/* 4010 */ -#define FM93C86A_SIZE_16 0x400/* 4022 */ - -#define FM93C56A_START 0x1 - -// Commands -#define FM93C56A_READ 0x2 -#define FM93C56A_WEN 0x0 -#define FM93C56A_WRITE 0x1 -#define FM93C56A_WRITE_ALL 0x0 -#define FM93C56A_WDS 0x0 -#define FM93C56A_ERASE 0x3 -#define FM93C56A_ERASE_ALL 0x0 - -/* Command Extentions */ -#define FM93C56A_WEN_EXT 0x3 -#define FM93C56A_WRITE_ALL_EXT 0x1 -#define FM93C56A_WDS_EXT 0x0 -#define FM93C56A_ERASE_ALL_EXT 0x2 - -/* Address Bits */ -#define FM93C56A_NO_ADDR_BITS_16 8 /* 4010 */ -#define FM93C56A_NO_ADDR_BITS_8 9 /* 4010 */ -#define FM93C86A_NO_ADDR_BITS_16 10 /* 4022 */ - -/* Data Bits */ -#define FM93C56A_DATA_BITS_16 16 -#define FM93C56A_DATA_BITS_8 8 - -/* Special Bits */ -#define FM93C56A_READ_DUMMY_BITS 1 -#define FM93C56A_READY 0 -#define FM93C56A_BUSY 1 -#define FM93C56A_CMD_BITS 2 - -/* Auburn Bits */ -#define AUBURN_EEPROM_DI 0x8 -#define AUBURN_EEPROM_DI_0 0x0 -#define AUBURN_EEPROM_DI_1 0x8 -#define AUBURN_EEPROM_DO 0x4 -#define AUBURN_EEPROM_DO_0 0x0 -#define AUBURN_EEPROM_DO_1 0x4 -#define AUBURN_EEPROM_CS 0x2 -#define AUBURN_EEPROM_CS_0 0x0 -#define AUBURN_EEPROM_CS_1 0x2 -#define AUBURN_EEPROM_CLK_RISE 0x1 -#define AUBURN_EEPROM_CLK_FALL 0x0 - -/* */ -/* EEPROM format */ -/* */ -struct bios_params { - uint16_t SpinUpDelay:1; - uint16_t BIOSDisable:1; - uint16_t MMAPEnable:1; - uint16_t BootEnable:1; - uint16_t Reserved0:12; - uint8_t bootID0:7; - uint8_t bootID0Valid:1; - uint8_t bootLUN0[8]; - uint8_t bootID1:7; - uint8_t bootID1Valid:1; - uint8_t bootLUN1[8]; - uint16_t MaxLunsPerTarget; - uint8_t Reserved1[10]; -}; - -struct eeprom_port_cfg { - - /* MTU MAC 0 */ - u16 etherMtu_mac; - - /* Flow Control MAC 0 */ - u16 pauseThreshold_mac; - u16 resumeThreshold_mac; - u16 reserved[13]; -}; - -struct eeprom_function_cfg { - u8 reserved[30]; - - /* MAC ADDR */ - u8 macAddress[6]; - u8 macAddressSecondary[6]; - u16 subsysVendorId; - u16 subsysDeviceId; -}; - -struct eeprom_data { - union { - struct { /* isp4010 */ - u8 asic_id[4]; /* x00 */ - u8 version; /* x04 */ - u8 reserved; /* x05 */ - u16 board_id; /* x06 */ -#define EEPROM_BOARDID_ELDORADO 1 -#define EEPROM_BOARDID_PLACER 2 - -#define EEPROM_SERIAL_NUM_SIZE 16 - u8 serial_number[EEPROM_SERIAL_NUM_SIZE]; /* x08 */ - - /* ExtHwConfig: */ - /* Offset = 24bytes - * - * | SSRAM Size| |ST|PD|SDRAM SZ| W| B| SP | | - * |15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| - * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - */ - u16 ext_hw_conf; /* x18 */ - u8 mac0[6]; /* x1A */ - u8 mac1[6]; /* x20 */ - u8 mac2[6]; /* x26 */ - u8 mac3[6]; /* x2C */ - u16 etherMtu; /* x32 */ - u16 macConfig; /* x34 */ -#define MAC_CONFIG_ENABLE_ANEG 0x0001 -#define MAC_CONFIG_ENABLE_PAUSE 0x0002 - u16 phyConfig; /* x36 */ -#define PHY_CONFIG_PHY_ADDR_MASK 0x1f -#define PHY_CONFIG_ENABLE_FW_MANAGEMENT_MASK 0x20 - u16 topcat; /* x38 */ -#define TOPCAT_PRESENT 0x0100 -#define TOPCAT_MASK 0xFF00 - -#define EEPROM_UNUSED_1_SIZE 2 - u8 unused_1[EEPROM_UNUSED_1_SIZE]; /* x3A */ - u16 bufletSize; /* x3C */ - u16 bufletCount; /* x3E */ - u16 bufletPauseThreshold; /* x40 */ - u16 tcpWindowThreshold50; /* x42 */ - u16 tcpWindowThreshold25; /* x44 */ - u16 tcpWindowThreshold0; /* x46 */ - u16 ipHashTableBaseHi; /* x48 */ - u16 ipHashTableBaseLo; /* x4A */ - u16 ipHashTableSize; /* x4C */ - u16 tcpHashTableBaseHi; /* x4E */ - u16 tcpHashTableBaseLo; /* x50 */ - u16 tcpHashTableSize; /* x52 */ - u16 ncbTableBaseHi; /* x54 */ - u16 ncbTableBaseLo; /* x56 */ - u16 ncbTableSize; /* x58 */ - u16 drbTableBaseHi; /* x5A */ - u16 drbTableBaseLo; /* x5C */ - u16 drbTableSize; /* x5E */ - -#define EEPROM_UNUSED_2_SIZE 4 - u8 unused_2[EEPROM_UNUSED_2_SIZE]; /* x60 */ - u16 ipReassemblyTimeout; /* x64 */ - u16 tcpMaxWindowSizeHi; /* x66 */ - u16 tcpMaxWindowSizeLo; /* x68 */ - u32 net_ip_addr0; /* x6A Added for TOE - * functionality. */ - u32 net_ip_addr1; /* x6E */ - u32 scsi_ip_addr0; /* x72 */ - u32 scsi_ip_addr1; /* x76 */ -#define EEPROM_UNUSED_3_SIZE 128 /* changed from 144 to account - * for ip addresses */ - u8 unused_3[EEPROM_UNUSED_3_SIZE]; /* x7A */ - u16 subsysVendorId_f0; /* xFA */ - u16 subsysDeviceId_f0; /* xFC */ - - /* Address = 0x7F */ -#define FM93C56A_SIGNATURE 0x9356 -#define FM93C66A_SIGNATURE 0x9366 - u16 signature; /* xFE */ - -#define EEPROM_UNUSED_4_SIZE 250 - u8 unused_4[EEPROM_UNUSED_4_SIZE]; /* x100 */ - u16 subsysVendorId_f1; /* x1FA */ - u16 subsysDeviceId_f1; /* x1FC */ - u16 checksum; /* x1FE */ - } __attribute__ ((packed)) isp4010; - struct { /* isp4022 */ - u8 asicId[4]; /* x00 */ - u8 version; /* x04 */ - u8 reserved_5; /* x05 */ - u16 boardId; /* x06 */ - u8 boardIdStr[16]; /* x08 */ - u8 serialNumber[16]; /* x18 */ - - /* External Hardware Configuration */ - u16 ext_hw_conf; /* x28 */ - - /* MAC 0 CONFIGURATION */ - struct eeprom_port_cfg macCfg_port0; /* x2A */ - - /* MAC 1 CONFIGURATION */ - struct eeprom_port_cfg macCfg_port1; /* x4A */ - - /* DDR SDRAM Configuration */ - u16 bufletSize; /* x6A */ - u16 bufletCount; /* x6C */ - u16 tcpWindowThreshold50; /* x6E */ - u16 tcpWindowThreshold25; /* x70 */ - u16 tcpWindowThreshold0; /* x72 */ - u16 ipHashTableBaseHi; /* x74 */ - u16 ipHashTableBaseLo; /* x76 */ - u16 ipHashTableSize; /* x78 */ - u16 tcpHashTableBaseHi; /* x7A */ - u16 tcpHashTableBaseLo; /* x7C */ - u16 tcpHashTableSize; /* x7E */ - u16 ncbTableBaseHi; /* x80 */ - u16 ncbTableBaseLo; /* x82 */ - u16 ncbTableSize; /* x84 */ - u16 drbTableBaseHi; /* x86 */ - u16 drbTableBaseLo; /* x88 */ - u16 drbTableSize; /* x8A */ - u16 reserved_142[4]; /* x8C */ - - /* TCP/IP Parameters */ - u16 ipReassemblyTimeout; /* x94 */ - u16 tcpMaxWindowSize; /* x96 */ - u16 ipSecurity; /* x98 */ - u8 reserved_156[294]; /* x9A */ - u16 qDebug[8]; /* QLOGIC USE ONLY x1C0 */ - struct eeprom_function_cfg funcCfg_fn0; /* x1D0 */ - u16 reserved_510; /* x1FE */ - - /* Address = 512 */ - u8 oemSpace[432]; /* x200 */ - struct bios_params sBIOSParams_fn1; /* x3B0 */ - struct eeprom_function_cfg funcCfg_fn1; /* x3D0 */ - u16 reserved_1022; /* x3FE */ - - /* Address = 1024 */ - u8 reserved_1024[464]; /* x400 */ - struct eeprom_function_cfg funcCfg_fn2; /* x5D0 */ - u16 reserved_1534; /* x5FE */ - - /* Address = 1536 */ - u8 reserved_1536[432]; /* x600 */ - struct bios_params sBIOSParams_fn3; /* x7B0 */ - struct eeprom_function_cfg funcCfg_fn3; /* x7D0 */ - u16 checksum; /* x7FE */ - } __attribute__ ((packed)) isp4022; - }; -}; - - -#endif /* _QL4XNVRM_H_ */ diff --git a/trunk/drivers/scsi/qla4xxx/ql4_os.c b/trunk/drivers/scsi/qla4xxx/ql4_os.c deleted file mode 100644 index 5b8db6109536..000000000000 --- a/trunk/drivers/scsi/qla4xxx/ql4_os.c +++ /dev/null @@ -1,1755 +0,0 @@ -/* - * QLogic iSCSI HBA Driver - * Copyright (c) 2003-2006 QLogic Corporation - * - * See LICENSE.qla4xxx for copyright and licensing details. - */ -#include - -#include -#include - -#include "ql4_def.h" - -/* - * Driver version - */ -char qla4xxx_version_str[40]; - -/* - * SRB allocation cache - */ -static kmem_cache_t *srb_cachep; - -/* - * Module parameter information and variables - */ -int ql4xdiscoverywait = 60; -module_param(ql4xdiscoverywait, int, S_IRUGO | S_IRUSR); -MODULE_PARM_DESC(ql4xdiscoverywait, "Discovery wait time"); -int ql4xdontresethba = 0; -module_param(ql4xdontresethba, int, S_IRUGO | S_IRUSR); -MODULE_PARM_DESC(ql4xdontresethba, - "Dont reset the HBA when the driver gets 0x8002 AEN " - " default it will reset hba :0" - " set to 1 to avoid resetting HBA"); - -int ql4xextended_error_logging = 0; /* 0 = off, 1 = log errors */ -module_param(ql4xextended_error_logging, int, S_IRUGO | S_IRUSR); -MODULE_PARM_DESC(ql4xextended_error_logging, - "Option to enable extended error logging, " - "Default is 0 - no logging, 1 - debug logging"); - -/* - * SCSI host template entry points - */ - -void qla4xxx_config_dma_addressing(struct scsi_qla_host *ha); - -/* - * iSCSI template entry points - */ -static int qla4xxx_tgt_dscvr(enum iscsi_tgt_dscvr type, uint32_t host_no, - uint32_t enable, struct sockaddr *dst_addr); -static int qla4xxx_conn_get_param(struct iscsi_cls_conn *conn, - enum iscsi_param param, char *buf); -static int qla4xxx_sess_get_param(struct iscsi_cls_session *sess, - enum iscsi_param param, char *buf); -static void qla4xxx_conn_stop(struct iscsi_cls_conn *conn, int flag); -static int qla4xxx_conn_start(struct iscsi_cls_conn *conn); -static void qla4xxx_recovery_timedout(struct iscsi_cls_session *session); - -/* - * SCSI host template entry points - */ -static int qla4xxx_queuecommand(struct scsi_cmnd *cmd, - void (*done) (struct scsi_cmnd *)); -static int qla4xxx_eh_device_reset(struct scsi_cmnd *cmd); -static int qla4xxx_eh_host_reset(struct scsi_cmnd *cmd); -static int qla4xxx_slave_alloc(struct scsi_device *device); -static int qla4xxx_slave_configure(struct scsi_device *device); -static void qla4xxx_slave_destroy(struct scsi_device *sdev); - -static struct scsi_host_template qla4xxx_driver_template = { - .module = THIS_MODULE, - .name = DRIVER_NAME, - .proc_name = DRIVER_NAME, - .queuecommand = qla4xxx_queuecommand, - - .eh_device_reset_handler = qla4xxx_eh_device_reset, - .eh_host_reset_handler = qla4xxx_eh_host_reset, - - .slave_configure = qla4xxx_slave_configure, - .slave_alloc = qla4xxx_slave_alloc, - .slave_destroy = qla4xxx_slave_destroy, - - .this_id = -1, - .cmd_per_lun = 3, - .use_clustering = ENABLE_CLUSTERING, - .sg_tablesize = SG_ALL, - - .max_sectors = 0xFFFF, -}; - -static struct iscsi_transport qla4xxx_iscsi_transport = { - .owner = THIS_MODULE, - .name = DRIVER_NAME, - .param_mask = ISCSI_CONN_PORT | - ISCSI_CONN_ADDRESS | - ISCSI_TARGET_NAME | - ISCSI_TPGT, - .sessiondata_size = sizeof(struct ddb_entry), - .host_template = &qla4xxx_driver_template, - - .tgt_dscvr = qla4xxx_tgt_dscvr, - .get_conn_param = qla4xxx_conn_get_param, - .get_session_param = qla4xxx_sess_get_param, - .start_conn = qla4xxx_conn_start, - .stop_conn = qla4xxx_conn_stop, - .session_recovery_timedout = qla4xxx_recovery_timedout, -}; - -static struct scsi_transport_template *qla4xxx_scsi_transport; - -static void qla4xxx_recovery_timedout(struct iscsi_cls_session *session) -{ - struct ddb_entry *ddb_entry = session->dd_data; - struct scsi_qla_host *ha = ddb_entry->ha; - - DEBUG2(printk("scsi%ld: %s: index [%d] port down retry count of (%d) " - "secs exhausted, marking device DEAD.\n", ha->host_no, - __func__, ddb_entry->fw_ddb_index, - ha->port_down_retry_count)); - - atomic_set(&ddb_entry->state, DDB_STATE_DEAD); - - DEBUG2(printk("scsi%ld: %s: scheduling dpc routine - dpc flags = " - "0x%lx\n", ha->host_no, __func__, ha->dpc_flags)); - queue_work(ha->dpc_thread, &ha->dpc_work); -} - -static int qla4xxx_conn_start(struct iscsi_cls_conn *conn) -{ - struct iscsi_cls_session *session; - struct ddb_entry *ddb_entry; - - session = iscsi_dev_to_session(conn->dev.parent); - ddb_entry = session->dd_data; - - DEBUG2(printk("scsi%ld: %s: index [%d] starting conn\n", - ddb_entry->ha->host_no, __func__, - ddb_entry->fw_ddb_index)); - iscsi_unblock_session(session); - return 0; -} - -static void qla4xxx_conn_stop(struct iscsi_cls_conn *conn, int flag) -{ - struct iscsi_cls_session *session; - struct ddb_entry *ddb_entry; - - session = iscsi_dev_to_session(conn->dev.parent); - ddb_entry = session->dd_data; - - DEBUG2(printk("scsi%ld: %s: index [%d] stopping conn\n", - ddb_entry->ha->host_no, __func__, - ddb_entry->fw_ddb_index)); - if (flag == STOP_CONN_RECOVER) - iscsi_block_session(session); - else - printk(KERN_ERR "iscsi: invalid stop flag %d\n", flag); -} - -static int qla4xxx_sess_get_param(struct iscsi_cls_session *sess, - enum iscsi_param param, char *buf) -{ - struct ddb_entry *ddb_entry = sess->dd_data; - int len; - - switch (param) { - case ISCSI_PARAM_TARGET_NAME: - len = snprintf(buf, PAGE_SIZE - 1, "%s\n", - ddb_entry->iscsi_name); - break; - case ISCSI_PARAM_TPGT: - len = sprintf(buf, "%u\n", ddb_entry->tpgt); - break; - default: - return -ENOSYS; - } - - return len; -} - -static int qla4xxx_conn_get_param(struct iscsi_cls_conn *conn, - enum iscsi_param param, char *buf) -{ - struct iscsi_cls_session *session; - struct ddb_entry *ddb_entry; - int len; - - session = iscsi_dev_to_session(conn->dev.parent); - ddb_entry = session->dd_data; - - switch (param) { - case ISCSI_PARAM_CONN_PORT: - len = sprintf(buf, "%hu\n", ddb_entry->port); - break; - case ISCSI_PARAM_CONN_ADDRESS: - /* TODO: what are the ipv6 bits */ - len = sprintf(buf, "%u.%u.%u.%u\n", - NIPQUAD(ddb_entry->ip_addr)); - break; - default: - return -ENOSYS; - } - - return len; -} - -static int qla4xxx_tgt_dscvr(enum iscsi_tgt_dscvr type, uint32_t host_no, - uint32_t enable, struct sockaddr *dst_addr) -{ - struct scsi_qla_host *ha; - struct Scsi_Host *shost; - struct sockaddr_in *addr; - struct sockaddr_in6 *addr6; - int ret = 0; - - shost = scsi_host_lookup(host_no); - if (IS_ERR(shost)) { - printk(KERN_ERR "Could not find host no %u\n", host_no); - return -ENODEV; - } - - ha = (struct scsi_qla_host *) shost->hostdata; - - switch (type) { - case ISCSI_TGT_DSCVR_SEND_TARGETS: - if (dst_addr->sa_family == AF_INET) { - addr = (struct sockaddr_in *)dst_addr; - if (qla4xxx_send_tgts(ha, (char *)&addr->sin_addr, - addr->sin_port) != QLA_SUCCESS) - ret = -EIO; - } else if (dst_addr->sa_family == AF_INET6) { - /* - * TODO: fix qla4xxx_send_tgts - */ - addr6 = (struct sockaddr_in6 *)dst_addr; - if (qla4xxx_send_tgts(ha, (char *)&addr6->sin6_addr, - addr6->sin6_port) != QLA_SUCCESS) - ret = -EIO; - } else - ret = -ENOSYS; - break; - default: - ret = -ENOSYS; - } - - scsi_host_put(shost); - return ret; -} - -void qla4xxx_destroy_sess(struct ddb_entry *ddb_entry) -{ - if (!ddb_entry->sess) - return; - - if (ddb_entry->conn) { - iscsi_if_destroy_session_done(ddb_entry->conn); - iscsi_destroy_conn(ddb_entry->conn); - iscsi_remove_session(ddb_entry->sess); - } - iscsi_free_session(ddb_entry->sess); -} - -int qla4xxx_add_sess(struct ddb_entry *ddb_entry) -{ - int err; - - err = iscsi_add_session(ddb_entry->sess, ddb_entry->fw_ddb_index); - if (err) { - DEBUG2(printk(KERN_ERR "Could not add session.\n")); - return err; - } - - ddb_entry->conn = iscsi_create_conn(ddb_entry->sess, 0); - if (!ddb_entry->conn) { - iscsi_remove_session(ddb_entry->sess); - DEBUG2(printk(KERN_ERR "Could not add connection.\n")); - return -ENOMEM; - } - - ddb_entry->sess->recovery_tmo = ddb_entry->ha->port_down_retry_count; - iscsi_if_create_session_done(ddb_entry->conn); - return 0; -} - -struct ddb_entry *qla4xxx_alloc_sess(struct scsi_qla_host *ha) -{ - struct ddb_entry *ddb_entry; - struct iscsi_cls_session *sess; - - sess = iscsi_alloc_session(ha->host, &qla4xxx_iscsi_transport); - if (!sess) - return NULL; - - ddb_entry = sess->dd_data; - memset(ddb_entry, 0, sizeof(*ddb_entry)); - ddb_entry->ha = ha; - ddb_entry->sess = sess; - return ddb_entry; -} - -/* - * Timer routines - */ - -static void qla4xxx_start_timer(struct scsi_qla_host *ha, void *func, - unsigned long interval) -{ - DEBUG(printk("scsi: %s: Starting timer thread for adapter %d\n", - __func__, ha->host->host_no)); - init_timer(&ha->timer); - ha->timer.expires = jiffies + interval * HZ; - ha->timer.data = (unsigned long)ha; - ha->timer.function = (void (*)(unsigned long))func; - add_timer(&ha->timer); - ha->timer_active = 1; -} - -static void qla4xxx_stop_timer(struct scsi_qla_host *ha) -{ - del_timer_sync(&ha->timer); - ha->timer_active = 0; -} - -/*** - * qla4xxx_mark_device_missing - mark a device as missing. - * @ha: Pointer to host adapter structure. - * @ddb_entry: Pointer to device database entry - * - * This routine marks a device missing and resets the relogin retry count. - **/ -void qla4xxx_mark_device_missing(struct scsi_qla_host *ha, - struct ddb_entry *ddb_entry) -{ - atomic_set(&ddb_entry->state, DDB_STATE_MISSING); - DEBUG3(printk("scsi%d:%d:%d: index [%d] marked MISSING\n", - ha->host_no, ddb_entry->bus, ddb_entry->target, - ddb_entry->fw_ddb_index)); - iscsi_conn_error(ddb_entry->conn, ISCSI_ERR_CONN_FAILED); -} - -static struct srb* qla4xxx_get_new_srb(struct scsi_qla_host *ha, - struct ddb_entry *ddb_entry, - struct scsi_cmnd *cmd, - void (*done)(struct scsi_cmnd *)) -{ - struct srb *srb; - - srb = mempool_alloc(ha->srb_mempool, GFP_ATOMIC); - if (!srb) - return srb; - - atomic_set(&srb->ref_count, 1); - srb->ha = ha; - srb->ddb = ddb_entry; - srb->cmd = cmd; - srb->flags = 0; - cmd->SCp.ptr = (void *)srb; - cmd->scsi_done = done; - - return srb; -} - -static void qla4xxx_srb_free_dma(struct scsi_qla_host *ha, struct srb *srb) -{ - struct scsi_cmnd *cmd = srb->cmd; - - if (srb->flags & SRB_DMA_VALID) { - if (cmd->use_sg) { - pci_unmap_sg(ha->pdev, cmd->request_buffer, - cmd->use_sg, cmd->sc_data_direction); - } else if (cmd->request_bufflen) { - pci_unmap_single(ha->pdev, srb->dma_handle, - cmd->request_bufflen, - cmd->sc_data_direction); - } - srb->flags &= ~SRB_DMA_VALID; - } - cmd->SCp.ptr = NULL; -} - -void qla4xxx_srb_compl(struct scsi_qla_host *ha, struct srb *srb) -{ - struct scsi_cmnd *cmd = srb->cmd; - - qla4xxx_srb_free_dma(ha, srb); - - mempool_free(srb, ha->srb_mempool); - - cmd->scsi_done(cmd); -} - -/** - * qla4xxx_queuecommand - scsi layer issues scsi command to driver. - * @cmd: Pointer to Linux's SCSI command structure - * @done_fn: Function that the driver calls to notify the SCSI mid-layer - * that the command has been processed. - * - * Remarks: - * This routine is invoked by Linux to send a SCSI command to the driver. - * The mid-level driver tries to ensure that queuecommand never gets - * invoked concurrently with itself or the interrupt handler (although - * the interrupt handler may call this routine as part of request- - * completion handling). Unfortunely, it sometimes calls the scheduler - * in interrupt context which is a big NO! NO!. - **/ -static int qla4xxx_queuecommand(struct scsi_cmnd *cmd, - void (*done)(struct scsi_cmnd *)) -{ - struct scsi_qla_host *ha = to_qla_host(cmd->device->host); - struct ddb_entry *ddb_entry = cmd->device->hostdata; - struct srb *srb; - int rval; - - if (atomic_read(&ddb_entry->state) != DDB_STATE_ONLINE) { - if (atomic_read(&ddb_entry->state) == DDB_STATE_DEAD) { - cmd->result = DID_NO_CONNECT << 16; - goto qc_fail_command; - } - goto qc_host_busy; - } - - spin_unlock_irq(ha->host->host_lock); - - srb = qla4xxx_get_new_srb(ha, ddb_entry, cmd, done); - if (!srb) - goto qc_host_busy_lock; - - rval = qla4xxx_send_command_to_isp(ha, srb); - if (rval != QLA_SUCCESS) - goto qc_host_busy_free_sp; - - spin_lock_irq(ha->host->host_lock); - return 0; - -qc_host_busy_free_sp: - qla4xxx_srb_free_dma(ha, srb); - mempool_free(srb, ha->srb_mempool); - -qc_host_busy_lock: - spin_lock_irq(ha->host->host_lock); - -qc_host_busy: - return SCSI_MLQUEUE_HOST_BUSY; - -qc_fail_command: - done(cmd); - - return 0; -} - -/** - * qla4xxx_mem_free - frees memory allocated to adapter - * @ha: Pointer to host adapter structure. - * - * Frees memory previously allocated by qla4xxx_mem_alloc - **/ -static void qla4xxx_mem_free(struct scsi_qla_host *ha) -{ - if (ha->queues) - dma_free_coherent(&ha->pdev->dev, ha->queues_len, ha->queues, - ha->queues_dma); - - ha->queues_len = 0; - ha->queues = NULL; - ha->queues_dma = 0; - ha->request_ring = NULL; - ha->request_dma = 0; - ha->response_ring = NULL; - ha->response_dma = 0; - ha->shadow_regs = NULL; - ha->shadow_regs_dma = 0; - - /* Free srb pool. */ - if (ha->srb_mempool) - mempool_destroy(ha->srb_mempool); - - ha->srb_mempool = NULL; - - /* release io space registers */ - if (ha->reg) - iounmap(ha->reg); - pci_release_regions(ha->pdev); -} - -/** - * qla4xxx_mem_alloc - allocates memory for use by adapter. - * @ha: Pointer to host adapter structure - * - * Allocates DMA memory for request and response queues. Also allocates memory - * for srbs. - **/ -static int qla4xxx_mem_alloc(struct scsi_qla_host *ha) -{ - unsigned long align; - - /* Allocate contiguous block of DMA memory for queues. */ - ha->queues_len = ((REQUEST_QUEUE_DEPTH * QUEUE_SIZE) + - (RESPONSE_QUEUE_DEPTH * QUEUE_SIZE) + - sizeof(struct shadow_regs) + - MEM_ALIGN_VALUE + - (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1); - ha->queues = dma_alloc_coherent(&ha->pdev->dev, ha->queues_len, - &ha->queues_dma, GFP_KERNEL); - if (ha->queues == NULL) { - dev_warn(&ha->pdev->dev, - "Memory Allocation failed - queues.\n"); - - goto mem_alloc_error_exit; - } - memset(ha->queues, 0, ha->queues_len); - - /* - * As per RISC alignment requirements -- the bus-address must be a - * multiple of the request-ring size (in bytes). - */ - align = 0; - if ((unsigned long)ha->queues_dma & (MEM_ALIGN_VALUE - 1)) - align = MEM_ALIGN_VALUE - ((unsigned long)ha->queues_dma & - (MEM_ALIGN_VALUE - 1)); - - /* Update request and response queue pointers. */ - ha->request_dma = ha->queues_dma + align; - ha->request_ring = (struct queue_entry *) (ha->queues + align); - ha->response_dma = ha->queues_dma + align + - (REQUEST_QUEUE_DEPTH * QUEUE_SIZE); - ha->response_ring = (struct queue_entry *) (ha->queues + align + - (REQUEST_QUEUE_DEPTH * - QUEUE_SIZE)); - ha->shadow_regs_dma = ha->queues_dma + align + - (REQUEST_QUEUE_DEPTH * QUEUE_SIZE) + - (RESPONSE_QUEUE_DEPTH * QUEUE_SIZE); - ha->shadow_regs = (struct shadow_regs *) (ha->queues + align + - (REQUEST_QUEUE_DEPTH * - QUEUE_SIZE) + - (RESPONSE_QUEUE_DEPTH * - QUEUE_SIZE)); - - /* Allocate memory for srb pool. */ - ha->srb_mempool = mempool_create(SRB_MIN_REQ, mempool_alloc_slab, - mempool_free_slab, srb_cachep); - if (ha->srb_mempool == NULL) { - dev_warn(&ha->pdev->dev, - "Memory Allocation failed - SRB Pool.\n"); - - goto mem_alloc_error_exit; - } - - return QLA_SUCCESS; - -mem_alloc_error_exit: - qla4xxx_mem_free(ha); - return QLA_ERROR; -} - -/** - * qla4xxx_timer - checks every second for work to do. - * @ha: Pointer to host adapter structure. - **/ -static void qla4xxx_timer(struct scsi_qla_host *ha) -{ - struct ddb_entry *ddb_entry, *dtemp; - int start_dpc = 0; - - /* Search for relogin's to time-out and port down retry. */ - list_for_each_entry_safe(ddb_entry, dtemp, &ha->ddb_list, list) { - /* Count down time between sending relogins */ - if (adapter_up(ha) && - !test_bit(DF_RELOGIN, &ddb_entry->flags) && - atomic_read(&ddb_entry->state) != DDB_STATE_ONLINE) { - if (atomic_read(&ddb_entry->retry_relogin_timer) != - INVALID_ENTRY) { - if (atomic_read(&ddb_entry->retry_relogin_timer) - == 0) { - atomic_set(&ddb_entry-> - retry_relogin_timer, - INVALID_ENTRY); - set_bit(DPC_RELOGIN_DEVICE, - &ha->dpc_flags); - set_bit(DF_RELOGIN, &ddb_entry->flags); - DEBUG2(printk("scsi%ld: %s: index [%d]" - " login device\n", - ha->host_no, __func__, - ddb_entry->fw_ddb_index)); - } else - atomic_dec(&ddb_entry-> - retry_relogin_timer); - } - } - - /* Wait for relogin to timeout */ - if (atomic_read(&ddb_entry->relogin_timer) && - (atomic_dec_and_test(&ddb_entry->relogin_timer) != 0)) { - /* - * If the relogin times out and the device is - * still NOT ONLINE then try and relogin again. - */ - if (atomic_read(&ddb_entry->state) != - DDB_STATE_ONLINE && - ddb_entry->fw_ddb_device_state == - DDB_DS_SESSION_FAILED) { - /* Reset retry relogin timer */ - atomic_inc(&ddb_entry->relogin_retry_count); - DEBUG2(printk("scsi%ld: index[%d] relogin" - " timed out-retrying" - " relogin (%d)\n", - ha->host_no, - ddb_entry->fw_ddb_index, - atomic_read(&ddb_entry-> - relogin_retry_count)) - ); - start_dpc++; - DEBUG(printk("scsi%ld:%d:%d: index [%d] " - "initate relogin after" - " %d seconds\n", - ha->host_no, ddb_entry->bus, - ddb_entry->target, - ddb_entry->fw_ddb_index, - ddb_entry->default_time2wait + 4) - ); - - atomic_set(&ddb_entry->retry_relogin_timer, - ddb_entry->default_time2wait + 4); - } - } - } - - /* Check for heartbeat interval. */ - if (ha->firmware_options & FWOPT_HEARTBEAT_ENABLE && - ha->heartbeat_interval != 0) { - ha->seconds_since_last_heartbeat++; - if (ha->seconds_since_last_heartbeat > - ha->heartbeat_interval + 2) - set_bit(DPC_RESET_HA, &ha->dpc_flags); - } - - - /* Wakeup the dpc routine for this adapter, if needed. */ - if ((start_dpc || - test_bit(DPC_RESET_HA, &ha->dpc_flags) || - test_bit(DPC_RETRY_RESET_HA, &ha->dpc_flags) || - test_bit(DPC_RELOGIN_DEVICE, &ha->dpc_flags) || - test_bit(DPC_RESET_HA_DESTROY_DDB_LIST, &ha->dpc_flags) || - test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags) || - test_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags) || - test_bit(DPC_AEN, &ha->dpc_flags)) && - ha->dpc_thread) { - DEBUG2(printk("scsi%ld: %s: scheduling dpc routine" - " - dpc flags = 0x%lx\n", - ha->host_no, __func__, ha->dpc_flags)); - queue_work(ha->dpc_thread, &ha->dpc_work); - } - - /* Reschedule timer thread to call us back in one second */ - mod_timer(&ha->timer, jiffies + HZ); - - DEBUG2(ha->seconds_since_last_intr++); -} - -/** - * qla4xxx_cmd_wait - waits for all outstanding commands to complete - * @ha: Pointer to host adapter structure. - * - * This routine stalls the driver until all outstanding commands are returned. - * Caller must release the Hardware Lock prior to calling this routine. - **/ -static int qla4xxx_cmd_wait(struct scsi_qla_host *ha) -{ - uint32_t index = 0; - int stat = QLA_SUCCESS; - unsigned long flags; - struct scsi_cmnd *cmd; - int wait_cnt = WAIT_CMD_TOV; /* - * Initialized for 30 seconds as we - * expect all commands to retuned - * ASAP. - */ - - while (wait_cnt) { - spin_lock_irqsave(&ha->hardware_lock, flags); - /* Find a command that hasn't completed. */ - for (index = 0; index < ha->host->can_queue; index++) { - cmd = scsi_host_find_tag(ha->host, index); - if (cmd != NULL) - break; - } - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - /* If No Commands are pending, wait is complete */ - if (index == ha->host->can_queue) { - break; - } - - /* If we timed out on waiting for commands to come back - * return ERROR. - */ - wait_cnt--; - if (wait_cnt == 0) - stat = QLA_ERROR; - else { - msleep(1000); - } - } /* End of While (wait_cnt) */ - - return stat; -} - -/** - * qla4010_soft_reset - performs soft reset. - * @ha: Pointer to host adapter structure. - **/ -static int qla4010_soft_reset(struct scsi_qla_host *ha) -{ - uint32_t max_wait_time; - unsigned long flags = 0; - int status = QLA_ERROR; - uint32_t ctrl_status; - - spin_lock_irqsave(&ha->hardware_lock, flags); - - /* - * If the SCSI Reset Interrupt bit is set, clear it. - * Otherwise, the Soft Reset won't work. - */ - ctrl_status = readw(&ha->reg->ctrl_status); - if ((ctrl_status & CSR_SCSI_RESET_INTR) != 0) - writel(set_rmask(CSR_SCSI_RESET_INTR), &ha->reg->ctrl_status); - - /* Issue Soft Reset */ - writel(set_rmask(CSR_SOFT_RESET), &ha->reg->ctrl_status); - readl(&ha->reg->ctrl_status); - - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - /* Wait until the Network Reset Intr bit is cleared */ - max_wait_time = RESET_INTR_TOV; - do { - spin_lock_irqsave(&ha->hardware_lock, flags); - ctrl_status = readw(&ha->reg->ctrl_status); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - if ((ctrl_status & CSR_NET_RESET_INTR) == 0) - break; - - msleep(1000); - } while ((--max_wait_time)); - - if ((ctrl_status & CSR_NET_RESET_INTR) != 0) { - DEBUG2(printk(KERN_WARNING - "scsi%ld: Network Reset Intr not cleared by " - "Network function, clearing it now!\n", - ha->host_no)); - spin_lock_irqsave(&ha->hardware_lock, flags); - writel(set_rmask(CSR_NET_RESET_INTR), &ha->reg->ctrl_status); - readl(&ha->reg->ctrl_status); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - } - - /* Wait until the firmware tells us the Soft Reset is done */ - max_wait_time = SOFT_RESET_TOV; - do { - spin_lock_irqsave(&ha->hardware_lock, flags); - ctrl_status = readw(&ha->reg->ctrl_status); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - if ((ctrl_status & CSR_SOFT_RESET) == 0) { - status = QLA_SUCCESS; - break; - } - - msleep(1000); - } while ((--max_wait_time)); - - /* - * Also, make sure that the SCSI Reset Interrupt bit has been cleared - * after the soft reset has taken place. - */ - spin_lock_irqsave(&ha->hardware_lock, flags); - ctrl_status = readw(&ha->reg->ctrl_status); - if ((ctrl_status & CSR_SCSI_RESET_INTR) != 0) { - writel(set_rmask(CSR_SCSI_RESET_INTR), &ha->reg->ctrl_status); - readl(&ha->reg->ctrl_status); - } - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - /* If soft reset fails then most probably the bios on other - * function is also enabled. - * Since the initialization is sequential the other fn - * wont be able to acknowledge the soft reset. - * Issue a force soft reset to workaround this scenario. - */ - if (max_wait_time == 0) { - /* Issue Force Soft Reset */ - spin_lock_irqsave(&ha->hardware_lock, flags); - writel(set_rmask(CSR_FORCE_SOFT_RESET), &ha->reg->ctrl_status); - readl(&ha->reg->ctrl_status); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - /* Wait until the firmware tells us the Soft Reset is done */ - max_wait_time = SOFT_RESET_TOV; - do { - spin_lock_irqsave(&ha->hardware_lock, flags); - ctrl_status = readw(&ha->reg->ctrl_status); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - if ((ctrl_status & CSR_FORCE_SOFT_RESET) == 0) { - status = QLA_SUCCESS; - break; - } - - msleep(1000); - } while ((--max_wait_time)); - } - - return status; -} - -/** - * qla4xxx_topcat_reset - performs hard reset of TopCat Chip. - * @ha: Pointer to host adapter structure. - **/ -static int qla4xxx_topcat_reset(struct scsi_qla_host *ha) -{ - unsigned long flags; - - ql4xxx_lock_nvram(ha); - spin_lock_irqsave(&ha->hardware_lock, flags); - writel(set_rmask(GPOR_TOPCAT_RESET), isp_gp_out(ha)); - readl(isp_gp_out(ha)); - mdelay(1); - - writel(clr_rmask(GPOR_TOPCAT_RESET), isp_gp_out(ha)); - readl(isp_gp_out(ha)); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - mdelay(2523); - - ql4xxx_unlock_nvram(ha); - return QLA_SUCCESS; -} - -/** - * qla4xxx_flush_active_srbs - returns all outstanding i/o requests to O.S. - * @ha: Pointer to host adapter structure. - * - * This routine is called just prior to a HARD RESET to return all - * outstanding commands back to the Operating System. - * Caller should make sure that the following locks are released - * before this calling routine: Hardware lock, and io_request_lock. - **/ -static void qla4xxx_flush_active_srbs(struct scsi_qla_host *ha) -{ - struct srb *srb; - int i; - unsigned long flags; - - spin_lock_irqsave(&ha->hardware_lock, flags); - for (i = 0; i < ha->host->can_queue; i++) { - srb = qla4xxx_del_from_active_array(ha, i); - if (srb != NULL) { - srb->cmd->result = DID_RESET << 16; - qla4xxx_srb_compl(ha, srb); - } - } - spin_unlock_irqrestore(&ha->hardware_lock, flags); - -} - -/** - * qla4xxx_hard_reset - performs HBA Hard Reset - * @ha: Pointer to host adapter structure. - **/ -static int qla4xxx_hard_reset(struct scsi_qla_host *ha) -{ - /* The QLA4010 really doesn't have an equivalent to a hard reset */ - qla4xxx_flush_active_srbs(ha); - if (test_bit(AF_TOPCAT_CHIP_PRESENT, &ha->flags)) { - int status = QLA_ERROR; - - if ((qla4010_soft_reset(ha) == QLA_SUCCESS) && - (qla4xxx_topcat_reset(ha) == QLA_SUCCESS) && - (qla4010_soft_reset(ha) == QLA_SUCCESS)) - status = QLA_SUCCESS; - return status; - } else - return qla4010_soft_reset(ha); -} - -/** - * qla4xxx_recover_adapter - recovers adapter after a fatal error - * @ha: Pointer to host adapter structure. - * @renew_ddb_list: Indicates what to do with the adapter's ddb list - * after adapter recovery has completed. - * 0=preserve ddb list, 1=destroy and rebuild ddb list - **/ -static int qla4xxx_recover_adapter(struct scsi_qla_host *ha, - uint8_t renew_ddb_list) -{ - int status; - - /* Stall incoming I/O until we are done */ - clear_bit(AF_ONLINE, &ha->flags); - DEBUG2(printk("scsi%ld: %s calling qla4xxx_cmd_wait\n", ha->host_no, - __func__)); - - /* Wait for outstanding commands to complete. - * Stalls the driver for max 30 secs - */ - status = qla4xxx_cmd_wait(ha); - - qla4xxx_disable_intrs(ha); - - /* Flush any pending ddb changed AENs */ - qla4xxx_process_aen(ha, FLUSH_DDB_CHANGED_AENS); - - /* Reset the firmware. If successful, function - * returns with ISP interrupts enabled. - */ - if (status == QLA_SUCCESS) { - DEBUG2(printk("scsi%ld: %s - Performing soft reset..\n", - ha->host_no, __func__)); - status = qla4xxx_soft_reset(ha); - } - /* FIXMEkaren: Do we want to keep interrupts enabled and process - AENs after soft reset */ - - /* If firmware (SOFT) reset failed, or if all outstanding - * commands have not returned, then do a HARD reset. - */ - if (status == QLA_ERROR) { - DEBUG2(printk("scsi%ld: %s - Performing hard reset..\n", - ha->host_no, __func__)); - status = qla4xxx_hard_reset(ha); - } - - /* Flush any pending ddb changed AENs */ - qla4xxx_process_aen(ha, FLUSH_DDB_CHANGED_AENS); - - /* Re-initialize firmware. If successful, function returns - * with ISP interrupts enabled */ - if (status == QLA_SUCCESS) { - DEBUG2(printk("scsi%ld: %s - Initializing adapter..\n", - ha->host_no, __func__)); - - /* If successful, AF_ONLINE flag set in - * qla4xxx_initialize_adapter */ - status = qla4xxx_initialize_adapter(ha, renew_ddb_list); - } - - /* Failed adapter initialization? - * Retry reset_ha only if invoked via DPC (DPC_RESET_HA) */ - if ((test_bit(AF_ONLINE, &ha->flags) == 0) && - (test_bit(DPC_RESET_HA, &ha->dpc_flags))) { - /* Adapter initialization failed, see if we can retry - * resetting the ha */ - if (!test_bit(DPC_RETRY_RESET_HA, &ha->dpc_flags)) { - ha->retry_reset_ha_cnt = MAX_RESET_HA_RETRIES; - DEBUG2(printk("scsi%ld: recover adapter - retrying " - "(%d) more times\n", ha->host_no, - ha->retry_reset_ha_cnt)); - set_bit(DPC_RETRY_RESET_HA, &ha->dpc_flags); - status = QLA_ERROR; - } else { - if (ha->retry_reset_ha_cnt > 0) { - /* Schedule another Reset HA--DPC will retry */ - ha->retry_reset_ha_cnt--; - DEBUG2(printk("scsi%ld: recover adapter - " - "retry remaining %d\n", - ha->host_no, - ha->retry_reset_ha_cnt)); - status = QLA_ERROR; - } - - if (ha->retry_reset_ha_cnt == 0) { - /* Recover adapter retries have been exhausted. - * Adapter DEAD */ - DEBUG2(printk("scsi%ld: recover adapter " - "failed - board disabled\n", - ha->host_no)); - qla4xxx_flush_active_srbs(ha); - clear_bit(DPC_RETRY_RESET_HA, &ha->dpc_flags); - clear_bit(DPC_RESET_HA, &ha->dpc_flags); - clear_bit(DPC_RESET_HA_DESTROY_DDB_LIST, - &ha->dpc_flags); - status = QLA_ERROR; - } - } - } else { - clear_bit(DPC_RESET_HA, &ha->dpc_flags); - clear_bit(DPC_RESET_HA_DESTROY_DDB_LIST, &ha->dpc_flags); - clear_bit(DPC_RETRY_RESET_HA, &ha->dpc_flags); - } - - ha->adapter_error_count++; - - if (status == QLA_SUCCESS) - qla4xxx_enable_intrs(ha); - - DEBUG2(printk("scsi%ld: recover adapter .. DONE\n", ha->host_no)); - return status; -} - -/** - * qla4xxx_do_dpc - dpc routine - * @data: in our case pointer to adapter structure - * - * This routine is a task that is schedule by the interrupt handler - * to perform the background processing for interrupts. We put it - * on a task queue that is consumed whenever the scheduler runs; that's - * so you can do anything (i.e. put the process to sleep etc). In fact, - * the mid-level tries to sleep when it reaches the driver threshold - * "host->can_queue". This can cause a panic if we were in our interrupt code. - **/ -static void qla4xxx_do_dpc(void *data) -{ - struct scsi_qla_host *ha = (struct scsi_qla_host *) data; - struct ddb_entry *ddb_entry, *dtemp; - - DEBUG2(printk("scsi%ld: %s: DPC handler waking up.\n", - ha->host_no, __func__)); - - DEBUG2(printk("scsi%ld: %s: ha->flags = 0x%08lx\n", - ha->host_no, __func__, ha->flags)); - DEBUG2(printk("scsi%ld: %s: ha->dpc_flags = 0x%08lx\n", - ha->host_no, __func__, ha->dpc_flags)); - - /* Initialization not yet finished. Don't do anything yet. */ - if (!test_bit(AF_INIT_DONE, &ha->flags)) - return; - - if (adapter_up(ha) || - test_bit(DPC_RESET_HA, &ha->dpc_flags) || - test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags) || - test_bit(DPC_RESET_HA_DESTROY_DDB_LIST, &ha->dpc_flags)) { - if (test_bit(DPC_RESET_HA_DESTROY_DDB_LIST, &ha->dpc_flags)) - /* - * dg 09/23 Never initialize ddb list - * once we up and running - * qla4xxx_recover_adapter(ha, - * REBUILD_DDB_LIST); - */ - qla4xxx_recover_adapter(ha, PRESERVE_DDB_LIST); - - if (test_bit(DPC_RESET_HA, &ha->dpc_flags)) - qla4xxx_recover_adapter(ha, PRESERVE_DDB_LIST); - - if (test_and_clear_bit(DPC_RESET_HA_INTR, &ha->dpc_flags)) { - uint8_t wait_time = RESET_INTR_TOV; - unsigned long flags = 0; - - qla4xxx_flush_active_srbs(ha); - - spin_lock_irqsave(&ha->hardware_lock, flags); - while ((readw(&ha->reg->ctrl_status) & - (CSR_SOFT_RESET | CSR_FORCE_SOFT_RESET)) != 0) { - if (--wait_time == 0) - break; - - spin_unlock_irqrestore(&ha->hardware_lock, - flags); - - msleep(1000); - - spin_lock_irqsave(&ha->hardware_lock, flags); - } - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - if (wait_time == 0) - DEBUG2(printk("scsi%ld: %s: SR|FSR " - "bit not cleared-- resetting\n", - ha->host_no, __func__)); - } - } - - /* ---- process AEN? --- */ - if (test_and_clear_bit(DPC_AEN, &ha->dpc_flags)) - qla4xxx_process_aen(ha, PROCESS_ALL_AENS); - - /* ---- Get DHCP IP Address? --- */ - if (test_and_clear_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags)) - qla4xxx_get_dhcp_ip_address(ha); - - /* ---- relogin device? --- */ - if (adapter_up(ha) && - test_and_clear_bit(DPC_RELOGIN_DEVICE, &ha->dpc_flags)) { - list_for_each_entry_safe(ddb_entry, dtemp, - &ha->ddb_list, list) { - if (test_and_clear_bit(DF_RELOGIN, &ddb_entry->flags) && - atomic_read(&ddb_entry->state) != DDB_STATE_ONLINE) - qla4xxx_relogin_device(ha, ddb_entry); - - /* - * If mbx cmd times out there is no point - * in continuing further. - * With large no of targets this can hang - * the system. - */ - if (test_bit(DPC_RESET_HA, &ha->dpc_flags)) { - printk(KERN_WARNING "scsi%ld: %s: " - "need to reset hba\n", - ha->host_no, __func__); - break; - } - } - } -} - -/** - * qla4xxx_free_adapter - release the adapter - * @ha: pointer to adapter structure - **/ -static void qla4xxx_free_adapter(struct scsi_qla_host *ha) -{ - - if (test_bit(AF_INTERRUPTS_ON, &ha->flags)) { - /* Turn-off interrupts on the card. */ - qla4xxx_disable_intrs(ha); - } - - /* Kill the kernel thread for this host */ - if (ha->dpc_thread) - destroy_workqueue(ha->dpc_thread); - - /* Issue Soft Reset to put firmware in unknown state */ - qla4xxx_soft_reset(ha); - - /* Remove timer thread, if present */ - if (ha->timer_active) - qla4xxx_stop_timer(ha); - - /* free extra memory */ - qla4xxx_mem_free(ha); - - /* Detach interrupts */ - if (test_and_clear_bit(AF_IRQ_ATTACHED, &ha->flags)) - free_irq(ha->pdev->irq, ha); - - pci_disable_device(ha->pdev); - -} - -/*** - * qla4xxx_iospace_config - maps registers - * @ha: pointer to adapter structure - * - * This routines maps HBA's registers from the pci address space - * into the kernel virtual address space for memory mapped i/o. - **/ -static int qla4xxx_iospace_config(struct scsi_qla_host *ha) -{ - unsigned long pio, pio_len, pio_flags; - unsigned long mmio, mmio_len, mmio_flags; - - pio = pci_resource_start(ha->pdev, 0); - pio_len = pci_resource_len(ha->pdev, 0); - pio_flags = pci_resource_flags(ha->pdev, 0); - if (pio_flags & IORESOURCE_IO) { - if (pio_len < MIN_IOBASE_LEN) { - dev_warn(&ha->pdev->dev, - "Invalid PCI I/O region size\n"); - pio = 0; - } - } else { - dev_warn(&ha->pdev->dev, "region #0 not a PIO resource\n"); - pio = 0; - } - - /* Use MMIO operations for all accesses. */ - mmio = pci_resource_start(ha->pdev, 1); - mmio_len = pci_resource_len(ha->pdev, 1); - mmio_flags = pci_resource_flags(ha->pdev, 1); - - if (!(mmio_flags & IORESOURCE_MEM)) { - dev_err(&ha->pdev->dev, - "region #0 not an MMIO resource, aborting\n"); - - goto iospace_error_exit; - } - if (mmio_len < MIN_IOBASE_LEN) { - dev_err(&ha->pdev->dev, - "Invalid PCI mem region size, aborting\n"); - goto iospace_error_exit; - } - - if (pci_request_regions(ha->pdev, DRIVER_NAME)) { - dev_warn(&ha->pdev->dev, - "Failed to reserve PIO/MMIO regions\n"); - - goto iospace_error_exit; - } - - ha->pio_address = pio; - ha->pio_length = pio_len; - ha->reg = ioremap(mmio, MIN_IOBASE_LEN); - if (!ha->reg) { - dev_err(&ha->pdev->dev, - "cannot remap MMIO, aborting\n"); - - goto iospace_error_exit; - } - - return 0; - -iospace_error_exit: - return -ENOMEM; -} - -/** - * qla4xxx_probe_adapter - callback function to probe HBA - * @pdev: pointer to pci_dev structure - * @pci_device_id: pointer to pci_device entry - * - * This routine will probe for Qlogic 4xxx iSCSI host adapters. - * It returns zero if successful. It also initializes all data necessary for - * the driver. - **/ -static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - int ret = -ENODEV, status; - struct Scsi_Host *host; - struct scsi_qla_host *ha; - struct ddb_entry *ddb_entry, *ddbtemp; - uint8_t init_retry_count = 0; - char buf[34]; - - if (pci_enable_device(pdev)) - return -1; - - host = scsi_host_alloc(&qla4xxx_driver_template, sizeof(*ha)); - if (host == NULL) { - printk(KERN_WARNING - "qla4xxx: Couldn't allocate host from scsi layer!\n"); - goto probe_disable_device; - } - - /* Clear our data area */ - ha = (struct scsi_qla_host *) host->hostdata; - memset(ha, 0, sizeof(*ha)); - - /* Save the information from PCI BIOS. */ - ha->pdev = pdev; - ha->host = host; - ha->host_no = host->host_no; - - /* Configure PCI I/O space. */ - ret = qla4xxx_iospace_config(ha); - if (ret) - goto probe_failed; - - dev_info(&ha->pdev->dev, "Found an ISP%04x, irq %d, iobase 0x%p\n", - pdev->device, pdev->irq, ha->reg); - - qla4xxx_config_dma_addressing(ha); - - /* Initialize lists and spinlocks. */ - INIT_LIST_HEAD(&ha->ddb_list); - INIT_LIST_HEAD(&ha->free_srb_q); - - mutex_init(&ha->mbox_sem); - init_waitqueue_head(&ha->mailbox_wait_queue); - - spin_lock_init(&ha->hardware_lock); - spin_lock_init(&ha->list_lock); - - /* Allocate dma buffers */ - if (qla4xxx_mem_alloc(ha)) { - dev_warn(&ha->pdev->dev, - "[ERROR] Failed to allocate memory for adapter\n"); - - ret = -ENOMEM; - goto probe_failed; - } - - /* - * Initialize the Host adapter request/response queues and - * firmware - * NOTE: interrupts enabled upon successful completion - */ - status = qla4xxx_initialize_adapter(ha, REBUILD_DDB_LIST); - while (status == QLA_ERROR && init_retry_count++ < MAX_INIT_RETRIES) { - DEBUG2(printk("scsi: %s: retrying adapter initialization " - "(%d)\n", __func__, init_retry_count)); - qla4xxx_soft_reset(ha); - status = qla4xxx_initialize_adapter(ha, REBUILD_DDB_LIST); - } - if (status == QLA_ERROR) { - dev_warn(&ha->pdev->dev, "Failed to initialize adapter\n"); - - ret = -ENODEV; - goto probe_failed; - } - - host->cmd_per_lun = 3; - host->max_channel = 0; - host->max_lun = MAX_LUNS - 1; - host->max_id = MAX_TARGETS; - host->max_cmd_len = IOCB_MAX_CDB_LEN; - host->can_queue = MAX_SRBS ; - host->transportt = qla4xxx_scsi_transport; - - ret = scsi_init_shared_tag_map(host, MAX_SRBS); - if (ret) { - dev_warn(&ha->pdev->dev, "scsi_init_shared_tag_map failed"); - goto probe_failed; - } - - /* Startup the kernel thread for this host adapter. */ - DEBUG2(printk("scsi: %s: Starting kernel thread for " - "qla4xxx_dpc\n", __func__)); - sprintf(buf, "qla4xxx_%lu_dpc", ha->host_no); - ha->dpc_thread = create_singlethread_workqueue(buf); - if (!ha->dpc_thread) { - dev_warn(&ha->pdev->dev, "Unable to start DPC thread!\n"); - ret = -ENODEV; - goto probe_failed; - } - INIT_WORK(&ha->dpc_work, qla4xxx_do_dpc, ha); - - ret = request_irq(pdev->irq, qla4xxx_intr_handler, - SA_INTERRUPT|SA_SHIRQ, "qla4xxx", ha); - if (ret) { - dev_warn(&ha->pdev->dev, "Failed to reserve interrupt %d" - " already in use.\n", pdev->irq); - goto probe_failed; - } - set_bit(AF_IRQ_ATTACHED, &ha->flags); - host->irq = pdev->irq; - DEBUG(printk("scsi%d: irq %d attached\n", ha->host_no, ha->pdev->irq)); - - qla4xxx_enable_intrs(ha); - - /* Start timer thread. */ - qla4xxx_start_timer(ha, qla4xxx_timer, 1); - - set_bit(AF_INIT_DONE, &ha->flags); - - pci_set_drvdata(pdev, ha); - - ret = scsi_add_host(host, &pdev->dev); - if (ret) - goto probe_failed; - - /* Update transport device information for all devices. */ - list_for_each_entry_safe(ddb_entry, ddbtemp, &ha->ddb_list, list) { - if (ddb_entry->fw_ddb_device_state == DDB_DS_SESSION_ACTIVE) - if (qla4xxx_add_sess(ddb_entry)) - goto remove_host; - } - - printk(KERN_INFO - " QLogic iSCSI HBA Driver version: %s\n" - " QLogic ISP%04x @ %s, host#=%ld, fw=%02d.%02d.%02d.%02d\n", - qla4xxx_version_str, ha->pdev->device, pci_name(ha->pdev), - ha->host_no, ha->firmware_version[0], ha->firmware_version[1], - ha->patch_number, ha->build_number); - - return 0; - -remove_host: - qla4xxx_free_ddb_list(ha); - scsi_remove_host(host); - -probe_failed: - qla4xxx_free_adapter(ha); - scsi_host_put(ha->host); - -probe_disable_device: - pci_disable_device(pdev); - - return ret; -} - -/** - * qla4xxx_remove_adapter - calback function to remove adapter. - * @pci_dev: PCI device pointer - **/ -static void __devexit qla4xxx_remove_adapter(struct pci_dev *pdev) -{ - struct scsi_qla_host *ha; - - ha = pci_get_drvdata(pdev); - - /* remove devs from iscsi_sessions to scsi_devices */ - qla4xxx_free_ddb_list(ha); - - scsi_remove_host(ha->host); - - qla4xxx_free_adapter(ha); - - scsi_host_put(ha->host); - - pci_set_drvdata(pdev, NULL); -} - -/** - * qla4xxx_config_dma_addressing() - Configure OS DMA addressing method. - * @ha: HA context - * - * At exit, the @ha's flags.enable_64bit_addressing set to indicated - * supported addressing method. - */ -void qla4xxx_config_dma_addressing(struct scsi_qla_host *ha) -{ - int retval; - - /* Update our PCI device dma_mask for full 64 bit mask */ - if (pci_set_dma_mask(ha->pdev, DMA_64BIT_MASK) == 0) { - if (pci_set_consistent_dma_mask(ha->pdev, DMA_64BIT_MASK)) { - dev_dbg(&ha->pdev->dev, - "Failed to set 64 bit PCI consistent mask; " - "using 32 bit.\n"); - retval = pci_set_consistent_dma_mask(ha->pdev, - DMA_32BIT_MASK); - } - } else - retval = pci_set_dma_mask(ha->pdev, DMA_32BIT_MASK); -} - -static int qla4xxx_slave_alloc(struct scsi_device *sdev) -{ - struct iscsi_cls_session *sess = starget_to_session(sdev->sdev_target); - struct ddb_entry *ddb = sess->dd_data; - - sdev->hostdata = ddb; - sdev->tagged_supported = 1; - scsi_activate_tcq(sdev, sdev->host->can_queue); - return 0; -} - -static int qla4xxx_slave_configure(struct scsi_device *sdev) -{ - sdev->tagged_supported = 1; - return 0; -} - -static void qla4xxx_slave_destroy(struct scsi_device *sdev) -{ - scsi_deactivate_tcq(sdev, 1); -} - -/** - * qla4xxx_del_from_active_array - returns an active srb - * @ha: Pointer to host adapter structure. - * @index: index into to the active_array - * - * This routine removes and returns the srb at the specified index - **/ -struct srb * qla4xxx_del_from_active_array(struct scsi_qla_host *ha, uint32_t index) -{ - struct srb *srb = NULL; - struct scsi_cmnd *cmd; - - if (!(cmd = scsi_host_find_tag(ha->host, index))) - return srb; - - if (!(srb = (struct srb *)cmd->host_scribble)) - return srb; - - /* update counters */ - if (srb->flags & SRB_DMA_VALID) { - ha->req_q_count += srb->iocb_cnt; - ha->iocb_cnt -= srb->iocb_cnt; - if (srb->cmd) - srb->cmd->host_scribble = NULL; - } - return srb; -} - -/** - * qla4xxx_soft_reset - performs a SOFT RESET of hba. - * @ha: Pointer to host adapter structure. - **/ -int qla4xxx_soft_reset(struct scsi_qla_host *ha) -{ - - DEBUG2(printk(KERN_WARNING "scsi%ld: %s: chip reset!\n", ha->host_no, - __func__)); - if (test_bit(AF_TOPCAT_CHIP_PRESENT, &ha->flags)) { - int status = QLA_ERROR; - - if ((qla4010_soft_reset(ha) == QLA_SUCCESS) && - (qla4xxx_topcat_reset(ha) == QLA_SUCCESS) && - (qla4010_soft_reset(ha) == QLA_SUCCESS) ) - status = QLA_SUCCESS; - return status; - } else - return qla4010_soft_reset(ha); -} - -/** - * qla4xxx_eh_wait_on_command - waits for command to be returned by firmware - * @ha: actual ha whose done queue will contain the comd returned by firmware. - * @cmd: Scsi Command to wait on. - * - * This routine waits for the command to be returned by the Firmware - * for some max time. - **/ -static int qla4xxx_eh_wait_on_command(struct scsi_qla_host *ha, - struct scsi_cmnd *cmd) -{ - int done = 0; - struct srb *rp; - uint32_t max_wait_time = EH_WAIT_CMD_TOV; - - do { - /* Checking to see if its returned to OS */ - rp = (struct srb *) cmd->SCp.ptr; - if (rp == NULL) { - done++; - break; - } - - msleep(2000); - } while (max_wait_time--); - - return done; -} - -/** - * qla4xxx_wait_for_hba_online - waits for HBA to come online - * @ha: Pointer to host adapter structure - **/ -static int qla4xxx_wait_for_hba_online(struct scsi_qla_host *ha) -{ - unsigned long wait_online; - - wait_online = jiffies + (30 * HZ); - while (time_before(jiffies, wait_online)) { - - if (adapter_up(ha)) - return QLA_SUCCESS; - else if (ha->retry_reset_ha_cnt == 0) - return QLA_ERROR; - - msleep(2000); - } - - return QLA_ERROR; -} - -/** - * qla4xxx_eh_wait_for_active_target_commands - wait for active cmds to finish. - * @ha: pointer to to HBA - * @t: target id - * @l: lun id - * - * This function waits for all outstanding commands to a lun to complete. It - * returns 0 if all pending commands are returned and 1 otherwise. - **/ -static int qla4xxx_eh_wait_for_active_target_commands(struct scsi_qla_host *ha, - int t, int l) -{ - int cnt; - int status = 0; - struct scsi_cmnd *cmd; - - /* - * Waiting for all commands for the designated target in the active - * array - */ - for (cnt = 0; cnt < ha->host->can_queue; cnt++) { - cmd = scsi_host_find_tag(ha->host, cnt); - if (cmd && cmd->device->id == t && cmd->device->lun == l) { - if (!qla4xxx_eh_wait_on_command(ha, cmd)) { - status++; - break; - } - } - } - return status; -} - -/** - * qla4xxx_eh_device_reset - callback for target reset. - * @cmd: Pointer to Linux's SCSI command structure - * - * This routine is called by the Linux OS to reset all luns on the - * specified target. - **/ -static int qla4xxx_eh_device_reset(struct scsi_cmnd *cmd) -{ - struct scsi_qla_host *ha = to_qla_host(cmd->device->host); - struct ddb_entry *ddb_entry = cmd->device->hostdata; - struct srb *sp; - int ret = FAILED, stat; - - sp = (struct srb *) cmd->SCp.ptr; - if (!sp || !ddb_entry) - return ret; - - dev_info(&ha->pdev->dev, - "scsi%ld:%d:%d:%d: DEVICE RESET ISSUED.\n", ha->host_no, - cmd->device->channel, cmd->device->id, cmd->device->lun); - - DEBUG2(printk(KERN_INFO - "scsi%ld: DEVICE_RESET cmd=%p jiffies = 0x%lx, to=%x," - "dpc_flags=%lx, status=%x allowed=%d\n", ha->host_no, - cmd, jiffies, cmd->timeout_per_command / HZ, - ha->dpc_flags, cmd->result, cmd->allowed)); - - /* FIXME: wait for hba to go online */ - stat = qla4xxx_reset_lun(ha, ddb_entry, cmd->device->lun); - if (stat != QLA_SUCCESS) { - dev_info(&ha->pdev->dev, "DEVICE RESET FAILED. %d\n", stat); - goto eh_dev_reset_done; - } - - /* Send marker. */ - ha->marker_needed = 1; - - /* - * If we are coming down the EH path, wait for all commands to complete - * for the device. - */ - if (cmd->device->host->shost_state == SHOST_RECOVERY) { - if (qla4xxx_eh_wait_for_active_target_commands(ha, - cmd->device->id, - cmd->device->lun)){ - dev_info(&ha->pdev->dev, - "DEVICE RESET FAILED - waiting for " - "commands.\n"); - goto eh_dev_reset_done; - } - } - - dev_info(&ha->pdev->dev, - "scsi(%ld:%d:%d:%d): DEVICE RESET SUCCEEDED.\n", - ha->host_no, cmd->device->channel, cmd->device->id, - cmd->device->lun); - - ret = SUCCESS; - -eh_dev_reset_done: - - return ret; -} - -/** - * qla4xxx_eh_host_reset - kernel callback - * @cmd: Pointer to Linux's SCSI command structure - * - * This routine is invoked by the Linux kernel to perform fatal error - * recovery on the specified adapter. - **/ -static int qla4xxx_eh_host_reset(struct scsi_cmnd *cmd) -{ - int return_status = FAILED; - struct scsi_qla_host *ha; - - ha = (struct scsi_qla_host *) cmd->device->host->hostdata; - - dev_info(&ha->pdev->dev, - "scsi(%ld:%d:%d:%d): ADAPTER RESET ISSUED.\n", ha->host_no, - cmd->device->channel, cmd->device->id, cmd->device->lun); - - if (qla4xxx_wait_for_hba_online(ha) != QLA_SUCCESS) { - DEBUG2(printk("scsi%ld:%d: %s: Unable to reset host. Adapter " - "DEAD.\n", ha->host_no, cmd->device->channel, - __func__)); - - return FAILED; - } - - if (qla4xxx_recover_adapter(ha, PRESERVE_DDB_LIST) == QLA_SUCCESS) { - return_status = SUCCESS; - } - - dev_info(&ha->pdev->dev, "HOST RESET %s.\n", - return_status == FAILED ? "FAILED" : "SUCCEDED"); - - return return_status; -} - - -static struct pci_device_id qla4xxx_pci_tbl[] = { - { - .vendor = PCI_VENDOR_ID_QLOGIC, - .device = PCI_DEVICE_ID_QLOGIC_ISP4010, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - }, - { - .vendor = PCI_VENDOR_ID_QLOGIC, - .device = PCI_DEVICE_ID_QLOGIC_ISP4022, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - }, - {0, 0}, -}; -MODULE_DEVICE_TABLE(pci, qla4xxx_pci_tbl); - -struct pci_driver qla4xxx_pci_driver = { - .name = DRIVER_NAME, - .id_table = qla4xxx_pci_tbl, - .probe = qla4xxx_probe_adapter, - .remove = qla4xxx_remove_adapter, -}; - -static int __init qla4xxx_module_init(void) -{ - int ret; - - /* Allocate cache for SRBs. */ - srb_cachep = kmem_cache_create("qla4xxx_srbs", sizeof(struct srb), 0, - SLAB_HWCACHE_ALIGN, NULL, NULL); - if (srb_cachep == NULL) { - printk(KERN_ERR - "%s: Unable to allocate SRB cache..." - "Failing load!\n", DRIVER_NAME); - ret = -ENOMEM; - goto no_srp_cache; - } - - /* Derive version string. */ - strcpy(qla4xxx_version_str, QLA4XXX_DRIVER_VERSION); - if (ql4xextended_error_logging) - strcat(qla4xxx_version_str, "-debug"); - - qla4xxx_scsi_transport = - iscsi_register_transport(&qla4xxx_iscsi_transport); - if (!qla4xxx_scsi_transport){ - ret = -ENODEV; - goto release_srb_cache; - } - - ret = pci_register_driver(&qla4xxx_pci_driver); - if (ret) - goto unregister_transport; - - printk(KERN_INFO "QLogic iSCSI HBA Driver\n"); - return 0; - -unregister_transport: - iscsi_unregister_transport(&qla4xxx_iscsi_transport); -release_srb_cache: - kmem_cache_destroy(srb_cachep); -no_srp_cache: - return ret; -} - -static void __exit qla4xxx_module_exit(void) -{ - pci_unregister_driver(&qla4xxx_pci_driver); - iscsi_unregister_transport(&qla4xxx_iscsi_transport); - kmem_cache_destroy(srb_cachep); -} - -module_init(qla4xxx_module_init); -module_exit(qla4xxx_module_exit); - -MODULE_AUTHOR("QLogic Corporation"); -MODULE_DESCRIPTION("QLogic iSCSI HBA Driver"); -MODULE_LICENSE("GPL"); -MODULE_VERSION(QLA4XXX_DRIVER_VERSION); diff --git a/trunk/drivers/scsi/qla4xxx/ql4_version.h b/trunk/drivers/scsi/qla4xxx/ql4_version.h deleted file mode 100644 index b3fe7e68988e..000000000000 --- a/trunk/drivers/scsi/qla4xxx/ql4_version.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * QLogic iSCSI HBA Driver - * Copyright (c) 2003-2006 QLogic Corporation - * - * See LICENSE.qla4xxx for copyright and licensing details. - */ - -#define QLA4XXX_DRIVER_VERSION "5.00.05b9-k" - -#define QL4_DRIVER_MAJOR_VER 5 -#define QL4_DRIVER_MINOR_VER 0 -#define QL4_DRIVER_PATCH_VER 5 -#define QL4_DRIVER_BETA_VER 9 diff --git a/trunk/drivers/scsi/qlogicfas408.c b/trunk/drivers/scsi/qlogicfas408.c index 2e7db18f5aef..52fb2ec3da70 100644 --- a/trunk/drivers/scsi/qlogicfas408.c +++ b/trunk/drivers/scsi/qlogicfas408.c @@ -209,7 +209,7 @@ static int ql_wai(struct qlogicfas408_priv *priv) * caller must hold host lock */ -static void ql_icmd(struct scsi_cmnd *cmd) +static void ql_icmd(Scsi_Cmnd * cmd) { struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd); int qbase = priv->qbase; @@ -256,7 +256,7 @@ static void ql_icmd(struct scsi_cmnd *cmd) * Process scsi command - usually after interrupt */ -static unsigned int ql_pcmd(struct scsi_cmnd *cmd) +static unsigned int ql_pcmd(Scsi_Cmnd * cmd) { unsigned int i, j; unsigned long k; @@ -405,10 +405,10 @@ static unsigned int ql_pcmd(struct scsi_cmnd *cmd) * Interrupt handler */ -static void ql_ihandl(void *dev_id) +static void ql_ihandl(int irq, void *dev_id, struct pt_regs *regs) { - struct scsi_cmnd *icmd; - struct Scsi_Host *host = dev_id; + Scsi_Cmnd *icmd; + struct Scsi_Host *host = (struct Scsi_Host *)dev_id; struct qlogicfas408_priv *priv = get_priv_by_host(host); int qbase = priv->qbase; REG0; @@ -432,13 +432,13 @@ static void ql_ihandl(void *dev_id) (icmd->scsi_done) (icmd); } -irqreturn_t qlogicfas408_ihandl(int irq, void *dev_id) +irqreturn_t qlogicfas408_ihandl(int irq, void *dev_id, struct pt_regs *regs) { unsigned long flags; struct Scsi_Host *host = dev_id; spin_lock_irqsave(host->host_lock, flags); - ql_ihandl(dev_id); + ql_ihandl(irq, dev_id, regs); spin_unlock_irqrestore(host->host_lock, flags); return IRQ_HANDLED; } @@ -447,8 +447,7 @@ irqreturn_t qlogicfas408_ihandl(int irq, void *dev_id) * Queued command */ -int qlogicfas408_queuecommand(struct scsi_cmnd *cmd, - void (*done) (struct scsi_cmnd *)) +int qlogicfas408_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)) { struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd); if (scmd_id(cmd) == priv->qinitid) { @@ -471,8 +470,9 @@ int qlogicfas408_queuecommand(struct scsi_cmnd *cmd, * Return bios parameters */ -int qlogicfas408_biosparam(struct scsi_device *disk, struct block_device *dev, - sector_t capacity, int ip[]) +int qlogicfas408_biosparam(struct scsi_device * disk, + struct block_device *dev, + sector_t capacity, int ip[]) { /* This should mimic the DOS Qlogic driver's behavior exactly */ ip[0] = 0x40; @@ -494,7 +494,7 @@ int qlogicfas408_biosparam(struct scsi_device *disk, struct block_device *dev, * Abort a command in progress */ -int qlogicfas408_abort(struct scsi_cmnd *cmd) +int qlogicfas408_abort(Scsi_Cmnd * cmd) { struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd); priv->qabort = 1; @@ -508,7 +508,7 @@ int qlogicfas408_abort(struct scsi_cmnd *cmd) * the PCMCIA qlogic_stub code. This wants fixing */ -int qlogicfas408_bus_reset(struct scsi_cmnd *cmd) +int qlogicfas408_bus_reset(Scsi_Cmnd * cmd) { struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd); unsigned long flags; diff --git a/trunk/drivers/scsi/qlogicfas408.h b/trunk/drivers/scsi/qlogicfas408.h index 260626427a32..4b3df2003660 100644 --- a/trunk/drivers/scsi/qlogicfas408.h +++ b/trunk/drivers/scsi/qlogicfas408.h @@ -75,15 +75,15 @@ /*----------------------------------------------------------------*/ struct qlogicfas408_priv { - int qbase; /* Port */ - int qinitid; /* initiator ID */ - int qabort; /* Flag to cause an abort */ - int qlirq; /* IRQ being used */ - int int_type; /* type of irq, 2 for ISA board, 0 for PCMCIA */ - char qinfo[80]; /* description */ - struct scsi_cmnd *qlcmd; /* current command being processed */ - struct Scsi_Host *shost; /* pointer back to host */ - struct qlogicfas408_priv *next; /* next private struct */ + int qbase; /* Port */ + int qinitid; /* initiator ID */ + int qabort; /* Flag to cause an abort */ + int qlirq; /* IRQ being used */ + int int_type; /* type of irq, 2 for ISA board, 0 for PCMCIA */ + char qinfo[80]; /* description */ + Scsi_Cmnd *qlcmd; /* current command being processed */ + struct Scsi_Host *shost; /* pointer back to host */ + struct qlogicfas408_priv *next; /* next private struct */ }; /* The qlogic card uses two register maps - These macros select which one */ @@ -102,14 +102,13 @@ struct qlogicfas408_priv { #define get_priv_by_cmd(x) (struct qlogicfas408_priv *)&((x)->device->host->hostdata[0]) #define get_priv_by_host(x) (struct qlogicfas408_priv *)&((x)->hostdata[0]) -irqreturn_t qlogicfas408_ihandl(int irq, void *dev_id); -int qlogicfas408_queuecommand(struct scsi_cmnd * cmd, - void (*done) (struct scsi_cmnd *)); +irqreturn_t qlogicfas408_ihandl(int irq, void *dev_id, struct pt_regs *regs); +int qlogicfas408_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)); int qlogicfas408_biosparam(struct scsi_device * disk, - struct block_device *dev, - sector_t capacity, int ip[]); -int qlogicfas408_abort(struct scsi_cmnd * cmd); -int qlogicfas408_bus_reset(struct scsi_cmnd * cmd); + struct block_device *dev, + sector_t capacity, int ip[]); +int qlogicfas408_abort(Scsi_Cmnd * cmd); +int qlogicfas408_bus_reset(Scsi_Cmnd * cmd); const char *qlogicfas408_info(struct Scsi_Host *host); int qlogicfas408_get_chip_type(int qbase, int int_type); void qlogicfas408_setup(int qbase, int id, int int_type); diff --git a/trunk/drivers/scsi/qlogicpti.c b/trunk/drivers/scsi/qlogicpti.c index 9b827ceec501..5b2f0741a55b 100644 --- a/trunk/drivers/scsi/qlogicpti.c +++ b/trunk/drivers/scsi/qlogicpti.c @@ -461,7 +461,7 @@ static int qlogicpti_reset_hardware(struct Scsi_Host *host) #define PTI_RESET_LIMIT 400 -static int __devinit qlogicpti_load_firmware(struct qlogicpti *qpti) +static int __init qlogicpti_load_firmware(struct qlogicpti *qpti) { struct Scsi_Host *host = qpti->qhost; unsigned short csum = 0; @@ -649,7 +649,7 @@ static int qlogicpti_verify_tmon(struct qlogicpti *qpti) return 0; } -static irqreturn_t qpti_intr(int irq, void *dev_id); +static irqreturn_t qpti_intr(int irq, void *dev_id, struct pt_regs *regs); static void __init qpti_chain_add(struct qlogicpti *qpti) { @@ -1297,7 +1297,7 @@ static struct scsi_cmnd *qlogicpti_intr_handler(struct qlogicpti *qpti) return done_queue; } -static irqreturn_t qpti_intr(int irq, void *dev_id) +static irqreturn_t qpti_intr(int irq, void *dev_id, struct pt_regs *regs) { struct qlogicpti *qpti = dev_id; unsigned long flags; diff --git a/trunk/drivers/scsi/qlogicpti_asm.c b/trunk/drivers/scsi/qlogicpti_asm.c index 19aa84f46018..1545b30681b4 100644 --- a/trunk/drivers/scsi/qlogicpti_asm.c +++ b/trunk/drivers/scsi/qlogicpti_asm.c @@ -1,5 +1,5 @@ /* Version 1.31.00 ISP1000 Initiator RISC firmware */ -unsigned short sbus_risc_code01[] __devinitdata = { +unsigned short sbus_risc_code01[] __initdata = { 0x0078, 0x1030, 0x0000, 0x2419, 0x0000, 0x12ff, 0x2043, 0x4f50, 0x5952, 0x4947, 0x4854, 0x2031, 0x3939, 0x312c, 0x3139, 0x3932, 0x2c31, 0x3939, 0x332c, 0x3139, 0x3934, 0x2051, 0x4c4f, 0x4749, @@ -1157,4 +1157,4 @@ unsigned short sbus_risc_code01[] __devinitdata = { 0x003c, 0x0040, 0x3415, 0x2019, 0x2626, 0x7b22, 0x7b26, 0x007c, 0x92a7 }; -unsigned short __devinitdata sbus_risc_code_length01 = 0x2419; +unsigned short sbus_risc_code_length01 = 0x2419; diff --git a/trunk/drivers/scsi/raid_class.c b/trunk/drivers/scsi/raid_class.c index 86e13183c9ba..327b33a57b0a 100644 --- a/trunk/drivers/scsi/raid_class.c +++ b/trunk/drivers/scsi/raid_class.c @@ -215,19 +215,18 @@ static void raid_component_release(struct class_device *cdev) kfree(rc); } -int raid_component_add(struct raid_template *r,struct device *raid_dev, - struct device *component_dev) +void raid_component_add(struct raid_template *r,struct device *raid_dev, + struct device *component_dev) { struct class_device *cdev = attribute_container_find_class_device(&r->raid_attrs.ac, raid_dev); struct raid_component *rc; struct raid_data *rd = class_get_devdata(cdev); - int err; rc = kzalloc(sizeof(*rc), GFP_KERNEL); if (!rc) - return -ENOMEM; + return; INIT_LIST_HEAD(&rc->node); class_device_initialize(&rc->cdev); @@ -240,18 +239,7 @@ int raid_component_add(struct raid_template *r,struct device *raid_dev, list_add_tail(&rc->node, &rd->component_list); rc->cdev.parent = cdev; rc->cdev.class = &raid_class.class; - err = class_device_add(&rc->cdev); - if (err) - goto err_out; - - return 0; - -err_out: - list_del(&rc->node); - rd->component_count--; - put_device(component_dev); - kfree(rc); - return err; + class_device_add(&rc->cdev); } EXPORT_SYMBOL(raid_component_add); diff --git a/trunk/drivers/scsi/scsi.c b/trunk/drivers/scsi/scsi.c index c59f31533ab4..da95bce907dd 100644 --- a/trunk/drivers/scsi/scsi.c +++ b/trunk/drivers/scsi/scsi.c @@ -128,7 +128,7 @@ const char * scsi_device_type(unsigned type) return "Well-known LUN "; if (type == 0x1f) return "No Device "; - if (type >= ARRAY_SIZE(scsi_device_types)) + if (type > ARRAY_SIZE(scsi_device_types)) return "Unknown "; return scsi_device_types[type]; } diff --git a/trunk/drivers/scsi/scsi_debug.c b/trunk/drivers/scsi/scsi_debug.c index 30ee3d72c021..9c0f35820e3e 100644 --- a/trunk/drivers/scsi/scsi_debug.c +++ b/trunk/drivers/scsi/scsi_debug.c @@ -52,7 +52,7 @@ #include "scsi_debug.h" #define SCSI_DEBUG_VERSION "1.80" -static const char * scsi_debug_version_date = "20061018"; +static const char * scsi_debug_version_date = "20060914"; /* Additional Sense Code (ASC) used */ #define NO_ADDITIONAL_SENSE 0x0 @@ -254,8 +254,6 @@ static int resp_requests(struct scsi_cmnd * SCpnt, struct sdebug_dev_info * devip); static int resp_start_stop(struct scsi_cmnd * scp, struct sdebug_dev_info * devip); -static int resp_report_tgtpgs(struct scsi_cmnd * scp, - struct sdebug_dev_info * devip); static int resp_readcap(struct scsi_cmnd * SCpnt, struct sdebug_dev_info * devip); static int resp_readcap16(struct scsi_cmnd * SCpnt, @@ -289,9 +287,9 @@ static void __init sdebug_build_parts(unsigned char * ramp); static void __init init_all_queued(void); static void stop_all_queued(void); static int stop_queued_cmnd(struct scsi_cmnd * cmnd); -static int inquiry_evpd_83(unsigned char * arr, int port_group_id, - int target_dev_id, int dev_id_num, - const char * dev_id_str, int dev_id_str_len); +static int inquiry_evpd_83(unsigned char * arr, int target_dev_id, + int dev_id_num, const char * dev_id_str, + int dev_id_str_len); static int inquiry_evpd_88(unsigned char * arr, int target_dev_id); static int do_create_driverfs_files(void); static void do_remove_driverfs_files(void); @@ -424,15 +422,6 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done) } errsts = resp_readcap16(SCpnt, devip); break; - case MAINTENANCE_IN: - if (MI_REPORT_TARGET_PGS != cmd[1]) { - mk_sense_buffer(devip, ILLEGAL_REQUEST, - INVALID_OPCODE, 0); - errsts = check_condition_result; - break; - } - errsts = resp_report_tgtpgs(SCpnt, devip); - break; case READ_16: case READ_12: case READ_10: @@ -676,9 +665,8 @@ static const char * inq_vendor_id = "Linux "; static const char * inq_product_id = "scsi_debug "; static const char * inq_product_rev = "0004"; -static int inquiry_evpd_83(unsigned char * arr, int port_group_id, - int target_dev_id, int dev_id_num, - const char * dev_id_str, +static int inquiry_evpd_83(unsigned char * arr, int target_dev_id, + int dev_id_num, const char * dev_id_str, int dev_id_str_len) { int num, port_a; @@ -732,15 +720,6 @@ static int inquiry_evpd_83(unsigned char * arr, int port_group_id, arr[num++] = (port_a >> 16) & 0xff; arr[num++] = (port_a >> 8) & 0xff; arr[num++] = port_a & 0xff; - /* NAA-5, Target port group identifier */ - arr[num++] = 0x61; /* proto=sas, binary */ - arr[num++] = 0x95; /* piv=1, target port group id */ - arr[num++] = 0x0; - arr[num++] = 0x4; - arr[num++] = 0; - arr[num++] = 0; - arr[num++] = (port_group_id >> 8) & 0xff; - arr[num++] = port_group_id & 0xff; /* NAA-5, Target device identifier */ arr[num++] = 0x61; /* proto=sas, binary */ arr[num++] = 0xa3; /* piv=1, target device, naa */ @@ -949,12 +928,12 @@ static int resp_inquiry(struct scsi_cmnd * scp, int target, struct sdebug_dev_info * devip) { unsigned char pq_pdt; - unsigned char * arr; + unsigned char arr[SDEBUG_MAX_INQ_ARR_SZ]; unsigned char *cmd = (unsigned char *)scp->cmnd; - int alloc_len, n, ret; + int alloc_len, n; alloc_len = (cmd[3] << 8) + cmd[4]; - arr = kzalloc(SDEBUG_MAX_INQ_ARR_SZ, GFP_KERNEL); + memset(arr, 0, SDEBUG_MAX_INQ_ARR_SZ); if (devip->wlun) pq_pdt = 0x1e; /* present, wlun */ else if (scsi_debug_no_lun_0 && (0 == devip->lun)) @@ -965,15 +944,12 @@ static int resp_inquiry(struct scsi_cmnd * scp, int target, if (0x2 & cmd[1]) { /* CMDDT bit set */ mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, 0); - kfree(arr); return check_condition_result; } else if (0x1 & cmd[1]) { /* EVPD bit set */ - int lu_id_num, port_group_id, target_dev_id, len; + int lu_id_num, target_dev_id, len; char lu_id_str[6]; int host_no = devip->sdbg_host->shost->host_no; - port_group_id = (((host_no + 1) & 0x7f) << 8) + - (devip->channel & 0x7f); if (0 == scsi_debug_vpd_use_hostno) host_no = 0; lu_id_num = devip->wlun ? -1 : (((host_no + 1) * 2000) + @@ -1001,9 +977,8 @@ static int resp_inquiry(struct scsi_cmnd * scp, int target, memcpy(&arr[4], lu_id_str, len); } else if (0x83 == cmd[2]) { /* device identification */ arr[1] = cmd[2]; /*sanity */ - arr[3] = inquiry_evpd_83(&arr[4], port_group_id, - target_dev_id, lu_id_num, - lu_id_str, len); + arr[3] = inquiry_evpd_83(&arr[4], target_dev_id, + lu_id_num, lu_id_str, len); } else if (0x84 == cmd[2]) { /* Software interface ident. */ arr[1] = cmd[2]; /*sanity */ arr[3] = inquiry_evpd_84(&arr[4]); @@ -1037,22 +1012,17 @@ static int resp_inquiry(struct scsi_cmnd * scp, int target, /* Illegal request, invalid field in cdb */ mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, 0); - kfree(arr); return check_condition_result; } len = min(((arr[2] << 8) + arr[3]) + 4, alloc_len); - ret = fill_from_dev_buffer(scp, arr, + return fill_from_dev_buffer(scp, arr, min(len, SDEBUG_MAX_INQ_ARR_SZ)); - kfree(arr); - return ret; } /* drops through here for a standard inquiry */ arr[1] = DEV_REMOVEABLE(target) ? 0x80 : 0; /* Removable disk */ arr[2] = scsi_debug_scsi_level; arr[3] = 2; /* response_data_format==2 */ arr[4] = SDEBUG_LONG_INQ_SZ - 5; - if (0 == scsi_debug_vpd_use_hostno) - arr[5] = 0x10; /* claim: implicit TGPS */ arr[6] = 0x10; /* claim: MultiP */ /* arr[6] |= 0x40; ... claim: EncServ (enclosure services) */ arr[7] = 0xa; /* claim: LINKED + CMDQUE */ @@ -1069,10 +1039,8 @@ static int resp_inquiry(struct scsi_cmnd * scp, int target, arr[n++] = 0x3; arr[n++] = 0x60; /* SSC-2 no version */ } arr[n++] = 0xc; arr[n++] = 0xf; /* SAS-1.1 rev 10 */ - ret = fill_from_dev_buffer(scp, arr, + return fill_from_dev_buffer(scp, arr, min(alloc_len, SDEBUG_LONG_INQ_SZ)); - kfree(arr); - return ret; } static int resp_requests(struct scsi_cmnd * scp, @@ -1203,87 +1171,6 @@ static int resp_readcap16(struct scsi_cmnd * scp, min(alloc_len, SDEBUG_READCAP16_ARR_SZ)); } -#define SDEBUG_MAX_TGTPGS_ARR_SZ 1412 - -static int resp_report_tgtpgs(struct scsi_cmnd * scp, - struct sdebug_dev_info * devip) -{ - unsigned char *cmd = (unsigned char *)scp->cmnd; - unsigned char * arr; - int host_no = devip->sdbg_host->shost->host_no; - int n, ret, alen, rlen; - int port_group_a, port_group_b, port_a, port_b; - - alen = ((cmd[6] << 24) + (cmd[7] << 16) + (cmd[8] << 8) - + cmd[9]); - - arr = kzalloc(SDEBUG_MAX_TGTPGS_ARR_SZ, GFP_KERNEL); - /* - * EVPD page 0x88 states we have two ports, one - * real and a fake port with no device connected. - * So we create two port groups with one port each - * and set the group with port B to unavailable. - */ - port_a = 0x1; /* relative port A */ - port_b = 0x2; /* relative port B */ - port_group_a = (((host_no + 1) & 0x7f) << 8) + - (devip->channel & 0x7f); - port_group_b = (((host_no + 1) & 0x7f) << 8) + - (devip->channel & 0x7f) + 0x80; - - /* - * The asymmetric access state is cycled according to the host_id. - */ - n = 4; - if (0 == scsi_debug_vpd_use_hostno) { - arr[n++] = host_no % 3; /* Asymm access state */ - arr[n++] = 0x0F; /* claim: all states are supported */ - } else { - arr[n++] = 0x0; /* Active/Optimized path */ - arr[n++] = 0x01; /* claim: only support active/optimized paths */ - } - arr[n++] = (port_group_a >> 8) & 0xff; - arr[n++] = port_group_a & 0xff; - arr[n++] = 0; /* Reserved */ - arr[n++] = 0; /* Status code */ - arr[n++] = 0; /* Vendor unique */ - arr[n++] = 0x1; /* One port per group */ - arr[n++] = 0; /* Reserved */ - arr[n++] = 0; /* Reserved */ - arr[n++] = (port_a >> 8) & 0xff; - arr[n++] = port_a & 0xff; - arr[n++] = 3; /* Port unavailable */ - arr[n++] = 0x08; /* claim: only unavailalbe paths are supported */ - arr[n++] = (port_group_b >> 8) & 0xff; - arr[n++] = port_group_b & 0xff; - arr[n++] = 0; /* Reserved */ - arr[n++] = 0; /* Status code */ - arr[n++] = 0; /* Vendor unique */ - arr[n++] = 0x1; /* One port per group */ - arr[n++] = 0; /* Reserved */ - arr[n++] = 0; /* Reserved */ - arr[n++] = (port_b >> 8) & 0xff; - arr[n++] = port_b & 0xff; - - rlen = n - 4; - arr[0] = (rlen >> 24) & 0xff; - arr[1] = (rlen >> 16) & 0xff; - arr[2] = (rlen >> 8) & 0xff; - arr[3] = rlen & 0xff; - - /* - * Return the smallest value of either - * - The allocated length - * - The constructed command length - * - The maximum array size - */ - rlen = min(alen,n); - ret = fill_from_dev_buffer(scp, arr, - min(rlen, SDEBUG_MAX_TGTPGS_ARR_SZ)); - kfree(arr); - return ret; -} - /* <> */ static int resp_err_recov_pg(unsigned char * p, int pcontrol, int target) diff --git a/trunk/drivers/scsi/scsi_devinfo.c b/trunk/drivers/scsi/scsi_devinfo.c index ce63044b1ec8..3d0429bc14ab 100644 --- a/trunk/drivers/scsi/scsi_devinfo.c +++ b/trunk/drivers/scsi/scsi_devinfo.c @@ -150,7 +150,6 @@ static struct { {"DELL", "PERCRAID", NULL, BLIST_FORCELUN}, {"DGC", "RAID", NULL, BLIST_SPARSELUN}, /* Dell PV 650F, storage on LUN 0 */ {"DGC", "DISK", NULL, BLIST_SPARSELUN}, /* Dell PV 650F, no storage on LUN 0 */ - {"EMC", "Invista", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, {"EMC", "SYMMETRIX", NULL, BLIST_SPARSELUN | BLIST_LARGELUN | BLIST_FORCELUN}, {"EMULEX", "MD21/S2 ESDI", NULL, BLIST_SINGLELUN}, {"FSC", "CentricStor", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, @@ -162,11 +161,6 @@ static struct { {"HITACHI", "DF600", "*", BLIST_SPARSELUN}, {"HITACHI", "DISK-SUBSYSTEM", "*", BLIST_ATTACH_PQ3 | BLIST_SPARSELUN | BLIST_LARGELUN}, {"HITACHI", "OPEN-E", "*", BLIST_ATTACH_PQ3 | BLIST_SPARSELUN | BLIST_LARGELUN}, - {"HITACHI", "OP-C-", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, - {"HITACHI", "3380-", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, - {"HITACHI", "3390-", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, - {"HITACHI", "6586-", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, - {"HITACHI", "6588-", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, {"HP", "A6189A", NULL, BLIST_SPARSELUN | BLIST_LARGELUN}, /* HP VA7400 */ {"HP", "OPEN-", "*", BLIST_REPORTLUN2}, /* HP XP Arrays */ {"HP", "NetRAID-4M", NULL, BLIST_FORCELUN}, @@ -174,14 +168,6 @@ static struct { {"HP", "C1557A", NULL, BLIST_FORCELUN}, {"HP", "C3323-300", "4269", BLIST_NOTQ}, {"HP", "C5713A", NULL, BLIST_NOREPORTLUN}, - {"HP", "DF400", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, - {"HP", "DF500", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, - {"HP", "DF600", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, - {"HP", "OP-C-", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, - {"HP", "3380-", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, - {"HP", "3390-", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, - {"HP", "6586-", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, - {"HP", "6588-", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, {"IBM", "AuSaV1S2", NULL, BLIST_FORCELUN}, {"IBM", "ProFibre 4000R", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, {"IBM", "2105", NULL, BLIST_RETRY_HWERROR}, @@ -202,7 +188,6 @@ static struct { {"NAKAMICH", "MJ-4.8S", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, {"NAKAMICH", "MJ-5.16S", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, {"NEC", "PD-1 ODX654P", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, - {"NEC", "iStorage", NULL, BLIST_REPORTLUN2}, {"NRC", "MBR-7", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, {"NRC", "MBR-7.4", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, {"PIONEER", "CD-ROM DRM-600", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, @@ -225,7 +210,6 @@ static struct { {"SUN", "T300", "*", BLIST_SPARSELUN}, {"SUN", "T4", "*", BLIST_SPARSELUN}, {"TEXEL", "CD-ROM", "1.06", BLIST_BORKEN}, - {"Tornado-", "F4", "*", BLIST_NOREPORTLUN}, {"TOSHIBA", "CDROM", NULL, BLIST_ISROM}, {"TOSHIBA", "CD-ROM", NULL, BLIST_ISROM}, {"USB2.0", "SMARTMEDIA/XD", NULL, BLIST_FORCELUN | BLIST_INQUIRY_36}, diff --git a/trunk/drivers/scsi/scsi_error.c b/trunk/drivers/scsi/scsi_error.c index aff1b0cfd4b2..3d355d054612 100644 --- a/trunk/drivers/scsi/scsi_error.c +++ b/trunk/drivers/scsi/scsi_error.c @@ -495,7 +495,7 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, memcpy(scmd->cmnd, cmnd, cmnd_size); if (copy_sense) { - gfp_t gfp_mask = GFP_ATOMIC; + int gfp_mask = GFP_ATOMIC; if (shost->hostt->unchecked_isa_dma) gfp_mask |= __GFP_DMA; diff --git a/trunk/drivers/scsi/scsi_lib.c b/trunk/drivers/scsi/scsi_lib.c index 3ac4890ce086..71084728eb42 100644 --- a/trunk/drivers/scsi/scsi_lib.c +++ b/trunk/drivers/scsi/scsi_lib.c @@ -410,7 +410,6 @@ int scsi_execute_async(struct scsi_device *sdev, const unsigned char *cmd, goto free_req; req->cmd_len = cmd_len; - memset(req->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */ memcpy(req->cmd, cmd, req->cmd_len); req->sense = sioc->sense; req->sense_len = 0; @@ -427,7 +426,7 @@ int scsi_execute_async(struct scsi_device *sdev, const unsigned char *cmd, free_req: blk_put_request(req); free_sense: - kmem_cache_free(scsi_io_context_cache, sioc); + kfree(sioc); return DRIVER_ERROR << 24; } EXPORT_SYMBOL_GPL(scsi_execute_async); @@ -1085,7 +1084,7 @@ static void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd) { struct request *req = cmd->request; - BUILD_BUG_ON(sizeof(req->cmd) > sizeof(cmd->cmnd)); + BUG_ON(sizeof(req->cmd) > sizeof(cmd->cmnd)); memcpy(cmd->cmnd, req->cmd, sizeof(cmd->cmnd)); cmd->cmd_len = req->cmd_len; if (!req->data_len) diff --git a/trunk/drivers/scsi/scsi_scan.c b/trunk/drivers/scsi/scsi_scan.c index 94a274645f6f..fd9e281c3bfe 100644 --- a/trunk/drivers/scsi/scsi_scan.c +++ b/trunk/drivers/scsi/scsi_scan.c @@ -631,22 +631,12 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, * scanning run at their own risk, or supply a user level program * that can correctly scan. */ - - /* - * Copy at least 36 bytes of INQUIRY data, so that we don't - * dereference unallocated memory when accessing the Vendor, - * Product, and Revision strings. Badly behaved devices may set - * the INQUIRY Additional Length byte to a small value, indicating - * these strings are invalid, but often they contain plausible data - * nonetheless. It doesn't matter if the device sent < 36 bytes - * total, since scsi_probe_lun() initializes inq_result with 0s. - */ - sdev->inquiry = kmemdup(inq_result, - max_t(size_t, sdev->inquiry_len, 36), - GFP_ATOMIC); - if (sdev->inquiry == NULL) + sdev->inquiry = kmalloc(sdev->inquiry_len, GFP_ATOMIC); + if (sdev->inquiry == NULL) { return SCSI_SCAN_NO_RESPONSE; + } + memcpy(sdev->inquiry, inq_result, sdev->inquiry_len); sdev->vendor = (char *) (sdev->inquiry + 8); sdev->model = (char *) (sdev->inquiry + 16); sdev->rev = (char *) (sdev->inquiry + 32); diff --git a/trunk/drivers/scsi/scsi_sysfs.c b/trunk/drivers/scsi/scsi_sysfs.c index e1a91665d1c2..e7fe565b96de 100644 --- a/trunk/drivers/scsi/scsi_sysfs.c +++ b/trunk/drivers/scsi/scsi_sysfs.c @@ -192,7 +192,6 @@ static CLASS_DEVICE_ATTR(state, S_IRUGO | S_IWUSR, show_shost_state, store_shost shost_rd_attr(unique_id, "%u\n"); shost_rd_attr(host_busy, "%hu\n"); shost_rd_attr(cmd_per_lun, "%hd\n"); -shost_rd_attr(can_queue, "%hd\n"); shost_rd_attr(sg_tablesize, "%hu\n"); shost_rd_attr(unchecked_isa_dma, "%d\n"); shost_rd_attr2(proc_name, hostt->proc_name, "%s\n"); @@ -201,7 +200,6 @@ static struct class_device_attribute *scsi_sysfs_shost_attrs[] = { &class_device_attr_unique_id, &class_device_attr_host_busy, &class_device_attr_cmd_per_lun, - &class_device_attr_can_queue, &class_device_attr_sg_tablesize, &class_device_attr_unchecked_isa_dma, &class_device_attr_proc_name, diff --git a/trunk/drivers/scsi/scsi_transport_iscsi.c b/trunk/drivers/scsi/scsi_transport_iscsi.c index 9b25124a989e..7b0019cccce3 100644 --- a/trunk/drivers/scsi/scsi_transport_iscsi.c +++ b/trunk/drivers/scsi/scsi_transport_iscsi.c @@ -21,6 +21,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include +#include #include #include #include @@ -33,7 +34,7 @@ #define ISCSI_SESSION_ATTRS 11 #define ISCSI_CONN_ATTRS 11 #define ISCSI_HOST_ATTRS 0 -#define ISCSI_TRANSPORT_VERSION "2.0-724" +#define ISCSI_TRANSPORT_VERSION "2.0-685" struct iscsi_internal { int daemon_pid; @@ -148,6 +149,30 @@ static DECLARE_TRANSPORT_CLASS(iscsi_connection_class, static struct sock *nls; static DEFINE_MUTEX(rx_queue_mutex); +struct mempool_zone { + mempool_t *pool; + atomic_t allocated; + int size; + int hiwat; + struct list_head freequeue; + spinlock_t freelock; +}; + +static struct mempool_zone *z_reply; + +/* + * Z_MAX_* - actual mempool size allocated at the mempool_zone_init() time + * Z_HIWAT_* - zone's high watermark when if_error bit will be set to -ENOMEM + * so daemon will notice OOM on NETLINK tranposrt level and will + * be able to predict or change operational behavior + */ +#define Z_MAX_REPLY 8 +#define Z_HIWAT_REPLY 6 +#define Z_MAX_PDU 8 +#define Z_HIWAT_PDU 6 +#define Z_MAX_ERROR 16 +#define Z_HIWAT_ERROR 12 + static LIST_HEAD(sesslist); static DEFINE_SPINLOCK(sesslock); static LIST_HEAD(connlist); @@ -389,11 +414,59 @@ int iscsi_destroy_session(struct iscsi_cls_session *session) } EXPORT_SYMBOL_GPL(iscsi_destroy_session); +static void mempool_zone_destroy(struct mempool_zone *zp) +{ + mempool_destroy(zp->pool); + kfree(zp); +} + +static void* +mempool_zone_alloc_skb(gfp_t gfp_mask, void *pool_data) +{ + struct mempool_zone *zone = pool_data; + + return alloc_skb(zone->size, gfp_mask); +} + +static void +mempool_zone_free_skb(void *element, void *pool_data) +{ + kfree_skb(element); +} + +static struct mempool_zone * +mempool_zone_init(unsigned max, unsigned size, unsigned hiwat) +{ + struct mempool_zone *zp; + + zp = kzalloc(sizeof(*zp), GFP_KERNEL); + if (!zp) + return NULL; + + zp->size = size; + zp->hiwat = hiwat; + INIT_LIST_HEAD(&zp->freequeue); + spin_lock_init(&zp->freelock); + atomic_set(&zp->allocated, 0); + + zp->pool = mempool_create(max, mempool_zone_alloc_skb, + mempool_zone_free_skb, zp); + if (!zp->pool) { + kfree(zp); + return NULL; + } + + return zp; +} + static void iscsi_conn_release(struct device *dev) { struct iscsi_cls_conn *conn = iscsi_dev_to_conn(dev); struct device *parent = conn->dev.parent; + mempool_zone_destroy(conn->z_pdu); + mempool_zone_destroy(conn->z_error); + kfree(conn); put_device(parent); } @@ -403,6 +476,31 @@ static int iscsi_is_conn_dev(const struct device *dev) return dev->release == iscsi_conn_release; } +static int iscsi_create_event_pools(struct iscsi_cls_conn *conn) +{ + conn->z_pdu = mempool_zone_init(Z_MAX_PDU, + NLMSG_SPACE(sizeof(struct iscsi_uevent) + + sizeof(struct iscsi_hdr) + + DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH), + Z_HIWAT_PDU); + if (!conn->z_pdu) { + dev_printk(KERN_ERR, &conn->dev, "iscsi: can not allocate " + "pdu zone for new conn\n"); + return -ENOMEM; + } + + conn->z_error = mempool_zone_init(Z_MAX_ERROR, + NLMSG_SPACE(sizeof(struct iscsi_uevent)), + Z_HIWAT_ERROR); + if (!conn->z_error) { + dev_printk(KERN_ERR, &conn->dev, "iscsi: can not allocate " + "error zone for new conn\n"); + mempool_zone_destroy(conn->z_pdu); + return -ENOMEM; + } + return 0; +} + /** * iscsi_create_conn - create iscsi class connection * @session: iscsi cls session @@ -435,9 +533,12 @@ iscsi_create_conn(struct iscsi_cls_session *session, uint32_t cid) conn->transport = transport; conn->cid = cid; + if (iscsi_create_event_pools(conn)) + goto free_conn; + /* this is released in the dev's release function */ if (!get_device(&session->dev)) - goto free_conn; + goto free_conn_pools; snprintf(conn->dev.bus_id, BUS_ID_SIZE, "connection%d:%u", session->sid, cid); @@ -454,6 +555,8 @@ iscsi_create_conn(struct iscsi_cls_session *session, uint32_t cid) release_parent_ref: put_device(&session->dev); +free_conn_pools: + free_conn: kfree(conn); return NULL; @@ -496,31 +599,81 @@ iscsi_if_transport_lookup(struct iscsi_transport *tt) return NULL; } +static inline struct list_head *skb_to_lh(struct sk_buff *skb) +{ + return (struct list_head *)&skb->cb; +} + +static void +mempool_zone_complete(struct mempool_zone *zone) +{ + unsigned long flags; + struct list_head *lh, *n; + + spin_lock_irqsave(&zone->freelock, flags); + list_for_each_safe(lh, n, &zone->freequeue) { + struct sk_buff *skb = (struct sk_buff *)((char *)lh - + offsetof(struct sk_buff, cb)); + if (!skb_shared(skb)) { + list_del(skb_to_lh(skb)); + mempool_free(skb, zone->pool); + atomic_dec(&zone->allocated); + } + } + spin_unlock_irqrestore(&zone->freelock, flags); +} + +static struct sk_buff* +mempool_zone_get_skb(struct mempool_zone *zone) +{ + struct sk_buff *skb; + + skb = mempool_alloc(zone->pool, GFP_ATOMIC); + if (skb) + atomic_inc(&zone->allocated); + return skb; +} + static int -iscsi_broadcast_skb(struct sk_buff *skb, gfp_t gfp) +iscsi_broadcast_skb(struct mempool_zone *zone, struct sk_buff *skb, gfp_t gfp) { + unsigned long flags; int rc; + skb_get(skb); rc = netlink_broadcast(nls, skb, 0, 1, gfp); if (rc < 0) { + mempool_free(skb, zone->pool); printk(KERN_ERR "iscsi: can not broadcast skb (%d)\n", rc); return rc; } + spin_lock_irqsave(&zone->freelock, flags); + INIT_LIST_HEAD(skb_to_lh(skb)); + list_add(skb_to_lh(skb), &zone->freequeue); + spin_unlock_irqrestore(&zone->freelock, flags); return 0; } static int -iscsi_unicast_skb(struct sk_buff *skb, int pid) +iscsi_unicast_skb(struct mempool_zone *zone, struct sk_buff *skb, int pid) { + unsigned long flags; int rc; + skb_get(skb); rc = netlink_unicast(nls, skb, pid, MSG_DONTWAIT); if (rc < 0) { + mempool_free(skb, zone->pool); printk(KERN_ERR "iscsi: can not unicast skb (%d)\n", rc); return rc; } + spin_lock_irqsave(&zone->freelock, flags); + INIT_LIST_HEAD(skb_to_lh(skb)); + list_add(skb_to_lh(skb), &zone->freequeue); + spin_unlock_irqrestore(&zone->freelock, flags); + return 0; } @@ -539,7 +692,9 @@ int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr, if (!priv) return -EINVAL; - skb = alloc_skb(len, GFP_ATOMIC); + mempool_zone_complete(conn->z_pdu); + + skb = mempool_zone_get_skb(conn->z_pdu); if (!skb) { iscsi_conn_error(conn, ISCSI_ERR_CONN_FAILED); dev_printk(KERN_ERR, &conn->dev, "iscsi: can not deliver " @@ -552,13 +707,15 @@ int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr, memset(ev, 0, sizeof(*ev)); ev->transport_handle = iscsi_handle(conn->transport); ev->type = ISCSI_KEVENT_RECV_PDU; + if (atomic_read(&conn->z_pdu->allocated) >= conn->z_pdu->hiwat) + ev->iferror = -ENOMEM; ev->r.recv_req.cid = conn->cid; ev->r.recv_req.sid = iscsi_conn_get_sid(conn); pdu = (char*)ev + sizeof(*ev); memcpy(pdu, hdr, sizeof(struct iscsi_hdr)); memcpy(pdu + sizeof(struct iscsi_hdr), data, data_size); - return iscsi_unicast_skb(skb, priv->daemon_pid); + return iscsi_unicast_skb(conn->z_pdu, skb, priv->daemon_pid); } EXPORT_SYMBOL_GPL(iscsi_recv_pdu); @@ -574,7 +731,9 @@ void iscsi_conn_error(struct iscsi_cls_conn *conn, enum iscsi_err error) if (!priv) return; - skb = alloc_skb(len, GFP_ATOMIC); + mempool_zone_complete(conn->z_error); + + skb = mempool_zone_get_skb(conn->z_error); if (!skb) { dev_printk(KERN_ERR, &conn->dev, "iscsi: gracefully ignored " "conn error (%d)\n", error); @@ -585,11 +744,13 @@ void iscsi_conn_error(struct iscsi_cls_conn *conn, enum iscsi_err error) ev = NLMSG_DATA(nlh); ev->transport_handle = iscsi_handle(conn->transport); ev->type = ISCSI_KEVENT_CONN_ERROR; + if (atomic_read(&conn->z_error->allocated) >= conn->z_error->hiwat) + ev->iferror = -ENOMEM; ev->r.connerror.error = error; ev->r.connerror.cid = conn->cid; ev->r.connerror.sid = iscsi_conn_get_sid(conn); - iscsi_broadcast_skb(skb, GFP_ATOMIC); + iscsi_broadcast_skb(conn->z_error, skb, GFP_ATOMIC); dev_printk(KERN_INFO, &conn->dev, "iscsi: detected conn error (%d)\n", error); @@ -606,7 +767,9 @@ iscsi_if_send_reply(int pid, int seq, int type, int done, int multi, int flags = multi ? NLM_F_MULTI : 0; int t = done ? NLMSG_DONE : type; - skb = alloc_skb(len, GFP_ATOMIC); + mempool_zone_complete(z_reply); + + skb = mempool_zone_get_skb(z_reply); /* * FIXME: * user is supposed to react on iferror == -ENOMEM; @@ -617,7 +780,7 @@ iscsi_if_send_reply(int pid, int seq, int type, int done, int multi, nlh = __nlmsg_put(skb, pid, seq, t, (len - sizeof(*nlh)), 0); nlh->nlmsg_flags = flags; memcpy(NLMSG_DATA(nlh), payload, size); - return iscsi_unicast_skb(skb, pid); + return iscsi_unicast_skb(z_reply, skb, pid); } static int @@ -647,7 +810,9 @@ iscsi_if_get_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh) do { int actual_size; - skbstat = alloc_skb(len, GFP_ATOMIC); + mempool_zone_complete(conn->z_pdu); + + skbstat = mempool_zone_get_skb(conn->z_pdu); if (!skbstat) { dev_printk(KERN_ERR, &conn->dev, "iscsi: can not " "deliver stats: OOM\n"); @@ -660,6 +825,8 @@ iscsi_if_get_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh) memset(evstat, 0, sizeof(*evstat)); evstat->transport_handle = iscsi_handle(conn->transport); evstat->type = nlh->nlmsg_type; + if (atomic_read(&conn->z_pdu->allocated) >= conn->z_pdu->hiwat) + evstat->iferror = -ENOMEM; evstat->u.get_stats.cid = ev->u.get_stats.cid; evstat->u.get_stats.sid = @@ -678,7 +845,7 @@ iscsi_if_get_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh) skb_trim(skbstat, NLMSG_ALIGN(actual_size)); nlhstat->nlmsg_len = actual_size; - err = iscsi_unicast_skb(skbstat, priv->daemon_pid); + err = iscsi_unicast_skb(conn->z_pdu, skbstat, priv->daemon_pid); } while (err < 0 && err != -ECONNREFUSED); return err; @@ -709,7 +876,9 @@ int iscsi_if_destroy_session_done(struct iscsi_cls_conn *conn) session = iscsi_dev_to_session(conn->dev.parent); shost = iscsi_session_to_shost(session); - skb = alloc_skb(len, GFP_KERNEL); + mempool_zone_complete(conn->z_pdu); + + skb = mempool_zone_get_skb(conn->z_pdu); if (!skb) { dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of " "session creation event\n"); @@ -727,7 +896,7 @@ int iscsi_if_destroy_session_done(struct iscsi_cls_conn *conn) * this will occur if the daemon is not up, so we just warn * the user and when the daemon is restarted it will handle it */ - rc = iscsi_broadcast_skb(skb, GFP_KERNEL); + rc = iscsi_broadcast_skb(conn->z_pdu, skb, GFP_KERNEL); if (rc < 0) dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of " "session destruction event. Check iscsi daemon\n"); @@ -770,7 +939,9 @@ int iscsi_if_create_session_done(struct iscsi_cls_conn *conn) session = iscsi_dev_to_session(conn->dev.parent); shost = iscsi_session_to_shost(session); - skb = alloc_skb(len, GFP_KERNEL); + mempool_zone_complete(conn->z_pdu); + + skb = mempool_zone_get_skb(conn->z_pdu); if (!skb) { dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of " "session creation event\n"); @@ -788,7 +959,7 @@ int iscsi_if_create_session_done(struct iscsi_cls_conn *conn) * this will occur if the daemon is not up, so we just warn * the user and when the daemon is restarted it will handle it */ - rc = iscsi_broadcast_skb(skb, GFP_KERNEL); + rc = iscsi_broadcast_skb(conn->z_pdu, skb, GFP_KERNEL); if (rc < 0) dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of " "session creation event. Check iscsi daemon\n"); @@ -1107,6 +1278,9 @@ iscsi_if_rx(struct sock *sk, int len) err = iscsi_if_send_reply( NETLINK_CREDS(skb)->pid, nlh->nlmsg_seq, nlh->nlmsg_type, 0, 0, ev, sizeof(*ev)); + if (atomic_read(&z_reply->allocated) >= + z_reply->hiwat) + ev->iferror = -ENOMEM; } while (err < 0 && err != -ECONNREFUSED); skb_pull(skb, rlen); } @@ -1410,6 +1584,32 @@ int iscsi_unregister_transport(struct iscsi_transport *tt) } EXPORT_SYMBOL_GPL(iscsi_unregister_transport); +static int +iscsi_rcv_nl_event(struct notifier_block *this, unsigned long event, void *ptr) +{ + struct netlink_notify *n = ptr; + + if (event == NETLINK_URELEASE && + n->protocol == NETLINK_ISCSI && n->pid) { + struct iscsi_cls_conn *conn; + unsigned long flags; + + mempool_zone_complete(z_reply); + spin_lock_irqsave(&connlock, flags); + list_for_each_entry(conn, &connlist, conn_list) { + mempool_zone_complete(conn->z_error); + mempool_zone_complete(conn->z_pdu); + } + spin_unlock_irqrestore(&connlock, flags); + } + + return NOTIFY_DONE; +} + +static struct notifier_block iscsi_nl_notifier = { + .notifier_call = iscsi_rcv_nl_event, +}; + static __init int iscsi_transport_init(void) { int err; @@ -1433,15 +1633,25 @@ static __init int iscsi_transport_init(void) if (err) goto unregister_conn_class; + err = netlink_register_notifier(&iscsi_nl_notifier); + if (err) + goto unregister_session_class; + nls = netlink_kernel_create(NETLINK_ISCSI, 1, iscsi_if_rx, THIS_MODULE); if (!nls) { err = -ENOBUFS; - goto unregister_session_class; + goto unregister_notifier; } - return 0; + z_reply = mempool_zone_init(Z_MAX_REPLY, + NLMSG_SPACE(sizeof(struct iscsi_uevent)), Z_HIWAT_REPLY); + if (z_reply) + return 0; + sock_release(nls->sk_socket); +unregister_notifier: + netlink_unregister_notifier(&iscsi_nl_notifier); unregister_session_class: transport_class_unregister(&iscsi_session_class); unregister_conn_class: @@ -1455,7 +1665,9 @@ static __init int iscsi_transport_init(void) static void __exit iscsi_transport_exit(void) { + mempool_zone_destroy(z_reply); sock_release(nls->sk_socket); + netlink_unregister_notifier(&iscsi_nl_notifier); transport_class_unregister(&iscsi_connection_class); transport_class_unregister(&iscsi_session_class); transport_class_unregister(&iscsi_host_class); diff --git a/trunk/drivers/scsi/sd.c b/trunk/drivers/scsi/sd.c index 84ff203ffedd..10bc99c911fa 100644 --- a/trunk/drivers/scsi/sd.c +++ b/trunk/drivers/scsi/sd.c @@ -1794,7 +1794,7 @@ static void sd_shutdown(struct device *dev) **/ static int __init init_sd(void) { - int majors = 0, i, err; + int majors = 0, i; SCSI_LOG_HLQUEUE(3, printk("init_sd: sd driver entry point\n")); @@ -1805,22 +1805,9 @@ static int __init init_sd(void) if (!majors) return -ENODEV; - err = class_register(&sd_disk_class); - if (err) - goto err_out; + class_register(&sd_disk_class); - err = scsi_register_driver(&sd_template.gendrv); - if (err) - goto err_out_class; - - return 0; - -err_out_class: - class_unregister(&sd_disk_class); -err_out: - for (i = 0; i < SD_MAJORS; i++) - unregister_blkdev(sd_major(i), "sd"); - return err; + return scsi_register_driver(&sd_template.gendrv); } /** @@ -1835,10 +1822,10 @@ static void __exit exit_sd(void) SCSI_LOG_HLQUEUE(3, printk("exit_sd: exiting sd driver\n")); scsi_unregister_driver(&sd_template.gendrv); - class_unregister(&sd_disk_class); - for (i = 0; i < SD_MAJORS; i++) unregister_blkdev(sd_major(i), "sd"); + + class_unregister(&sd_disk_class); } module_init(init_sd); diff --git a/trunk/drivers/scsi/seagate.c b/trunk/drivers/scsi/seagate.c index 5ffec2721b28..2679ea8bff1a 100644 --- a/trunk/drivers/scsi/seagate.c +++ b/trunk/drivers/scsi/seagate.c @@ -94,21 +94,21 @@ #include #include #include +#include #include #include #include -#include +#include #include #include -#include -#include -#include - +#include "scsi.h" #include #include +#include "seagate.h" +#include #ifdef DEBUG #define DPRINTK( when, msg... ) do { if ( (DEBUG & (when)) == (when) ) printk( msg ); } while (0) @@ -320,9 +320,8 @@ static Signature __initdata signatures[] = { */ static int hostno = -1; -static void seagate_reconnect_intr (int, void *); -static irqreturn_t do_seagate_reconnect_intr (int, void *); -static int seagate_st0x_bus_reset(struct scsi_cmnd *); +static void seagate_reconnect_intr (int, void *, struct pt_regs *); +static irqreturn_t do_seagate_reconnect_intr (int, void *, struct pt_regs *); #ifdef FAST static int fast = 1; @@ -586,8 +585,8 @@ static int linked_connected = 0; static unsigned char linked_target, linked_lun; #endif -static void (*done_fn) (struct scsi_cmnd *) = NULL; -static struct scsi_cmnd *SCint = NULL; +static void (*done_fn) (Scsi_Cmnd *) = NULL; +static Scsi_Cmnd *SCint = NULL; /* * These control whether or not disconnect / reconnect will be attempted, @@ -619,21 +618,22 @@ static int should_reconnect = 0; * asserting SEL. */ -static irqreturn_t do_seagate_reconnect_intr(int irq, void *dev_id) +static irqreturn_t do_seagate_reconnect_intr(int irq, void *dev_id, + struct pt_regs *regs) { unsigned long flags; struct Scsi_Host *dev = dev_id; spin_lock_irqsave (dev->host_lock, flags); - seagate_reconnect_intr (irq, dev_id); + seagate_reconnect_intr (irq, dev_id, regs); spin_unlock_irqrestore (dev->host_lock, flags); return IRQ_HANDLED; } -static void seagate_reconnect_intr (int irq, void *dev_id) +static void seagate_reconnect_intr (int irq, void *dev_id, struct pt_regs *regs) { int temp; - struct scsi_cmnd *SCtmp; + Scsi_Cmnd *SCtmp; DPRINTK (PHASE_RESELECT, "scsi%d : seagate_reconnect_intr() called\n", hostno); @@ -675,11 +675,10 @@ static void seagate_reconnect_intr (int irq, void *dev_id) static int recursion_depth = 0; -static int seagate_st0x_queue_command(struct scsi_cmnd * SCpnt, - void (*done) (struct scsi_cmnd *)) +static int seagate_st0x_queue_command (Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *)) { int result, reconnect; - struct scsi_cmnd *SCtmp; + Scsi_Cmnd *SCtmp; DANY ("seagate: que_command"); done_fn = done; @@ -1610,7 +1609,7 @@ static int internal_command (unsigned char target, unsigned char lun, return retcode (st0x_aborted); } /* end of internal_command */ -static int seagate_st0x_abort(struct scsi_cmnd * SCpnt) +static int seagate_st0x_abort (Scsi_Cmnd * SCpnt) { st0x_aborted = DID_ABORT; return SUCCESS; @@ -1625,7 +1624,7 @@ static int seagate_st0x_abort(struct scsi_cmnd * SCpnt) * May be called with SCpnt = NULL */ -static int seagate_st0x_bus_reset(struct scsi_cmnd * SCpnt) +static int seagate_st0x_bus_reset(Scsi_Cmnd * SCpnt) { /* No timeouts - this command is going to fail because it was reset. */ DANY ("scsi%d: Reseting bus... ", hostno); diff --git a/trunk/drivers/scsi/seagate.h b/trunk/drivers/scsi/seagate.h new file mode 100644 index 000000000000..fb5f380fa4b3 --- /dev/null +++ b/trunk/drivers/scsi/seagate.h @@ -0,0 +1,19 @@ +/* + * seagate.h Copyright (C) 1992 Drew Eckhardt + * low level scsi driver header for ST01/ST02 by + * Drew Eckhardt + * + * + */ + +#ifndef _SEAGATE_H +#define SEAGATE_H + +static int seagate_st0x_detect(struct scsi_host_template *); +static int seagate_st0x_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); + +static int seagate_st0x_abort(Scsi_Cmnd *); +static const char *seagate_st0x_info(struct Scsi_Host *); +static int seagate_st0x_bus_reset(Scsi_Cmnd *); + +#endif /* _SEAGATE_H */ diff --git a/trunk/drivers/scsi/sg.c b/trunk/drivers/scsi/sg.c index 81e3bc7b02a1..34f9343ed0af 100644 --- a/trunk/drivers/scsi/sg.c +++ b/trunk/drivers/scsi/sg.c @@ -60,7 +60,7 @@ static int sg_version_num = 30534; /* 2 digits for each component */ #ifdef CONFIG_SCSI_PROC_FS #include -static char *sg_version_date = "20061027"; +static char *sg_version_date = "20060818"; static int sg_proc_init(void); static void sg_proc_cleanup(void); @@ -94,9 +94,6 @@ int sg_big_buff = SG_DEF_RESERVED_SIZE; static int def_reserved_size = -1; /* picks up init parameter */ static int sg_allow_dio = SG_ALLOW_DIO_DEF; -static int scatter_elem_sz = SG_SCATTER_SZ; -static int scatter_elem_sz_prev = SG_SCATTER_SZ; - #define SG_SECTOR_SZ 512 #define SG_SECTOR_MSK (SG_SECTOR_SZ - 1) @@ -710,12 +707,12 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp, (int) cmnd[0], (int) hp->cmd_len)); if ((k = sg_start_req(srp))) { - SCSI_LOG_TIMEOUT(1, printk("sg_common_write: start_req err=%d\n", k)); + SCSI_LOG_TIMEOUT(1, printk("sg_write: start_req err=%d\n", k)); sg_finish_rem_req(srp); return k; /* probably out of space --> ENOMEM */ } if ((k = sg_write_xfer(srp))) { - SCSI_LOG_TIMEOUT(1, printk("sg_common_write: write_xfer, bad address\n")); + SCSI_LOG_TIMEOUT(1, printk("sg_write: write_xfer, bad address\n")); sg_finish_rem_req(srp); return k; } @@ -746,7 +743,7 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp, hp->dxfer_len, srp->data.k_use_sg, timeout, SG_DEFAULT_RETRIES, srp, sg_cmd_done, GFP_ATOMIC)) { - SCSI_LOG_TIMEOUT(1, printk("sg_common_write: scsi_execute_async failed\n")); + SCSI_LOG_TIMEOUT(1, printk("sg_write: scsi_execute_async failed\n")); /* * most likely out of mem, but could also be a bad map */ @@ -1283,7 +1280,7 @@ sg_cmd_done(void *data, char *sense, int result, int resid) sg_finish_rem_req(srp); srp = NULL; if (NULL == sfp->headrp) { - SCSI_LOG_TIMEOUT(1, printk("sg_cmd_done: already closed, final cleanup\n")); + SCSI_LOG_TIMEOUT(1, printk("sg...bh: already closed, final cleanup\n")); if (0 == sg_remove_sfp(sdp, sfp)) { /* device still present */ scsi_device_put(sdp->device); } @@ -1512,12 +1509,12 @@ sg_remove(struct class_device *cl_dev, struct class_interface *cl_intf) POLL_HUP); } } - SCSI_LOG_TIMEOUT(3, printk("sg_remove: dev=%d, dirty\n", k)); + SCSI_LOG_TIMEOUT(3, printk("sg_detach: dev=%d, dirty\n", k)); if (NULL == sdp->headfp) { sg_dev_arr[k] = NULL; } } else { /* nothing active, simple case */ - SCSI_LOG_TIMEOUT(3, printk("sg_remove: dev=%d\n", k)); + SCSI_LOG_TIMEOUT(3, printk("sg_detach: dev=%d\n", k)); sg_dev_arr[k] = NULL; } sg_nr_dev--; @@ -1540,9 +1537,11 @@ sg_remove(struct class_device *cl_dev, struct class_interface *cl_intf) msleep(10); /* dirty detach so delay device destruction */ } -module_param_named(scatter_elem_sz, scatter_elem_sz, int, S_IRUGO | S_IWUSR); -module_param_named(def_reserved_size, def_reserved_size, int, - S_IRUGO | S_IWUSR); +/* Set 'perm' (4th argument) to 0 to disable module_param's definition + * of sysfs parameters (which module_param doesn't yet support). + * Sysfs parameters defined explicitly below. + */ +module_param_named(def_reserved_size, def_reserved_size, int, S_IRUGO); module_param_named(allow_dio, sg_allow_dio, int, S_IRUGO | S_IWUSR); MODULE_AUTHOR("Douglas Gilbert"); @@ -1551,8 +1550,6 @@ MODULE_LICENSE("GPL"); MODULE_VERSION(SG_VERSION_STR); MODULE_ALIAS_CHARDEV_MAJOR(SCSI_GENERIC_MAJOR); -MODULE_PARM_DESC(scatter_elem_sz, "scatter gather element " - "size (default: max(SG_SCATTER_SZ, PAGE_SIZE))"); MODULE_PARM_DESC(def_reserved_size, "size of buffer reserved for each fd"); MODULE_PARM_DESC(allow_dio, "allow direct I/O (default: 0 (disallow))"); @@ -1561,14 +1558,8 @@ init_sg(void) { int rc; - if (scatter_elem_sz < PAGE_SIZE) { - scatter_elem_sz = PAGE_SIZE; - scatter_elem_sz_prev = scatter_elem_sz; - } if (def_reserved_size >= 0) sg_big_buff = def_reserved_size; - else - def_reserved_size = sg_big_buff; rc = register_chrdev_region(MKDEV(SCSI_GENERIC_MAJOR, 0), SG_MAX_DEVS, "sg"); @@ -1851,40 +1842,24 @@ sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size) if (mx_sc_elems < 0) return mx_sc_elems; /* most likely -ENOMEM */ - num = scatter_elem_sz; - if (unlikely(num != scatter_elem_sz_prev)) { - if (num < PAGE_SIZE) { - scatter_elem_sz = PAGE_SIZE; - scatter_elem_sz_prev = PAGE_SIZE; - } else - scatter_elem_sz_prev = num; - } for (k = 0, sg = schp->buffer, rem_sz = blk_size; (rem_sz > 0) && (k < mx_sc_elems); ++k, rem_sz -= ret_sz, ++sg) { - num = (rem_sz > scatter_elem_sz_prev) ? - scatter_elem_sz_prev : rem_sz; + num = (rem_sz > SG_SCATTER_SZ) ? SG_SCATTER_SZ : rem_sz; p = sg_page_malloc(num, sfp->low_dma, &ret_sz); if (!p) return -ENOMEM; - if (num == scatter_elem_sz_prev) { - if (unlikely(ret_sz > scatter_elem_sz_prev)) { - scatter_elem_sz = ret_sz; - scatter_elem_sz_prev = ret_sz; - } - } sg->page = p; - sg->length = (ret_sz > num) ? num : ret_sz; + sg->length = ret_sz; - SCSI_LOG_TIMEOUT(5, printk("sg_build_indirect: k=%d, num=%d, " - "ret_sz=%d\n", k, num, ret_sz)); + SCSI_LOG_TIMEOUT(5, printk("sg_build_build: k=%d, a=0x%p, len=%d\n", + k, p, ret_sz)); } /* end of for loop */ schp->k_use_sg = k; - SCSI_LOG_TIMEOUT(5, printk("sg_build_indirect: k_use_sg=%d, " - "rem_sz=%d\n", k, rem_sz)); + SCSI_LOG_TIMEOUT(5, printk("sg_build_indirect: k_use_sg=%d, rem_sz=%d\n", k, rem_sz)); schp->bufflen = blk_size; if (rem_sz > 0) /* must have failed */ @@ -2015,7 +1990,7 @@ sg_remove_scat(Sg_scatter_hold * schp) for (k = 0; (k < schp->k_use_sg) && sg->page; ++k, ++sg) { SCSI_LOG_TIMEOUT(5, printk( - "sg_remove_scat: k=%d, pg=0x%p, len=%d\n", + "sg_remove_scat: k=%d, a=0x%p, len=%d\n", k, sg->page, sg->length)); sg_page_free(sg->page, sg->length); } @@ -2366,9 +2341,6 @@ sg_add_sfp(Sg_device * sdp, int dev) } write_unlock_irqrestore(&sg_dev_arr_lock, iflags); SCSI_LOG_TIMEOUT(3, printk("sg_add_sfp: sfp=0x%p\n", sfp)); - if (unlikely(sg_big_buff != def_reserved_size)) - sg_big_buff = def_reserved_size; - sg_build_reserve(sfp, sg_big_buff); SCSI_LOG_TIMEOUT(3, printk("sg_add_sfp: bufflen=%d, k_use_sg=%d\n", sfp->reserve.bufflen, sfp->reserve.k_use_sg)); @@ -2465,16 +2437,16 @@ sg_res_in_use(Sg_fd * sfp) return srp ? 1 : 0; } -/* The size fetched (value output via retSzp) set when non-NULL return */ +/* If retSzp==NULL want exact size or fail */ static struct page * sg_page_malloc(int rqSz, int lowDma, int *retSzp) { struct page *resp = NULL; gfp_t page_mask; int order, a_size; - int resSz; + int resSz = rqSz; - if ((rqSz <= 0) || (NULL == retSzp)) + if (rqSz <= 0) return resp; if (lowDma) @@ -2484,9 +2456,8 @@ sg_page_malloc(int rqSz, int lowDma, int *retSzp) for (order = 0, a_size = PAGE_SIZE; a_size < rqSz; order++, a_size <<= 1) ; - resSz = a_size; /* rounded up if necessary */ resp = alloc_pages(page_mask, order); - while ((!resp) && order) { + while ((!resp) && order && retSzp) { --order; a_size >>= 1; /* divide by 2, until PAGE_SIZE */ resp = alloc_pages(page_mask, order); /* try half */ @@ -2495,7 +2466,8 @@ sg_page_malloc(int rqSz, int lowDma, int *retSzp) if (resp) { if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) memset(page_address(resp), 0, resSz); - *retSzp = resSz; + if (retSzp) + *retSzp = resSz; } return resp; } diff --git a/trunk/drivers/scsi/sgiwd93.c b/trunk/drivers/scsi/sgiwd93.c index e81f97a35bc8..4f1db6f2aae8 100644 --- a/trunk/drivers/scsi/sgiwd93.c +++ b/trunk/drivers/scsi/sgiwd93.c @@ -84,7 +84,7 @@ static inline unsigned long read_wd33c93_count(const wd33c93_regs regs) return value; } -static irqreturn_t sgiwd93_intr(int irq, void *dev_id) +static irqreturn_t sgiwd93_intr(int irq, void *dev_id, struct pt_regs *regs) { struct Scsi_Host * host = (struct Scsi_Host *) dev_id; unsigned long flags; diff --git a/trunk/drivers/scsi/st.c b/trunk/drivers/scsi/st.c index e1a52c525ed4..7f669b600677 100644 --- a/trunk/drivers/scsi/st.c +++ b/trunk/drivers/scsi/st.c @@ -195,9 +195,9 @@ static int sgl_unmap_user_pages(struct scatterlist *, const unsigned int, int); static int st_probe(struct device *); static int st_remove(struct device *); -static int do_create_driverfs_files(void); +static void do_create_driverfs_files(void); static void do_remove_driverfs_files(void); -static int do_create_class_files(struct scsi_tape *, int, int); +static void do_create_class_files(struct scsi_tape *, int, int); static struct scsi_driver st_template = { .owner = THIS_MODULE, @@ -1177,10 +1177,7 @@ static int st_open(struct inode *inode, struct file *filp) goto err_out; if ((filp->f_flags & O_NONBLOCK) == 0 && retval != CHKRES_READY) { - if (STp->ready == NO_TAPE) - retval = (-ENOMEDIUM); - else - retval = (-EIO); + retval = (-EIO); goto err_out; } return 0; @@ -4051,9 +4048,7 @@ static int st_probe(struct device *dev) STm->cdevs[j] = cdev; } - error = do_create_class_files(tpnt, dev_num, mode); - if (error) - goto out_free_tape; + do_create_class_files(tpnt, dev_num, mode); } sdev_printk(KERN_WARNING, SDp, @@ -4162,45 +4157,32 @@ static void scsi_tape_release(struct kref *kref) static int __init init_st(void) { - int err; - validate_options(); - printk(KERN_INFO "st: Version %s, fixed bufsize %d, s/g segs %d\n", + printk(KERN_INFO + "st: Version %s, fixed bufsize %d, s/g segs %d\n", verstr, st_fixed_buffer_size, st_max_sg_segs); st_sysfs_class = class_create(THIS_MODULE, "scsi_tape"); if (IS_ERR(st_sysfs_class)) { + st_sysfs_class = NULL; printk(KERN_ERR "Unable create sysfs class for SCSI tapes\n"); - return PTR_ERR(st_sysfs_class); + return 1; } - err = register_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0), - ST_MAX_TAPE_ENTRIES, "st"); - if (err) { - printk(KERN_ERR "Unable to get major %d for SCSI tapes\n", - SCSI_TAPE_MAJOR); - goto err_class; + if (!register_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0), + ST_MAX_TAPE_ENTRIES, "st")) { + if (scsi_register_driver(&st_template.gendrv) == 0) { + do_create_driverfs_files(); + return 0; + } + unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0), + ST_MAX_TAPE_ENTRIES); } - - err = scsi_register_driver(&st_template.gendrv); - if (err) - goto err_chrdev; - - err = do_create_driverfs_files(); - if (err) - goto err_scsidrv; - - return 0; - -err_scsidrv: - scsi_unregister_driver(&st_template.gendrv); -err_chrdev: - unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0), - ST_MAX_TAPE_ENTRIES); -err_class: class_destroy(st_sysfs_class); - return err; + + printk(KERN_ERR "Unable to get major %d for SCSI tapes\n", SCSI_TAPE_MAJOR); + return 1; } static void __exit exit_st(void) @@ -4243,33 +4225,14 @@ static ssize_t st_version_show(struct device_driver *ddd, char *buf) } static DRIVER_ATTR(version, S_IRUGO, st_version_show, NULL); -static int do_create_driverfs_files(void) +static void do_create_driverfs_files(void) { struct device_driver *driverfs = &st_template.gendrv; - int err; - - err = driver_create_file(driverfs, &driver_attr_try_direct_io); - if (err) - return err; - err = driver_create_file(driverfs, &driver_attr_fixed_buffer_size); - if (err) - goto err_try_direct_io; - err = driver_create_file(driverfs, &driver_attr_max_sg_segs); - if (err) - goto err_attr_fixed_buf; - err = driver_create_file(driverfs, &driver_attr_version); - if (err) - goto err_attr_max_sg; - - return 0; -err_attr_max_sg: - driver_remove_file(driverfs, &driver_attr_max_sg_segs); -err_attr_fixed_buf: - driver_remove_file(driverfs, &driver_attr_fixed_buffer_size); -err_try_direct_io: - driver_remove_file(driverfs, &driver_attr_try_direct_io); - return err; + driver_create_file(driverfs, &driver_attr_try_direct_io); + driver_create_file(driverfs, &driver_attr_fixed_buffer_size); + driver_create_file(driverfs, &driver_attr_max_sg_segs); + driver_create_file(driverfs, &driver_attr_version); } static void do_remove_driverfs_files(void) @@ -4330,12 +4293,15 @@ static ssize_t st_defcompression_show(struct class_device *class_dev, char *buf) CLASS_DEVICE_ATTR(default_compression, S_IRUGO, st_defcompression_show, NULL); -static int do_create_class_files(struct scsi_tape *STp, int dev_num, int mode) +static void do_create_class_files(struct scsi_tape *STp, int dev_num, int mode) { int i, rew, error; char name[10]; struct class_device *st_class_member; + if (!st_sysfs_class) + return; + for (rew=0; rew < 2; rew++) { /* Make sure that the minor numbers corresponding to the four first modes always get the same names */ @@ -4350,24 +4316,18 @@ static int do_create_class_files(struct scsi_tape *STp, int dev_num, int mode) if (IS_ERR(st_class_member)) { printk(KERN_WARNING "st%d: class_device_create failed\n", dev_num); - error = PTR_ERR(st_class_member); goto out; } class_set_devdata(st_class_member, &STp->modes[mode]); - error = class_device_create_file(st_class_member, - &class_device_attr_defined); - if (error) goto out; - error = class_device_create_file(st_class_member, - &class_device_attr_default_blksize); - if (error) goto out; - error = class_device_create_file(st_class_member, - &class_device_attr_default_density); - if (error) goto out; - error = class_device_create_file(st_class_member, - &class_device_attr_default_compression); - if (error) goto out; - + class_device_create_file(st_class_member, + &class_device_attr_defined); + class_device_create_file(st_class_member, + &class_device_attr_default_blksize); + class_device_create_file(st_class_member, + &class_device_attr_default_density); + class_device_create_file(st_class_member, + &class_device_attr_default_compression); if (mode == 0 && rew == 0) { error = sysfs_create_link(&STp->device->sdev_gendev.kobj, &st_class_member->kobj, @@ -4376,15 +4336,11 @@ static int do_create_class_files(struct scsi_tape *STp, int dev_num, int mode) printk(KERN_ERR "st%d: Can't create sysfs link from SCSI device.\n", dev_num); - goto out; } } } - - return 0; - -out: - return error; + out: + return; } /* The following functions may be useful for a larger audience. */ diff --git a/trunk/drivers/scsi/stex.c b/trunk/drivers/scsi/stex.c index 185c270bb043..3cf3106a29b8 100644 --- a/trunk/drivers/scsi/stex.c +++ b/trunk/drivers/scsi/stex.c @@ -11,7 +11,7 @@ * Written By: * Ed Lin * - * Version: 3.0.0.1 + * Version: 2.9.0.13 * */ @@ -37,11 +37,11 @@ #include #define DRV_NAME "stex" -#define ST_DRIVER_VERSION "3.0.0.1" -#define ST_VER_MAJOR 3 -#define ST_VER_MINOR 0 +#define ST_DRIVER_VERSION "2.9.0.13" +#define ST_VER_MAJOR 2 +#define ST_VER_MINOR 9 #define ST_OEM 0 -#define ST_BUILD_VER 1 +#define ST_BUILD_VER 13 enum { /* MU register offset */ @@ -120,18 +120,12 @@ enum { st_shasta = 0, st_vsc = 1, - st_yosemite = 2, PASSTHRU_REQ_TYPE = 0x00000001, PASSTHRU_REQ_NO_WAKEUP = 0x00000100, ST_INTERNAL_TIMEOUT = 30, - ST_TO_CMD = 0, - ST_FROM_CMD = 1, - /* vendor specific commands of Promise */ - MGT_CMD = 0xd8, - SINBAND_MGT_CMD = 0xd9, ARRAY_CMD = 0xe0, CONTROLLER_CMD = 0xe1, DEBUGGING_CMD = 0xe2, @@ -139,48 +133,14 @@ enum { PASSTHRU_GET_ADAPTER = 0x05, PASSTHRU_GET_DRVVER = 0x10, - - CTLR_CONFIG_CMD = 0x03, - CTLR_SHUTDOWN = 0x0d, - CTLR_POWER_STATE_CHANGE = 0x0e, CTLR_POWER_SAVING = 0x01, PASSTHRU_SIGNATURE = 0x4e415041, - MGT_CMD_SIGNATURE = 0xba, INQUIRY_EVPD = 0x01, }; -/* SCSI inquiry data */ -typedef struct st_inq { - u8 DeviceType :5; - u8 DeviceTypeQualifier :3; - u8 DeviceTypeModifier :7; - u8 RemovableMedia :1; - u8 Versions; - u8 ResponseDataFormat :4; - u8 HiSupport :1; - u8 NormACA :1; - u8 ReservedBit :1; - u8 AERC :1; - u8 AdditionalLength; - u8 Reserved[2]; - u8 SoftReset :1; - u8 CommandQueue :1; - u8 Reserved2 :1; - u8 LinkedCommands :1; - u8 Synchronous :1; - u8 Wide16Bit :1; - u8 Wide32Bit :1; - u8 RelativeAddressing :1; - u8 VendorId[8]; - u8 ProductId[16]; - u8 ProductRevisionLevel[4]; - u8 VendorSpecific[20]; - u8 Reserved3[40]; -} ST_INQ; - struct st_sgitem { u8 ctrl; /* SG_CF_xxx */ u8 reserved[3]; @@ -221,7 +181,7 @@ struct req_msg { u8 task_attr; u8 task_manage; u8 prd_entry; - u8 payload_sz; /* payload size in 4-byte, not used */ + u8 payload_sz; /* payload size in 4-byte */ u8 cdb[STEX_CDB_LENGTH]; u8 variable[REQ_VARIABLE_LEN]; }; @@ -282,8 +242,7 @@ struct st_drvver { #define MU_REQ_BUFFER_SIZE (MU_REQ_COUNT * sizeof(struct req_msg)) #define MU_STATUS_BUFFER_SIZE (MU_STATUS_COUNT * sizeof(struct status_msg)) #define MU_BUFFER_SIZE (MU_REQ_BUFFER_SIZE + MU_STATUS_BUFFER_SIZE) -#define STEX_EXTRA_SIZE max(sizeof(struct st_frame), sizeof(ST_INQ)) -#define STEX_BUFFER_SIZE (MU_BUFFER_SIZE + STEX_EXTRA_SIZE) +#define STEX_BUFFER_SIZE (MU_BUFFER_SIZE + sizeof(struct st_frame)) struct st_ccb { struct req_msg *req; @@ -444,7 +403,7 @@ static int stex_map_sg(struct st_hba *hba, } static void stex_internal_copy(struct scsi_cmnd *cmd, - const void *src, size_t *count, int sg_count, int direction) + const void *src, size_t *count, int sg_count) { size_t lcount; size_t len; @@ -468,10 +427,7 @@ static void stex_internal_copy(struct scsi_cmnd *cmd, } else d = cmd->request_buffer; - if (direction == ST_TO_CMD) - memcpy(d, s, len); - else - memcpy(s, d, len); + memcpy(d, s, len); lcount -= len; if (cmd->use_sg) @@ -493,7 +449,7 @@ static int stex_direct_copy(struct scsi_cmnd *cmd, return 0; } - stex_internal_copy(cmd, src, &cp_len, n_elem, ST_TO_CMD); + stex_internal_copy(cmd, src, &cp_len, n_elem); if (cmd->use_sg) pci_unmap_sg(hba->pdev, cmd->request_buffer, @@ -524,7 +480,7 @@ static void stex_controller_info(struct st_hba *hba, struct st_ccb *ccb) p->subid = hba->pdev->subsystem_vendor << 16 | hba->pdev->subsystem_device; - stex_internal_copy(ccb->cmd, p, &count, ccb->sg_count, ST_TO_CMD); + stex_internal_copy(ccb->cmd, p, &count, ccb->sg_count); } static void @@ -533,6 +489,7 @@ stex_send_cmd(struct st_hba *hba, struct req_msg *req, u16 tag) req->tag = cpu_to_le16(tag); req->task_attr = TASK_ATTRIBUTE_SIMPLE; req->task_manage = 0; /* not supported yet */ + req->payload_sz = (u8)(sizeof(struct req_msg)/sizeof(u32)); hba->ccb[tag].req = req; hba->out_req_cnt++; @@ -638,14 +595,8 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) return SCSI_MLQUEUE_HOST_BUSY; req = stex_alloc_req(hba); - - if (hba->cardtype == st_yosemite) { - req->lun = lun * (ST_MAX_TARGET_NUM - 1) + id; - req->target = 0; - } else { - req->lun = lun; - req->target = id; - } + req->lun = lun; + req->target = id; /* cdb */ memcpy(req->cdb, cmd->cmnd, STEX_CDB_LENGTH); @@ -729,51 +680,7 @@ static void stex_copy_data(struct st_ccb *ccb, if (ccb->cmd == NULL) return; - stex_internal_copy(ccb->cmd, - resp->variable, &count, ccb->sg_count, ST_TO_CMD); -} - -static void stex_ys_commands(struct st_hba *hba, - struct st_ccb *ccb, struct status_msg *resp) -{ - size_t count; - - if (ccb->cmd->cmnd[0] == MGT_CMD && - resp->scsi_status != SAM_STAT_CHECK_CONDITION) { - ccb->cmd->request_bufflen = - le32_to_cpu(*(__le32 *)&resp->variable[0]); - return; - } - - if (resp->srb_status != 0) - return; - - /* determine inquiry command status by DeviceTypeQualifier */ - if (ccb->cmd->cmnd[0] == INQUIRY && - resp->scsi_status == SAM_STAT_GOOD) { - ST_INQ *inq_data; - - count = STEX_EXTRA_SIZE; - stex_internal_copy(ccb->cmd, hba->copy_buffer, - &count, ccb->sg_count, ST_FROM_CMD); - inq_data = (ST_INQ *)hba->copy_buffer; - if (inq_data->DeviceTypeQualifier != 0) - ccb->srb_status = SRB_STATUS_SELECTION_TIMEOUT; - else - ccb->srb_status = SRB_STATUS_SUCCESS; - } else if (ccb->cmd->cmnd[0] == REPORT_LUNS) { - u8 *report_lun_data = (u8 *)hba->copy_buffer; - - count = STEX_EXTRA_SIZE; - stex_internal_copy(ccb->cmd, report_lun_data, - &count, ccb->sg_count, ST_FROM_CMD); - if (report_lun_data[2] || report_lun_data[3]) { - report_lun_data[2] = 0x00; - report_lun_data[3] = 0x08; - stex_internal_copy(ccb->cmd, report_lun_data, - &count, ccb->sg_count, ST_TO_CMD); - } - } + stex_internal_copy(ccb->cmd, resp->variable, &count, ccb->sg_count); } static void stex_mu_intr(struct st_hba *hba, u32 doorbell) @@ -795,17 +702,8 @@ static void stex_mu_intr(struct st_hba *hba, u32 doorbell) return; } - /* - * it's not a valid status payload if: - * 1. there are no pending requests(e.g. during init stage) - * 2. there are some pending requests, but the controller is in - * reset status, and its type is not st_yosemite - * firmware of st_yosemite in reset status will return pending requests - * to driver, so we allow it to pass - */ - if (unlikely(hba->out_req_cnt <= 0 || - (hba->mu_status == MU_STATE_RESETTING && - hba->cardtype != st_yosemite))) { + if (unlikely(hba->mu_status != MU_STATE_STARTED || + hba->out_req_cnt <= 0)) { hba->status_tail = hba->status_head; goto update_status; } @@ -825,7 +723,6 @@ static void stex_mu_intr(struct st_hba *hba, u32 doorbell) if (unlikely(ccb->req == NULL)) { printk(KERN_WARNING DRV_NAME "(%s): lagging req\n", pci_name(hba->pdev)); - hba->out_req_cnt--; continue; } @@ -844,13 +741,9 @@ static void stex_mu_intr(struct st_hba *hba, u32 doorbell) ccb->scsi_status = resp->scsi_status; if (likely(ccb->cmd != NULL)) { - if (hba->cardtype == st_yosemite) - stex_ys_commands(hba, ccb, resp); - if (unlikely(ccb->cmd->cmnd[0] == PASSTHRU_CMD && ccb->cmd->cmnd[1] == PASSTHRU_GET_ADAPTER)) stex_controller_info(hba, ccb); - stex_unmap_sg(hba, ccb->cmd); stex_scsi_done(ccb); hba->out_req_cnt--; @@ -871,7 +764,7 @@ static void stex_mu_intr(struct st_hba *hba, u32 doorbell) readl(base + IMR1); /* flush */ } -static irqreturn_t stex_intr(int irq, void *__hba) +static irqreturn_t stex_intr(int irq, void *__hba, struct pt_regs *regs) { struct st_hba *hba = __hba; void __iomem *base = hba->mmio_base; @@ -1055,7 +948,6 @@ static int stex_reset(struct scsi_cmnd *cmd) { struct st_hba *hba; unsigned long flags; - unsigned long before; hba = (struct st_hba *) &cmd->device->host->hostdata[0]; hba->mu_status = MU_STATE_RESETTING; @@ -1063,37 +955,20 @@ static int stex_reset(struct scsi_cmnd *cmd) if (hba->cardtype == st_shasta) stex_hard_reset(hba); - if (hba->cardtype != st_yosemite) { - if (stex_handshake(hba)) { - printk(KERN_WARNING DRV_NAME - "(%s): resetting: handshake failed\n", - pci_name(hba->pdev)); - return FAILED; - } - spin_lock_irqsave(hba->host->host_lock, flags); - hba->req_head = 0; - hba->req_tail = 0; - hba->status_head = 0; - hba->status_tail = 0; - hba->out_req_cnt = 0; - spin_unlock_irqrestore(hba->host->host_lock, flags); - return SUCCESS; - } - - /* st_yosemite */ - writel(MU_INBOUND_DOORBELL_RESET, hba->mmio_base + IDBL); - readl(hba->mmio_base + IDBL); /* flush */ - before = jiffies; - while (hba->out_req_cnt > 0) { - if (time_after(jiffies, before + ST_INTERNAL_TIMEOUT * HZ)) { - printk(KERN_WARNING DRV_NAME - "(%s): reset timeout\n", pci_name(hba->pdev)); - return FAILED; - } - msleep(1); + if (stex_handshake(hba)) { + printk(KERN_WARNING DRV_NAME + "(%s): resetting: handshake failed\n", + pci_name(hba->pdev)); + return FAILED; } + spin_lock_irqsave(hba->host->host_lock, flags); + hba->req_head = 0; + hba->req_tail = 0; + hba->status_head = 0; + hba->status_tail = 0; + hba->out_req_cnt = 0; + spin_unlock_irqrestore(hba->host->host_lock, flags); - hba->mu_status = MU_STATE_STARTED; return SUCCESS; } @@ -1281,16 +1156,9 @@ static void stex_hba_stop(struct st_hba *hba) req = stex_alloc_req(hba); memset(req->cdb, 0, STEX_CDB_LENGTH); - if (hba->cardtype == st_yosemite) { - req->cdb[0] = MGT_CMD; - req->cdb[1] = MGT_CMD_SIGNATURE; - req->cdb[2] = CTLR_CONFIG_CMD; - req->cdb[3] = CTLR_SHUTDOWN; - } else { - req->cdb[0] = CONTROLLER_CMD; - req->cdb[1] = CTLR_POWER_STATE_CHANGE; - req->cdb[2] = CTLR_POWER_SAVING; - } + req->cdb[0] = CONTROLLER_CMD; + req->cdb[1] = CTLR_POWER_STATE_CHANGE; + req->cdb[2] = CTLR_POWER_SAVING; hba->ccb[tag].cmd = NULL; hba->ccb[tag].sg_count = 0; @@ -1354,7 +1222,6 @@ static struct pci_device_id stex_pci_tbl[] = { { 0x105a, 0x8301, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_shasta }, { 0x105a, 0x8302, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_shasta }, { 0x1725, 0x7250, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_vsc }, - { 0x105a, 0x8650, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_yosemite }, { } /* terminate list */ }; MODULE_DEVICE_TABLE(pci, stex_pci_tbl); diff --git a/trunk/drivers/scsi/sun3_NCR5380.c b/trunk/drivers/scsi/sun3_NCR5380.c index 3b3f3050a877..7f9bcef6adfa 100644 --- a/trunk/drivers/scsi/sun3_NCR5380.c +++ b/trunk/drivers/scsi/sun3_NCR5380.c @@ -266,8 +266,8 @@ static struct scsi_host_template *the_template = NULL; (struct NCR5380_hostdata *)(in)->hostdata #define HOSTDATA(in) ((struct NCR5380_hostdata *)(in)->hostdata) -#define NEXT(cmd) ((struct scsi_cmnd *)((cmd)->host_scribble)) -#define NEXTADDR(cmd) ((struct scsi_cmnd **)&((cmd)->host_scribble)) +#define NEXT(cmd) ((Scsi_Cmnd *)((cmd)->host_scribble)) +#define NEXTADDR(cmd) ((Scsi_Cmnd **)&((cmd)->host_scribble)) #define HOSTNO instance->host_no #define H_NO(cmd) (cmd)->device->host->host_no @@ -360,7 +360,7 @@ static void __init init_tags( void ) * conditions. */ -static int is_lun_busy(struct scsi_cmnd *cmd, int should_be_tagged) +static int is_lun_busy( Scsi_Cmnd *cmd, int should_be_tagged ) { SETUP_HOSTDATA(cmd->device->host); @@ -384,7 +384,7 @@ static int is_lun_busy(struct scsi_cmnd *cmd, int should_be_tagged) * untagged. */ -static void cmd_get_tag(struct scsi_cmnd *cmd, int should_be_tagged) +static void cmd_get_tag( Scsi_Cmnd *cmd, int should_be_tagged ) { SETUP_HOSTDATA(cmd->device->host); @@ -416,7 +416,7 @@ static void cmd_get_tag(struct scsi_cmnd *cmd, int should_be_tagged) * unlock the LUN. */ -static void cmd_free_tag(struct scsi_cmnd *cmd) +static void cmd_free_tag( Scsi_Cmnd *cmd ) { SETUP_HOSTDATA(cmd->device->host); @@ -460,18 +460,18 @@ static void free_all_tags( void ) /* - * Function: void merge_contiguous_buffers(struct scsi_cmnd *cmd) + * Function: void merge_contiguous_buffers( Scsi_Cmnd *cmd ) * * Purpose: Try to merge several scatter-gather requests into one DMA * transfer. This is possible if the scatter buffers lie on * physical contiguous addresses. * - * Parameters: struct scsi_cmnd *cmd + * Parameters: Scsi_Cmnd *cmd * The command to work on. The first scatter buffer's data are * assumed to be already transfered into ptr/this_residual. */ -static void merge_contiguous_buffers(struct scsi_cmnd *cmd) +static void merge_contiguous_buffers( Scsi_Cmnd *cmd ) { unsigned long endaddr; #if (NDEBUG & NDEBUG_MERGING) @@ -501,15 +501,15 @@ static void merge_contiguous_buffers(struct scsi_cmnd *cmd) } /* - * Function : void initialize_SCp(struct scsi_cmnd *cmd) + * Function : void initialize_SCp(Scsi_Cmnd *cmd) * * Purpose : initialize the saved data pointers for cmd to point to the * start of the buffer. * - * Inputs : cmd - struct scsi_cmnd structure to have pointers reset. + * Inputs : cmd - Scsi_Cmnd structure to have pointers reset. */ -static __inline__ void initialize_SCp(struct scsi_cmnd *cmd) +static __inline__ void initialize_SCp(Scsi_Cmnd *cmd) { /* * Initialize the Scsi Pointer field so that all of the commands in the @@ -753,15 +753,14 @@ static void NCR5380_print_status (struct Scsi_Host *instance) do { if (pos + strlen(fmt) + 20 /* slop */ < buffer + length) \ pos += sprintf(pos, fmt , ## args); } while(0) static -char *lprint_Scsi_Cmnd(struct scsi_cmnd *cmd, char *pos, char *buffer, - int length); +char *lprint_Scsi_Cmnd (Scsi_Cmnd *cmd, char *pos, char *buffer, int length); -static int NCR5380_proc_info(struct Scsi_Host *instance, char *buffer, - char **start, off_t offset, int length, int inout) +static int NCR5380_proc_info (struct Scsi_Host *instance, char *buffer, char **start, + off_t offset, int length, int inout) { char *pos = buffer; struct NCR5380_hostdata *hostdata; - struct scsi_cmnd *ptr; + Scsi_Cmnd *ptr; unsigned long flags; off_t begin = 0; #define check_offset() \ @@ -785,19 +784,18 @@ static int NCR5380_proc_info(struct Scsi_Host *instance, char *buffer, if (!hostdata->connected) SPRINTF("scsi%d: no currently connected command\n", HOSTNO); else - pos = lprint_Scsi_Cmnd ((struct scsi_cmnd *) hostdata->connected, + pos = lprint_Scsi_Cmnd ((Scsi_Cmnd *) hostdata->connected, pos, buffer, length); SPRINTF("scsi%d: issue_queue\n", HOSTNO); check_offset(); - for (ptr = (struct scsi_cmnd *) hostdata->issue_queue; ptr; ptr = NEXT(ptr)) - { + for (ptr = (Scsi_Cmnd *) hostdata->issue_queue; ptr; ptr = NEXT(ptr)) { pos = lprint_Scsi_Cmnd (ptr, pos, buffer, length); check_offset(); } SPRINTF("scsi%d: disconnected_queue\n", HOSTNO); check_offset(); - for (ptr = (struct scsi_cmnd *) hostdata->disconnected_queue; ptr; + for (ptr = (Scsi_Cmnd *) hostdata->disconnected_queue; ptr; ptr = NEXT(ptr)) { pos = lprint_Scsi_Cmnd (ptr, pos, buffer, length); check_offset(); @@ -812,8 +810,8 @@ static int NCR5380_proc_info(struct Scsi_Host *instance, char *buffer, return length; } -static char *lprint_Scsi_Cmnd(struct scsi_cmnd *cmd, char *pos, char *buffer, - int length) +static char * +lprint_Scsi_Cmnd (Scsi_Cmnd *cmd, char *pos, char *buffer, int length) { int i, s; unsigned char *command; @@ -890,8 +888,8 @@ static int NCR5380_init (struct Scsi_Host *instance, int flags) } /* - * Function : int NCR5380_queue_command (struct scsi_cmnd *cmd, - * void (*done)(struct scsi_cmnd *)) + * Function : int NCR5380_queue_command (Scsi_Cmnd *cmd, + * void (*done)(Scsi_Cmnd *)) * * Purpose : enqueues a SCSI command * @@ -908,11 +906,10 @@ static int NCR5380_init (struct Scsi_Host *instance, int flags) */ /* Only make static if a wrapper function is used */ -static int NCR5380_queue_command(struct scsi_cmnd *cmd, - void (*done)(struct scsi_cmnd *)) +static int NCR5380_queue_command (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *)) { SETUP_HOSTDATA(cmd->device->host); - struct scsi_cmnd *tmp; + Scsi_Cmnd *tmp; unsigned long flags; #if (NDEBUG & NDEBUG_NO_WRITE) @@ -993,7 +990,7 @@ static int NCR5380_queue_command(struct scsi_cmnd *cmd, NEXT(cmd) = hostdata->issue_queue; hostdata->issue_queue = cmd; } else { - for (tmp = (struct scsi_cmnd *)hostdata->issue_queue; + for (tmp = (Scsi_Cmnd *)hostdata->issue_queue; NEXT(tmp); tmp = NEXT(tmp)) ; LIST(cmd, tmp); @@ -1033,7 +1030,7 @@ static int NCR5380_queue_command(struct scsi_cmnd *cmd, static void NCR5380_main (void *bl) { - struct scsi_cmnd *tmp, *prev; + Scsi_Cmnd *tmp, *prev; struct Scsi_Host *instance = first_instance; struct NCR5380_hostdata *hostdata = HOSTDATA(instance); int done; @@ -1076,12 +1073,12 @@ static void NCR5380_main (void *bl) * for a target that's not busy. */ #if (NDEBUG & NDEBUG_LISTS) - for (tmp = (struct scsi_cmnd *) hostdata->issue_queue, prev = NULL; + for (tmp = (Scsi_Cmnd *) hostdata->issue_queue, prev = NULL; tmp && (tmp != prev); prev = tmp, tmp = NEXT(tmp)) ; if ((tmp == prev) && tmp) printk(" LOOP\n");/* else printk("\n");*/ #endif - for (tmp = (struct scsi_cmnd *) hostdata->issue_queue, + for (tmp = (Scsi_Cmnd *) hostdata->issue_queue, prev = NULL; tmp; prev = tmp, tmp = NEXT(tmp) ) { #if (NDEBUG & NDEBUG_LISTS) @@ -1255,7 +1252,7 @@ static void NCR5380_dma_complete( struct Scsi_Host *instance ) * */ -static irqreturn_t NCR5380_intr (int irq, void *dev_id) +static irqreturn_t NCR5380_intr (int irq, void *dev_id, struct pt_regs *regs) { struct Scsi_Host *instance = first_instance; int done = 1, handled = 0; @@ -1342,8 +1339,7 @@ static irqreturn_t NCR5380_intr (int irq, void *dev_id) } #ifdef NCR5380_STATS -static void collect_stats(struct NCR5380_hostdata *hostdata, - struct scsi_cmnd *cmd) +static void collect_stats(struct NCR5380_hostdata* hostdata, Scsi_Cmnd* cmd) { # ifdef NCR5380_STAT_LIMIT if (cmd->request_bufflen > NCR5380_STAT_LIMIT) @@ -1369,8 +1365,8 @@ static void collect_stats(struct NCR5380_hostdata *hostdata, #endif /* - * Function : int NCR5380_select(struct Scsi_Host *instance, - * struct scsi_cmnd *cmd, int tag); + * Function : int NCR5380_select (struct Scsi_Host *instance, Scsi_Cmnd *cmd, + * int tag); * * Purpose : establishes I_T_L or I_T_L_Q nexus for new or existing command, * including ARBITRATION, SELECTION, and initial message out for @@ -1399,8 +1395,7 @@ static void collect_stats(struct NCR5380_hostdata *hostdata, * cmd->result host byte set to DID_BAD_TARGET. */ -static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd, - int tag) +static int NCR5380_select (struct Scsi_Host *instance, Scsi_Cmnd *cmd, int tag) { SETUP_HOSTDATA(instance); unsigned char tmp[3], phase; @@ -1990,7 +1985,7 @@ static void NCR5380_information_transfer (struct Scsi_Host *instance) #endif unsigned char *data; unsigned char phase, tmp, extended_msg[10], old_phase=0xff; - struct scsi_cmnd *cmd = (struct scsi_cmnd *) hostdata->connected; + Scsi_Cmnd *cmd = (Scsi_Cmnd *) hostdata->connected; #ifdef SUN3_SCSI_VME dregs->csr |= CSR_INTR; @@ -2277,7 +2272,7 @@ static void NCR5380_information_transfer (struct Scsi_Host *instance) local_irq_save(flags); LIST(cmd,hostdata->issue_queue); NEXT(cmd) = hostdata->issue_queue; - hostdata->issue_queue = (struct scsi_cmnd *) cmd; + hostdata->issue_queue = (Scsi_Cmnd *) cmd; local_irq_restore(flags); QU_PRINTK("scsi%d: REQUEST SENSE added to head of " "issue queue\n", H_NO(cmd)); @@ -2507,7 +2502,7 @@ static void NCR5380_information_transfer (struct Scsi_Host *instance) * Function : void NCR5380_reselect (struct Scsi_Host *instance) * * Purpose : does reselection, initializing the instance->connected - * field to point to the struct scsi_cmnd for which the I_T_L or I_T_L_Q + * field to point to the Scsi_Cmnd for which the I_T_L or I_T_L_Q * nexus has been reestablished, * * Inputs : instance - this instance of the NCR5380. @@ -2526,7 +2521,7 @@ static void NCR5380_reselect (struct Scsi_Host *instance) unsigned char tag; #endif unsigned char msg[3]; - struct scsi_cmnd *tmp = NULL, *prev; + Scsi_Cmnd *tmp = NULL, *prev; /* unsigned long flags; */ /* @@ -2582,7 +2577,7 @@ static void NCR5380_reselect (struct Scsi_Host *instance) * just reestablished, and remove it from the disconnected queue. */ - for (tmp = (struct scsi_cmnd *) hostdata->disconnected_queue, prev = NULL; + for (tmp = (Scsi_Cmnd *) hostdata->disconnected_queue, prev = NULL; tmp; prev = tmp, tmp = NEXT(tmp) ) { if ((target_mask == (1 << tmp->device->id)) && (lun == tmp->device->lun) #ifdef SUPPORT_TAGS @@ -2673,11 +2668,11 @@ static void NCR5380_reselect (struct Scsi_Host *instance) /* - * Function : int NCR5380_abort(struct scsi_cmnd *cmd) + * Function : int NCR5380_abort (Scsi_Cmnd *cmd) * * Purpose : abort a command * - * Inputs : cmd - the struct scsi_cmnd to abort, code - code to set the + * Inputs : cmd - the Scsi_Cmnd to abort, code - code to set the * host byte of the result field to, if zero DID_ABORTED is * used. * @@ -2689,11 +2684,11 @@ static void NCR5380_reselect (struct Scsi_Host *instance) * called where the loop started in NCR5380_main(). */ -static int NCR5380_abort(struct scsi_cmnd *cmd) +static int NCR5380_abort (Scsi_Cmnd *cmd) { struct Scsi_Host *instance = cmd->device->host; SETUP_HOSTDATA(instance); - struct scsi_cmnd *tmp, **prev; + Scsi_Cmnd *tmp, **prev; unsigned long flags; printk(KERN_NOTICE "scsi%d: aborting command\n", HOSTNO); @@ -2758,9 +2753,9 @@ static int NCR5380_abort(struct scsi_cmnd *cmd) * Case 2 : If the command hasn't been issued yet, we simply remove it * from the issue queue. */ - for (prev = (struct scsi_cmnd **) &(hostdata->issue_queue), - tmp = (struct scsi_cmnd *) hostdata->issue_queue; - tmp; prev = NEXTADDR(tmp), tmp = NEXT(tmp)) + for (prev = (Scsi_Cmnd **) &(hostdata->issue_queue), + tmp = (Scsi_Cmnd *) hostdata->issue_queue; + tmp; prev = NEXTADDR(tmp), tmp = NEXT(tmp) ) if (cmd == tmp) { REMOVE(5, *prev, tmp, NEXT(tmp)); (*prev) = NEXT(tmp); @@ -2817,7 +2812,7 @@ static int NCR5380_abort(struct scsi_cmnd *cmd) * it from the disconnected queue. */ - for (tmp = (struct scsi_cmnd *) hostdata->disconnected_queue; tmp; + for (tmp = (Scsi_Cmnd *) hostdata->disconnected_queue; tmp; tmp = NEXT(tmp)) if (cmd == tmp) { local_irq_restore(flags); @@ -2831,8 +2826,8 @@ static int NCR5380_abort(struct scsi_cmnd *cmd) do_abort (instance); local_irq_save(flags); - for (prev = (struct scsi_cmnd **) &(hostdata->disconnected_queue), - tmp = (struct scsi_cmnd *) hostdata->disconnected_queue; + for (prev = (Scsi_Cmnd **) &(hostdata->disconnected_queue), + tmp = (Scsi_Cmnd *) hostdata->disconnected_queue; tmp; prev = NEXTADDR(tmp), tmp = NEXT(tmp) ) if (cmd == tmp) { REMOVE(5, *prev, tmp, NEXT(tmp)); @@ -2873,7 +2868,7 @@ static int NCR5380_abort(struct scsi_cmnd *cmd) /* - * Function : int NCR5380_bus_reset(struct scsi_cmnd *cmd) + * Function : int NCR5380_bus_reset (Scsi_Cmnd *cmd) * * Purpose : reset the SCSI bus. * @@ -2881,13 +2876,13 @@ static int NCR5380_abort(struct scsi_cmnd *cmd) * */ -static int NCR5380_bus_reset(struct scsi_cmnd *cmd) +static int NCR5380_bus_reset( Scsi_Cmnd *cmd) { SETUP_HOSTDATA(cmd->device->host); int i; unsigned long flags; #if 1 - struct scsi_cmnd *connected, *disconnected_queue; + Scsi_Cmnd *connected, *disconnected_queue; #endif @@ -2919,9 +2914,9 @@ static int NCR5380_bus_reset(struct scsi_cmnd *cmd) * remembered in local variables first. */ local_irq_save(flags); - connected = (struct scsi_cmnd *)hostdata->connected; + connected = (Scsi_Cmnd *)hostdata->connected; hostdata->connected = NULL; - disconnected_queue = (struct scsi_cmnd *)hostdata->disconnected_queue; + disconnected_queue = (Scsi_Cmnd *)hostdata->disconnected_queue; hostdata->disconnected_queue = NULL; #ifdef SUPPORT_TAGS free_all_tags(); diff --git a/trunk/drivers/scsi/sun3_scsi.c b/trunk/drivers/scsi/sun3_scsi.c index d56d85dd9ba0..44a99aeb8180 100644 --- a/trunk/drivers/scsi/sun3_scsi.c +++ b/trunk/drivers/scsi/sun3_scsi.c @@ -102,7 +102,7 @@ static void NCR5380_print(struct Scsi_Host *instance); #define ENABLE_IRQ() enable_irq( IRQ_SUN3_SCSI ); -static irqreturn_t scsi_sun3_intr(int irq, void *dummy); +static irqreturn_t scsi_sun3_intr(int irq, void *dummy, struct pt_regs *fp); static inline unsigned char sun3scsi_read(int reg); static inline void sun3scsi_write(int reg, int value); @@ -119,7 +119,7 @@ module_param(setup_use_tagged_queuing, int, 0); static int setup_hostid = -1; module_param(setup_hostid, int, 0); -static struct scsi_cmnd *sun3_dma_setup_done = NULL; +static Scsi_Cmnd *sun3_dma_setup_done = NULL; #define AFTER_RESET_DELAY (HZ/2) @@ -371,7 +371,7 @@ const char * sun3scsi_info (struct Scsi_Host *spnt) { // safe bits for the CSR #define CSR_GOOD 0x060f -static irqreturn_t scsi_sun3_intr(int irq, void *dummy) +static irqreturn_t scsi_sun3_intr(int irq, void *dummy, struct pt_regs *fp) { unsigned short csr = dregs->csr; int handled = 0; @@ -388,7 +388,7 @@ static irqreturn_t scsi_sun3_intr(int irq, void *dummy) } if(csr & (CSR_SDB_INT | CSR_DMA_INT)) { - NCR5380_intr(irq, dummy); + NCR5380_intr(irq, dummy, fp); handled = 1; } @@ -521,9 +521,8 @@ static inline unsigned long sun3scsi_dma_residual(struct Scsi_Host *instance) return last_residual; } -static inline unsigned long sun3scsi_dma_xfer_len(unsigned long wanted, - struct scsi_cmnd *cmd, - int write_flag) +static inline unsigned long sun3scsi_dma_xfer_len(unsigned long wanted, Scsi_Cmnd *cmd, + int write_flag) { if(blk_fs_request(cmd->request)) return wanted; diff --git a/trunk/drivers/scsi/sun3_scsi.h b/trunk/drivers/scsi/sun3_scsi.h index a1103b3e2034..834dab428019 100644 --- a/trunk/drivers/scsi/sun3_scsi.h +++ b/trunk/drivers/scsi/sun3_scsi.h @@ -47,12 +47,11 @@ #define IOBASE_SUN3_VMESCSI 0xff200000 -static int sun3scsi_abort(struct scsi_cmnd *); +static int sun3scsi_abort (Scsi_Cmnd *); static int sun3scsi_detect (struct scsi_host_template *); static const char *sun3scsi_info (struct Scsi_Host *); -static int sun3scsi_bus_reset(struct scsi_cmnd *); -static int sun3scsi_queue_command(struct scsi_cmnd *, - void (*done)(struct scsi_cmnd *)); +static int sun3scsi_bus_reset(Scsi_Cmnd *); +static int sun3scsi_queue_command (Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); static int sun3scsi_release (struct Scsi_Host *); #ifndef CMD_PER_LUN diff --git a/trunk/drivers/scsi/sun3_scsi_vme.c b/trunk/drivers/scsi/sun3_scsi_vme.c index 92def310a84c..f5742b84b27a 100644 --- a/trunk/drivers/scsi/sun3_scsi_vme.c +++ b/trunk/drivers/scsi/sun3_scsi_vme.c @@ -67,7 +67,7 @@ extern int sun3_map_test(unsigned long, char *); #define ENABLE_IRQ() -static irqreturn_t scsi_sun3_intr(int irq, void *dummy); +static irqreturn_t scsi_sun3_intr(int irq, void *dummy, struct pt_regs *fp); static inline unsigned char sun3scsi_read(int reg); static inline void sun3scsi_write(int reg, int value); @@ -84,7 +84,7 @@ module_param(setup_use_tagged_queuing, int, 0); static int setup_hostid = -1; module_param(setup_hostid, int, 0); -static struct scsi_cmnd *sun3_dma_setup_done = NULL; +static Scsi_Cmnd *sun3_dma_setup_done = NULL; #define AFTER_RESET_DELAY (HZ/2) @@ -340,7 +340,7 @@ static const char * sun3scsi_info (struct Scsi_Host *spnt) { // safe bits for the CSR #define CSR_GOOD 0x060f -static irqreturn_t scsi_sun3_intr(int irq, void *dummy) +static irqreturn_t scsi_sun3_intr(int irq, void *dummy, struct pt_regs *fp) { unsigned short csr = dregs->csr; int handled = 0; @@ -371,7 +371,7 @@ static irqreturn_t scsi_sun3_intr(int irq, void *dummy) } if(csr & (CSR_SDB_INT | CSR_DMA_INT)) { - NCR5380_intr(irq, dummy); + NCR5380_intr(irq, dummy, fp); handled = 1; } @@ -455,9 +455,8 @@ static inline unsigned long sun3scsi_dma_residual(struct Scsi_Host *instance) return last_residual; } -static inline unsigned long sun3scsi_dma_xfer_len(unsigned long wanted, - struct scsi_cmnd *cmd, - int write_flag) +static inline unsigned long sun3scsi_dma_xfer_len(unsigned long wanted, Scsi_Cmnd *cmd, + int write_flag) { if(blk_fs_request(cmd->request)) return wanted; diff --git a/trunk/drivers/scsi/sym53c416.c b/trunk/drivers/scsi/sym53c416.c index 32c883f1efa1..8640253d6215 100644 --- a/trunk/drivers/scsi/sym53c416.c +++ b/trunk/drivers/scsi/sym53c416.c @@ -326,7 +326,8 @@ static __inline__ unsigned int sym53c416_write(int base, unsigned char *buffer, return orig_len - len; } -static irqreturn_t sym53c416_intr_handle(int irq, void *dev_id) +static irqreturn_t sym53c416_intr_handle(int irq, void *dev_id, + struct pt_regs *regs) { struct Scsi_Host *dev = dev_id; int base = 0; diff --git a/trunk/drivers/scsi/sym53c8xx_2/sym_glue.c b/trunk/drivers/scsi/sym53c8xx_2/sym_glue.c index 4d78c7e87cca..739d3ef46a40 100644 --- a/trunk/drivers/scsi/sym53c8xx_2/sym_glue.c +++ b/trunk/drivers/scsi/sym53c8xx_2/sym_glue.c @@ -652,7 +652,7 @@ static int sym53c8xx_queue_command(struct scsi_cmnd *cmd, /* * Linux entry point of the interrupt handler. */ -static irqreturn_t sym53c8xx_intr(int irq, void *dev_id) +static irqreturn_t sym53c8xx_intr(int irq, void *dev_id, struct pt_regs * regs) { unsigned long flags; struct sym_hcb *np = (struct sym_hcb *)dev_id; diff --git a/trunk/drivers/scsi/t128.c b/trunk/drivers/scsi/t128.c index 0b7a70f61e0d..2df6747cb76f 100644 --- a/trunk/drivers/scsi/t128.c +++ b/trunk/drivers/scsi/t128.c @@ -109,7 +109,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/trunk/drivers/scsi/tmscsim.c b/trunk/drivers/scsi/tmscsim.c index fa5382e354be..9404ff3d4c79 100644 --- a/trunk/drivers/scsi/tmscsim.c +++ b/trunk/drivers/scsi/tmscsim.c @@ -279,10 +279,6 @@ static void dc390_ResetDevParam(struct dc390_acb* pACB); static u32 dc390_laststatus = 0; static u8 dc390_adapterCnt = 0; -static int disable_clustering; -module_param(disable_clustering, int, S_IRUGO); -MODULE_PARM_DESC(disable_clustering, "If you experience problems with your devices, try setting to 1"); - /* Startup values, to be overriden on the commandline */ static int tmscsim[] = {-2, -2, -2, -2, -2, -2}; @@ -700,9 +696,9 @@ dc390_InvalidCmd(struct dc390_acb* pACB) static irqreturn_t __inline__ -DC390_Interrupt(void *dev_id) +DC390_Interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct dc390_acb *pACB = dev_id; + struct dc390_acb *pACB = (struct dc390_acb*)dev_id; struct dc390_dcb *pDCB; struct dc390_srb *pSRB; u8 sstatus=0; @@ -811,12 +807,12 @@ DC390_Interrupt(void *dev_id) return IRQ_HANDLED; } -static irqreturn_t do_DC390_Interrupt(int irq, void *dev_id) +static irqreturn_t do_DC390_Interrupt( int irq, void *dev_id, struct pt_regs *regs) { irqreturn_t ret; DEBUG1(printk (KERN_INFO "DC390: Irq (%i) caught: ", irq)); /* Locking is done in DC390_Interrupt */ - ret = DC390_Interrupt(dev_id); + ret = DC390_Interrupt(irq, dev_id, regs); DEBUG1(printk (".. IRQ returned\n")); return ret; } @@ -2303,8 +2299,7 @@ static struct scsi_host_template driver_template = { .this_id = 7, .sg_tablesize = SG_ALL, .cmd_per_lun = 1, - .use_clustering = ENABLE_CLUSTERING, - .max_sectors = 0x4000, /* 8MiB = 16 * 1024 * 512 */ + .use_clustering = DISABLE_CLUSTERING, }; /*********************************************************************** @@ -2530,8 +2525,6 @@ static int __devinit dc390_probe_one(struct pci_dev *pdev, pci_set_master(pdev); error = -ENOMEM; - if (disable_clustering) - driver_template.use_clustering = DISABLE_CLUSTERING; shost = scsi_host_alloc(&driver_template, sizeof(struct dc390_acb)); if (!shost) goto out_disable_device; @@ -2667,10 +2660,6 @@ static struct pci_driver dc390_driver = { static int __init dc390_module_init(void) { - if (!disable_clustering) - printk(KERN_INFO "DC390: clustering now enabled by default. If you get problems load\n" - "\twith \"disable_clustering=1\" and report to maintainers\n"); - if (tmscsim[0] == -1 || tmscsim[0] > 15) { tmscsim[0] = 7; tmscsim[1] = 4; diff --git a/trunk/drivers/scsi/u14-34f.c b/trunk/drivers/scsi/u14-34f.c index 3de08a15de40..57449611e714 100644 --- a/trunk/drivers/scsi/u14-34f.c +++ b/trunk/drivers/scsi/u14-34f.c @@ -634,7 +634,7 @@ static unsigned long io_port[] = { #define H2DEV(x) cpu_to_le32(x) #define DEV2H(x) le32_to_cpu(x) -static irqreturn_t do_interrupt_handler(int, void *); +static irqreturn_t do_interrupt_handler(int, void *, struct pt_regs *); static void flush_dev(struct scsi_device *, unsigned long, unsigned int, unsigned int); static int do_trace = FALSE; static int setup_done = FALSE; @@ -1932,7 +1932,8 @@ static irqreturn_t ihdlr(int irq, unsigned int j) { return IRQ_NONE; } -static irqreturn_t do_interrupt_handler(int irq, void *shap) { +static irqreturn_t do_interrupt_handler(int irq, void *shap, + struct pt_regs *regs) { unsigned int j; unsigned long spin_flags; irqreturn_t ret; diff --git a/trunk/drivers/scsi/ultrastor.c b/trunk/drivers/scsi/ultrastor.c index 56906aba5ee3..0372aa9fa190 100644 --- a/trunk/drivers/scsi/ultrastor.c +++ b/trunk/drivers/scsi/ultrastor.c @@ -287,8 +287,8 @@ static const unsigned short ultrastor_ports_14f[] = { }; #endif -static void ultrastor_interrupt(void *); -static irqreturn_t do_ultrastor_interrupt(int, void *); +static void ultrastor_interrupt(int, void *, struct pt_regs *); +static irqreturn_t do_ultrastor_interrupt(int, void *, struct pt_regs *); static inline void build_sg_list(struct mscp *, struct scsi_cmnd *SCpnt); @@ -893,7 +893,7 @@ static int ultrastor_abort(struct scsi_cmnd *SCpnt) spin_lock_irqsave(host->host_lock, flags); /* FIXME: Ewww... need to think about passing host around properly */ - ultrastor_interrupt(NULL); + ultrastor_interrupt(0, NULL, NULL); spin_unlock_irqrestore(host->host_lock, flags); return SUCCESS; } @@ -1039,7 +1039,7 @@ int ultrastor_biosparam(struct scsi_device *sdev, struct block_device *bdev, return 0; } -static void ultrastor_interrupt(void *dev_id) +static void ultrastor_interrupt(int irq, void *dev_id, struct pt_regs *regs) { unsigned int status; #if ULTRASTOR_MAX_CMDS > 1 @@ -1171,13 +1171,14 @@ static void ultrastor_interrupt(void *dev_id) #endif } -static irqreturn_t do_ultrastor_interrupt(int irq, void *dev_id) +static irqreturn_t do_ultrastor_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { unsigned long flags; struct Scsi_Host *dev = dev_id; spin_lock_irqsave(dev->host_lock, flags); - ultrastor_interrupt(dev_id); + ultrastor_interrupt(irq, dev_id, regs); spin_unlock_irqrestore(dev->host_lock, flags); return IRQ_HANDLED; } diff --git a/trunk/drivers/scsi/wd7000.c b/trunk/drivers/scsi/wd7000.c index 30be76514c43..a0b61af48f1c 100644 --- a/trunk/drivers/scsi/wd7000.c +++ b/trunk/drivers/scsi/wd7000.c @@ -178,10 +178,10 @@ #include #include #include -#include #include #include +#include #include #include @@ -998,7 +998,7 @@ static int make_code(unsigned hosterr, unsigned scsierr) #define wd7000_intr_ack(host) outb (0, host->iobase + ASC_INTR_ACK) -static irqreturn_t wd7000_intr(int irq, void *dev_id) +static irqreturn_t wd7000_intr(int irq, void *dev_id, struct pt_regs *regs) { Adapter *host = (Adapter *) dev_id; int flag, icmb, errstatus, icmb_status; diff --git a/trunk/drivers/serial/21285.c b/trunk/drivers/serial/21285.c index 6a1a568ca649..76d83ade9857 100644 --- a/trunk/drivers/serial/21285.c +++ b/trunk/drivers/serial/21285.c @@ -85,7 +85,7 @@ static void serial21285_enable_ms(struct uart_port *port) { } -static irqreturn_t serial21285_rx_chars(int irq, void *dev_id) +static irqreturn_t serial21285_rx_chars(int irq, void *dev_id, struct pt_regs *regs) { struct uart_port *port = dev_id; struct tty_struct *tty = port->info->tty; @@ -123,7 +123,7 @@ static irqreturn_t serial21285_rx_chars(int irq, void *dev_id) return IRQ_HANDLED; } -static irqreturn_t serial21285_tx_chars(int irq, void *dev_id) +static irqreturn_t serial21285_tx_chars(int irq, void *dev_id, struct pt_regs *regs) { struct uart_port *port = dev_id; struct circ_buf *xmit = &port->info->xmit; diff --git a/trunk/drivers/serial/68328serial.c b/trunk/drivers/serial/68328serial.c index 9b8b585513ec..bac853c5abb5 100644 --- a/trunk/drivers/serial/68328serial.c +++ b/trunk/drivers/serial/68328serial.c @@ -275,7 +275,8 @@ static void status_handle(struct m68k_serial *info, unsigned short status) return; } -static void receive_chars(struct m68k_serial *info, unsigned short rx) +static void receive_chars(struct m68k_serial *info, struct pt_regs *regs, + unsigned short rx) { struct tty_struct *tty = info->tty; m68328_uart *uart = &uart_addr[info->line]; @@ -376,7 +377,7 @@ static void transmit_chars(struct m68k_serial *info) /* * This is the serial driver's generic interrupt routine */ -irqreturn_t rs_interrupt(int irq, void *dev_id) +irqreturn_t rs_interrupt(int irq, void *dev_id, struct pt_regs * regs) { struct m68k_serial * info; m68328_uart *uart; @@ -393,10 +394,10 @@ irqreturn_t rs_interrupt(int irq, void *dev_id) #ifdef USE_INTS tx = uart->utx.w; - if (rx & URX_DATA_READY) receive_chars(info, rx); + if (rx & URX_DATA_READY) receive_chars(info, regs, rx); if (tx & UTX_TX_AVAIL) transmit_chars(info); #else - receive_chars(info, rx); + receive_chars(info, regs, rx); #endif return IRQ_HANDLED; } diff --git a/trunk/drivers/serial/68360serial.c b/trunk/drivers/serial/68360serial.c index 634ecca36a77..1b299e8c57cd 100644 --- a/trunk/drivers/serial/68360serial.c +++ b/trunk/drivers/serial/68360serial.c @@ -612,7 +612,7 @@ static _INLINE_ void check_modem_status(struct async_struct *info) * This is the serial driver's interrupt routine for a single port */ /* static void rs_360_interrupt(void *dev_id) */ /* until and if we start servicing irqs here */ -static void rs_360_interrupt(int vec, void *dev_id) +static void rs_360_interrupt(int vec, void *dev_id, struct pt_regs *fp) { u_char events; int idx; @@ -620,7 +620,7 @@ static void rs_360_interrupt(int vec, void *dev_id) volatile struct smc_regs *smcp; volatile struct scc_regs *sccp; - info = dev_id; + info = (ser_info_t *)dev_id; idx = PORT_NUM(info->state->smc_scc_num); if (info->state->smc_scc_num & NUM_IS_SCC) { diff --git a/trunk/drivers/serial/8250.c b/trunk/drivers/serial/8250.c index e34bd03cfce7..cc2a205d4230 100644 --- a/trunk/drivers/serial/8250.c +++ b/trunk/drivers/serial/8250.c @@ -1175,7 +1175,7 @@ static void serial8250_enable_ms(struct uart_port *port) } static void -receive_chars(struct uart_8250_port *up, int *status) +receive_chars(struct uart_8250_port *up, int *status, struct pt_regs *regs) { struct tty_struct *tty = up->port.info->tty; unsigned char ch, lsr = *status; @@ -1233,7 +1233,7 @@ receive_chars(struct uart_8250_port *up, int *status) else if (lsr & UART_LSR_FE) flag = TTY_FRAME; } - if (uart_handle_sysrq_char(&up->port, ch)) + if (uart_handle_sysrq_char(&up->port, ch, regs)) goto ignore_char; uart_insert_char(&up->port, lsr, UART_LSR_OE, ch, flag); @@ -1309,7 +1309,7 @@ static unsigned int check_modem_status(struct uart_8250_port *up) * This handles the interrupt from one port. */ static inline void -serial8250_handle_port(struct uart_8250_port *up) +serial8250_handle_port(struct uart_8250_port *up, struct pt_regs *regs) { unsigned int status; @@ -1320,7 +1320,7 @@ serial8250_handle_port(struct uart_8250_port *up) DEBUG_INTR("status = %x...", status); if (status & UART_LSR_DR) - receive_chars(up, &status); + receive_chars(up, &status, regs); check_modem_status(up); if (status & UART_LSR_THRE) transmit_chars(up); @@ -1342,7 +1342,7 @@ serial8250_handle_port(struct uart_8250_port *up) * This means we need to loop through all ports. checking that they * don't have an interrupt pending. */ -static irqreturn_t serial8250_interrupt(int irq, void *dev_id) +static irqreturn_t serial8250_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct irq_info *i = dev_id; struct list_head *l, *end = NULL; @@ -1361,7 +1361,7 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id) iir = serial_in(up, UART_IIR); if (!(iir & UART_IIR_NO_INT)) { - serial8250_handle_port(up); + serial8250_handle_port(up, regs); handled = 1; @@ -1461,7 +1461,7 @@ static void serial8250_timeout(unsigned long data) iir = serial_in(up, UART_IIR); if (!(iir & UART_IIR_NO_INT)) - serial8250_handle_port(up); + serial8250_handle_port(up, NULL); timeout = up->port.timeout; timeout = timeout > 6 ? (timeout / 2 - 2) : 1; diff --git a/trunk/drivers/serial/Kconfig b/trunk/drivers/serial/Kconfig index 0b71e7d18903..b0d502622d94 100644 --- a/trunk/drivers/serial/Kconfig +++ b/trunk/drivers/serial/Kconfig @@ -767,37 +767,37 @@ config SERIAL_CPM_SCC1 bool "Support for SCC1 serial port" depends on SERIAL_CPM=y help - Select this option to use SCC1 as a serial port + Select the is option to use SCC1 as a serial port config SERIAL_CPM_SCC2 bool "Support for SCC2 serial port" depends on SERIAL_CPM=y help - Select this option to use SCC2 as a serial port + Select the is option to use SCC2 as a serial port config SERIAL_CPM_SCC3 bool "Support for SCC3 serial port" depends on SERIAL_CPM=y help - Select this option to use SCC3 as a serial port + Select the is option to use SCC3 as a serial port config SERIAL_CPM_SCC4 bool "Support for SCC4 serial port" depends on SERIAL_CPM=y help - Select this option to use SCC4 as a serial port + Select the is option to use SCC4 as a serial port config SERIAL_CPM_SMC1 bool "Support for SMC1 serial port" depends on SERIAL_CPM=y help - Select this option to use SMC1 as a serial port + Select the is option to use SMC1 as a serial port config SERIAL_CPM_SMC2 bool "Support for SMC2 serial port" depends on SERIAL_CPM=y help - Select this option to use SMC2 as a serial port + Select the is option to use SMC2 as a serial port config SERIAL_SGI_L1_CONSOLE bool "SGI Altix L1 serial console support" diff --git a/trunk/drivers/serial/amba-pl010.c b/trunk/drivers/serial/amba-pl010.c index 4213fabc62bf..7311d8487c96 100644 --- a/trunk/drivers/serial/amba-pl010.c +++ b/trunk/drivers/serial/amba-pl010.c @@ -111,7 +111,12 @@ static void pl010_enable_ms(struct uart_port *port) writel(cr, port->membase + UART010_CR); } -static void pl010_rx_chars(struct uart_port *port) +static void +#ifdef SUPPORT_SYSRQ +pl010_rx_chars(struct uart_port *port, struct pt_regs *regs) +#else +pl010_rx_chars(struct uart_port *port) +#endif { struct tty_struct *tty = port->info->tty; unsigned int status, ch, flag, rsr, max_count = 256; @@ -151,7 +156,7 @@ static void pl010_rx_chars(struct uart_port *port) flag = TTY_FRAME; } - if (uart_handle_sysrq_char(port, ch)) + if (uart_handle_sysrq_char(port, ch, regs)) goto ignore_char; uart_insert_char(port, rsr, UART01x_RSR_OE, ch, flag); @@ -222,7 +227,7 @@ static void pl010_modem_status(struct uart_port *port) wake_up_interruptible(&uap->port.info->delta_msr_wait); } -static irqreturn_t pl010_int(int irq, void *dev_id) +static irqreturn_t pl010_int(int irq, void *dev_id, struct pt_regs *regs) { struct uart_port *port = dev_id; unsigned int status, pass_counter = AMBA_ISR_PASS_LIMIT; @@ -234,7 +239,11 @@ static irqreturn_t pl010_int(int irq, void *dev_id) if (status) { do { if (status & (UART010_IIR_RTIS | UART010_IIR_RIS)) +#ifdef SUPPORT_SYSRQ + pl010_rx_chars(port, regs); +#else pl010_rx_chars(port); +#endif if (status & UART010_IIR_MIS) pl010_modem_status(port); if (status & UART010_IIR_TIS) diff --git a/trunk/drivers/serial/amba-pl011.c b/trunk/drivers/serial/amba-pl011.c index d503625730df..a8d7124e84a1 100644 --- a/trunk/drivers/serial/amba-pl011.c +++ b/trunk/drivers/serial/amba-pl011.c @@ -107,7 +107,12 @@ static void pl011_enable_ms(struct uart_port *port) writew(uap->im, uap->port.membase + UART011_IMSC); } -static void pl011_rx_chars(struct uart_amba_port *uap) +static void +#ifdef SUPPORT_SYSRQ +pl011_rx_chars(struct uart_amba_port *uap, struct pt_regs *regs) +#else +pl011_rx_chars(struct uart_amba_port *uap) +#endif { struct tty_struct *tty = uap->port.info->tty; unsigned int status, ch, flag, max_count = 256; @@ -145,7 +150,7 @@ static void pl011_rx_chars(struct uart_amba_port *uap) flag = TTY_FRAME; } - if (uart_handle_sysrq_char(&uap->port, ch & 255)) + if (uart_handle_sysrq_char(&uap->port, ch & 255, regs)) goto ignore_char; uart_insert_char(&uap->port, ch, UART011_DR_OE, ch, flag); @@ -213,7 +218,7 @@ static void pl011_modem_status(struct uart_amba_port *uap) wake_up_interruptible(&uap->port.info->delta_msr_wait); } -static irqreturn_t pl011_int(int irq, void *dev_id) +static irqreturn_t pl011_int(int irq, void *dev_id, struct pt_regs *regs) { struct uart_amba_port *uap = dev_id; unsigned int status, pass_counter = AMBA_ISR_PASS_LIMIT; @@ -229,7 +234,11 @@ static irqreturn_t pl011_int(int irq, void *dev_id) uap->port.membase + UART011_ICR); if (status & (UART011_RTIS|UART011_RXIS)) +#ifdef SUPPORT_SYSRQ + pl011_rx_chars(uap, regs); +#else pl011_rx_chars(uap); +#endif if (status & (UART011_DSRMIS|UART011_DCDMIS| UART011_CTSMIS|UART011_RIMIS)) pl011_modem_status(uap); diff --git a/trunk/drivers/serial/atmel_serial.c b/trunk/drivers/serial/atmel_serial.c index 391a1f4167a4..955c46da5800 100644 --- a/trunk/drivers/serial/atmel_serial.c +++ b/trunk/drivers/serial/atmel_serial.c @@ -249,7 +249,7 @@ static void atmel_break_ctl(struct uart_port *port, int break_state) /* * Characters received (called from interrupt handler) */ -static void atmel_rx_chars(struct uart_port *port) +static void atmel_rx_chars(struct uart_port *port, struct pt_regs *regs) { struct tty_struct *tty = port->info->tty; unsigned int status, ch, flg; @@ -291,7 +291,7 @@ static void atmel_rx_chars(struct uart_port *port) flg = TTY_FRAME; } - if (uart_handle_sysrq_char(port, ch)) + if (uart_handle_sysrq_char(port, ch, regs)) goto ignore_char; uart_insert_char(port, status, ATMEL_US_OVRE, ch, flg); @@ -339,7 +339,7 @@ static void atmel_tx_chars(struct uart_port *port) /* * Interrupt handler */ -static irqreturn_t atmel_interrupt(int irq, void *dev_id) +static irqreturn_t atmel_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct uart_port *port = dev_id; struct atmel_uart_port *atmel_port = (struct atmel_uart_port *) port; @@ -350,7 +350,7 @@ static irqreturn_t atmel_interrupt(int irq, void *dev_id) while (pending) { /* Interrupt receive */ if (pending & ATMEL_US_RXRDY) - atmel_rx_chars(port); + atmel_rx_chars(port, regs); // TODO: All reads to CSR will clear these interrupts! if (pending & ATMEL_US_RIIC) port->icount.rng++; diff --git a/trunk/drivers/serial/clps711x.c b/trunk/drivers/serial/clps711x.c index 598012714882..f27d852ce50d 100644 --- a/trunk/drivers/serial/clps711x.c +++ b/trunk/drivers/serial/clps711x.c @@ -93,7 +93,7 @@ static void clps711xuart_enable_ms(struct uart_port *port) { } -static irqreturn_t clps711xuart_int_rx(int irq, void *dev_id) +static irqreturn_t clps711xuart_int_rx(int irq, void *dev_id, struct pt_regs *regs) { struct uart_port *port = dev_id; struct tty_struct *tty = port->info->tty; @@ -131,7 +131,7 @@ static irqreturn_t clps711xuart_int_rx(int irq, void *dev_id) #endif } - if (uart_handle_sysrq_char(port, ch)) + if (uart_handle_sysrq_char(port, ch, regs)) goto ignore_char; /* @@ -147,7 +147,7 @@ static irqreturn_t clps711xuart_int_rx(int irq, void *dev_id) return IRQ_HANDLED; } -static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id) +static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id, struct pt_regs *regs) { struct uart_port *port = dev_id; struct circ_buf *xmit = &port->info->xmit; diff --git a/trunk/drivers/serial/cpm_uart/cpm_uart.h b/trunk/drivers/serial/cpm_uart/cpm_uart.h index 69715e556506..a8f894c78194 100644 --- a/trunk/drivers/serial/cpm_uart/cpm_uart.h +++ b/trunk/drivers/serial/cpm_uart/cpm_uart.h @@ -88,7 +88,7 @@ extern struct uart_cpm_port cpm_uart_ports[UART_NR]; /* these are located in their respective files */ void cpm_line_cr_cmd(int line, int cmd); -int __init cpm_uart_init_portdesc(void); +int cpm_uart_init_portdesc(void); int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con); void cpm_uart_freebuf(struct uart_cpm_port *pinfo); diff --git a/trunk/drivers/serial/cpm_uart/cpm_uart_core.c b/trunk/drivers/serial/cpm_uart/cpm_uart_core.c index 7a3b97fdf8d1..a0d6136deb9b 100644 --- a/trunk/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/trunk/drivers/serial/cpm_uart/cpm_uart_core.c @@ -195,8 +195,10 @@ static void cpm_uart_start_tx(struct uart_port *port) if (cpm_uart_tx_pump(port) != 0) { if (IS_SMC(pinfo)) { smcp->smc_smcm |= SMCM_TX; + smcp->smc_smcmr |= SMCMR_TEN; } else { sccp->scc_sccm |= UART_SCCM_TX; + pinfo->sccp->scc_gsmrl |= SCC_GSMRL_ENT; } } } @@ -246,7 +248,7 @@ static void cpm_uart_break_ctl(struct uart_port *port, int break_state) /* * Transmit characters, refill buffer descriptor, if possible */ -static void cpm_uart_int_tx(struct uart_port *port) +static void cpm_uart_int_tx(struct uart_port *port, struct pt_regs *regs) { pr_debug("CPM uart[%d]:TX INT\n", port->line); @@ -256,7 +258,7 @@ static void cpm_uart_int_tx(struct uart_port *port) /* * Receive characters */ -static void cpm_uart_int_rx(struct uart_port *port) +static void cpm_uart_int_rx(struct uart_port *port, struct pt_regs *regs) { int i; unsigned char ch, *cp; @@ -302,7 +304,7 @@ static void cpm_uart_int_rx(struct uart_port *port) if (status & (BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV)) goto handle_error; - if (uart_handle_sysrq_char(port, ch)) + if (uart_handle_sysrq_char(port, ch, regs)) continue; error_return: @@ -371,7 +373,7 @@ static void cpm_uart_int_rx(struct uart_port *port) /* * Asynchron mode interrupt handler */ -static irqreturn_t cpm_uart_int(int irq, void *data) +static irqreturn_t cpm_uart_int(int irq, void *data, struct pt_regs *regs) { u8 events; struct uart_port *port = (struct uart_port *)data; @@ -387,18 +389,18 @@ static irqreturn_t cpm_uart_int(int irq, void *data) if (events & SMCM_BRKE) uart_handle_break(port); if (events & SMCM_RX) - cpm_uart_int_rx(port); + cpm_uart_int_rx(port, regs); if (events & SMCM_TX) - cpm_uart_int_tx(port); + cpm_uart_int_tx(port, regs); } else { events = sccp->scc_scce; sccp->scc_scce = events; if (events & UART_SCCM_BRKE) uart_handle_break(port); if (events & UART_SCCM_RX) - cpm_uart_int_rx(port); + cpm_uart_int_rx(port, regs); if (events & UART_SCCM_TX) - cpm_uart_int_tx(port); + cpm_uart_int_tx(port, regs); } return (events) ? IRQ_HANDLED : IRQ_NONE; } @@ -419,10 +421,9 @@ static int cpm_uart_startup(struct uart_port *port) /* Startup rx-int */ if (IS_SMC(pinfo)) { pinfo->smcp->smc_smcm |= SMCM_RX; - pinfo->smcp->smc_smcmr |= (SMCMR_REN | SMCMR_TEN); + pinfo->smcp->smc_smcmr |= SMCMR_REN; } else { pinfo->sccp->scc_sccm |= UART_SCCM_RX; - pinfo->sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT); } if (!(pinfo->flags & FLAG_CONSOLE)) @@ -1349,10 +1350,11 @@ static int cpm_uart_init(void) { pr_info("cpm_uart: WARNING: no UART devices found on platform bus!\n"); pr_info( "cpm_uart: the driver will guess configuration, but this mode is no longer supported.\n"); - - /* Don't run this again, if the console driver did it already */ - if (cpm_uart_nr == 0) - cpm_uart_init_portdesc(); +#ifndef CONFIG_SERIAL_CPM_CONSOLE + ret = cpm_uart_init_portdesc(); + if (ret) + return ret; +#endif cpm_reg.nr = cpm_uart_nr; ret = uart_register_driver(&cpm_reg); @@ -1364,8 +1366,6 @@ static int cpm_uart_init(void) { int con = cpm_uart_port_map[i]; cpm_uart_ports[con].port.line = i; cpm_uart_ports[con].port.flags = UPF_BOOT_AUTOCONF; - if (cpm_uart_ports[con].set_lineif) - cpm_uart_ports[con].set_lineif(&cpm_uart_ports[con]); uart_add_one_port(&cpm_reg, &cpm_uart_ports[con].port); } diff --git a/trunk/drivers/serial/cpm_uart/cpm_uart_cpm1.c b/trunk/drivers/serial/cpm_uart/cpm_uart_cpm1.c index 08e55fdc882a..95afc37297a8 100644 --- a/trunk/drivers/serial/cpm_uart/cpm_uart_cpm1.c +++ b/trunk/drivers/serial/cpm_uart/cpm_uart_cpm1.c @@ -184,7 +184,7 @@ void cpm_uart_freebuf(struct uart_cpm_port *pinfo) } /* Setup any dynamic params in the uart desc */ -int __init cpm_uart_init_portdesc(void) +int cpm_uart_init_portdesc(void) { pr_debug("CPM uart[-]:init portdesc\n"); diff --git a/trunk/drivers/serial/crisv10.c b/trunk/drivers/serial/crisv10.c index 7a24e53546c7..9851d9eff022 100644 --- a/trunk/drivers/serial/crisv10.c +++ b/trunk/drivers/serial/crisv10.c @@ -2346,7 +2346,7 @@ start_receive(struct e100_serial *info) */ static irqreturn_t -tr_interrupt(int irq, void *dev_id) +tr_interrupt(int irq, void *dev_id, struct pt_regs * regs) { struct e100_serial *info; unsigned long ireg; @@ -2395,7 +2395,7 @@ tr_interrupt(int irq, void *dev_id) /* dma input channel interrupt handler */ static irqreturn_t -rec_interrupt(int irq, void *dev_id) +rec_interrupt(int irq, void *dev_id, struct pt_regs * regs) { struct e100_serial *info; unsigned long ireg; @@ -3054,7 +3054,7 @@ static void handle_ser_tx_interrupt(struct e100_serial *info) * ser_int duration: just sending: 8-15 us normally, up to 73 us */ static irqreturn_t -ser_interrupt(int irq, void *dev_id) +ser_interrupt(int irq, void *dev_id, struct pt_regs *regs) { static volatile int tx_started = 0; struct e100_serial *info; diff --git a/trunk/drivers/serial/dz.c b/trunk/drivers/serial/dz.c index 53662b33b841..8a98aae80e22 100644 --- a/trunk/drivers/serial/dz.c +++ b/trunk/drivers/serial/dz.c @@ -339,7 +339,7 @@ static inline void check_modem_status(struct dz_port *dport) * It deals with the multiple ports. * ------------------------------------------------------------ */ -static irqreturn_t dz_interrupt(int irq, void *dev) +static irqreturn_t dz_interrupt(int irq, void *dev, struct pt_regs *regs) { struct dz_port *dport; unsigned short status; diff --git a/trunk/drivers/serial/icom.c b/trunk/drivers/serial/icom.c index 8aa0f641866b..a3c00a252149 100644 --- a/trunk/drivers/serial/icom.c +++ b/trunk/drivers/serial/icom.c @@ -844,7 +844,8 @@ static void process_interrupt(u16 port_int_reg, spin_unlock(&icom_port->uart_port.lock); } -static irqreturn_t icom_interrupt(int irq, void *dev_id) +static irqreturn_t icom_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { void __iomem * int_reg; u32 adapter_interrupts; diff --git a/trunk/drivers/serial/imx.c b/trunk/drivers/serial/imx.c index ee5c782597dd..4a142d6b8f38 100644 --- a/trunk/drivers/serial/imx.c +++ b/trunk/drivers/serial/imx.c @@ -182,7 +182,7 @@ static void imx_start_tx(struct uart_port *port) imx_transmit_buffer(sport); } -static irqreturn_t imx_rtsint(int irq, void *dev_id) +static irqreturn_t imx_rtsint(int irq, void *dev_id, struct pt_regs *regs) { struct imx_port *sport = (struct imx_port *)dev_id; unsigned int val = USR1((u32)sport->port.membase)&USR1_RTSS; @@ -198,7 +198,7 @@ static irqreturn_t imx_rtsint(int irq, void *dev_id) return IRQ_HANDLED; } -static irqreturn_t imx_txint(int irq, void *dev_id) +static irqreturn_t imx_txint(int irq, void *dev_id, struct pt_regs *regs) { struct imx_port *sport = (struct imx_port *)dev_id; struct circ_buf *xmit = &sport->port.info->xmit; @@ -227,7 +227,7 @@ static irqreturn_t imx_txint(int irq, void *dev_id) return IRQ_HANDLED; } -static irqreturn_t imx_rxint(int irq, void *dev_id) +static irqreturn_t imx_rxint(int irq, void *dev_id, struct pt_regs *regs) { struct imx_port *sport = dev_id; unsigned int rx,flg,ignored = 0; @@ -248,7 +248,7 @@ static irqreturn_t imx_rxint(int irq, void *dev_id) } if (uart_handle_sysrq_char - (&sport->port, (unsigned char)rx)) + (&sport->port, (unsigned char)rx, regs)) goto ignore_char; if( rx & (URXD_PRERR | URXD_OVRRUN | URXD_FRMERR) ) diff --git a/trunk/drivers/serial/ioc3_serial.c b/trunk/drivers/serial/ioc3_serial.c index 2308d26c8629..8097cd91f16b 100644 --- a/trunk/drivers/serial/ioc3_serial.c +++ b/trunk/drivers/serial/ioc3_serial.c @@ -1428,12 +1428,13 @@ static int receive_chars(struct uart_port *the_port) * @is : submodule * @idd: driver data * @pending: interrupts to handle + * @regs: pt_regs */ static int inline ioc3uart_intr_one(struct ioc3_submodule *is, struct ioc3_driver_data *idd, - unsigned int pending) + unsigned int pending, struct pt_regs *regs) { int port_num = GET_PORT_FROM_SIO_IR(pending); struct port_hooks *hooks; @@ -1627,12 +1628,13 @@ ioc3uart_intr_one(struct ioc3_submodule *is, * @is : submodule * @idd: driver data * @pending: interrupts to handle + * @regs: pt_regs * */ static int ioc3uart_intr(struct ioc3_submodule *is, struct ioc3_driver_data *idd, - unsigned int pending) + unsigned int pending, struct pt_regs *regs) { int ret = 0; @@ -1642,9 +1644,9 @@ static int ioc3uart_intr(struct ioc3_submodule *is, */ if (pending & SIO_IR_SA) - ret |= ioc3uart_intr_one(is, idd, pending & SIO_IR_SA); + ret |= ioc3uart_intr_one(is, idd, pending & SIO_IR_SA, regs); if (pending & SIO_IR_SB) - ret |= ioc3uart_intr_one(is, idd, pending & SIO_IR_SB); + ret |= ioc3uart_intr_one(is, idd, pending & SIO_IR_SB, regs); return ret; } diff --git a/trunk/drivers/serial/ioc4_serial.c b/trunk/drivers/serial/ioc4_serial.c index 711bd1511439..5ec4716c99bf 100644 --- a/trunk/drivers/serial/ioc4_serial.c +++ b/trunk/drivers/serial/ioc4_serial.c @@ -921,7 +921,7 @@ static void handle_dma_error_intr(void *arg, uint32_t other_ir) { struct ioc4_port *port = (struct ioc4_port *)arg; struct hooks *hooks = port->ip_hooks; - unsigned long flags; + unsigned int flags; spin_lock_irqsave(&port->ip_lock, flags); @@ -987,9 +987,10 @@ intr_connect(struct ioc4_soft *soft, int type, * ioc4_intr - Top level IOC4 interrupt handler. * @irq: irq value * @arg: handler arg + * @regs: registers */ -static irqreturn_t ioc4_intr(int irq, void *arg) +static irqreturn_t ioc4_intr(int irq, void *arg, struct pt_regs *regs) { struct ioc4_soft *soft; uint32_t this_ir, this_mir; @@ -1834,7 +1835,7 @@ static void handle_intr(void *arg, uint32_t sio_ir) struct ioc4_port *port = (struct ioc4_port *)arg; struct hooks *hooks = port->ip_hooks; unsigned int rx_high_rd_aborted = 0; - unsigned long flags; + unsigned int flags; struct uart_port *the_port; int loop_counter; @@ -2935,7 +2936,7 @@ static void __devexit ioc4_serial_exit(void) uart_unregister_driver(&ioc4_uart_rs422); } -late_initcall(ioc4_serial_init); /* Call only after tty init is done */ +module_init(ioc4_serial_init); module_exit(ioc4_serial_exit); MODULE_AUTHOR("Pat Gefre - Silicon Graphics Inc. (SGI) "); diff --git a/trunk/drivers/serial/ip22zilog.c b/trunk/drivers/serial/ip22zilog.c index dca6c1bde8f9..dbf13c03a1bb 100644 --- a/trunk/drivers/serial/ip22zilog.c +++ b/trunk/drivers/serial/ip22zilog.c @@ -252,7 +252,8 @@ static void ip22zilog_maybe_update_regs(struct uart_ip22zilog_port *up, } static void ip22zilog_receive_chars(struct uart_ip22zilog_port *up, - struct zilog_channel *channel) + struct zilog_channel *channel, + struct pt_regs *regs) { struct tty_struct *tty = up->port.info->tty; /* XXX info==NULL? */ @@ -318,7 +319,7 @@ static void ip22zilog_receive_chars(struct uart_ip22zilog_port *up, else if (r1 & CRC_ERR) flag = TTY_FRAME; } - if (uart_handle_sysrq_char(&up->port, ch)) + if (uart_handle_sysrq_char(&up->port, ch, regs)) goto next_char; if (up->port.ignore_status_mask == 0xff || @@ -338,7 +339,8 @@ static void ip22zilog_receive_chars(struct uart_ip22zilog_port *up, } static void ip22zilog_status_handle(struct uart_ip22zilog_port *up, - struct zilog_channel *channel) + struct zilog_channel *channel, + struct pt_regs *regs) { unsigned char status; @@ -441,7 +443,7 @@ static void ip22zilog_transmit_chars(struct uart_ip22zilog_port *up, ZS_WSYNC(channel); } -static irqreturn_t ip22zilog_interrupt(int irq, void *dev_id) +static irqreturn_t ip22zilog_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct uart_ip22zilog_port *up = dev_id; @@ -460,9 +462,9 @@ static irqreturn_t ip22zilog_interrupt(int irq, void *dev_id) ZS_WSYNC(channel); if (r3 & CHARxIP) - ip22zilog_receive_chars(up, channel); + ip22zilog_receive_chars(up, channel, regs); if (r3 & CHAEXT) - ip22zilog_status_handle(up, channel); + ip22zilog_status_handle(up, channel, regs); if (r3 & CHATxIP) ip22zilog_transmit_chars(up, channel); } @@ -479,9 +481,9 @@ static irqreturn_t ip22zilog_interrupt(int irq, void *dev_id) ZS_WSYNC(channel); if (r3 & CHBRxIP) - ip22zilog_receive_chars(up, channel); + ip22zilog_receive_chars(up, channel, regs); if (r3 & CHBEXT) - ip22zilog_status_handle(up, channel); + ip22zilog_status_handle(up, channel, regs); if (r3 & CHBTxIP) ip22zilog_transmit_chars(up, channel); } diff --git a/trunk/drivers/serial/jsm/jsm.h b/trunk/drivers/serial/jsm/jsm.h index 12c934a1f274..043f50b1d10c 100644 --- a/trunk/drivers/serial/jsm/jsm.h +++ b/trunk/drivers/serial/jsm/jsm.h @@ -99,7 +99,7 @@ struct jsm_channel; * Per board operations structure * ************************************************************************/ struct board_ops { - irq_handler_t intr; + irqreturn_t (*intr) (int irq, void *voidbrd, struct pt_regs *regs); void (*uart_init) (struct jsm_channel *ch); void (*uart_off) (struct jsm_channel *ch); void (*param) (struct jsm_channel *ch); diff --git a/trunk/drivers/serial/jsm/jsm_neo.c b/trunk/drivers/serial/jsm/jsm_neo.c index 8be8da37f629..a5fc589d6ef5 100644 --- a/trunk/drivers/serial/jsm/jsm_neo.c +++ b/trunk/drivers/serial/jsm/jsm_neo.c @@ -1114,9 +1114,9 @@ static void neo_param(struct jsm_channel *ch) * * Neo specific interrupt handler. */ -static irqreturn_t neo_intr(int irq, void *voidbrd) +static irqreturn_t neo_intr(int irq, void *voidbrd, struct pt_regs *regs) { - struct jsm_board *brd = voidbrd; + struct jsm_board *brd = (struct jsm_board *) voidbrd; struct jsm_channel *ch; int port = 0; int type = 0; diff --git a/trunk/drivers/serial/m32r_sio.c b/trunk/drivers/serial/m32r_sio.c index 7656a35f5e2f..28c9ce6f0bdc 100644 --- a/trunk/drivers/serial/m32r_sio.c +++ b/trunk/drivers/serial/m32r_sio.c @@ -323,7 +323,8 @@ static void m32r_sio_enable_ms(struct uart_port *port) serial_out(up, UART_IER, up->ier); } -static void receive_chars(struct uart_sio_port *up, int *status) +static void receive_chars(struct uart_sio_port *up, int *status, + struct pt_regs *regs) { struct tty_struct *tty = up->port.info->tty; unsigned char ch; @@ -377,7 +378,7 @@ static void receive_chars(struct uart_sio_port *up, int *status) else if (*status & UART_LSR_FE) flag = TTY_FRAME; } - if (uart_handle_sysrq_char(&up->port, ch)) + if (uart_handle_sysrq_char(&up->port, ch, regs)) goto ignore_char; if ((*status & up->port.ignore_status_mask) == 0) tty_insert_flip_char(tty, ch, flag); @@ -438,12 +439,12 @@ static void transmit_chars(struct uart_sio_port *up) * This handles the interrupt from one port. */ static inline void m32r_sio_handle_port(struct uart_sio_port *up, - unsigned int status) + unsigned int status, struct pt_regs *regs) { DEBUG_INTR("status = %x...", status); if (status & 0x04) - receive_chars(up, &status); + receive_chars(up, &status, regs); if (status & 0x01) transmit_chars(up); } @@ -462,7 +463,8 @@ static inline void m32r_sio_handle_port(struct uart_sio_port *up, * This means we need to loop through all ports. checking that they * don't have an interrupt pending. */ -static irqreturn_t m32r_sio_interrupt(int irq, void *dev_id) +static irqreturn_t m32r_sio_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { struct irq_info *i = dev_id; struct list_head *l, *end = NULL; @@ -490,7 +492,7 @@ static irqreturn_t m32r_sio_interrupt(int irq, void *dev_id) sts = sio_in(up, SIOSTS); if (sts & 0x5) { spin_lock(&up->port.lock); - m32r_sio_handle_port(up, sts); + m32r_sio_handle_port(up, sts, regs); spin_unlock(&up->port.lock); end = NULL; @@ -590,7 +592,7 @@ static void m32r_sio_timeout(unsigned long data) sts = sio_in(up, SIOSTS); if (sts & 0x5) { spin_lock(&up->port.lock); - m32r_sio_handle_port(up, sts); + m32r_sio_handle_port(up, sts, NULL); spin_unlock(&up->port.lock); } diff --git a/trunk/drivers/serial/mcfserial.c b/trunk/drivers/serial/mcfserial.c index aee1b31f1a1c..00d7859c167e 100644 --- a/trunk/drivers/serial/mcfserial.c +++ b/trunk/drivers/serial/mcfserial.c @@ -385,7 +385,7 @@ static inline void transmit_chars(struct mcf_serial *info) /* * This is the serial driver's generic interrupt routine */ -irqreturn_t mcfrs_interrupt(int irq, void *dev_id) +irqreturn_t mcfrs_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct mcf_serial *info; unsigned char isr; diff --git a/trunk/drivers/serial/mpc52xx_uart.c b/trunk/drivers/serial/mpc52xx_uart.c index 4f80c5b4a753..dbad0e31e005 100644 --- a/trunk/drivers/serial/mpc52xx_uart.c +++ b/trunk/drivers/serial/mpc52xx_uart.c @@ -85,7 +85,7 @@ static struct uart_port mpc52xx_uart_ports[MPC52xx_PSC_MAXNUM]; /* Forward declaration of the interruption handling routine */ -static irqreturn_t mpc52xx_uart_int(int irq,void *dev_id); +static irqreturn_t mpc52xx_uart_int(int irq,void *dev_id,struct pt_regs *regs); /* Simple macro to test if a port is console or not. This one is taken @@ -410,7 +410,7 @@ static struct uart_ops mpc52xx_uart_ops = { /* ======================================================================== */ static inline int -mpc52xx_uart_int_rx_chars(struct uart_port *port) +mpc52xx_uart_int_rx_chars(struct uart_port *port, struct pt_regs *regs) { struct tty_struct *tty = port->info->tty; unsigned char ch, flag; @@ -425,7 +425,7 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port) /* Handle sysreq char */ #ifdef SUPPORT_SYSRQ - if (uart_handle_sysrq_char(port, ch)) { + if (uart_handle_sysrq_char(port, ch, regs)) { port->sysrq = 0; continue; } @@ -510,13 +510,21 @@ mpc52xx_uart_int_tx_chars(struct uart_port *port) } static irqreturn_t -mpc52xx_uart_int(int irq, void *dev_id) +mpc52xx_uart_int(int irq, void *dev_id, struct pt_regs *regs) { - struct uart_port *port = dev_id; + struct uart_port *port = (struct uart_port *) dev_id; unsigned long pass = ISR_PASS_LIMIT; unsigned int keepgoing; unsigned short status; + if ( irq != port->irq ) { + printk( KERN_WARNING + "mpc52xx_uart_int : " \ + "Received wrong int %d. Waiting for %d\n", + irq, port->irq); + return IRQ_NONE; + } + spin_lock(&port->lock); /* While we have stuff to do, we continue */ @@ -531,7 +539,7 @@ mpc52xx_uart_int(int irq, void *dev_id) /* Do we need to receive chars ? */ /* For this RX interrupts must be on and some chars waiting */ if ( status & MPC52xx_PSC_IMR_RXRDY ) - keepgoing |= mpc52xx_uart_int_rx_chars(port); + keepgoing |= mpc52xx_uart_int_rx_chars(port, regs); /* Do we need to send chars ? */ /* For this, TX must be ready and TX interrupt enabled */ diff --git a/trunk/drivers/serial/mpsc.c b/trunk/drivers/serial/mpsc.c index 8eea69f29989..704243c9f78a 100644 --- a/trunk/drivers/serial/mpsc.c +++ b/trunk/drivers/serial/mpsc.c @@ -992,7 +992,7 @@ mpsc_make_ready(struct mpsc_port_info *pi) */ static inline int -mpsc_rx_intr(struct mpsc_port_info *pi) +mpsc_rx_intr(struct mpsc_port_info *pi, struct pt_regs *regs) { struct mpsc_rx_desc *rxre; struct tty_struct *tty = pi->port.info->tty; @@ -1072,7 +1072,7 @@ mpsc_rx_intr(struct mpsc_port_info *pi) flag = TTY_PARITY; } - if (uart_handle_sysrq_char(&pi->port, *bp)) { + if (uart_handle_sysrq_char(&pi->port, *bp, regs)) { bp++; bytes_in--; goto next_frame; @@ -1257,7 +1257,7 @@ mpsc_tx_intr(struct mpsc_port_info *pi) * handling those descriptors, we restart the Rx/Tx engines if they're stopped. */ static irqreturn_t -mpsc_sdma_intr(int irq, void *dev_id) +mpsc_sdma_intr(int irq, void *dev_id, struct pt_regs *regs) { struct mpsc_port_info *pi = dev_id; ulong iflags; @@ -1267,7 +1267,7 @@ mpsc_sdma_intr(int irq, void *dev_id) spin_lock_irqsave(&pi->port.lock, iflags); mpsc_sdma_intr_ack(pi); - if (mpsc_rx_intr(pi)) + if (mpsc_rx_intr(pi, regs)) rc = IRQ_HANDLED; if (mpsc_tx_intr(pi)) rc = IRQ_HANDLED; diff --git a/trunk/drivers/serial/mux.c b/trunk/drivers/serial/mux.c index 8ad1b8c5ec5d..aa819d3f8ee5 100644 --- a/trunk/drivers/serial/mux.c +++ b/trunk/drivers/serial/mux.c @@ -230,7 +230,7 @@ static void mux_read(struct uart_port *port) continue; } - if (uart_handle_sysrq_char(port, data & 0xffu)) + if (uart_handle_sysrq_char(port, data & 0xffu, NULL)) continue; tty_insert_flip_char(tty, data & 0xFF, TTY_NORMAL); diff --git a/trunk/drivers/serial/netx-serial.c b/trunk/drivers/serial/netx-serial.c index 062bad457b1a..7502109d37f0 100644 --- a/trunk/drivers/serial/netx-serial.c +++ b/trunk/drivers/serial/netx-serial.c @@ -200,7 +200,7 @@ static void netx_txint(struct uart_port *port) uart_write_wakeup(port); } -static void netx_rxint(struct uart_port *port) +static void netx_rxint(struct uart_port *port, struct pt_regs *regs) { unsigned char rx, flg, status; struct tty_struct *tty = port->info->tty; @@ -235,7 +235,7 @@ static void netx_rxint(struct uart_port *port) flg = TTY_FRAME; } - if (uart_handle_sysrq_char(port, rx)) + if (uart_handle_sysrq_char(port, rx, regs)) continue; uart_insert_char(port, status, SR_OE, rx, flg); @@ -245,9 +245,9 @@ static void netx_rxint(struct uart_port *port) return; } -static irqreturn_t netx_int(int irq, void *dev_id) +static irqreturn_t netx_int(int irq, void *dev_id, struct pt_regs *regs) { - struct uart_port *port = dev_id; + struct uart_port *port = (struct uart_port *)dev_id; unsigned long flags; unsigned char status; @@ -256,7 +256,7 @@ static irqreturn_t netx_int(int irq, void *dev_id) status = readl(port->membase + UART_IIR) & IIR_MASK; while (status) { if (status & IIR_RIS) - netx_rxint(port); + netx_rxint(port, regs); if (status & IIR_TIS) netx_txint(port); if (status & IIR_MIS) { diff --git a/trunk/drivers/serial/pmac_zilog.c b/trunk/drivers/serial/pmac_zilog.c index bf9809ed9c0b..a3b99caf80e6 100644 --- a/trunk/drivers/serial/pmac_zilog.c +++ b/trunk/drivers/serial/pmac_zilog.c @@ -204,7 +204,8 @@ static void pmz_maybe_update_regs(struct uart_pmac_port *uap) } } -static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap) +static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap, + struct pt_regs *regs) { struct tty_struct *tty = NULL; unsigned char ch, r1, drop, error, flag; @@ -266,7 +267,7 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap) if (uap->port.sysrq) { int swallow; spin_unlock(&uap->port.lock); - swallow = uart_handle_sysrq_char(&uap->port, ch); + swallow = uart_handle_sysrq_char(&uap->port, ch, regs); spin_lock(&uap->port.lock); if (swallow) goto next_char; @@ -334,7 +335,7 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap) return tty; } -static void pmz_status_handle(struct uart_pmac_port *uap) +static void pmz_status_handle(struct uart_pmac_port *uap, struct pt_regs *regs) { unsigned char status; @@ -437,7 +438,7 @@ static void pmz_transmit_chars(struct uart_pmac_port *uap) } /* Hrm... we register that twice, fixme later.... */ -static irqreturn_t pmz_interrupt(int irq, void *dev_id) +static irqreturn_t pmz_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct uart_pmac_port *uap = dev_id; struct uart_pmac_port *uap_a; @@ -461,9 +462,9 @@ static irqreturn_t pmz_interrupt(int irq, void *dev_id) write_zsreg(uap_a, R0, RES_H_IUS); zssync(uap_a); if (r3 & CHAEXT) - pmz_status_handle(uap_a); + pmz_status_handle(uap_a, regs); if (r3 & CHARxIP) - tty = pmz_receive_chars(uap_a); + tty = pmz_receive_chars(uap_a, regs); if (r3 & CHATxIP) pmz_transmit_chars(uap_a); rc = IRQ_HANDLED; @@ -481,9 +482,9 @@ static irqreturn_t pmz_interrupt(int irq, void *dev_id) write_zsreg(uap_b, R0, RES_H_IUS); zssync(uap_b); if (r3 & CHBEXT) - pmz_status_handle(uap_b); + pmz_status_handle(uap_b, regs); if (r3 & CHBRxIP) - tty = pmz_receive_chars(uap_b); + tty = pmz_receive_chars(uap_b, regs); if (r3 & CHBTxIP) pmz_transmit_chars(uap_b); rc = IRQ_HANDLED; diff --git a/trunk/drivers/serial/pxa.c b/trunk/drivers/serial/pxa.c index 415fe9633a9b..a720953a404e 100644 --- a/trunk/drivers/serial/pxa.c +++ b/trunk/drivers/serial/pxa.c @@ -98,7 +98,8 @@ static void serial_pxa_stop_rx(struct uart_port *port) serial_out(up, UART_IER, up->ier); } -static inline void receive_chars(struct uart_pxa_port *up, int *status) +static inline void +receive_chars(struct uart_pxa_port *up, int *status, struct pt_regs *regs) { struct tty_struct *tty = up->port.info->tty; unsigned int ch, flag; @@ -152,7 +153,7 @@ static inline void receive_chars(struct uart_pxa_port *up, int *status) flag = TTY_FRAME; } - if (uart_handle_sysrq_char(&up->port, ch)) + if (uart_handle_sysrq_char(&up->port, ch, regs)) goto ignore_char; uart_insert_char(&up->port, *status, UART_LSR_OE, ch, flag); @@ -230,9 +231,10 @@ static inline void check_modem_status(struct uart_pxa_port *up) /* * This handles the interrupt from one port. */ -static inline irqreturn_t serial_pxa_irq(int irq, void *dev_id) +static inline irqreturn_t +serial_pxa_irq(int irq, void *dev_id, struct pt_regs *regs) { - struct uart_pxa_port *up = dev_id; + struct uart_pxa_port *up = (struct uart_pxa_port *)dev_id; unsigned int iir, lsr; iir = serial_in(up, UART_IIR); @@ -240,7 +242,7 @@ static inline irqreturn_t serial_pxa_irq(int irq, void *dev_id) return IRQ_NONE; lsr = serial_in(up, UART_LSR); if (lsr & UART_LSR_DR) - receive_chars(up, &lsr); + receive_chars(up, &lsr, regs); check_modem_status(up); if (lsr & UART_LSR_THRE) transmit_chars(up); diff --git a/trunk/drivers/serial/s3c2410.c b/trunk/drivers/serial/s3c2410.c index 8dfc2dd058ca..95738a19cde7 100644 --- a/trunk/drivers/serial/s3c2410.c +++ b/trunk/drivers/serial/s3c2410.c @@ -310,7 +310,7 @@ static int s3c24xx_serial_rx_fifocnt(struct s3c24xx_uart_port *ourport, #define S3C2410_UERSTAT_PARITY (0x1000) static irqreturn_t -s3c24xx_serial_rx_chars(int irq, void *dev_id) +s3c24xx_serial_rx_chars(int irq, void *dev_id, struct pt_regs *regs) { struct s3c24xx_uart_port *ourport = dev_id; struct uart_port *port = &ourport->port; @@ -379,7 +379,7 @@ s3c24xx_serial_rx_chars(int irq, void *dev_id) flag = TTY_FRAME; } - if (uart_handle_sysrq_char(port, ch)) + if (uart_handle_sysrq_char(port, ch, regs)) goto ignore_char; uart_insert_char(port, uerstat, S3C2410_UERSTAT_OVERRUN, ch, flag); @@ -393,7 +393,7 @@ s3c24xx_serial_rx_chars(int irq, void *dev_id) return IRQ_HANDLED; } -static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id) +static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id, struct pt_regs *regs) { struct s3c24xx_uart_port *ourport = id; struct uart_port *port = &ourport->port; diff --git a/trunk/drivers/serial/sa1100.c b/trunk/drivers/serial/sa1100.c index d4065266b6fc..db3486d33870 100644 --- a/trunk/drivers/serial/sa1100.c +++ b/trunk/drivers/serial/sa1100.c @@ -190,7 +190,7 @@ static void sa1100_enable_ms(struct uart_port *port) } static void -sa1100_rx_chars(struct sa1100_port *sport) +sa1100_rx_chars(struct sa1100_port *sport, struct pt_regs *regs) { struct tty_struct *tty = sport->port.info->tty; unsigned int status, ch, flg; @@ -228,7 +228,7 @@ sa1100_rx_chars(struct sa1100_port *sport) #endif } - if (uart_handle_sysrq_char(&sport->port, ch)) + if (uart_handle_sysrq_char(&sport->port, ch, regs)) goto ignore_char; uart_insert_char(&sport->port, status, UTSR1_TO_SM(UTSR1_ROR), ch, flg); @@ -281,7 +281,7 @@ static void sa1100_tx_chars(struct sa1100_port *sport) sa1100_stop_tx(&sport->port); } -static irqreturn_t sa1100_int(int irq, void *dev_id) +static irqreturn_t sa1100_int(int irq, void *dev_id, struct pt_regs *regs) { struct sa1100_port *sport = dev_id; unsigned int status, pass_counter = 0; @@ -294,7 +294,7 @@ static irqreturn_t sa1100_int(int irq, void *dev_id) /* Clear the receiver idle bit, if set */ if (status & UTSR0_RID) UART_PUT_UTSR0(sport, UTSR0_RID); - sa1100_rx_chars(sport); + sa1100_rx_chars(sport, regs); } /* Clear the relevant break bits */ diff --git a/trunk/drivers/serial/serial_lh7a40x.c b/trunk/drivers/serial/serial_lh7a40x.c index 5e1ac356bbb0..23ddedbaec08 100644 --- a/trunk/drivers/serial/serial_lh7a40x.c +++ b/trunk/drivers/serial/serial_lh7a40x.c @@ -135,7 +135,12 @@ static void lh7a40xuart_enable_ms (struct uart_port* port) BIT_SET (port, UART_R_INTEN, ModemInt); } -static void lh7a40xuart_rx_chars (struct uart_port* port) +static void +#ifdef SUPPORT_SYSRQ +lh7a40xuart_rx_chars (struct uart_port* port, struct pt_regs* regs) +#else +lh7a40xuart_rx_chars (struct uart_port* port) +#endif { struct tty_struct* tty = port->info->tty; int cbRxMax = 256; /* (Gross) limit on receive */ @@ -172,7 +177,7 @@ static void lh7a40xuart_rx_chars (struct uart_port* port) flag = TTY_FRAME; } - if (uart_handle_sysrq_char (port, (unsigned char) data)) + if (uart_handle_sysrq_char (port, (unsigned char) data, regs)) continue; uart_insert_char(port, data, RxOverrunError, data, flag); @@ -243,7 +248,8 @@ static void lh7a40xuart_modem_status (struct uart_port* port) wake_up_interruptible (&port->info->delta_msr_wait); } -static irqreturn_t lh7a40xuart_int (int irq, void* dev_id) +static irqreturn_t lh7a40xuart_int (int irq, void* dev_id, + struct pt_regs* regs) { struct uart_port* port = dev_id; unsigned int cLoopLimit = ISR_LOOP_LIMIT; @@ -252,7 +258,11 @@ static irqreturn_t lh7a40xuart_int (int irq, void* dev_id) do { if (isr & (RxInt | RxTimeoutInt)) +#ifdef SUPPORT_SYSRQ + lh7a40xuart_rx_chars(port, regs); +#else lh7a40xuart_rx_chars(port); +#endif if (isr & ModemInt) lh7a40xuart_modem_status (port); if (isr & TxInt) diff --git a/trunk/drivers/serial/serial_txx9.c b/trunk/drivers/serial/serial_txx9.c index 2a48289ac722..ebd8d2bb17fd 100644 --- a/trunk/drivers/serial/serial_txx9.c +++ b/trunk/drivers/serial/serial_txx9.c @@ -283,7 +283,7 @@ static void serial_txx9_enable_ms(struct uart_port *port) } static inline void -receive_chars(struct uart_txx9_port *up, unsigned int *status) +receive_chars(struct uart_txx9_port *up, unsigned int *status, struct pt_regs *regs) { struct tty_struct *tty = up->port.info->tty; unsigned char ch; @@ -344,7 +344,7 @@ receive_chars(struct uart_txx9_port *up, unsigned int *status) else if (disr & TXX9_SIDISR_UFER) flag = TTY_FRAME; } - if (uart_handle_sysrq_char(&up->port, ch)) + if (uart_handle_sysrq_char(&up->port, ch, regs)) goto ignore_char; uart_insert_char(&up->port, disr, TXX9_SIDISR_UOER, ch, flag); @@ -391,7 +391,7 @@ static inline void transmit_chars(struct uart_txx9_port *up) serial_txx9_stop_tx(&up->port); } -static irqreturn_t serial_txx9_interrupt(int irq, void *dev_id) +static irqreturn_t serial_txx9_interrupt(int irq, void *dev_id, struct pt_regs *regs) { int pass_counter = 0; struct uart_txx9_port *up = dev_id; @@ -409,7 +409,7 @@ static irqreturn_t serial_txx9_interrupt(int irq, void *dev_id) } if (status & TXX9_SIDISR_RDIS) - receive_chars(up, &status); + receive_chars(up, &status, regs); if (status & TXX9_SIDISR_TDIS) transmit_chars(up); /* Clear TX/RX Int. Status */ diff --git a/trunk/drivers/serial/sh-sci.c b/trunk/drivers/serial/sh-sci.c index cfcc3caf49d8..5c025d1190c1 100644 --- a/trunk/drivers/serial/sh-sci.c +++ b/trunk/drivers/serial/sh-sci.c @@ -446,7 +446,8 @@ static void sci_transmit_chars(struct uart_port *port) /* On SH3, SCIF may read end-of-break as a space->mark char */ #define STEPFN(c) ({int __c=(c); (((__c-1)|(__c)) == -1); }) -static inline void sci_receive_chars(struct uart_port *port) +static inline void sci_receive_chars(struct uart_port *port, + struct pt_regs *regs) { struct sci_port *sci_port = (struct sci_port *)port; struct tty_struct *tty = port->info->tty; @@ -475,7 +476,7 @@ static inline void sci_receive_chars(struct uart_port *port) if (port->type == PORT_SCI) { char c = sci_in(port, SCxRDR); - if (uart_handle_sysrq_char(port, c) || sci_port->break_flag) + if (uart_handle_sysrq_char(port, c, regs) || sci_port->break_flag) count = 0; else { tty_insert_flip_char(tty, c, TTY_NORMAL); @@ -503,7 +504,7 @@ static inline void sci_receive_chars(struct uart_port *port) } } #endif /* CONFIG_CPU_SH3 */ - if (uart_handle_sysrq_char(port, c)) { + if (uart_handle_sysrq_char(port, c, regs)) { count--; i--; continue; } @@ -651,18 +652,18 @@ static inline int sci_handle_breaks(struct uart_port *port) return copied; } -static irqreturn_t sci_rx_interrupt(int irq, void *port) +static irqreturn_t sci_rx_interrupt(int irq, void *port, struct pt_regs *regs) { /* I think sci_receive_chars has to be called irrespective * of whether the I_IXOFF is set, otherwise, how is the interrupt * to be disabled? */ - sci_receive_chars(port); + sci_receive_chars(port, regs); return IRQ_HANDLED; } -static irqreturn_t sci_tx_interrupt(int irq, void *ptr) +static irqreturn_t sci_tx_interrupt(int irq, void *ptr, struct pt_regs *regs) { struct uart_port *port = ptr; @@ -673,7 +674,7 @@ static irqreturn_t sci_tx_interrupt(int irq, void *ptr) return IRQ_HANDLED; } -static irqreturn_t sci_er_interrupt(int irq, void *ptr) +static irqreturn_t sci_er_interrupt(int irq, void *ptr, struct pt_regs *regs) { struct uart_port *port = ptr; @@ -695,18 +696,18 @@ static irqreturn_t sci_er_interrupt(int irq, void *ptr) pr_debug("scif: overrun error\n"); } #endif - sci_rx_interrupt(irq, ptr); + sci_rx_interrupt(irq, ptr, regs); } sci_out(port, SCxSR, SCxSR_ERROR_CLEAR(port)); /* Kick the transmission */ - sci_tx_interrupt(irq, ptr); + sci_tx_interrupt(irq, ptr, regs); return IRQ_HANDLED; } -static irqreturn_t sci_br_interrupt(int irq, void *ptr) +static irqreturn_t sci_br_interrupt(int irq, void *ptr, struct pt_regs *regs) { struct uart_port *port = ptr; @@ -723,7 +724,7 @@ static irqreturn_t sci_br_interrupt(int irq, void *ptr) return IRQ_HANDLED; } -static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr) +static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr, struct pt_regs *regs) { unsigned short ssr_status, scr_status; struct uart_port *port = ptr; @@ -733,16 +734,16 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr) /* Tx Interrupt */ if ((ssr_status & 0x0020) && (scr_status & 0x0080)) - sci_tx_interrupt(irq, ptr); + sci_tx_interrupt(irq, ptr, regs); /* Rx Interrupt */ if ((ssr_status & 0x0002) && (scr_status & 0x0040)) - sci_rx_interrupt(irq, ptr); + sci_rx_interrupt(irq, ptr, regs); /* Error Interrupt */ if ((ssr_status & 0x0080) && (scr_status & 0x0400)) - sci_er_interrupt(irq, ptr); + sci_er_interrupt(irq, ptr, regs); /* Break Interrupt */ if ((ssr_status & 0x0010) && (scr_status & 0x0200)) - sci_br_interrupt(irq, ptr); + sci_br_interrupt(irq, ptr, regs); return IRQ_HANDLED; } @@ -794,7 +795,7 @@ static struct notifier_block sci_nb = { &sci_notifier, NULL, 0 }; static int sci_request_irq(struct sci_port *port) { int i; - irqreturn_t (*handlers[4])(int irq, void *ptr) = { + irqreturn_t (*handlers[4])(int irq, void *ptr, struct pt_regs *regs) = { sci_er_interrupt, sci_rx_interrupt, sci_tx_interrupt, sci_br_interrupt, }; @@ -808,7 +809,7 @@ static int sci_request_irq(struct sci_port *port) } if (request_irq(port->irqs[0], sci_mpxed_interrupt, - IRQF_DISABLED, "sci", port)) { + SA_INTERRUPT, "sci", port)) { printk(KERN_ERR "sci: Cannot allocate irq.\n"); return -ENODEV; } @@ -817,7 +818,7 @@ static int sci_request_irq(struct sci_port *port) if (!port->irqs[i]) continue; if (request_irq(port->irqs[i], handlers[i], - IRQF_DISABLED, desc[i], port)) { + SA_INTERRUPT, desc[i], port)) { printk(KERN_ERR "sci: Cannot allocate irq.\n"); return -ENODEV; } diff --git a/trunk/drivers/serial/sn_console.c b/trunk/drivers/serial/sn_console.c index 956b2cf08e1e..2f148e5b9255 100644 --- a/trunk/drivers/serial/sn_console.c +++ b/trunk/drivers/serial/sn_console.c @@ -447,6 +447,7 @@ static int sn_debug_printf(const char *fmt, ...) /** * sn_receive_chars - Grab characters, pass them to tty layer * @port: Port to operate on + * @regs: Saved registers (needed by uart_handle_sysrq_char) * @flags: irq flags * * Note: If we're not registered with the serial core infrastructure yet, @@ -454,7 +455,8 @@ static int sn_debug_printf(const char *fmt, ...) * */ static void -sn_receive_chars(struct sn_cons_port *port, unsigned long flags) +sn_receive_chars(struct sn_cons_port *port, struct pt_regs *regs, + unsigned long flags) { int ch; struct tty_struct *tty; @@ -492,7 +494,7 @@ sn_receive_chars(struct sn_cons_port *port, unsigned long flags) sysrq_requested = 0; if (ch && time_before(jiffies, sysrq_timeout)) { spin_unlock_irqrestore(&port->sc_port.lock, flags); - handle_sysrq(ch, NULL); + handle_sysrq(ch, regs, NULL); spin_lock_irqsave(&port->sc_port.lock, flags); /* ignore actual sysrq command char */ continue; @@ -613,9 +615,10 @@ static void sn_transmit_chars(struct sn_cons_port *port, int raw) * sn_sal_interrupt - Handle console interrupts * @irq: irq #, useful for debug statements * @dev_id: our pointer to our port (sn_cons_port which contains the uart port) + * @regs: Saved registers, used by sn_receive_chars for uart_handle_sysrq_char * */ -static irqreturn_t sn_sal_interrupt(int irq, void *dev_id) +static irqreturn_t sn_sal_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct sn_cons_port *port = (struct sn_cons_port *)dev_id; unsigned long flags; @@ -626,7 +629,7 @@ static irqreturn_t sn_sal_interrupt(int irq, void *dev_id) spin_lock_irqsave(&port->sc_port.lock, flags); if (status & SAL_CONSOLE_INTR_RECV) { - sn_receive_chars(port, flags); + sn_receive_chars(port, regs, flags); } if (status & SAL_CONSOLE_INTR_XMIT) { sn_transmit_chars(port, TRANSMIT_BUFFERED); @@ -674,7 +677,7 @@ static void sn_sal_timer_poll(unsigned long data) if (!port->sc_port.irq) { spin_lock_irqsave(&port->sc_port.lock, flags); if (sn_process_input) - sn_receive_chars(port, flags); + sn_receive_chars(port, NULL, flags); sn_transmit_chars(port, TRANSMIT_RAW); spin_unlock_irqrestore(&port->sc_port.lock, flags); mod_timer(&port->sc_timer, diff --git a/trunk/drivers/serial/sunhv.c b/trunk/drivers/serial/sunhv.c index 03941d27d15d..f851f0f44f9b 100644 --- a/trunk/drivers/serial/sunhv.c +++ b/trunk/drivers/serial/sunhv.c @@ -73,7 +73,7 @@ static inline long hypervisor_con_putchar(long ch) static int hung_up = 0; -static struct tty_struct *receive_chars(struct uart_port *port) +static struct tty_struct *receive_chars(struct uart_port *port, struct pt_regs *regs) { struct tty_struct *tty = NULL; int saw_console_brk = 0; @@ -106,7 +106,7 @@ static struct tty_struct *receive_chars(struct uart_port *port) } if (tty == NULL) { - uart_handle_sysrq_char(port, c); + uart_handle_sysrq_char(port, c, regs); continue; } @@ -119,7 +119,7 @@ static struct tty_struct *receive_chars(struct uart_port *port) flag = TTY_BREAK; } - if (uart_handle_sysrq_char(port, c)) + if (uart_handle_sysrq_char(port, c, regs)) continue; if ((port->ignore_status_mask & IGNORE_ALL) || @@ -161,14 +161,14 @@ static void transmit_chars(struct uart_port *port) uart_write_wakeup(port); } -static irqreturn_t sunhv_interrupt(int irq, void *dev_id) +static irqreturn_t sunhv_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct uart_port *port = dev_id; struct tty_struct *tty; unsigned long flags; spin_lock_irqsave(&port->lock, flags); - tty = receive_chars(port); + tty = receive_chars(port, regs); transmit_chars(port); spin_unlock_irqrestore(&port->lock, flags); diff --git a/trunk/drivers/serial/sunsab.c b/trunk/drivers/serial/sunsab.c index 08a7cd6a3a0c..cfe20f730436 100644 --- a/trunk/drivers/serial/sunsab.c +++ b/trunk/drivers/serial/sunsab.c @@ -108,7 +108,8 @@ static __inline__ void sunsab_cec_wait(struct uart_sunsab_port *up) static struct tty_struct * receive_chars(struct uart_sunsab_port *up, - union sab82532_irq_status *stat) + union sab82532_irq_status *stat, + struct pt_regs *regs) { struct tty_struct *tty = NULL; unsigned char buf[32]; @@ -160,7 +161,7 @@ receive_chars(struct uart_sunsab_port *up, unsigned char ch = buf[i], flag; if (tty == NULL) { - uart_handle_sysrq_char(&up->port, ch); + uart_handle_sysrq_char(&up->port, ch, regs); continue; } @@ -207,7 +208,7 @@ receive_chars(struct uart_sunsab_port *up, flag = TTY_FRAME; } - if (uart_handle_sysrq_char(&up->port, ch)) + if (uart_handle_sysrq_char(&up->port, ch, regs)) continue; if ((stat->sreg.isr0 & (up->port.ignore_status_mask & 0xff)) == 0 && @@ -300,7 +301,7 @@ static void check_status(struct uart_sunsab_port *up, wake_up_interruptible(&up->port.info->delta_msr_wait); } -static irqreturn_t sunsab_interrupt(int irq, void *dev_id) +static irqreturn_t sunsab_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct uart_sunsab_port *up = dev_id; struct tty_struct *tty; @@ -320,7 +321,7 @@ static irqreturn_t sunsab_interrupt(int irq, void *dev_id) if ((status.sreg.isr0 & (SAB82532_ISR0_TCD | SAB82532_ISR0_TIME | SAB82532_ISR0_RFO | SAB82532_ISR0_RPF)) || (status.sreg.isr1 & SAB82532_ISR1_BRK)) - tty = receive_chars(up, &status); + tty = receive_chars(up, &status, regs); if ((status.sreg.isr0 & SAB82532_ISR0_CDSC) || (status.sreg.isr1 & SAB82532_ISR1_CSC)) check_status(up, &status); @@ -349,7 +350,7 @@ static irqreturn_t sunsab_interrupt(int irq, void *dev_id) SAB82532_ISR0_RFO | SAB82532_ISR0_RPF)) || (status.sreg.isr1 & SAB82532_ISR1_BRK)) - tty = receive_chars(up, &status); + tty = receive_chars(up, &status, regs); if ((status.sreg.isr0 & SAB82532_ISR0_CDSC) || (status.sreg.isr1 & (SAB82532_ISR1_BRK | SAB82532_ISR1_CSC))) check_status(up, &status); diff --git a/trunk/drivers/serial/sunsu.c b/trunk/drivers/serial/sunsu.c index c577faea60e8..9b3b9aaa6b90 100644 --- a/trunk/drivers/serial/sunsu.c +++ b/trunk/drivers/serial/sunsu.c @@ -310,7 +310,7 @@ static void sunsu_enable_ms(struct uart_port *port) } static struct tty_struct * -receive_chars(struct uart_sunsu_port *up, unsigned char *status) +receive_chars(struct uart_sunsu_port *up, unsigned char *status, struct pt_regs *regs) { struct tty_struct *tty = up->port.info->tty; unsigned char ch, flag; @@ -367,7 +367,7 @@ receive_chars(struct uart_sunsu_port *up, unsigned char *status) else if (*status & UART_LSR_FE) flag = TTY_FRAME; } - if (uart_handle_sysrq_char(&up->port, ch)) + if (uart_handle_sysrq_char(&up->port, ch, regs)) goto ignore_char; if ((*status & up->port.ignore_status_mask) == 0) tty_insert_flip_char(tty, ch, flag); @@ -445,7 +445,7 @@ static void check_modem_status(struct uart_sunsu_port *up) wake_up_interruptible(&up->port.info->delta_msr_wait); } -static irqreturn_t sunsu_serial_interrupt(int irq, void *dev_id) +static irqreturn_t sunsu_serial_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct uart_sunsu_port *up = dev_id; unsigned long flags; @@ -459,7 +459,7 @@ static irqreturn_t sunsu_serial_interrupt(int irq, void *dev_id) status = serial_inp(up, UART_LSR); tty = NULL; if (status & UART_LSR_DR) - tty = receive_chars(up, &status); + tty = receive_chars(up, &status, regs); check_modem_status(up); if (status & UART_LSR_THRE) transmit_chars(up); @@ -497,7 +497,7 @@ static void sunsu_change_mouse_baud(struct uart_sunsu_port *up) sunsu_change_speed(&up->port, up->cflag, 0, quot); } -static void receive_kbd_ms_chars(struct uart_sunsu_port *up, int is_break) +static void receive_kbd_ms_chars(struct uart_sunsu_port *up, struct pt_regs *regs, int is_break) { do { unsigned char ch = serial_inp(up, UART_RX); @@ -505,7 +505,7 @@ static void receive_kbd_ms_chars(struct uart_sunsu_port *up, int is_break) /* Stop-A is handled by drivers/char/keyboard.c now. */ if (up->su_type == SU_PORT_KBD) { #ifdef CONFIG_SERIO - serio_interrupt(&up->serio, ch, 0); + serio_interrupt(&up->serio, ch, 0, regs); #endif } else if (up->su_type == SU_PORT_MS) { int ret = suncore_mouse_baud_detection(ch, is_break); @@ -519,7 +519,7 @@ static void receive_kbd_ms_chars(struct uart_sunsu_port *up, int is_break) case 0: #ifdef CONFIG_SERIO - serio_interrupt(&up->serio, ch, 0); + serio_interrupt(&up->serio, ch, 0, regs); #endif break; }; @@ -527,7 +527,7 @@ static void receive_kbd_ms_chars(struct uart_sunsu_port *up, int is_break) } while (serial_in(up, UART_LSR) & UART_LSR_DR); } -static irqreturn_t sunsu_kbd_ms_interrupt(int irq, void *dev_id) +static irqreturn_t sunsu_kbd_ms_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct uart_sunsu_port *up = dev_id; @@ -535,7 +535,8 @@ static irqreturn_t sunsu_kbd_ms_interrupt(int irq, void *dev_id) unsigned char status = serial_inp(up, UART_LSR); if ((status & UART_LSR_DR) || (status & UART_LSR_BI)) - receive_kbd_ms_chars(up, (status & UART_LSR_BI) != 0); + receive_kbd_ms_chars(up, regs, + (status & UART_LSR_BI) != 0); } return IRQ_HANDLED; diff --git a/trunk/drivers/serial/sunzilog.c b/trunk/drivers/serial/sunzilog.c index b2cc703b2b9e..0da3ebfff82d 100644 --- a/trunk/drivers/serial/sunzilog.c +++ b/trunk/drivers/serial/sunzilog.c @@ -277,13 +277,14 @@ static void sunzilog_change_mouse_baud(struct uart_sunzilog_port *up) } static void sunzilog_kbdms_receive_chars(struct uart_sunzilog_port *up, - unsigned char ch, int is_break) + unsigned char ch, int is_break, + struct pt_regs *regs) { if (ZS_IS_KEYB(up)) { /* Stop-A is handled by drivers/char/keyboard.c now. */ #ifdef CONFIG_SERIO if (up->serio_open) - serio_interrupt(&up->serio, ch, 0); + serio_interrupt(&up->serio, ch, 0, regs); #endif } else if (ZS_IS_MOUSE(up)) { int ret = suncore_mouse_baud_detection(ch, is_break); @@ -298,7 +299,7 @@ static void sunzilog_kbdms_receive_chars(struct uart_sunzilog_port *up, case 0: #ifdef CONFIG_SERIO if (up->serio_open) - serio_interrupt(&up->serio, ch, 0); + serio_interrupt(&up->serio, ch, 0, regs); #endif break; }; @@ -307,7 +308,8 @@ static void sunzilog_kbdms_receive_chars(struct uart_sunzilog_port *up, static struct tty_struct * sunzilog_receive_chars(struct uart_sunzilog_port *up, - struct zilog_channel __iomem *channel) + struct zilog_channel __iomem *channel, + struct pt_regs *regs) { struct tty_struct *tty; unsigned char ch, r1, flag; @@ -344,12 +346,12 @@ sunzilog_receive_chars(struct uart_sunzilog_port *up, ch &= up->parity_mask; if (unlikely(ZS_IS_KEYB(up)) || unlikely(ZS_IS_MOUSE(up))) { - sunzilog_kbdms_receive_chars(up, ch, 0); + sunzilog_kbdms_receive_chars(up, ch, 0, regs); continue; } if (tty == NULL) { - uart_handle_sysrq_char(&up->port, ch); + uart_handle_sysrq_char(&up->port, ch, regs); continue; } @@ -377,7 +379,7 @@ sunzilog_receive_chars(struct uart_sunzilog_port *up, else if (r1 & CRC_ERR) flag = TTY_FRAME; } - if (uart_handle_sysrq_char(&up->port, ch)) + if (uart_handle_sysrq_char(&up->port, ch, regs)) continue; if (up->port.ignore_status_mask == 0xff || @@ -392,7 +394,8 @@ sunzilog_receive_chars(struct uart_sunzilog_port *up, } static void sunzilog_status_handle(struct uart_sunzilog_port *up, - struct zilog_channel __iomem *channel) + struct zilog_channel __iomem *channel, + struct pt_regs *regs) { unsigned char status; @@ -405,7 +408,7 @@ static void sunzilog_status_handle(struct uart_sunzilog_port *up, if (status & BRK_ABRT) { if (ZS_IS_MOUSE(up)) - sunzilog_kbdms_receive_chars(up, 0, 1); + sunzilog_kbdms_receive_chars(up, 0, 1, regs); if (ZS_IS_CONS(up)) { /* Wait for BREAK to deassert to avoid potentially * confusing the PROM. @@ -514,7 +517,7 @@ static void sunzilog_transmit_chars(struct uart_sunzilog_port *up, ZS_WSYNC(channel); } -static irqreturn_t sunzilog_interrupt(int irq, void *dev_id) +static irqreturn_t sunzilog_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct uart_sunzilog_port *up = dev_id; @@ -535,9 +538,9 @@ static irqreturn_t sunzilog_interrupt(int irq, void *dev_id) ZS_WSYNC(channel); if (r3 & CHARxIP) - tty = sunzilog_receive_chars(up, channel); + tty = sunzilog_receive_chars(up, channel, regs); if (r3 & CHAEXT) - sunzilog_status_handle(up, channel); + sunzilog_status_handle(up, channel, regs); if (r3 & CHATxIP) sunzilog_transmit_chars(up, channel); } @@ -558,9 +561,9 @@ static irqreturn_t sunzilog_interrupt(int irq, void *dev_id) ZS_WSYNC(channel); if (r3 & CHBRxIP) - tty = sunzilog_receive_chars(up, channel); + tty = sunzilog_receive_chars(up, channel, regs); if (r3 & CHBEXT) - sunzilog_status_handle(up, channel); + sunzilog_status_handle(up, channel, regs); if (r3 & CHBTxIP) sunzilog_transmit_chars(up, channel); } @@ -1057,7 +1060,7 @@ static void sunzilog_free_tables(void) static void sunzilog_putchar(struct uart_port *port, int ch) { - struct zilog_channel __iomem *channel = ZILOG_CHANNEL_FROM_PORT(port); + struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(port); int loops = ZS_PUT_CHAR_MAX_DELAY; /* This is a timed polling loop so do not switch the explicit @@ -1182,7 +1185,7 @@ static int __init sunzilog_console_setup(struct console *con, char *options) return 0; } -static struct console sunzilog_console_ops = { +static struct console sunzilog_console = { .name = "ttyS", .write = sunzilog_console_write, .device = uart_console_device, @@ -1208,10 +1211,10 @@ static inline struct console *SUNZILOG_CONSOLE(void) if (i == NUM_CHANNELS) return NULL; - sunzilog_console_ops.index = i; + sunzilog_console.index = i; sunzilog_port_table[i].flags |= SUNZILOG_FLAG_IS_CONS; - return &sunzilog_console_ops; + return &sunzilog_console; } #else diff --git a/trunk/drivers/serial/v850e_uart.c b/trunk/drivers/serial/v850e_uart.c index 28f3bbff87bf..f802867c95c5 100644 --- a/trunk/drivers/serial/v850e_uart.c +++ b/trunk/drivers/serial/v850e_uart.c @@ -271,14 +271,14 @@ void v850e_uart_tx (struct uart_port *port) v850e_uart_stop_tx (port, stopped); } -static irqreturn_t v850e_uart_tx_irq(int irq, void *data) +static irqreturn_t v850e_uart_tx_irq(int irq, void *data, struct pt_regs *regs) { struct uart_port *port = data; v850e_uart_tx (port); return IRQ_HANDLED; } -static irqreturn_t v850e_uart_rx_irq(int irq, void *data) +static irqreturn_t v850e_uart_rx_irq(int irq, void *data, struct pt_regs *regs) { struct uart_port *port = data; unsigned ch_stat = TTY_NORMAL; diff --git a/trunk/drivers/serial/vr41xx_siu.c b/trunk/drivers/serial/vr41xx_siu.c index fd51f8182dec..6c8b0ea83c3c 100644 --- a/trunk/drivers/serial/vr41xx_siu.c +++ b/trunk/drivers/serial/vr41xx_siu.c @@ -359,7 +359,8 @@ static void siu_break_ctl(struct uart_port *port, int ctl) spin_unlock_irqrestore(&port->lock, flags); } -static inline void receive_chars(struct uart_port *port, uint8_t *status) +static inline void receive_chars(struct uart_port *port, uint8_t *status, + struct pt_regs *regs) { struct tty_struct *tty; uint8_t lsr, ch; @@ -404,7 +405,7 @@ static inline void receive_chars(struct uart_port *port, uint8_t *status) flag = TTY_PARITY; } - if (uart_handle_sysrq_char(port, ch)) + if (uart_handle_sysrq_char(port, ch, regs)) goto ignore_char; uart_insert_char(port, lsr, UART_LSR_OE, ch, flag); @@ -471,7 +472,7 @@ static inline void transmit_chars(struct uart_port *port) siu_stop_tx(port); } -static irqreturn_t siu_interrupt(int irq, void *dev_id) +static irqreturn_t siu_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct uart_port *port; uint8_t iir, lsr; @@ -484,7 +485,7 @@ static irqreturn_t siu_interrupt(int irq, void *dev_id) lsr = siu_read(port, UART_LSR); if (lsr & UART_LSR_DR) - receive_chars(port, &lsr); + receive_chars(port, &lsr, regs); check_modem_status(port); diff --git a/trunk/drivers/sn/Kconfig b/trunk/drivers/sn/Kconfig index c66ba9ad833d..a34731625877 100644 --- a/trunk/drivers/sn/Kconfig +++ b/trunk/drivers/sn/Kconfig @@ -5,6 +5,19 @@ menu "SN Devices" depends on SGI_SN +config SGI_IOC4 + tristate "SGI IOC4 Base IO support" + depends on MMTIMER + default m + ---help--- + This option enables basic support for the SGI IOC4-based Base IO + controller card. This option does not enable any specific + functions on such a card, but provides necessary infrastructure + for other drivers to utilize. + + If you have an SGI Altix with an IOC4-based + I/O controller say Y. Otherwise say N. + config SGI_IOC3 tristate "SGI IOC3 Base IO support" default m diff --git a/trunk/drivers/sn/Makefile b/trunk/drivers/sn/Makefile index 693db8bb8d9c..2cda011597c0 100644 --- a/trunk/drivers/sn/Makefile +++ b/trunk/drivers/sn/Makefile @@ -3,4 +3,5 @@ # # +obj-$(CONFIG_SGI_IOC4) += ioc4.o obj-$(CONFIG_SGI_IOC3) += ioc3.o diff --git a/trunk/drivers/sn/ioc3.c b/trunk/drivers/sn/ioc3.c index cd6b65333b71..6c7e0352d561 100644 --- a/trunk/drivers/sn/ioc3.c +++ b/trunk/drivers/sn/ioc3.c @@ -398,10 +398,10 @@ static inline uint32_t get_pending_intrs(struct ioc3_driver_data *idd) return intrs; } -static irqreturn_t ioc3_intr_io(int irq, void *arg) +static irqreturn_t ioc3_intr_io(int irq, void *arg, struct pt_regs *regs) { unsigned long flags; - struct ioc3_driver_data *idd = arg; + struct ioc3_driver_data *idd = (struct ioc3_driver_data *)arg; int handled = 1, id; unsigned int pending; @@ -412,7 +412,7 @@ static irqreturn_t ioc3_intr_io(int irq, void *arg) if(ioc3_ethernet && idd->active[ioc3_ethernet->id] && ioc3_ethernet->intr) { handled = handled && !ioc3_ethernet->intr(ioc3_ethernet, - idd, 0); + idd, 0, regs); } } pending = get_pending_intrs(idd); /* look at the IO IRQs */ @@ -424,7 +424,8 @@ static irqreturn_t ioc3_intr_io(int irq, void *arg) write_ireg(idd, ioc3_submodules[id]->irq_mask, IOC3_W_IEC); if(!ioc3_submodules[id]->intr(ioc3_submodules[id], - idd, pending & ioc3_submodules[id]->irq_mask)) + idd, pending & ioc3_submodules[id]->irq_mask, + regs)) pending &= ~ioc3_submodules[id]->irq_mask; if (ioc3_submodules[id]->reset_mask) write_ireg(idd, ioc3_submodules[id]->irq_mask, @@ -441,7 +442,7 @@ static irqreturn_t ioc3_intr_io(int irq, void *arg) return handled?IRQ_HANDLED:IRQ_NONE; } -static irqreturn_t ioc3_intr_eth(int irq, void *arg) +static irqreturn_t ioc3_intr_eth(int irq, void *arg, struct pt_regs *regs) { unsigned long flags; struct ioc3_driver_data *idd = (struct ioc3_driver_data *)arg; @@ -452,7 +453,8 @@ static irqreturn_t ioc3_intr_eth(int irq, void *arg) read_lock_irqsave(&ioc3_submodules_lock, flags); if(ioc3_ethernet && idd->active[ioc3_ethernet->id] && ioc3_ethernet->intr) - handled = handled && !ioc3_ethernet->intr(ioc3_ethernet, idd, 0); + handled = handled && !ioc3_ethernet->intr(ioc3_ethernet, idd, 0, + regs); read_unlock_irqrestore(&ioc3_submodules_lock, flags); return handled?IRQ_HANDLED:IRQ_NONE; } diff --git a/trunk/drivers/misc/ioc4.c b/trunk/drivers/sn/ioc4.c similarity index 92% rename from trunk/drivers/misc/ioc4.c rename to trunk/drivers/sn/ioc4.c index b995a15b7526..8562821e6498 100644 --- a/trunk/drivers/misc/ioc4.c +++ b/trunk/drivers/sn/ioc4.c @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2005-2006 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (C) 2005 Silicon Graphics, Inc. All Rights Reserved. */ /* This file contains the master driver module for use by SGI IOC4 subdrivers. @@ -29,10 +29,12 @@ #include #include #include -#include +#include +#include #include -#include -#include +#include +#include +#include /*************** * Definitions * @@ -41,7 +43,7 @@ /* Tweakable values */ /* PCI bus speed detection/calibration */ -#define IOC4_CALIBRATE_COUNT 63 /* Calibration cycle period */ +#define IOC4_CALIBRATE_COUNT 63 /* Calibration cycle period */ #define IOC4_CALIBRATE_CYCLES 256 /* Average over this many cycles */ #define IOC4_CALIBRATE_DISCARD 2 /* Discard first few cycles */ #define IOC4_CALIBRATE_LOW_MHZ 25 /* Lower bound on bus speed sanity */ @@ -141,11 +143,11 @@ ioc4_unregister_submodule(struct ioc4_submodule *is) static void ioc4_clock_calibrate(struct ioc4_driver_data *idd) { + extern unsigned long sn_rtc_cycles_per_second; union ioc4_int_out int_out; union ioc4_gpcr gpcr; unsigned int state, last_state = 1; - struct timespec start_ts, end_ts; - uint64_t start, end, period; + uint64_t start = 0, end, period; unsigned int count = 0; /* Enable output */ @@ -173,28 +175,30 @@ ioc4_clock_calibrate(struct ioc4_driver_data *idd) if (!last_state && state) { count++; if (count == IOC4_CALIBRATE_END) { - ktime_get_ts(&end_ts); + end = rtc_time(); break; } else if (count == IOC4_CALIBRATE_DISCARD) - ktime_get_ts(&start_ts); + start = rtc_time(); } last_state = state; } while (1); /* Calculation rearranged to preserve intermediate precision. * Logically: - * 1. "end - start" gives us the measurement period over all - * the square wave cycles. - * 2. Divide by number of square wave cycles to get the period - * of a square wave cycle. + * 1. "end - start" gives us number of RTC cycles over all the + * square wave cycles measured. + * 2. Divide by number of square wave cycles to get number of + * RTC cycles per square wave cycle. * 3. Divide by 2*(int_out.fields.count+1), which is the formula * by which the IOC4 generates the square wave, to get the - * period of an IOC4 INT_OUT count. + * number of RTC cycles per IOC4 INT_OUT count. + * 4. Divide by sn_rtc_cycles_per_second to get seconds per + * count. + * 5. Multiply by 1E9 to get nanoseconds per count. */ - end = end_ts.tv_sec * NSEC_PER_SEC + end_ts.tv_nsec; - start = start_ts.tv_sec * NSEC_PER_SEC + start_ts.tv_nsec; - period = (end - start) / - (IOC4_CALIBRATE_CYCLES * 2 * (IOC4_CALIBRATE_COUNT + 1)); + period = ((end - start) * 1000000000) / + (IOC4_CALIBRATE_CYCLES * 2 * (IOC4_CALIBRATE_COUNT + 1) + * sn_rtc_cycles_per_second); /* Bounds check the result. */ if (period > IOC4_CALIBRATE_LOW_LIMIT || @@ -206,12 +210,10 @@ ioc4_clock_calibrate(struct ioc4_driver_data *idd) IOC4_CALIBRATE_DEFAULT / IOC4_EXTINT_COUNT_DIVISOR); period = IOC4_CALIBRATE_DEFAULT; } else { - u64 ns = period; - - do_div(ns, IOC4_EXTINT_COUNT_DIVISOR); printk(KERN_DEBUG - "IOC4 %s: PCI clock is %llu ns.\n", - pci_name(idd->idd_pdev), (unsigned long long)ns); + "IOC4 %s: PCI clock is %ld ns.\n", + pci_name(idd->idd_pdev), + period / IOC4_EXTINT_COUNT_DIVISOR); } /* Remember results. We store the extint clock period rather diff --git a/trunk/drivers/spi/Kconfig b/trunk/drivers/spi/Kconfig index d895a1adb428..23334c8bc4c7 100644 --- a/trunk/drivers/spi/Kconfig +++ b/trunk/drivers/spi/Kconfig @@ -16,7 +16,7 @@ config SPI controller and a chipselect. Most SPI slaves don't support dynamic device discovery; some are even write-only or read-only. - SPI is widely used by microcontrollers to talk with sensors, + SPI is widely used by microcontollers to talk with sensors, eeprom and flash memory, codecs and various other controller chips, analog to digital (and d-to-a) converters, and more. MMC and SD cards can be accessed using SPI protocol; and for diff --git a/trunk/drivers/spi/pxa2xx_spi.c b/trunk/drivers/spi/pxa2xx_spi.c index 72025df5561d..29aec77f98be 100644 --- a/trunk/drivers/spi/pxa2xx_spi.c +++ b/trunk/drivers/spi/pxa2xx_spi.c @@ -409,7 +409,7 @@ static int wait_dma_channel_stop(int channel) return limit; } -static void dma_handler(int channel, void *data) +static void dma_handler(int channel, void *data, struct pt_regs *regs) { struct driver_data *drv_data = data; struct spi_message *msg = drv_data->cur_msg; @@ -667,9 +667,9 @@ static irqreturn_t interrupt_transfer(struct driver_data *drv_data) return IRQ_HANDLED; } -static irqreturn_t ssp_int(int irq, void *dev_id) +static irqreturn_t ssp_int(int irq, void *dev_id, struct pt_regs *regs) { - struct driver_data *drv_data = dev_id; + struct driver_data *drv_data = (struct driver_data *)dev_id; void *reg = drv_data->ioaddr; if (!drv_data->cur_msg) { diff --git a/trunk/drivers/spi/spi.c b/trunk/drivers/spi/spi.c index c3c0626f550b..146298ad7371 100644 --- a/trunk/drivers/spi/spi.c +++ b/trunk/drivers/spi/spi.c @@ -281,6 +281,7 @@ spi_register_board_info(struct spi_board_info const *info, unsigned n) up(&board_lock); return 0; } +EXPORT_SYMBOL_GPL(spi_register_board_info); /* FIXME someone should add support for a __setup("spi", ...) that * creates board info from kernel command lines diff --git a/trunk/drivers/spi/spi_mpc83xx.c b/trunk/drivers/spi/spi_mpc83xx.c index ff0b04895db0..5d92a7e5cb41 100644 --- a/trunk/drivers/spi/spi_mpc83xx.c +++ b/trunk/drivers/spi/spi_mpc83xx.c @@ -296,7 +296,8 @@ static int mpc83xx_spi_bufs(struct spi_device *spi, struct spi_transfer *t) return t->len - mpc83xx_spi->count; } -irqreturn_t mpc83xx_spi_irq(s32 irq, void *context_data) +irqreturn_t mpc83xx_spi_irq(s32 irq, void *context_data, + struct pt_regs * ptregs) { struct mpc83xx_spi *mpc83xx_spi = context_data; u32 event; diff --git a/trunk/drivers/spi/spi_s3c24xx.c b/trunk/drivers/spi/spi_s3c24xx.c index 2ebe1fc4c398..20eb6e95a3a0 100644 --- a/trunk/drivers/spi/spi_s3c24xx.c +++ b/trunk/drivers/spi/spi_s3c24xx.c @@ -196,7 +196,7 @@ static int s3c24xx_spi_txrx(struct spi_device *spi, struct spi_transfer *t) return hw->count; } -static irqreturn_t s3c24xx_spi_irq(int irq, void *dev) +static irqreturn_t s3c24xx_spi_irq(int irq, void *dev, struct pt_regs *regs) { struct s3c24xx_spi *hw = dev; unsigned int spsta = readb(hw->regs + S3C2410_SPSTA); diff --git a/trunk/drivers/tc/zs.c b/trunk/drivers/tc/zs.c index 792becdfe6f8..622881f26761 100644 --- a/trunk/drivers/tc/zs.c +++ b/trunk/drivers/tc/zs.c @@ -347,7 +347,7 @@ static void rs_sched_event(struct dec_serial *info, int event) tasklet_schedule(&info->tlet); } -static void receive_chars(struct dec_serial *info) +static void receive_chars(struct dec_serial *info, struct pt_regs *regs) { struct tty_struct *tty = info->tty; unsigned char ch, stat, flag; @@ -389,7 +389,7 @@ static void receive_chars(struct dec_serial *info) if (ch == 0) continue; if (time_before(jiffies, break_pressed + HZ * 5)) { - handle_sysrq(ch, NULL); + handle_sysrq(ch, regs, NULL); break_pressed = 0; continue; } @@ -490,7 +490,7 @@ static void status_handle(struct dec_serial *info) /* * This is the serial driver's generic interrupt routine */ -static irqreturn_t rs_interrupt(int irq, void *dev_id) +static irqreturn_t rs_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct dec_serial *info = (struct dec_serial *) dev_id; irqreturn_t status = IRQ_NONE; @@ -518,7 +518,7 @@ static irqreturn_t rs_interrupt(int irq, void *dev_id) status = IRQ_HANDLED; if (zs_intreg & CHBRxIP) { - receive_chars(info); + receive_chars(info, regs); } if (zs_intreg & CHBTxIP) { transmit_chars(info); diff --git a/trunk/drivers/telephony/ixj.c b/trunk/drivers/telephony/ixj.c index 1b601b6cf2a2..f6b2948ab288 100644 --- a/trunk/drivers/telephony/ixj.c +++ b/trunk/drivers/telephony/ixj.c @@ -284,14 +284,6 @@ static int samplerate = 100; module_param(ixjdebug, int, 0); -static struct pci_device_id ixj_pci_tbl[] __devinitdata = { - { PCI_VENDOR_ID_QUICKNET, PCI_DEVICE_ID_QUICKNET_XJ, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { } -}; - -MODULE_DEVICE_TABLE(pci, ixj_pci_tbl); - /************************************************************************ * * ixjdebug meanings are now bit mapped instead of level based @@ -7691,8 +7683,7 @@ static int __init ixj_probe_pci(int *cnt) IXJ *j = NULL; for (i = 0; i < IXJMAX - *cnt; i++) { - pci = pci_find_device(PCI_VENDOR_ID_QUICKNET, - PCI_DEVICE_ID_QUICKNET_XJ, pci); + pci = pci_find_device(0x15E2, 0x0500, pci); if (!pci) break; diff --git a/trunk/drivers/telephony/ixj.h b/trunk/drivers/telephony/ixj.h index 8d69bcdc29c9..fbea4541c234 100644 --- a/trunk/drivers/telephony/ixj.h +++ b/trunk/drivers/telephony/ixj.h @@ -1295,7 +1295,7 @@ typedef struct { Proc_Info_Type Info_write; unsigned short frame_count; unsigned int filter_hist[4]; - unsigned char filter_en[6]; + unsigned char filter_en[4]; unsigned short proc_load; unsigned long framesread; unsigned long frameswritten; diff --git a/trunk/drivers/usb/Makefile b/trunk/drivers/usb/Makefile index 825bf884537a..97d57cfc343b 100644 --- a/trunk/drivers/usb/Makefile +++ b/trunk/drivers/usb/Makefile @@ -33,6 +33,7 @@ obj-$(CONFIG_USB_KBTAB) += input/ obj-$(CONFIG_USB_MOUSE) += input/ obj-$(CONFIG_USB_MTOUCH) += input/ obj-$(CONFIG_USB_POWERMATE) += input/ +obj-$(CONFIG_USB_TRANCEVIBRATOR)+= input/ obj-$(CONFIG_USB_WACOM) += input/ obj-$(CONFIG_USB_XPAD) += input/ @@ -65,7 +66,6 @@ obj-$(CONFIG_USB_PHIDGETSERVO) += misc/ obj-$(CONFIG_USB_RIO500) += misc/ obj-$(CONFIG_USB_SISUSBVGA) += misc/ obj-$(CONFIG_USB_TEST) += misc/ -obj-$(CONFIG_USB_TRANCEVIBRATOR)+= misc/ obj-$(CONFIG_USB_USS720) += misc/ obj-$(CONFIG_USB_ATM) += atm/ diff --git a/trunk/drivers/usb/atm/cxacru.c b/trunk/drivers/usb/atm/cxacru.c index e6565633ba0f..04631dcbabbc 100644 --- a/trunk/drivers/usb/atm/cxacru.c +++ b/trunk/drivers/usb/atm/cxacru.c @@ -171,7 +171,7 @@ struct cxacru_data { }; /* the following three functions are stolen from drivers/usb/core/message.c */ -static void cxacru_blocking_completion(struct urb *urb) +static void cxacru_blocking_completion(struct urb *urb, struct pt_regs *regs) { complete((struct completion *)urb->context); } @@ -793,9 +793,6 @@ static const struct usb_device_id cxacru_usb_ids[] = { { /* V = Conexant P = ADSL modem */ USB_DEVICE(0x0572, 0xcb06), .driver_info = (unsigned long) &cxacru_cb00 }, - { /* V = Conexant P = ADSL modem (ZTE ZXDSL 852) */ - USB_DEVICE(0x0572, 0xcb07), .driver_info = (unsigned long) &cxacru_cb00 - }, { /* V = Olitec P = ADSL modem version 2 */ USB_DEVICE(0x08e3, 0x0100), .driver_info = (unsigned long) &cxacru_cafe }, diff --git a/trunk/drivers/usb/atm/speedtch.c b/trunk/drivers/usb/atm/speedtch.c index a823486495c3..956b7a1e8af9 100644 --- a/trunk/drivers/usb/atm/speedtch.c +++ b/trunk/drivers/usb/atm/speedtch.c @@ -55,6 +55,7 @@ static const char speedtch_driver_name[] = "speedtch"; #define OFFSET_d 9 /* size 4 */ #define OFFSET_e 13 /* size 1 */ #define OFFSET_f 14 /* size 1 */ +#define TOTAL 15 #define SIZE_7 1 #define SIZE_b 8 @@ -78,18 +79,6 @@ static int dl_512_first = DEFAULT_DL_512_FIRST; static int enable_isoc = DEFAULT_ENABLE_ISOC; static int sw_buffering = DEFAULT_SW_BUFFERING; -#define DEFAULT_B_MAX_DSL 8128 -#define DEFAULT_MODEM_MODE 11 -#define MODEM_OPTION_LENGTH 16 -static const unsigned char DEFAULT_MODEM_OPTION[MODEM_OPTION_LENGTH] = { - 0x10, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -static unsigned int BMaxDSL = DEFAULT_B_MAX_DSL; -static unsigned char ModemMode = DEFAULT_MODEM_MODE; -static unsigned char ModemOption[MODEM_OPTION_LENGTH]; -static int num_ModemOption; - module_param(altsetting, uint, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(altsetting, "Alternative setting for data interface (bulk_default: " @@ -111,17 +100,6 @@ MODULE_PARM_DESC(sw_buffering, "Enable software buffering (default: " __MODULE_STRING(DEFAULT_SW_BUFFERING) ")"); -module_param(BMaxDSL, uint, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(BMaxDSL, - "default: " __MODULE_STRING(DEFAULT_B_MAX_DSL)); - -module_param(ModemMode, byte, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(ModemMode, - "default: " __MODULE_STRING(DEFAULT_MODEM_MODE)); - -module_param_array(ModemOption, byte, &num_ModemOption, S_IRUGO); -MODULE_PARM_DESC(ModemOption, "default: 0x10,0x00,0x00,0x00,0x20"); - #define INTERFACE_DATA 1 #define ENDPOINT_INT 0x81 #define ENDPOINT_BULK_DATA 0x07 @@ -130,17 +108,10 @@ MODULE_PARM_DESC(ModemOption, "default: 0x10,0x00,0x00,0x00,0x20"); #define hex2int(c) ( (c >= '0') && (c <= '9') ? (c - '0') : ((c & 0xf) + 9) ) -struct speedtch_params { - unsigned int altsetting; - unsigned int BMaxDSL; - unsigned char ModemMode; - unsigned char ModemOption[MODEM_OPTION_LENGTH]; -}; - struct speedtch_instance_data { struct usbatm_data *usbatm; - struct speedtch_params params; /* set in probe, constant afterwards */ + unsigned int altsetting; struct work_struct status_checker; @@ -152,7 +123,7 @@ struct speedtch_instance_data { struct urb *int_urb; unsigned char int_data[16]; - unsigned char scratch_buffer[16]; + unsigned char scratch_buffer[TOTAL]; }; /*************** @@ -215,34 +186,6 @@ static void speedtch_test_sequence(struct speedtch_instance_data *instance) 0x01, 0x40, 0x04, 0x00, buf, 3, CTRL_TIMEOUT); if (ret < 0) usb_warn(usbatm, "%s failed on URB150: %d\n", __func__, ret); - - /* Extra initialisation in recent drivers - gives higher speeds */ - - /* URBext1 */ - buf[0] = instance->params.ModemMode; - ret = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), - 0x01, 0x40, 0x11, 0x00, buf, 1, CTRL_TIMEOUT); - if (ret < 0) - usb_warn(usbatm, "%s failed on URBext1: %d\n", __func__, ret); - - /* URBext2 */ - /* This seems to be the one which actually triggers the higher sync - rate -- it does require the new firmware too, although it works OK - with older firmware */ - ret = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), - 0x01, 0x40, 0x14, 0x00, - instance->params.ModemOption, - MODEM_OPTION_LENGTH, CTRL_TIMEOUT); - if (ret < 0) - usb_warn(usbatm, "%s failed on URBext2: %d\n", __func__, ret); - - /* URBext3 */ - buf[0] = instance->params.BMaxDSL & 0xff; - buf[1] = instance->params.BMaxDSL >> 8; - ret = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), - 0x01, 0x40, 0x12, 0x00, buf, 2, CTRL_TIMEOUT); - if (ret < 0) - usb_warn(usbatm, "%s failed on URBext3: %d\n", __func__, ret); } static int speedtch_upload_firmware(struct speedtch_instance_data *instance, @@ -342,8 +285,8 @@ static int speedtch_upload_firmware(struct speedtch_instance_data *instance, because we're in our own kernel thread anyway. */ msleep_interruptible(1000); - if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, instance->params.altsetting)) < 0) { - usb_err(usbatm, "%s: setting interface to %d failed (%d)!\n", __func__, instance->params.altsetting, ret); + if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, instance->altsetting)) < 0) { + usb_err(usbatm, "%s: setting interface to %d failed (%d)!\n", __func__, instance->altsetting, ret); goto out_free; } @@ -429,7 +372,7 @@ static int speedtch_read_status(struct speedtch_instance_data *instance) unsigned char *buf = instance->scratch_buffer; int ret; - memset(buf, 0, 16); + memset(buf, 0, TOTAL); ret = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), 0x12, 0xc0, 0x07, 0x00, buf + OFFSET_7, SIZE_7, @@ -604,7 +547,7 @@ static void speedtch_resubmit_int(unsigned long data) } } -static void speedtch_handle_int(struct urb *int_urb) +static void speedtch_handle_int(struct urb *int_urb, struct pt_regs *regs) { struct speedtch_instance_data *instance = int_urb->context; struct usbatm_data *usbatm = instance->usbatm; @@ -803,21 +746,17 @@ static int speedtch_bind(struct usbatm_data *usbatm, instance->usbatm = usbatm; - /* module parameters may change at any moment, so take a snapshot */ - instance->params.altsetting = altsetting; - instance->params.BMaxDSL = BMaxDSL; - instance->params.ModemMode = ModemMode; - memcpy(instance->params.ModemOption, DEFAULT_MODEM_OPTION, MODEM_OPTION_LENGTH); - memcpy(instance->params.ModemOption, ModemOption, num_ModemOption); + /* altsetting and enable_isoc may change at any moment, so take a snapshot */ + instance->altsetting = altsetting; use_isoc = enable_isoc; - if (instance->params.altsetting) - if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, instance->params.altsetting)) < 0) { - usb_err(usbatm, "%s: setting interface to %2d failed (%d)!\n", __func__, instance->params.altsetting, ret); - instance->params.altsetting = 0; /* fall back to default */ + if (instance->altsetting) + if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, instance->altsetting)) < 0) { + usb_err(usbatm, "%s: setting interface to %2d failed (%d)!\n", __func__, instance->altsetting, ret); + instance->altsetting = 0; /* fall back to default */ } - if (!instance->params.altsetting && use_isoc) + if (!instance->altsetting && use_isoc) if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, DEFAULT_ISOC_ALTSETTING)) < 0) { usb_dbg(usbatm, "%s: setting interface to %2d failed (%d)!\n", __func__, DEFAULT_ISOC_ALTSETTING, ret); use_isoc = 0; /* fall back to bulk */ @@ -834,8 +773,8 @@ static int speedtch_bind(struct usbatm_data *usbatm, const struct usb_endpoint_descriptor *endpoint_desc = &desc->endpoint[i].desc; if ((endpoint_desc->bEndpointAddress == target_address)) { - use_isoc = - usb_endpoint_xfer_isoc(endpoint_desc); + use_isoc = (endpoint_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == + USB_ENDPOINT_XFER_ISOC; break; } } @@ -844,14 +783,14 @@ static int speedtch_bind(struct usbatm_data *usbatm, usb_info(usbatm, "isochronous transfer not supported - using bulk\n"); } - if (!use_isoc && !instance->params.altsetting) + if (!use_isoc && !instance->altsetting) if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, DEFAULT_BULK_ALTSETTING)) < 0) { usb_err(usbatm, "%s: setting interface to %2d failed (%d)!\n", __func__, DEFAULT_BULK_ALTSETTING, ret); goto fail_free; } - if (!instance->params.altsetting) - instance->params.altsetting = use_isoc ? DEFAULT_ISOC_ALTSETTING : DEFAULT_BULK_ALTSETTING; + if (!instance->altsetting) + instance->altsetting = use_isoc ? DEFAULT_ISOC_ALTSETTING : DEFAULT_BULK_ALTSETTING; usbatm->flags |= (use_isoc ? UDSL_USE_ISOC : 0); diff --git a/trunk/drivers/usb/atm/ueagle-atm.c b/trunk/drivers/usb/atm/ueagle-atm.c index c137c041f7a4..465961a26e4a 100644 --- a/trunk/drivers/usb/atm/ueagle-atm.c +++ b/trunk/drivers/usb/atm/ueagle-atm.c @@ -68,7 +68,7 @@ #include "usbatm.h" -#define EAGLEUSBVERSION "ueagle 1.4" +#define EAGLEUSBVERSION "ueagle 1.3" /* @@ -80,14 +80,14 @@ dev_dbg(&(usb_dev)->dev, \ "[ueagle-atm dbg] %s: " format, \ __FUNCTION__, ##args); \ - } while (0) + } while (0) #define uea_vdbg(usb_dev, format, args...) \ do { \ if (debug >= 2) \ dev_dbg(&(usb_dev)->dev, \ "[ueagle-atm vdbg] " format, ##args); \ - } while (0) + } while (0) #define uea_enters(usb_dev) \ uea_vdbg(usb_dev, "entering %s\n", __FUNCTION__) @@ -218,8 +218,8 @@ enum { #define UEA_CHIP_VERSION(x) \ ((x)->driver_info & 0xf) -#define IS_ISDN(usb_dev) \ - (le16_to_cpu((usb_dev)->descriptor.bcdDevice) & 0x80) +#define IS_ISDN(sc) \ + (le16_to_cpu(sc->usb_dev->descriptor.bcdDevice) & 0x80) #define INS_TO_USBDEV(ins) ins->usb_dev @@ -401,8 +401,9 @@ static int uea_send_modem_cmd(struct usb_device *usb, int ret = -ENOMEM; u8 *xfer_buff; - xfer_buff = kmemdup(buff, size, GFP_KERNEL); + xfer_buff = kmalloc(size, GFP_KERNEL); if (xfer_buff) { + memcpy(xfer_buff, buff, size); ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0), LOAD_INTERNAL, @@ -594,12 +595,14 @@ static int uea_idma_write(struct uea_softc *sc, void *data, u32 size) u8 *xfer_buff; int bytes_read; - xfer_buff = kmemdup(data, size, GFP_KERNEL); + xfer_buff = kmalloc(size, GFP_KERNEL); if (!xfer_buff) { uea_err(INS_TO_USBDEV(sc), "can't allocate xfer_buff\n"); return ret; } + memcpy(xfer_buff, data, size); + ret = usb_bulk_msg(sc->usb_dev, usb_sndbulkpipe(sc->usb_dev, UEA_IDMA_PIPE), xfer_buff, size, &bytes_read, BULK_TIMEOUT); @@ -622,12 +625,12 @@ static int request_dsp(struct uea_softc *sc) char *dsp_name; if (UEA_CHIP_VERSION(sc) == ADI930) { - if (IS_ISDN(sc->usb_dev)) + if (IS_ISDN(sc)) dsp_name = FW_DIR "DSP9i.bin"; else dsp_name = FW_DIR "DSP9p.bin"; } else { - if (IS_ISDN(sc->usb_dev)) + if (IS_ISDN(sc)) dsp_name = FW_DIR "DSPei.bin"; else dsp_name = FW_DIR "DSPep.bin"; @@ -741,7 +744,7 @@ static inline void wake_up_cmv_ack(struct uea_softc *sc) static inline int wait_cmv_ack(struct uea_softc *sc) { - int ret = wait_event_interruptible_timeout(sc->cmv_ack_wait, + int ret = wait_event_timeout(sc->cmv_ack_wait, sc->cmv_ack, ACK_TIMEOUT); sc->cmv_ack = 0; @@ -762,11 +765,12 @@ static int uea_request(struct uea_softc *sc, u8 *xfer_buff; int ret = -ENOMEM; - xfer_buff = kmemdup(data, size, GFP_KERNEL); + xfer_buff = kmalloc(size, GFP_KERNEL); if (!xfer_buff) { uea_err(INS_TO_USBDEV(sc), "can't allocate xfer_buff\n"); return ret; } + memcpy(xfer_buff, data, size); ret = usb_control_msg(sc->usb_dev, usb_sndctrlpipe(sc->usb_dev, 0), UCDC_SEND_ENCAPSULATED_COMMAND, @@ -881,8 +885,7 @@ static int uea_stat(struct uea_softc *sc) break; case 3: /* fail ... */ - uea_info(INS_TO_USBDEV(sc), "modem synchronization failed" - " (may be try other cmv/dsp)\n"); + uea_info(INS_TO_USBDEV(sc), "modem synchronization failed\n"); return -EAGAIN; case 4 ... 6: /* test state */ @@ -910,6 +913,12 @@ static int uea_stat(struct uea_softc *sc) release_firmware(sc->dsp_firm); sc->dsp_firm = NULL; } + + ret = uea_read_cmv(sc, SA_INFO, 10, &sc->stats.phy.firmid); + if (ret < 0) + return ret; + uea_info(INS_TO_USBDEV(sc), "ATU-R firmware version : %x\n", + sc->stats.phy.firmid); } /* always update it as atm layer could not be init when we switch to @@ -1024,9 +1033,9 @@ static int request_cmvs(struct uea_softc *sc, if (cmv_file[sc->modem_index] == NULL) { if (UEA_CHIP_VERSION(sc) == ADI930) - file = (IS_ISDN(sc->usb_dev)) ? "CMV9i.bin" : "CMV9p.bin"; + file = (IS_ISDN(sc)) ? "CMV9i.bin" : "CMV9p.bin"; else - file = (IS_ISDN(sc->usb_dev)) ? "CMVei.bin" : "CMVep.bin"; + file = (IS_ISDN(sc)) ? "CMVei.bin" : "CMVep.bin"; } else file = cmv_file[sc->modem_index]; @@ -1122,13 +1131,6 @@ static int uea_start_reset(struct uea_softc *sc) if (ret < 0) return ret; - /* Dump firmware version */ - ret = uea_read_cmv(sc, SA_INFO, 10, &sc->stats.phy.firmid); - if (ret < 0) - return ret; - uea_info(INS_TO_USBDEV(sc), "ATU-R firmware version : %x\n", - sc->stats.phy.firmid); - /* get options */ ret = len = request_cmvs(sc, &cmvs, &cmvs_fw); if (ret < 0) @@ -1145,8 +1147,6 @@ static int uea_start_reset(struct uea_softc *sc) /* Enter in R-ACT-REQ */ ret = uea_write_cmv(sc, SA_CNTL, 0, 2); uea_vdbg(INS_TO_USBDEV(sc), "Entering in R-ACT-REQ state\n"); - uea_info(INS_TO_USBDEV(sc), "Modem started, " - "waiting synchronization\n"); out: release_firmware(cmvs_fw); sc->reset = 0; @@ -1172,10 +1172,7 @@ static int uea_kthread(void *data) if (!ret) ret = uea_stat(sc); if (ret != -EAGAIN) - msleep_interruptible(1000); - if (try_to_freeze()) - uea_err(INS_TO_USBDEV(sc), "suspend/resume not supported, " - "please unplug/replug your modem\n"); + msleep(1000); } uea_leaves(INS_TO_USBDEV(sc)); return ret; @@ -1300,7 +1297,7 @@ static void uea_dispatch_cmv(struct uea_softc *sc, struct cmv* cmv) /* * interrupt handler */ -static void uea_intr(struct urb *urb) +static void uea_intr(struct urb *urb, struct pt_regs *regs) { struct uea_softc *sc = urb->context; struct intr_pkt *intr = urb->transfer_buffer; @@ -1569,7 +1566,6 @@ UEA_ATTR(uscorr, 0); UEA_ATTR(dscorr, 0); UEA_ATTR(usunc, 0); UEA_ATTR(dsunc, 0); -UEA_ATTR(firmid, 0); /* Retrieve the device End System Identifier (MAC) */ @@ -1601,7 +1597,7 @@ static int uea_heavy(struct usbatm_data *usbatm, struct usb_interface *intf) { struct uea_softc *sc = usbatm->driver_data; - wait_event_interruptible(sc->sync_q, IS_OPERATIONAL(sc)); + wait_event(sc->sync_q, IS_OPERATIONAL(sc)); return 0; @@ -1643,13 +1639,16 @@ static struct attribute *attrs[] = { &dev_attr_stat_dscorr.attr, &dev_attr_stat_usunc.attr, &dev_attr_stat_dsunc.attr, - &dev_attr_stat_firmid.attr, - NULL, }; static struct attribute_group attr_grp = { .attrs = attrs, }; +static int create_fs_entries(struct usb_interface *intf) +{ + return sysfs_create_group(&intf->dev.kobj, &attr_grp); +} + static int uea_bind(struct usbatm_data *usbatm, struct usb_interface *intf, const struct usb_device_id *id) { @@ -1709,25 +1708,31 @@ static int uea_bind(struct usbatm_data *usbatm, struct usb_interface *intf, } } - ret = sysfs_create_group(&intf->dev.kobj, &attr_grp); - if (ret < 0) - goto error; - ret = uea_boot(sc); - if (ret < 0) - goto error; + if (ret < 0) { + kfree(sc); + return ret; + } + ret = create_fs_entries(intf); + if (ret) { + uea_stop(sc); + kfree(sc); + return ret; + } return 0; -error: - kfree(sc); - return ret; +} + +static void destroy_fs_entries(struct usb_interface *intf) +{ + sysfs_remove_group(&intf->dev.kobj, &attr_grp); } static void uea_unbind(struct usbatm_data *usbatm, struct usb_interface *intf) { struct uea_softc *sc = usbatm->driver_data; - sysfs_remove_group(&intf->dev.kobj, &attr_grp); + destroy_fs_entries(intf); uea_stop(sc); kfree(sc); } @@ -1748,10 +1753,10 @@ static int uea_probe(struct usb_interface *intf, const struct usb_device_id *id) struct usb_device *usb = interface_to_usbdev(intf); uea_enters(usb); - uea_info(usb, "ADSL device founded vid (%#X) pid (%#X) : %s %s\n", + uea_info(usb, "ADSL device founded vid (%#X) pid (%#X) : %s\n", le16_to_cpu(usb->descriptor.idVendor), le16_to_cpu(usb->descriptor.idProduct), - chip_name[UEA_CHIP_VERSION(id)], IS_ISDN(usb)?"isdn":"pots"); + chip_name[UEA_CHIP_VERSION(id)]); usb_reset_device(usb); diff --git a/trunk/drivers/usb/atm/usbatm.c b/trunk/drivers/usb/atm/usbatm.c index ec63b0ee0743..a38701c742c3 100644 --- a/trunk/drivers/usb/atm/usbatm.c +++ b/trunk/drivers/usb/atm/usbatm.c @@ -254,7 +254,7 @@ static int usbatm_submit_urb(struct urb *urb) return ret; } -static void usbatm_complete(struct urb *urb) +static void usbatm_complete(struct urb *urb, struct pt_regs *regs) { struct usbatm_channel *channel = urb->context; unsigned long flags; @@ -1001,7 +1001,6 @@ static int usbatm_do_heavy_init(void *arg) daemonize(instance->driver->driver_name); allow_signal(SIGTERM); - instance->thread_pid = current->pid; complete(&instance->thread_started); @@ -1026,6 +1025,10 @@ static int usbatm_heavy_init(struct usbatm_data *instance) return ret; } + mutex_lock(&instance->serialize); + instance->thread_pid = ret; + mutex_unlock(&instance->serialize); + wait_for_completion(&instance->thread_started); return 0; diff --git a/trunk/drivers/usb/class/cdc-acm.c b/trunk/drivers/usb/class/cdc-acm.c index ec3438dc8ee5..71288295df2f 100644 --- a/trunk/drivers/usb/class/cdc-acm.c +++ b/trunk/drivers/usb/class/cdc-acm.c @@ -218,7 +218,7 @@ static int acm_write_start(struct acm *acm) */ /* control interface reports status changes with "interrupt" transfers */ -static void acm_ctrl_irq(struct urb *urb) +static void acm_ctrl_irq(struct urb *urb, struct pt_regs *regs) { struct acm *acm = urb->context; struct usb_cdc_notification *dr = urb->transfer_buffer; @@ -285,7 +285,7 @@ static void acm_ctrl_irq(struct urb *urb) } /* data interface returns incoming bytes, or we got unthrottled */ -static void acm_read_bulk(struct urb *urb) +static void acm_read_bulk(struct urb *urb, struct pt_regs *regs) { struct acm_rb *buf; struct acm_ru *rcv = urb->context; @@ -325,7 +325,7 @@ static void acm_rx_tasklet(unsigned long _acm) struct acm_rb *buf; struct tty_struct *tty = acm->tty; struct acm_ru *rcv; - unsigned long flags; + //unsigned long flags; int i = 0; dbg("Entering acm_rx_tasklet"); @@ -333,15 +333,15 @@ static void acm_rx_tasklet(unsigned long _acm) return; next_buffer: - spin_lock_irqsave(&acm->read_lock, flags); + spin_lock(&acm->read_lock); if (list_empty(&acm->filled_read_bufs)) { - spin_unlock_irqrestore(&acm->read_lock, flags); + spin_unlock(&acm->read_lock); goto urbs; } buf = list_entry(acm->filled_read_bufs.next, struct acm_rb, list); list_del(&buf->list); - spin_unlock_irqrestore(&acm->read_lock, flags); + spin_unlock(&acm->read_lock); dbg("acm_rx_tasklet: procesing buf 0x%p, size = %d", buf, buf->size); @@ -356,29 +356,29 @@ static void acm_rx_tasklet(unsigned long _acm) memmove(buf->base, buf->base + i, buf->size - i); buf->size -= i; spin_unlock(&acm->throttle_lock); - spin_lock_irqsave(&acm->read_lock, flags); + spin_lock(&acm->read_lock); list_add(&buf->list, &acm->filled_read_bufs); - spin_unlock_irqrestore(&acm->read_lock, flags); + spin_unlock(&acm->read_lock); return; } spin_unlock(&acm->throttle_lock); - spin_lock_irqsave(&acm->read_lock, flags); + spin_lock(&acm->read_lock); list_add(&buf->list, &acm->spare_read_bufs); - spin_unlock_irqrestore(&acm->read_lock, flags); + spin_unlock(&acm->read_lock); goto next_buffer; urbs: while (!list_empty(&acm->spare_read_bufs)) { - spin_lock_irqsave(&acm->read_lock, flags); + spin_lock(&acm->read_lock); if (list_empty(&acm->spare_read_urbs)) { - spin_unlock_irqrestore(&acm->read_lock, flags); + spin_unlock(&acm->read_lock); return; } rcv = list_entry(acm->spare_read_urbs.next, struct acm_ru, list); list_del(&rcv->list); - spin_unlock_irqrestore(&acm->read_lock, flags); + spin_unlock(&acm->read_lock); buf = list_entry(acm->spare_read_bufs.next, struct acm_rb, list); @@ -400,16 +400,16 @@ static void acm_rx_tasklet(unsigned long _acm) free-urbs-pool and resubmited ASAP */ if (usb_submit_urb(rcv->urb, GFP_ATOMIC) < 0) { list_add(&buf->list, &acm->spare_read_bufs); - spin_lock_irqsave(&acm->read_lock, flags); + spin_lock(&acm->read_lock); list_add(&rcv->list, &acm->spare_read_urbs); - spin_unlock_irqrestore(&acm->read_lock, flags); + spin_unlock(&acm->read_lock); return; } } } /* data interface wrote those outgoing bytes */ -static void acm_write_bulk(struct urb *urb) +static void acm_write_bulk(struct urb *urb, struct pt_regs *regs) { struct acm *acm = (struct acm *)urb->context; @@ -892,7 +892,7 @@ static int acm_probe (struct usb_interface *intf, /* workaround for switched endpoints */ - if (!usb_endpoint_dir_in(epread)) { + if ((epread->bEndpointAddress & USB_DIR_IN) != USB_DIR_IN) { /* descriptors are swapped */ struct usb_endpoint_descriptor *t; dev_dbg(&intf->dev,"The data interface has switched endpoints"); @@ -1083,9 +1083,6 @@ static struct usb_device_id acm_ids[] = { { USB_DEVICE(0x0482, 0x0203), /* KYOCERA AH-K3001V */ .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ }, - { USB_DEVICE(0x079b, 0x000f), /* BT On-Air USB MODEM */ - .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ - }, { USB_DEVICE(0x0ace, 0x1608), /* ZyDAS 56K USB MODEM */ .driver_info = SINGLE_RX_URB, /* firmware bug */ }, diff --git a/trunk/drivers/usb/class/usblp.c b/trunk/drivers/usb/class/usblp.c index 6303970e93c1..9cac11ca1bb7 100644 --- a/trunk/drivers/usb/class/usblp.c +++ b/trunk/drivers/usb/class/usblp.c @@ -154,7 +154,6 @@ struct usblp { unsigned char used; /* True if open */ unsigned char present; /* True if not disconnected */ unsigned char bidir; /* interface is bidirectional */ - unsigned char sleeping; /* interface is suspended */ unsigned char *device_id_string; /* IEEE 1284 DEVICE ID string (ptr) */ /* first 2 bytes are (big-endian) length */ }; @@ -184,7 +183,6 @@ static void usblp_dump(struct usblp *usblp) { dbg("quirks=%d", usblp->quirks); dbg("used=%d", usblp->used); dbg("bidir=%d", usblp->bidir); - dbg("sleeping=%d", usblp->sleeping); dbg("device_id_string=\"%s\"", usblp->device_id_string ? usblp->device_id_string + 2 : @@ -273,7 +271,7 @@ static int proto_bias = -1; * URB callback. */ -static void usblp_bulk_read(struct urb *urb) +static void usblp_bulk_read(struct urb *urb, struct pt_regs *regs) { struct usblp *usblp = urb->context; @@ -290,7 +288,7 @@ static void usblp_bulk_read(struct urb *urb) wake_up_interruptible(&usblp->wait); } -static void usblp_bulk_write(struct urb *urb) +static void usblp_bulk_write(struct urb *urb, struct pt_regs *regs) { struct usblp *usblp = urb->context; @@ -340,20 +338,6 @@ static int usblp_check_status(struct usblp *usblp, int err) return newerr; } -static int handle_bidir (struct usblp *usblp) -{ - if (usblp->bidir && usblp->used && !usblp->sleeping) { - usblp->readcount = 0; - usblp->readurb->dev = usblp->dev; - if (usb_submit_urb(usblp->readurb, GFP_KERNEL) < 0) { - usblp->used = 0; - return -EIO; - } - } - - return 0; -} - /* * File op functions. */ @@ -406,9 +390,14 @@ static int usblp_open(struct inode *inode, struct file *file) usblp->writeurb->status = 0; usblp->readurb->status = 0; - if (handle_bidir(usblp) < 0) { - file->private_data = NULL; - retval = -EIO; + if (usblp->bidir) { + usblp->readcount = 0; + usblp->readurb->dev = usblp->dev; + if (usb_submit_urb(usblp->readurb, GFP_KERNEL) < 0) { + retval = -EIO; + usblp->used = 0; + file->private_data = NULL; + } } out: mutex_unlock (&usblp_mutex); @@ -471,11 +460,6 @@ static long usblp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) goto done; } - if (usblp->sleeping) { - retval = -ENODEV; - goto done; - } - dbg("usblp_ioctl: cmd=0x%x (%c nr=%d len=%d dir=%d)", cmd, _IOC_TYPE(cmd), _IOC_NR(cmd), _IOC_SIZE(cmd), _IOC_DIR(cmd) ); @@ -674,11 +658,6 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t return -ENODEV; } - if (usblp->sleeping) { - up (&usblp->sem); - return writecount ? writecount : -ENODEV; - } - if (usblp->writeurb->status != 0) { if (usblp->quirks & USBLP_QUIRK_BIDIR) { if (!usblp->wcomplete) @@ -722,7 +701,6 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t usblp->wcomplete = 0; err = usb_submit_urb(usblp->writeurb, GFP_KERNEL); if (err) { - usblp->wcomplete = 1; if (err != -ENOMEM) count = -EIO; else @@ -771,11 +749,6 @@ static ssize_t usblp_read(struct file *file, char __user *buffer, size_t count, goto done; } - if (usblp->sleeping) { - count = -ENODEV; - goto done; - } - if (usblp->readurb->status) { err("usblp%d: error %d reading from printer", usblp->minor, usblp->readurb->status); @@ -1194,39 +1167,6 @@ static void usblp_disconnect(struct usb_interface *intf) mutex_unlock (&usblp_mutex); } -static int usblp_suspend (struct usb_interface *intf, pm_message_t message) -{ - struct usblp *usblp = usb_get_intfdata (intf); - - /* this races against normal access and open */ - mutex_lock (&usblp_mutex); - down (&usblp->sem); - /* we take no more IO */ - usblp->sleeping = 1; - usblp_unlink_urbs(usblp); - up (&usblp->sem); - mutex_unlock (&usblp_mutex); - - return 0; -} - -static int usblp_resume (struct usb_interface *intf) -{ - struct usblp *usblp = usb_get_intfdata (intf); - int r; - - mutex_lock (&usblp_mutex); - down (&usblp->sem); - - usblp->sleeping = 0; - r = handle_bidir (usblp); - - up (&usblp->sem); - mutex_unlock (&usblp_mutex); - - return r; -} - static struct usb_device_id usblp_ids [] = { { USB_DEVICE_INFO(7, 1, 1) }, { USB_DEVICE_INFO(7, 1, 2) }, @@ -1243,8 +1183,6 @@ static struct usb_driver usblp_driver = { .name = "usblp", .probe = usblp_probe, .disconnect = usblp_disconnect, - .suspend = usblp_suspend, - .resume = usblp_resume, .id_table = usblp_ids, }; diff --git a/trunk/drivers/usb/core/Kconfig b/trunk/drivers/usb/core/Kconfig index f8324d8d06ac..6e3b5358a760 100644 --- a/trunk/drivers/usb/core/Kconfig +++ b/trunk/drivers/usb/core/Kconfig @@ -72,21 +72,6 @@ config USB_SUSPEND If you are unsure about this, say N here. -config USB_MULTITHREAD_PROBE - bool "USB Multi-threaded probe (EXPERIMENTAL)" - depends on USB && EXPERIMENTAL - default n - help - Say Y here if you want the USB core to spawn a new thread for - every USB device that is probed. This can cause a small speedup - in boot times on systems with a lot of different USB devices. - - This option should be safe to enable, but if any odd probing - problems are found, please disable it, or dynamically turn it - off in the /sys/module/usbcore/parameters/multithread_probe - file - - When in doubt, say N. config USB_OTG bool diff --git a/trunk/drivers/usb/core/devices.c b/trunk/drivers/usb/core/devices.c index ea398e5d50af..3538c2fdadfe 100644 --- a/trunk/drivers/usb/core/devices.c +++ b/trunk/drivers/usb/core/devices.c @@ -175,13 +175,12 @@ static char *usb_dump_endpoint_descriptor ( ) { char dir, unit, *type; - unsigned interval, bandwidth = 1; + unsigned interval, in, bandwidth = 1; if (start > end) return start; - - dir = usb_endpoint_dir_in(desc) ? 'I' : 'O'; - + in = (desc->bEndpointAddress & USB_DIR_IN); + dir = in ? 'I' : 'O'; if (speed == USB_SPEED_HIGH) { switch (le16_to_cpu(desc->wMaxPacketSize) & (0x03 << 11)) { case 1 << 11: bandwidth = 2; break; @@ -205,7 +204,7 @@ static char *usb_dump_endpoint_descriptor ( break; case USB_ENDPOINT_XFER_BULK: type = "Bulk"; - if (speed == USB_SPEED_HIGH && dir == 'O') /* uframes per NAK */ + if (speed == USB_SPEED_HIGH && !in) /* uframes per NAK */ interval = desc->bInterval; else interval = 0; diff --git a/trunk/drivers/usb/core/devio.c b/trunk/drivers/usb/core/devio.c index 3ed4cb2d56d9..3f509beb88e4 100644 --- a/trunk/drivers/usb/core/devio.c +++ b/trunk/drivers/usb/core/devio.c @@ -304,7 +304,7 @@ static void snoop_urb(struct urb *urb, void __user *userurb) printk("\n"); } -static void async_completed(struct urb *urb) +static void async_completed(struct urb *urb, struct pt_regs *regs) { struct async *as = urb->context; struct dev_state *ps = as->ps; @@ -561,7 +561,7 @@ static int usbdev_open(struct inode *inode, struct file *file) dev = inode->i_private; if (!dev) goto out; - ret = usb_autoresume_device(dev); + ret = usb_autoresume_device(dev, 1); if (ret) goto out; @@ -609,7 +609,7 @@ static int usbdev_release(struct inode *inode, struct file *file) releaseintf(ps, ifnum); } destroy_all_async(ps); - usb_autosuspend_device(dev); + usb_autosuspend_device(dev, 1); usb_unlock_device(dev); usb_put_dev(dev); put_pid(ps->disc_pid); @@ -1216,7 +1216,7 @@ static int proc_submiturb_compat(struct dev_state *ps, void __user *arg) { struct usbdevfs_urb uurb; - if (get_urb32(&uurb,(struct usbdevfs_urb32 __user *)arg)) + if (get_urb32(&uurb,(struct usbdevfs_urb32 *)arg)) return -EFAULT; return proc_do_submiturb(ps, &uurb, ((struct usbdevfs_urb32 __user *)arg)->iso_frame_desc, arg); @@ -1251,7 +1251,7 @@ static int processcompl_compat(struct async *as, void __user * __user *arg) } free_async(as); - if (put_user(ptr_to_compat(addr), (u32 __user *)arg)) + if (put_user((u32)(u64)addr, (u32 __user *)arg)) return -EFAULT; return 0; } @@ -1520,7 +1520,7 @@ static int usbdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd case USBDEVFS_IOCTL32: snoop(&dev->dev, "%s: IOCTL\n", __FUNCTION__); - ret = proc_ioctl_compat(ps, ptr_to_compat(p)); + ret = proc_ioctl_compat(ps, (compat_uptr_t)(long)p); break; #endif @@ -1588,18 +1588,15 @@ const struct file_operations usbfs_device_file_operations = { .release = usbdev_release, }; -static int usbdev_add(struct usb_device *dev) +static void usbdev_add(struct usb_device *dev) { int minor = ((dev->bus->busnum-1) * 128) + (dev->devnum-1); dev->class_dev = class_device_create(usb_device_class, NULL, MKDEV(USB_DEVICE_MAJOR, minor), &dev->dev, "usbdev%d.%d", dev->bus->busnum, dev->devnum); - if (IS_ERR(dev->class_dev)) - return PTR_ERR(dev->class_dev); dev->class_dev->class_data = dev; - return 0; } static void usbdev_remove(struct usb_device *dev) @@ -1612,8 +1609,7 @@ static int usbdev_notify(struct notifier_block *self, unsigned long action, { switch (action) { case USB_DEVICE_ADD: - if (usbdev_add(dev)) - return NOTIFY_BAD; + usbdev_add(dev); break; case USB_DEVICE_REMOVE: usbdev_remove(dev); diff --git a/trunk/drivers/usb/core/driver.c b/trunk/drivers/usb/core/driver.c index d6eb5ce1dd1d..113e484c763e 100644 --- a/trunk/drivers/usb/core/driver.c +++ b/trunk/drivers/usb/core/driver.c @@ -205,7 +205,7 @@ static int usb_probe_interface(struct device *dev) if (id) { dev_dbg(dev, "%s - got id\n", __FUNCTION__); - error = usb_autoresume_device(udev); + error = usb_autoresume_device(udev, 1); if (error) return error; @@ -229,7 +229,7 @@ static int usb_probe_interface(struct device *dev) } else intf->condition = USB_INTERFACE_BOUND; - usb_autosuspend_device(udev); + usb_autosuspend_device(udev, 1); } return error; @@ -247,7 +247,7 @@ static int usb_unbind_interface(struct device *dev) /* Autoresume for set_interface call below */ udev = interface_to_usbdev(intf); - error = usb_autoresume_device(udev); + error = usb_autoresume_device(udev, 1); /* release all urbs for this interface */ usb_disable_interface(interface_to_usbdev(intf), intf); @@ -265,7 +265,7 @@ static int usb_unbind_interface(struct device *dev) intf->needs_remote_wakeup = 0; if (!error) - usb_autosuspend_device(udev); + usb_autosuspend_device(udev, 1); return 0; } @@ -408,16 +408,6 @@ static int usb_match_one_id(struct usb_interface *interface, (id->bDeviceProtocol != dev->descriptor.bDeviceProtocol)) return 0; - /* The interface class, subclass, and protocol should never be - * checked for a match if the device class is Vendor Specific, - * unless the match record specifies the Vendor ID. */ - if (dev->descriptor.bDeviceClass == USB_CLASS_VENDOR_SPEC && - !(id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) && - (id->match_flags & (USB_DEVICE_ID_MATCH_INT_CLASS | - USB_DEVICE_ID_MATCH_INT_SUBCLASS | - USB_DEVICE_ID_MATCH_INT_PROTOCOL))) - return 0; - if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) && (id->bInterfaceClass != intf->desc.bInterfaceClass)) return 0; @@ -486,17 +476,7 @@ static int usb_match_one_id(struct usb_interface *interface, * most general; they let drivers bind to any interface on a * multiple-function device. Use the USB_INTERFACE_INFO * macro, or its siblings, to match class-per-interface style - * devices (as recorded in bInterfaceClass). - * - * Note that an entry created by USB_INTERFACE_INFO won't match - * any interface if the device class is set to Vendor-Specific. - * This is deliberate; according to the USB spec the meanings of - * the interface class/subclass/protocol for these devices are also - * vendor-specific, and hence matching against a standard product - * class wouldn't work anyway. If you really want to use an - * interface-based match for such a device, create a match record - * that also specifies the vendor ID. (Unforunately there isn't a - * standard macro for creating records like this.) + * devices (as recorded in bDeviceClass). * * Within those groups, remember that not all combinations are * meaningful. For example, don't give a product version range @@ -525,7 +505,7 @@ const struct usb_device_id *usb_match_id(struct usb_interface *interface, } EXPORT_SYMBOL_GPL_FUTURE(usb_match_id); -static int usb_device_match(struct device *dev, struct device_driver *drv) +int usb_device_match(struct device *dev, struct device_driver *drv) { /* devices and interfaces are handled separately */ if (is_usb_device(dev)) { @@ -810,7 +790,7 @@ EXPORT_SYMBOL_GPL_FUTURE(usb_deregister); #ifdef CONFIG_PM /* Caller has locked udev's pm_mutex */ -static int usb_suspend_device(struct usb_device *udev, pm_message_t msg) +static int suspend_device(struct usb_device *udev, pm_message_t msg) { struct usb_device_driver *udriver; int status = 0; @@ -837,7 +817,7 @@ static int usb_suspend_device(struct usb_device *udev, pm_message_t msg) } /* Caller has locked udev's pm_mutex */ -static int usb_resume_device(struct usb_device *udev) +static int resume_device(struct usb_device *udev) { struct usb_device_driver *udriver; int status = 0; @@ -863,7 +843,7 @@ static int usb_resume_device(struct usb_device *udev) } /* Caller has locked intf's usb_device's pm mutex */ -static int usb_suspend_interface(struct usb_interface *intf, pm_message_t msg) +static int suspend_interface(struct usb_interface *intf, pm_message_t msg) { struct usb_driver *driver; int status = 0; @@ -900,7 +880,7 @@ static int usb_suspend_interface(struct usb_interface *intf, pm_message_t msg) } /* Caller has locked intf's usb_device's pm_mutex */ -static int usb_resume_interface(struct usb_interface *intf) +static int resume_interface(struct usb_interface *intf) { struct usb_driver *driver; int status = 0; @@ -940,44 +920,6 @@ static int usb_resume_interface(struct usb_interface *intf) return status; } -#ifdef CONFIG_USB_SUSPEND - -/* Internal routine to check whether we may autosuspend a device. */ -static int autosuspend_check(struct usb_device *udev) -{ - int i; - struct usb_interface *intf; - - /* For autosuspend, fail fast if anything is in use. - * Also fail if any interfaces require remote wakeup but it - * isn't available. */ - udev->do_remote_wakeup = device_may_wakeup(&udev->dev); - if (udev->pm_usage_cnt > 0) - return -EBUSY; - if (udev->actconfig) { - for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { - intf = udev->actconfig->interface[i]; - if (!is_active(intf)) - continue; - if (intf->pm_usage_cnt > 0) - return -EBUSY; - if (intf->needs_remote_wakeup && - !udev->do_remote_wakeup) { - dev_dbg(&udev->dev, "remote wakeup needed " - "for autosuspend\n"); - return -EOPNOTSUPP; - } - } - } - return 0; -} - -#else - -#define autosuspend_check(udev) 0 - -#endif - /** * usb_suspend_both - suspend a USB device and its interfaces * @udev: the usb_device to suspend @@ -1029,34 +971,52 @@ int usb_suspend_both(struct usb_device *udev, pm_message_t msg) udev->do_remote_wakeup = device_may_wakeup(&udev->dev); + /* For autosuspend, fail fast if anything is in use. + * Also fail if any interfaces require remote wakeup but it + * isn't available. */ if (udev->auto_pm) { - status = autosuspend_check(udev); - if (status < 0) - return status; + if (udev->pm_usage_cnt > 0) + return -EBUSY; + if (udev->actconfig) { + for (; i < udev->actconfig->desc.bNumInterfaces; i++) { + intf = udev->actconfig->interface[i]; + if (!is_active(intf)) + continue; + if (intf->pm_usage_cnt > 0) + return -EBUSY; + if (intf->needs_remote_wakeup && + !udev->do_remote_wakeup) { + dev_dbg(&udev->dev, + "remote wakeup needed for autosuspend\n"); + return -EOPNOTSUPP; + } + } + i = 0; + } } /* Suspend all the interfaces and then udev itself */ if (udev->actconfig) { for (; i < udev->actconfig->desc.bNumInterfaces; i++) { intf = udev->actconfig->interface[i]; - status = usb_suspend_interface(intf, msg); + status = suspend_interface(intf, msg); if (status != 0) break; } } if (status == 0) - status = usb_suspend_device(udev, msg); + status = suspend_device(udev, msg); /* If the suspend failed, resume interfaces that did get suspended */ if (status != 0) { while (--i >= 0) { intf = udev->actconfig->interface[i]; - usb_resume_interface(intf); + resume_interface(intf); } /* If the suspend succeeded, propagate it up the tree */ } else if (parent) - usb_autosuspend_device(parent); + usb_autosuspend_device(parent, 0); // dev_dbg(&udev->dev, "%s: status %d\n", __FUNCTION__, status); return status; @@ -1104,25 +1064,9 @@ int usb_resume_both(struct usb_device *udev) /* Propagate the resume up the tree, if necessary */ if (udev->state == USB_STATE_SUSPENDED) { if (parent) { - status = usb_autoresume_device(parent); - if (status == 0) { - status = usb_resume_device(udev); - if (status) { - usb_autosuspend_device(parent); - - /* It's possible usb_resume_device() - * failed after the port was - * unsuspended, causing udev to be - * logically disconnected. We don't - * want usb_disconnect() to autosuspend - * the parent again, so tell it that - * udev disconnected while still - * suspended. */ - if (udev->state == - USB_STATE_NOTATTACHED) - udev->discon_suspended = 1; - } - } + usb_pm_lock(parent); + parent->auto_pm = 1; + status = usb_resume_both(parent); } else { /* We can't progagate beyond the USB subsystem, @@ -1131,20 +1075,24 @@ int usb_resume_both(struct usb_device *udev) if (udev->dev.parent->power.power_state.event != PM_EVENT_ON) status = -EHOSTUNREACH; - else - status = usb_resume_device(udev); - } + } + if (status == 0) + status = resume_device(udev); + if (parent) + usb_pm_unlock(parent); } else { /* Needed only for setting udev->dev.power.power_state.event * and for possible debugging message. */ - status = usb_resume_device(udev); + status = resume_device(udev); } + /* Now the parent won't suspend until we are finished */ + if (status == 0 && udev->actconfig) { for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { intf = udev->actconfig->interface[i]; - usb_resume_interface(intf); + resume_interface(intf); } } @@ -1154,53 +1102,39 @@ int usb_resume_both(struct usb_device *udev) #ifdef CONFIG_USB_SUSPEND -/* Internal routine to adjust a device's usage counter and change - * its autosuspend state. - */ -static int usb_autopm_do_device(struct usb_device *udev, int inc_usage_cnt) -{ - int status = 0; - - usb_pm_lock(udev); - udev->pm_usage_cnt += inc_usage_cnt; - WARN_ON(udev->pm_usage_cnt < 0); - if (inc_usage_cnt >= 0 && udev->pm_usage_cnt > 0) { - udev->auto_pm = 1; - status = usb_resume_both(udev); - if (status != 0) - udev->pm_usage_cnt -= inc_usage_cnt; - } else if (inc_usage_cnt <= 0 && autosuspend_check(udev) == 0) - queue_delayed_work(ksuspend_usb_wq, &udev->autosuspend, - USB_AUTOSUSPEND_DELAY); - usb_pm_unlock(udev); - return status; -} - /** * usb_autosuspend_device - delayed autosuspend of a USB device and its interfaces * @udev: the usb_device to autosuspend + * @dec_usage_cnt: flag to decrement @udev's PM-usage counter * * This routine should be called when a core subsystem is finished using * @udev and wants to allow it to autosuspend. Examples would be when * @udev's device file in usbfs is closed or after a configuration change. * - * @udev's usage counter is decremented. If it or any of the usage counters - * for an active interface is greater than 0, no autosuspend request will be - * queued. (If an interface driver does not support autosuspend then its - * usage counter is permanently positive.) Furthermore, if an interface - * driver requires remote-wakeup capability during autosuspend but remote - * wakeup is disabled, the autosuspend will fail. + * @dec_usage_cnt should be 1 if the subsystem previously incremented + * @udev's usage counter (such as by passing 1 to usb_autoresume_device); + * otherwise it should be 0. + * + * If the usage counter for @udev or any of its active interfaces is greater + * than 0, the autosuspend request will not be queued. (If an interface + * driver does not support autosuspend then its usage counter is permanently + * positive.) Likewise, if an interface driver requires remote-wakeup + * capability during autosuspend but remote wakeup is disabled, the + * autosuspend will fail. * * Often the caller will hold @udev's device lock, but this is not * necessary. * * This routine can run only in process context. */ -void usb_autosuspend_device(struct usb_device *udev) +void usb_autosuspend_device(struct usb_device *udev, int dec_usage_cnt) { - int status; - - status = usb_autopm_do_device(udev, -1); + usb_pm_lock(udev); + udev->pm_usage_cnt -= dec_usage_cnt; + if (udev->pm_usage_cnt <= 0) + queue_delayed_work(ksuspend_usb_wq, &udev->autosuspend, + USB_AUTOSUSPEND_DELAY); + usb_pm_unlock(udev); // dev_dbg(&udev->dev, "%s: cnt %d\n", // __FUNCTION__, udev->pm_usage_cnt); } @@ -1208,56 +1142,41 @@ void usb_autosuspend_device(struct usb_device *udev) /** * usb_autoresume_device - immediately autoresume a USB device and its interfaces * @udev: the usb_device to autoresume + * @inc_usage_cnt: flag to increment @udev's PM-usage counter * * This routine should be called when a core subsystem wants to use @udev - * and needs to guarantee that it is not suspended. No autosuspend will - * occur until usb_autosuspend_device is called. (Note that this will not - * prevent suspend events originating in the PM core.) Examples would be - * when @udev's device file in usbfs is opened or when a remote-wakeup - * request is received. + * and needs to guarantee that it is not suspended. In addition, the + * caller can prevent @udev from being autosuspended subsequently. (Note + * that this will not prevent suspend events originating in the PM core.) + * Examples would be when @udev's device file in usbfs is opened (autosuspend + * should be prevented until the file is closed) or when a remote-wakeup + * request is received (later autosuspends should not be prevented). * - * @udev's usage counter is incremented to prevent subsequent autosuspends. - * However if the autoresume fails then the usage counter is re-decremented. + * @inc_usage_cnt should be 1 to increment @udev's usage counter and prevent + * autosuspends. This prevention will persist until the usage counter is + * decremented again (such as by passing 1 to usb_autosuspend_device). + * Otherwise @inc_usage_cnt should be 0 to leave the usage counter unchanged. + * Regardless, if the autoresume fails then the usage counter is not + * incremented. * * Often the caller will hold @udev's device lock, but this is not * necessary (and attempting it might cause deadlock). * * This routine can run only in process context. */ -int usb_autoresume_device(struct usb_device *udev) +int usb_autoresume_device(struct usb_device *udev, int inc_usage_cnt) { int status; - status = usb_autopm_do_device(udev, 1); - // dev_dbg(&udev->dev, "%s: status %d cnt %d\n", - // __FUNCTION__, status, udev->pm_usage_cnt); - return status; -} - -/* Internal routine to adjust an interface's usage counter and change - * its device's autosuspend state. - */ -static int usb_autopm_do_interface(struct usb_interface *intf, - int inc_usage_cnt) -{ - struct usb_device *udev = interface_to_usbdev(intf); - int status = 0; - usb_pm_lock(udev); - if (intf->condition == USB_INTERFACE_UNBOUND) - status = -ENODEV; - else { - intf->pm_usage_cnt += inc_usage_cnt; - if (inc_usage_cnt >= 0 && intf->pm_usage_cnt > 0) { - udev->auto_pm = 1; - status = usb_resume_both(udev); - if (status != 0) - intf->pm_usage_cnt -= inc_usage_cnt; - } else if (inc_usage_cnt <= 0 && autosuspend_check(udev) == 0) - queue_delayed_work(ksuspend_usb_wq, &udev->autosuspend, - USB_AUTOSUSPEND_DELAY); - } + udev->pm_usage_cnt += inc_usage_cnt; + udev->auto_pm = 1; + status = usb_resume_both(udev); + if (status != 0) + udev->pm_usage_cnt -= inc_usage_cnt; usb_pm_unlock(udev); + // dev_dbg(&udev->dev, "%s: status %d cnt %d\n", + // __FUNCTION__, status, udev->pm_usage_cnt); return status; } @@ -1294,11 +1213,17 @@ static int usb_autopm_do_interface(struct usb_interface *intf, */ void usb_autopm_put_interface(struct usb_interface *intf) { - int status; + struct usb_device *udev = interface_to_usbdev(intf); - status = usb_autopm_do_interface(intf, -1); - // dev_dbg(&intf->dev, "%s: status %d cnt %d\n", - // __FUNCTION__, status, intf->pm_usage_cnt); + usb_pm_lock(udev); + if (intf->condition != USB_INTERFACE_UNBOUND && + --intf->pm_usage_cnt <= 0) { + queue_delayed_work(ksuspend_usb_wq, &udev->autosuspend, + USB_AUTOSUSPEND_DELAY); + } + usb_pm_unlock(udev); + // dev_dbg(&intf->dev, "%s: cnt %d\n", + // __FUNCTION__, intf->pm_usage_cnt); } EXPORT_SYMBOL_GPL(usb_autopm_put_interface); @@ -1335,37 +1260,26 @@ EXPORT_SYMBOL_GPL(usb_autopm_put_interface); */ int usb_autopm_get_interface(struct usb_interface *intf) { - int status; + struct usb_device *udev = interface_to_usbdev(intf); + int status; - status = usb_autopm_do_interface(intf, 1); + usb_pm_lock(udev); + if (intf->condition == USB_INTERFACE_UNBOUND) + status = -ENODEV; + else { + ++intf->pm_usage_cnt; + udev->auto_pm = 1; + status = usb_resume_both(udev); + if (status != 0) + --intf->pm_usage_cnt; + } + usb_pm_unlock(udev); // dev_dbg(&intf->dev, "%s: status %d cnt %d\n", // __FUNCTION__, status, intf->pm_usage_cnt); return status; } EXPORT_SYMBOL_GPL(usb_autopm_get_interface); -/** - * usb_autopm_set_interface - set a USB interface's autosuspend state - * @intf: the usb_interface whose state should be set - * - * This routine sets the autosuspend state of @intf's device according - * to @intf's usage counter, which the caller must have set previously. - * If the counter is <= 0, the device is autosuspended (if it isn't - * already suspended and if nothing else prevents the autosuspend). If - * the counter is > 0, the device is autoresumed (if it isn't already - * awake). - */ -int usb_autopm_set_interface(struct usb_interface *intf) -{ - int status; - - status = usb_autopm_do_interface(intf, 0); - // dev_dbg(&intf->dev, "%s: status %d cnt %d\n", - // __FUNCTION__, status, intf->pm_usage_cnt); - return status; -} -EXPORT_SYMBOL_GPL(usb_autopm_set_interface); - #endif /* CONFIG_USB_SUSPEND */ static int usb_suspend(struct device *dev, pm_message_t message) diff --git a/trunk/drivers/usb/core/endpoint.c b/trunk/drivers/usb/core/endpoint.c index c505b767cee1..3ebb90149e93 100644 --- a/trunk/drivers/usb/core/endpoint.c +++ b/trunk/drivers/usb/core/endpoint.c @@ -10,20 +10,15 @@ */ #include -#include -#include #include #include "usb.h" -#define MAX_ENDPOINT_MINORS (64*128*32) -static int usb_endpoint_major; -static DEFINE_IDR(endpoint_idr); +/* endpoint stuff */ struct ep_device { struct usb_endpoint_descriptor *desc; struct usb_device *udev; struct device dev; - int minor; }; #define to_ep_device(_dev) \ container_of(_dev, struct ep_device, dev) @@ -157,55 +152,6 @@ static struct attribute_group ep_dev_attr_grp = { .attrs = ep_dev_attrs, }; -static int usb_endpoint_major_init(void) -{ - dev_t dev; - int error; - - error = alloc_chrdev_region(&dev, 0, MAX_ENDPOINT_MINORS, - "usb_endpoint"); - if (error) { - err("unable to get a dynamic major for usb endpoints"); - return error; - } - usb_endpoint_major = MAJOR(dev); - - return error; -} - -static void usb_endpoint_major_cleanup(void) -{ - unregister_chrdev_region(MKDEV(usb_endpoint_major, 0), - MAX_ENDPOINT_MINORS); -} - -static int endpoint_get_minor(struct ep_device *ep_dev) -{ - static DEFINE_MUTEX(minor_lock); - int retval = -ENOMEM; - int id; - - mutex_lock(&minor_lock); - if (idr_pre_get(&endpoint_idr, GFP_KERNEL) == 0) - goto exit; - - retval = idr_get_new(&endpoint_idr, ep_dev, &id); - if (retval < 0) { - if (retval == -EAGAIN) - retval = -ENOMEM; - goto exit; - } - ep_dev->minor = id & MAX_ID_MASK; -exit: - mutex_unlock(&minor_lock); - return retval; -} - -static void endpoint_free_minor(struct ep_device *ep_dev) -{ - idr_remove(&endpoint_idr, ep_dev->minor); -} - static struct endpoint_class { struct kref kref; struct class *class; @@ -230,20 +176,11 @@ static int init_endpoint_class(void) ep_class->class = class_create(THIS_MODULE, "usb_endpoint"); if (IS_ERR(ep_class->class)) { result = IS_ERR(ep_class->class); - goto class_create_error; + kfree(ep_class); + ep_class = NULL; + goto exit; } - result = usb_endpoint_major_init(); - if (result) - goto endpoint_major_error; - - goto exit; - -endpoint_major_error: - class_destroy(ep_class->class); -class_create_error: - kfree(ep_class); - ep_class = NULL; exit: return result; } @@ -254,7 +191,6 @@ static void release_endpoint_class(struct kref *kref) class_destroy(ep_class->class); kfree(ep_class); ep_class = NULL; - usb_endpoint_major_cleanup(); } static void destroy_endpoint_class(void) @@ -277,6 +213,7 @@ int usb_create_ep_files(struct device *parent, { char name[8]; struct ep_device *ep_dev; + int minor; int retval; retval = init_endpoint_class(); @@ -286,19 +223,15 @@ int usb_create_ep_files(struct device *parent, ep_dev = kzalloc(sizeof(*ep_dev), GFP_KERNEL); if (!ep_dev) { retval = -ENOMEM; - goto error_alloc; + goto exit; } - retval = endpoint_get_minor(ep_dev); - if (retval) { - dev_err(parent, "can not allocate minor number for %s", - ep_dev->dev.bus_id); - goto error_register; - } + /* fun calculation to determine the minor of this endpoint */ + minor = (((udev->bus->busnum - 1) * 128) * 16) + (udev->devnum - 1); ep_dev->desc = &endpoint->desc; ep_dev->udev = udev; - ep_dev->dev.devt = MKDEV(usb_endpoint_major, ep_dev->minor); + ep_dev->dev.devt = MKDEV(442, minor); // FIXME fake number... ep_dev->dev.class = ep_class->class; ep_dev->dev.parent = parent; ep_dev->dev.release = ep_device_release; @@ -308,50 +241,49 @@ int usb_create_ep_files(struct device *parent, retval = device_register(&ep_dev->dev); if (retval) - goto error_chrdev; + goto error; retval = sysfs_create_group(&ep_dev->dev.kobj, &ep_dev_attr_grp); if (retval) goto error_group; + endpoint->ep_dev = ep_dev; + /* create the symlink to the old-style "ep_XX" directory */ sprintf(name, "ep_%02x", endpoint->desc.bEndpointAddress); - retval = sysfs_create_link(&parent->kobj, &ep_dev->dev.kobj, name); + retval = sysfs_create_link(&parent->kobj, + &endpoint->ep_dev->dev.kobj, name); if (retval) goto error_link; - endpoint->ep_dev = ep_dev; +exit: return retval; error_link: sysfs_remove_group(&ep_dev->dev.kobj, &ep_dev_attr_grp); + error_group: device_unregister(&ep_dev->dev); + endpoint->ep_dev = NULL; destroy_endpoint_class(); return retval; - -error_chrdev: - endpoint_free_minor(ep_dev); - -error_register: +error: kfree(ep_dev); -error_alloc: destroy_endpoint_class(); -exit: return retval; } void usb_remove_ep_files(struct usb_host_endpoint *endpoint) { - struct ep_device *ep_dev = endpoint->ep_dev; - if (ep_dev) { + if (endpoint->ep_dev) { char name[8]; sprintf(name, "ep_%02x", endpoint->desc.bEndpointAddress); - sysfs_remove_link(&ep_dev->dev.parent->kobj, name); - sysfs_remove_group(&ep_dev->dev.kobj, &ep_dev_attr_grp); - endpoint_free_minor(ep_dev); - device_unregister(&ep_dev->dev); + sysfs_remove_link(&endpoint->ep_dev->dev.parent->kobj, name); + sysfs_remove_group(&endpoint->ep_dev->dev.kobj, &ep_dev_attr_grp); + device_unregister(&endpoint->ep_dev->dev); endpoint->ep_dev = NULL; - destroy_endpoint_class(); } + destroy_endpoint_class(); } + + diff --git a/trunk/drivers/usb/core/hcd.c b/trunk/drivers/usb/core/hcd.c index 10064af65d17..e658089f7b50 100644 --- a/trunk/drivers/usb/core/hcd.c +++ b/trunk/drivers/usb/core/hcd.c @@ -256,9 +256,7 @@ static const u8 hs_rh_config_descriptor [] = { 0x05, /* __u8 ep_bDescriptorType; Endpoint */ 0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */ 0x03, /* __u8 ep_bmAttributes; Interrupt */ - /* __le16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) - * see hub.c:hub_configure() for details. */ - (USB_MAXCHILDREN + 1 + 7) / 8, 0x00, + 0x02, 0x00, /* __le16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */ 0x0c /* __u8 ep_bInterval; (256ms -- usb 2.0 spec) */ }; @@ -524,7 +522,7 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb) if (urb->status == -EINPROGRESS) urb->status = status; spin_unlock (&urb->lock); - usb_hcd_giveback_urb (hcd, urb); + usb_hcd_giveback_urb (hcd, urb, NULL); local_irq_restore (flags); return 0; } @@ -574,7 +572,7 @@ void usb_hcd_poll_rh_status(struct usb_hcd *hcd) /* local irqs are always blocked in completions */ if (length > 0) - usb_hcd_giveback_urb (hcd, urb); + usb_hcd_giveback_urb (hcd, urb, NULL); else hcd->poll_pending = 1; local_irq_restore (flags); @@ -658,7 +656,7 @@ static int usb_rh_urb_dequeue (struct usb_hcd *hcd, struct urb *urb) urb = NULL; /* wasn't fully queued */ spin_unlock (&hcd_root_hub_lock); if (urb) - usb_hcd_giveback_urb (hcd, urb); + usb_hcd_giveback_urb (hcd, urb, NULL); local_irq_restore (flags); } @@ -1500,6 +1498,7 @@ EXPORT_SYMBOL (usb_bus_start_enum); * usb_hcd_giveback_urb - return URB from HCD to device driver * @hcd: host controller returning the URB * @urb: urb being returned to the USB device driver. + * @regs: pt_regs, passed down to the URB completion handler * Context: in_interrupt() * * This hands the URB from HCD to its USB device driver, using its @@ -1508,7 +1507,7 @@ EXPORT_SYMBOL (usb_bus_start_enum); * the device driver won't cause problems if it frees, modifies, * or resubmits this URB. */ -void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb) +void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb, struct pt_regs *regs) { int at_root_hub; @@ -1535,7 +1534,7 @@ void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb) usbmon_urb_complete (&hcd->self, urb); /* pass ownership to the completion handler */ - urb->complete (urb); + urb->complete (urb, regs); atomic_dec (&urb->use_count); if (unlikely (urb->reject)) wake_up (&usb_kill_urb_queue); @@ -1554,7 +1553,7 @@ EXPORT_SYMBOL (usb_hcd_giveback_urb); * If the controller isn't HALTed, calls the driver's irq handler. * Checks whether the controller is now dead. */ -irqreturn_t usb_hcd_irq (int irq, void *__hcd) +irqreturn_t usb_hcd_irq (int irq, void *__hcd, struct pt_regs * r) { struct usb_hcd *hcd = __hcd; int start = hcd->state; @@ -1562,7 +1561,7 @@ irqreturn_t usb_hcd_irq (int irq, void *__hcd) if (unlikely(start == HC_STATE_HALT || !test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))) return IRQ_NONE; - if (hcd->driver->irq (hcd) == IRQ_NONE) + if (hcd->driver->irq (hcd, r) == IRQ_NONE) return IRQ_NONE; set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); diff --git a/trunk/drivers/usb/core/hcd.h b/trunk/drivers/usb/core/hcd.h index 8f8df0d4382e..676877c15f81 100644 --- a/trunk/drivers/usb/core/hcd.h +++ b/trunk/drivers/usb/core/hcd.h @@ -143,13 +143,15 @@ struct hcd_timeout { /* timeouts we allocate */ /*-------------------------------------------------------------------------*/ +struct pt_regs; + struct hc_driver { const char *description; /* "ehci-hcd" etc */ const char *product_desc; /* product/vendor string */ size_t hcd_priv_size; /* size of private data */ /* irq handler */ - irqreturn_t (*irq) (struct usb_hcd *hcd); + irqreturn_t (*irq) (struct usb_hcd *hcd, struct pt_regs *regs); int flags; #define HCD_MEMORY 0x0001 /* HC regs use memory (else I/O) */ @@ -203,7 +205,8 @@ struct hc_driver { extern int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags); extern int usb_hcd_unlink_urb (struct urb *urb, int status); -extern void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb); +extern void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb, + struct pt_regs *regs); extern void usb_hcd_endpoint_disable (struct usb_device *udev, struct usb_host_endpoint *ep); extern int usb_hcd_get_frame_number (struct usb_device *udev); @@ -245,7 +248,7 @@ void hcd_buffer_free (struct usb_bus *bus, size_t size, void *addr, dma_addr_t dma); /* generic bus glue, needed for host controllers that don't use PCI */ -extern irqreturn_t usb_hcd_irq (int irq, void *__hcd); +extern irqreturn_t usb_hcd_irq (int irq, void *__hcd, struct pt_regs *r); extern void usb_hc_died (struct usb_hcd *hcd); extern void usb_hcd_poll_rh_status(struct usb_hcd *hcd); diff --git a/trunk/drivers/usb/core/hub.c b/trunk/drivers/usb/core/hub.c index 0ce393eb3c4b..7676690a0386 100644 --- a/trunk/drivers/usb/core/hub.c +++ b/trunk/drivers/usb/core/hub.c @@ -31,47 +31,6 @@ #include "hcd.h" #include "hub.h" -struct usb_hub { - struct device *intfdev; /* the "interface" device */ - struct usb_device *hdev; - struct urb *urb; /* for interrupt polling pipe */ - - /* buffer for urb ... with extra space in case of babble */ - char (*buffer)[8]; - dma_addr_t buffer_dma; /* DMA address for buffer */ - union { - struct usb_hub_status hub; - struct usb_port_status port; - } *status; /* buffer for status reports */ - - int error; /* last reported error */ - int nerrors; /* track consecutive errors */ - - struct list_head event_list; /* hubs w/data or errs ready */ - unsigned long event_bits[1]; /* status change bitmask */ - unsigned long change_bits[1]; /* ports with logical connect - status change */ - unsigned long busy_bits[1]; /* ports being reset or - resumed */ -#if USB_MAXCHILDREN > 31 /* 8*sizeof(unsigned long) - 1 */ -#error event_bits[] is too short! -#endif - - struct usb_hub_descriptor *descriptor; /* class descriptor */ - struct usb_tt tt; /* Transaction Translator */ - - unsigned mA_per_port; /* current for each child */ - - unsigned limited_power:1; - unsigned quiescing:1; - unsigned activating:1; - - unsigned has_indicators:1; - u8 indicator[USB_MAXCHILDREN]; - struct work_struct leds; -}; - - /* Protect struct usb_device->state and ->children members * Note: Both are also protected by ->dev.sem, except that ->state can * change to USB_STATE_NOTATTACHED even when the semaphore isn't held. */ @@ -86,16 +45,6 @@ static DECLARE_WAIT_QUEUE_HEAD(khubd_wait); static struct task_struct *khubd_task; -/* multithreaded probe logic */ -static int multithread_probe = -#ifdef CONFIG_USB_MULTITHREAD_PROBE - 1; -#else - 0; -#endif -module_param(multithread_probe, bool, S_IRUGO); -MODULE_PARM_DESC(multithread_probe, "Run each USB device probe in a new thread"); - /* cycle leds on hubs that aren't blinking for attention */ static int blinkenlights = 0; module_param (blinkenlights, bool, S_IRUGO); @@ -327,9 +276,6 @@ static void kick_khubd(struct usb_hub *hub) { unsigned long flags; - /* Suppress autosuspend until khubd runs */ - to_usb_interface(hub->intfdev)->pm_usage_cnt = 1; - spin_lock_irqsave(&hub_event_lock, flags); if (list_empty(&hub->event_list)) { list_add_tail(&hub->event_list, &hub_event_list); @@ -345,7 +291,7 @@ void usb_kick_khubd(struct usb_device *hdev) /* completion function, fires on port status changes and various faults */ -static void hub_irq(struct urb *urb) +static void hub_irq(struct urb *urb, struct pt_regs *regs) { struct usb_hub *hub = urb->context; int status; @@ -511,6 +457,7 @@ static void hub_quiesce(struct usb_hub *hub) /* (nonblocking) khubd and related activity won't re-trigger */ hub->quiescing = 1; hub->activating = 0; + hub->resume_root_hub = 0; /* (blocking) stop khubd and related activity */ usb_kill_urb(hub->urb); @@ -526,7 +473,7 @@ static void hub_activate(struct usb_hub *hub) hub->quiescing = 0; hub->activating = 1; - + hub->resume_root_hub = 0; status = usb_submit_urb(hub->urb, GFP_NOIO); if (status < 0) dev_err(hub->intfdev, "activate --> %d\n", status); @@ -812,12 +759,7 @@ static int hub_configure(struct usb_hub *hub, dev_dbg(hub_dev, "%sover-current condition exists\n", (hubstatus & HUB_STATUS_OVERCURRENT) ? "" : "no "); - /* set up the interrupt endpoint - * We use the EP's maxpacket size instead of (PORTS+1+7)/8 - * bytes as USB2.0[11.12.3] says because some hubs are known - * to send more data (and thus cause overflow). For root hubs, - * maxpktsize is defined in hcd.c's fake endpoint descriptors - * to be big enough for at least USB_MAXCHILDREN ports. */ + /* set up the interrupt endpoint */ pipe = usb_rcvintpipe(hdev, endpoint->bEndpointAddress); maxp = usb_maxpacket(hdev, pipe, usb_pipeout(pipe)); @@ -941,7 +883,6 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) INIT_WORK(&hub->leds, led_work, hub); usb_set_intfdata (intf, hub); - intf->needs_remote_wakeup = 1; if (hdev->speed == USB_SPEED_HIGH) highspeed_hubs++; @@ -1039,8 +980,6 @@ static void recursively_mark_NOTATTACHED(struct usb_device *udev) if (udev->children[i]) recursively_mark_NOTATTACHED(udev->children[i]); } - if (udev->state == USB_STATE_SUSPENDED) - udev->discon_suspended = 1; udev->state = USB_STATE_NOTATTACHED; } @@ -1230,14 +1169,6 @@ void usb_disconnect(struct usb_device **pdev) *pdev = NULL; spin_unlock_irq(&device_state_lock); - /* Decrement the parent's count of unsuspended children */ - if (udev->parent) { - usb_pm_lock(udev); - if (!udev->discon_suspended) - usb_autosuspend_device(udev->parent); - usb_pm_unlock(udev); - } - put_device(&udev->dev); } @@ -1257,20 +1188,31 @@ static inline void show_string(struct usb_device *udev, char *id, char *string) #ifdef CONFIG_USB_OTG #include "otg_whitelist.h" -static int __usb_port_suspend(struct usb_device *, int port1); #endif -static int __usb_new_device(void *void_data) +/** + * usb_new_device - perform initial device setup (usbcore-internal) + * @udev: newly addressed device (in ADDRESS state) + * + * This is called with devices which have been enumerated, but not yet + * configured. The device descriptor is available, but not descriptors + * for any device configuration. The caller must have locked either + * the parent hub (if udev is a normal device) or else the + * usb_bus_list_lock (if udev is a root hub). The parent's pointer to + * udev has already been installed, but udev is not yet visible through + * sysfs or other filesystem code. + * + * Returns 0 for success (device is configured and listed, with its + * interfaces, in sysfs); else a negative errno value. + * + * This call is synchronous, and may not be used in an interrupt context. + * + * Only the hub driver or root-hub registrar should ever call this. + */ +int usb_new_device(struct usb_device *udev) { - struct usb_device *udev = void_data; int err; - /* Lock ourself into memory in order to keep a probe sequence - * sleeping in a new thread from allowing us to be unloaded. - */ - if (!try_module_get(THIS_MODULE)) - return -EINVAL; - err = usb_get_configuration(udev); if (err < 0) { dev_err(&udev->dev, "can't read configurations, error %d\n", @@ -1347,6 +1289,8 @@ static int __usb_new_device(void *void_data) * (Includes HNP test device.) */ if (udev->bus->b_hnp_enable || udev->bus->is_b_host) { + static int __usb_port_suspend(struct usb_device *, + int port1); err = __usb_port_suspend(udev, udev->bus->otg_port); if (err < 0) dev_dbg(&udev->dev, "HNP fail, %d\n", err); @@ -1366,56 +1310,13 @@ static int __usb_new_device(void *void_data) goto fail; } - /* Increment the parent's count of unsuspended children */ - if (udev->parent) - usb_autoresume_device(udev->parent); - -exit: - module_put(THIS_MODULE); - return err; + return 0; fail: usb_set_device_state(udev, USB_STATE_NOTATTACHED); - goto exit; + return err; } -/** - * usb_new_device - perform initial device setup (usbcore-internal) - * @udev: newly addressed device (in ADDRESS state) - * - * This is called with devices which have been enumerated, but not yet - * configured. The device descriptor is available, but not descriptors - * for any device configuration. The caller must have locked either - * the parent hub (if udev is a normal device) or else the - * usb_bus_list_lock (if udev is a root hub). The parent's pointer to - * udev has already been installed, but udev is not yet visible through - * sysfs or other filesystem code. - * - * The return value for this function depends on if the - * multithread_probe variable is set or not. If it's set, it will - * return a if the probe thread was successfully created or not. If the - * variable is not set, it will return if the device is configured - * properly or not. interfaces, in sysfs); else a negative errno value. - * - * This call is synchronous, and may not be used in an interrupt context. - * - * Only the hub driver or root-hub registrar should ever call this. - */ -int usb_new_device(struct usb_device *udev) -{ - struct task_struct *probe_task; - int ret = 0; - - if (multithread_probe) { - probe_task = kthread_run(__usb_new_device, udev, - "usb-probe-%s", udev->devnum); - if (IS_ERR(probe_task)) - ret = PTR_ERR(probe_task); - } else - ret = __usb_new_device(udev); - - return ret; -} static int hub_port_status(struct usb_hub *hub, int port1, u16 *status, u16 *change) @@ -1423,12 +1324,10 @@ static int hub_port_status(struct usb_hub *hub, int port1, int ret; ret = get_port_status(hub->hdev, port1, &hub->status->port); - if (ret < 4) { + if (ret < 0) dev_err (hub->intfdev, "%s failed (err = %d)\n", __FUNCTION__, ret); - if (ret >= 0) - ret = -EIO; - } else { + else { *status = le16_to_cpu(hub->status->port.wPortStatus); *change = le16_to_cpu(hub->status->port.wPortChange); ret = 0; @@ -1776,12 +1675,6 @@ static int hub_port_resume(struct usb_hub *hub, int port1, struct usb_device *udev) { int status; - u16 portchange, portstatus; - - /* Skip the initial Clear-Suspend step for a remote wakeup */ - status = hub_port_status(hub, port1, &portstatus, &portchange); - if (status == 0 && !(portstatus & USB_PORT_STAT_SUSPEND)) - goto SuspendCleared; // dev_dbg(hub->intfdev, "resume port %d\n", port1); @@ -1795,6 +1688,9 @@ hub_port_resume(struct usb_hub *hub, int port1, struct usb_device *udev) "can't resume port %d, status %d\n", port1, status); } else { + u16 devstatus; + u16 portchange; + /* drive resume for at least 20 msec */ if (udev) dev_dbg(&udev->dev, "usb %sresume\n", @@ -1809,15 +1705,16 @@ hub_port_resume(struct usb_hub *hub, int port1, struct usb_device *udev) * stop resume signaling. Then finish the resume * sequence. */ - status = hub_port_status(hub, port1, &portstatus, &portchange); -SuspendCleared: + devstatus = portchange = 0; + status = hub_port_status(hub, port1, + &devstatus, &portchange); if (status < 0 - || (portstatus & LIVE_FLAGS) != LIVE_FLAGS - || (portstatus & USB_PORT_STAT_SUSPEND) != 0 + || (devstatus & LIVE_FLAGS) != LIVE_FLAGS + || (devstatus & USB_PORT_STAT_SUSPEND) != 0 ) { dev_dbg(hub->intfdev, "port %d status %04x.%04x after resume, %d\n", - port1, portchange, portstatus, status); + port1, portchange, devstatus, status); if (status >= 0) status = -ENODEV; } else { @@ -1878,16 +1775,23 @@ static int remote_wakeup(struct usb_device *udev) { int status = 0; + /* All this just to avoid sending a port-resume message + * to the parent hub! */ + usb_lock_device(udev); + usb_pm_lock(udev); if (udev->state == USB_STATE_SUSPENDED) { dev_dbg(&udev->dev, "usb %sresume\n", "wakeup-"); - status = usb_autoresume_device(udev); - - /* Give the interface drivers a chance to do something, - * then autosuspend the device again. */ + /* TRSMRCY = 10 msec */ + msleep(10); + status = finish_port_resume(udev); if (status == 0) - usb_autosuspend_device(udev); + udev->dev.power.power_state.event = PM_EVENT_ON; } + usb_pm_unlock(udev); + + if (status == 0) + usb_autoresume_device(udev, 0); usb_unlock_device(udev); return status; } @@ -1951,8 +1855,6 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg) } } - dev_dbg(&intf->dev, "%s\n", __FUNCTION__); - /* "global suspend" of the downstream HC-to-USB interface */ if (!hdev->parent) { struct usb_bus *bus = hdev->bus; @@ -1975,12 +1877,10 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg) static int hub_resume(struct usb_interface *intf) { + struct usb_device *hdev = interface_to_usbdev(intf); struct usb_hub *hub = usb_get_intfdata (intf); - struct usb_device *hdev = hub->hdev; int status; - dev_dbg(&intf->dev, "%s\n", __FUNCTION__); - /* "global resume" of the downstream HC-to-USB interface */ if (!hdev->parent) { struct usb_bus *bus = hdev->bus; @@ -2019,6 +1919,7 @@ void usb_resume_root_hub(struct usb_device *hdev) { struct usb_hub *hub = hdev_to_hub(hdev); + hub->resume_root_hub = 1; kick_khubd(hub); } @@ -2655,13 +2556,16 @@ static void hub_events(void) intf = to_usb_interface(hub->intfdev); hub_dev = &intf->dev; - dev_dbg(hub_dev, "state %d ports %d chg %04x evt %04x\n", + i = hub->resume_root_hub; + + dev_dbg(hub_dev, "state %d ports %d chg %04x evt %04x%s\n", hdev->state, hub->descriptor ? hub->descriptor->bNbrPorts : 0, /* NOTE: expects max 15 ports... */ (u16) hub->change_bits[0], - (u16) hub->event_bits[0]); + (u16) hub->event_bits[0], + i ? ", resume root" : ""); usb_get_intf(intf); spin_unlock_irq(&hub_event_lock); @@ -2682,16 +2586,16 @@ static void hub_events(void) goto loop; } - /* Autoresume */ - ret = usb_autopm_get_interface(intf); - if (ret) { - dev_dbg(hub_dev, "Can't autoresume: %d\n", ret); - goto loop; - } + /* Is this is a root hub wanting to reactivate the downstream + * ports? If so, be sure the interface resumes even if its + * stub "device" node was never suspended. + */ + if (i) + usb_autoresume_device(hdev, 0); - /* If this is an inactive hub, do nothing */ + /* If this is an inactive or suspended hub, do nothing */ if (hub->quiescing) - goto loop_autopm; + goto loop; if (hub->error) { dev_dbg (hub_dev, "resetting for error %d\n", @@ -2701,7 +2605,7 @@ static void hub_events(void) if (ret) { dev_dbg (hub_dev, "error resetting hub: %d\n", ret); - goto loop_autopm; + goto loop; } hub->nerrors = 0; @@ -2829,10 +2733,6 @@ static void hub_events(void) if (!hdev->parent && !hub->busy_bits[0]) usb_enable_root_hub_irq(hdev->bus); -loop_autopm: - /* Allow autosuspend if we're not going to run again */ - if (list_empty(&hub->event_list)) - usb_autopm_enable(intf); loop: usb_unlock_device(hdev); usb_put_intf(intf); @@ -2874,7 +2774,6 @@ static struct usb_driver hub_driver = { .post_reset = hub_post_reset, .ioctl = hub_ioctl, .id_table = hub_id_table, - .supports_autosuspend = 1, }; int usb_hub_init(void) @@ -3099,7 +2998,7 @@ int usb_reset_composite_device(struct usb_device *udev, } /* Prevent autosuspend during the reset */ - usb_autoresume_device(udev); + usb_autoresume_device(udev, 1); if (iface && iface->condition != USB_INTERFACE_BINDING) iface = NULL; @@ -3142,7 +3041,7 @@ int usb_reset_composite_device(struct usb_device *udev, } } - usb_autosuspend_device(udev); + usb_autosuspend_device(udev, 1); return ret; } EXPORT_SYMBOL(usb_reset_composite_device); diff --git a/trunk/drivers/usb/core/hub.h b/trunk/drivers/usb/core/hub.h index cf9559c6c9b6..0f8e82a4d480 100644 --- a/trunk/drivers/usb/core/hub.h +++ b/trunk/drivers/usb/core/hub.h @@ -192,4 +192,45 @@ struct usb_tt_clear { extern void usb_hub_tt_clear_buffer (struct usb_device *dev, int pipe); +struct usb_hub { + struct device *intfdev; /* the "interface" device */ + struct usb_device *hdev; + struct urb *urb; /* for interrupt polling pipe */ + + /* buffer for urb ... with extra space in case of babble */ + char (*buffer)[8]; + dma_addr_t buffer_dma; /* DMA address for buffer */ + union { + struct usb_hub_status hub; + struct usb_port_status port; + } *status; /* buffer for status reports */ + + int error; /* last reported error */ + int nerrors; /* track consecutive errors */ + + struct list_head event_list; /* hubs w/data or errs ready */ + unsigned long event_bits[1]; /* status change bitmask */ + unsigned long change_bits[1]; /* ports with logical connect + status change */ + unsigned long busy_bits[1]; /* ports being reset or + resumed */ +#if USB_MAXCHILDREN > 31 /* 8*sizeof(unsigned long) - 1 */ +#error event_bits[] is too short! +#endif + + struct usb_hub_descriptor *descriptor; /* class descriptor */ + struct usb_tt tt; /* Transaction Translator */ + + unsigned mA_per_port; /* current for each child */ + + unsigned limited_power:1; + unsigned quiescing:1; + unsigned activating:1; + unsigned resume_root_hub:1; + + unsigned has_indicators:1; + enum hub_led_mode indicator[USB_MAXCHILDREN]; + struct work_struct leds; +}; + #endif /* __LINUX_HUB_H */ diff --git a/trunk/drivers/usb/core/message.c b/trunk/drivers/usb/core/message.c index 29b0fa9ff9d0..85b1cd18336f 100644 --- a/trunk/drivers/usb/core/message.c +++ b/trunk/drivers/usb/core/message.c @@ -17,7 +17,7 @@ #include "hcd.h" /* for usbcore internals */ #include "usb.h" -static void usb_api_blocking_completion(struct urb *urb) +static void usb_api_blocking_completion(struct urb *urb, struct pt_regs *regs) { complete((struct completion *)urb->context); } @@ -246,7 +246,7 @@ static void sg_clean (struct usb_sg_request *io) io->dev = NULL; } -static void sg_complete (struct urb *urb) +static void sg_complete (struct urb *urb, struct pt_regs *regs) { struct usb_sg_request *io = urb->context; @@ -764,7 +764,7 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size) err = -EINVAL; goto errout; } else { - dev->have_langid = 1; + dev->have_langid = -1; dev->string_langid = tbuf[2] | (tbuf[3]<< 8); /* always use the first langid listed */ dev_dbg (&dev->dev, "default language 0x%04x\n", @@ -828,7 +828,10 @@ char *usb_cache_string(struct usb_device *udev, int index) * Context: !in_interrupt () * * Updates the copy of the device descriptor stored in the device structure, - * which dedicates space for this purpose. + * which dedicates space for this purpose. Note that several fields are + * converted to the host CPU's byte order: the USB version (bcdUSB), and + * vendors product and version fields (idVendor, idProduct, and bcdDevice). + * That lets device drivers compare against non-byteswapped constants. * * Not exported, only for use by the core. If drivers really want to read * the device descriptor directly, they can call usb_get_descriptor() with @@ -1398,7 +1401,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration) } /* Wake up the device so we can send it the Set-Config request */ - ret = usb_autoresume_device(dev); + ret = usb_autoresume_device(dev, 1); if (ret) goto free_interfaces; @@ -1421,7 +1424,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration) dev->actconfig = cp; if (!cp) { usb_set_device_state(dev, USB_STATE_ADDRESS); - usb_autosuspend_device(dev); + usb_autosuspend_device(dev, 1); goto free_interfaces; } usb_set_device_state(dev, USB_STATE_CONFIGURED); @@ -1490,7 +1493,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration) usb_create_sysfs_intf_files (intf); } - usb_autosuspend_device(dev); + usb_autosuspend_device(dev, 1); return 0; } diff --git a/trunk/drivers/usb/core/usb.c b/trunk/drivers/usb/core/usb.c index 81cb52564e68..467cb02832f3 100644 --- a/trunk/drivers/usb/core/usb.c +++ b/trunk/drivers/usb/core/usb.c @@ -200,6 +200,13 @@ static void ksuspend_usb_cleanup(void) destroy_workqueue(ksuspend_usb_wq); } +#else + +#define ksuspend_usb_init() 0 +#define ksuspend_usb_cleanup() do {} while (0) + +#endif + #ifdef CONFIG_USB_SUSPEND /* usb_autosuspend_work - callback routine to autosuspend a USB device */ @@ -218,14 +225,7 @@ static void usb_autosuspend_work(void *_udev) static void usb_autosuspend_work(void *_udev) {} -#endif /* CONFIG_USB_SUSPEND */ - -#else - -#define ksuspend_usb_init() 0 -#define ksuspend_usb_cleanup() do {} while (0) - -#endif /* CONFIG_PM */ +#endif /** * usb_alloc_dev - usb device constructor (usbcore-internal) @@ -537,6 +537,138 @@ int usb_get_current_frame_number(struct usb_device *dev) return usb_hcd_get_frame_number (dev); } +/** + * usb_endpoint_dir_in - check if the endpoint has IN direction + * @epd: endpoint to be checked + * + * Returns true if the endpoint is of type IN, otherwise it returns false. + */ +int usb_endpoint_dir_in(const struct usb_endpoint_descriptor *epd) +{ + return ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN); +} + +/** + * usb_endpoint_dir_out - check if the endpoint has OUT direction + * @epd: endpoint to be checked + * + * Returns true if the endpoint is of type OUT, otherwise it returns false. + */ +int usb_endpoint_dir_out(const struct usb_endpoint_descriptor *epd) +{ + return ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT); +} + +/** + * usb_endpoint_xfer_bulk - check if the endpoint has bulk transfer type + * @epd: endpoint to be checked + * + * Returns true if the endpoint is of type bulk, otherwise it returns false. + */ +int usb_endpoint_xfer_bulk(const struct usb_endpoint_descriptor *epd) +{ + return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == + USB_ENDPOINT_XFER_BULK); +} + +/** + * usb_endpoint_xfer_int - check if the endpoint has interrupt transfer type + * @epd: endpoint to be checked + * + * Returns true if the endpoint is of type interrupt, otherwise it returns + * false. + */ +int usb_endpoint_xfer_int(const struct usb_endpoint_descriptor *epd) +{ + return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == + USB_ENDPOINT_XFER_INT); +} + +/** + * usb_endpoint_xfer_isoc - check if the endpoint has isochronous transfer type + * @epd: endpoint to be checked + * + * Returns true if the endpoint is of type isochronous, otherwise it returns + * false. + */ +int usb_endpoint_xfer_isoc(const struct usb_endpoint_descriptor *epd) +{ + return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == + USB_ENDPOINT_XFER_ISOC); +} + +/** + * usb_endpoint_is_bulk_in - check if the endpoint is bulk IN + * @epd: endpoint to be checked + * + * Returns true if the endpoint has bulk transfer type and IN direction, + * otherwise it returns false. + */ +int usb_endpoint_is_bulk_in(const struct usb_endpoint_descriptor *epd) +{ + return (usb_endpoint_xfer_bulk(epd) && usb_endpoint_dir_in(epd)); +} + +/** + * usb_endpoint_is_bulk_out - check if the endpoint is bulk OUT + * @epd: endpoint to be checked + * + * Returns true if the endpoint has bulk transfer type and OUT direction, + * otherwise it returns false. + */ +int usb_endpoint_is_bulk_out(const struct usb_endpoint_descriptor *epd) +{ + return (usb_endpoint_xfer_bulk(epd) && usb_endpoint_dir_out(epd)); +} + +/** + * usb_endpoint_is_int_in - check if the endpoint is interrupt IN + * @epd: endpoint to be checked + * + * Returns true if the endpoint has interrupt transfer type and IN direction, + * otherwise it returns false. + */ +int usb_endpoint_is_int_in(const struct usb_endpoint_descriptor *epd) +{ + return (usb_endpoint_xfer_int(epd) && usb_endpoint_dir_in(epd)); +} + +/** + * usb_endpoint_is_int_out - check if the endpoint is interrupt OUT + * @epd: endpoint to be checked + * + * Returns true if the endpoint has interrupt transfer type and OUT direction, + * otherwise it returns false. + */ +int usb_endpoint_is_int_out(const struct usb_endpoint_descriptor *epd) +{ + return (usb_endpoint_xfer_int(epd) && usb_endpoint_dir_out(epd)); +} + +/** + * usb_endpoint_is_isoc_in - check if the endpoint is isochronous IN + * @epd: endpoint to be checked + * + * Returns true if the endpoint has isochronous transfer type and IN direction, + * otherwise it returns false. + */ +int usb_endpoint_is_isoc_in(const struct usb_endpoint_descriptor *epd) +{ + return (usb_endpoint_xfer_isoc(epd) && usb_endpoint_dir_in(epd)); +} + +/** + * usb_endpoint_is_isoc_out - check if the endpoint is isochronous OUT + * @epd: endpoint to be checked + * + * Returns true if the endpoint has isochronous transfer type and OUT direction, + * otherwise it returns false. + */ +int usb_endpoint_is_isoc_out(const struct usb_endpoint_descriptor *epd) +{ + return (usb_endpoint_xfer_isoc(epd) && usb_endpoint_dir_out(epd)); +} + /*-------------------------------------------------------------------*/ /* * __usb_get_extra_descriptor() finds a descriptor of specific type in the @@ -970,6 +1102,18 @@ EXPORT_SYMBOL(__usb_get_extra_descriptor); EXPORT_SYMBOL(usb_find_device); EXPORT_SYMBOL(usb_get_current_frame_number); +EXPORT_SYMBOL_GPL(usb_endpoint_dir_in); +EXPORT_SYMBOL_GPL(usb_endpoint_dir_out); +EXPORT_SYMBOL_GPL(usb_endpoint_xfer_bulk); +EXPORT_SYMBOL_GPL(usb_endpoint_xfer_int); +EXPORT_SYMBOL_GPL(usb_endpoint_xfer_isoc); +EXPORT_SYMBOL_GPL(usb_endpoint_is_bulk_in); +EXPORT_SYMBOL_GPL(usb_endpoint_is_bulk_out); +EXPORT_SYMBOL_GPL(usb_endpoint_is_int_in); +EXPORT_SYMBOL_GPL(usb_endpoint_is_int_out); +EXPORT_SYMBOL_GPL(usb_endpoint_is_isoc_in); +EXPORT_SYMBOL_GPL(usb_endpoint_is_isoc_out); + EXPORT_SYMBOL (usb_buffer_alloc); EXPORT_SYMBOL (usb_buffer_free); diff --git a/trunk/drivers/usb/core/usb.h b/trunk/drivers/usb/core/usb.h index 17830a81be14..13322e33f912 100644 --- a/trunk/drivers/usb/core/usb.h +++ b/trunk/drivers/usb/core/usb.h @@ -64,13 +64,14 @@ static inline void usb_pm_unlock(struct usb_device *udev) {} #define USB_AUTOSUSPEND_DELAY (HZ*2) -extern void usb_autosuspend_device(struct usb_device *udev); -extern int usb_autoresume_device(struct usb_device *udev); +extern void usb_autosuspend_device(struct usb_device *udev, int dec_busy_cnt); +extern int usb_autoresume_device(struct usb_device *udev, int inc_busy_cnt); #else -#define usb_autosuspend_device(udev) do {} while (0) -static inline int usb_autoresume_device(struct usb_device *udev) +#define usb_autosuspend_device(udev, dec_busy_cnt) do {} while (0) +static inline int usb_autoresume_device(struct usb_device *udev, + int inc_busy_cnt) { return 0; } diff --git a/trunk/drivers/usb/gadget/at91_udc.c b/trunk/drivers/usb/gadget/at91_udc.c index 72f3db99ff94..77beba485a84 100644 --- a/trunk/drivers/usb/gadget/at91_udc.c +++ b/trunk/drivers/usb/gadget/at91_udc.c @@ -1366,7 +1366,7 @@ static void handle_ep0(struct at91_udc *udc) } } -static irqreturn_t at91_udc_irq (int irq, void *_udc) +static irqreturn_t at91_udc_irq (int irq, void *_udc, struct pt_regs *r) { struct at91_udc *udc = _udc; u32 rescans = 5; @@ -1552,7 +1552,7 @@ static struct at91_udc controller = { /* ep6 and ep7 are also reserved (custom silicon might use them) */ }; -static irqreturn_t at91_vbus_irq(int irq, void *_udc) +static irqreturn_t at91_vbus_irq(int irq, void *_udc, struct pt_regs *r) { struct at91_udc *udc = _udc; unsigned value; diff --git a/trunk/drivers/usb/gadget/dummy_hcd.c b/trunk/drivers/usb/gadget/dummy_hcd.c index f1f32d7be5f9..4d2946e540cf 100644 --- a/trunk/drivers/usb/gadget/dummy_hcd.c +++ b/trunk/drivers/usb/gadget/dummy_hcd.c @@ -1551,7 +1551,7 @@ static void dummy_timer (unsigned long _dum) ep->already_seen = ep->setup_stage = 0; spin_unlock (&dum->lock); - usb_hcd_giveback_urb (dummy_to_hcd(dum), urb); + usb_hcd_giveback_urb (dummy_to_hcd(dum), urb, NULL); spin_lock (&dum->lock); goto restart; diff --git a/trunk/drivers/usb/gadget/ether.c b/trunk/drivers/usb/gadget/ether.c index 3bd1dfe565c1..1c17d26d03b8 100644 --- a/trunk/drivers/usb/gadget/ether.c +++ b/trunk/drivers/usb/gadget/ether.c @@ -1894,13 +1894,13 @@ static int eth_start_xmit (struct sk_buff *skb, struct net_device *net) if (!eth_is_promisc (dev)) { u8 *dest = skb->data; - if (is_multicast_ether_addr(dest)) { + if (dest [0] & 0x01) { u16 type; /* ignores USB_CDC_PACKET_TYPE_MULTICAST and host * SET_ETHERNET_MULTICAST_FILTERS requests */ - if (is_broadcast_ether_addr(dest)) + if (memcmp (dest, net->broadcast, ETH_ALEN) == 0) type = USB_CDC_PACKET_TYPE_BROADCAST; else type = USB_CDC_PACKET_TYPE_ALL_MULTICAST; diff --git a/trunk/drivers/usb/gadget/goku_udc.c b/trunk/drivers/usb/gadget/goku_udc.c index a3076da3f4eb..7cf2999e8616 100644 --- a/trunk/drivers/usb/gadget/goku_udc.c +++ b/trunk/drivers/usb/gadget/goku_udc.c @@ -1628,7 +1628,7 @@ static void ep0_setup(struct goku_udc *dev) handled = 1; \ } -static irqreturn_t goku_irq(int irq, void *_dev) +static irqreturn_t goku_irq(int irq, void *_dev, struct pt_regs *r) { struct goku_udc *dev = _dev; struct goku_udc_regs __iomem *regs = dev->regs; diff --git a/trunk/drivers/usb/gadget/lh7a40x_udc.c b/trunk/drivers/usb/gadget/lh7a40x_udc.c index 4a991564a03e..36db72579377 100644 --- a/trunk/drivers/usb/gadget/lh7a40x_udc.c +++ b/trunk/drivers/usb/gadget/lh7a40x_udc.c @@ -83,6 +83,7 @@ static int lh7a40x_queue(struct usb_ep *ep, struct usb_request *, gfp_t); static int lh7a40x_dequeue(struct usb_ep *ep, struct usb_request *); static int lh7a40x_set_halt(struct usb_ep *ep, int); static int lh7a40x_fifo_status(struct usb_ep *ep); +static int lh7a40x_fifo_status(struct usb_ep *ep); static void lh7a40x_fifo_flush(struct usb_ep *ep); static void lh7a40x_ep0_kick(struct lh7a40x_udc *dev, struct lh7a40x_ep *ep); static void lh7a40x_handle_ep0(struct lh7a40x_udc *dev, u32 intr); @@ -921,7 +922,7 @@ static void lh7a40x_reset_intr(struct lh7a40x_udc *dev) /* * lh7a40x usb client interrupt handler. */ -static irqreturn_t lh7a40x_udc_irq(int irq, void *_dev) +static irqreturn_t lh7a40x_udc_irq(int irq, void *_dev, struct pt_regs *r) { struct lh7a40x_udc *dev = _dev; diff --git a/trunk/drivers/usb/gadget/net2280.c b/trunk/drivers/usb/gadget/net2280.c index 0b590831582c..3bda37f9a35f 100644 --- a/trunk/drivers/usb/gadget/net2280.c +++ b/trunk/drivers/usb/gadget/net2280.c @@ -1040,7 +1040,6 @@ net2280_queue (struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) } /* else the irq handler advances the queue. */ - ep->responded = 1; if (req) list_add_tail (&req->queue, &ep->queue); done: @@ -1775,8 +1774,8 @@ static DEVICE_ATTR (queues, S_IRUGO, show_queues, NULL); #else -#define device_create_file(a,b) (0) -#define device_remove_file(a,b) do { } while (0) +#define device_create_file(a,b) do {} while (0) +#define device_remove_file device_create_file #endif @@ -2045,10 +2044,8 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver) return retval; } - retval = device_create_file (&dev->pdev->dev, &dev_attr_function); - if (retval) goto err_unbind; - retval = device_create_file (&dev->pdev->dev, &dev_attr_queues); - if (retval) goto err_func; + device_create_file (&dev->pdev->dev, &dev_attr_function); + device_create_file (&dev->pdev->dev, &dev_attr_queues); /* ... then enable host detection and ep0; and we're ready * for set_configuration as well as eventual disconnect. @@ -2063,14 +2060,6 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver) /* pci writes may still be posted */ return 0; - -err_func: - device_remove_file (&dev->pdev->dev, &dev_attr_function); -err_unbind: - driver->unbind (&dev->gadget); - dev->gadget.dev.driver = NULL; - dev->driver = NULL; - return retval; } EXPORT_SYMBOL (usb_gadget_register_driver); @@ -2189,8 +2178,7 @@ static void handle_ep_small (struct net2280_ep *ep) ep->stopped = 1; set_halt (ep); mode = 2; - } else if (ep->responded && - !req && !ep->stopped) + } else if (!req && !ep->stopped) write_fifo (ep, NULL); } } else { @@ -2205,7 +2193,7 @@ static void handle_ep_small (struct net2280_ep *ep) } else if (((t & (1 << DATA_OUT_PING_TOKEN_INTERRUPT)) && req && req->req.actual == req->req.length) - || (ep->responded && !req)) { + || !req) { ep->dev->protocol_stall = 1; set_halt (ep); ep->stopped = 1; @@ -2471,7 +2459,6 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat) /* we made the hardware handle most lowlevel requests; * everything else goes uplevel to the gadget code. */ - ep->responded = 1; switch (u.r.bRequest) { case USB_REQ_GET_STATUS: { struct net2280_ep *e; @@ -2540,7 +2527,6 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat) u.r.bRequestType, u.r.bRequest, w_value, w_index, w_length, readl (&ep->regs->ep_cfg)); - ep->responded = 0; spin_unlock (&dev->lock); tmp = dev->driver->setup (&dev->gadget, &u.r); spin_lock (&dev->lock); @@ -2767,7 +2753,7 @@ static void handle_stat1_irqs (struct net2280 *dev, u32 stat) DEBUG (dev, "unhandled irqstat1 %08x\n", stat); } -static irqreturn_t net2280_irq (int irq, void *_dev) +static irqreturn_t net2280_irq (int irq, void *_dev, struct pt_regs * r) { struct net2280 *dev = _dev; @@ -2988,10 +2974,8 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id) : "disabled"); the_controller = dev; - retval = device_register (&dev->gadget.dev); - if (retval) goto done; - retval = device_create_file (&pdev->dev, &dev_attr_registers); - if (retval) goto done; + device_register (&dev->gadget.dev); + device_create_file (&pdev->dev, &dev_attr_registers); return 0; diff --git a/trunk/drivers/usb/gadget/net2280.h b/trunk/drivers/usb/gadget/net2280.h index 44ca139983d8..957d6df34015 100644 --- a/trunk/drivers/usb/gadget/net2280.h +++ b/trunk/drivers/usb/gadget/net2280.h @@ -110,8 +110,7 @@ struct net2280_ep { out_overflow : 1, stopped : 1, is_in : 1, - is_iso : 1, - responded : 1; + is_iso : 1; }; static inline void allow_status (struct net2280_ep *ep) diff --git a/trunk/drivers/usb/gadget/omap_udc.c b/trunk/drivers/usb/gadget/omap_udc.c index 48a09fd89d18..8c18df869833 100644 --- a/trunk/drivers/usb/gadget/omap_udc.c +++ b/trunk/drivers/usb/gadget/omap_udc.c @@ -1815,7 +1815,8 @@ static void devstate_irq(struct omap_udc *udc, u16 irq_src) UDC_IRQ_SRC_REG = UDC_DS_CHG; } -static irqreturn_t omap_udc_irq(int irq, void *_udc) +static irqreturn_t +omap_udc_irq(int irq, void *_udc, struct pt_regs *r) { struct omap_udc *udc = _udc; u16 irq_src; @@ -1887,7 +1888,8 @@ static void pio_out_timer(unsigned long _ep) spin_unlock_irqrestore(&ep->udc->lock, flags); } -static irqreturn_t omap_udc_pio_irq(int irq, void *_dev) +static irqreturn_t +omap_udc_pio_irq(int irq, void *_dev, struct pt_regs *r) { u16 epn_stat, irq_src; irqreturn_t status = IRQ_NONE; @@ -1966,7 +1968,8 @@ static irqreturn_t omap_udc_pio_irq(int irq, void *_dev) } #ifdef USE_ISO -static irqreturn_t omap_udc_iso_irq(int irq, void *_dev) +static irqreturn_t +omap_udc_iso_irq(int irq, void *_dev, struct pt_regs *r) { struct omap_udc *udc = _dev; struct omap_ep *ep; diff --git a/trunk/drivers/usb/gadget/pxa2xx_udc.c b/trunk/drivers/usb/gadget/pxa2xx_udc.c index 1ed506e95985..f1adcf8b2023 100644 --- a/trunk/drivers/usb/gadget/pxa2xx_udc.c +++ b/trunk/drivers/usb/gadget/pxa2xx_udc.c @@ -43,11 +43,11 @@ #include #include #include -#include #include #include #include +#include #include #include #include @@ -110,7 +110,7 @@ static int use_dma = 1; module_param(use_dma, bool, 0); MODULE_PARM_DESC (use_dma, "true to use dma"); -static void dma_nodesc_handler (int dmach, void *_ep); +static void dma_nodesc_handler (int dmach, void *_ep, struct pt_regs *r); static void kick_dma(struct pxa2xx_ep *ep, struct pxa2xx_request *req); #ifdef USE_OUT_DMA @@ -828,7 +828,7 @@ static void cancel_dma(struct pxa2xx_ep *ep) } /* dma channel stopped ... normal tx end (IN), or on error (IN/OUT) */ -static void dma_nodesc_handler(int dmach, void *_ep) +static void dma_nodesc_handler(int dmach, void *_ep, struct pt_regs *r) { struct pxa2xx_ep *ep = _ep; struct pxa2xx_request *req; @@ -1724,7 +1724,7 @@ EXPORT_SYMBOL(usb_gadget_unregister_driver); */ static irqreturn_t -lubbock_vbus_irq(int irq, void *_dev) +lubbock_vbus_irq(int irq, void *_dev, struct pt_regs *r) { struct pxa2xx_udc *dev = _dev; int vbus; @@ -1754,7 +1754,8 @@ lubbock_vbus_irq(int irq, void *_dev) #endif -static irqreturn_t udc_vbus_irq(int irq, void *_dev) +static irqreturn_t +udc_vbus_irq(int irq, void *_dev, struct pt_regs *r) { struct pxa2xx_udc *dev = _dev; int vbus = pxa_gpio_get(dev->mach->gpio_vbus); @@ -2083,7 +2084,7 @@ static void handle_ep(struct pxa2xx_ep *ep) * could cause usb protocol errors. */ static irqreturn_t -pxa2xx_udc_irq(int irq, void *_dev) +pxa2xx_udc_irq(int irq, void *_dev, struct pt_regs *r) { struct pxa2xx_udc *dev = _dev; int handled; @@ -2472,7 +2473,6 @@ static struct pxa2xx_udc memory = { #define PXA210_B1 0x00000123 #define PXA210_B0 0x00000122 #define IXP425_A0 0x000001c1 -#define IXP425_B0 0x000001f1 #define IXP465_AD 0x00000200 /* @@ -2510,7 +2510,6 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev) break; #elif defined(CONFIG_ARCH_IXP4XX) case IXP425_A0: - case IXP425_B0: case IXP465_AD: dev->has_cfr = 1; out_dma = 0; diff --git a/trunk/drivers/usb/host/Kconfig b/trunk/drivers/usb/host/Kconfig index cc60759083bf..cf10cbc98f80 100644 --- a/trunk/drivers/usb/host/Kconfig +++ b/trunk/drivers/usb/host/Kconfig @@ -153,7 +153,7 @@ config USB_U132_HCD adapter will *NOT* work with PC cards that do not contain an OHCI controller. - For those PC cards that contain multiple OHCI controllers only the + For those PC cards that contain multiple OHCI controllers only ther first one is used. The driver consists of two modules, the "ftdi-elan" module is a diff --git a/trunk/drivers/usb/host/ehci-dbg.c b/trunk/drivers/usb/host/ehci-dbg.c index 34b7a31cd85b..23b95b2bfe15 100644 --- a/trunk/drivers/usb/host/ehci-dbg.c +++ b/trunk/drivers/usb/host/ehci-dbg.c @@ -754,9 +754,7 @@ show_registers (struct class_device *class_dev, char *buf) } if (ehci->reclaim) { - temp = scnprintf (next, size, "reclaim qh %p%s\n", - ehci->reclaim, - ehci->reclaim_ready ? " ready" : ""); + temp = scnprintf (next, size, "reclaim qh %p\n", ehci->reclaim); size -= temp; next += temp; } diff --git a/trunk/drivers/usb/host/ehci-hcd.c b/trunk/drivers/usb/host/ehci-hcd.c index 025d33313681..5ac918591131 100644 --- a/trunk/drivers/usb/host/ehci-hcd.c +++ b/trunk/drivers/usb/host/ehci-hcd.c @@ -111,7 +111,7 @@ static const char hcd_name [] = "ehci_hcd"; #define EHCI_TUNE_MULT_TT 1 #define EHCI_TUNE_FLS 2 /* (small) 256 frame schedule */ -#define EHCI_IAA_JIFFIES (HZ/100) /* arbitrary; ~10 msec */ +#define EHCI_IAA_MSECS 10 /* arbitrary */ #define EHCI_IO_JIFFIES (HZ/10) /* io watchdog > irq_thresh */ #define EHCI_ASYNC_JIFFIES (HZ/20) /* async idle timeout */ #define EHCI_SHRINK_JIFFIES (HZ/200) /* async qh unlink delay */ @@ -126,11 +126,6 @@ static unsigned park = 0; module_param (park, uint, S_IRUGO); MODULE_PARM_DESC (park, "park setting; 1-3 back-to-back async packets"); -/* for flakey hardware, ignore overcurrent indicators */ -static int ignore_oc = 0; -module_param (ignore_oc, bool, S_IRUGO); -MODULE_PARM_DESC (ignore_oc, "ignore bogus hardware overcurrent indications"); - #define INTR_MASK (STS_IAA | STS_FATAL | STS_PCD | STS_ERR | STS_INT) /*-------------------------------------------------------------------------*/ @@ -259,7 +254,8 @@ static void ehci_quiesce (struct ehci_hcd *ehci) /*-------------------------------------------------------------------------*/ -static void ehci_work(struct ehci_hcd *ehci); +static void end_unlink_async (struct ehci_hcd *ehci, struct pt_regs *regs); +static void ehci_work(struct ehci_hcd *ehci, struct pt_regs *regs); #include "ehci-hub.c" #include "ehci-mem.c" @@ -268,30 +264,42 @@ static void ehci_work(struct ehci_hcd *ehci); /*-------------------------------------------------------------------------*/ -static void ehci_watchdog (unsigned long param) +static void ehci_iaa_watchdog (unsigned long param) { struct ehci_hcd *ehci = (struct ehci_hcd *) param; unsigned long flags; + u32 status; spin_lock_irqsave (&ehci->lock, flags); + WARN_ON(!ehci->reclaim); - /* lost IAA irqs wedge things badly; seen with a vt8235 */ + /* lost IAA irqs wedge things badly; seen first with a vt8235 */ if (ehci->reclaim) { - u32 status = readl (&ehci->regs->status); + status = readl (&ehci->regs->status); if (status & STS_IAA) { ehci_vdbg (ehci, "lost IAA\n"); COUNT (ehci->stats.lost_iaa); writel (STS_IAA, &ehci->regs->status); - ehci->reclaim_ready = 1; + end_unlink_async (ehci, NULL); } } - /* stop async processing after it's idled a bit */ + spin_unlock_irqrestore (&ehci->lock, flags); +} + +static void ehci_watchdog (unsigned long param) +{ + struct ehci_hcd *ehci = (struct ehci_hcd *) param; + unsigned long flags; + + spin_lock_irqsave (&ehci->lock, flags); + + /* stop async processing after it's idled a bit */ if (test_bit (TIMER_ASYNC_OFF, &ehci->actions)) start_unlink_async (ehci, ehci->async); /* ehci could run by timer, without IRQs ... */ - ehci_work (ehci); + ehci_work (ehci, NULL); spin_unlock_irqrestore (&ehci->lock, flags); } @@ -334,11 +342,9 @@ static void ehci_port_power (struct ehci_hcd *ehci, int is_on) * ehci_work is called from some interrupts, timers, and so on. * it calls driver completion functions, after dropping ehci->lock. */ -static void ehci_work (struct ehci_hcd *ehci) +static void ehci_work (struct ehci_hcd *ehci, struct pt_regs *regs) { timer_action_done (ehci, TIMER_IO_WATCHDOG); - if (ehci->reclaim_ready) - end_unlink_async (ehci); /* another CPU may drop ehci->lock during a schedule scan while * it reports urb completions. this flag guards against bogus @@ -347,9 +353,9 @@ static void ehci_work (struct ehci_hcd *ehci) if (ehci->scanning) return; ehci->scanning = 1; - scan_async (ehci); + scan_async (ehci, regs); if (ehci->next_uframe != -1) - scan_periodic (ehci); + scan_periodic (ehci, regs); ehci->scanning = 0; /* the IO watchdog guards against hardware or driver bugs that @@ -373,6 +379,7 @@ static void ehci_stop (struct usb_hcd *hcd) /* no more interrupts ... */ del_timer_sync (&ehci->watchdog); + del_timer_sync (&ehci->iaa_watchdog); spin_lock_irq(&ehci->lock); if (HC_IS_RUNNING (hcd->state)) @@ -390,7 +397,7 @@ static void ehci_stop (struct usb_hcd *hcd) /* root hub is shut down separately (first, when possible) */ spin_lock_irq (&ehci->lock); if (ehci->async) - ehci_work (ehci); + ehci_work (ehci, NULL); spin_unlock_irq (&ehci->lock); ehci_mem_cleanup (ehci); @@ -419,6 +426,10 @@ static int ehci_init(struct usb_hcd *hcd) ehci->watchdog.function = ehci_watchdog; ehci->watchdog.data = (unsigned long) ehci; + init_timer(&ehci->iaa_watchdog); + ehci->iaa_watchdog.function = ehci_iaa_watchdog; + ehci->iaa_watchdog.data = (unsigned long) ehci; + /* * hw default: 1K periodic list heads, one per frame. * periodic_size can shrink by USBCMD update if hcc_params allows. @@ -435,7 +446,6 @@ static int ehci_init(struct usb_hcd *hcd) ehci->i_thresh = 2 + HCC_ISOC_THRES(hcc_params); ehci->reclaim = NULL; - ehci->reclaim_ready = 0; ehci->next_uframe = -1; /* @@ -546,10 +556,9 @@ static int ehci_run (struct usb_hcd *hcd) temp = HC_VERSION(readl (&ehci->caps->hc_capbase)); ehci_info (ehci, - "USB %x.%x started, EHCI %x.%02x, driver %s%s\n", + "USB %x.%x started, EHCI %x.%02x, driver %s\n", ((ehci->sbrn & 0xf0)>>4), (ehci->sbrn & 0x0f), - temp >> 8, temp & 0xff, DRIVER_VERSION, - ignore_oc ? ", overcurrent ignored" : ""); + temp >> 8, temp & 0xff, DRIVER_VERSION); writel (INTR_MASK, &ehci->regs->intr_enable); /* Turn On Interrupts */ @@ -564,7 +573,7 @@ static int ehci_run (struct usb_hcd *hcd) /*-------------------------------------------------------------------------*/ -static irqreturn_t ehci_irq (struct usb_hcd *hcd) +static irqreturn_t ehci_irq (struct usb_hcd *hcd, struct pt_regs *regs) { struct ehci_hcd *ehci = hcd_to_ehci (hcd); u32 status; @@ -610,7 +619,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) /* complete the unlinking of some qh [4.15.2.3] */ if (status & STS_IAA) { COUNT (ehci->stats.reclaim); - ehci->reclaim_ready = 1; + end_unlink_async (ehci, regs); bh = 1; } @@ -619,8 +628,9 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) unsigned i = HCS_N_PORTS (ehci->hcs_params); /* resume root hub? */ - if (!(readl(&ehci->regs->command) & CMD_RUN)) - usb_hcd_resume_root_hub(hcd); + status = readl (&ehci->regs->command); + if (!(status & CMD_RUN)) + writel (status | CMD_RUN, &ehci->regs->command); while (i--) { int pstatus = readl (&ehci->regs->port_status [i]); @@ -637,6 +647,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) */ ehci->reset_done [i] = jiffies + msecs_to_jiffies (20); ehci_dbg (ehci, "port %d remote wakeup\n", i + 1); + usb_hcd_resume_root_hub(hcd); } } @@ -659,7 +670,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) } if (bh) - ehci_work (ehci); + ehci_work (ehci, regs); spin_unlock (&ehci->lock); return IRQ_HANDLED; } @@ -712,10 +723,14 @@ static int ehci_urb_enqueue ( static void unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) { - /* if we need to use IAA and it's busy, defer */ - if (qh->qh_state == QH_STATE_LINKED - && ehci->reclaim - && HC_IS_RUNNING (ehci_to_hcd(ehci)->state)) { + // BUG_ON(qh->qh_state != QH_STATE_LINKED); + + /* failfast */ + if (!HC_IS_RUNNING (ehci_to_hcd(ehci)->state)) + end_unlink_async (ehci, NULL); + + /* defer till later if busy */ + else if (ehci->reclaim) { struct ehci_qh *last; for (last = ehci->reclaim; @@ -725,12 +740,8 @@ static void unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) qh->qh_state = QH_STATE_UNLINK_WAIT; last->reclaim = qh; - /* bypass IAA if the hc can't care */ - } else if (!HC_IS_RUNNING (ehci_to_hcd(ehci)->state) && ehci->reclaim) - end_unlink_async (ehci); - - /* something else might have unlinked the qh by now */ - if (qh->qh_state == QH_STATE_LINKED) + /* start IAA cycle */ + } else start_unlink_async (ehci, qh); } @@ -752,7 +763,19 @@ static int ehci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb) qh = (struct ehci_qh *) urb->hcpriv; if (!qh) break; - unlink_async (ehci, qh); + switch (qh->qh_state) { + case QH_STATE_LINKED: + case QH_STATE_COMPLETING: + unlink_async (ehci, qh); + break; + case QH_STATE_UNLINK: + case QH_STATE_UNLINK_WAIT: + /* already started */ + break; + case QH_STATE_IDLE: + WARN_ON(1); + break; + } break; case PIPE_INTERRUPT: @@ -764,7 +787,7 @@ static int ehci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb) intr_deschedule (ehci, qh); /* FALL THROUGH */ case QH_STATE_IDLE: - qh_completions (ehci, qh); + qh_completions (ehci, qh, NULL); break; default: ehci_dbg (ehci, "bogus qh %p state %d\n", @@ -844,6 +867,7 @@ ehci_endpoint_disable (struct usb_hcd *hcd, struct usb_host_endpoint *ep) unlink_async (ehci, qh); /* FALL THROUGH */ case QH_STATE_UNLINK: /* wait for hw to finish? */ + case QH_STATE_UNLINK_WAIT: idle_timeout: spin_unlock_irqrestore (&ehci->lock, flags); schedule_timeout_uninterruptible(1); diff --git a/trunk/drivers/usb/host/ehci-hub.c b/trunk/drivers/usb/host/ehci-hub.c index bfe5f307cba6..b2ee13c58517 100644 --- a/trunk/drivers/usb/host/ehci-hub.c +++ b/trunk/drivers/usb/host/ehci-hub.c @@ -34,7 +34,6 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci (hcd); int port; - int mask; if (time_before (jiffies, ehci->next_statechange)) msleep(5); @@ -49,28 +48,17 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) } ehci->command = readl (&ehci->regs->command); if (ehci->reclaim) - ehci->reclaim_ready = 1; - ehci_work(ehci); + end_unlink_async (ehci, NULL); + ehci_work(ehci, NULL); - /* Unlike other USB host controller types, EHCI doesn't have - * any notion of "global" or bus-wide suspend. The driver has - * to manually suspend all the active unsuspended ports, and - * then manually resume them in the bus_resume() routine. - */ - ehci->bus_suspended = 0; + /* suspend any active/unsuspended ports, maybe allow wakeup */ while (port--) { u32 __iomem *reg = &ehci->regs->port_status [port]; u32 t1 = readl (reg) & ~PORT_RWC_BITS; u32 t2 = t1; - /* keep track of which ports we suspend */ - if ((t1 & PORT_PE) && !(t1 & PORT_OWNER) && - !(t1 & PORT_SUSPEND)) { + if ((t1 & PORT_PE) && !(t1 & PORT_OWNER)) t2 |= PORT_SUSPEND; - set_bit(port, &ehci->bus_suspended); - } - - /* enable remote wakeup on all ports */ if (device_may_wakeup(&hcd->self.root_hub->dev)) t2 |= PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E; else @@ -88,13 +76,6 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) ehci_halt (ehci); hcd->state = HC_STATE_SUSPENDED; - /* allow remote wakeup */ - mask = INTR_MASK; - if (!device_may_wakeup(&hcd->self.root_hub->dev)) - mask &= ~STS_PCD; - writel(mask, &ehci->regs->intr_enable); - readl(&ehci->regs->intr_enable); - ehci->next_statechange = jiffies + msecs_to_jiffies(10); spin_unlock_irq (&ehci->lock); return 0; @@ -107,6 +88,7 @@ static int ehci_bus_resume (struct usb_hcd *hcd) struct ehci_hcd *ehci = hcd_to_ehci (hcd); u32 temp; int i; + int intr_enable; if (time_before (jiffies, ehci->next_statechange)) msleep(5); @@ -118,30 +100,31 @@ static int ehci_bus_resume (struct usb_hcd *hcd) * the last user of the controller, not reset/pm hardware keeping * state we gave to it. */ - temp = readl(&ehci->regs->intr_enable); - ehci_dbg(ehci, "resume root hub%s\n", temp ? "" : " after power loss"); - - /* at least some APM implementations will try to deliver - * IRQs right away, so delay them until we're ready. - */ - writel(0, &ehci->regs->intr_enable); - /* re-init operational registers */ - writel(0, &ehci->regs->segment); - writel(ehci->periodic_dma, &ehci->regs->frame_list); - writel((u32) ehci->async->qh_dma, &ehci->regs->async_next); + /* re-init operational registers in case we lost power */ + if (readl (&ehci->regs->intr_enable) == 0) { + /* at least some APM implementations will try to deliver + * IRQs right away, so delay them until we're ready. + */ + intr_enable = 1; + writel (0, &ehci->regs->segment); + writel (ehci->periodic_dma, &ehci->regs->frame_list); + writel ((u32)ehci->async->qh_dma, &ehci->regs->async_next); + } else + intr_enable = 0; + ehci_dbg(ehci, "resume root hub%s\n", + intr_enable ? " after power loss" : ""); /* restore CMD_RUN, framelist size, and irq threshold */ writel (ehci->command, &ehci->regs->command); - /* manually resume the ports we suspended during bus_suspend() */ + /* take ports out of suspend */ i = HCS_N_PORTS (ehci->hcs_params); while (i--) { temp = readl (&ehci->regs->port_status [i]); temp &= ~(PORT_RWC_BITS | PORT_WKOC_E | PORT_WKDISC_E | PORT_WKCONN_E); - if (test_bit(i, &ehci->bus_suspended) && - (temp & PORT_SUSPEND)) { + if (temp & PORT_SUSPEND) { ehci->reset_done [i] = jiffies + msecs_to_jiffies (20); temp |= PORT_RESUME; } @@ -151,12 +134,11 @@ static int ehci_bus_resume (struct usb_hcd *hcd) mdelay (20); while (i--) { temp = readl (&ehci->regs->port_status [i]); - if (test_bit(i, &ehci->bus_suspended) && - (temp & PORT_SUSPEND)) { - temp &= ~(PORT_RWC_BITS | PORT_RESUME); - writel (temp, &ehci->regs->port_status [i]); - ehci_vdbg (ehci, "resumed port %d\n", i + 1); - } + if ((temp & PORT_SUSPEND) == 0) + continue; + temp &= ~(PORT_RWC_BITS | PORT_RESUME); + writel (temp, &ehci->regs->port_status [i]); + ehci_vdbg (ehci, "resumed port %d\n", i + 1); } (void) readl (&ehci->regs->command); @@ -175,7 +157,8 @@ static int ehci_bus_resume (struct usb_hcd *hcd) hcd->state = HC_STATE_RUNNING; /* Now we can safely re-enable irqs */ - writel(INTR_MASK, &ehci->regs->intr_enable); + if (intr_enable) + writel (INTR_MASK, &ehci->regs->intr_enable); spin_unlock_irq (&ehci->lock); return 0; @@ -235,7 +218,6 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf) { struct ehci_hcd *ehci = hcd_to_ehci (hcd); u32 temp, status = 0; - u32 mask; int ports, i, retval = 1; unsigned long flags; @@ -251,18 +233,6 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf) retval++; } - /* Some boards (mostly VIA?) report bogus overcurrent indications, - * causing massive log spam unless we completely ignore them. It - * may be relevant that VIA VT8235 controlers, where PORT_POWER is - * always set, seem to clear PORT_OCC and PORT_CSC when writing to - * PORT_POWER; that's surprising, but maybe within-spec. - */ - if (!ignore_oc) - mask = PORT_CSC | PORT_PEC | PORT_OCC; - else - mask = PORT_CSC | PORT_PEC; - // PORT_RESUME from hardware ~= PORT_STAT_C_SUSPEND - /* no hub change reports (bit 0) for now (power, ...) */ /* port N changes (bit N)? */ @@ -280,7 +250,8 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf) } if (!(temp & PORT_CONNECT)) ehci->reset_done [i] = 0; - if ((temp & mask) != 0 + if ((temp & (PORT_CSC | PORT_PEC | PORT_OCC)) != 0 + // PORT_STAT_C_SUSPEND? || ((temp & PORT_RESUME) != 0 && time_after (jiffies, ehci->reset_done [i]))) { @@ -348,7 +319,6 @@ static int ehci_hub_control ( u32 temp, status; unsigned long flags; int retval = 0; - unsigned selector; /* * FIXME: support SetPortFeatures USB_PORT_FEAT_INDICATOR. @@ -447,7 +417,7 @@ static int ehci_hub_control ( status |= 1 << USB_PORT_FEAT_C_CONNECTION; if (temp & PORT_PEC) status |= 1 << USB_PORT_FEAT_C_ENABLE; - if ((temp & PORT_OCC) && !ignore_oc) + if (temp & PORT_OCC) status |= 1 << USB_PORT_FEAT_C_OVER_CURRENT; /* whoever resumes must GetPortStatus to complete it!! */ @@ -536,8 +506,6 @@ static int ehci_hub_control ( } break; case SetPortFeature: - selector = wIndex >> 8; - wIndex &= 0xff; if (!wIndex || wIndex > ports) goto error; wIndex--; @@ -591,22 +559,6 @@ static int ehci_hub_control ( } writel (temp, &ehci->regs->port_status [wIndex]); break; - - /* For downstream facing ports (these): one hub port is put - * into test mode according to USB2 11.24.2.13, then the hub - * must be reset (which for root hub now means rmmod+modprobe, - * or else system reboot). See EHCI 2.3.9 and 4.14 for info - * about the EHCI-specific stuff. - */ - case USB_PORT_FEAT_TEST: - if (!selector || selector > 5) - goto error; - ehci_quiesce(ehci); - ehci_halt(ehci); - temp |= selector << 16; - writel (temp, &ehci->regs->port_status [wIndex]); - break; - default: goto error; } diff --git a/trunk/drivers/usb/host/ehci-pci.c b/trunk/drivers/usb/host/ehci-pci.c index 4bc7970ba3ef..08d0472d4f57 100644 --- a/trunk/drivers/usb/host/ehci-pci.c +++ b/trunk/drivers/usb/host/ehci-pci.c @@ -257,7 +257,9 @@ static int ehci_pci_suspend(struct usb_hcd *hcd, pm_message_t message) static int ehci_pci_resume(struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); + unsigned port; struct pci_dev *pdev = to_pci_dev(hcd->self.controller); + int retval = -EINVAL; // maybe restore FLADJ @@ -267,19 +269,27 @@ static int ehci_pci_resume(struct usb_hcd *hcd) /* Mark hardware accessible again as we are out of D3 state by now */ set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); - /* If CF is still set, we maintained PCI Vaux power. - * Just undo the effect of ehci_pci_suspend(). + /* If CF is clear, we lost PCI Vaux power and need to restart. */ + if (readl(&ehci->regs->configured_flag) != FLAG_CF) + goto restart; + + /* If any port is suspended (or owned by the companion), + * we know we can/must resume the HC (and mustn't reset it). + * We just defer that to the root hub code. */ - if (readl(&ehci->regs->configured_flag) == FLAG_CF) { - int mask = INTR_MASK; - - if (!device_may_wakeup(&hcd->self.root_hub->dev)) - mask &= ~STS_PCD; - writel(mask, &ehci->regs->intr_enable); - readl(&ehci->regs->intr_enable); - return 0; + for (port = HCS_N_PORTS(ehci->hcs_params); port > 0; ) { + u32 status; + port--; + status = readl(&ehci->regs->port_status [port]); + if (!(status & PORT_POWER)) + continue; + if (status & (PORT_SUSPEND | PORT_RESUME | PORT_OWNER)) { + usb_hcd_resume_root_hub(hcd); + return 0; + } } +restart: ehci_dbg(ehci, "lost power, restarting\n"); usb_root_hub_lost_power(hcd->self.root_hub); @@ -293,19 +303,17 @@ static int ehci_pci_resume(struct usb_hcd *hcd) /* emptying the schedule aborts any urbs */ spin_lock_irq(&ehci->lock); if (ehci->reclaim) - ehci->reclaim_ready = 1; - ehci_work(ehci); + end_unlink_async (ehci, NULL); + ehci_work(ehci, NULL); spin_unlock_irq(&ehci->lock); + /* restart; khubd will disconnect devices */ + retval = ehci_run(hcd); + /* here we "know" root ports should always stay powered */ ehci_port_power(ehci, 1); - writel(ehci->command, &ehci->regs->command); - writel(FLAG_CF, &ehci->regs->configured_flag); - readl(&ehci->regs->command); /* unblock posted writes */ - - hcd->state = HC_STATE_SUSPENDED; - return 0; + return retval; } #endif diff --git a/trunk/drivers/usb/host/ehci-q.c b/trunk/drivers/usb/host/ehci-q.c index 62e46dc60e86..7fc25b6bd7d2 100644 --- a/trunk/drivers/usb/host/ehci-q.c +++ b/trunk/drivers/usb/host/ehci-q.c @@ -214,7 +214,7 @@ static void qtd_copy_status ( } static void -ehci_urb_done (struct ehci_hcd *ehci, struct urb *urb) +ehci_urb_done (struct ehci_hcd *ehci, struct urb *urb, struct pt_regs *regs) __releases(ehci->lock) __acquires(ehci->lock) { @@ -262,7 +262,7 @@ __acquires(ehci->lock) /* complete() can reenter this HCD */ spin_unlock (&ehci->lock); - usb_hcd_giveback_urb (ehci_to_hcd(ehci), urb); + usb_hcd_giveback_urb (ehci_to_hcd(ehci), urb, regs); spin_lock (&ehci->lock); } @@ -279,7 +279,7 @@ static int qh_schedule (struct ehci_hcd *ehci, struct ehci_qh *qh); */ #define HALT_BIT __constant_cpu_to_le32(QTD_STS_HALT) static unsigned -qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) +qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh, struct pt_regs *regs) { struct ehci_qtd *last = NULL, *end = qh->dummy; struct list_head *entry, *tmp; @@ -317,7 +317,7 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) /* clean up any state from previous QTD ...*/ if (last) { if (likely (last->urb != urb)) { - ehci_urb_done (ehci, last->urb); + ehci_urb_done (ehci, last->urb, regs); count++; } ehci_qtd_free (ehci, last); @@ -407,7 +407,7 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) /* last urb's completion might still need calling */ if (likely (last != NULL)) { - ehci_urb_done (ehci, last->urb); + ehci_urb_done (ehci, last->urb, regs); count++; ehci_qtd_free (ehci, last); } @@ -962,12 +962,12 @@ submit_async ( /* the async qh for the qtds being reclaimed are now unlinked from the HC */ -static void end_unlink_async (struct ehci_hcd *ehci) +static void end_unlink_async (struct ehci_hcd *ehci, struct pt_regs *regs) { struct ehci_qh *qh = ehci->reclaim; struct ehci_qh *next; - timer_action_done (ehci, TIMER_IAA_WATCHDOG); + iaa_watchdog_done (ehci); // qh->hw_next = cpu_to_le32 (qh->qh_dma); qh->qh_state = QH_STATE_IDLE; @@ -977,10 +977,9 @@ static void end_unlink_async (struct ehci_hcd *ehci) /* other unlink(s) may be pending (in QH_STATE_UNLINK_WAIT) */ next = qh->reclaim; ehci->reclaim = next; - ehci->reclaim_ready = 0; qh->reclaim = NULL; - qh_completions (ehci, qh); + qh_completions (ehci, qh, regs); if (!list_empty (&qh->qtd_list) && HC_IS_RUNNING (ehci_to_hcd(ehci)->state)) @@ -1048,20 +1047,20 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) /* if (unlikely (qh->reclaim != 0)) * this will recurse, probably not much */ - end_unlink_async (ehci); + end_unlink_async (ehci, NULL); return; } - ehci->reclaim_ready = 0; cmd |= CMD_IAAD; writel (cmd, &ehci->regs->command); (void) readl (&ehci->regs->command); - timer_action (ehci, TIMER_IAA_WATCHDOG); + iaa_watchdog_start (ehci); } /*-------------------------------------------------------------------------*/ -static void scan_async (struct ehci_hcd *ehci) +static void +scan_async (struct ehci_hcd *ehci, struct pt_regs *regs) { struct ehci_qh *qh; enum ehci_timer_action action = TIMER_IO_WATCHDOG; @@ -1085,7 +1084,7 @@ static void scan_async (struct ehci_hcd *ehci) */ qh = qh_get (qh); qh->stamp = ehci->stamp; - temp = qh_completions (ehci, qh); + temp = qh_completions (ehci, qh, regs); qh_put (qh); if (temp != 0) { goto rescan; diff --git a/trunk/drivers/usb/host/ehci-sched.c b/trunk/drivers/usb/host/ehci-sched.c index 65c402a0fa7a..e5e9c653c907 100644 --- a/trunk/drivers/usb/host/ehci-sched.c +++ b/trunk/drivers/usb/host/ehci-sched.c @@ -1553,7 +1553,8 @@ itd_link_urb ( static unsigned itd_complete ( struct ehci_hcd *ehci, - struct ehci_itd *itd + struct ehci_itd *itd, + struct pt_regs *regs ) { struct urb *urb = itd->urb; struct usb_iso_packet_descriptor *desc; @@ -1612,7 +1613,7 @@ itd_complete ( /* give urb back to the driver ... can be out-of-order */ dev = urb->dev; - ehci_urb_done (ehci, urb); + ehci_urb_done (ehci, urb, regs); urb = NULL; /* defer stopping schedule; completion can submit */ @@ -1929,7 +1930,8 @@ sitd_link_urb ( static unsigned sitd_complete ( struct ehci_hcd *ehci, - struct ehci_sitd *sitd + struct ehci_sitd *sitd, + struct pt_regs *regs ) { struct urb *urb = sitd->urb; struct usb_iso_packet_descriptor *desc; @@ -1976,7 +1978,7 @@ sitd_complete ( /* give urb back to the driver */ dev = urb->dev; - ehci_urb_done (ehci, urb); + ehci_urb_done (ehci, urb, regs); urb = NULL; /* defer stopping schedule; completion can submit */ @@ -2063,7 +2065,8 @@ sitd_submit (struct ehci_hcd *ehci, struct urb *urb, gfp_t mem_flags) static inline unsigned sitd_complete ( struct ehci_hcd *ehci, - struct ehci_sitd *sitd + struct ehci_sitd *sitd, + struct pt_regs *regs ) { ehci_err (ehci, "sitd_complete %p?\n", sitd); return 0; @@ -2074,7 +2077,7 @@ sitd_complete ( /*-------------------------------------------------------------------------*/ static void -scan_periodic (struct ehci_hcd *ehci) +scan_periodic (struct ehci_hcd *ehci, struct pt_regs *regs) { unsigned frame, clock, now_uframe, mod; unsigned modified; @@ -2128,7 +2131,7 @@ scan_periodic (struct ehci_hcd *ehci) temp.qh = qh_get (q.qh); type = Q_NEXT_TYPE (q.qh->hw_next); q = q.qh->qh_next; - modified = qh_completions (ehci, temp.qh); + modified = qh_completions (ehci, temp.qh, regs); if (unlikely (list_empty (&temp.qh->qtd_list))) intr_deschedule (ehci, temp.qh); qh_put (temp.qh); @@ -2166,7 +2169,7 @@ scan_periodic (struct ehci_hcd *ehci) *hw_p = q.itd->hw_next; type = Q_NEXT_TYPE (q.itd->hw_next); wmb(); - modified = itd_complete (ehci, q.itd); + modified = itd_complete (ehci, q.itd, regs); q = *q_p; break; case Q_TYPE_SITD: @@ -2182,7 +2185,7 @@ scan_periodic (struct ehci_hcd *ehci) *hw_p = q.sitd->hw_next; type = Q_NEXT_TYPE (q.sitd->hw_next); wmb(); - modified = sitd_complete (ehci, q.sitd); + modified = sitd_complete (ehci, q.sitd, regs); q = *q_p; break; default: diff --git a/trunk/drivers/usb/host/ehci.h b/trunk/drivers/usb/host/ehci.h index 74dbc6c8228f..6aac39f50e07 100644 --- a/trunk/drivers/usb/host/ehci.h +++ b/trunk/drivers/usb/host/ehci.h @@ -58,7 +58,6 @@ struct ehci_hcd { /* one per controller */ /* async schedule support */ struct ehci_qh *async; struct ehci_qh *reclaim; - unsigned reclaim_ready : 1; unsigned scanning : 1; /* periodic schedule support */ @@ -74,7 +73,6 @@ struct ehci_hcd { /* one per controller */ /* per root hub port */ unsigned long reset_done [EHCI_MAX_ROOT_PORTS]; - unsigned long bus_suspended; /* per-HC memory pools (could be per-bus, but ...) */ struct dma_pool *qh_pool; /* qh per active urb */ @@ -82,6 +80,7 @@ struct ehci_hcd { /* one per controller */ struct dma_pool *itd_pool; /* itd per iso urb */ struct dma_pool *sitd_pool; /* sitd per split iso urb */ + struct timer_list iaa_watchdog; struct timer_list watchdog; unsigned long actions; unsigned stamp; @@ -115,9 +114,21 @@ static inline struct usb_hcd *ehci_to_hcd (struct ehci_hcd *ehci) } +static inline void +iaa_watchdog_start (struct ehci_hcd *ehci) +{ + WARN_ON(timer_pending(&ehci->iaa_watchdog)); + mod_timer (&ehci->iaa_watchdog, + jiffies + msecs_to_jiffies(EHCI_IAA_MSECS)); +} + +static inline void iaa_watchdog_done (struct ehci_hcd *ehci) +{ + del_timer (&ehci->iaa_watchdog); +} + enum ehci_timer_action { TIMER_IO_WATCHDOG, - TIMER_IAA_WATCHDOG, TIMER_ASYNC_SHRINK, TIMER_ASYNC_OFF, }; @@ -135,9 +146,6 @@ timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action) unsigned long t; switch (action) { - case TIMER_IAA_WATCHDOG: - t = EHCI_IAA_JIFFIES; - break; case TIMER_IO_WATCHDOG: t = EHCI_IO_JIFFIES; break; @@ -154,8 +162,7 @@ timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action) // async queue SHRINK often precedes IAA. while it's ready // to go OFF neither can matter, and afterwards the IO // watchdog stops unless there's still periodic traffic. - if (action != TIMER_IAA_WATCHDOG - && t > ehci->watchdog.expires + if (time_before_eq(t, ehci->watchdog.expires) && timer_pending (&ehci->watchdog)) return; mod_timer (&ehci->watchdog, t); diff --git a/trunk/drivers/usb/host/hc_crisv10.c b/trunk/drivers/usb/host/hc_crisv10.c index 87eca6aeacf2..61e571782cf7 100644 --- a/trunk/drivers/usb/host/hc_crisv10.c +++ b/trunk/drivers/usb/host/hc_crisv10.c @@ -478,9 +478,9 @@ static int etrax_usb_submit_urb(struct urb *urb, unsigned mem_flags); static int etrax_usb_unlink_urb(struct urb *urb, int status); static int etrax_usb_get_frame_number(struct usb_device *usb_dev); -static irqreturn_t etrax_usb_tx_interrupt(int irq, void *vhc); -static irqreturn_t etrax_usb_rx_interrupt(int irq, void *vhc); -static irqreturn_t etrax_usb_hc_interrupt_top_half(int irq, void *vhc); +static irqreturn_t etrax_usb_tx_interrupt(int irq, void *vhc, struct pt_regs *regs); +static irqreturn_t etrax_usb_rx_interrupt(int irq, void *vhc, struct pt_regs *regs); +static irqreturn_t etrax_usb_hc_interrupt_top_half(int irq, void *vhc, struct pt_regs *regs); static void etrax_usb_hc_interrupt_bottom_half(void *data); static void etrax_usb_isoc_descr_interrupt_bottom_half(void *data); @@ -1573,7 +1573,7 @@ static int etrax_usb_get_frame_number(struct usb_device *usb_dev) return (*R_USB_FM_NUMBER & 0x7ff); } -static irqreturn_t etrax_usb_tx_interrupt(int irq, void *vhc) +static irqreturn_t etrax_usb_tx_interrupt(int irq, void *vhc, struct pt_regs *regs) { DBFENTER; @@ -1839,7 +1839,7 @@ static void etrax_usb_isoc_descr_interrupt_bottom_half(void *data) -static irqreturn_t etrax_usb_rx_interrupt(int irq, void *vhc) +static irqreturn_t etrax_usb_rx_interrupt(int irq, void *vhc, struct pt_regs *regs) { struct urb *urb; etrax_urb_priv_t *urb_priv; @@ -3280,7 +3280,7 @@ static void etrax_usb_complete_urb(struct urb *urb, int status) -static irqreturn_t etrax_usb_hc_interrupt_top_half(int irq, void *vhc) +static irqreturn_t etrax_usb_hc_interrupt_top_half(int irq, void *vhc, struct pt_regs *regs) { usb_interrupt_registers_t *reg; unsigned long flags; diff --git a/trunk/drivers/usb/host/isp116x-hcd.c b/trunk/drivers/usb/host/isp116x-hcd.c index 2718b5dc4ec1..a72e041df8e7 100644 --- a/trunk/drivers/usb/host/isp116x-hcd.c +++ b/trunk/drivers/usb/host/isp116x-hcd.c @@ -418,7 +418,7 @@ static void postproc_atl_queue(struct isp116x *isp116x) processed urbs. */ static void finish_request(struct isp116x *isp116x, struct isp116x_ep *ep, - struct urb *urb) + struct urb *urb, struct pt_regs *regs) __releases(isp116x->lock) __acquires(isp116x->lock) { unsigned i; @@ -432,7 +432,7 @@ __releases(isp116x->lock) __acquires(isp116x->lock) urb_dbg(urb, "Finish"); spin_unlock(&isp116x->lock); - usb_hcd_giveback_urb(isp116x_to_hcd(isp116x), urb); + usb_hcd_giveback_urb(isp116x_to_hcd(isp116x), urb, regs); spin_lock(&isp116x->lock); /* take idle endpoints out of the schedule */ @@ -568,7 +568,7 @@ static void start_atl_transfers(struct isp116x *isp116x) /* Finish the processed transfers */ -static void finish_atl_transfers(struct isp116x *isp116x) +static void finish_atl_transfers(struct isp116x *isp116x, struct pt_regs *regs) { struct isp116x_ep *ep; struct urb *urb; @@ -590,12 +590,12 @@ static void finish_atl_transfers(struct isp116x *isp116x) occured, while URB_SHORT_NOT_OK was set */ if (urb && urb->status != -EINPROGRESS && ep->nextpid != USB_PID_ACK) - finish_request(isp116x, ep, urb); + finish_request(isp116x, ep, urb, regs); } atomic_dec(&isp116x->atl_finishing); } -static irqreturn_t isp116x_irq(struct usb_hcd *hcd) +static irqreturn_t isp116x_irq(struct usb_hcd *hcd, struct pt_regs *regs) { struct isp116x *isp116x = hcd_to_isp116x(hcd); u16 irqstat; @@ -608,7 +608,7 @@ static irqreturn_t isp116x_irq(struct usb_hcd *hcd) if (irqstat & (HCuPINT_ATL | HCuPINT_SOF)) { ret = IRQ_HANDLED; - finish_atl_transfers(isp116x); + finish_atl_transfers(isp116x, regs); } if (irqstat & HCuPINT_OPR) { @@ -824,7 +824,7 @@ static int isp116x_urb_enqueue(struct usb_hcd *hcd, spin_lock(&urb->lock); if (urb->status != -EINPROGRESS) { spin_unlock(&urb->lock); - finish_request(isp116x, ep, urb); + finish_request(isp116x, ep, urb, NULL); ret = 0; goto fail; } @@ -870,7 +870,7 @@ static int isp116x_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) } if (urb) - finish_request(isp116x, ep, urb); + finish_request(isp116x, ep, urb, NULL); spin_unlock_irqrestore(&isp116x->lock, flags); return 0; diff --git a/trunk/drivers/usb/host/ohci-hcd.c b/trunk/drivers/usb/host/ohci-hcd.c index a95275a401b1..d1d68c402251 100644 --- a/trunk/drivers/usb/host/ohci-hcd.c +++ b/trunk/drivers/usb/host/ohci-hcd.c @@ -261,7 +261,7 @@ static int ohci_urb_enqueue ( if (urb->status != -EINPROGRESS) { spin_unlock (&urb->lock); urb->hcpriv = urb_priv; - finish_urb (ohci, urb); + finish_urb (ohci, urb, NULL); retval = 0; goto fail; } @@ -337,7 +337,7 @@ static int ohci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb) * any more ... just clean up every urb's memory. */ if (urb->hcpriv) - finish_urb (ohci, urb); + finish_urb (ohci, urb, NULL); } spin_unlock_irqrestore (&ohci->lock, flags); return 0; @@ -369,7 +369,7 @@ ohci_endpoint_disable (struct usb_hcd *hcd, struct usb_host_endpoint *ep) if (!HC_IS_RUNNING (hcd->state)) { sanitize: ed->state = ED_IDLE; - finish_unlinks (ohci, 0); + finish_unlinks (ohci, 0, NULL); } switch (ed->state) { @@ -691,7 +691,7 @@ static int ohci_run (struct ohci_hcd *ohci) /* an interrupt happens */ -static irqreturn_t ohci_irq (struct usb_hcd *hcd) +static irqreturn_t ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs) { struct ohci_hcd *ohci = hcd_to_ohci (hcd); struct ohci_regs __iomem *regs = ohci->regs; @@ -715,6 +715,13 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd) return IRQ_NOTMINE; } + if (ints & OHCI_INTR_RHSC) { + ohci_vdbg (ohci, "rhsc\n"); + ohci->next_statechange = jiffies + STATECHANGE_DELAY; + ohci_writel (ohci, OHCI_INTR_RHSC, ®s->intrstatus); + usb_hcd_poll_rh_status(hcd); + } + if (ints & OHCI_INTR_UE) { disable (ohci); ohci_err (ohci, "OHCI Unrecoverable Error, disabled\n"); @@ -724,31 +731,9 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd) ohci_usb_reset (ohci); } - if (ints & OHCI_INTR_RHSC) { - ohci_vdbg(ohci, "rhsc\n"); - ohci->next_statechange = jiffies + STATECHANGE_DELAY; - ohci_writel(ohci, OHCI_INTR_RD | OHCI_INTR_RHSC, - ®s->intrstatus); - - /* NOTE: Vendors didn't always make the same implementation - * choices for RHSC. Many followed the spec; RHSC triggers - * on an edge, like setting and maybe clearing a port status - * change bit. With others it's level-triggered, active - * until khubd clears all the port status change bits. We'll - * always disable it here and rely on polling until khubd - * re-enables it. - */ - ohci_writel(ohci, OHCI_INTR_RHSC, ®s->intrdisable); - usb_hcd_poll_rh_status(hcd); - } - - /* For connect and disconnect events, we expect the controller - * to turn on RHSC along with RD. But for remote wakeup events - * this might not happen. - */ - else if (ints & OHCI_INTR_RD) { - ohci_vdbg(ohci, "resume detect\n"); - ohci_writel(ohci, OHCI_INTR_RD, ®s->intrstatus); + if (ints & OHCI_INTR_RD) { + ohci_vdbg (ohci, "resume detect\n"); + ohci_writel (ohci, OHCI_INTR_RD, ®s->intrstatus); hcd->poll_rh = 1; if (ohci->autostop) { spin_lock (&ohci->lock); @@ -762,7 +747,7 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd) if (HC_IS_RUNNING(hcd->state)) ohci_writel (ohci, OHCI_INTR_WDH, ®s->intrdisable); spin_lock (&ohci->lock); - dl_done_list (ohci); + dl_done_list (ohci, ptregs); spin_unlock (&ohci->lock); if (HC_IS_RUNNING(hcd->state)) ohci_writel (ohci, OHCI_INTR_WDH, ®s->intrenable); @@ -775,7 +760,7 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd) */ spin_lock (&ohci->lock); if (ohci->ed_rm_list) - finish_unlinks (ohci, ohci_frame_no(ohci)); + finish_unlinks (ohci, ohci_frame_no(ohci), ptregs); if ((ints & OHCI_INTR_SF) != 0 && !ohci->ed_rm_list && HC_IS_RUNNING(hcd->state)) ohci_writel (ohci, OHCI_INTR_SF, ®s->intrdisable); @@ -867,7 +852,7 @@ static int ohci_restart (struct ohci_hcd *ohci) urb->status = -ESHUTDOWN; spin_unlock (&urb->lock); } - finish_unlinks (ohci, 0); + finish_unlinks (ohci, 0, NULL); spin_unlock_irq(&ohci->lock); /* paranoia, in case that didn't work: */ diff --git a/trunk/drivers/usb/host/ohci-hub.c b/trunk/drivers/usb/host/ohci-hub.c index 2441642cb7b4..ec75774abeac 100644 --- a/trunk/drivers/usb/host/ohci-hub.c +++ b/trunk/drivers/usb/host/ohci-hub.c @@ -41,21 +41,14 @@ static void ohci_rhsc_enable (struct usb_hcd *hcd) { struct ohci_hcd *ohci = hcd_to_ohci (hcd); - spin_lock_irq(&ohci->lock); - if (!ohci->autostop) - del_timer(&hcd->rh_timer); /* Prevent next poll */ - ohci_writel(ohci, OHCI_INTR_RHSC, &ohci->regs->intrenable); - spin_unlock_irq(&ohci->lock); + ohci_writel (ohci, OHCI_INTR_RHSC, &ohci->regs->intrenable); } #define OHCI_SCHED_ENABLES \ (OHCI_CTRL_CLE|OHCI_CTRL_BLE|OHCI_CTRL_PLE|OHCI_CTRL_IE) -static void dl_done_list (struct ohci_hcd *); -static void finish_unlinks (struct ohci_hcd *, u16); - -#ifdef CONFIG_PM -static int ohci_restart(struct ohci_hcd *ohci); +static void dl_done_list (struct ohci_hcd *, struct pt_regs *); +static void finish_unlinks (struct ohci_hcd *, u16 , struct pt_regs *); static int ohci_rh_suspend (struct ohci_hcd *ohci, int autostop) __releases(ohci->lock) @@ -101,8 +94,8 @@ __acquires(ohci->lock) msleep (8); spin_lock_irq (&ohci->lock); } - dl_done_list (ohci); - finish_unlinks (ohci, ohci_frame_no(ohci)); + dl_done_list (ohci, NULL); + finish_unlinks (ohci, ohci_frame_no(ohci), NULL); /* maybe resume can wake root hub */ if (device_may_wakeup(&ohci_to_hcd(ohci)->self.root_hub->dev) || @@ -139,6 +132,8 @@ static inline struct ed *find_head (struct ed *ed) return ed; } +static int ohci_restart (struct ohci_hcd *ohci); + /* caller has locked the root hub */ static int ohci_rh_resume (struct ohci_hcd *ohci) __releases(ohci->lock) @@ -174,8 +169,7 @@ __acquires(ohci->lock) break; case OHCI_USB_RESUME: /* HCFS changes sometime after INTR_RD */ - ohci_dbg(ohci, "%swakeup root hub\n", - autostopped ? "auto-" : ""); + ohci_info (ohci, "wakeup\n"); break; case OHCI_USB_OPER: /* this can happen after resuming a swsusp snapshot */ @@ -186,6 +180,7 @@ __acquires(ohci->lock) ohci_dbg (ohci, "lost power\n"); status = -EBUSY; } +#ifdef CONFIG_PM if (status == -EBUSY) { if (!autostopped) { spin_unlock_irq (&ohci->lock); @@ -195,12 +190,25 @@ __acquires(ohci->lock) } return status; } +#endif if (status != -EINPROGRESS) return status; if (autostopped) goto skip_resume; spin_unlock_irq (&ohci->lock); + temp = ohci->num_ports; + while (temp--) { + u32 stat = ohci_readl (ohci, + &ohci->regs->roothub.portstatus [temp]); + + /* force global, not selective, resume */ + if (!(stat & RH_PS_PSS)) + continue; + ohci_writel (ohci, RH_PS_POCI, + &ohci->regs->roothub.portstatus [temp]); + } + /* Some controllers (lucent erratum) need extra-long delays */ msleep (20 /* usb 11.5.1.10 */ + 12 /* 32 msec counter */ + 1); @@ -208,7 +216,6 @@ __acquires(ohci->lock) temp &= OHCI_CTRL_HCFS; if (temp != OHCI_USB_RESUME) { ohci_err (ohci, "controller won't resume\n"); - spin_lock_irq(&ohci->lock); return -EBUSY; } @@ -288,6 +295,8 @@ __acquires(ohci->lock) return 0; } +#ifdef CONFIG_PM + static int ohci_bus_suspend (struct usb_hcd *hcd) { struct ohci_hcd *ohci = hcd_to_ohci (hcd); @@ -325,83 +334,6 @@ static int ohci_bus_resume (struct usb_hcd *hcd) return rc; } -/* Carry out polling-, autostop-, and autoresume-related state changes */ -static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed, - int any_connected) -{ - int poll_rh = 1; - - switch (ohci->hc_control & OHCI_CTRL_HCFS) { - - case OHCI_USB_OPER: - /* keep on polling until we know a device is connected - * and RHSC is enabled */ - if (!ohci->autostop) { - if (any_connected || - !device_may_wakeup(&ohci_to_hcd(ohci) - ->self.root_hub->dev)) { - if (ohci_readl(ohci, &ohci->regs->intrenable) & - OHCI_INTR_RHSC) - poll_rh = 0; - } else { - ohci->autostop = 1; - ohci->next_statechange = jiffies + HZ; - } - - /* if no devices have been attached for one second, autostop */ - } else { - if (changed || any_connected) { - ohci->autostop = 0; - ohci->next_statechange = jiffies + - STATECHANGE_DELAY; - } else if (time_after_eq(jiffies, - ohci->next_statechange) - && !ohci->ed_rm_list - && !(ohci->hc_control & - OHCI_SCHED_ENABLES)) { - ohci_rh_suspend(ohci, 1); - } - } - break; - - /* if there is a port change, autostart or ask to be resumed */ - case OHCI_USB_SUSPEND: - case OHCI_USB_RESUME: - if (changed) { - if (ohci->autostop) - ohci_rh_resume(ohci); - else - usb_hcd_resume_root_hub(ohci_to_hcd(ohci)); - } else { - /* everything is idle, no need for polling */ - poll_rh = 0; - } - break; - } - return poll_rh; -} - -#else /* CONFIG_PM */ - -static inline int ohci_rh_resume(struct ohci_hcd *ohci) -{ - return 0; -} - -/* Carry out polling-related state changes. - * autostop isn't used when CONFIG_PM is turned off. - */ -static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed, - int any_connected) -{ - int poll_rh = 1; - - /* keep on polling until RHSC is enabled */ - if (ohci_readl(ohci, &ohci->regs->intrenable) & OHCI_INTR_RHSC) - poll_rh = 0; - return poll_rh; -} - #endif /* CONFIG_PM */ /*-------------------------------------------------------------------------*/ @@ -413,7 +345,7 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf) { struct ohci_hcd *ohci = hcd_to_ohci (hcd); int i, changed = 0, length = 1; - int any_connected = 0; + int any_connected = 0, rhsc_enabled = 1; unsigned long flags; spin_lock_irqsave (&ohci->lock, flags); @@ -454,8 +386,66 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf) } } - hcd->poll_rh = ohci_root_hub_state_changes(ohci, changed, - any_connected); + /* NOTE: vendors didn't always make the same implementation + * choices for RHSC. Sometimes it triggers on an edge (like + * setting and maybe clearing a port status change bit); and + * it's level-triggered on other silicon, active until khubd + * clears all active port status change bits. If it's still + * set (level-triggered) we must disable it and rely on + * polling until khubd re-enables it. + */ + if (ohci_readl (ohci, &ohci->regs->intrstatus) & OHCI_INTR_RHSC) { + ohci_writel (ohci, OHCI_INTR_RHSC, &ohci->regs->intrdisable); + (void) ohci_readl (ohci, &ohci->regs->intrdisable); + rhsc_enabled = 0; + } + hcd->poll_rh = 1; + + /* carry out appropriate state changes */ + switch (ohci->hc_control & OHCI_CTRL_HCFS) { + + case OHCI_USB_OPER: + /* keep on polling until we know a device is connected + * and RHSC is enabled */ + if (!ohci->autostop) { + if (any_connected) { + if (rhsc_enabled) + hcd->poll_rh = 0; + } else { + ohci->autostop = 1; + ohci->next_statechange = jiffies + HZ; + } + + /* if no devices have been attached for one second, autostop */ + } else { + if (changed || any_connected) { + ohci->autostop = 0; + ohci->next_statechange = jiffies + + STATECHANGE_DELAY; + } else if (time_after_eq (jiffies, + ohci->next_statechange) + && !ohci->ed_rm_list + && !(ohci->hc_control & + OHCI_SCHED_ENABLES)) { + ohci_rh_suspend (ohci, 1); + } + } + break; + + /* if there is a port change, autostart or ask to be resumed */ + case OHCI_USB_SUSPEND: + case OHCI_USB_RESUME: + if (changed) { + if (ohci->autostop) + ohci_rh_resume (ohci); + else + usb_hcd_resume_root_hub (hcd); + } else { + /* everything is idle, no need for polling */ + hcd->poll_rh = 0; + } + break; + } done: spin_unlock_irqrestore (&ohci->lock, flags); diff --git a/trunk/drivers/usb/host/ohci-pnx4008.c b/trunk/drivers/usb/host/ohci-pnx4008.c index 2dbb77414905..82cb22f002e7 100644 --- a/trunk/drivers/usb/host/ohci-pnx4008.c +++ b/trunk/drivers/usb/host/ohci-pnx4008.c @@ -262,7 +262,6 @@ static const struct hc_driver ohci_pnx4008_hc_driver = { */ .start = ohci_pnx4008_start, .stop = ohci_stop, - .shutdown = ohci_shutdown, /* * managing i/o requests and associated device resources @@ -281,11 +280,7 @@ static const struct hc_driver ohci_pnx4008_hc_driver = { */ .hub_status_data = ohci_hub_status_data, .hub_control = ohci_hub_control, - .hub_irq_enable = ohci_rhsc_enable, -#ifdef CONFIG_PM - .bus_suspend = ohci_bus_suspend, - .bus_resume = ohci_bus_resume, -#endif + .start_port_reset = ohci_start_port_reset, }; @@ -415,6 +410,8 @@ static int __devinit usb_hcd_pnx4008_probe(struct platform_device *pdev) goto out4; } + hcd->self.hcpriv = (void *)hcd; + pnx4008_start_hc(); platform_set_drvdata(pdev, hcd); ohci = hcd_to_ohci(hcd); diff --git a/trunk/drivers/usb/host/ohci-q.c b/trunk/drivers/usb/host/ohci-q.c index fe1fe2f97cb5..e372306ed0da 100644 --- a/trunk/drivers/usb/host/ohci-q.c +++ b/trunk/drivers/usb/host/ohci-q.c @@ -7,8 +7,6 @@ * This file is licenced under the GPL. */ -#include - static void urb_free_priv (struct ohci_hcd *hc, urb_priv_t *urb_priv) { int last = urb_priv->length - 1; @@ -36,7 +34,7 @@ static void urb_free_priv (struct ohci_hcd *hc, urb_priv_t *urb_priv) * PRECONDITION: ohci lock held, irqs blocked. */ static void -finish_urb (struct ohci_hcd *ohci, struct urb *urb) +finish_urb (struct ohci_hcd *ohci, struct urb *urb, struct pt_regs *regs) __releases(ohci->lock) __acquires(ohci->lock) { @@ -75,7 +73,7 @@ __acquires(ohci->lock) /* urb->complete() can reenter this HCD */ spin_unlock (&ohci->lock); - usb_hcd_giveback_urb (ohci_to_hcd(ohci), urb); + usb_hcd_giveback_urb (ohci_to_hcd(ohci), urb, regs); spin_lock (&ohci->lock); /* stop periodic dma if it's not needed */ @@ -912,7 +910,7 @@ static struct td *dl_reverse_done_list (struct ohci_hcd *ohci) /* there are some urbs/eds to unlink; called in_irq(), with HCD locked */ static void -finish_unlinks (struct ohci_hcd *ohci, u16 tick) +finish_unlinks (struct ohci_hcd *ohci, u16 tick, struct pt_regs *regs) { struct ed *ed, **last; @@ -925,7 +923,7 @@ finish_unlinks (struct ohci_hcd *ohci, u16 tick) /* only take off EDs that the HC isn't using, accounting for * frame counter wraps and EDs with partially retired TDs */ - if (likely (HC_IS_RUNNING(ohci_to_hcd(ohci)->state))) { + if (likely (regs && HC_IS_RUNNING(ohci_to_hcd(ohci)->state))) { if (tick_before (tick, ed->tick)) { skip_ed: last = &ed->ed_next; @@ -992,7 +990,7 @@ finish_unlinks (struct ohci_hcd *ohci, u16 tick) /* if URB is done, clean up */ if (urb_priv->td_cnt == urb_priv->length) { modified = completed = 1; - finish_urb (ohci, urb); + finish_urb (ohci, urb, regs); } } if (completed && !list_empty (&ed->td_list)) @@ -1070,7 +1068,7 @@ finish_unlinks (struct ohci_hcd *ohci, u16 tick) * scanning the (re-reversed) donelist as this does. */ static void -dl_done_list (struct ohci_hcd *ohci) +dl_done_list (struct ohci_hcd *ohci, struct pt_regs *regs) { struct td *td = dl_reverse_done_list (ohci); @@ -1086,7 +1084,7 @@ dl_done_list (struct ohci_hcd *ohci) /* If all this urb's TDs are done, call complete() */ if (urb_priv->td_cnt == urb_priv->length) - finish_urb (ohci, urb); + finish_urb (ohci, urb, regs); /* clean schedule: unlink EDs that are no longer busy */ if (list_empty (&ed->td_list)) { diff --git a/trunk/drivers/usb/host/sl811-hcd.c b/trunk/drivers/usb/host/sl811-hcd.c index 5fa5647ea095..3a586aab3939 100644 --- a/trunk/drivers/usb/host/sl811-hcd.c +++ b/trunk/drivers/usb/host/sl811-hcd.c @@ -428,6 +428,7 @@ static void finish_request( struct sl811 *sl811, struct sl811h_ep *ep, struct urb *urb, + struct pt_regs *regs, int status ) __releases(sl811->lock) __acquires(sl811->lock) { @@ -443,7 +444,7 @@ static void finish_request( spin_unlock(&urb->lock); spin_unlock(&sl811->lock); - usb_hcd_giveback_urb(sl811_to_hcd(sl811), urb); + usb_hcd_giveback_urb(sl811_to_hcd(sl811), urb, regs); spin_lock(&sl811->lock); /* leave active endpoints in the schedule */ @@ -483,7 +484,7 @@ static void finish_request( } static void -done(struct sl811 *sl811, struct sl811h_ep *ep, u8 bank) +done(struct sl811 *sl811, struct sl811h_ep *ep, u8 bank, struct pt_regs *regs) { u8 status; struct urb *urb; @@ -607,7 +608,7 @@ done(struct sl811 *sl811, struct sl811h_ep *ep, u8 bank) } if (urb && (urbstat != -EINPROGRESS || urb->status != -EINPROGRESS)) - finish_request(sl811, ep, urb, urbstat); + finish_request(sl811, ep, urb, regs, urbstat); } static inline u8 checkdone(struct sl811 *sl811) @@ -640,7 +641,7 @@ static inline u8 checkdone(struct sl811 *sl811) return irqstat; } -static irqreturn_t sl811h_irq(struct usb_hcd *hcd) +static irqreturn_t sl811h_irq(struct usb_hcd *hcd, struct pt_regs *regs) { struct sl811 *sl811 = hcd_to_sl811(hcd); u8 irqstat; @@ -669,13 +670,13 @@ static irqreturn_t sl811h_irq(struct usb_hcd *hcd) * issued ... that's fine if they're different endpoints. */ if (irqstat & SL11H_INTMASK_DONE_A) { - done(sl811, sl811->active_a, SL811_EP_A(SL811_HOST_BUF)); + done(sl811, sl811->active_a, SL811_EP_A(SL811_HOST_BUF), regs); sl811->active_a = NULL; sl811->stat_a++; } #ifdef USE_B if (irqstat & SL11H_INTMASK_DONE_B) { - done(sl811, sl811->active_b, SL811_EP_B(SL811_HOST_BUF)); + done(sl811, sl811->active_b, SL811_EP_B(SL811_HOST_BUF), regs); sl811->active_b = NULL; sl811->stat_b++; } @@ -722,7 +723,7 @@ static irqreturn_t sl811h_irq(struct usb_hcd *hcd) container_of(sl811->active_a ->hep->urb_list.next, struct urb, urb_list), - -ESHUTDOWN); + NULL, -ESHUTDOWN); sl811->active_a = NULL; } #ifdef USE_B @@ -956,7 +957,7 @@ static int sl811h_urb_enqueue( spin_lock(&urb->lock); if (urb->status != -EINPROGRESS) { spin_unlock(&urb->lock); - finish_request(sl811, ep, urb, 0); + finish_request(sl811, ep, urb, NULL, 0); retval = 0; goto fail; } @@ -1025,7 +1026,7 @@ static int sl811h_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) } if (urb) - finish_request(sl811, ep, urb, 0); + finish_request(sl811, ep, urb, NULL, 0); else VDBG("dequeue, urb %p active %s; wait4irq\n", urb, (sl811->active_a == ep) ? "A" : "B"); @@ -1082,7 +1083,7 @@ sl811h_hub_status_data(struct usb_hcd *hcd, char *buf) */ local_irq_save(flags); if (!timer_pending(&sl811->timer)) { - if (sl811h_irq( /* ~0, */ hcd) != IRQ_NONE) + if (sl811h_irq( /* ~0, */ hcd, NULL) != IRQ_NONE) sl811->stat_lost++; } local_irq_restore(flags); diff --git a/trunk/drivers/usb/host/u132-hcd.c b/trunk/drivers/usb/host/u132-hcd.c index ef54e310bfc4..0a315200b331 100644 --- a/trunk/drivers/usb/host/u132-hcd.c +++ b/trunk/drivers/usb/host/u132-hcd.c @@ -71,7 +71,7 @@ static int distrust_firmware = 1; module_param(distrust_firmware, bool, 0); MODULE_PARM_DESC(distrust_firmware, "true to distrust firmware power/overcurren" "t setup"); -static DECLARE_WAIT_QUEUE_HEAD(u132_hcd_wait); +DECLARE_WAIT_QUEUE_HEAD(u132_hcd_wait); /* * u132_module_lock exists to protect access to global variables * @@ -205,9 +205,13 @@ struct u132 { struct u132_port port[MAX_U132_PORTS]; struct u132_endp *endp[MAX_U132_ENDPS]; }; - +int usb_ftdi_elan_read_reg(struct platform_device *pdev, u32 *data); +int usb_ftdi_elan_read_pcimem(struct platform_device *pdev, u8 addressofs, + u8 width, u32 *data); +int usb_ftdi_elan_write_pcimem(struct platform_device *pdev, u8 addressofs, + u8 width, u32 data); /* -* these cannot be inlines because we need the structure offset!! +* these can not be inlines because we need the structure offset!! * Does anyone have a better way????? */ #define u132_read_pcimem(u132, member, data) \ @@ -553,7 +557,7 @@ static void u132_hcd_giveback_urb(struct u132 *u132, struct u132_endp *endp, u132_ring_queue_work(u132, ring, 0); up(&u132->scheduler_lock); u132_endp_put_kref(u132, endp); - usb_hcd_giveback_urb(hcd, urb); + usb_hcd_giveback_urb(hcd, urb, NULL); return; } @@ -586,7 +590,7 @@ static void u132_hcd_abandon_urb(struct u132 *u132, struct u132_endp *endp, endp->active = 0; spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); kfree(urbq); - } usb_hcd_giveback_urb(hcd, urb); + } usb_hcd_giveback_urb(hcd, urb, NULL); return; } @@ -2430,7 +2434,7 @@ static int dequeue_from_overflow_chain(struct u132 *u132, endp->queue_size -= 1; urb->error_count = 0; urb->hcpriv = NULL; - usb_hcd_giveback_urb(hcd, urb); + usb_hcd_giveback_urb(hcd, urb, NULL); return 0; } else continue; @@ -2508,7 +2512,7 @@ static int u132_endp_urb_dequeue(struct u132 *u132, struct u132_endp *endp, kfree(urbq); } urb->error_count = 0; urb->hcpriv = NULL; - usb_hcd_giveback_urb(hcd, urb); + usb_hcd_giveback_urb(hcd, urb, NULL); return 0; } else if (list_empty(&endp->urb_more)) { dev_err(&u132->platform_dev->dev, "urb=%p not found in " @@ -3041,7 +3045,7 @@ static struct hc_driver u132_hc_driver = { * This function may be called by the USB core whilst the "usb_all_devices_rwsem" * is held for writing, thus this module must not call usb_remove_hcd() * synchronously - but instead should immediately stop activity to the -* device and asynchronously call usb_remove_hcd() +* device and ansynchronously call usb_remove_hcd() */ static int __devexit u132_remove(struct platform_device *pdev) { @@ -3237,7 +3241,7 @@ static int u132_resume(struct platform_device *pdev) #define u132_resume NULL #endif /* -* this driver is loaded explicitly by ftdi_u132 +* this driver is loaded explicitely by ftdi_u132 * * the platform_driver struct is static because it is per type of module */ diff --git a/trunk/drivers/usb/host/uhci-hcd.c b/trunk/drivers/usb/host/uhci-hcd.c index 226bf3de8edd..eb4eab98e8bf 100644 --- a/trunk/drivers/usb/host/uhci-hcd.c +++ b/trunk/drivers/usb/host/uhci-hcd.c @@ -40,7 +40,6 @@ #include #include #include -#include #include #include @@ -197,42 +196,12 @@ static int resume_detect_interrupts_are_broken(struct uhci_hcd *uhci) return 0; } -static int remote_wakeup_is_broken(struct uhci_hcd *uhci) -{ - static struct dmi_system_id broken_wakeup_table[] = { - { - .ident = "Asus A7V8X", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK"), - DMI_MATCH(DMI_BOARD_NAME, "A7V8X"), - DMI_MATCH(DMI_BOARD_VERSION, "REV 1.xx"), - } - }, - { } - }; - int port; - - /* One of Asus's motherboards has a bug which causes it to - * wake up immediately from suspend-to-RAM if any of the ports - * are connected. In such cases we will not set EGSM. - */ - if (dmi_check_system(broken_wakeup_table)) { - for (port = 0; port < uhci->rh_numports; ++port) { - if (inw(uhci->io_addr + USBPORTSC1 + port * 2) & - USBPORTSC_CCS) - return 1; - } - } - - return 0; -} - static void suspend_rh(struct uhci_hcd *uhci, enum uhci_rh_state new_state) __releases(uhci->lock) __acquires(uhci->lock) { int auto_stop; - int int_enable, egsm_enable; + int int_enable; auto_stop = (new_state == UHCI_RH_AUTO_STOPPED); dev_dbg(&uhci_to_hcd(uhci)->self.root_hub->dev, @@ -248,18 +217,15 @@ __acquires(uhci->lock) } /* Enable resume-detect interrupts if they work. - * Then enter Global Suspend mode if _it_ works, still configured. + * Then enter Global Suspend mode, still configured. */ - egsm_enable = USBCMD_EGSM; uhci->working_RD = 1; int_enable = USBINTR_RESUME; - if (remote_wakeup_is_broken(uhci)) - egsm_enable = 0; - if (resume_detect_interrupts_are_broken(uhci) || !egsm_enable) + if (resume_detect_interrupts_are_broken(uhci)) { uhci->working_RD = int_enable = 0; - + } outw(int_enable, uhci->io_addr + USBINTR); - outw(egsm_enable | USBCMD_CF, uhci->io_addr + USBCMD); + outw(USBCMD_EGSM | USBCMD_CF, uhci->io_addr + USBCMD); mb(); udelay(5); @@ -286,7 +252,7 @@ __acquires(uhci->lock) uhci->is_stopped = UHCI_IS_STOPPED; uhci_to_hcd(uhci)->poll_rh = !int_enable; - uhci_scan_schedule(uhci); + uhci_scan_schedule(uhci, NULL); uhci_fsbr_off(uhci); } @@ -343,7 +309,7 @@ __acquires(uhci->lock) mod_timer(&uhci_to_hcd(uhci)->rh_timer, jiffies); } -static irqreturn_t uhci_irq(struct usb_hcd *hcd) +static irqreturn_t uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs) { struct uhci_hcd *uhci = hcd_to_uhci(hcd); unsigned short status; @@ -392,7 +358,7 @@ static irqreturn_t uhci_irq(struct usb_hcd *hcd) usb_hcd_poll_rh_status(hcd); else { spin_lock_irqsave(&uhci->lock, flags); - uhci_scan_schedule(uhci); + uhci_scan_schedule(uhci, regs); spin_unlock_irqrestore(&uhci->lock, flags); } @@ -705,7 +671,7 @@ static void uhci_stop(struct usb_hcd *hcd) spin_lock_irq(&uhci->lock); if (test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags) && !uhci->dead) uhci_hc_died(uhci); - uhci_scan_schedule(uhci); + uhci_scan_schedule(uhci, NULL); spin_unlock_irq(&uhci->lock); del_timer_sync(&uhci->fsbr_timer); diff --git a/trunk/drivers/usb/host/uhci-hub.c b/trunk/drivers/usb/host/uhci-hub.c index f8347f1a10b6..16fb72eb6fc9 100644 --- a/trunk/drivers/usb/host/uhci-hub.c +++ b/trunk/drivers/usb/host/uhci-hub.c @@ -176,7 +176,7 @@ static int uhci_hub_status_data(struct usb_hcd *hcd, char *buf) spin_lock_irqsave(&uhci->lock, flags); - uhci_scan_schedule(uhci); + uhci_scan_schedule(uhci, NULL); if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags) || uhci->dead) goto done; uhci_check_ports(uhci); diff --git a/trunk/drivers/usb/host/uhci-q.c b/trunk/drivers/usb/host/uhci-q.c index 06115f22a4fa..431e8f31f1a9 100644 --- a/trunk/drivers/usb/host/uhci-q.c +++ b/trunk/drivers/usb/host/uhci-q.c @@ -1244,7 +1244,7 @@ static int uhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) * Finish unlinking an URB and give it back */ static void uhci_giveback_urb(struct uhci_hcd *uhci, struct uhci_qh *qh, - struct urb *urb) + struct urb *urb, struct pt_regs *regs) __releases(uhci->lock) __acquires(uhci->lock) { @@ -1293,7 +1293,7 @@ __acquires(uhci->lock) } spin_unlock(&uhci->lock); - usb_hcd_giveback_urb(uhci_to_hcd(uhci), urb); + usb_hcd_giveback_urb(uhci_to_hcd(uhci), urb, regs); spin_lock(&uhci->lock); /* If the queue is now empty, we can unlink the QH and give up its @@ -1313,7 +1313,8 @@ __acquires(uhci->lock) (qh->state == QH_STATE_UNLINKING && \ uhci->frame_number + uhci->is_stopped != qh->unlink_frame) -static void uhci_scan_qh(struct uhci_hcd *uhci, struct uhci_qh *qh) +static void uhci_scan_qh(struct uhci_hcd *uhci, struct uhci_qh *qh, + struct pt_regs *regs) { struct urb_priv *urbp; struct urb *urb; @@ -1346,7 +1347,7 @@ static void uhci_scan_qh(struct uhci_hcd *uhci, struct uhci_qh *qh) return; } - uhci_giveback_urb(uhci, qh, urb); + uhci_giveback_urb(uhci, qh, urb, regs); if (status < 0 && qh->type != USB_ENDPOINT_XFER_ISOC) break; } @@ -1371,7 +1372,7 @@ static void uhci_scan_qh(struct uhci_hcd *uhci, struct uhci_qh *qh) qh->is_stopped = 0; return; } - uhci_giveback_urb(uhci, qh, urb); + uhci_giveback_urb(uhci, qh, urb, regs); goto restart; } } @@ -1486,7 +1487,7 @@ static int uhci_advance_check(struct uhci_hcd *uhci, struct uhci_qh *qh) /* * Process events in the schedule, but only in one thread at a time */ -static void uhci_scan_schedule(struct uhci_hcd *uhci) +static void uhci_scan_schedule(struct uhci_hcd *uhci, struct pt_regs *regs) { int i; struct uhci_qh *qh; @@ -1514,7 +1515,7 @@ static void uhci_scan_schedule(struct uhci_hcd *uhci) struct uhci_qh, node); if (uhci_advance_check(uhci, qh)) { - uhci_scan_qh(uhci, qh); + uhci_scan_qh(uhci, qh, regs); if (qh->state == QH_STATE_ACTIVE) { uhci_urbp_wants_fsbr(uhci, list_entry(qh->queue.next, struct urb_priv, node)); diff --git a/trunk/drivers/usb/image/mdc800.c b/trunk/drivers/usb/image/mdc800.c index 63a84bbc310d..ca6305c1d64c 100644 --- a/trunk/drivers/usb/image/mdc800.c +++ b/trunk/drivers/usb/image/mdc800.c @@ -280,7 +280,7 @@ static int mdc800_isReady (char *ch) /* * USB IRQ Handler for InputLine */ -static void mdc800_usb_irq (struct urb *urb) +static void mdc800_usb_irq (struct urb *urb, struct pt_regs *res) { int data_received=0, wake_up; unsigned char* b=urb->transfer_buffer; @@ -374,7 +374,7 @@ static int mdc800_usb_waitForIRQ (int mode, int msec) /* * The write_urb callback function */ -static void mdc800_usb_write_notify (struct urb *urb) +static void mdc800_usb_write_notify (struct urb *urb, struct pt_regs *res) { struct mdc800_data* mdc800=urb->context; @@ -394,7 +394,7 @@ static void mdc800_usb_write_notify (struct urb *urb) /* * The download_urb callback function */ -static void mdc800_usb_download_notify (struct urb *urb) +static void mdc800_usb_download_notify (struct urb *urb, struct pt_regs *res) { struct mdc800_data* mdc800=urb->context; diff --git a/trunk/drivers/usb/image/microtek.c b/trunk/drivers/usb/image/microtek.c index 8ccddf74534a..5f861331932a 100644 --- a/trunk/drivers/usb/image/microtek.c +++ b/trunk/drivers/usb/image/microtek.c @@ -370,7 +370,7 @@ static int mts_scsi_queuecommand(struct scsi_cmnd *srb, mts_scsi_cmnd_callback callback); static void mts_transfer_cleanup( struct urb *transfer ); -static void mts_do_sg(struct urb * transfer); +static void mts_do_sg(struct urb * transfer, struct pt_regs *regs); static inline void mts_int_submit_urb (struct urb* transfer, @@ -417,7 +417,7 @@ static void mts_transfer_cleanup( struct urb *transfer ) } -static void mts_transfer_done( struct urb *transfer ) +static void mts_transfer_done( struct urb *transfer, struct pt_regs *regs ) { MTS_INT_INIT(); @@ -443,7 +443,7 @@ static void mts_get_status( struct urb *transfer ) mts_transfer_done ); } -static void mts_data_done( struct urb* transfer ) +static void mts_data_done( struct urb* transfer, struct pt_regs *regs ) /* Interrupt context! */ { MTS_INT_INIT(); @@ -460,7 +460,7 @@ static void mts_data_done( struct urb* transfer ) } -static void mts_command_done( struct urb *transfer ) +static void mts_command_done( struct urb *transfer, struct pt_regs *regs ) /* Interrupt context! */ { MTS_INT_INIT(); @@ -501,7 +501,7 @@ static void mts_command_done( struct urb *transfer ) return; } -static void mts_do_sg (struct urb* transfer) +static void mts_do_sg (struct urb* transfer, struct pt_regs *regs) { struct scatterlist * sg; MTS_INT_INIT(); @@ -796,7 +796,7 @@ static int mts_usb_probe(struct usb_interface *intf, new_desc->context.scsi_status = kmalloc(1, GFP_KERNEL); if (!new_desc->context.scsi_status) - goto out_free_urb; + goto out_kfree2; new_desc->usb_dev = dev; new_desc->usb_intf = intf; @@ -822,20 +822,18 @@ static int mts_usb_probe(struct usb_interface *intf, new_desc->host = scsi_host_alloc(&mts_scsi_host_template, sizeof(new_desc)); if (!new_desc->host) - goto out_kfree2; + goto out_free_urb; new_desc->host->hostdata[0] = (unsigned long)new_desc; if (scsi_add_host(new_desc->host, NULL)) { err_retval = -EIO; - goto out_host_put; + goto out_free_urb; } scsi_scan_host(new_desc->host); usb_set_intfdata(intf, new_desc); return 0; - out_host_put: - scsi_host_put(new_desc->host); out_kfree2: kfree(new_desc->context.scsi_status); out_free_urb: diff --git a/trunk/drivers/usb/input/Kconfig b/trunk/drivers/usb/input/Kconfig index 661af7aa6236..21cd22640080 100644 --- a/trunk/drivers/usb/input/Kconfig +++ b/trunk/drivers/usb/input/Kconfig @@ -221,7 +221,6 @@ config USB_TOUCHSCREEN - ITM - some other eTurboTouch - Gunze AHL61 - - DMC TSC-10/25 Have a look at for a usage description and the required user-space stuff. @@ -259,11 +258,6 @@ config USB_TOUCHSCREEN_GUNZE bool "Gunze AHL61 device support" if EMBEDDED depends on USB_TOUCHSCREEN -config USB_TOUCHSCREEN_DMC_TSC10 - default y - bool "DMC TSC-10/25 device support" if EMBEDDED - depends on USB_TOUCHSCREEN - config USB_YEALINK tristate "Yealink usb-p1k voip phone" depends on USB && INPUT && EXPERIMENTAL @@ -354,3 +348,13 @@ config USB_APPLETOUCH To compile this driver as a module, choose M here: the module will be called appletouch. + +config USB_TRANCEVIBRATOR + tristate "PlayStation 2 Trance Vibrator driver support" + depends on USB + help + Say Y here if you want to connect a PlayStation 2 Trance Vibrator + device to your computer's USB port. + + To compile this driver as a module, choose M here: the + module will be called trancevibrator. diff --git a/trunk/drivers/usb/input/Makefile b/trunk/drivers/usb/input/Makefile index d946d5213b30..295f459d1079 100644 --- a/trunk/drivers/usb/input/Makefile +++ b/trunk/drivers/usb/input/Makefile @@ -3,7 +3,7 @@ # # Multipart objects. -wacom-objs := wacom_wac.o wacom_sys.o +wacom-objs := wacom_sys.o wacom_wac.o usbhid-objs := hid-core.o # Optional parts of multipart objects. @@ -48,6 +48,7 @@ obj-$(CONFIG_USB_ACECAD) += acecad.o obj-$(CONFIG_USB_YEALINK) += yealink.o obj-$(CONFIG_USB_XPAD) += xpad.o obj-$(CONFIG_USB_APPLETOUCH) += appletouch.o +obj-$(CONFIG_USB_TRANCEVIBRATOR) += trancevibrator.o ifeq ($(CONFIG_USB_DEBUG),y) EXTRA_CFLAGS += -DDEBUG diff --git a/trunk/drivers/usb/input/acecad.c b/trunk/drivers/usb/input/acecad.c index 0096373b5f98..d83603ba40ae 100644 --- a/trunk/drivers/usb/input/acecad.c +++ b/trunk/drivers/usb/input/acecad.c @@ -58,7 +58,7 @@ struct usb_acecad { dma_addr_t data_dma; }; -static void usb_acecad_irq(struct urb *urb) +static void usb_acecad_irq(struct urb *urb, struct pt_regs *regs) { struct usb_acecad *acecad = urb->context; unsigned char *data = acecad->data; diff --git a/trunk/drivers/usb/input/aiptek.c b/trunk/drivers/usb/input/aiptek.c index bf428184608f..b138dae2b055 100644 --- a/trunk/drivers/usb/input/aiptek.c +++ b/trunk/drivers/usb/input/aiptek.c @@ -396,7 +396,7 @@ static int aiptek_convert_from_2s_complement(unsigned char c) * replaced with the input_sync() method (which emits EV_SYN.) */ -static void aiptek_irq(struct urb *urb) +static void aiptek_irq(struct urb *urb, struct pt_regs *regs) { struct aiptek *aiptek = urb->context; unsigned char *data = aiptek->data; @@ -442,6 +442,8 @@ static void aiptek_irq(struct urb *urb) aiptek->diagnostic = AIPTEK_DIAGNOSTIC_SENDING_RELATIVE_IN_ABSOLUTE; } else { + input_regs(inputdev, regs); + x = aiptek_convert_from_2s_complement(data[2]); y = aiptek_convert_from_2s_complement(data[3]); @@ -486,6 +488,8 @@ static void aiptek_irq(struct urb *urb) (aiptek->curSetting.pointerMode)) { aiptek->diagnostic = AIPTEK_DIAGNOSTIC_TOOL_DISALLOWED; } else { + input_regs(inputdev, regs); + x = le16_to_cpu(get_unaligned((__le16 *) (data + 1))); y = le16_to_cpu(get_unaligned((__le16 *) (data + 3))); z = le16_to_cpu(get_unaligned((__le16 *) (data + 6))); @@ -564,6 +568,7 @@ static void aiptek_irq(struct urb *urb) (aiptek->curSetting.pointerMode)) { aiptek->diagnostic = AIPTEK_DIAGNOSTIC_TOOL_DISALLOWED; } else { + input_regs(inputdev, regs); x = le16_to_cpu(get_unaligned((__le16 *) (data + 1))); y = le16_to_cpu(get_unaligned((__le16 *) (data + 3))); @@ -626,6 +631,8 @@ static void aiptek_irq(struct urb *urb) z = le16_to_cpu(get_unaligned((__le16 *) (data + 4))); if (dv != 0) { + input_regs(inputdev, regs); + /* If we've not already sent a tool_button_?? code, do * so now. Then set FIRED_BIT so it won't be resent unless * the user forces FIRED_BIT off. @@ -674,6 +681,8 @@ static void aiptek_irq(struct urb *urb) macro = data[3]; if (dv != 0) { + input_regs(inputdev, regs); + /* If we've not already sent a tool_button_?? code, do * so now. Then set FIRED_BIT so it won't be resent unless * the user forces FIRED_BIT off. @@ -717,6 +726,8 @@ static void aiptek_irq(struct urb *urb) */ else if (data[0] == 6) { macro = le16_to_cpu(get_unaligned((__le16 *) (data + 1))); + input_regs(inputdev, regs); + if (macro > 0) { input_report_key(inputdev, macroKeyEvents[macro - 1], 0); diff --git a/trunk/drivers/usb/input/appletouch.c b/trunk/drivers/usb/input/appletouch.c index 4c213513484d..0aa9cc2bfd69 100644 --- a/trunk/drivers/usb/input/appletouch.c +++ b/trunk/drivers/usb/input/appletouch.c @@ -210,7 +210,7 @@ static inline void atp_report_fingers(struct input_dev *input, int fingers) input_report_key(input, BTN_TOOL_TRIPLETAP, fingers > 2); } -static void atp_complete(struct urb* urb) +static void atp_complete(struct urb* urb, struct pt_regs* regs) { int x, y, x_z, y_z, x_f, y_f; int retval, i, j; diff --git a/trunk/drivers/usb/input/ati_remote.c b/trunk/drivers/usb/input/ati_remote.c index ff23318dc301..3558d7ed99b9 100644 --- a/trunk/drivers/usb/input/ati_remote.c +++ b/trunk/drivers/usb/input/ati_remote.c @@ -283,9 +283,9 @@ static void ati_remote_dump (unsigned char *data, unsigned int actual_length); static int ati_remote_open (struct input_dev *inputdev); static void ati_remote_close (struct input_dev *inputdev); static int ati_remote_sendpacket (struct ati_remote *ati_remote, u16 cmd, unsigned char *data); -static void ati_remote_irq_out (struct urb *urb); -static void ati_remote_irq_in (struct urb *urb); -static void ati_remote_input_report (struct urb *urb); +static void ati_remote_irq_out (struct urb *urb, struct pt_regs *regs); +static void ati_remote_irq_in (struct urb *urb, struct pt_regs *regs); +static void ati_remote_input_report (struct urb *urb, struct pt_regs *regs); static int ati_remote_initialize (struct ati_remote *ati_remote); static int ati_remote_probe (struct usb_interface *interface, const struct usb_device_id *id); static void ati_remote_disconnect (struct usb_interface *interface); @@ -344,7 +344,7 @@ static void ati_remote_close(struct input_dev *inputdev) /* * ati_remote_irq_out */ -static void ati_remote_irq_out(struct urb *urb) +static void ati_remote_irq_out(struct urb *urb, struct pt_regs *regs) { struct ati_remote *ati_remote = urb->context; @@ -453,7 +453,7 @@ static int ati_remote_compute_accel(struct ati_remote *ati_remote) /* * ati_remote_report_input */ -static void ati_remote_input_report(struct urb *urb) +static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs) { struct ati_remote *ati_remote = urb->context; unsigned char *data= ati_remote->inbuf; @@ -491,6 +491,7 @@ static void ati_remote_input_report(struct urb *urb) remote_num, data[1], data[2], index, ati_remote_tbl[index].code); if (ati_remote_tbl[index].kind == KIND_LITERAL) { + input_regs(dev, regs); input_event(dev, ati_remote_tbl[index].type, ati_remote_tbl[index].code, ati_remote_tbl[index].value); @@ -519,6 +520,7 @@ static void ati_remote_input_report(struct urb *urb) return; + input_regs(dev, regs); input_event(dev, ati_remote_tbl[index].type, ati_remote_tbl[index].code, 1); input_sync(dev); @@ -535,6 +537,7 @@ static void ati_remote_input_report(struct urb *urb) */ acc = ati_remote_compute_accel(ati_remote); + input_regs(dev, regs); switch (ati_remote_tbl[index].kind) { case KIND_ACCEL: input_event(dev, ati_remote_tbl[index].type, @@ -572,14 +575,14 @@ static void ati_remote_input_report(struct urb *urb) /* * ati_remote_irq_in */ -static void ati_remote_irq_in(struct urb *urb) +static void ati_remote_irq_in(struct urb *urb, struct pt_regs *regs) { struct ati_remote *ati_remote = urb->context; int retval; switch (urb->status) { case 0: /* success */ - ati_remote_input_report(urb); + ati_remote_input_report(urb, regs); break; case -ECONNRESET: /* unlink */ case -ENOENT: @@ -630,14 +633,19 @@ static int ati_remote_alloc_buffers(struct usb_device *udev, */ static void ati_remote_free_buffers(struct ati_remote *ati_remote) { - usb_free_urb(ati_remote->irq_urb); - usb_free_urb(ati_remote->out_urb); + if (ati_remote->irq_urb) + usb_free_urb(ati_remote->irq_urb); - usb_buffer_free(ati_remote->udev, DATA_BUFSIZE, - ati_remote->inbuf, ati_remote->inbuf_dma); + if (ati_remote->out_urb) + usb_free_urb(ati_remote->out_urb); - usb_buffer_free(ati_remote->udev, DATA_BUFSIZE, - ati_remote->outbuf, ati_remote->outbuf_dma); + if (ati_remote->inbuf) + usb_buffer_free(ati_remote->udev, DATA_BUFSIZE, + ati_remote->inbuf, ati_remote->inbuf_dma); + + if (ati_remote->outbuf) + usb_buffer_free(ati_remote->udev, DATA_BUFSIZE, + ati_remote->inbuf, ati_remote->outbuf_dma); } static void ati_remote_input_init(struct ati_remote *ati_remote) diff --git a/trunk/drivers/usb/input/ati_remote2.c b/trunk/drivers/usb/input/ati_remote2.c index 83f1f79db7c7..ea71de81ca6b 100644 --- a/trunk/drivers/usb/input/ati_remote2.c +++ b/trunk/drivers/usb/input/ati_remote2.c @@ -142,7 +142,7 @@ static void ati_remote2_close(struct input_dev *idev) usb_kill_urb(ar2->urb[1]); } -static void ati_remote2_input_mouse(struct ati_remote2 *ar2) +static void ati_remote2_input_mouse(struct ati_remote2 *ar2, struct pt_regs *regs) { struct input_dev *idev = ar2->idev; u8 *data = ar2->buf[0]; @@ -157,6 +157,7 @@ static void ati_remote2_input_mouse(struct ati_remote2 *ar2) if (!((1 << data[0]) & mode_mask)) return; + input_regs(idev, regs); input_event(idev, EV_REL, REL_X, (s8) data[1]); input_event(idev, EV_REL, REL_Y, (s8) data[2]); input_sync(idev); @@ -173,7 +174,7 @@ static int ati_remote2_lookup(unsigned int hw_code) return -1; } -static void ati_remote2_input_key(struct ati_remote2 *ar2) +static void ati_remote2_input_key(struct ati_remote2 *ar2, struct pt_regs *regs) { struct input_dev *idev = ar2->idev; u8 *data = ar2->buf[1]; @@ -244,18 +245,19 @@ static void ati_remote2_input_key(struct ati_remote2 *ar2) return; } + input_regs(idev, regs); input_event(idev, EV_KEY, ati_remote2_key_table[index].key_code, data[1]); input_sync(idev); } -static void ati_remote2_complete_mouse(struct urb *urb) +static void ati_remote2_complete_mouse(struct urb *urb, struct pt_regs *regs) { struct ati_remote2 *ar2 = urb->context; int r; switch (urb->status) { case 0: - ati_remote2_input_mouse(ar2); + ati_remote2_input_mouse(ar2, regs); break; case -ENOENT: case -EILSEQ: @@ -275,14 +277,14 @@ static void ati_remote2_complete_mouse(struct urb *urb) "%s(): usb_submit_urb() = %d\n", __FUNCTION__, r); } -static void ati_remote2_complete_key(struct urb *urb) +static void ati_remote2_complete_key(struct urb *urb, struct pt_regs *regs) { struct ati_remote2 *ar2 = urb->context; int r; switch (urb->status) { case 0: - ati_remote2_input_key(ar2); + ati_remote2_input_key(ar2, regs); break; case -ENOENT: case -EILSEQ: @@ -372,7 +374,8 @@ static void ati_remote2_urb_cleanup(struct ati_remote2 *ar2) int i; for (i = 0; i < 2; i++) { - usb_free_urb(ar2->urb[i]); + if (ar2->urb[i]) + usb_free_urb(ar2->urb[i]); if (ar2->buf[i]) usb_buffer_free(ar2->udev, 4, ar2->buf[i], ar2->buf_dma[i]); diff --git a/trunk/drivers/usb/input/hid-core.c b/trunk/drivers/usb/input/hid-core.c index a49644b7c58e..e0fd11605b43 100644 --- a/trunk/drivers/usb/input/hid-core.c +++ b/trunk/drivers/usb/input/hid-core.c @@ -270,7 +270,7 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign * Read data value from item. */ -static u32 item_udata(struct hid_item *item) +static __inline__ __u32 item_udata(struct hid_item *item) { switch (item->size) { case 1: return item->data.u8; @@ -280,7 +280,7 @@ static u32 item_udata(struct hid_item *item) return 0; } -static s32 item_sdata(struct hid_item *item) +static __inline__ __s32 item_sdata(struct hid_item *item) { switch (item->size) { case 1: return item->data.s8; @@ -727,7 +727,7 @@ static struct hid_device *hid_parse_report(__u8 *start, unsigned size) * done by hand. */ -static s32 snto32(__u32 value, unsigned n) +static __inline__ __s32 snto32(__u32 value, unsigned n) { switch (n) { case 8: return ((__s8)value); @@ -741,65 +741,30 @@ static s32 snto32(__u32 value, unsigned n) * Convert a signed 32-bit integer to a signed n-bit integer. */ -static u32 s32ton(__s32 value, unsigned n) +static __inline__ __u32 s32ton(__s32 value, unsigned n) { - s32 a = value >> (n - 1); + __s32 a = value >> (n - 1); if (a && a != -1) return value < 0 ? 1 << (n - 1) : (1 << (n - 1)) - 1; return value & ((1 << n) - 1); } /* - * Extract/implement a data field from/to a little endian report (bit array). - * - * Code sort-of follows HID spec: - * http://www.usb.org/developers/devclass_docs/HID1_11.pdf - * - * While the USB HID spec allows unlimited length bit fields in "report - * descriptors", most devices never use more than 16 bits. - * One model of UPS is claimed to report "LINEV" as a 32-bit field. - * Search linux-kernel and linux-usb-devel archives for "hid-core extract". + * Extract/implement a data field from/to a report. */ static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n) { - u64 x; - - WARN_ON(n > 32); - - report += offset >> 3; /* adjust byte index */ - offset &= 7; /* now only need bit offset into one byte */ - x = get_unaligned((u64 *) report); - x = le64_to_cpu(x); - x = (x >> offset) & ((1ULL << n) - 1); /* extract bit field */ - return (u32) x; + report += (offset >> 5) << 2; offset &= 31; + return (le64_to_cpu(get_unaligned((__le64*)report)) >> offset) & ((1ULL << n) - 1); } -/* - * "implement" : set bits in a little endian bit stream. - * Same concepts as "extract" (see comments above). - * The data mangled in the bit stream remains in little endian - * order the whole time. It make more sense to talk about - * endianness of register values by considering a register - * a "cached" copy of the little endiad bit stream. - */ static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u32 value) { - u64 x; - u64 m = (1ULL << n) - 1; - - WARN_ON(n > 32); - - WARN_ON(value > m); - value &= m; - - report += offset >> 3; - offset &= 7; - - x = get_unaligned((u64 *)report); - x &= cpu_to_le64(~(m << offset)); - x |= cpu_to_le64(((u64) value) << offset); - put_unaligned(x, (u64 *) report); + report += (offset >> 5) << 2; offset &= 31; + put_unaligned((get_unaligned((__le64*)report) + & cpu_to_le64(~((((__u64) 1 << n) - 1) << offset))) + | cpu_to_le64((__u64)value << offset), (__le64*)report); } /* @@ -815,13 +780,13 @@ static __inline__ int search(__s32 *array, __s32 value, unsigned n) return -1; } -static void hid_process_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, int interrupt) +static void hid_process_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, int interrupt, struct pt_regs *regs) { hid_dump_input(usage, value); if (hid->claimed & HID_CLAIMED_INPUT) - hidinput_hid_event(hid, field, usage, value); + hidinput_hid_event(hid, field, usage, value, regs); if (hid->claimed & HID_CLAIMED_HIDDEV && interrupt) - hiddev_hid_event(hid, field, usage, value); + hiddev_hid_event(hid, field, usage, value, regs); } /* @@ -830,7 +795,7 @@ static void hid_process_event(struct hid_device *hid, struct hid_field *field, s * reporting to the layer). */ -static void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, int interrupt) +static void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, int interrupt, struct pt_regs *regs) { unsigned n; unsigned count = field->report_count; @@ -857,19 +822,19 @@ static void hid_input_field(struct hid_device *hid, struct hid_field *field, __u for (n = 0; n < count; n++) { if (HID_MAIN_ITEM_VARIABLE & field->flags) { - hid_process_event(hid, field, &field->usage[n], value[n], interrupt); + hid_process_event(hid, field, &field->usage[n], value[n], interrupt, regs); continue; } if (field->value[n] >= min && field->value[n] <= max && field->usage[field->value[n] - min].hid && search(value, field->value[n], count)) - hid_process_event(hid, field, &field->usage[field->value[n] - min], 0, interrupt); + hid_process_event(hid, field, &field->usage[field->value[n] - min], 0, interrupt, regs); if (value[n] >= min && value[n] <= max && field->usage[value[n] - min].hid && search(field->value, value[n], count)) - hid_process_event(hid, field, &field->usage[value[n] - min], 1, interrupt); + hid_process_event(hid, field, &field->usage[value[n] - min], 1, interrupt, regs); } memcpy(field->value, value, count * sizeof(__s32)); @@ -877,7 +842,7 @@ static void hid_input_field(struct hid_device *hid, struct hid_field *field, __u kfree(value); } -static int hid_input_report(int type, struct urb *urb, int interrupt) +static int hid_input_report(int type, struct urb *urb, int interrupt, struct pt_regs *regs) { struct hid_device *hid = urb->context; struct hid_report_enum *report_enum = hid->report_enum + type; @@ -927,7 +892,7 @@ static int hid_input_report(int type, struct urb *urb, int interrupt) hiddev_report_event(hid, report); for (n = 0; n < report->maxfield; n++) - hid_input_field(hid, report->field[n], data, interrupt); + hid_input_field(hid, report->field[n], data, interrupt, regs); if (hid->claimed & HID_CLAIMED_INPUT) hidinput_report_event(hid, report); @@ -968,29 +933,20 @@ static void hid_retry_timeout(unsigned long _hid) hid_io_error(hid); } -/* Workqueue routine to reset the device or clear a halt */ +/* Workqueue routine to reset the device */ static void hid_reset(void *_hid) { struct hid_device *hid = (struct hid_device *) _hid; - int rc_lock, rc = 0; - - if (test_bit(HID_CLEAR_HALT, &hid->iofl)) { - dev_dbg(&hid->intf->dev, "clear halt\n"); - rc = usb_clear_halt(hid->dev, hid->urbin->pipe); - clear_bit(HID_CLEAR_HALT, &hid->iofl); - hid_start_in(hid); - } - - else if (test_bit(HID_RESET_PENDING, &hid->iofl)) { - dev_dbg(&hid->intf->dev, "resetting device\n"); - rc = rc_lock = usb_lock_device_for_reset(hid->dev, hid->intf); - if (rc_lock >= 0) { - rc = usb_reset_composite_device(hid->dev, hid->intf); - if (rc_lock) - usb_unlock_device(hid->dev); - } - clear_bit(HID_RESET_PENDING, &hid->iofl); + int rc_lock, rc; + + dev_dbg(&hid->intf->dev, "resetting device\n"); + rc = rc_lock = usb_lock_device_for_reset(hid->dev, hid->intf); + if (rc_lock >= 0) { + rc = usb_reset_composite_device(hid->dev, hid->intf); + if (rc_lock) + usb_unlock_device(hid->dev); } + clear_bit(HID_RESET_PENDING, &hid->iofl); switch (rc) { case 0: @@ -1032,8 +988,9 @@ static void hid_io_error(struct hid_device *hid) /* Retries failed, so do a port reset */ if (!test_and_set_bit(HID_RESET_PENDING, &hid->iofl)) { - schedule_work(&hid->reset_work); - goto done; + if (schedule_work(&hid->reset_work)) + goto done; + clear_bit(HID_RESET_PENDING, &hid->iofl); } } @@ -1047,7 +1004,7 @@ static void hid_io_error(struct hid_device *hid) * Input interrupt completion handler. */ -static void hid_irq_in(struct urb *urb) +static void hid_irq_in(struct urb *urb, struct pt_regs *regs) { struct hid_device *hid = urb->context; int status; @@ -1055,13 +1012,8 @@ static void hid_irq_in(struct urb *urb) switch (urb->status) { case 0: /* success */ hid->retry_delay = 0; - hid_input_report(HID_INPUT_REPORT, urb, 1); + hid_input_report(HID_INPUT_REPORT, urb, 1, regs); break; - case -EPIPE: /* stall */ - clear_bit(HID_IN_RUNNING, &hid->iofl); - set_bit(HID_CLEAR_HALT, &hid->iofl); - schedule_work(&hid->reset_work); - return; case -ECONNRESET: /* unlink */ case -ENOENT: case -ESHUTDOWN: /* unplug */ @@ -1241,7 +1193,7 @@ static int hid_submit_ctrl(struct hid_device *hid) * Output interrupt completion handler. */ -static void hid_irq_out(struct urb *urb) +static void hid_irq_out(struct urb *urb, struct pt_regs *regs) { struct hid_device *hid = urb->context; unsigned long flags; @@ -1286,7 +1238,7 @@ static void hid_irq_out(struct urb *urb) * Control pipe completion handler. */ -static void hid_ctrl(struct urb *urb) +static void hid_ctrl(struct urb *urb, struct pt_regs *regs) { struct hid_device *hid = urb->context; unsigned long flags; @@ -1297,7 +1249,7 @@ static void hid_ctrl(struct urb *urb) switch (urb->status) { case 0: /* success */ if (hid->ctrl[hid->ctrltail].dir == USB_DIR_IN) - hid_input_report(hid->ctrl[hid->ctrltail].report->type, urb, 0); + hid_input_report(hid->ctrl[hid->ctrltail].report->type, urb, 0, regs); break; case -ESHUTDOWN: /* unplug */ unplug = 1; @@ -1429,9 +1381,6 @@ void hid_close(struct hid_device *hid) #define USB_VENDOR_ID_PANJIT 0x134c -#define USB_VENDOR_ID_TURBOX 0x062a -#define USB_DEVICE_ID_TURBOX_KEYBOARD 0x0201 - /* * Initialize all reports */ @@ -1640,19 +1589,6 @@ void hid_init_reports(struct hid_device *hid) #define USB_VENDOR_ID_APPLE 0x05ac #define USB_DEVICE_ID_APPLE_MIGHTYMOUSE 0x0304 -#define USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI 0x020e -#define USB_DEVICE_ID_APPLE_FOUNTAIN_ISO 0x020f -#define USB_DEVICE_ID_APPLE_GEYSER_ANSI 0x0214 -#define USB_DEVICE_ID_APPLE_GEYSER_ISO 0x0215 -#define USB_DEVICE_ID_APPLE_GEYSER_JIS 0x0216 -#define USB_DEVICE_ID_APPLE_GEYSER3_ANSI 0x0217 -#define USB_DEVICE_ID_APPLE_GEYSER3_ISO 0x0218 -#define USB_DEVICE_ID_APPLE_GEYSER3_JIS 0x0219 -#define USB_DEVICE_ID_APPLE_GEYSER4_ANSI 0x021a -#define USB_DEVICE_ID_APPLE_GEYSER4_ISO 0x021b -#define USB_DEVICE_ID_APPLE_GEYSER4_JIS 0x021c -#define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a -#define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b #define USB_VENDOR_ID_CHERRY 0x046a #define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023 @@ -1666,9 +1602,6 @@ void hid_init_reports(struct hid_device *hid) #define USB_VENDOR_ID_SUN 0x0430 #define USB_DEVICE_ID_RARITAN_KVM_DONGLE 0xcdab -#define USB_VENDOR_ID_AIRCABLE 0x16CA -#define USB_DEVICE_ID_AIRCABLE1 0x1502 - /* * Alphabetically sorted blacklist by quirk type. */ @@ -1686,7 +1619,6 @@ static const struct hid_blacklist { { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_22, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_23, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_24, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_AIRCABLE, USB_DEVICE_ID_AIRCABLE1, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_ALCOR, USB_DEVICE_ID_ALCOR_USBRS232, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW40, HID_QUIRK_IGNORE }, @@ -1820,27 +1752,22 @@ static const struct hid_blacklist { { USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION, HID_QUIRK_CYMOTION }, - { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI, HID_QUIRK_POWERBOOK_HAS_FN }, - { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO, HID_QUIRK_POWERBOOK_HAS_FN }, - { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI, HID_QUIRK_POWERBOOK_HAS_FN }, - { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_POWERBOOK_ISO_KEYBOARD}, - { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS, HID_QUIRK_POWERBOOK_HAS_FN }, - { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI, HID_QUIRK_POWERBOOK_HAS_FN }, - { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_POWERBOOK_ISO_KEYBOARD}, - { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS, HID_QUIRK_POWERBOOK_HAS_FN }, - { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI, HID_QUIRK_POWERBOOK_HAS_FN }, - { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO, HID_QUIRK_POWERBOOK_HAS_FN }, - { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS, HID_QUIRK_POWERBOOK_HAS_FN }, - { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY, HID_QUIRK_POWERBOOK_HAS_FN }, - { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY, HID_QUIRK_POWERBOOK_HAS_FN }, + { USB_VENDOR_ID_APPLE, 0x020E, HID_QUIRK_POWERBOOK_HAS_FN }, + { USB_VENDOR_ID_APPLE, 0x020F, HID_QUIRK_POWERBOOK_HAS_FN }, + { USB_VENDOR_ID_APPLE, 0x0214, HID_QUIRK_POWERBOOK_HAS_FN }, + { USB_VENDOR_ID_APPLE, 0x0215, HID_QUIRK_POWERBOOK_HAS_FN }, + { USB_VENDOR_ID_APPLE, 0x0216, HID_QUIRK_POWERBOOK_HAS_FN }, + { USB_VENDOR_ID_APPLE, 0x0217, HID_QUIRK_POWERBOOK_HAS_FN }, + { USB_VENDOR_ID_APPLE, 0x0218, HID_QUIRK_POWERBOOK_HAS_FN }, + { USB_VENDOR_ID_APPLE, 0x0219, HID_QUIRK_POWERBOOK_HAS_FN }, + { USB_VENDOR_ID_APPLE, 0x030A, HID_QUIRK_POWERBOOK_HAS_FN }, + { USB_VENDOR_ID_APPLE, 0x030B, HID_QUIRK_POWERBOOK_HAS_FN }, { USB_VENDOR_ID_PANJIT, 0x0001, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_PANJIT, 0x0002, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_PANJIT, 0x0003, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_PANJIT, 0x0004, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET }, - { 0, 0 } }; @@ -2013,7 +1940,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) if (hid->collection->usage == HID_GD_MOUSE && hid_mousepoll_interval > 0) interval = hid_mousepoll_interval; - if (usb_endpoint_dir_in(endpoint)) { + if (endpoint->bEndpointAddress & USB_DIR_IN) { if (hid->urbin) continue; if (!(hid->urbin = usb_alloc_urb(0, GFP_KERNEL))) @@ -2095,9 +2022,13 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) return hid; fail: - usb_free_urb(hid->urbin); - usb_free_urb(hid->urbout); - usb_free_urb(hid->urbctrl); + + if (hid->urbin) + usb_free_urb(hid->urbin); + if (hid->urbout) + usb_free_urb(hid->urbout); + if (hid->urbctrl) + usb_free_urb(hid->urbctrl); hid_free_buffers(dev, hid); hid_free_device(hid); @@ -2128,7 +2059,8 @@ static void hid_disconnect(struct usb_interface *intf) usb_free_urb(hid->urbin); usb_free_urb(hid->urbctrl); - usb_free_urb(hid->urbout); + if (hid->urbout) + usb_free_urb(hid->urbout); hid_free_buffers(hid->dev, hid); hid_free_device(hid); diff --git a/trunk/drivers/usb/input/hid-input.c b/trunk/drivers/usb/input/hid-input.c index 68e7ebb978a9..4c62afbeb430 100644 --- a/trunk/drivers/usb/input/hid-input.c +++ b/trunk/drivers/usb/input/hid-input.c @@ -121,12 +121,6 @@ static struct hidinput_key_translation powerbook_numlock_keys[] = { { } }; -static struct hidinput_key_translation powerbook_iso_keyboard[] = { - { KEY_GRAVE, KEY_102ND }, - { KEY_102ND, KEY_GRAVE }, - { } -}; - static int usbhid_pb_fnmode = 1; module_param_named(pb_fnmode, usbhid_pb_fnmode, int, 0644); MODULE_PARM_DESC(pb_fnmode, @@ -201,14 +195,6 @@ static int hidinput_pb_event(struct hid_device *hid, struct input_dev *input, } } - if (hid->quirks & HID_QUIRK_POWERBOOK_ISO_KEYBOARD) { - trans = find_translation(powerbook_iso_keyboard, usage->code); - if (trans) { - input_event(input, usage->type, trans->to, value); - return 1; - } - } - return 0; } @@ -224,9 +210,6 @@ static void hidinput_pb_setup(struct input_dev *input) for (trans = powerbook_numlock_keys; trans->from; trans++) set_bit(trans->to, input->keybit); - - for (trans = powerbook_iso_keyboard; trans->from; trans++) - set_bit(trans->to, input->keybit); } #else static inline int hidinput_pb_event(struct hid_device *hid, struct input_dev *input, @@ -630,7 +613,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel return; } -void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value) +void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, struct pt_regs *regs) { struct input_dev *input; int *quirks = &hid->quirks; @@ -640,6 +623,8 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct input = field->hidinput->input; + input_regs(input, regs); + if (!usage->type) return; diff --git a/trunk/drivers/usb/input/hid.h b/trunk/drivers/usb/input/hid.h index 2a9bf07944c0..b03fd9b075df 100644 --- a/trunk/drivers/usb/input/hid.h +++ b/trunk/drivers/usb/input/hid.h @@ -260,7 +260,6 @@ struct hid_item { #define HID_QUIRK_POWERBOOK_HAS_FN 0x00001000 #define HID_QUIRK_POWERBOOK_FN_ON 0x00002000 #define HID_QUIRK_INVERT_HWHEEL 0x00004000 -#define HID_QUIRK_POWERBOOK_ISO_KEYBOARD 0x00008000 /* * This is the global environment of the parser. This information is @@ -385,7 +384,6 @@ struct hid_control_fifo { #define HID_IN_RUNNING 3 #define HID_RESET_PENDING 4 #define HID_SUSPENDED 5 -#define HID_CLEAR_HALT 6 struct hid_input { struct list_head list; @@ -501,13 +499,13 @@ struct hid_descriptor { /* Applications from HID Usage Tables 4/8/99 Version 1.1 */ /* We ignore a few input applications that are not widely used */ #define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || (a == 0x00010080) || (a == 0x000c0001)) -extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32); +extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32, struct pt_regs *regs); extern void hidinput_report_event(struct hid_device *hid, struct hid_report *report); extern int hidinput_connect(struct hid_device *); extern void hidinput_disconnect(struct hid_device *); #else #define IS_INPUT_APPLICATION(a) (0) -static inline void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value) { } +static inline void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, struct pt_regs *regs) { } static inline void hidinput_report_event(struct hid_device *hid, struct hid_report *report) { } static inline int hidinput_connect(struct hid_device *hid) { return -ENODEV; } static inline void hidinput_disconnect(struct hid_device *hid) { } diff --git a/trunk/drivers/usb/input/hiddev.c b/trunk/drivers/usb/input/hiddev.c index 7dc14d0cacc1..a2b419d13740 100644 --- a/trunk/drivers/usb/input/hiddev.c +++ b/trunk/drivers/usb/input/hiddev.c @@ -179,7 +179,7 @@ static void hiddev_send_event(struct hid_device *hid, * the interrupt pipe */ void hiddev_hid_event(struct hid_device *hid, struct hid_field *field, - struct hid_usage *usage, __s32 value) + struct hid_usage *usage, __s32 value, struct pt_regs *regs) { unsigned type = field->report_type; struct hiddev_usage_ref uref; diff --git a/trunk/drivers/usb/input/itmtouch.c b/trunk/drivers/usb/input/itmtouch.c index aac968aab860..61966d719ca3 100644 --- a/trunk/drivers/usb/input/itmtouch.c +++ b/trunk/drivers/usb/input/itmtouch.c @@ -36,11 +36,7 @@ * * 1.2.1 09/03/2005 (HCE) hc@mivu.no * Code cleanup and adjusting syntax to start matching kernel standards - * - * 1.2.2 10/05/2006 (MJA) massad@gmail.com - * Flag for detecting if the screen was being touch was incorrectly - * inverted, so no touch events were being detected. - * + * *****************************************************************************/ #include @@ -57,7 +53,7 @@ #define USB_PRODUCT_ID_TOUCHPANEL 0xf9e9 #define DRIVER_AUTHOR "Hans-Christian Egtvedt " -#define DRIVER_VERSION "v1.2.2" +#define DRIVER_VERSION "v1.2.1" #define DRIVER_DESC "USB ITM Inc Touch Panel Driver" #define DRIVER_LICENSE "GPL" @@ -80,7 +76,7 @@ static struct usb_device_id itmtouch_ids [] = { { } }; -static void itmtouch_irq(struct urb *urb) +static void itmtouch_irq(struct urb *urb, struct pt_regs *regs) { struct itmtouch_dev *itmtouch = urb->context; unsigned char *data = urb->transfer_buffer; @@ -109,8 +105,10 @@ static void itmtouch_irq(struct urb *urb) goto exit; } + input_regs(dev, regs); + /* if pressure has been released, then don't report X/Y */ - if (!(data[7] & 0x20)) { + if (data[7] & 0x20) { input_report_abs(dev, ABS_X, (data[0] & 0x1F) << 7 | (data[3] & 0x7F)); input_report_abs(dev, ABS_Y, (data[1] & 0x1F) << 7 | (data[4] & 0x7F)); } diff --git a/trunk/drivers/usb/input/kbtab.c b/trunk/drivers/usb/input/kbtab.c index fedbcb127c21..604ade356ead 100644 --- a/trunk/drivers/usb/input/kbtab.c +++ b/trunk/drivers/usb/input/kbtab.c @@ -41,7 +41,7 @@ struct kbtab { char phys[32]; }; -static void kbtab_irq(struct urb *urb) +static void kbtab_irq(struct urb *urb, struct pt_regs *regs) { struct kbtab *kbtab = urb->context; unsigned char *data = kbtab->data; diff --git a/trunk/drivers/usb/input/keyspan_remote.c b/trunk/drivers/usb/input/keyspan_remote.c index 50aa8108a50b..a90359551575 100644 --- a/trunk/drivers/usb/input/keyspan_remote.c +++ b/trunk/drivers/usb/input/keyspan_remote.c @@ -176,7 +176,7 @@ static int keyspan_load_tester(struct usb_keyspan* dev, int bits_needed) /* * Routine that handles all the logic needed to parse out the message from the remote. */ -static void keyspan_check_data(struct usb_keyspan *remote) +static void keyspan_check_data(struct usb_keyspan *remote, struct pt_regs *regs) { int i; int found = 0; @@ -311,6 +311,7 @@ static void keyspan_check_data(struct usb_keyspan *remote) __FUNCTION__, message.system, message.button, message.toggle); if (message.toggle != remote->toggle) { + input_regs(remote->input, regs); input_report_key(remote->input, keyspan_key_table[message.button], 1); input_report_key(remote->input, keyspan_key_table[message.button], 0); input_sync(remote->input); @@ -360,7 +361,7 @@ static int keyspan_setup(struct usb_device* dev) /* * Routine used to handle a new message that has come in. */ -static void keyspan_irq_recv(struct urb *urb) +static void keyspan_irq_recv(struct urb *urb, struct pt_regs *regs) { struct usb_keyspan *dev = urb->context; int retval; @@ -384,7 +385,7 @@ static void keyspan_irq_recv(struct urb *urb) if (debug) keyspan_print(dev); - keyspan_check_data(dev); + keyspan_check_data(dev, regs); resubmit: retval = usb_submit_urb(urb, GFP_ATOMIC); diff --git a/trunk/drivers/usb/input/mtouchusb.c b/trunk/drivers/usb/input/mtouchusb.c index 79a85d46cb13..5dce951f2751 100644 --- a/trunk/drivers/usb/input/mtouchusb.c +++ b/trunk/drivers/usb/input/mtouchusb.c @@ -98,7 +98,7 @@ static struct usb_device_id mtouchusb_devices[] = { { } }; -static void mtouchusb_irq(struct urb *urb) +static void mtouchusb_irq(struct urb *urb, struct pt_regs *regs) { struct mtouch_usb *mtouch = urb->context; int retval; @@ -125,6 +125,7 @@ static void mtouchusb_irq(struct urb *urb) goto exit; } + input_regs(mtouch->input, regs); input_report_key(mtouch->input, BTN_TOUCH, MTOUCHUSB_GET_TOUCHED(mtouch->data)); input_report_abs(mtouch->input, ABS_X, MTOUCHUSB_GET_XC(mtouch->data)); diff --git a/trunk/drivers/usb/input/powermate.c b/trunk/drivers/usb/input/powermate.c index 0bf91778c40d..f0f8db6810a2 100644 --- a/trunk/drivers/usb/input/powermate.c +++ b/trunk/drivers/usb/input/powermate.c @@ -80,10 +80,10 @@ struct powermate_device { static char pm_name_powermate[] = "Griffin PowerMate"; static char pm_name_soundknob[] = "Griffin SoundKnob"; -static void powermate_config_complete(struct urb *urb); +static void powermate_config_complete(struct urb *urb, struct pt_regs *regs); /* Callback for data arriving from the PowerMate over the USB interrupt pipe */ -static void powermate_irq(struct urb *urb) +static void powermate_irq(struct urb *urb, struct pt_regs *regs) { struct powermate_device *pm = urb->context; int retval; @@ -104,6 +104,7 @@ static void powermate_irq(struct urb *urb) } /* handle updates to device state */ + input_regs(pm->input, regs); input_report_key(pm->input, BTN_0, pm->data[0] & 0x01); input_report_rel(pm->input, REL_DIAL, pm->data[1]); input_sync(pm->input); @@ -190,7 +191,7 @@ static void powermate_sync_state(struct powermate_device *pm) } /* Called when our asynchronous control message completes. We may need to issue another immediately */ -static void powermate_config_complete(struct urb *urb) +static void powermate_config_complete(struct urb *urb, struct pt_regs *regs) { struct powermate_device *pm = urb->context; unsigned long flags; diff --git a/trunk/drivers/usb/input/touchkitusb.c b/trunk/drivers/usb/input/touchkitusb.c index 05c0d1ca39ab..30b9f820e7a8 100644 --- a/trunk/drivers/usb/input/touchkitusb.c +++ b/trunk/drivers/usb/input/touchkitusb.c @@ -92,7 +92,8 @@ static inline int touchkit_get_y(char *data) /* processes one input packet. */ -static void touchkit_process_pkt(struct touchkit_usb *touchkit, char *pkt) +static void touchkit_process_pkt(struct touchkit_usb *touchkit, + struct pt_regs *regs, char *pkt) { int x, y; @@ -108,6 +109,7 @@ static void touchkit_process_pkt(struct touchkit_usb *touchkit, char *pkt) y = touchkit_get_y(pkt); } + input_regs(touchkit->input, regs); input_report_key(touchkit->input, BTN_TOUCH, touchkit_get_touched(pkt)); input_report_abs(touchkit->input, ABS_X, x); input_report_abs(touchkit->input, ABS_Y, y); @@ -128,7 +130,8 @@ static int touchkit_get_pkt_len(char *buf) return 0; } -static void touchkit_process(struct touchkit_usb *touchkit, int len) +static void touchkit_process(struct touchkit_usb *touchkit, int len, + struct pt_regs *regs) { char *buffer; int pkt_len, buf_len, pos; @@ -150,7 +153,7 @@ static void touchkit_process(struct touchkit_usb *touchkit, int len) /* append, process */ tmp = pkt_len - touchkit->buf_len; memcpy(touchkit->buffer + touchkit->buf_len, touchkit->data, tmp); - touchkit_process_pkt(touchkit, touchkit->buffer); + touchkit_process_pkt(touchkit, regs, touchkit->buffer); buffer = touchkit->data + tmp; buf_len = len - tmp; @@ -178,7 +181,7 @@ static void touchkit_process(struct touchkit_usb *touchkit, int len) /* full packet: process */ if (likely(pkt_len <= buf_len)) { - touchkit_process_pkt(touchkit, buffer + pos); + touchkit_process_pkt(touchkit, regs, buffer + pos); } else { /* incomplete packet: save in buffer */ memcpy(touchkit->buffer, buffer + pos, buf_len - pos); @@ -189,7 +192,7 @@ static void touchkit_process(struct touchkit_usb *touchkit, int len) } -static void touchkit_irq(struct urb *urb) +static void touchkit_irq(struct urb *urb, struct pt_regs *regs) { struct touchkit_usb *touchkit = urb->context; int retval; @@ -216,7 +219,7 @@ static void touchkit_irq(struct urb *urb) goto exit; } - touchkit_process(touchkit, urb->actual_length); + touchkit_process(touchkit, urb->actual_length, regs); exit: retval = usb_submit_urb(urb, GFP_ATOMIC); diff --git a/trunk/drivers/usb/misc/trancevibrator.c b/trunk/drivers/usb/input/trancevibrator.c similarity index 100% rename from trunk/drivers/usb/misc/trancevibrator.c rename to trunk/drivers/usb/input/trancevibrator.c diff --git a/trunk/drivers/usb/input/usbkbd.c b/trunk/drivers/usb/input/usbkbd.c index dac88640eab6..5067a6ae650f 100644 --- a/trunk/drivers/usb/input/usbkbd.c +++ b/trunk/drivers/usb/input/usbkbd.c @@ -80,7 +80,7 @@ struct usb_kbd { dma_addr_t leds_dma; }; -static void usb_kbd_irq(struct urb *urb) +static void usb_kbd_irq(struct urb *urb, struct pt_regs *regs) { struct usb_kbd *kbd = urb->context; int i; @@ -97,6 +97,8 @@ static void usb_kbd_irq(struct urb *urb) goto resubmit; } + input_regs(kbd->dev, regs); + for (i = 0; i < 8; i++) input_report_key(kbd->dev, usb_kbd_keycode[i + 224], (kbd->new[0] >> i) & 1); @@ -156,7 +158,7 @@ static int usb_kbd_event(struct input_dev *dev, unsigned int type, return 0; } -static void usb_kbd_led(struct urb *urb) +static void usb_kbd_led(struct urb *urb, struct pt_regs *regs) { struct usb_kbd *kbd = urb->context; @@ -208,8 +210,10 @@ static int usb_kbd_alloc_mem(struct usb_device *dev, struct usb_kbd *kbd) static void usb_kbd_free_mem(struct usb_device *dev, struct usb_kbd *kbd) { - usb_free_urb(kbd->irq); - usb_free_urb(kbd->led); + if (kbd->irq) + usb_free_urb(kbd->irq); + if (kbd->led) + usb_free_urb(kbd->led); if (kbd->new) usb_buffer_free(dev, 8, kbd->new, kbd->new_dma); if (kbd->cr) @@ -234,7 +238,9 @@ static int usb_kbd_probe(struct usb_interface *iface, return -ENODEV; endpoint = &interface->endpoint[0].desc; - if (!usb_endpoint_is_int_in(endpoint)) + if (!(endpoint->bEndpointAddress & USB_DIR_IN)) + return -ENODEV; + if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) return -ENODEV; pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); diff --git a/trunk/drivers/usb/input/usbmouse.c b/trunk/drivers/usb/input/usbmouse.c index 68a55642c082..0fb792be95ef 100644 --- a/trunk/drivers/usb/input/usbmouse.c +++ b/trunk/drivers/usb/input/usbmouse.c @@ -55,7 +55,7 @@ struct usb_mouse { dma_addr_t data_dma; }; -static void usb_mouse_irq(struct urb *urb) +static void usb_mouse_irq(struct urb *urb, struct pt_regs *regs) { struct usb_mouse *mouse = urb->context; signed char *data = mouse->data; @@ -74,6 +74,8 @@ static void usb_mouse_irq(struct urb *urb) goto resubmit; } + input_regs(dev, regs); + input_report_key(dev, BTN_LEFT, data[0] & 0x01); input_report_key(dev, BTN_RIGHT, data[0] & 0x02); input_report_key(dev, BTN_MIDDLE, data[0] & 0x04); @@ -126,7 +128,9 @@ static int usb_mouse_probe(struct usb_interface *intf, const struct usb_device_i return -ENODEV; endpoint = &interface->endpoint[0].desc; - if (!usb_endpoint_is_int_in(endpoint)) + if (!(endpoint->bEndpointAddress & USB_DIR_IN)) + return -ENODEV; + if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) return -ENODEV; pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); diff --git a/trunk/drivers/usb/input/usbtouchscreen.c b/trunk/drivers/usb/input/usbtouchscreen.c index 49704d4ed0e2..923e22db18d4 100644 --- a/trunk/drivers/usb/input/usbtouchscreen.c +++ b/trunk/drivers/usb/input/usbtouchscreen.c @@ -8,7 +8,6 @@ * - PanJit TouchSet * - eTurboTouch * - Gunze AHL61 - * - DMC TSC-10/25 * * Copyright (C) 2004-2006 by Daniel Ritz * Copyright (C) by Todd E. Johnson (mtouchusb.c) @@ -31,8 +30,6 @@ * - ITM parts are from itmtouch.c * - 3M parts are from mtouchusb.c * - PanJit parts are from an unmerged driver by Lanslott Gish - * - DMC TSC 10/25 are from Holger Schurig, with ideas from an unmerged - * driver from Marius Vollmer * *****************************************************************************/ @@ -47,7 +44,7 @@ #include -#define DRIVER_VERSION "v0.5" +#define DRIVER_VERSION "v0.4" #define DRIVER_AUTHOR "Daniel Ritz " #define DRIVER_DESC "USB Touchscreen Driver" @@ -64,7 +61,7 @@ struct usbtouch_device_info { int rept_size; int flags; - void (*process_pkt) (struct usbtouch_usb *usbtouch, unsigned char *pkt, int len); + void (*process_pkt) (struct usbtouch_usb *usbtouch, struct pt_regs *regs, unsigned char *pkt, int len); int (*get_pkt_len) (unsigned char *pkt, int len); int (*read_data) (unsigned char *pkt, int *x, int *y, int *touch, int *press); int (*init) (struct usbtouch_usb *usbtouch); @@ -94,6 +91,7 @@ struct usbtouch_usb { #ifdef MULTI_PACKET static void usbtouch_process_multi(struct usbtouch_usb *usbtouch, + struct pt_regs *regs, unsigned char *pkt, int len); #endif @@ -106,7 +104,6 @@ enum { DEVTYPE_ITM, DEVTYPE_ETURBO, DEVTYPE_GUNZE, - DEVTYPE_DMC_TSC10, }; static struct usb_device_id usbtouch_devices[] = { @@ -143,10 +140,6 @@ static struct usb_device_id usbtouch_devices[] = { {USB_DEVICE(0x0637, 0x0001), .driver_info = DEVTYPE_GUNZE}, #endif -#ifdef CONFIG_USB_TOUCHSCREEN_DMC_TSC10 - {USB_DEVICE(0x0afa, 0x03e8), .driver_info = DEVTYPE_DMC_TSC10}, -#endif - {} }; @@ -264,10 +257,10 @@ static int itm_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *pr { *x = ((pkt[0] & 0x1F) << 7) | (pkt[3] & 0x7F); *y = ((pkt[1] & 0x1F) << 7) | (pkt[4] & 0x7F); - *press = ((pkt[2] & 0x01) << 7) | (pkt[5] & 0x7F); + *press = ((pkt[2] & 0x1F) << 7) | (pkt[5] & 0x7F); *touch = ~pkt[7] & 0x20; - return *touch; + return 1; } #endif @@ -320,80 +313,6 @@ static int gunze_read_data(unsigned char *pkt, int *x, int *y, int *touch, int * } #endif -/***************************************************************************** - * DMC TSC-10/25 Part - * - * Documentation about the controller and it's protocol can be found at - * http://www.dmccoltd.com/files/controler/tsc10usb_pi_e.pdf - * http://www.dmccoltd.com/files/controler/tsc25_usb_e.pdf - */ -#ifdef CONFIG_USB_TOUCHSCREEN_DMC_TSC10 - -/* supported data rates. currently using 130 */ -#define TSC10_RATE_POINT 0x50 -#define TSC10_RATE_30 0x40 -#define TSC10_RATE_50 0x41 -#define TSC10_RATE_80 0x42 -#define TSC10_RATE_100 0x43 -#define TSC10_RATE_130 0x44 -#define TSC10_RATE_150 0x45 - -/* commands */ -#define TSC10_CMD_RESET 0x55 -#define TSC10_CMD_RATE 0x05 -#define TSC10_CMD_DATA1 0x01 - -static int dmc_tsc10_init(struct usbtouch_usb *usbtouch) -{ - struct usb_device *dev = usbtouch->udev; - int ret; - unsigned char buf[2]; - - /* reset */ - buf[0] = buf[1] = 0xFF; - ret = usb_control_msg(dev, usb_rcvctrlpipe (dev, 0), - TSC10_CMD_RESET, - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0, 0, buf, 2, USB_CTRL_SET_TIMEOUT); - if (ret < 0) - return ret; - if (buf[0] != 0x06 || buf[1] != 0x00) - return -ENODEV; - - /* set coordinate output rate */ - buf[0] = buf[1] = 0xFF; - ret = usb_control_msg(dev, usb_rcvctrlpipe (dev, 0), - TSC10_CMD_RATE, - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - TSC10_RATE_150, 0, buf, 2, USB_CTRL_SET_TIMEOUT); - if (ret < 0) - return ret; - if (buf[0] != 0x06 || buf[1] != 0x00) - return -ENODEV; - - /* start sending data */ - ret = usb_control_msg(dev, usb_rcvctrlpipe (dev, 0), - TSC10_CMD_DATA1, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); - if (ret < 0) - return ret; - - return 0; -} - - -static int dmc_tsc10_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press) -{ - *x = ((pkt[2] & 0x03) << 8) | pkt[1]; - *y = ((pkt[4] & 0x03) << 8) | pkt[3]; - *touch = pkt[0] & 0x01; - - return 1; -} -#endif - - /***************************************************************************** * the different device descriptors */ @@ -471,18 +390,6 @@ static struct usbtouch_device_info usbtouch_dev_info[] = { .read_data = gunze_read_data, }, #endif - -#ifdef CONFIG_USB_TOUCHSCREEN_DMC_TSC10 - [DEVTYPE_DMC_TSC10] = { - .min_xc = 0x0, - .max_xc = 0x03ff, - .min_yc = 0x0, - .max_yc = 0x03ff, - .rept_size = 5, - .init = dmc_tsc10_init, - .read_data = dmc_tsc10_read_data, - }, -#endif }; @@ -490,7 +397,7 @@ static struct usbtouch_device_info usbtouch_dev_info[] = { * Generic Part */ static void usbtouch_process_pkt(struct usbtouch_usb *usbtouch, - unsigned char *pkt, int len) + struct pt_regs *regs, unsigned char *pkt, int len) { int x, y, touch, press; struct usbtouch_device_info *type = usbtouch->type; @@ -498,6 +405,7 @@ static void usbtouch_process_pkt(struct usbtouch_usb *usbtouch, if (!type->read_data(pkt, &x, &y, &touch, &press)) return; + input_regs(usbtouch->input, regs); input_report_key(usbtouch->input, BTN_TOUCH, touch); if (swap_xy) { @@ -515,6 +423,7 @@ static void usbtouch_process_pkt(struct usbtouch_usb *usbtouch, #ifdef MULTI_PACKET static void usbtouch_process_multi(struct usbtouch_usb *usbtouch, + struct pt_regs *regs, unsigned char *pkt, int len) { unsigned char *buffer; @@ -551,7 +460,7 @@ static void usbtouch_process_multi(struct usbtouch_usb *usbtouch, if (usbtouch->buf_len + tmp >= usbtouch->type->rept_size) goto out_flush_buf; memcpy(usbtouch->buffer + usbtouch->buf_len, pkt, tmp); - usbtouch_process_pkt(usbtouch, usbtouch->buffer, pkt_len); + usbtouch_process_pkt(usbtouch, regs, usbtouch->buffer, pkt_len); buffer = pkt + tmp; buf_len = len - tmp; @@ -572,7 +481,7 @@ static void usbtouch_process_multi(struct usbtouch_usb *usbtouch, /* full packet: process */ if (likely((pkt_len > 0) && (pkt_len <= buf_len - pos))) { - usbtouch_process_pkt(usbtouch, buffer + pos, pkt_len); + usbtouch_process_pkt(usbtouch, regs, buffer + pos, pkt_len); } else { /* incomplete packet: save in buffer */ memcpy(usbtouch->buffer, buffer + pos, buf_len - pos); @@ -589,7 +498,7 @@ static void usbtouch_process_multi(struct usbtouch_usb *usbtouch, #endif -static void usbtouch_irq(struct urb *urb) +static void usbtouch_irq(struct urb *urb, struct pt_regs *regs) { struct usbtouch_usb *usbtouch = urb->context; int retval; @@ -616,7 +525,7 @@ static void usbtouch_irq(struct urb *urb) goto exit; } - usbtouch->type->process_pkt(usbtouch, usbtouch->data, urb->actual_length); + usbtouch->type->process_pkt(usbtouch, regs, usbtouch->data, urb->actual_length); exit: retval = usb_submit_urb(urb, GFP_ATOMIC); @@ -734,7 +643,7 @@ static int usbtouch_probe(struct usb_interface *intf, type->max_press, 0, 0); usb_fill_int_urb(usbtouch->irq, usbtouch->udev, - usb_rcvintpipe(usbtouch->udev, endpoint->bEndpointAddress), + usb_rcvintpipe(usbtouch->udev, 0x81), usbtouch->data, type->rept_size, usbtouch_irq, usbtouch, endpoint->bInterval); diff --git a/trunk/drivers/usb/input/wacom.h b/trunk/drivers/usb/input/wacom.h index d85abfc5ab58..832737b658cf 100644 --- a/trunk/drivers/usb/input/wacom.h +++ b/trunk/drivers/usb/input/wacom.h @@ -63,7 +63,6 @@ * v1.46 (pc) - Split wacom.c into wacom_sys.c and wacom_wac.c, * - where wacom_sys.c deals with system specific code, * - and wacom_wac.c deals with Wacom specific code - * - Support Intuos3 4x6 */ /* @@ -107,18 +106,20 @@ struct wacom { struct wacom_combo { struct wacom * wacom; struct urb * urb; + struct pt_regs *regs; }; extern int wacom_wac_irq(struct wacom_wac * wacom_wac, void * wcombo); +extern void wacom_sys_irq(struct urb *urb, struct pt_regs *regs); extern void wacom_report_abs(void *wcombo, unsigned int abs_type, int abs_data); extern void wacom_report_rel(void *wcombo, unsigned int rel_type, int rel_data); extern void wacom_report_key(void *wcombo, unsigned int key_type, int key_data); extern void wacom_input_event(void *wcombo, unsigned int type, unsigned int code, int value); +extern void wacom_input_regs(void *wcombo); extern void wacom_input_sync(void *wcombo); extern void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_wac); extern void input_dev_g4(struct input_dev *input_dev, struct wacom_wac *wacom_wac); extern void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac); -extern void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac); extern void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac); extern void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac); extern void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac); diff --git a/trunk/drivers/usb/input/wacom_sys.c b/trunk/drivers/usb/input/wacom_sys.c index e7cc20ab8155..7c3b52bdd9d6 100644 --- a/trunk/drivers/usb/input/wacom_sys.c +++ b/trunk/drivers/usb/input/wacom_sys.c @@ -42,7 +42,7 @@ static struct input_dev * get_input_dev(struct wacom_combo *wcombo) return wcombo->wacom->dev; } -static void wacom_sys_irq(struct urb *urb) +void wacom_sys_irq(struct urb *urb, struct pt_regs *regs) { struct wacom *wacom = urb->context; struct wacom_combo wcombo; @@ -65,6 +65,7 @@ static void wacom_sys_irq(struct urb *urb) wcombo.wacom = wacom; wcombo.urb = urb; + wcombo.regs = regs; if (wacom_wac_irq(wacom->wacom_wac, (void *)&wcombo)) input_sync(get_input_dev(&wcombo)); @@ -110,10 +111,16 @@ __u16 wacom_be16_to_cpu(unsigned char *data) __u16 wacom_le16_to_cpu(unsigned char *data) { __u16 value; - value = le16_to_cpu(*(__le16 *) data); + value = be16_to_cpu(*(__be16 *) data); return value; } +void wacom_input_regs(void *wcombo) +{ + input_regs(get_input_dev((struct wacom_combo *)wcombo), ((struct wacom_combo *)wcombo)->regs); + return; +} + void wacom_input_sync(void *wcombo) { input_sync(get_input_dev((struct wacom_combo *)wcombo)); @@ -143,7 +150,7 @@ void input_dev_g4(struct input_dev *input_dev, struct wacom_wac *wacom_wac) input_dev->evbit[0] |= BIT(EV_MSC); input_dev->mscbit[0] |= BIT(MSC_SERIAL); input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); - input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_4); + input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3) | BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7); } void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac) @@ -155,16 +162,11 @@ void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac) input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0); } -void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac) +void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac) { input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); - input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3); + input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3) | BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7); input_set_abs_params(input_dev, ABS_RX, 0, 4097, 0, 0); -} - -void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac) -{ - input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7); input_set_abs_params(input_dev, ABS_RY, 0, 4097, 0, 0); } @@ -223,7 +225,8 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i strlcat(wacom->phys, "/input0", sizeof(wacom->phys)); wacom_wac->features = get_wacom_feature(id); - BUG_ON(wacom_wac->features->pktlen > 10); + if (wacom_wac->features->pktlen > 10) + BUG(); input_dev->name = wacom_wac->features->name; wacom->wacom_wac = wacom_wac; @@ -248,7 +251,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i usb_fill_int_urb(wacom->irq, dev, usb_rcvintpipe(dev, endpoint->bEndpointAddress), wacom_wac->data, wacom_wac->features->pktlen, - wacom_sys_irq, wacom, endpoint->bInterval); + wacom_wac->features->irq, wacom, endpoint->bInterval); wacom->irq->transfer_dma = wacom->data_dma; wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; @@ -282,8 +285,8 @@ static void wacom_disconnect(struct usb_interface *intf) input_unregister_device(wacom->dev); usb_free_urb(wacom->irq); usb_buffer_free(interface_to_usbdev(intf), 10, wacom->wacom_wac->data, wacom->data_dma); - kfree(wacom->wacom_wac); kfree(wacom); + kfree(wacom->wacom_wac); } } diff --git a/trunk/drivers/usb/input/wacom_wac.c b/trunk/drivers/usb/input/wacom_wac.c index 92726fe89379..85d458c98b6e 100644 --- a/trunk/drivers/usb/input/wacom_wac.c +++ b/trunk/drivers/usb/input/wacom_wac.c @@ -20,6 +20,7 @@ static int wacom_penpartner_irq(struct wacom_wac *wacom, void *wcombo) switch (data[0]) { case 1: + wacom_input_regs(wcombo); if (data[5] & 0x80) { wacom->tool[0] = (data[5] & 0x20) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; wacom->id[0] = (data[5] & 0x20) ? ERASER_DEVICE_ID : STYLUS_DEVICE_ID; @@ -38,6 +39,7 @@ static int wacom_penpartner_irq(struct wacom_wac *wacom, void *wcombo) } break; case 2: + wacom_input_regs(wcombo); wacom_report_key(wcombo, BTN_TOOL_PEN, 1); wacom_report_abs(wcombo, ABS_MISC, STYLUS_DEVICE_ID); /* report tool id */ wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[1])); @@ -65,6 +67,8 @@ static int wacom_pl_irq(struct wacom_wac *wacom, void *wcombo) prox = data[1] & 0x40; + wacom_input_regs(wcombo); + id = ERASER_DEVICE_ID; if (prox) { @@ -134,6 +138,7 @@ static int wacom_ptu_irq(struct wacom_wac *wacom, void *wcombo) return 0; } + wacom_input_regs(wcombo); if (data[1] & 0x04) { wacom_report_key(wcombo, BTN_TOOL_RUBBER, data[1] & 0x20); wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x08); @@ -162,6 +167,8 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) return 0; } + wacom_input_regs(wcombo); + id = STYLUS_DEVICE_ID; if (data[1] & 0x10) { /* in prox */ @@ -191,9 +198,9 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01); wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02); if (wacom->features->type == WACOM_G4) - wacom_report_abs(wcombo, ABS_DISTANCE, data[6] & 0x3f); + wacom_report_abs(wcombo, ABS_DISTANCE, data[6]); else - wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f); + wacom_report_abs(wcombo, ABS_DISTANCE, data[7]); break; } } @@ -303,9 +310,8 @@ static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo) wacom->tool[idx] = BTN_TOOL_PEN; } /* only large I3 support Lens Cursor */ - if(!((wacom->tool[idx] == BTN_TOOL_LENS) - && ((wacom->features->type == INTUOS3) - || (wacom->features->type == INTUOS3S)))) { + if(!((wacom->tool[idx] == BTN_TOOL_LENS) && + (wacom->features->type == INTUOS3))) { wacom_report_abs(wcombo, ABS_MISC, wacom->id[idx]); /* report tool id */ wacom_report_key(wcombo, wacom->tool[idx], 1); wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, wacom->serial[idx]); @@ -316,14 +322,10 @@ static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo) /* Exit report */ if ((data[1] & 0xfe) == 0x80) { - if(!((wacom->tool[idx] == BTN_TOOL_LENS) - && ((wacom->features->type == INTUOS3) - || (wacom->features->type == INTUOS3S)))) { - wacom_report_key(wcombo, wacom->tool[idx], 0); - wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */ - wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, wacom->serial[idx]); - return 2; - } + wacom_report_key(wcombo, wacom->tool[idx], 0); + wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */ + wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, wacom->serial[idx]); + return 2; } return 0; } @@ -367,6 +369,8 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) return 0; } + wacom_input_regs(wcombo); + /* tool number */ idx = data[1] & 0x01; @@ -387,8 +391,7 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) wacom_report_abs(wcombo, ABS_RX, ((data[1] & 0x1f) << 8) | data[2]); wacom_report_abs(wcombo, ABS_RY, ((data[3] & 0x1f) << 8) | data[4]); - if((data[5] & 0x0f) | (data[6] & 0x0f) | (data[1] & 0x1f) | - data[2] | (data[3] & 0x1f) | data[4]) + if((data[5] & 0x0f) | (data[6] & 0x0f) | (data[1] & 0x1f) | data[2]) wacom_report_key(wcombo, wacom->tool[1], 1); else wacom_report_key(wcombo, wacom->tool[1], 0); @@ -438,7 +441,7 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) ((t - 1) / 2) : -t / 2); } - } else if (!(data[1] & 0x10) && wacom->features->type < INTUOS3S) { + } else if (!(data[1] & 0x10) && wacom->features->type < INTUOS3) { /* 4D mouse packet */ wacom_report_key(wcombo, BTN_LEFT, data[8] & 0x01); wacom_report_key(wcombo, BTN_MIDDLE, data[8] & 0x02); @@ -458,12 +461,12 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) - ((data[8] & 0x02) >> 1)); /* I3 2D mouse side buttons */ - if (wacom->features->type >= INTUOS3S && wacom->features->type <= INTUOS3L) { + if (wacom->features->type == INTUOS3) { wacom_report_key(wcombo, BTN_SIDE, data[8] & 0x40); wacom_report_key(wcombo, BTN_EXTRA, data[8] & 0x20); } - } else if (wacom->features->type < INTUOS3S || wacom->features->type == INTUOS3L) { + } else if (wacom->features->type < INTUOS3) { /* Lens cursor packets */ wacom_report_key(wcombo, BTN_LEFT, data[8] & 0x01); wacom_report_key(wcombo, BTN_MIDDLE, data[8] & 0x02); @@ -496,7 +499,6 @@ int wacom_wac_irq(struct wacom_wac *wacom_wac, void *wcombo) return (wacom_ptu_irq(wacom_wac, wcombo)); break; case INTUOS: - case INTUOS3S: case INTUOS3: case INTUOS3L: case CINTIQ: @@ -522,8 +524,6 @@ void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_w case CINTIQ: input_dev_i3(input_dev, wacom_wac); /* fall through */ - case INTUOS3S: - input_dev_i3s(input_dev, wacom_wac); case INTUOS: input_dev_i(input_dev, wacom_wac); break; @@ -539,50 +539,49 @@ void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_w } static struct wacom_features wacom_features[] = { - { "Wacom Penpartner", 7, 5040, 3780, 255, 0, PENPARTNER }, - { "Wacom Graphire", 8, 10206, 7422, 511, 63, GRAPHIRE }, - { "Wacom Graphire2 4x5", 8, 10206, 7422, 511, 63, GRAPHIRE }, - { "Wacom Graphire2 5x7", 8, 13918, 10206, 511, 63, GRAPHIRE }, - { "Wacom Graphire3", 8, 10208, 7424, 511, 63, GRAPHIRE }, - { "Wacom Graphire3 6x8", 8, 16704, 12064, 511, 63, GRAPHIRE }, - { "Wacom Graphire4 4x5", 8, 10208, 7424, 511, 63, WACOM_G4 }, - { "Wacom Graphire4 6x8", 8, 16704, 12064, 511, 63, WACOM_G4 }, - { "Wacom Volito", 8, 5104, 3712, 511, 0, GRAPHIRE }, - { "Wacom PenStation2", 8, 3250, 2320, 255, 0, GRAPHIRE }, - { "Wacom Volito2 4x5", 8, 5104, 3712, 511, 0, GRAPHIRE }, - { "Wacom Volito2 2x3", 8, 3248, 2320, 511, 0, GRAPHIRE }, - { "Wacom PenPartner2", 8, 3250, 2320, 255, 0, GRAPHIRE }, - { "Wacom Intuos 4x5", 10, 12700, 10600, 1023, 63, INTUOS }, - { "Wacom Intuos 6x8", 10, 20320, 16240, 1023, 63, INTUOS }, - { "Wacom Intuos 9x12", 10, 30480, 24060, 1023, 63, INTUOS }, - { "Wacom Intuos 12x12", 10, 30480, 31680, 1023, 63, INTUOS }, - { "Wacom Intuos 12x18", 10, 45720, 31680, 1023, 63, INTUOS }, - { "Wacom PL400", 8, 5408, 4056, 255, 0, PL }, - { "Wacom PL500", 8, 6144, 4608, 255, 0, PL }, - { "Wacom PL600", 8, 6126, 4604, 255, 0, PL }, - { "Wacom PL600SX", 8, 6260, 5016, 255, 0, PL }, - { "Wacom PL550", 8, 6144, 4608, 511, 0, PL }, - { "Wacom PL800", 8, 7220, 5780, 511, 0, PL }, - { "Wacom PL700", 8, 6758, 5406, 511, 0, PL }, - { "Wacom PL510", 8, 6282, 4762, 511, 0, PL }, - { "Wacom DTU710", 8, 34080, 27660, 511, 0, PL }, - { "Wacom DTF521", 8, 6282, 4762, 511, 0, PL }, - { "Wacom DTF720", 8, 6858, 5506, 511, 0, PL }, - { "Wacom Cintiq Partner",8, 20480, 15360, 511, 0, PTU }, - { "Wacom Intuos2 4x5", 10, 12700, 10600, 1023, 63, INTUOS }, - { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 63, INTUOS }, - { "Wacom Intuos2 9x12", 10, 30480, 24060, 1023, 63, INTUOS }, - { "Wacom Intuos2 12x12", 10, 30480, 31680, 1023, 63, INTUOS }, - { "Wacom Intuos2 12x18", 10, 45720, 31680, 1023, 63, INTUOS }, - { "Wacom Intuos3 4x5", 10, 25400, 20320, 1023, 63, INTUOS3S }, - { "Wacom Intuos3 6x8", 10, 40640, 30480, 1023, 63, INTUOS3 }, - { "Wacom Intuos3 9x12", 10, 60960, 45720, 1023, 63, INTUOS3 }, - { "Wacom Intuos3 12x12", 10, 60960, 60960, 1023, 63, INTUOS3L }, - { "Wacom Intuos3 12x19", 10, 97536, 60960, 1023, 63, INTUOS3L }, - { "Wacom Intuos3 6x11", 10, 54204, 31750, 1023, 63, INTUOS3 }, - { "Wacom Intuos3 4x6", 10, 31496, 19685, 1023, 15, INTUOS3S }, - { "Wacom Cintiq 21UX", 10, 87200, 65600, 1023, 63, CINTIQ }, - { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 63, INTUOS }, + { "Wacom Penpartner", 7, 5040, 3780, 255, 32, PENPARTNER, wacom_sys_irq }, + { "Wacom Graphire", 8, 10206, 7422, 511, 32, GRAPHIRE, wacom_sys_irq }, + { "Wacom Graphire2 4x5", 8, 10206, 7422, 511, 32, GRAPHIRE, wacom_sys_irq }, + { "Wacom Graphire2 5x7", 8, 13918, 10206, 511, 32, GRAPHIRE, wacom_sys_irq }, + { "Wacom Graphire3", 8, 10208, 7424, 511, 32, GRAPHIRE, wacom_sys_irq }, + { "Wacom Graphire3 6x8", 8, 16704, 12064, 511, 32, GRAPHIRE, wacom_sys_irq }, + { "Wacom Graphire4 4x5", 8, 10208, 7424, 511, 32, WACOM_G4, wacom_sys_irq }, + { "Wacom Graphire4 6x8", 8, 16704, 12064, 511, 32, WACOM_G4, wacom_sys_irq }, + { "Wacom Volito", 8, 5104, 3712, 511, 32, GRAPHIRE, wacom_sys_irq }, + { "Wacom PenStation2", 8, 3250, 2320, 255, 32, GRAPHIRE, wacom_sys_irq }, + { "Wacom Volito2 4x5", 8, 5104, 3712, 511, 32, GRAPHIRE, wacom_sys_irq }, + { "Wacom Volito2 2x3", 8, 3248, 2320, 511, 32, GRAPHIRE, wacom_sys_irq }, + { "Wacom PenPartner2", 8, 3250, 2320, 255, 32, GRAPHIRE, wacom_sys_irq }, + { "Wacom Intuos 4x5", 10, 12700, 10600, 1023, 15, INTUOS, wacom_sys_irq}, + { "Wacom Intuos 6x8", 10, 20320, 16240, 1023, 15, INTUOS, wacom_sys_irq }, + { "Wacom Intuos 9x12", 10, 30480, 24060, 1023, 15, INTUOS, wacom_sys_irq }, + { "Wacom Intuos 12x12", 10, 30480, 31680, 1023, 15, INTUOS, wacom_sys_irq }, + { "Wacom Intuos 12x18", 10, 45720, 31680, 1023, 15, INTUOS, wacom_sys_irq}, + { "Wacom PL400", 8, 5408, 4056, 255, 32, PL, wacom_sys_irq }, + { "Wacom PL500", 8, 6144, 4608, 255, 32, PL, wacom_sys_irq }, + { "Wacom PL600", 8, 6126, 4604, 255, 32, PL, wacom_sys_irq }, + { "Wacom PL600SX", 8, 6260, 5016, 255, 32, PL, wacom_sys_irq }, + { "Wacom PL550", 8, 6144, 4608, 511, 32, PL, wacom_sys_irq }, + { "Wacom PL800", 8, 7220, 5780, 511, 32, PL, wacom_sys_irq }, + { "Wacom PL700", 8, 6758, 5406, 511, 32, PL, wacom_sys_irq }, + { "Wacom PL510", 8, 6282, 4762, 511, 32, PL, wacom_sys_irq }, + { "Wacom DTU710", 8, 34080, 27660, 511, 32, PL, wacom_sys_irq }, + { "Wacom DTF521", 8, 6282, 4762, 511, 32, PL, wacom_sys_irq }, + { "Wacom DTF720", 8, 6858, 5506, 511, 32, PL, wacom_sys_irq }, + { "Wacom Cintiq Partner",8, 20480, 15360, 511, 32, PTU, wacom_sys_irq }, + { "Wacom Intuos2 4x5", 10, 12700, 10600, 1023, 15, INTUOS, wacom_sys_irq }, + { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 15, INTUOS, wacom_sys_irq }, + { "Wacom Intuos2 9x12", 10, 30480, 24060, 1023, 15, INTUOS, wacom_sys_irq }, + { "Wacom Intuos2 12x12", 10, 30480, 31680, 1023, 15, INTUOS, wacom_sys_irq }, + { "Wacom Intuos2 12x18", 10, 45720, 31680, 1023, 15, INTUOS, wacom_sys_irq }, + { "Wacom Intuos3 4x5", 10, 25400, 20320, 1023, 15, INTUOS3, wacom_sys_irq }, + { "Wacom Intuos3 6x8", 10, 40640, 30480, 1023, 15, INTUOS3, wacom_sys_irq }, + { "Wacom Intuos3 9x12", 10, 60960, 45720, 1023, 15, INTUOS3, wacom_sys_irq }, + { "Wacom Intuos3 12x12", 10, 60960, 60960, 1023, 15, INTUOS3L, wacom_sys_irq }, + { "Wacom Intuos3 12x19", 10, 97536, 60960, 1023, 15, INTUOS3L, wacom_sys_irq }, + { "Wacom Intuos3 6x11", 10, 54204, 31750, 1023, 15, INTUOS3, wacom_sys_irq }, + { "Wacom Cintiq 21UX", 10, 87200, 65600, 1023, 15, CINTIQ, wacom_sys_irq }, + { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 15, INTUOS, wacom_sys_irq }, { } }; @@ -628,7 +627,6 @@ static struct usb_device_id wacom_ids[] = { { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB3) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB4) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB5) }, - { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB7) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x3F) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47) }, { } diff --git a/trunk/drivers/usb/input/wacom_wac.h b/trunk/drivers/usb/input/wacom_wac.h index a1d9ce007970..ceae7bf59d9f 100644 --- a/trunk/drivers/usb/input/wacom_wac.h +++ b/trunk/drivers/usb/input/wacom_wac.h @@ -20,7 +20,6 @@ enum { PTU, PL, INTUOS, - INTUOS3S, INTUOS3, INTUOS3L, CINTIQ, @@ -35,6 +34,7 @@ struct wacom_features { int pressure_max; int distance_max; int type; + usb_complete_t irq; }; struct wacom_wac { diff --git a/trunk/drivers/usb/input/xpad.c b/trunk/drivers/usb/input/xpad.c index df97e5c803f9..9889b1cda05b 100644 --- a/trunk/drivers/usb/input/xpad.c +++ b/trunk/drivers/usb/input/xpad.c @@ -1,13 +1,8 @@ /* - * X-Box gamepad - v0.0.6 + * X-Box gamepad - v0.0.5 * * Copyright (c) 2002 Marko Friedemann - * 2004 Oliver Schwartz , - * Steven Toth , - * Franz Lehner , - * Ivan Hawkes - * 2005 Dominic Cerquetti - * 2006 Adam Buchbinder + * * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -33,13 +28,11 @@ * - ITO Takayuki for providing essential xpad information on his website * - Vojtech Pavlik - iforce driver / input subsystem * - Greg Kroah-Hartman - usb-skeleton driver - * - XBOX Linux project - extra USB id's * * TODO: - * - fine tune axes (especially trigger axes) + * - fine tune axes * - fix "analog" buttons (reported as digital now) * - get rumble working - * - need USB IDs for other dance pads * * History: * @@ -59,79 +52,30 @@ * - fixed d-pad to axes mapping * * 2002-07-17 - 0.0.5 : simplified d-pad handling - * - * 2004-10-02 - 0.0.6 : DDR pad support - * - borrowed from the XBOX linux kernel - * - USB id's for commonly used dance pads are present - * - dance pads will map D-PAD to buttons, not axes - * - pass the module paramater 'dpad_to_buttons' to force - * the D-PAD to map to buttons if your pad is not detected */ #include #include #include -#include #include -#include #include #include -#define DRIVER_VERSION "v0.0.6" +#define DRIVER_VERSION "v0.0.5" #define DRIVER_AUTHOR "Marko Friedemann " #define DRIVER_DESC "X-Box pad driver" #define XPAD_PKT_LEN 32 -/* xbox d-pads should map to buttons, as is required for DDR pads - but we map them to axes when possible to simplify things */ -#define MAP_DPAD_TO_BUTTONS 0 -#define MAP_DPAD_TO_AXES 1 -#define MAP_DPAD_UNKNOWN -1 - -static int dpad_to_buttons; -module_param(dpad_to_buttons, bool, S_IRUGO); -MODULE_PARM_DESC(dpad_to_buttons, "Map D-PAD to buttons rather than axes for unknown pads"); - static const struct xpad_device { u16 idVendor; u16 idProduct; char *name; - u8 dpad_mapping; } xpad_device[] = { - { 0x045e, 0x0202, "Microsoft X-Box pad v1 (US)", MAP_DPAD_TO_AXES }, - { 0x045e, 0x0289, "Microsoft X-Box pad v2 (US)", MAP_DPAD_TO_AXES }, - { 0x045e, 0x0285, "Microsoft X-Box pad (Japan)", MAP_DPAD_TO_AXES }, - { 0x045e, 0x0287, "Microsoft Xbox Controller S", MAP_DPAD_TO_AXES }, - { 0x0c12, 0x8809, "RedOctane Xbox Dance Pad", MAP_DPAD_TO_BUTTONS }, - { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", MAP_DPAD_TO_AXES }, - { 0x046d, 0xca84, "Logitech Xbox Cordless Controller", MAP_DPAD_TO_AXES }, - { 0x046d, 0xca88, "Logitech Compact Controller for Xbox", MAP_DPAD_TO_AXES }, - { 0x05fd, 0x1007, "Mad Catz Controller (unverified)", MAP_DPAD_TO_AXES }, - { 0x05fd, 0x107a, "InterAct 'PowerPad Pro' X-Box pad (Germany)", MAP_DPAD_TO_AXES }, - { 0x0738, 0x4516, "Mad Catz Control Pad", MAP_DPAD_TO_AXES }, - { 0x0738, 0x4522, "Mad Catz LumiCON", MAP_DPAD_TO_AXES }, - { 0x0738, 0x4526, "Mad Catz Control Pad Pro", MAP_DPAD_TO_AXES }, - { 0x0738, 0x4536, "Mad Catz MicroCON", MAP_DPAD_TO_AXES }, - { 0x0738, 0x4540, "Mad Catz Beat Pad", MAP_DPAD_TO_BUTTONS }, - { 0x0738, 0x4556, "Mad Catz Lynx Wireless Controller", MAP_DPAD_TO_AXES }, - { 0x0738, 0x6040, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS }, - { 0x0c12, 0x8802, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES }, - { 0x0c12, 0x8810, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES }, - { 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", MAP_DPAD_TO_AXES }, - { 0x0e4c, 0x1097, "Radica Gamester Controller", MAP_DPAD_TO_AXES }, - { 0x0e4c, 0x2390, "Radica Games Jtech Controller", MAP_DPAD_TO_AXES}, - { 0x0e6f, 0x0003, "Logic3 Freebird wireless Controller", MAP_DPAD_TO_AXES }, - { 0x0e6f, 0x0005, "Eclipse wireless Controller", MAP_DPAD_TO_AXES }, - { 0x0e6f, 0x0006, "Edge wireless Controller", MAP_DPAD_TO_AXES }, - { 0x0e8f, 0x0201, "SmartJoy Frag Xpad/PS2 adaptor", MAP_DPAD_TO_AXES }, - { 0x0f30, 0x0202, "Joytech Advanced Controller", MAP_DPAD_TO_AXES }, - { 0x0f30, 0x8888, "BigBen XBMiniPad Controller", MAP_DPAD_TO_AXES }, - { 0x102c, 0xff0c, "Joytech Wireless Advanced Controller", MAP_DPAD_TO_AXES }, - { 0x12ab, 0x8809, "Xbox DDR dancepad", MAP_DPAD_TO_BUTTONS }, - { 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS }, - { 0xffff, 0xffff, "Chinese-made Xbox Controller", MAP_DPAD_TO_AXES }, - { 0x0000, 0x0000, "Generic X-Box pad", MAP_DPAD_UNKNOWN } + { 0x045e, 0x0202, "Microsoft X-Box pad (US)" }, + { 0x045e, 0x0285, "Microsoft X-Box pad (Japan)" }, + { 0x05fd, 0x107a, "InterAct 'PowerPad Pro' X-Box pad (Germany)" }, + { 0x0000, 0x0000, "X-Box pad" } }; static const signed short xpad_btn[] = { @@ -140,23 +84,11 @@ static const signed short xpad_btn[] = { -1 /* terminating entry */ }; -/* only used if MAP_DPAD_TO_BUTTONS */ -static const signed short xpad_btn_pad[] = { - BTN_LEFT, BTN_RIGHT, /* d-pad left, right */ - BTN_0, BTN_1, /* d-pad up, down (XXX names??) */ - -1 /* terminating entry */ -}; - static const signed short xpad_abs[] = { ABS_X, ABS_Y, /* left stick */ ABS_RX, ABS_RY, /* right stick */ ABS_Z, ABS_RZ, /* triggers left/right */ - -1 /* terminating entry */ -}; - -/* only used if MAP_DPAD_TO_AXES */ -static const signed short xpad_abs_pad[] = { - ABS_HAT0X, ABS_HAT0Y, /* d-pad axes */ + ABS_HAT0X, ABS_HAT0Y, /* digital pad */ -1 /* terminating entry */ }; @@ -168,16 +100,14 @@ static struct usb_device_id xpad_table [] = { MODULE_DEVICE_TABLE (usb, xpad_table); struct usb_xpad { - struct input_dev *dev; /* input device interface */ - struct usb_device *udev; /* usb device */ + struct input_dev *dev; /* input device interface */ + struct usb_device *udev; /* usb device */ - struct urb *irq_in; /* urb for interrupt in report */ - unsigned char *idata; /* input data */ + struct urb *irq_in; /* urb for interrupt in report */ + unsigned char *idata; /* input data */ dma_addr_t idata_dma; - char phys[65]; /* physical device path */ - - int dpad_mapping; /* map d-pad to buttons or to axes */ + char phys[65]; /* physical device path */ }; /* @@ -190,10 +120,12 @@ struct usb_xpad { * http://euc.jp/periphs/xbox-controller.ja.html */ -static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data) +static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data, struct pt_regs *regs) { struct input_dev *dev = xpad->dev; + input_regs(dev, regs); + /* left stick */ input_report_abs(dev, ABS_X, (__s16) (((__s16)data[13] << 8) | data[12])); input_report_abs(dev, ABS_Y, (__s16) (((__s16)data[15] << 8) | data[14])); @@ -207,21 +139,14 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d input_report_abs(dev, ABS_RZ, data[11]); /* digital pad */ - if (xpad->dpad_mapping == MAP_DPAD_TO_AXES) { - input_report_abs(dev, ABS_HAT0X, !!(data[2] & 0x08) - !!(data[2] & 0x04)); - input_report_abs(dev, ABS_HAT0Y, !!(data[2] & 0x02) - !!(data[2] & 0x01)); - } else /* xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS */ { - input_report_key(dev, BTN_LEFT, data[2] & 0x04); - input_report_key(dev, BTN_RIGHT, data[2] & 0x08); - input_report_key(dev, BTN_0, data[2] & 0x01); // up - input_report_key(dev, BTN_1, data[2] & 0x02); // down - } + input_report_abs(dev, ABS_HAT0X, !!(data[2] & 0x08) - !!(data[2] & 0x04)); + input_report_abs(dev, ABS_HAT0Y, !!(data[2] & 0x02) - !!(data[2] & 0x01)); /* start/back buttons and stick press left/right */ - input_report_key(dev, BTN_START, data[2] & 0x10); - input_report_key(dev, BTN_BACK, data[2] & 0x20); - input_report_key(dev, BTN_THUMBL, data[2] & 0x40); - input_report_key(dev, BTN_THUMBR, data[2] & 0x80); + input_report_key(dev, BTN_START, (data[2] & 0x10) >> 4); + input_report_key(dev, BTN_BACK, (data[2] & 0x20) >> 5); + input_report_key(dev, BTN_THUMBL, (data[2] & 0x40) >> 6); + input_report_key(dev, BTN_THUMBR, data[2] >> 7); /* "analog" buttons A, B, X, Y */ input_report_key(dev, BTN_A, data[4]); @@ -236,7 +161,7 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d input_sync(dev); } -static void xpad_irq_in(struct urb *urb) +static void xpad_irq_in(struct urb *urb, struct pt_regs *regs) { struct usb_xpad *xpad = urb->context; int retval; @@ -256,7 +181,7 @@ static void xpad_irq_in(struct urb *urb) goto exit; } - xpad_process_packet(xpad, 0, xpad->idata); + xpad_process_packet(xpad, 0, xpad->idata, regs); exit: retval = usb_submit_urb (urb, GFP_ATOMIC); @@ -283,28 +208,6 @@ static void xpad_close (struct input_dev *dev) usb_kill_urb(xpad->irq_in); } -static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs) -{ - set_bit(abs, input_dev->absbit); - - switch (abs) { - case ABS_X: - case ABS_Y: - case ABS_RX: - case ABS_RY: /* the two sticks */ - input_set_abs_params(input_dev, abs, -32768, 32767, 16, 128); - break; - case ABS_Z: - case ABS_RZ: /* the triggers */ - input_set_abs_params(input_dev, abs, 0, 255, 0, 0); - break; - case ABS_HAT0X: - case ABS_HAT0Y: /* the d-pad (only if MAP_DPAD_TO_AXES) */ - input_set_abs_params(input_dev, abs, -1, 1, 0, 0); - break; - } -} - static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev (intf); @@ -334,9 +237,6 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id goto fail2; xpad->udev = udev; - xpad->dpad_mapping = xpad_device[i].dpad_mapping; - if (xpad->dpad_mapping == MAP_DPAD_UNKNOWN) - xpad->dpad_mapping = dpad_to_buttons; xpad->dev = input_dev; usb_make_path(udev, xpad->phys, sizeof(xpad->phys)); strlcat(xpad->phys, "/input0", sizeof(xpad->phys)); @@ -351,19 +251,32 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); - /* set up buttons */ for (i = 0; xpad_btn[i] >= 0; i++) set_bit(xpad_btn[i], input_dev->keybit); - if (xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS) - for (i = 0; xpad_btn_pad[i] >= 0; i++) - set_bit(xpad_btn_pad[i], input_dev->keybit); - /* set up axes */ - for (i = 0; xpad_abs[i] >= 0; i++) - xpad_set_up_abs(input_dev, xpad_abs[i]); - if (xpad->dpad_mapping == MAP_DPAD_TO_AXES) - for (i = 0; xpad_abs_pad[i] >= 0; i++) - xpad_set_up_abs(input_dev, xpad_abs_pad[i]); + for (i = 0; xpad_abs[i] >= 0; i++) { + + signed short t = xpad_abs[i]; + + set_bit(t, input_dev->absbit); + + switch (t) { + case ABS_X: + case ABS_Y: + case ABS_RX: + case ABS_RY: /* the two sticks */ + input_set_abs_params(input_dev, t, -32768, 32767, 16, 128); + break; + case ABS_Z: + case ABS_RZ: /* the triggers */ + input_set_abs_params(input_dev, t, 0, 255, 0, 0); + break; + case ABS_HAT0X: + case ABS_HAT0Y: /* the d-pad */ + input_set_abs_params(input_dev, t, -1, 1, 0, 0); + break; + } + } ep_irq_in = &intf->cur_altsetting->endpoint[0].desc; usb_fill_int_urb(xpad->irq_in, udev, @@ -394,8 +307,7 @@ static void xpad_disconnect(struct usb_interface *intf) usb_kill_urb(xpad->irq_in); input_unregister_device(xpad->dev); usb_free_urb(xpad->irq_in); - usb_buffer_free(interface_to_usbdev(intf), XPAD_PKT_LEN, - xpad->idata, xpad->idata_dma); + usb_buffer_free(interface_to_usbdev(intf), XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); kfree(xpad); } } diff --git a/trunk/drivers/usb/input/yealink.c b/trunk/drivers/usb/input/yealink.c index 2268ca311ade..7291e7a2717b 100644 --- a/trunk/drivers/usb/input/yealink.c +++ b/trunk/drivers/usb/input/yealink.c @@ -233,10 +233,11 @@ static int map_p1k_to_key(int scancode) * * The key parameter can be cascaded: key2 << 8 | key1 */ -static void report_key(struct yealink_dev *yld, int key) +static void report_key(struct yealink_dev *yld, int key, struct pt_regs *regs) { struct input_dev *idev = yld->idev; + input_regs(idev, regs); if (yld->key_code >= 0) { /* old key up */ input_report_key(idev, yld->key_code & 0xff, 0); @@ -421,7 +422,7 @@ static int yealink_do_idle_tasks(struct yealink_dev *yld) * error,start * */ -static void urb_irq_callback(struct urb *urb) +static void urb_irq_callback(struct urb *urb, struct pt_regs *regs) { struct yealink_dev *yld = urb->context; int ret; @@ -438,7 +439,7 @@ static void urb_irq_callback(struct urb *urb) case CMD_SCANCODE: dbg("get scancode %x", yld->irq_data->data[0]); - report_key(yld, map_p1k_to_key(yld->irq_data->data[0])); + report_key(yld, map_p1k_to_key(yld->irq_data->data[0]), regs); break; default: @@ -452,7 +453,7 @@ static void urb_irq_callback(struct urb *urb) err("%s - usb_submit_urb failed %d", __FUNCTION__, ret); } -static void urb_ctl_callback(struct urb *urb) +static void urb_ctl_callback(struct urb *urb, struct pt_regs *regs) { struct yealink_dev *yld = urb->context; int ret; @@ -859,8 +860,10 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id) interface = intf->cur_altsetting; endpoint = &interface->endpoint[0].desc; - if (!usb_endpoint_is_int_in(endpoint)) - return -ENODEV; + if (!(endpoint->bEndpointAddress & USB_DIR_IN)) + return -EIO; + if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) + return -EIO; yld = kzalloc(sizeof(struct yealink_dev), GFP_KERNEL); if (!yld) diff --git a/trunk/drivers/usb/misc/Kconfig b/trunk/drivers/usb/misc/Kconfig index a74bf8617e7f..c29658f69e2a 100644 --- a/trunk/drivers/usb/misc/Kconfig +++ b/trunk/drivers/usb/misc/Kconfig @@ -223,16 +223,6 @@ config USB_LD To compile this driver as a module, choose M here: the module will be called ldusb. -config USB_TRANCEVIBRATOR - tristate "PlayStation 2 Trance Vibrator driver support" - depends on USB - help - Say Y here if you want to connect a PlayStation 2 Trance Vibrator - device to your computer's USB port. - - To compile this driver as a module, choose M here: the - module will be called trancevibrator. - config USB_TEST tristate "USB testing driver (DEVELOPMENT)" depends on USB && USB_DEVICEFS && EXPERIMENTAL diff --git a/trunk/drivers/usb/misc/Makefile b/trunk/drivers/usb/misc/Makefile index 2cba07d31971..2be70fa259bf 100644 --- a/trunk/drivers/usb/misc/Makefile +++ b/trunk/drivers/usb/misc/Makefile @@ -4,7 +4,6 @@ # obj-$(CONFIG_USB_ADUTUX) += adutux.o -obj-$(CONFIG_USB_APPLEDISPLAY) += appledisplay.o obj-$(CONFIG_USB_AUERSWALD) += auerswald.o obj-$(CONFIG_USB_CYPRESS_CY7C63)+= cypress_cy7c63.o obj-$(CONFIG_USB_CYTHERM) += cytherm.o @@ -22,7 +21,6 @@ obj-$(CONFIG_USB_PHIDGETMOTORCONTROL) += phidgetmotorcontrol.o obj-$(CONFIG_USB_PHIDGETSERVO) += phidgetservo.o obj-$(CONFIG_USB_RIO500) += rio500.o obj-$(CONFIG_USB_TEST) += usbtest.o -obj-$(CONFIG_USB_TRANCEVIBRATOR) += trancevibrator.o obj-$(CONFIG_USB_USS720) += uss720.o obj-$(CONFIG_USB_SISUSBVGA) += sisusbvga/ diff --git a/trunk/drivers/usb/misc/adutux.c b/trunk/drivers/usb/misc/adutux.c index af2934e016a7..d3963199b6ec 100644 --- a/trunk/drivers/usb/misc/adutux.c +++ b/trunk/drivers/usb/misc/adutux.c @@ -177,7 +177,7 @@ static void adu_delete(struct adu_device *dev) dbg(2, "%s : leave", __FUNCTION__); } -static void adu_interrupt_in_callback(struct urb *urb) +static void adu_interrupt_in_callback(struct urb *urb, struct pt_regs *regs) { struct adu_device *dev = urb->context; @@ -221,7 +221,7 @@ static void adu_interrupt_in_callback(struct urb *urb) dbg(4," %s : leave, status %d", __FUNCTION__, urb->status); } -static void adu_interrupt_out_callback(struct urb *urb) +static void adu_interrupt_out_callback(struct urb *urb, struct pt_regs *regs) { struct adu_device *dev = urb->context; @@ -370,8 +370,7 @@ static int adu_release(struct inode *inode, struct file *file) retval = adu_release_internal(dev); exit: - if (dev) - up(&dev->sem); + up(&dev->sem); dbg(2," %s : leave, return value %d", __FUNCTION__, retval); return retval; } diff --git a/trunk/drivers/usb/misc/appledisplay.c b/trunk/drivers/usb/misc/appledisplay.c index ba30ca6a14aa..fc6cc147996f 100644 --- a/trunk/drivers/usb/misc/appledisplay.c +++ b/trunk/drivers/usb/misc/appledisplay.c @@ -84,7 +84,7 @@ struct appledisplay { static atomic_t count_displays = ATOMIC_INIT(0); static struct workqueue_struct *wq; -static void appledisplay_complete(struct urb *urb) +static void appledisplay_complete(struct urb *urb, struct pt_regs *regs) { struct appledisplay *pdata = urb->context; unsigned long flags; @@ -216,7 +216,10 @@ static int appledisplay_probe(struct usb_interface *iface, iface_desc = iface->cur_altsetting; for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) { endpoint = &iface_desc->endpoint[i].desc; - if (!int_in_endpointAddr && usb_endpoint_is_int_in(endpoint)) { + if (!int_in_endpointAddr && + (endpoint->bEndpointAddress & USB_DIR_IN) && + ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == + USB_ENDPOINT_XFER_INT)) { /* we found an interrupt in endpoint */ int_in_endpointAddr = endpoint->bEndpointAddress; break; diff --git a/trunk/drivers/usb/misc/auerswald.c b/trunk/drivers/usb/misc/auerswald.c index c703f73e1655..4fd2110b3411 100644 --- a/trunk/drivers/usb/misc/auerswald.c +++ b/trunk/drivers/usb/misc/auerswald.c @@ -267,7 +267,7 @@ typedef struct /*-------------------------------------------------------------------*/ /* Forwards */ -static void auerswald_ctrlread_complete (struct urb * urb); +static void auerswald_ctrlread_complete (struct urb * urb, struct pt_regs *regs); static void auerswald_removeservice (pauerswald_t cp, pauerscon_t scp); static struct usb_driver auerswald_driver; @@ -277,7 +277,7 @@ static struct usb_driver auerswald_driver; /* -------------------------- */ /* completion function for chained urbs */ -static void auerchain_complete (struct urb * urb) +static void auerchain_complete (struct urb * urb, struct pt_regs *regs) { unsigned long flags; int result; @@ -296,7 +296,7 @@ static void auerchain_complete (struct urb * urb) NOTE: this function may lead to more urbs submitted into the chain. (no chain lock at calling complete()!) acp->active != NULL is protecting us against recursion.*/ - urb->complete (urb); + urb->complete (urb, regs); /* detach element from chain data structure */ spin_lock_irqsave (&acp->lock, flags); @@ -331,7 +331,7 @@ static void auerchain_complete (struct urb * urb) urb->status = result; dbg("auerchain_complete: usb_submit_urb with error code %d", result); /* and do error handling via *this* completion function (recursive) */ - auerchain_complete( urb); + auerchain_complete( urb, NULL); } } else { /* simple return without submitting a new urb. @@ -408,7 +408,7 @@ static int auerchain_submit_urb_list (pauerchain_t acp, struct urb * urb, int ea urb->status = result; dbg("auerchain_submit_urb: usb_submit_urb with error code %d", result); /* and do error handling via completion function */ - auerchain_complete( urb); + auerchain_complete( urb, NULL); } } @@ -448,7 +448,7 @@ static int auerchain_unlink_urb (pauerchain_t acp, struct urb * urb) spin_unlock_irqrestore (&acp->lock, flags); dbg ("unlink waiting urb"); urb->status = -ENOENT; - urb->complete (urb); + urb->complete (urb, NULL); return 0; } } @@ -505,7 +505,7 @@ static void auerchain_unlink_all (pauerchain_t acp) spin_unlock_irqrestore (&acp->lock, flags); dbg ("unlink waiting urb"); urbp->status = -ENOENT; - urbp->complete (urbp); + urbp->complete (urbp, NULL); spin_lock_irqsave (&acp->lock, flags); } spin_unlock_irqrestore (&acp->lock, flags); @@ -591,7 +591,7 @@ static int auerchain_setup (pauerchain_t acp, unsigned int numElements) /* completion handler for synchronous chained URBs */ -static void auerchain_blocking_completion (struct urb *urb) +static void auerchain_blocking_completion (struct urb *urb, struct pt_regs *regs) { pauerchain_chs_t pchs = (pauerchain_chs_t)urb->context; pchs->done = 1; @@ -704,7 +704,9 @@ static void auerbuf_free (pauerbuf_t bp) { kfree(bp->bufp); kfree(bp->dr); - usb_free_urb(bp->urbp); + if (bp->urbp) { + usb_free_urb(bp->urbp); + } kfree(bp); } @@ -778,7 +780,7 @@ static int auerbuf_setup (pauerbufctl_t bcp, unsigned int numElements, unsigned bl_fail:/* not enough memory. Free allocated elements */ dbg ("auerbuf_setup: no more memory"); - auerbuf_free(bep); + kfree(bep); auerbuf_free_buffers (bcp); return -ENOMEM; } @@ -844,7 +846,7 @@ static int auerswald_status_retry (int status) } /* Completion of asynchronous write block */ -static void auerchar_ctrlwrite_complete (struct urb * urb) +static void auerchar_ctrlwrite_complete (struct urb * urb, struct pt_regs *regs) { pauerbuf_t bp = (pauerbuf_t) urb->context; pauerswald_t cp = ((pauerswald_t)((char *)(bp->list)-(unsigned long)(&((pauerswald_t)0)->bufctl))); @@ -857,7 +859,7 @@ static void auerchar_ctrlwrite_complete (struct urb * urb) } /* Completion handler for dummy retry packet */ -static void auerswald_ctrlread_wretcomplete (struct urb * urb) +static void auerswald_ctrlread_wretcomplete (struct urb * urb, struct pt_regs *regs) { pauerbuf_t bp = (pauerbuf_t) urb->context; pauerswald_t cp; @@ -891,12 +893,12 @@ static void auerswald_ctrlread_wretcomplete (struct urb * urb) if (ret) { dbg ("auerswald_ctrlread_complete: nonzero result of auerchain_submit_urb_list %d", ret); bp->urbp->status = ret; - auerswald_ctrlread_complete (bp->urbp); + auerswald_ctrlread_complete (bp->urbp, NULL); } } /* completion handler for receiving of control messages */ -static void auerswald_ctrlread_complete (struct urb * urb) +static void auerswald_ctrlread_complete (struct urb * urb, struct pt_regs *regs) { unsigned int serviceid; pauerswald_t cp; @@ -939,7 +941,7 @@ static void auerswald_ctrlread_complete (struct urb * urb) if (ret) { dbg ("auerswald_ctrlread_complete: nonzero result of auerchain_submit_urb_list %d", ret); bp->urbp->status = ret; - auerswald_ctrlread_wretcomplete (bp->urbp); + auerswald_ctrlread_wretcomplete (bp->urbp, regs); } return; } @@ -968,7 +970,7 @@ static void auerswald_ctrlread_complete (struct urb * urb) messages from the USB device. */ /* int completion handler. */ -static void auerswald_int_complete (struct urb * urb) +static void auerswald_int_complete (struct urb * urb, struct pt_regs *regs) { unsigned long flags; unsigned int channelid; @@ -1068,7 +1070,7 @@ static void auerswald_int_complete (struct urb * urb) if (ret) { dbg ("auerswald_int_complete: nonzero result of auerchain_submit_urb %d", ret); bp->urbp->status = ret; - auerswald_ctrlread_complete( bp->urbp); + auerswald_ctrlread_complete( bp->urbp, NULL); /* here applies the same problem as above: device locking! */ } exit: @@ -1153,7 +1155,8 @@ static void auerswald_int_release (pauerswald_t cp) dbg ("auerswald_int_release"); /* stop the int endpoint */ - usb_kill_urb (cp->inturbp); + if (cp->inturbp) + usb_kill_urb (cp->inturbp); /* deallocate memory */ auerswald_int_free (cp); diff --git a/trunk/drivers/usb/misc/emi26.c b/trunk/drivers/usb/misc/emi26.c index 5c0a26cbd128..1fd9cb85f4ca 100644 --- a/trunk/drivers/usb/misc/emi26.c +++ b/trunk/drivers/usb/misc/emi26.c @@ -53,12 +53,13 @@ static void __exit emi26_exit (void); static int emi26_writememory (struct usb_device *dev, int address, unsigned char *data, int length, __u8 request) { int result; - unsigned char *buffer = kmemdup(data, length, GFP_KERNEL); + unsigned char *buffer = kmalloc (length, GFP_KERNEL); if (!buffer) { err("emi26: kmalloc(%d) failed.", length); return -ENOMEM; } + memcpy (buffer, data, length); /* Note: usb_control_msg returns negative value on error or length of the * data that was written! */ result = usb_control_msg (dev, usb_sndctrlpipe(dev, 0), request, 0x40, address, 0, buffer, length, 300); diff --git a/trunk/drivers/usb/misc/emi62.c b/trunk/drivers/usb/misc/emi62.c index 23153eac0dfa..fe351371f274 100644 --- a/trunk/drivers/usb/misc/emi62.c +++ b/trunk/drivers/usb/misc/emi62.c @@ -61,12 +61,13 @@ static void __exit emi62_exit (void); static int emi62_writememory (struct usb_device *dev, int address, unsigned char *data, int length, __u8 request) { int result; - unsigned char *buffer = kmemdup(data, length, GFP_KERNEL); + unsigned char *buffer = kmalloc (length, GFP_KERNEL); if (!buffer) { err("emi62: kmalloc(%d) failed.", length); return -ENOMEM; } + memcpy (buffer, data, length); /* Note: usb_control_msg returns negative value on error or length of the * data that was written! */ result = usb_control_msg (dev, usb_sndctrlpipe(dev, 0), request, 0x40, address, 0, buffer, length, 300); diff --git a/trunk/drivers/usb/misc/ftdi-elan.c b/trunk/drivers/usb/misc/ftdi-elan.c index cb0ba3107d7f..c6f2f488a40f 100644 --- a/trunk/drivers/usb/misc/ftdi-elan.c +++ b/trunk/drivers/usb/misc/ftdi-elan.c @@ -303,7 +303,7 @@ void ftdi_elan_gone_away(struct platform_device *pdev) EXPORT_SYMBOL_GPL(ftdi_elan_gone_away); -static void ftdi_release_platform_dev(struct device *dev) +void ftdi_release_platform_dev(struct device *dev) { dev->parent = NULL; } @@ -513,6 +513,8 @@ static void ftdi_elan_respond_work(void *data) ftdi->disconnected += 1; } else if (retval == -ENODEV) { ftdi->disconnected += 1; + } else if (retval == -ENODEV) { + ftdi->disconnected += 1; } else if (retval == -EILSEQ) { ftdi->disconnected += 1; } else { @@ -756,7 +758,7 @@ static ssize_t ftdi_elan_read(struct file *file, char __user *buffer, return bytes_read; } -static void ftdi_elan_write_bulk_callback(struct urb *urb) +static void ftdi_elan_write_bulk_callback(struct urb *urb, struct pt_regs *regs) { struct usb_ftdi *ftdi = (struct usb_ftdi *)urb->context; if (urb->status && !(urb->status == -ENOENT || urb->status == @@ -1184,8 +1186,11 @@ static ssize_t ftdi_elan_write(struct file *file, int retval = 0; struct urb *urb; char *buf; - struct usb_ftdi *ftdi = file->private_data; - + char data[30 *3 + 4]; + char *d = data; + const char __user *s = user_buffer; + int m = (sizeof(data) - 1) / 3; + struct usb_ftdi *ftdi = (struct usb_ftdi *)file->private_data; if (ftdi->disconnected > 0) { return -ENODEV; } @@ -1215,18 +1220,27 @@ static ssize_t ftdi_elan_write(struct file *file, if (retval) { dev_err(&ftdi->udev->dev, "failed submitting write urb, error %" "d\n", retval); - goto error_3; + goto error_4; } usb_free_urb(urb); - -exit: + exit:; + if (count > m) { + int I = m - 1; + while (I-- > 0) { + d += sprintf(d, " %02X", 0x000000FF & *s++); + } + d += sprintf(d, " .."); + } else { + int I = count; + while (I-- > 0) { + d += sprintf(d, " %02X", 0x000000FF & *s++); + } + } return count; -error_3: - usb_buffer_free(ftdi->udev, count, buf, urb->transfer_dma); -error_2: - usb_free_urb(urb); -error_1: - return retval; + error_4: error_3:usb_buffer_free(ftdi->udev, count, buf, + urb->transfer_dma); + error_2:usb_free_urb(urb); + error_1:return retval; } static struct file_operations ftdi_elan_fops = { @@ -1426,6 +1440,14 @@ static int ftdi_elan_read_reg(struct usb_ftdi *ftdi, u32 *data) } } +int usb_ftdi_elan_read_reg(struct platform_device *pdev, u32 *data) +{ + struct usb_ftdi *ftdi = platform_device_to_usb_ftdi(pdev); + return ftdi_elan_read_reg(ftdi, data); +} + + +EXPORT_SYMBOL_GPL(usb_ftdi_elan_read_reg); static int ftdi_elan_read_config(struct usb_ftdi *ftdi, int config_offset, u8 width, u32 *data) { @@ -2625,7 +2647,10 @@ static int ftdi_elan_probe(struct usb_interface *interface, for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { endpoint = &iface_desc->endpoint[i].desc; if (!ftdi->bulk_in_endpointAddr && - usb_endpoint_is_bulk_in(endpoint)) { + ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) + == USB_DIR_IN) && ((endpoint->bmAttributes & + USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK)) + { buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); ftdi->bulk_in_size = buffer_size; ftdi->bulk_in_endpointAddr = endpoint->bEndpointAddress; @@ -2638,7 +2663,10 @@ static int ftdi_elan_probe(struct usb_interface *interface, } } if (!ftdi->bulk_out_endpointAddr && - usb_endpoint_is_bulk_out(endpoint)) { + ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) + == USB_DIR_OUT) && ((endpoint->bmAttributes & + USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK)) + { ftdi->bulk_out_endpointAddr = endpoint->bEndpointAddress; } diff --git a/trunk/drivers/usb/misc/idmouse.c b/trunk/drivers/usb/misc/idmouse.c index c9418535bef8..8e6e195a22ba 100644 --- a/trunk/drivers/usb/misc/idmouse.c +++ b/trunk/drivers/usb/misc/idmouse.c @@ -125,12 +125,12 @@ static DEFINE_MUTEX(disconnect_mutex); static int idmouse_create_image(struct usb_idmouse *dev) { - int bytes_read; - int bulk_read; - int result; + int bytes_read = 0; + int bulk_read = 0; + int result = 0; memcpy(dev->bulk_in_buffer, HEADER, sizeof(HEADER)-1); - bytes_read = sizeof(HEADER)-1; + bytes_read += sizeof(HEADER)-1; /* reset the device and set a fast blink rate */ result = ftip_command(dev, FTIP_RELEASE, 0, 0); @@ -208,9 +208,9 @@ static inline void idmouse_delete(struct usb_idmouse *dev) static int idmouse_open(struct inode *inode, struct file *file) { - struct usb_idmouse *dev; + struct usb_idmouse *dev = NULL; struct usb_interface *interface; - int result; + int result = 0; /* prevent disconnects */ mutex_lock(&disconnect_mutex); @@ -305,7 +305,7 @@ static ssize_t idmouse_read(struct file *file, char __user *buffer, size_t count loff_t * ppos) { struct usb_idmouse *dev; - int result; + int result = 0; dev = (struct usb_idmouse *) file->private_data; @@ -329,7 +329,7 @@ static int idmouse_probe(struct usb_interface *interface, const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev(interface); - struct usb_idmouse *dev; + struct usb_idmouse *dev = NULL; struct usb_host_interface *iface_desc; struct usb_endpoint_descriptor *endpoint; int result; @@ -350,7 +350,11 @@ static int idmouse_probe(struct usb_interface *interface, /* set up the endpoint information - use only the first bulk-in endpoint */ endpoint = &iface_desc->endpoint[0].desc; - if (!dev->bulk_in_endpointAddr && usb_endpoint_is_bulk_in(endpoint)) { + if (!dev->bulk_in_endpointAddr + && (endpoint->bEndpointAddress & USB_DIR_IN) + && ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == + USB_ENDPOINT_XFER_BULK)) { + /* we found a bulk in endpoint */ dev->orig_bi_size = le16_to_cpu(endpoint->wMaxPacketSize); dev->bulk_in_size = 0x200; /* works _much_ faster */ diff --git a/trunk/drivers/usb/misc/ldusb.c b/trunk/drivers/usb/misc/ldusb.c index 788a11e6772f..10b640339d8d 100644 --- a/trunk/drivers/usb/misc/ldusb.c +++ b/trunk/drivers/usb/misc/ldusb.c @@ -212,7 +212,7 @@ static void ld_usb_delete(struct ld_usb *dev) /** * ld_usb_interrupt_in_callback */ -static void ld_usb_interrupt_in_callback(struct urb *urb) +static void ld_usb_interrupt_in_callback(struct urb *urb, struct pt_regs *regs) { struct ld_usb *dev = urb->context; size_t *actual_buffer; @@ -264,7 +264,7 @@ static void ld_usb_interrupt_in_callback(struct urb *urb) /** * ld_usb_interrupt_out_callback */ -static void ld_usb_interrupt_out_callback(struct urb *urb) +static void ld_usb_interrupt_out_callback(struct urb *urb, struct pt_regs *regs) { struct ld_usb *dev = urb->context; diff --git a/trunk/drivers/usb/misc/legousbtower.c b/trunk/drivers/usb/misc/legousbtower.c index 5dce797bddb7..77c36e63c7bf 100644 --- a/trunk/drivers/usb/misc/legousbtower.c +++ b/trunk/drivers/usb/misc/legousbtower.c @@ -248,8 +248,8 @@ static loff_t tower_llseek (struct file *file, loff_t off, int whence); static void tower_abort_transfers (struct lego_usb_tower *dev); static void tower_check_for_read_packet (struct lego_usb_tower *dev); -static void tower_interrupt_in_callback (struct urb *urb); -static void tower_interrupt_out_callback (struct urb *urb); +static void tower_interrupt_in_callback (struct urb *urb, struct pt_regs *regs); +static void tower_interrupt_out_callback (struct urb *urb, struct pt_regs *regs); static int tower_probe (struct usb_interface *interface, const struct usb_device_id *id); static void tower_disconnect (struct usb_interface *interface); @@ -317,8 +317,12 @@ static inline void tower_delete (struct lego_usb_tower *dev) tower_abort_transfers (dev); /* free data structures */ - usb_free_urb(dev->interrupt_in_urb); - usb_free_urb(dev->interrupt_out_urb); + if (dev->interrupt_in_urb != NULL) { + usb_free_urb (dev->interrupt_in_urb); + } + if (dev->interrupt_out_urb != NULL) { + usb_free_urb (dev->interrupt_out_urb); + } kfree (dev->read_buffer); kfree (dev->interrupt_in_buffer); kfree (dev->interrupt_out_buffer); @@ -498,11 +502,15 @@ static void tower_abort_transfers (struct lego_usb_tower *dev) if (dev->interrupt_in_running) { dev->interrupt_in_running = 0; mb(); - if (dev->udev) + if (dev->interrupt_in_urb != NULL && dev->udev) { usb_kill_urb (dev->interrupt_in_urb); + } + } + if (dev->interrupt_out_busy) { + if (dev->interrupt_out_urb != NULL && dev->udev) { + usb_kill_urb (dev->interrupt_out_urb); + } } - if (dev->interrupt_out_busy && dev->udev) - usb_kill_urb(dev->interrupt_out_urb); exit: dbg(2, "%s: leave", __FUNCTION__); @@ -747,7 +755,7 @@ static ssize_t tower_write (struct file *file, const char __user *buffer, size_t /** * tower_interrupt_in_callback */ -static void tower_interrupt_in_callback (struct urb *urb) +static void tower_interrupt_in_callback (struct urb *urb, struct pt_regs *regs) { struct lego_usb_tower *dev = (struct lego_usb_tower *)urb->context; int retval; @@ -803,7 +811,7 @@ static void tower_interrupt_in_callback (struct urb *urb) /** * tower_interrupt_out_callback */ -static void tower_interrupt_out_callback (struct urb *urb) +static void tower_interrupt_out_callback (struct urb *urb, struct pt_regs *regs) { struct lego_usb_tower *dev = (struct lego_usb_tower *)urb->context; @@ -890,11 +898,14 @@ static int tower_probe (struct usb_interface *interface, const struct usb_device for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { endpoint = &iface_desc->endpoint[i].desc; - if (usb_endpoint_xfer_int(endpoint)) { - if (usb_endpoint_dir_in(endpoint)) - dev->interrupt_in_endpoint = endpoint; - else - dev->interrupt_out_endpoint = endpoint; + if (((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) && + ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)) { + dev->interrupt_in_endpoint = endpoint; + } + + if (((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) && + ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)) { + dev->interrupt_out_endpoint = endpoint; } } if(dev->interrupt_in_endpoint == NULL) { diff --git a/trunk/drivers/usb/misc/phidgetkit.c b/trunk/drivers/usb/misc/phidgetkit.c index 9110793f81d3..78e419904abf 100644 --- a/trunk/drivers/usb/misc/phidgetkit.c +++ b/trunk/drivers/usb/misc/phidgetkit.c @@ -300,7 +300,7 @@ static ssize_t enable_lcd_files(struct device *dev, struct device_attribute *att static DEVICE_ATTR(lcd, S_IWUGO, NULL, enable_lcd_files); -static void interfacekit_irq(struct urb *urb) +static void interfacekit_irq(struct urb *urb, struct pt_regs *regs) { struct interfacekit *kit = urb->context; unsigned char *buffer = kit->data; @@ -551,7 +551,7 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic return -ENODEV; endpoint = &interface->endpoint[0].desc; - if (!usb_endpoint_dir_in(endpoint)) + if (!(endpoint->bEndpointAddress & 0x80)) return -ENODEV; /* * bmAttributes @@ -650,7 +650,8 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic device_remove_file(kit->dev, &dev_output_attrs[i]); out: if (kit) { - usb_free_urb(kit->irq); + if (kit->irq) + usb_free_urb(kit->irq); if (kit->data) usb_buffer_free(dev, URB_INT_SIZE, kit->data, kit->data_dma); if (kit->dev) diff --git a/trunk/drivers/usb/misc/phidgetmotorcontrol.c b/trunk/drivers/usb/misc/phidgetmotorcontrol.c index c3469b0a67c2..6b59b620d616 100644 --- a/trunk/drivers/usb/misc/phidgetmotorcontrol.c +++ b/trunk/drivers/usb/misc/phidgetmotorcontrol.c @@ -90,7 +90,7 @@ static int set_motor(struct motorcontrol *mc, int motor) return retval < 0 ? retval : 0; } -static void motorcontrol_irq(struct urb *urb) +static void motorcontrol_irq(struct urb *urb, struct pt_regs *regs) { struct motorcontrol *mc = urb->context; unsigned char *buffer = mc->data; @@ -323,7 +323,7 @@ static int motorcontrol_probe(struct usb_interface *intf, const struct usb_devic return -ENODEV; endpoint = &interface->endpoint[0].desc; - if (!usb_endpoint_dir_in(endpoint)) + if (!(endpoint->bEndpointAddress & 0x80)) return -ENODEV; /* @@ -392,7 +392,8 @@ static int motorcontrol_probe(struct usb_interface *intf, const struct usb_devic device_remove_file(mc->dev, &dev_attrs[i]); out: if (mc) { - usb_free_urb(mc->irq); + if (mc->irq) + usb_free_urb(mc->irq); if (mc->data) usb_buffer_free(dev, URB_INT_SIZE, mc->data, mc->data_dma); if (mc->dev) diff --git a/trunk/drivers/usb/misc/sisusbvga/sisusb.c b/trunk/drivers/usb/misc/sisusbvga/sisusb.c index b99ca9c79821..a287836e39f1 100644 --- a/trunk/drivers/usb/misc/sisusbvga/sisusb.c +++ b/trunk/drivers/usb/misc/sisusbvga/sisusb.c @@ -209,7 +209,7 @@ sisusb_free_outbuf(struct sisusb_usb_data *sisusb, int index) /* completion callback */ static void -sisusb_bulk_completeout(struct urb *urb) +sisusb_bulk_completeout(struct urb *urb, struct pt_regs *regs) { struct sisusb_urb_context *context = urb->context; struct sisusb_usb_data *sisusb; @@ -288,7 +288,7 @@ sisusb_bulkout_msg(struct sisusb_usb_data *sisusb, int index, unsigned int pipe, /* completion callback */ static void -sisusb_bulk_completein(struct urb *urb) +sisusb_bulk_completein(struct urb *urb, struct pt_regs *regs) { struct sisusb_usb_data *sisusb = urb->context; diff --git a/trunk/drivers/usb/misc/usb_u132.h b/trunk/drivers/usb/misc/usb_u132.h index dc2e5a31caec..551ba8906d62 100644 --- a/trunk/drivers/usb/misc/usb_u132.h +++ b/trunk/drivers/usb/misc/usb_u132.h @@ -52,7 +52,7 @@ * the kernel to load the "u132-hcd" module. * * The "ftdi-u132" module provides the interface to the inserted -* PC card and the "u132-hcd" module uses the API to send and receive +* PC card and the "u132-hcd" module uses the API to send and recieve * data. The API features call-backs, so that part of the "u132-hcd" * module code will run in the context of one of the kernel threads * of the "ftdi-u132" module. @@ -95,7 +95,3 @@ int usb_ftdi_elan_edset_setup(struct platform_device *pdev, u8 ed_number, int halted, int skipped, int actual, int non_null)); int usb_ftdi_elan_edset_flush(struct platform_device *pdev, u8 ed_number, void *endp); -int usb_ftdi_elan_read_pcimem(struct platform_device *pdev, int mem_offset, - u8 width, u32 *data); -int usb_ftdi_elan_write_pcimem(struct platform_device *pdev, int mem_offset, - u8 width, u32 data); diff --git a/trunk/drivers/usb/misc/usblcd.c b/trunk/drivers/usb/misc/usblcd.c index ada2ebc464ae..dbaca9f1efad 100644 --- a/trunk/drivers/usb/misc/usblcd.c +++ b/trunk/drivers/usb/misc/usblcd.c @@ -165,7 +165,7 @@ static int lcd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u return 0; } -static void lcd_write_bulk_callback(struct urb *urb) +static void lcd_write_bulk_callback(struct urb *urb, struct pt_regs *regs) { struct usb_lcd *dev; diff --git a/trunk/drivers/usb/misc/usbtest.c b/trunk/drivers/usb/misc/usbtest.c index 194065dbb51f..983e104dd452 100644 --- a/trunk/drivers/usb/misc/usbtest.c +++ b/trunk/drivers/usb/misc/usbtest.c @@ -138,7 +138,7 @@ get_endpoints (struct usbtest_dev *dev, struct usb_interface *intf) default: continue; } - if (usb_endpoint_dir_in(&e->desc)) { + if (e->desc.bEndpointAddress & USB_DIR_IN) { if (!in) in = e; } else { @@ -147,7 +147,7 @@ get_endpoints (struct usbtest_dev *dev, struct usb_interface *intf) } continue; try_iso: - if (usb_endpoint_dir_in(&e->desc)) { + if (e->desc.bEndpointAddress & USB_DIR_IN) { if (!iso_in) iso_in = e; } else { @@ -198,7 +198,7 @@ get_endpoints (struct usbtest_dev *dev, struct usb_interface *intf) * them with non-zero test data (or test for it) when appropriate. */ -static void simple_callback (struct urb *urb) +static void simple_callback (struct urb *urb, struct pt_regs *regs) { complete ((struct completion *) urb->context); } @@ -730,7 +730,7 @@ struct subcase { int expected; }; -static void ctrl_complete (struct urb *urb) +static void ctrl_complete (struct urb *urb, struct pt_regs *regs) { struct ctrl_ctx *ctx = urb->context; struct usb_ctrlrequest *reqp; @@ -1035,7 +1035,7 @@ test_ctrl_queue (struct usbtest_dev *dev, struct usbtest_param *param) /*-------------------------------------------------------------------------*/ -static void unlink1_callback (struct urb *urb) +static void unlink1_callback (struct urb *urb, struct pt_regs *regs) { int status = urb->status; @@ -1343,7 +1343,7 @@ struct iso_context { struct usbtest_dev *dev; }; -static void iso_callback (struct urb *urb) +static void iso_callback (struct urb *urb, struct pt_regs *regs) { struct iso_context *ctx = urb->context; diff --git a/trunk/drivers/usb/misc/uss720.c b/trunk/drivers/usb/misc/uss720.c index 7e8a0acd52ee..4081990b7d1a 100644 --- a/trunk/drivers/usb/misc/uss720.c +++ b/trunk/drivers/usb/misc/uss720.c @@ -106,7 +106,7 @@ static void destroy_async(struct kref *kref) /* --------------------------------------------------------------------- */ -static void async_complete(struct urb *urb) +static void async_complete(struct urb *urb, struct pt_regs *ptregs) { struct uss720_async_request *rq; struct parport *pp; @@ -127,7 +127,7 @@ static void async_complete(struct urb *urb) #endif /* if nAck interrupts are enabled and we have an interrupt, call the interrupt procedure */ if (rq->reg[2] & rq->reg[1] & 0x10 && pp) - parport_generic_irq(0, pp); + parport_generic_irq(0, pp, NULL); } complete(&rq->compl); kref_put(&rq->ref_count, destroy_async); diff --git a/trunk/drivers/usb/net/Kconfig b/trunk/drivers/usb/net/Kconfig index e081836014ac..054059632a21 100644 --- a/trunk/drivers/usb/net/Kconfig +++ b/trunk/drivers/usb/net/Kconfig @@ -92,13 +92,8 @@ config USB_RTL8150 To compile this driver as a module, choose M here: the module will be called rtl8150. -config USB_USBNET_MII - tristate - default n - config USB_USBNET tristate "Multi-purpose USB Networking Framework" - select MII if USBNET_MII != n ---help--- This driver supports several kinds of network links over USB, with "minidrivers" built around a common network driver core @@ -134,7 +129,7 @@ config USB_NET_AX8817X tristate "ASIX AX88xxx Based USB 2.0 Ethernet Adapters" depends on USB_USBNET && NET_ETHERNET select CRC32 - select USB_USBNET_MII + select MII default y help This option adds support for ASIX AX88xxx based USB 2.0 @@ -212,15 +207,6 @@ config USB_NET_PLUSB Choose this option if you're using a host-to-host cable with one of these chips. -config USB_NET_MCS7830 - tristate "MosChip MCS7830 based Ethernet adapters" - depends on USB_USBNET - select USB_USBNET_MII - help - Choose this option if you're using a 10/100 Ethernet USB2 - adapter based on the MosChip 7830 controller. This includes - adapters marketed under the DeLOCK brand. - config USB_NET_RNDIS_HOST tristate "Host for RNDIS devices (EXPERIMENTAL)" depends on USB_USBNET && EXPERIMENTAL diff --git a/trunk/drivers/usb/net/Makefile b/trunk/drivers/usb/net/Makefile index 7b51964de171..160f19dbdf12 100644 --- a/trunk/drivers/usb/net/Makefile +++ b/trunk/drivers/usb/net/Makefile @@ -14,7 +14,6 @@ obj-$(CONFIG_USB_NET_PLUSB) += plusb.o obj-$(CONFIG_USB_NET_RNDIS_HOST) += rndis_host.o obj-$(CONFIG_USB_NET_CDC_SUBSET) += cdc_subset.o obj-$(CONFIG_USB_NET_ZAURUS) += zaurus.o -obj-$(CONFIG_USB_NET_MCS7830) += mcs7830.o obj-$(CONFIG_USB_USBNET) += usbnet.o ifeq ($(CONFIG_USB_DEBUG),y) diff --git a/trunk/drivers/usb/net/asix.c b/trunk/drivers/usb/net/asix.c index 95e682e2c9d6..9c0eacf7055c 100644 --- a/trunk/drivers/usb/net/asix.c +++ b/trunk/drivers/usb/net/asix.c @@ -214,7 +214,7 @@ static int asix_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, USB_CTRL_SET_TIMEOUT); } -static void asix_async_cmd_callback(struct urb *urb) +static void asix_async_cmd_callback(struct urb *urb, struct pt_regs *regs) { struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context; @@ -249,9 +249,9 @@ asix_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index, req->bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE; req->bRequest = cmd; - req->wValue = cpu_to_le16(value); - req->wIndex = cpu_to_le16(index); - req->wLength = cpu_to_le16(size); + req->wValue = value; + req->wIndex = index; + req->wLength = size; usb_fill_control_urb(urb, dev->udev, usb_sndctrlpipe(dev->udev, 0), @@ -569,12 +569,10 @@ static int asix_mdio_read(struct net_device *netdev, int phy_id, int loc) struct usbnet *dev = netdev_priv(netdev); u16 res; - mutex_lock(&dev->phy_mutex); asix_set_sw_mii(dev); asix_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id, (__u16)loc, 2, (u16 *)&res); asix_set_hw_mii(dev); - mutex_unlock(&dev->phy_mutex); devdbg(dev, "asix_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x", phy_id, loc, le16_to_cpu(res & 0xffff)); @@ -588,12 +586,10 @@ asix_mdio_write(struct net_device *netdev, int phy_id, int loc, int val) u16 res = cpu_to_le16(val); devdbg(dev, "asix_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x", phy_id, loc, val); - mutex_lock(&dev->phy_mutex); asix_set_sw_mii(dev); asix_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, (__u16)loc, 2, (u16 *)&res); asix_set_hw_mii(dev); - mutex_unlock(&dev->phy_mutex); } /* Get the PHY Identifier from the PHYSID1 & PHYSID2 MII registers */ @@ -704,6 +700,32 @@ static void asix_get_drvinfo (struct net_device *net, info->eedump_len = data->eeprom_len; } +static int asix_get_settings(struct net_device *net, struct ethtool_cmd *cmd) +{ + struct usbnet *dev = netdev_priv(net); + + return mii_ethtool_gset(&dev->mii,cmd); +} + +static int asix_set_settings(struct net_device *net, struct ethtool_cmd *cmd) +{ + struct usbnet *dev = netdev_priv(net); + int res = mii_ethtool_sset(&dev->mii,cmd); + + /* link speed/duplex might have changed */ + if (dev->driver_info->link_reset) + dev->driver_info->link_reset(dev); + + return res; +} + +static int asix_nway_reset(struct net_device *net) +{ + struct usbnet *dev = netdev_priv(net); + + return mii_nway_restart(&dev->mii); +} + static u32 asix_get_link(struct net_device *net) { struct usbnet *dev = netdev_priv(net); @@ -724,15 +746,15 @@ static int asix_ioctl (struct net_device *net, struct ifreq *rq, int cmd) static struct ethtool_ops ax88172_ethtool_ops = { .get_drvinfo = asix_get_drvinfo, .get_link = asix_get_link, + .nway_reset = asix_nway_reset, .get_msglevel = usbnet_get_msglevel, .set_msglevel = usbnet_set_msglevel, .get_wol = asix_get_wol, .set_wol = asix_set_wol, .get_eeprom_len = asix_get_eeprom_len, .get_eeprom = asix_get_eeprom, - .get_settings = usbnet_get_settings, - .set_settings = usbnet_set_settings, - .nway_reset = usbnet_nway_reset, + .get_settings = asix_get_settings, + .set_settings = asix_set_settings, }; static void ax88172_set_multicast(struct net_device *net) @@ -863,15 +885,15 @@ static int ax88172_bind(struct usbnet *dev, struct usb_interface *intf) static struct ethtool_ops ax88772_ethtool_ops = { .get_drvinfo = asix_get_drvinfo, .get_link = asix_get_link, + .nway_reset = asix_nway_reset, .get_msglevel = usbnet_get_msglevel, .set_msglevel = usbnet_set_msglevel, .get_wol = asix_get_wol, .set_wol = asix_set_wol, .get_eeprom_len = asix_get_eeprom_len, .get_eeprom = asix_get_eeprom, - .get_settings = usbnet_get_settings, - .set_settings = usbnet_set_settings, - .nway_reset = usbnet_nway_reset, + .get_settings = asix_get_settings, + .set_settings = asix_set_settings, }; static int ax88772_link_reset(struct usbnet *dev) @@ -1024,15 +1046,15 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf) static struct ethtool_ops ax88178_ethtool_ops = { .get_drvinfo = asix_get_drvinfo, .get_link = asix_get_link, + .nway_reset = asix_nway_reset, .get_msglevel = usbnet_get_msglevel, .set_msglevel = usbnet_set_msglevel, .get_wol = asix_get_wol, .set_wol = asix_set_wol, .get_eeprom_len = asix_get_eeprom_len, .get_eeprom = asix_get_eeprom, - .get_settings = usbnet_get_settings, - .set_settings = usbnet_set_settings, - .nway_reset = usbnet_nway_reset, + .get_settings = asix_get_settings, + .set_settings = asix_set_settings, }; static int marvell_phy_init(struct usbnet *dev) diff --git a/trunk/drivers/usb/net/catc.c b/trunk/drivers/usb/net/catc.c index 907b820a5faf..be5f5e142dd0 100644 --- a/trunk/drivers/usb/net/catc.c +++ b/trunk/drivers/usb/net/catc.c @@ -223,7 +223,7 @@ struct catc { * Receive routines. */ -static void catc_rx_done(struct urb *urb) +static void catc_rx_done(struct urb *urb, struct pt_regs *regs) { struct catc *catc = urb->context; u8 *pkt_start = urb->transfer_buffer; @@ -289,7 +289,7 @@ static void catc_rx_done(struct urb *urb) } } -static void catc_irq_done(struct urb *urb) +static void catc_irq_done(struct urb *urb, struct pt_regs *regs) { struct catc *catc = urb->context; u8 *data = urb->transfer_buffer; @@ -376,7 +376,7 @@ static void catc_tx_run(struct catc *catc) catc->netdev->trans_start = jiffies; } -static void catc_tx_done(struct urb *urb) +static void catc_tx_done(struct urb *urb, struct pt_regs *regs) { struct catc *catc = urb->context; unsigned long flags; @@ -486,7 +486,7 @@ static void catc_ctrl_run(struct catc *catc) err("submit(ctrl_urb) status %d", status); } -static void catc_ctrl_done(struct urb *urb) +static void catc_ctrl_done(struct urb *urb, struct pt_regs *regs) { struct catc *catc = urb->context; struct ctrl_queue *q; @@ -786,10 +786,14 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id if ((!catc->ctrl_urb) || (!catc->tx_urb) || (!catc->rx_urb) || (!catc->irq_urb)) { err("No free urbs available."); - usb_free_urb(catc->ctrl_urb); - usb_free_urb(catc->tx_urb); - usb_free_urb(catc->rx_urb); - usb_free_urb(catc->irq_urb); + if (catc->ctrl_urb) + usb_free_urb(catc->ctrl_urb); + if (catc->tx_urb) + usb_free_urb(catc->tx_urb); + if (catc->rx_urb) + usb_free_urb(catc->rx_urb); + if (catc->irq_urb) + usb_free_urb(catc->irq_urb); free_netdev(netdev); return -ENOMEM; } diff --git a/trunk/drivers/usb/net/cdc_ether.c b/trunk/drivers/usb/net/cdc_ether.c index 44a91547146e..82ce0358d9a3 100644 --- a/trunk/drivers/usb/net/cdc_ether.c +++ b/trunk/drivers/usb/net/cdc_ether.c @@ -200,7 +200,8 @@ int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf) dev->status = &info->control->cur_altsetting->endpoint [0]; desc = &dev->status->desc; - if (!usb_endpoint_is_int_in(desc) + if (desc->bmAttributes != USB_ENDPOINT_XFER_INT + || !(desc->bEndpointAddress & USB_DIR_IN) || (le16_to_cpu(desc->wMaxPacketSize) < sizeof(struct usb_cdc_notification)) || !desc->bInterval) { @@ -497,7 +498,7 @@ static struct usb_driver cdc_driver = { static int __init cdc_init(void) { - BUILD_BUG_ON((sizeof(((struct usbnet *)0)->data) + BUG_ON((sizeof(((struct usbnet *)0)->data) < sizeof(struct cdc_state))); return usb_register(&cdc_driver); diff --git a/trunk/drivers/usb/net/gl620a.c b/trunk/drivers/usb/net/gl620a.c index a3242be21959..3155f25f1d48 100644 --- a/trunk/drivers/usb/net/gl620a.c +++ b/trunk/drivers/usb/net/gl620a.c @@ -106,7 +106,7 @@ static inline int gl_control_write(struct usbnet *dev, u8 request, u16 value) return retval; } -static void gl_interrupt_complete(struct urb *urb) +static void gl_interrupt_complete(struct urb *urb, struct pt_regs *regs) { int status = urb->status; diff --git a/trunk/drivers/usb/net/kaweth.c b/trunk/drivers/usb/net/kaweth.c index 7c906a43e497..544d41fe9b92 100644 --- a/trunk/drivers/usb/net/kaweth.c +++ b/trunk/drivers/usb/net/kaweth.c @@ -65,6 +65,16 @@ #undef DEBUG +#ifdef DEBUG +#define kaweth_dbg(format, arg...) printk(KERN_DEBUG __FILE__ ": " format "\n" ,##arg) +#else +#define kaweth_dbg(format, arg...) do {} while (0) +#endif +#define kaweth_err(format, arg...) printk(KERN_ERR __FILE__ ": " format "\n" ,##arg) +#define kaweth_info(format, arg...) printk(KERN_INFO __FILE__ ": " format "\n" , ##arg) +#define kaweth_warn(format, arg...) printk(KERN_WARNING __FILE__ ": " format "\n" , ##arg) + + #include "kawethfw.h" #define KAWETH_MTU 1514 @@ -76,9 +86,6 @@ #define KAWETH_STATUS_BROKEN 0x0000001 #define KAWETH_STATUS_CLOSING 0x0000002 -#define KAWETH_STATUS_SUSPENDING 0x0000004 - -#define KAWETH_STATUS_BLOCKED (KAWETH_STATUS_CLOSING | KAWETH_STATUS_SUSPENDING) #define KAWETH_PACKET_FILTER_PROMISCUOUS 0x01 #define KAWETH_PACKET_FILTER_ALL_MULTICAST 0x02 @@ -105,8 +112,6 @@ #define STATE_MASK 0x40 #define STATE_SHIFT 5 -#define IS_BLOCKED(s) (s & KAWETH_STATUS_BLOCKED) - MODULE_AUTHOR("Michael Zappe , Stephane Alnet , Brad Hards and Oliver Neukum "); MODULE_DESCRIPTION("KL5USB101 USB Ethernet driver"); @@ -123,8 +128,6 @@ static int kaweth_internal_control_msg(struct usb_device *usb_dev, unsigned int pipe, struct usb_ctrlrequest *cmd, void *data, int len, int timeout); -static int kaweth_suspend(struct usb_interface *intf, pm_message_t message); -static int kaweth_resume(struct usb_interface *intf); /**************************************************************** * usb_device_id @@ -176,8 +179,6 @@ static struct usb_driver kaweth_driver = { .name = driver_name, .probe = kaweth_probe, .disconnect = kaweth_disconnect, - .suspend = kaweth_suspend, - .resume = kaweth_resume, .id_table = usb_klsi_table, }; @@ -221,7 +222,6 @@ struct kaweth_device int suspend_lowmem_rx; int suspend_lowmem_ctrl; int linkstate; - int opened; struct work_struct lowmem_work; struct usb_device *dev; @@ -265,17 +265,17 @@ static int kaweth_control(struct kaweth_device *kaweth, { struct usb_ctrlrequest *dr; - dbg("kaweth_control()"); + kaweth_dbg("kaweth_control()"); if(in_interrupt()) { - dbg("in_interrupt()"); + kaweth_dbg("in_interrupt()"); return -EBUSY; } dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC); if (!dr) { - dbg("kmalloc() failed"); + kaweth_dbg("kmalloc() failed"); return -ENOMEM; } @@ -300,7 +300,7 @@ static int kaweth_read_configuration(struct kaweth_device *kaweth) { int retval; - dbg("Reading kaweth configuration"); + kaweth_dbg("Reading kaweth configuration"); retval = kaweth_control(kaweth, usb_rcvctrlpipe(kaweth->dev, 0), @@ -322,7 +322,7 @@ static int kaweth_set_urb_size(struct kaweth_device *kaweth, __u16 urb_size) { int retval; - dbg("Setting URB size to %d", (unsigned)urb_size); + kaweth_dbg("Setting URB size to %d", (unsigned)urb_size); retval = kaweth_control(kaweth, usb_sndctrlpipe(kaweth->dev, 0), @@ -344,7 +344,7 @@ static int kaweth_set_sofs_wait(struct kaweth_device *kaweth, __u16 sofs_wait) { int retval; - dbg("Set SOFS wait to %d", (unsigned)sofs_wait); + kaweth_dbg("Set SOFS wait to %d", (unsigned)sofs_wait); retval = kaweth_control(kaweth, usb_sndctrlpipe(kaweth->dev, 0), @@ -367,7 +367,7 @@ static int kaweth_set_receive_filter(struct kaweth_device *kaweth, { int retval; - dbg("Set receive filter to %d", (unsigned)receive_filter); + kaweth_dbg("Set receive filter to %d", (unsigned)receive_filter); retval = kaweth_control(kaweth, usb_sndctrlpipe(kaweth->dev, 0), @@ -392,7 +392,7 @@ static int kaweth_download_firmware(struct kaweth_device *kaweth, __u8 type) { if(data_len > KAWETH_FIRMWARE_BUF_SIZE) { - err("Firmware too big: %d", data_len); + kaweth_err("Firmware too big: %d", data_len); return -ENOSPC; } @@ -403,13 +403,13 @@ static int kaweth_download_firmware(struct kaweth_device *kaweth, kaweth->firmware_buf[4] = type; kaweth->firmware_buf[5] = interrupt; - dbg("High: %i, Low:%i", kaweth->firmware_buf[3], + kaweth_dbg("High: %i, Low:%i", kaweth->firmware_buf[3], kaweth->firmware_buf[2]); - dbg("Downloading firmware at %p to kaweth device at %p", + kaweth_dbg("Downloading firmware at %p to kaweth device at %p", data, kaweth); - dbg("Firmware length: %d", data_len); + kaweth_dbg("Firmware length: %d", data_len); return kaweth_control(kaweth, usb_sndctrlpipe(kaweth->dev, 0), @@ -437,7 +437,7 @@ static int kaweth_trigger_firmware(struct kaweth_device *kaweth, kaweth->firmware_buf[6] = 0x00; kaweth->firmware_buf[7] = 0x00; - dbg("Triggering firmware"); + kaweth_dbg("Triggering firmware"); return kaweth_control(kaweth, usb_sndctrlpipe(kaweth->dev, 0), @@ -457,7 +457,7 @@ static int kaweth_reset(struct kaweth_device *kaweth) { int result; - dbg("kaweth_reset(%p)", kaweth); + kaweth_dbg("kaweth_reset(%p)", kaweth); result = kaweth_control(kaweth, usb_sndctrlpipe(kaweth->dev, 0), USB_REQ_SET_CONFIGURATION, @@ -470,12 +470,12 @@ static int kaweth_reset(struct kaweth_device *kaweth) mdelay(10); - dbg("kaweth_reset() returns %d.",result); + kaweth_dbg("kaweth_reset() returns %d.",result); return result; } -static void kaweth_usb_receive(struct urb *); +static void kaweth_usb_receive(struct urb *, struct pt_regs *regs); static int kaweth_resubmit_rx_urb(struct kaweth_device *, gfp_t); /**************************************************************** @@ -500,7 +500,7 @@ static void kaweth_resubmit_int_urb(struct kaweth_device *kaweth, gfp_t mf) kaweth->dev->devpath, status); } -static void int_callback(struct urb *u) +static void int_callback(struct urb *u, struct pt_regs *regs) { struct kaweth_device *kaweth = u->context; int act_state; @@ -534,7 +534,7 @@ static void kaweth_resubmit_tl(void *d) { struct kaweth_device *kaweth = (struct kaweth_device *)d; - if (IS_BLOCKED(kaweth->status)) + if (kaweth->status | KAWETH_STATUS_CLOSING) return; if (kaweth->suspend_lowmem_rx) @@ -568,7 +568,7 @@ static int kaweth_resubmit_rx_urb(struct kaweth_device *kaweth, kaweth->suspend_lowmem_rx = 1; schedule_delayed_work(&kaweth->lowmem_work, HZ/4); } - err("resubmitting rx_urb %d failed", result); + kaweth_err("resubmitting rx_urb %d failed", result); } else { kaweth->suspend_lowmem_rx = 0; } @@ -581,7 +581,7 @@ static void kaweth_async_set_rx_mode(struct kaweth_device *kaweth); /**************************************************************** * kaweth_usb_receive ****************************************************************/ -static void kaweth_usb_receive(struct urb *urb) +static void kaweth_usb_receive(struct urb *urb, struct pt_regs *regs) { struct kaweth_device *kaweth = urb->context; struct net_device *net = kaweth->net; @@ -601,15 +601,11 @@ static void kaweth_usb_receive(struct urb *urb) return; } - spin_lock(&kaweth->device_lock); - if (IS_BLOCKED(kaweth->status)) { - spin_unlock(&kaweth->device_lock); + if (kaweth->status & KAWETH_STATUS_CLOSING) return; - } - spin_unlock(&kaweth->device_lock); if(urb->status && urb->status != -EREMOTEIO && count != 1) { - err("%s RX status: %d count: %d packet_len: %d", + kaweth_err("%s RX status: %d count: %d packet_len: %d", net->name, urb->status, count, @@ -620,9 +616,9 @@ static void kaweth_usb_receive(struct urb *urb) if(kaweth->net && (count > 2)) { if(pkt_len > (count - 2)) { - err("Packet length too long for USB frame (pkt_len: %x, count: %x)",pkt_len, count); - err("Packet len & 2047: %x", pkt_len & 2047); - err("Count 2: %x", count2); + kaweth_err("Packet length too long for USB frame (pkt_len: %x, count: %x)",pkt_len, count); + kaweth_err("Packet len & 2047: %x", pkt_len & 2047); + kaweth_err("Count 2: %x", count2); kaweth_resubmit_rx_urb(kaweth, GFP_ATOMIC); return; } @@ -659,7 +655,7 @@ static int kaweth_open(struct net_device *net) struct kaweth_device *kaweth = netdev_priv(net); int res; - dbg("Opening network device."); + kaweth_dbg("Opening network device."); res = kaweth_resubmit_rx_urb(kaweth, GFP_KERNEL); if (res) @@ -682,7 +678,6 @@ static int kaweth_open(struct net_device *net) usb_kill_urb(kaweth->rx_urb); return -EIO; } - kaweth->opened = 1; netif_start_queue(net); @@ -693,8 +688,14 @@ static int kaweth_open(struct net_device *net) /**************************************************************** * kaweth_close ****************************************************************/ -static void kaweth_kill_urbs(struct kaweth_device *kaweth) +static int kaweth_close(struct net_device *net) { + struct kaweth_device *kaweth = netdev_priv(net); + + netif_stop_queue(net); + + kaweth->status |= KAWETH_STATUS_CLOSING; + usb_kill_urb(kaweth->irq_urb); usb_kill_urb(kaweth->rx_urb); usb_kill_urb(kaweth->tx_urb); @@ -705,21 +706,6 @@ static void kaweth_kill_urbs(struct kaweth_device *kaweth) we hit them again */ usb_kill_urb(kaweth->irq_urb); usb_kill_urb(kaweth->rx_urb); -} - -/**************************************************************** - * kaweth_close - ****************************************************************/ -static int kaweth_close(struct net_device *net) -{ - struct kaweth_device *kaweth = netdev_priv(net); - - netif_stop_queue(net); - kaweth->opened = 0; - - kaweth->status |= KAWETH_STATUS_CLOSING; - - kaweth_kill_urbs(kaweth); kaweth->status &= ~KAWETH_STATUS_CLOSING; @@ -739,14 +725,14 @@ static struct ethtool_ops ops = { /**************************************************************** * kaweth_usb_transmit_complete ****************************************************************/ -static void kaweth_usb_transmit_complete(struct urb *urb) +static void kaweth_usb_transmit_complete(struct urb *urb, struct pt_regs *regs) { struct kaweth_device *kaweth = urb->context; struct sk_buff *skb = kaweth->tx_skb; if (unlikely(urb->status != 0)) if (urb->status != -ENOENT) - dbg("%s: TX status %d.", kaweth->net->name, urb->status); + kaweth_dbg("%s: TX status %d.", kaweth->net->name, urb->status); netif_wake_queue(kaweth->net); dev_kfree_skb_irq(skb); @@ -766,9 +752,6 @@ static int kaweth_start_xmit(struct sk_buff *skb, struct net_device *net) kaweth_async_set_rx_mode(kaweth); netif_stop_queue(net); - if (IS_BLOCKED(kaweth->status)) { - goto skip; - } /* We now decide whether we can put our special header into the sk_buff */ if (skb_cloned(skb) || skb_headroom(skb) < 2) { @@ -800,8 +783,7 @@ static int kaweth_start_xmit(struct sk_buff *skb, struct net_device *net) if((res = usb_submit_urb(kaweth->tx_urb, GFP_ATOMIC))) { - warn("kaweth failed tx_urb %d", res); -skip: + kaweth_warn("kaweth failed tx_urb %d", res); kaweth->stats.tx_errors++; netif_start_queue(net); @@ -830,7 +812,7 @@ static void kaweth_set_rx_mode(struct net_device *net) KAWETH_PACKET_FILTER_BROADCAST | KAWETH_PACKET_FILTER_MULTICAST; - dbg("Setting Rx mode to %d", packet_filter_bitmap); + kaweth_dbg("Setting Rx mode to %d", packet_filter_bitmap); netif_stop_queue(net); @@ -868,10 +850,10 @@ static void kaweth_async_set_rx_mode(struct kaweth_device *kaweth) KAWETH_CONTROL_TIMEOUT); if(result < 0) { - err("Failed to set Rx mode: %d", result); + kaweth_err("Failed to set Rx mode: %d", result); } else { - dbg("Set Rx mode to %d", packet_filter_bitmap); + kaweth_dbg("Set Rx mode to %d", packet_filter_bitmap); } } } @@ -892,49 +874,13 @@ static void kaweth_tx_timeout(struct net_device *net) { struct kaweth_device *kaweth = netdev_priv(net); - warn("%s: Tx timed out. Resetting.", net->name); + kaweth_warn("%s: Tx timed out. Resetting.", net->name); kaweth->stats.tx_errors++; net->trans_start = jiffies; usb_unlink_urb(kaweth->tx_urb); } -/**************************************************************** - * kaweth_suspend - ****************************************************************/ -static int kaweth_suspend(struct usb_interface *intf, pm_message_t message) -{ - struct kaweth_device *kaweth = usb_get_intfdata(intf); - unsigned long flags; - - spin_lock_irqsave(&kaweth->device_lock, flags); - kaweth->status |= KAWETH_STATUS_SUSPENDING; - spin_unlock_irqrestore(&kaweth->device_lock, flags); - - kaweth_kill_urbs(kaweth); - return 0; -} - -/**************************************************************** - * kaweth_resume - ****************************************************************/ -static int kaweth_resume(struct usb_interface *intf) -{ - struct kaweth_device *kaweth = usb_get_intfdata(intf); - unsigned long flags; - - spin_lock_irqsave(&kaweth->device_lock, flags); - kaweth->status &= ~KAWETH_STATUS_SUSPENDING; - spin_unlock_irqrestore(&kaweth->device_lock, flags); - - if (!kaweth->opened) - return 0; - kaweth_resubmit_rx_urb(kaweth, GFP_NOIO); - kaweth_resubmit_int_urb(kaweth, GFP_NOIO); - - return 0; -} - /**************************************************************** * kaweth_probe ****************************************************************/ @@ -949,15 +895,15 @@ static int kaweth_probe( const eth_addr_t bcast_addr = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; int result = 0; - dbg("Kawasaki Device Probe (Device number:%d): 0x%4.4x:0x%4.4x:0x%4.4x", + kaweth_dbg("Kawasaki Device Probe (Device number:%d): 0x%4.4x:0x%4.4x:0x%4.4x", dev->devnum, le16_to_cpu(dev->descriptor.idVendor), le16_to_cpu(dev->descriptor.idProduct), le16_to_cpu(dev->descriptor.bcdDevice)); - dbg("Device at %p", dev); + kaweth_dbg("Device at %p", dev); - dbg("Descriptor length: %x type: %x", + kaweth_dbg("Descriptor length: %x type: %x", (int)dev->descriptor.bLength, (int)dev->descriptor.bDescriptorType); @@ -972,7 +918,7 @@ static int kaweth_probe( spin_lock_init(&kaweth->device_lock); init_waitqueue_head(&kaweth->term_wait); - dbg("Resetting."); + kaweth_dbg("Resetting."); kaweth_reset(kaweth); @@ -982,17 +928,17 @@ static int kaweth_probe( */ if (le16_to_cpu(dev->descriptor.bcdDevice) >> 8) { - info("Firmware present in device."); + kaweth_info("Firmware present in device."); } else { /* Download the firmware */ - info("Downloading firmware..."); + kaweth_info("Downloading firmware..."); kaweth->firmware_buf = (__u8 *)__get_free_page(GFP_KERNEL); if ((result = kaweth_download_firmware(kaweth, kaweth_new_code, len_kaweth_new_code, 100, 2)) < 0) { - err("Error downloading firmware (%d)", result); + kaweth_err("Error downloading firmware (%d)", result); goto err_fw; } @@ -1001,7 +947,7 @@ static int kaweth_probe( len_kaweth_new_code_fix, 100, 3)) < 0) { - err("Error downloading firmware fix (%d)", result); + kaweth_err("Error downloading firmware fix (%d)", result); goto err_fw; } @@ -1010,7 +956,7 @@ static int kaweth_probe( len_kaweth_trigger_code, 126, 2)) < 0) { - err("Error downloading trigger code (%d)", result); + kaweth_err("Error downloading trigger code (%d)", result); goto err_fw; } @@ -1020,18 +966,18 @@ static int kaweth_probe( len_kaweth_trigger_code_fix, 126, 3)) < 0) { - err("Error downloading trigger code fix (%d)", result); + kaweth_err("Error downloading trigger code fix (%d)", result); goto err_fw; } if ((result = kaweth_trigger_firmware(kaweth, 126)) < 0) { - err("Error triggering firmware (%d)", result); + kaweth_err("Error triggering firmware (%d)", result); goto err_fw; } /* Device will now disappear for a moment... */ - info("Firmware loaded. I'll be back..."); + kaweth_info("Firmware loaded. I'll be back..."); err_fw: free_page((unsigned long)kaweth->firmware_buf); free_netdev(netdev); @@ -1041,14 +987,14 @@ static int kaweth_probe( result = kaweth_read_configuration(kaweth); if(result < 0) { - err("Error reading configuration (%d), no net device created", result); + kaweth_err("Error reading configuration (%d), no net device created", result); goto err_free_netdev; } - info("Statistics collection: %x", kaweth->configuration.statistics_mask); - info("Multicast filter limit: %x", kaweth->configuration.max_multicast_filters & ((1 << 15) - 1)); - info("MTU: %d", le16_to_cpu(kaweth->configuration.segment_size)); - info("Read MAC address %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x", + kaweth_info("Statistics collection: %x", kaweth->configuration.statistics_mask); + kaweth_info("Multicast filter limit: %x", kaweth->configuration.max_multicast_filters & ((1 << 15) - 1)); + kaweth_info("MTU: %d", le16_to_cpu(kaweth->configuration.segment_size)); + kaweth_info("Read MAC address %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x", (int)kaweth->configuration.hw_addr[0], (int)kaweth->configuration.hw_addr[1], (int)kaweth->configuration.hw_addr[2], @@ -1059,17 +1005,17 @@ static int kaweth_probe( if(!memcmp(&kaweth->configuration.hw_addr, &bcast_addr, sizeof(bcast_addr))) { - err("Firmware not functioning properly, no net device created"); + kaweth_err("Firmware not functioning properly, no net device created"); goto err_free_netdev; } if(kaweth_set_urb_size(kaweth, KAWETH_BUF_SIZE) < 0) { - dbg("Error setting URB size"); + kaweth_dbg("Error setting URB size"); goto err_free_netdev; } if(kaweth_set_sofs_wait(kaweth, KAWETH_SOFS_TO_WAIT) < 0) { - err("Error setting SOFS wait"); + kaweth_err("Error setting SOFS wait"); goto err_free_netdev; } @@ -1079,11 +1025,11 @@ static int kaweth_probe( KAWETH_PACKET_FILTER_MULTICAST); if(result < 0) { - err("Error setting receive filter"); + kaweth_err("Error setting receive filter"); goto err_free_netdev; } - dbg("Initializing net device."); + kaweth_dbg("Initializing net device."); kaweth->tx_urb = usb_alloc_urb(0, GFP_KERNEL); if (!kaweth->tx_urb) @@ -1140,13 +1086,13 @@ static int kaweth_probe( SET_NETDEV_DEV(netdev, &intf->dev); if (register_netdev(netdev) != 0) { - err("Error registering netdev."); + kaweth_err("Error registering netdev."); goto err_intfdata; } - info("kaweth interface created at %s", kaweth->net->name); + kaweth_info("kaweth interface created at %s", kaweth->net->name); - dbg("Kaweth probe returning."); + kaweth_dbg("Kaweth probe returning."); return 0; @@ -1175,16 +1121,16 @@ static void kaweth_disconnect(struct usb_interface *intf) struct kaweth_device *kaweth = usb_get_intfdata(intf); struct net_device *netdev; - info("Unregistering"); + kaweth_info("Unregistering"); usb_set_intfdata(intf, NULL); if (!kaweth) { - warn("unregistering non-existant device"); + kaweth_warn("unregistering non-existant device"); return; } netdev = kaweth->net; - dbg("Unregistering net device"); + kaweth_dbg("Unregistering net device"); unregister_netdev(netdev); usb_free_urb(kaweth->rx_urb); @@ -1208,7 +1154,7 @@ struct usb_api_data { /*-------------------------------------------------------------------* * completion handler for compatibility wrappers (sync control/bulk) * *-------------------------------------------------------------------*/ -static void usb_api_blocking_completion(struct urb *urb) +static void usb_api_blocking_completion(struct urb *urb, struct pt_regs *regs) { struct usb_api_data *awd = (struct usb_api_data *)urb->context; @@ -1239,7 +1185,7 @@ static int usb_start_wait_urb(struct urb *urb, int timeout, int* actual_length) if (!wait_event_timeout(awd.wqh, awd.done, timeout)) { // timeout - warn("usb_control/bulk_msg: timeout"); + kaweth_warn("usb_control/bulk_msg: timeout"); usb_kill_urb(urb); // remove urb safely status = -ETIMEDOUT; } @@ -1288,7 +1234,7 @@ static int kaweth_internal_control_msg(struct usb_device *usb_dev, ****************************************************************/ static int __init kaweth_init(void) { - dbg("Driver loading"); + kaweth_dbg("Driver loading"); return usb_register(&kaweth_driver); } diff --git a/trunk/drivers/usb/net/mcs7830.c b/trunk/drivers/usb/net/mcs7830.c deleted file mode 100644 index 6240b978fe3d..000000000000 --- a/trunk/drivers/usb/net/mcs7830.c +++ /dev/null @@ -1,534 +0,0 @@ -/* - * MosChips MCS7830 based USB 2.0 Ethernet Devices - * - * based on usbnet.c, asix.c and the vendor provided mcs7830 driver - * - * Copyright (C) 2006 Arnd Bergmann - * Copyright (C) 2003-2005 David Hollis - * Copyright (C) 2005 Phil Chang - * Copyright (c) 2002-2003 TiVo Inc. - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "usbnet.h" - -/* requests */ -#define MCS7830_RD_BMREQ (USB_DIR_IN | USB_TYPE_VENDOR | \ - USB_RECIP_DEVICE) -#define MCS7830_WR_BMREQ (USB_DIR_OUT | USB_TYPE_VENDOR | \ - USB_RECIP_DEVICE) -#define MCS7830_RD_BREQ 0x0E -#define MCS7830_WR_BREQ 0x0D - -#define MCS7830_CTRL_TIMEOUT 1000 -#define MCS7830_MAX_MCAST 64 - -#define MCS7830_VENDOR_ID 0x9710 -#define MCS7830_PRODUCT_ID 0x7830 - -#define MCS7830_MII_ADVERTISE (ADVERTISE_PAUSE_CAP | ADVERTISE_100FULL | \ - ADVERTISE_100HALF | ADVERTISE_10FULL | \ - ADVERTISE_10HALF | ADVERTISE_CSMA) - -/* HIF_REG_XX coressponding index value */ -enum { - HIF_REG_MULTICAST_HASH = 0x00, - HIF_REG_PACKET_GAP1 = 0x08, - HIF_REG_PACKET_GAP2 = 0x09, - HIF_REG_PHY_DATA = 0x0a, - HIF_REG_PHY_CMD1 = 0x0c, - HIF_REG_PHY_CMD1_READ = 0x40, - HIF_REG_PHY_CMD1_WRITE = 0x20, - HIF_REG_PHY_CMD1_PHYADDR = 0x01, - HIF_REG_PHY_CMD2 = 0x0d, - HIF_REG_PHY_CMD2_PEND_FLAG_BIT = 0x80, - HIF_REG_PHY_CMD2_READY_FLAG_BIT = 0x40, - HIF_REG_CONFIG = 0x0e, - HIF_REG_CONFIG_CFG = 0x80, - HIF_REG_CONFIG_SPEED100 = 0x40, - HIF_REG_CONFIG_FULLDUPLEX_ENABLE = 0x20, - HIF_REG_CONFIG_RXENABLE = 0x10, - HIF_REG_CONFIG_TXENABLE = 0x08, - HIF_REG_CONFIG_SLEEPMODE = 0x04, - HIF_REG_CONFIG_ALLMULTICAST = 0x02, - HIF_REG_CONFIG_PROMISCIOUS = 0x01, - HIF_REG_ETHERNET_ADDR = 0x0f, - HIF_REG_22 = 0x15, - HIF_REG_PAUSE_THRESHOLD = 0x16, - HIF_REG_PAUSE_THRESHOLD_DEFAULT = 0, -}; - -struct mcs7830_data { - u8 multi_filter[8]; - u8 config; -}; - -static const char driver_name[] = "MOSCHIP usb-ethernet driver"; - -static int mcs7830_get_reg(struct usbnet *dev, u16 index, u16 size, void *data) -{ - struct usb_device *xdev = dev->udev; - int ret; - - ret = usb_control_msg(xdev, usb_rcvctrlpipe(xdev, 0), MCS7830_RD_BREQ, - MCS7830_RD_BMREQ, 0x0000, index, data, - size, msecs_to_jiffies(MCS7830_CTRL_TIMEOUT)); - return ret; -} - -static int mcs7830_set_reg(struct usbnet *dev, u16 index, u16 size, void *data) -{ - struct usb_device *xdev = dev->udev; - int ret; - - ret = usb_control_msg(xdev, usb_sndctrlpipe(xdev, 0), MCS7830_WR_BREQ, - MCS7830_WR_BMREQ, 0x0000, index, data, - size, msecs_to_jiffies(MCS7830_CTRL_TIMEOUT)); - return ret; -} - -static void mcs7830_async_cmd_callback(struct urb *urb) -{ - struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context; - - if (urb->status < 0) - printk(KERN_DEBUG "mcs7830_async_cmd_callback() failed with %d", - urb->status); - - kfree(req); - usb_free_urb(urb); -} - -static void mcs7830_set_reg_async(struct usbnet *dev, u16 index, u16 size, void *data) -{ - struct usb_ctrlrequest *req; - int ret; - struct urb *urb; - - urb = usb_alloc_urb(0, GFP_ATOMIC); - if (!urb) { - dev_dbg(&dev->udev->dev, "Error allocating URB " - "in write_cmd_async!"); - return; - } - - req = kmalloc(sizeof *req, GFP_ATOMIC); - if (!req) { - dev_err(&dev->udev->dev, "Failed to allocate memory for " - "control request"); - goto out; - } - req->bRequestType = MCS7830_WR_BMREQ; - req->bRequest = MCS7830_WR_BREQ; - req->wValue = 0; - req->wIndex = cpu_to_le16(index); - req->wLength = cpu_to_le16(size); - - usb_fill_control_urb(urb, dev->udev, - usb_sndctrlpipe(dev->udev, 0), - (void *)req, data, size, - mcs7830_async_cmd_callback, req); - - ret = usb_submit_urb(urb, GFP_ATOMIC); - if (ret < 0) { - dev_err(&dev->udev->dev, "Error submitting the control " - "message: ret=%d", ret); - goto out; - } - return; -out: - kfree(req); - usb_free_urb(urb); -} - -static int mcs7830_get_address(struct usbnet *dev) -{ - int ret; - ret = mcs7830_get_reg(dev, HIF_REG_ETHERNET_ADDR, ETH_ALEN, - dev->net->dev_addr); - if (ret < 0) - return ret; - return 0; -} - -static int mcs7830_read_phy(struct usbnet *dev, u8 index) -{ - int ret; - int i; - __le16 val; - - u8 cmd[2] = { - HIF_REG_PHY_CMD1_READ | HIF_REG_PHY_CMD1_PHYADDR, - HIF_REG_PHY_CMD2_PEND_FLAG_BIT | index, - }; - - mutex_lock(&dev->phy_mutex); - /* write the MII command */ - ret = mcs7830_set_reg(dev, HIF_REG_PHY_CMD1, 2, cmd); - if (ret < 0) - goto out; - - /* wait for the data to become valid, should be within < 1ms */ - for (i = 0; i < 10; i++) { - ret = mcs7830_get_reg(dev, HIF_REG_PHY_CMD1, 2, cmd); - if ((ret < 0) || (cmd[1] & HIF_REG_PHY_CMD2_READY_FLAG_BIT)) - break; - ret = -EIO; - msleep(1); - } - if (ret < 0) - goto out; - - /* read actual register contents */ - ret = mcs7830_get_reg(dev, HIF_REG_PHY_DATA, 2, &val); - if (ret < 0) - goto out; - ret = le16_to_cpu(val); - dev_dbg(&dev->udev->dev, "read PHY reg %02x: %04x (%d tries)\n", - index, val, i); -out: - mutex_unlock(&dev->phy_mutex); - return ret; -} - -static int mcs7830_write_phy(struct usbnet *dev, u8 index, u16 val) -{ - int ret; - int i; - __le16 le_val; - - u8 cmd[2] = { - HIF_REG_PHY_CMD1_WRITE | HIF_REG_PHY_CMD1_PHYADDR, - HIF_REG_PHY_CMD2_PEND_FLAG_BIT | (index & 0x1F), - }; - - mutex_lock(&dev->phy_mutex); - - /* write the new register contents */ - le_val = cpu_to_le16(val); - ret = mcs7830_set_reg(dev, HIF_REG_PHY_DATA, 2, &le_val); - if (ret < 0) - goto out; - - /* write the MII command */ - ret = mcs7830_set_reg(dev, HIF_REG_PHY_CMD1, 2, cmd); - if (ret < 0) - goto out; - - /* wait for the command to be accepted by the PHY */ - for (i = 0; i < 10; i++) { - ret = mcs7830_get_reg(dev, HIF_REG_PHY_CMD1, 2, cmd); - if ((ret < 0) || (cmd[1] & HIF_REG_PHY_CMD2_READY_FLAG_BIT)) - break; - ret = -EIO; - msleep(1); - } - if (ret < 0) - goto out; - - ret = 0; - dev_dbg(&dev->udev->dev, "write PHY reg %02x: %04x (%d tries)\n", - index, val, i); -out: - mutex_unlock(&dev->phy_mutex); - return ret; -} - -/* - * This algorithm comes from the original mcs7830 version 1.4 driver, - * not sure if it is needed. - */ -static int mcs7830_set_autoneg(struct usbnet *dev, int ptrUserPhyMode) -{ - int ret; - /* Enable all media types */ - ret = mcs7830_write_phy(dev, MII_ADVERTISE, MCS7830_MII_ADVERTISE); - - /* First reset BMCR */ - if (!ret) - ret = mcs7830_write_phy(dev, MII_BMCR, 0x0000); - /* Enable Auto Neg */ - if (!ret) - ret = mcs7830_write_phy(dev, MII_BMCR, BMCR_ANENABLE); - /* Restart Auto Neg (Keep the Enable Auto Neg Bit Set) */ - if (!ret) - ret = mcs7830_write_phy(dev, MII_BMCR, - BMCR_ANENABLE | BMCR_ANRESTART ); - return ret < 0 ? : 0; -} - - -/* - * if we can read register 22, the chip revision is C or higher - */ -static int mcs7830_get_rev(struct usbnet *dev) -{ - u8 dummy[2]; - int ret; - ret = mcs7830_get_reg(dev, HIF_REG_22, 2, dummy); - if (ret > 0) - return 2; /* Rev C or later */ - return 1; /* earlier revision */ -} - -/* - * On rev. C we need to set the pause threshold - */ -static void mcs7830_rev_C_fixup(struct usbnet *dev) -{ - u8 pause_threshold = HIF_REG_PAUSE_THRESHOLD_DEFAULT; - int retry; - - for (retry = 0; retry < 2; retry++) { - if (mcs7830_get_rev(dev) == 2) { - dev_info(&dev->udev->dev, "applying rev.C fixup\n"); - mcs7830_set_reg(dev, HIF_REG_PAUSE_THRESHOLD, - 1, &pause_threshold); - } - msleep(1); - } -} - -static int mcs7830_init_dev(struct usbnet *dev) -{ - int ret; - int retry; - - /* Read MAC address from EEPROM */ - ret = -EINVAL; - for (retry = 0; retry < 5 && ret; retry++) - ret = mcs7830_get_address(dev); - if (ret) { - dev_warn(&dev->udev->dev, "Cannot read MAC address\n"); - goto out; - } - - /* Set up PHY */ - ret = mcs7830_set_autoneg(dev, 0); - if (ret) { - dev_info(&dev->udev->dev, "Cannot set autoneg\n"); - goto out; - } - - mcs7830_rev_C_fixup(dev); - ret = 0; -out: - return ret; -} - -static int mcs7830_mdio_read(struct net_device *netdev, int phy_id, - int location) -{ - struct usbnet *dev = netdev->priv; - return mcs7830_read_phy(dev, location); -} - -static void mcs7830_mdio_write(struct net_device *netdev, int phy_id, - int location, int val) -{ - struct usbnet *dev = netdev->priv; - mcs7830_write_phy(dev, location, val); -} - -static int mcs7830_ioctl(struct net_device *net, struct ifreq *rq, int cmd) -{ - struct usbnet *dev = netdev_priv(net); - return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL); -} - -/* credits go to asix_set_multicast */ -static void mcs7830_set_multicast(struct net_device *net) -{ - struct usbnet *dev = netdev_priv(net); - struct mcs7830_data *data = (struct mcs7830_data *)&dev->data; - - data->config = HIF_REG_CONFIG_TXENABLE; - - /* this should not be needed, but it doesn't work otherwise */ - data->config |= HIF_REG_CONFIG_ALLMULTICAST; - - if (net->flags & IFF_PROMISC) { - data->config |= HIF_REG_CONFIG_PROMISCIOUS; - } else if (net->flags & IFF_ALLMULTI - || net->mc_count > MCS7830_MAX_MCAST) { - data->config |= HIF_REG_CONFIG_ALLMULTICAST; - } else if (net->mc_count == 0) { - /* just broadcast and directed */ - } else { - /* We use the 20 byte dev->data - * for our 8 byte filter buffer - * to avoid allocating memory that - * is tricky to free later */ - struct dev_mc_list *mc_list = net->mc_list; - u32 crc_bits; - int i; - - memset(data->multi_filter, 0, sizeof data->multi_filter); - - /* Build the multicast hash filter. */ - for (i = 0; i < net->mc_count; i++) { - crc_bits = ether_crc(ETH_ALEN, mc_list->dmi_addr) >> 26; - data->multi_filter[crc_bits >> 3] |= 1 << (crc_bits & 7); - mc_list = mc_list->next; - } - - mcs7830_set_reg_async(dev, HIF_REG_MULTICAST_HASH, - sizeof data->multi_filter, - data->multi_filter); - } - - mcs7830_set_reg_async(dev, HIF_REG_CONFIG, 1, &data->config); -} - -static int mcs7830_get_regs_len(struct net_device *net) -{ - struct usbnet *dev = netdev_priv(net); - - switch (mcs7830_get_rev(dev)) { - case 1: - return 21; - case 2: - return 32; - } - return 0; -} - -static void mcs7830_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *drvinfo) -{ - usbnet_get_drvinfo(net, drvinfo); - drvinfo->regdump_len = mcs7830_get_regs_len(net); -} - -static void mcs7830_get_regs(struct net_device *net, struct ethtool_regs *regs, void *data) -{ - struct usbnet *dev = netdev_priv(net); - - regs->version = mcs7830_get_rev(dev); - mcs7830_get_reg(dev, 0, regs->len, data); -} - -static struct ethtool_ops mcs7830_ethtool_ops = { - .get_drvinfo = mcs7830_get_drvinfo, - .get_regs_len = mcs7830_get_regs_len, - .get_regs = mcs7830_get_regs, - - /* common usbnet calls */ - .get_link = usbnet_get_link, - .get_msglevel = usbnet_get_msglevel, - .set_msglevel = usbnet_set_msglevel, - .get_settings = usbnet_get_settings, - .set_settings = usbnet_set_settings, - .nway_reset = usbnet_nway_reset, -}; - -static int mcs7830_bind(struct usbnet *dev, struct usb_interface *udev) -{ - struct net_device *net = dev->net; - int ret; - - ret = mcs7830_init_dev(dev); - if (ret) - goto out; - - net->do_ioctl = mcs7830_ioctl; - net->ethtool_ops = &mcs7830_ethtool_ops; - net->set_multicast_list = mcs7830_set_multicast; - mcs7830_set_multicast(net); - - /* reserve space for the status byte on rx */ - dev->rx_urb_size = ETH_FRAME_LEN + 1; - - dev->mii.mdio_read = mcs7830_mdio_read; - dev->mii.mdio_write = mcs7830_mdio_write; - dev->mii.dev = net; - dev->mii.phy_id_mask = 0x3f; - dev->mii.reg_num_mask = 0x1f; - dev->mii.phy_id = *((u8 *) net->dev_addr + 1); - - ret = usbnet_get_endpoints(dev, udev); -out: - return ret; -} - -/* The chip always appends a status bytes that we need to strip */ -static int mcs7830_rx_fixup(struct usbnet *dev, struct sk_buff *skb) -{ - u8 status; - - if (skb->len == 0) { - dev_err(&dev->udev->dev, "unexpected empty rx frame\n"); - return 0; - } - - skb_trim(skb, skb->len - 1); - status = skb->data[skb->len]; - - if (status != 0x20) - dev_dbg(&dev->udev->dev, "rx fixup status %x\n", status); - - return skb->len > 0; -} - -static const struct driver_info moschip_info = { - .description = "MOSCHIP 7830 usb-NET adapter", - .bind = mcs7830_bind, - .rx_fixup = mcs7830_rx_fixup, - .flags = FLAG_ETHER, - .in = 1, - .out = 2, -}; - -static const struct usb_device_id products[] = { - { - USB_DEVICE(MCS7830_VENDOR_ID, MCS7830_PRODUCT_ID), - .driver_info = (unsigned long) &moschip_info, - }, - {}, -}; -MODULE_DEVICE_TABLE(usb, products); - -static struct usb_driver mcs7830_driver = { - .name = driver_name, - .id_table = products, - .probe = usbnet_probe, - .disconnect = usbnet_disconnect, - .suspend = usbnet_suspend, - .resume = usbnet_resume, -}; - -static int __init mcs7830_init(void) -{ - return usb_register(&mcs7830_driver); -} -module_init(mcs7830_init); - -static void __exit mcs7830_exit(void) -{ - usb_deregister(&mcs7830_driver); -} -module_exit(mcs7830_exit); - -MODULE_DESCRIPTION("USB to network adapter MCS7830)"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/usb/net/net1080.c b/trunk/drivers/usb/net/net1080.c index a77410562e12..301baa72bac7 100644 --- a/trunk/drivers/usb/net/net1080.c +++ b/trunk/drivers/usb/net/net1080.c @@ -237,12 +237,12 @@ static inline void nc_dump_usbctl(struct usbnet *dev, u16 usbctl) #define STATUS_CONN_OTHER (1 << 14) #define STATUS_SUSPEND_OTHER (1 << 13) #define STATUS_MAILBOX_OTHER (1 << 12) -#define STATUS_PACKETS_OTHER(n) (((n) >> 8) & 0x03) +#define STATUS_PACKETS_OTHER(n) (((n) >> 8) && 0x03) #define STATUS_CONN_THIS (1 << 6) #define STATUS_SUSPEND_THIS (1 << 5) #define STATUS_MAILBOX_THIS (1 << 4) -#define STATUS_PACKETS_THIS(n) (((n) >> 0) & 0x03) +#define STATUS_PACKETS_THIS(n) (((n) >> 0) && 0x03) #define STATUS_UNSPEC_MASK 0x0c8c #define STATUS_NOISE_MASK ((u16)~(0x0303|STATUS_UNSPEC_MASK)) @@ -368,7 +368,7 @@ static int net1080_check_connect(struct usbnet *dev) return 0; } -static void nc_flush_complete(struct urb *urb) +static void nc_flush_complete(struct urb *urb, struct pt_regs *regs) { kfree(urb->context); usb_free_urb(urb); diff --git a/trunk/drivers/usb/net/pegasus.c b/trunk/drivers/usb/net/pegasus.c index 69eb0db399df..918cf5a77c08 100644 --- a/trunk/drivers/usb/net/pegasus.c +++ b/trunk/drivers/usb/net/pegasus.c @@ -96,7 +96,7 @@ MODULE_DEVICE_TABLE(usb, pegasus_ids); static int update_eth_regs_async(pegasus_t *); /* Aargh!!! I _really_ hate such tweaks */ -static void ctrl_callback(struct urb *urb) +static void ctrl_callback(struct urb *urb, struct pt_regs *regs) { pegasus_t *pegasus = urb->context; @@ -163,7 +163,6 @@ static int get_registers(pegasus_t * pegasus, __u16 indx, __u16 size, /* using ATOMIC, we'd never wake up if we slept */ if ((ret = usb_submit_urb(pegasus->ctrl_urb, GFP_ATOMIC))) { - set_current_state(TASK_RUNNING); if (ret == -ENODEV) netif_device_detach(pegasus->net); if (netif_msg_drv(pegasus)) @@ -606,7 +605,7 @@ static inline struct sk_buff *pull_skb(pegasus_t * pegasus) return NULL; } -static void read_bulk_callback(struct urb *urb) +static void read_bulk_callback(struct urb *urb, struct pt_regs *regs) { pegasus_t *pegasus = urb->context; struct net_device *net; @@ -765,7 +764,7 @@ static void rx_fixup(unsigned long data) spin_unlock_irqrestore(&pegasus->rx_pool_lock, flags); } -static void write_bulk_callback(struct urb *urb) +static void write_bulk_callback(struct urb *urb, struct pt_regs *regs) { pegasus_t *pegasus = urb->context; struct net_device *net = pegasus->net; @@ -802,7 +801,7 @@ static void write_bulk_callback(struct urb *urb) netif_wake_queue(net); } -static void intr_callback(struct urb *urb) +static void intr_callback(struct urb *urb, struct pt_regs *regs) { pegasus_t *pegasus = urb->context; struct net_device *net; @@ -1227,7 +1226,7 @@ static void pegasus_set_multicast(struct net_device *net) } pegasus->flags |= ETH_REGS_CHANGE; - ctrl_callback(pegasus->ctrl_urb); + ctrl_callback(pegasus->ctrl_urb, NULL); } static __u8 mii_phy_probe(pegasus_t * pegasus) @@ -1434,11 +1433,11 @@ static int pegasus_resume (struct usb_interface *intf) if (netif_running(pegasus->net)) { pegasus->rx_urb->status = 0; pegasus->rx_urb->actual_length = 0; - read_bulk_callback(pegasus->rx_urb); + read_bulk_callback(pegasus->rx_urb, NULL); pegasus->intr_urb->status = 0; pegasus->intr_urb->actual_length = 0; - intr_callback(pegasus->intr_urb); + intr_callback(pegasus->intr_urb, NULL); } queue_delayed_work(pegasus_workqueue, &pegasus->carrier_check, CARRIER_CHECK_DELAY); diff --git a/trunk/drivers/usb/net/rtl8150.c b/trunk/drivers/usb/net/rtl8150.c index 72171f94ded4..2364c2099387 100644 --- a/trunk/drivers/usb/net/rtl8150.c +++ b/trunk/drivers/usb/net/rtl8150.c @@ -208,7 +208,7 @@ static int set_registers(rtl8150_t * dev, u16 indx, u16 size, void *data) indx, 0, data, size, 500); } -static void ctrl_callback(struct urb *urb) +static void ctrl_callback(struct urb *urb, struct pt_regs *regs) { rtl8150_t *dev; @@ -415,7 +415,7 @@ static inline struct sk_buff *pull_skb(rtl8150_t *dev) return NULL; } -static void read_bulk_callback(struct urb *urb) +static void read_bulk_callback(struct urb *urb, struct pt_regs *regs) { rtl8150_t *dev; unsigned pkt_len, res; @@ -525,7 +525,7 @@ static void rx_fixup(unsigned long data) tasklet_schedule(&dev->tl); } -static void write_bulk_callback(struct urb *urb) +static void write_bulk_callback(struct urb *urb, struct pt_regs *regs) { rtl8150_t *dev; @@ -541,7 +541,7 @@ static void write_bulk_callback(struct urb *urb) netif_wake_queue(dev->netdev); } -static void intr_callback(struct urb *urb) +static void intr_callback(struct urb *urb, struct pt_regs *regs) { rtl8150_t *dev; __u8 *d; @@ -617,11 +617,11 @@ static int rtl8150_resume(struct usb_interface *intf) if (netif_running(dev->netdev)) { dev->rx_urb->status = 0; dev->rx_urb->actual_length = 0; - read_bulk_callback(dev->rx_urb); + read_bulk_callback(dev->rx_urb, NULL); dev->intr_urb->status = 0; dev->intr_urb->actual_length = 0; - intr_callback(dev->intr_urb); + intr_callback(dev->intr_urb, NULL); } return 0; } diff --git a/trunk/drivers/usb/net/usbnet.c b/trunk/drivers/usb/net/usbnet.c index 7672e11c94c4..98a522f1e264 100644 --- a/trunk/drivers/usb/net/usbnet.c +++ b/trunk/drivers/usb/net/usbnet.c @@ -116,7 +116,7 @@ int usbnet_get_endpoints(struct usbnet *dev, struct usb_interface *intf) e = alt->endpoint + ep; switch (e->desc.bmAttributes) { case USB_ENDPOINT_XFER_INT: - if (!usb_endpoint_dir_in(&e->desc)) + if (!(e->desc.bEndpointAddress & USB_DIR_IN)) continue; intr = 1; /* FALLTHROUGH */ @@ -125,7 +125,7 @@ int usbnet_get_endpoints(struct usbnet *dev, struct usb_interface *intf) default: continue; } - if (usb_endpoint_dir_in(&e->desc)) { + if (e->desc.bEndpointAddress & USB_DIR_IN) { if (!intr && !in) in = e; else if (intr && !status) @@ -158,7 +158,7 @@ int usbnet_get_endpoints(struct usbnet *dev, struct usb_interface *intf) } EXPORT_SYMBOL_GPL(usbnet_get_endpoints); -static void intr_complete (struct urb *urb); +static void intr_complete (struct urb *urb, struct pt_regs *regs); static int init_status (struct usbnet *dev, struct usb_interface *intf) { @@ -295,7 +295,7 @@ EXPORT_SYMBOL_GPL(usbnet_defer_kevent); /*-------------------------------------------------------------------------*/ -static void rx_complete (struct urb *urb); +static void rx_complete (struct urb *urb, struct pt_regs *regs); static void rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags) { @@ -383,7 +383,7 @@ static inline void rx_process (struct usbnet *dev, struct sk_buff *skb) /*-------------------------------------------------------------------------*/ -static void rx_complete (struct urb *urb) +static void rx_complete (struct urb *urb, struct pt_regs *regs) { struct sk_buff *skb = (struct sk_buff *) urb->context; struct skb_data *entry = (struct skb_data *) skb->cb; @@ -467,7 +467,7 @@ static void rx_complete (struct urb *urb) devdbg (dev, "no read resubmitted"); } -static void intr_complete (struct urb *urb) +static void intr_complete (struct urb *urb, struct pt_regs *regs) { struct usbnet *dev = urb->context; int status = urb->status; @@ -554,7 +554,7 @@ static int usbnet_stop (struct net_device *net) { struct usbnet *dev = netdev_priv(net); int temp; - DECLARE_WAIT_QUEUE_HEAD_ONSTACK (unlink_wakeup); + DECLARE_WAIT_QUEUE_HEAD (unlink_wakeup); DECLARE_WAITQUEUE (wait, current); netif_stop_queue (net); @@ -669,40 +669,20 @@ static int usbnet_open (struct net_device *net) * they'll probably want to use this base set. */ -#if defined(CONFIG_MII) || defined(CONFIG_MII_MODULE) -#define HAVE_MII - -int usbnet_get_settings (struct net_device *net, struct ethtool_cmd *cmd) -{ - struct usbnet *dev = netdev_priv(net); - - if (!dev->mii.mdio_read) - return -EOPNOTSUPP; - - return mii_ethtool_gset(&dev->mii, cmd); -} -EXPORT_SYMBOL_GPL(usbnet_get_settings); - -int usbnet_set_settings (struct net_device *net, struct ethtool_cmd *cmd) +void usbnet_get_drvinfo (struct net_device *net, struct ethtool_drvinfo *info) { struct usbnet *dev = netdev_priv(net); - int retval; - - if (!dev->mii.mdio_write) - return -EOPNOTSUPP; - - retval = mii_ethtool_sset(&dev->mii, cmd); - - /* link speed/duplex might have changed */ - if (dev->driver_info->link_reset) - dev->driver_info->link_reset(dev); - - return retval; + /* REVISIT don't always return "usbnet" */ + strncpy (info->driver, driver_name, sizeof info->driver); + strncpy (info->version, DRIVER_VERSION, sizeof info->version); + strncpy (info->fw_version, dev->driver_info->description, + sizeof info->fw_version); + usb_make_path (dev->udev, info->bus_info, sizeof info->bus_info); } -EXPORT_SYMBOL_GPL(usbnet_set_settings); +EXPORT_SYMBOL_GPL(usbnet_get_drvinfo); -u32 usbnet_get_link (struct net_device *net) +static u32 usbnet_get_link (struct net_device *net) { struct usbnet *dev = netdev_priv(net); @@ -710,40 +690,9 @@ u32 usbnet_get_link (struct net_device *net) if (dev->driver_info->check_connect) return dev->driver_info->check_connect (dev) == 0; - /* if the device has mii operations, use those */ - if (dev->mii.mdio_read) - return mii_link_ok(&dev->mii); - /* Otherwise, say we're up (to avoid breaking scripts) */ return 1; } -EXPORT_SYMBOL_GPL(usbnet_get_link); - -int usbnet_nway_reset(struct net_device *net) -{ - struct usbnet *dev = netdev_priv(net); - - if (!dev->mii.mdio_write) - return -EOPNOTSUPP; - - return mii_nway_restart(&dev->mii); -} -EXPORT_SYMBOL_GPL(usbnet_nway_reset); - -#endif /* HAVE_MII */ - -void usbnet_get_drvinfo (struct net_device *net, struct ethtool_drvinfo *info) -{ - struct usbnet *dev = netdev_priv(net); - - /* REVISIT don't always return "usbnet" */ - strncpy (info->driver, driver_name, sizeof info->driver); - strncpy (info->version, DRIVER_VERSION, sizeof info->version); - strncpy (info->fw_version, dev->driver_info->description, - sizeof info->fw_version); - usb_make_path (dev->udev, info->bus_info, sizeof info->bus_info); -} -EXPORT_SYMBOL_GPL(usbnet_get_drvinfo); u32 usbnet_get_msglevel (struct net_device *net) { @@ -763,13 +712,8 @@ EXPORT_SYMBOL_GPL(usbnet_set_msglevel); /* drivers may override default ethtool_ops in their bind() routine */ static struct ethtool_ops usbnet_ethtool_ops = { -#ifdef HAVE_MII - .get_settings = usbnet_get_settings, - .set_settings = usbnet_set_settings, - .get_link = usbnet_get_link, - .nway_reset = usbnet_nway_reset, -#endif .get_drvinfo = usbnet_get_drvinfo, + .get_link = usbnet_get_link, .get_msglevel = usbnet_get_msglevel, .set_msglevel = usbnet_set_msglevel, }; @@ -853,7 +797,7 @@ kevent (void *data) /*-------------------------------------------------------------------------*/ -static void tx_complete (struct urb *urb) +static void tx_complete (struct urb *urb, struct pt_regs *regs) { struct sk_buff *skb = (struct sk_buff *) urb->context; struct skb_data *entry = (struct skb_data *) skb->cb; @@ -1150,7 +1094,6 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) dev->delay.function = usbnet_bh; dev->delay.data = (unsigned long) dev; init_timer (&dev->delay); - mutex_init (&dev->phy_mutex); SET_MODULE_OWNER (net); dev->net = net; @@ -1282,7 +1225,7 @@ EXPORT_SYMBOL_GPL(usbnet_resume); static int __init usbnet_init(void) { /* compiler should optimize this out */ - BUILD_BUG_ON (sizeof (((struct sk_buff *)0)->cb) + BUG_ON (sizeof (((struct sk_buff *)0)->cb) < sizeof (struct skb_data)); random_ether_addr(node_id); diff --git a/trunk/drivers/usb/net/usbnet.h b/trunk/drivers/usb/net/usbnet.h index 07c70abbe0ec..c0746f0454af 100644 --- a/trunk/drivers/usb/net/usbnet.h +++ b/trunk/drivers/usb/net/usbnet.h @@ -30,7 +30,6 @@ struct usbnet { struct usb_device *udev; struct driver_info *driver_info; wait_queue_head_t *wait; - struct mutex phy_mutex; /* i/o info: pipes etc */ unsigned in, out; @@ -169,13 +168,9 @@ extern void usbnet_defer_kevent (struct usbnet *, int); extern void usbnet_skb_return (struct usbnet *, struct sk_buff *); extern void usbnet_unlink_rx_urbs(struct usbnet *); -extern int usbnet_get_settings (struct net_device *net, struct ethtool_cmd *cmd); -extern int usbnet_set_settings (struct net_device *net, struct ethtool_cmd *cmd); -extern u32 usbnet_get_link (struct net_device *net); extern u32 usbnet_get_msglevel (struct net_device *); extern void usbnet_set_msglevel (struct net_device *, u32); extern void usbnet_get_drvinfo (struct net_device *, struct ethtool_drvinfo *); -extern int usbnet_nway_reset(struct net_device *net); /* messaging support includes the interface name, so it must not be * used before it has one ... notably, in minidriver bind() calls. diff --git a/trunk/drivers/usb/serial/Kconfig b/trunk/drivers/usb/serial/Kconfig index 2f4d303ee36f..5076b9d97057 100644 --- a/trunk/drivers/usb/serial/Kconfig +++ b/trunk/drivers/usb/serial/Kconfig @@ -54,10 +54,10 @@ config USB_SERIAL_GENERIC properly. config USB_SERIAL_AIRCABLE - tristate "USB AIRcable Bluetooth Dongle Driver (EXPERIMENTAL)" + tristate "AIRcable USB Bluetooth Dongle Driver (EXPERIMENTAL)" depends on USB_SERIAL && EXPERIMENTAL help - Say Y here if you want to use USB AIRcable Bluetooth Dongle. + Say Y here if you want to use AIRcable USB Bluetoot Dongle. To compile this driver as a module, choose M here: the module will be called aircable. @@ -422,16 +422,6 @@ config USB_SERIAL_MCT_U232 To compile this driver as a module, choose M here: the module will be called mct_u232. -config USB_SERIAL_MOS7720 - tristate "USB Moschip 7720 Single Port Serial Driver" - depends on USB_SERIAL - ---help--- - Say Y here if you want to use a USB Serial single port adapter from - Moschip Semiconductor Tech. - - To compile this driver as a module, choose M here: the - module will be called mos7720. - config USB_SERIAL_MOS7840 tristate "USB Moschip 7840/7820 USB Serial Driver" depends on USB_SERIAL @@ -537,7 +527,8 @@ config USB_SERIAL_OPTION The USB bus on these cards is not accessible externally. Supported devices include (some of?) those made by: - Option, Huawei, Audiovox, Novatel Wireless, or Anydata. + Option, Huawei, Audiovox, Sierra Wireless, Novatel Wireless, or + Anydata. To compile this driver as a module, choose M here: the module will be called option. @@ -554,17 +545,6 @@ config USB_SERIAL_OMNINET To compile this driver as a module, choose M here: the module will be called omninet. -config USB_SERIAL_DEBUG - tristate "USB Debugging Device" - depends on USB_SERIAL - help - Say Y here if you have a USB debugging device used to recieve - debugging data from another machine. The most common of these - devices is the NetChip TurboCONNECT device. - - To compile this driver as a module, choose M here: the - module will be called usb-debug. - config USB_EZUSB bool depends on USB_SERIAL_KEYSPAN_PDA || USB_SERIAL_XIRCOM || USB_SERIAL_KEYSPAN || USB_SERIAL_WHITEHEAT diff --git a/trunk/drivers/usb/serial/Makefile b/trunk/drivers/usb/serial/Makefile index 61166ad450e6..8dce83340e31 100644 --- a/trunk/drivers/usb/serial/Makefile +++ b/trunk/drivers/usb/serial/Makefile @@ -18,7 +18,6 @@ obj-$(CONFIG_USB_SERIAL_BELKIN) += belkin_sa.o obj-$(CONFIG_USB_SERIAL_CP2101) += cp2101.o obj-$(CONFIG_USB_SERIAL_CYBERJACK) += cyberjack.o obj-$(CONFIG_USB_SERIAL_CYPRESS_M8) += cypress_m8.o -obj-$(CONFIG_USB_SERIAL_DEBUG) += usb_debug.o obj-$(CONFIG_USB_SERIAL_DIGI_ACCELEPORT) += digi_acceleport.o obj-$(CONFIG_USB_SERIAL_EDGEPORT) += io_edgeport.o obj-$(CONFIG_USB_SERIAL_EDGEPORT_TI) += io_ti.o @@ -35,7 +34,6 @@ obj-$(CONFIG_USB_SERIAL_KEYSPAN_PDA) += keyspan_pda.o obj-$(CONFIG_USB_SERIAL_KLSI) += kl5kusb105.o obj-$(CONFIG_USB_SERIAL_KOBIL_SCT) += kobil_sct.o obj-$(CONFIG_USB_SERIAL_MCT_U232) += mct_u232.o -obj-$(CONFIG_USB_SERIAL_MOS7720) += mos7720.o obj-$(CONFIG_USB_SERIAL_MOS7840) += mos7840.o obj-$(CONFIG_USB_SERIAL_NAVMAN) += navman.o obj-$(CONFIG_USB_SERIAL_OMNINET) += omninet.o diff --git a/trunk/drivers/usb/serial/aircable.c b/trunk/drivers/usb/serial/aircable.c index b1b5707bc99a..2ccd9ded52a5 100644 --- a/trunk/drivers/usb/serial/aircable.c +++ b/trunk/drivers/usb/serial/aircable.c @@ -270,11 +270,8 @@ static void aircable_read(void *params) */ tty = port->tty; - if (!tty) { + if (!tty) schedule_work(&priv->rx_work); - err("%s - No tty available", __FUNCTION__); - return ; - } count = min(64, serial_buf_data_avail(priv->rx_buf)); @@ -308,7 +305,9 @@ static int aircable_probe(struct usb_serial *serial, for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) { endpoint = &iface_desc->endpoint[i].desc; - if (usb_endpoint_is_bulk_out(endpoint)) { + if (((endpoint->bEndpointAddress & 0x80) == 0x00) && + ((endpoint->bmAttributes & 3) == 0x02)) { + /* we found our bulk out endpoint */ dbg("found bulk out on endpoint %d", i); ++num_bulk_out; } @@ -404,7 +403,7 @@ static int aircable_write(struct usb_serial_port *port, } -static void aircable_write_bulk_callback(struct urb *urb) +static void aircable_write_bulk_callback(struct urb *urb, struct pt_regs *regs) { struct usb_serial_port *port = urb->context; int result; @@ -445,7 +444,7 @@ static void aircable_write_bulk_callback(struct urb *urb) aircable_send(port); } -static void aircable_read_bulk_callback(struct urb *urb) +static void aircable_read_bulk_callback(struct urb *urb, struct pt_regs *regs) { struct usb_serial_port *port = urb->context; struct aircable_private *priv = usb_get_serial_port_data(port); diff --git a/trunk/drivers/usb/serial/airprime.c b/trunk/drivers/usb/serial/airprime.c index 96c73726d74a..6e1a84a858d4 100644 --- a/trunk/drivers/usb/serial/airprime.c +++ b/trunk/drivers/usb/serial/airprime.c @@ -18,9 +18,12 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(0x0c88, 0x17da) }, /* Kyocera Wireless KPC650/Passport */ + { USB_DEVICE(0x0f3d, 0x0112) }, /* AirPrime CDMA Wireless PC Card */ + { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ + { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */ + { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless Aircard 580 */ + { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ { USB_DEVICE(0x1410, 0x1110) }, /* Novatel Wireless Merlin CDMA */ - { USB_DEVICE(0x1410, 0x1430) }, /* Novatel Merlin XU870 HSDPA/3G */ - { USB_DEVICE(0x1410, 0x1100) }, /* ExpressCard34 Qualcomm 3G CDMA */ { }, }; MODULE_DEVICE_TABLE(usb, id_table); @@ -43,7 +46,7 @@ struct airprime_private { struct urb *read_urbp[NUM_READ_URBS]; }; -static void airprime_read_bulk_callback(struct urb *urb) +static void airprime_read_bulk_callback(struct urb *urb, struct pt_regs *regs) { struct usb_serial_port *port = urb->context; unsigned char *data = urb->transfer_buffer; @@ -77,7 +80,7 @@ static void airprime_read_bulk_callback(struct urb *urb) return; } -static void airprime_write_bulk_callback(struct urb *urb) +static void airprime_write_bulk_callback(struct urb *urb, struct pt_regs *regs) { struct usb_serial_port *port = urb->context; struct airprime_private *priv = usb_get_serial_port_data(port); @@ -130,7 +133,6 @@ static int airprime_open(struct usb_serial_port *port, struct file *filp) } urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) { - kfree(buffer); dev_err(&port->dev, "%s - no more urbs?\n", __FUNCTION__); result = -ENOMEM; diff --git a/trunk/drivers/usb/serial/ark3116.c b/trunk/drivers/usb/serial/ark3116.c index 863966c1c5ac..ca52f12f0e24 100644 --- a/trunk/drivers/usb/serial/ark3116.c +++ b/trunk/drivers/usb/serial/ark3116.c @@ -85,9 +85,10 @@ static int ark3116_attach(struct usb_serial *serial) int i; for (i = 0; i < serial->num_ports; ++i) { - priv = kzalloc(sizeof(struct ark3116_private), GFP_KERNEL); + priv = kmalloc(sizeof (struct ark3116_private), GFP_KERNEL); if (!priv) goto cleanup; + memset(priv, 0x00, sizeof (struct ark3116_private)); spin_lock_init(&priv->lock); usb_set_serial_port_data(serial->port[i], priv); diff --git a/trunk/drivers/usb/serial/belkin_sa.c b/trunk/drivers/usb/serial/belkin_sa.c index 8835bb58ca9b..70ece9e01ce4 100644 --- a/trunk/drivers/usb/serial/belkin_sa.c +++ b/trunk/drivers/usb/serial/belkin_sa.c @@ -91,7 +91,7 @@ static int belkin_sa_startup (struct usb_serial *serial); static void belkin_sa_shutdown (struct usb_serial *serial); static int belkin_sa_open (struct usb_serial_port *port, struct file *filp); static void belkin_sa_close (struct usb_serial_port *port, struct file *filp); -static void belkin_sa_read_int_callback (struct urb *urb); +static void belkin_sa_read_int_callback (struct urb *urb, struct pt_regs *regs); static void belkin_sa_set_termios (struct usb_serial_port *port, struct termios * old); static int belkin_sa_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg); static void belkin_sa_break_ctl (struct usb_serial_port *port, int break_state ); @@ -248,7 +248,7 @@ static void belkin_sa_close (struct usb_serial_port *port, struct file *filp) } /* belkin_sa_close */ -static void belkin_sa_read_int_callback (struct urb *urb) +static void belkin_sa_read_int_callback (struct urb *urb, struct pt_regs *regs) { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; struct belkin_sa_private *priv; diff --git a/trunk/drivers/usb/serial/console.c b/trunk/drivers/usb/serial/console.c index 7167728d764c..3a9073dbfe6a 100644 --- a/trunk/drivers/usb/serial/console.c +++ b/trunk/drivers/usb/serial/console.c @@ -166,17 +166,19 @@ static int usb_console_setup(struct console *co, char *options) if (serial->type->set_termios) { /* build up a fake tty structure so that the open call has something * to look at to get the cflag value */ - tty = kzalloc(sizeof(*tty), GFP_KERNEL); + tty = kmalloc (sizeof (*tty), GFP_KERNEL); if (!tty) { err ("no more memory"); return -ENOMEM; } - termios = kzalloc(sizeof(*termios), GFP_KERNEL); + termios = kmalloc (sizeof (*termios), GFP_KERNEL); if (!termios) { err ("no more memory"); kfree (tty); return -ENOMEM; } + memset (tty, 0x00, sizeof(*tty)); + memset (termios, 0x00, sizeof(*termios)); termios->c_cflag = cflag; tty->termios = termios; port->tty = tty; diff --git a/trunk/drivers/usb/serial/cp2101.c b/trunk/drivers/usb/serial/cp2101.c index f95d42c0d16a..486c7411b9a7 100644 --- a/trunk/drivers/usb/serial/cp2101.c +++ b/trunk/drivers/usb/serial/cp2101.c @@ -64,11 +64,7 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(0x10C4, 0x80F6) }, /* Suunto sports instrument */ { USB_DEVICE(0x10C4, 0x813D) }, /* Burnside Telecom Deskmobile */ { USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */ - { USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */ - { USB_DEVICE(0x10C4, 0x81E2) }, /* Lipowsky Industrie Elektronik GmbH, Baby-LIN */ - { USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */ { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ - { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ { USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */ { } /* Terminating Entry */ }; diff --git a/trunk/drivers/usb/serial/cyberjack.c b/trunk/drivers/usb/serial/cyberjack.c index a63c3286caa0..d954ec34b018 100644 --- a/trunk/drivers/usb/serial/cyberjack.c +++ b/trunk/drivers/usb/serial/cyberjack.c @@ -63,9 +63,9 @@ static int cyberjack_open (struct usb_serial_port *port, struct file *filp); static void cyberjack_close (struct usb_serial_port *port, struct file *filp); static int cyberjack_write (struct usb_serial_port *port, const unsigned char *buf, int count); static int cyberjack_write_room( struct usb_serial_port *port ); -static void cyberjack_read_int_callback (struct urb *urb); -static void cyberjack_read_bulk_callback (struct urb *urb); -static void cyberjack_write_bulk_callback (struct urb *urb); +static void cyberjack_read_int_callback (struct urb *urb, struct pt_regs *regs); +static void cyberjack_read_bulk_callback (struct urb *urb, struct pt_regs *regs); +static void cyberjack_write_bulk_callback (struct urb *urb, struct pt_regs *regs); static struct usb_device_id id_table [] = { { USB_DEVICE(CYBERJACK_VENDOR_ID, CYBERJACK_PRODUCT_ID) }, @@ -299,7 +299,7 @@ static int cyberjack_write_room( struct usb_serial_port *port ) return CYBERJACK_LOCAL_BUF_SIZE; } -static void cyberjack_read_int_callback( struct urb *urb ) +static void cyberjack_read_int_callback( struct urb *urb, struct pt_regs *regs ) { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; struct cyberjack_private *priv = usb_get_serial_port_data(port); @@ -356,7 +356,7 @@ static void cyberjack_read_int_callback( struct urb *urb ) dbg("%s - usb_submit_urb(int urb)", __FUNCTION__); } -static void cyberjack_read_bulk_callback (struct urb *urb) +static void cyberjack_read_bulk_callback (struct urb *urb, struct pt_regs *regs) { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; struct cyberjack_private *priv = usb_get_serial_port_data(port); @@ -406,7 +406,7 @@ static void cyberjack_read_bulk_callback (struct urb *urb) } } -static void cyberjack_write_bulk_callback (struct urb *urb) +static void cyberjack_write_bulk_callback (struct urb *urb, struct pt_regs *regs) { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; struct cyberjack_private *priv = usb_get_serial_port_data(port); diff --git a/trunk/drivers/usb/serial/cypress_m8.c b/trunk/drivers/usb/serial/cypress_m8.c index 093f303b3189..e1173c1aee37 100644 --- a/trunk/drivers/usb/serial/cypress_m8.c +++ b/trunk/drivers/usb/serial/cypress_m8.c @@ -172,8 +172,8 @@ static int cypress_chars_in_buffer (struct usb_serial_port *port); static void cypress_throttle (struct usb_serial_port *port); static void cypress_unthrottle (struct usb_serial_port *port); static void cypress_set_dead (struct usb_serial_port *port); -static void cypress_read_int_callback (struct urb *urb); -static void cypress_write_int_callback (struct urb *urb); +static void cypress_read_int_callback (struct urb *urb, struct pt_regs *regs); +static void cypress_write_int_callback (struct urb *urb, struct pt_regs *regs); /* baud helper functions */ static int mask_to_rate (unsigned mask); static unsigned rate_to_mask (int rate); @@ -1275,7 +1275,7 @@ static void cypress_unthrottle (struct usb_serial_port *port) } -static void cypress_read_int_callback(struct urb *urb) +static void cypress_read_int_callback(struct urb *urb, struct pt_regs *regs) { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; struct cypress_private *priv = usb_get_serial_port_data(port); @@ -1426,7 +1426,7 @@ static void cypress_read_int_callback(struct urb *urb) } /* cypress_read_int_callback */ -static void cypress_write_int_callback(struct urb *urb) +static void cypress_write_int_callback(struct urb *urb, struct pt_regs *regs) { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; struct cypress_private *priv = usb_get_serial_port_data(port); @@ -1684,14 +1684,15 @@ static int __init cypress_init(void) info(DRIVER_DESC " " DRIVER_VERSION); return 0; - failed_usb_register: - usb_serial_deregister(&cypress_ca42v2_device); + usb_deregister(&cypress_driver); failed_ca42v2_register: - usb_serial_deregister(&cypress_hidcom_device); + usb_serial_deregister(&cypress_ca42v2_device); failed_hidcom_register: - usb_serial_deregister(&cypress_earthmate_device); + usb_serial_deregister(&cypress_hidcom_device); failed_em_register: + usb_serial_deregister(&cypress_earthmate_device); + return retval; } diff --git a/trunk/drivers/usb/serial/digi_acceleport.c b/trunk/drivers/usb/serial/digi_acceleport.c index 5e3ac281a2f8..9b225183fc7a 100644 --- a/trunk/drivers/usb/serial/digi_acceleport.c +++ b/trunk/drivers/usb/serial/digi_acceleport.c @@ -157,7 +157,7 @@ * to TASK_RUNNING will be lost and write_chan's subsequent call to * schedule() will never return (unless it catches a signal). * This race condition occurs because write_bulk_callback() (and thus -* the wakeup) are called asynchronously from an interrupt, rather than +* the wakeup) are called asynchonously from an interrupt, rather than * from the scheduler. We can avoid the race by calling the wakeup * from the scheduler queue and that's our fix: Now, at the end of * write_bulk_callback() we queue up a wakeup call on the scheduler @@ -456,7 +456,7 @@ static int digi_tiocmget( struct usb_serial_port *port, struct file *file ); static int digi_tiocmset( struct usb_serial_port *port, struct file *file, unsigned int set, unsigned int clear ); static int digi_write( struct usb_serial_port *port, const unsigned char *buf, int count ); -static void digi_write_bulk_callback( struct urb *urb ); +static void digi_write_bulk_callback( struct urb *urb, struct pt_regs *regs ); static int digi_write_room( struct usb_serial_port *port ); static int digi_chars_in_buffer( struct usb_serial_port *port ); static int digi_open( struct usb_serial_port *port, struct file *filp ); @@ -464,7 +464,7 @@ static void digi_close( struct usb_serial_port *port, struct file *filp ); static int digi_startup_device( struct usb_serial *serial ); static int digi_startup( struct usb_serial *serial ); static void digi_shutdown( struct usb_serial *serial ); -static void digi_read_bulk_callback( struct urb *urb ); +static void digi_read_bulk_callback( struct urb *urb, struct pt_regs *regs ); static int digi_read_inb_callback( struct urb *urb ); static int digi_read_oob_callback( struct urb *urb ); @@ -1336,7 +1336,7 @@ dbg( "digi_write: returning %d", ret ); } -static void digi_write_bulk_callback( struct urb *urb ) +static void digi_write_bulk_callback( struct urb *urb, struct pt_regs *regs ) { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; @@ -1754,7 +1754,7 @@ dbg( "digi_shutdown: TOP, in_interrupt()=%ld", in_interrupt() ); } -static void digi_read_bulk_callback( struct urb *urb ) +static void digi_read_bulk_callback( struct urb *urb, struct pt_regs *regs ) { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; diff --git a/trunk/drivers/usb/serial/empeg.c b/trunk/drivers/usb/serial/empeg.c index 4ce10a831953..daafe405d86d 100644 --- a/trunk/drivers/usb/serial/empeg.c +++ b/trunk/drivers/usb/serial/empeg.c @@ -93,8 +93,8 @@ static int empeg_ioctl (struct usb_serial_port *port, unsigned int cmd, unsigned long arg); static void empeg_set_termios (struct usb_serial_port *port, struct termios *old_termios); -static void empeg_write_bulk_callback (struct urb *urb); -static void empeg_read_bulk_callback (struct urb *urb); +static void empeg_write_bulk_callback (struct urb *urb, struct pt_regs *regs); +static void empeg_read_bulk_callback (struct urb *urb, struct pt_regs *regs); static struct usb_device_id id_table [] = { { USB_DEVICE(EMPEG_VENDOR_ID, EMPEG_PRODUCT_ID) }, @@ -323,7 +323,7 @@ static int empeg_chars_in_buffer (struct usb_serial_port *port) } -static void empeg_write_bulk_callback (struct urb *urb) +static void empeg_write_bulk_callback (struct urb *urb, struct pt_regs *regs) { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; @@ -338,7 +338,7 @@ static void empeg_write_bulk_callback (struct urb *urb) } -static void empeg_read_bulk_callback (struct urb *urb) +static void empeg_read_bulk_callback (struct urb *urb, struct pt_regs *regs) { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; struct tty_struct *tty; diff --git a/trunk/drivers/usb/serial/ezusb.c b/trunk/drivers/usb/serial/ezusb.c index 97ee718b1da2..5169c2d154ab 100644 --- a/trunk/drivers/usb/serial/ezusb.c +++ b/trunk/drivers/usb/serial/ezusb.c @@ -31,11 +31,12 @@ int ezusb_writememory (struct usb_serial *serial, int address, unsigned char *da return -ENODEV; } - transfer_buffer = kmemdup(data, length, GFP_KERNEL); + transfer_buffer = kmalloc (length, GFP_KERNEL); if (!transfer_buffer) { dev_err(&serial->dev->dev, "%s - kmalloc(%d) failed.\n", __FUNCTION__, length); return -ENOMEM; } + memcpy (transfer_buffer, data, length); result = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0), bRequest, 0x40, address, 0, transfer_buffer, length, 3000); kfree (transfer_buffer); return result; diff --git a/trunk/drivers/usb/serial/ftdi_sio.c b/trunk/drivers/usb/serial/ftdi_sio.c index 89ce2775be15..e774a27c6c98 100644 --- a/trunk/drivers/usb/serial/ftdi_sio.c +++ b/trunk/drivers/usb/serial/ftdi_sio.c @@ -1,16 +1,16 @@ /* * USB FTDI SIO driver * - * Copyright (C) 1999 - 2001 - * Greg Kroah-Hartman (greg@kroah.com) + * Copyright (C) 1999 - 2001 + * Greg Kroah-Hartman (greg@kroah.com) * Bill Ryder (bryder@sgi.com) * Copyright (C) 2002 * Kuba Ober (kuba@mareimbrium.org) * - * 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 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. * * See Documentation/usb/usb-serial.txt for more information on using this driver * @@ -32,7 +32,7 @@ * Changed full name of USB-UIRT device to avoid "/" character. * Added FTDI's alternate PID (0x6006) for FT232/245 devices. * Added PID for "ELV USB Module UO100" from Stefan Frings. - * + * * (21/Oct/2003) Ian Abbott * Renamed some VID/PID macros for Matrix Orbital and Perle Systems * devices. Removed Matrix Orbital and Perle Systems devices from the @@ -69,7 +69,7 @@ * does not incure any measurable overhead. This also relies on the fact * that we have proper reference counting logic for urbs. I nicked this * from Greg KH's Visor driver. - * + * * (23/Jun/2003) Ian Abbott * Reduced flip buffer pushes and corrected a data length test in * ftdi_read_bulk_callback. @@ -77,7 +77,7 @@ * * (21/Jun/2003) Erik Nygren * Added support for Home Electronics Tira-1 IR transceiver using FT232BM chip. - * See . Only operates properly + * See . Only operates properly * at 100000 and RTS-CTS, so set custom divisor mode on startup. * Also force the Tira-1 and USB-UIRT to only use their custom baud rates. * @@ -137,17 +137,17 @@ * (17/Feb/2003) Bill Ryder * Added write urb buffer pool on a per device basis * Added more checking for open file on callbacks (fixed OOPS) - * Added CrystalFontz 632 and 634 PIDs + * Added CrystalFontz 632 and 634 PIDs * (thanx to CrystalFontz for the sample devices - they flushed out * some driver bugs) * Minor debugging message changes * Added throttle, unthrottle and chars_in_buffer functions * Fixed FTDI_SIO (the original device) bug * Fixed some shutdown handling - * - * - * - * + * + * + * + * * (07/Jun/2002) Kuba Ober * Changed FTDI_SIO_BASE_BAUD_TO_DIVISOR macro into ftdi_baud_to_divisor * function. It was getting too complex. @@ -158,7 +158,7 @@ * * (25/Jul/2002) Bill Ryder inserted Dmitri's TIOCMIWAIT patch * Not tested by me but it doesn't break anything I use. - * + * * (04/Jan/2002) Kuba Ober * Implemented 38400 baudrate kludge, where it can be substituted with other * values. That's the only way to set custom baudrates. @@ -179,7 +179,7 @@ * (the previous version caused panics) * Removed port iteration code since the device only has one I/O port and it * was wrong anyway. - * + * * (31/May/2001) gkh * Switched from using spinlock to a semaphore, which fixes lots of problems. * @@ -188,16 +188,16 @@ * Cleaned up comments for 8U232 * Added parity, framing and overrun error handling * Added receive break handling. - * + * * (04/08/2001) gb * Identify version on module load. - * + * * (18/March/2001) Bill Ryder * (Not released) * Added send break handling. (requires kernel patch too) * Fixed 8U232AM hardware RTS/CTS etc status reporting. * Added flipbuf fix copied from generic device - * + * * (12/3/2000) Bill Ryder * Added support for 8U232AM device. * Moved PID and VIDs into header file only. @@ -211,14 +211,14 @@ * Cleaned up comments. Removed multiple PID/VID definitions. * Factorised cts/dtr code * Made use of __FUNCTION__ in dbg's - * + * * (11/01/2000) Adam J. Richter * usb_device_id table support - * + * * (10/05/2000) gkh * Fixed bug with urb->dev not being set properly, now that the usb * core needs it. - * + * * (09/11/2000) gkh * Removed DEBUG #ifdefs with call to usb_serial_debug_data * @@ -226,11 +226,11 @@ * Added module_init and module_exit functions to handle the fact that this * driver is a loadable module now. * - * (04/04/2000) Bill Ryder + * (04/04/2000) Bill Ryder * Fixed bugs in TCGET/TCSET ioctls (by removing them - they are * handled elsewhere in the tty io driver chain). * - * (03/30/2000) Bill Ryder + * (03/30/2000) Bill Ryder * Implemented lots of ioctls * Fixed a race condition in write * Changed some dbg's to errs @@ -311,7 +311,6 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_ACTZWAVE_PID) }, { USB_DEVICE(FTDI_VID, FTDI_IRTRANS_PID) }, { USB_DEVICE(FTDI_VID, FTDI_IPLUS_PID) }, - { USB_DEVICE(FTDI_VID, FTDI_DMX4ALL) }, { USB_DEVICE(FTDI_VID, FTDI_SIO_PID) }, { USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) }, { USB_DEVICE(FTDI_VID, FTDI_8U232AM_ALT_PID) }, @@ -445,13 +444,13 @@ static struct usb_device_id id_table_combined [] = { /* { USB_DEVICE(FTDI_VID, FTDI_ELV_WS300PC_PID) }, */ /* { USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1300PC_PID) }, */ /* { USB_DEVICE(FTDI_VID, FTDI_ELV_WS500_PID) }, */ - { USB_DEVICE(FTDI_VID, LINX_SDMUSBQSS_PID) }, - { USB_DEVICE(FTDI_VID, LINX_MASTERDEVEL2_PID) }, - { USB_DEVICE(FTDI_VID, LINX_FUTURE_0_PID) }, - { USB_DEVICE(FTDI_VID, LINX_FUTURE_1_PID) }, - { USB_DEVICE(FTDI_VID, LINX_FUTURE_2_PID) }, - { USB_DEVICE(FTDI_VID, FTDI_CCSICDU20_0_PID) }, - { USB_DEVICE(FTDI_VID, FTDI_CCSICDU40_1_PID) }, + { USB_DEVICE(FTDI_VID, LINX_SDMUSBQSS_PID) }, + { USB_DEVICE(FTDI_VID, LINX_MASTERDEVEL2_PID) }, + { USB_DEVICE(FTDI_VID, LINX_FUTURE_0_PID) }, + { USB_DEVICE(FTDI_VID, LINX_FUTURE_1_PID) }, + { USB_DEVICE(FTDI_VID, LINX_FUTURE_2_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_CCSICDU20_0_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_CCSICDU40_1_PID) }, { USB_DEVICE(FTDI_VID, INSIDE_ACCESSO) }, { USB_DEVICE(INTREPID_VID, INTREPID_VALUECAN_PID) }, { USB_DEVICE(INTREPID_VID, INTREPID_NEOVI_PID) }, @@ -512,7 +511,6 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13M_PID) }, { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13S_PID) }, { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13U_PID) }, - { USB_DEVICE(ELEKTOR_VID, ELEKTOR_FT323R_PID) }, { }, /* Optional parameter entry */ { } /* Terminating entry */ }; @@ -524,7 +522,7 @@ static struct usb_driver ftdi_driver = { .probe = usb_serial_probe, .disconnect = usb_serial_disconnect, .id_table = id_table_combined, - .no_dynamic_id = 1, + .no_dynamic_id = 1, }; static const char *ftdi_chip_name[] = { @@ -550,13 +548,13 @@ struct ftdi_private { int custom_divisor; /* custom_divisor kludge, this is for baud_base (different from what goes to the chip!) */ __u16 last_set_data_urb_value ; /* the last data state set - needed for doing a break */ - int write_offset; /* This is the offset in the usb data block to write the serial data - + int write_offset; /* This is the offset in the usb data block to write the serial data - * it is different between devices */ int flags; /* some ASYNC_xxxx flags are supported */ unsigned long last_dtr_rts; /* saved modem control outputs */ wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ - char prev_status, diff_status; /* Used for TIOCMIWAIT */ + char prev_status, diff_status; /* Used for TIOCMIWAIT */ __u8 rx_flags; /* receive state flags (throttling) */ spinlock_t rx_lock; /* spinlock for receive state */ struct work_struct rx_work; @@ -591,8 +589,8 @@ static void ftdi_close (struct usb_serial_port *port, struct file *filp); static int ftdi_write (struct usb_serial_port *port, const unsigned char *buf, int count); static int ftdi_write_room (struct usb_serial_port *port); static int ftdi_chars_in_buffer (struct usb_serial_port *port); -static void ftdi_write_bulk_callback (struct urb *urb); -static void ftdi_read_bulk_callback (struct urb *urb); +static void ftdi_write_bulk_callback (struct urb *urb, struct pt_regs *regs); +static void ftdi_read_bulk_callback (struct urb *urb, struct pt_regs *regs); static void ftdi_process_read (void *param); static void ftdi_set_termios (struct usb_serial_port *port, struct termios * old); static int ftdi_tiocmget (struct usb_serial_port *port, struct file *file); @@ -723,7 +721,7 @@ static int update_mctrl(struct usb_serial_port *port, unsigned int set, unsigned urb_value |= FTDI_SIO_SET_RTS_HIGH; rv = usb_control_msg(port->serial->dev, usb_sndctrlpipe(port->serial->dev, 0), - FTDI_SIO_SET_MODEM_CTRL_REQUEST, + FTDI_SIO_SET_MODEM_CTRL_REQUEST, FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE, urb_value, priv->interface, buf, 0, WDR_TIMEOUT); @@ -770,7 +768,7 @@ static int change_speed(struct usb_serial_port *port) if (priv->interface) { /* FT2232C */ urb_index = (__u16)((urb_index << 8) | priv->interface); } - + rv = usb_control_msg(port->serial->dev, usb_sndctrlpipe(port->serial->dev, 0), FTDI_SIO_SET_BAUDRATE_REQUEST, @@ -829,7 +827,7 @@ static __u32 get_ftdi_divisor(struct usb_serial_port * port) /* 3. Convert baudrate to device-specific divisor */ - if (!baud) baud = 9600; + if (!baud) baud = 9600; switch(priv->chip_type) { case SIO: /* SIO chip */ switch(baud) { @@ -845,7 +843,7 @@ static __u32 get_ftdi_divisor(struct usb_serial_port * port) case 115200: div_value = ftdi_sio_b115200; break; } /* baud */ if (div_value == 0) { - dbg("%s - Baudrate (%d) requested is not supported", __FUNCTION__, baud); + dbg("%s - Baudrate (%d) requested is not supported", __FUNCTION__, baud); div_value = ftdi_sio_b9600; div_okay = 0; } @@ -927,7 +925,7 @@ static int set_serial_info(struct usb_serial_port * port, struct serial_struct _ /* Make the changes - these are privileged changes! */ priv->flags = ((priv->flags & ~ASYNC_FLAGS) | - (new_serial.flags & ASYNC_FLAGS)); + (new_serial.flags & ASYNC_FLAGS)); priv->custom_divisor = new_serial.custom_divisor; port->tty->low_latency = (priv->flags & ASYNC_LOW_LATENCY) ? 1 : 0; @@ -952,7 +950,7 @@ static int set_serial_info(struct usb_serial_port * port, struct serial_struct _ (old_priv.custom_divisor != priv->custom_divisor))) { change_speed(port); } - + return (0); } /* set_serial_info */ @@ -1024,18 +1022,18 @@ static ssize_t show_latency_timer(struct device *dev, struct device_attribute *a struct usb_device *udev; unsigned short latency = 0; int rv = 0; - + udev = to_usb_device(dev); - + dbg("%s",__FUNCTION__); - + rv = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), FTDI_SIO_GET_LATENCY_TIMER_REQUEST, FTDI_SIO_GET_LATENCY_TIMER_REQUEST_TYPE, - 0, priv->interface, + 0, priv->interface, (char*) &latency, 1, WDR_TIMEOUT); - + if (rv < 0) { dev_err(dev, "Unable to read latency timer: %i", rv); return -EIO; @@ -1053,23 +1051,23 @@ static ssize_t store_latency_timer(struct device *dev, struct device_attribute * char buf[1]; int v = simple_strtoul(valbuf, NULL, 10); int rv = 0; - + udev = to_usb_device(dev); - + dbg("%s: setting latency timer = %i", __FUNCTION__, v); - + rv = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), FTDI_SIO_SET_LATENCY_TIMER_REQUEST, FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE, - v, priv->interface, + v, priv->interface, buf, 0, WDR_TIMEOUT); - + if (rv < 0) { dev_err(dev, "Unable to write latency timer: %i", rv); return -EIO; } - + return count; } @@ -1084,23 +1082,23 @@ static ssize_t store_event_char(struct device *dev, struct device_attribute *att char buf[1]; int v = simple_strtoul(valbuf, NULL, 10); int rv = 0; - + udev = to_usb_device(dev); - + dbg("%s: setting event char = %i", __FUNCTION__, v); - + rv = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), FTDI_SIO_SET_EVENT_CHAR_REQUEST, FTDI_SIO_SET_EVENT_CHAR_REQUEST_TYPE, - v, priv->interface, + v, priv->interface, buf, 0, WDR_TIMEOUT); - + if (rv < 0) { dbg("Unable to write event character: %i", rv); return -EIO; } - + return count; } @@ -1137,11 +1135,11 @@ static void remove_sysfs_attrs(struct usb_serial *serial) struct ftdi_private *priv; struct usb_device *udev; - dbg("%s",__FUNCTION__); + dbg("%s",__FUNCTION__); priv = usb_get_serial_port_data(serial->port[0]); udev = serial->dev; - + /* XXX see create_sysfs_attrs */ if (priv->chip_type != SIO) { device_remove_file(&udev->dev, &dev_attr_event_char); @@ -1149,7 +1147,7 @@ static void remove_sysfs_attrs(struct usb_serial *serial) device_remove_file(&udev->dev, &dev_attr_latency_timer); } } - + } /* @@ -1260,7 +1258,7 @@ static void ftdi_HE_TIRA1_setup (struct usb_serial *serial) } /* ftdi_HE_TIRA1_setup */ -/* ftdi_shutdown is called from usbserial:usb_serial_disconnect +/* ftdi_shutdown is called from usbserial:usb_serial_disconnect * it is called when the usb device is disconnected * * usbserial:usb_serial_disconnect @@ -1271,16 +1269,16 @@ static void ftdi_HE_TIRA1_setup (struct usb_serial *serial) static void ftdi_shutdown (struct usb_serial *serial) { /* ftdi_shutdown */ - + struct usb_serial_port *port = serial->port[0]; struct ftdi_private *priv = usb_get_serial_port_data(port); dbg("%s", __FUNCTION__); remove_sysfs_attrs(serial); - - /* all open ports are closed at this point - * (by usbserial.c:__serial_close, which calls ftdi_close) + + /* all open ports are closed at this point + * (by usbserial.c:__serial_close, which calls ftdi_close) */ if (priv) { @@ -1295,7 +1293,7 @@ static int ftdi_open (struct usb_serial_port *port, struct file *filp) struct usb_device *dev = port->serial->dev; struct ftdi_private *priv = usb_get_serial_port_data(port); unsigned long flags; - + int result = 0; char buf[1]; /* Needed for the usb_control_msg I think */ @@ -1314,8 +1312,8 @@ static int ftdi_open (struct usb_serial_port *port, struct file *filp) /* No error checking for this (will get errors later anyway) */ /* See ftdi_sio.h for description of what is reset */ usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - FTDI_SIO_RESET_REQUEST, FTDI_SIO_RESET_REQUEST_TYPE, - FTDI_SIO_RESET_SIO, + FTDI_SIO_RESET_REQUEST, FTDI_SIO_RESET_REQUEST_TYPE, + FTDI_SIO_RESET_SIO, priv->interface, buf, 0, WDR_TIMEOUT); /* Termios defaults are set by usb_serial_init. We don't change @@ -1352,12 +1350,12 @@ static int ftdi_open (struct usb_serial_port *port, struct file *filp) -/* +/* * usbserial:__serial_close only calls ftdi_close if the point is open * * This only gets called when it is the last close - * - * + * + * */ static void ftdi_close (struct usb_serial_port *port, struct file *filp) @@ -1370,14 +1368,14 @@ static void ftdi_close (struct usb_serial_port *port, struct file *filp) if (c_cflag & HUPCL){ /* Disable flow control */ - if (usb_control_msg(port->serial->dev, + if (usb_control_msg(port->serial->dev, usb_sndctrlpipe(port->serial->dev, 0), FTDI_SIO_SET_FLOW_CTRL_REQUEST, FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, 0, priv->interface, buf, 0, WDR_TIMEOUT) < 0) { err("error from flowcontrol urb"); - } + } /* drop RTS and DTR */ clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); @@ -1386,13 +1384,14 @@ static void ftdi_close (struct usb_serial_port *port, struct file *filp) /* cancel any scheduled reading */ cancel_delayed_work(&priv->rx_work); flush_scheduled_work(); - + /* shutdown our bulk read */ - usb_kill_urb(port->read_urb); + if (port->read_urb) + usb_kill_urb(port->read_urb); } /* ftdi_close */ - + /* The SIO requires the first byte to have: * B0 1 * B1 0 @@ -1424,7 +1423,7 @@ static int ftdi_write (struct usb_serial_port *port, return 0; } spin_unlock_irqrestore(&priv->tx_lock, flags); - + data_offset = priv->write_offset; dbg("data_offset set to %d",data_offset); @@ -1463,7 +1462,7 @@ static int ftdi_write (struct usb_serial_port *port, user_pktsz = todo; } /* Write the control byte at the front of the packet*/ - *first_byte = 1 | ((user_pktsz) << 2); + *first_byte = 1 | ((user_pktsz) << 2); /* Copy data for packet */ memcpy (first_byte + data_offset, current_position, user_pktsz); @@ -1480,7 +1479,7 @@ static int ftdi_write (struct usb_serial_port *port, usb_serial_debug_data(debug, &port->dev, __FUNCTION__, transfer_size, buffer); /* fill the buffer and send it */ - usb_fill_bulk_urb(urb, port->serial->dev, + usb_fill_bulk_urb(urb, port->serial->dev, usb_sndbulkpipe(port->serial->dev, port->bulk_out_endpointAddress), buffer, transfer_size, ftdi_write_bulk_callback, port); @@ -1509,7 +1508,7 @@ static int ftdi_write (struct usb_serial_port *port, /* This function may get called when the device is closed */ -static void ftdi_write_bulk_callback (struct urb *urb) +static void ftdi_write_bulk_callback (struct urb *urb, struct pt_regs *regs) { unsigned long flags; struct usb_serial_port *port = (struct usb_serial_port *)urb->context; @@ -1521,7 +1520,7 @@ static void ftdi_write_bulk_callback (struct urb *urb) kfree (urb->transfer_buffer); dbg("%s - port %d", __FUNCTION__, port->number); - + if (urb->status) { dbg("nonzero write bulk status received: %d", urb->status); return; @@ -1592,7 +1591,7 @@ static int ftdi_chars_in_buffer (struct usb_serial_port *port) -static void ftdi_read_bulk_callback (struct urb *urb) +static void ftdi_read_bulk_callback (struct urb *urb, struct pt_regs *regs) { /* ftdi_read_bulk_callback */ struct usb_serial_port *port = (struct usb_serial_port *)urb->context; struct tty_struct *tty; @@ -1652,7 +1651,7 @@ static void ftdi_process_read (void *param) struct tty_struct *tty; struct ftdi_private *priv; char error_flag; - unsigned char *data; + unsigned char *data; int i; int result; @@ -1760,7 +1759,7 @@ static void ftdi_process_read (void *param) } if (length > 0) { for (i = 2; i < length+2; i++) { - /* Note that the error flag is duplicated for + /* Note that the error flag is duplicated for every character received since we don't know which character it applied to */ tty_insert_flip_char(tty, data[packet_offset+i], error_flag); @@ -1774,7 +1773,7 @@ static void ftdi_process_read (void *param) This doesn't work well since the application receives a never ending stream of bad data - even though new data hasn't been sent. Therefore I (bill) have taken this out. - However - this might make sense for framing errors and so on + However - this might make sense for framing errors and so on so I am leaving the code in for now. */ else { @@ -1828,7 +1827,7 @@ static void ftdi_process_read (void *param) /* if the port is closed stop trying to read */ if (port->open_count > 0){ /* Continue trying to always read */ - usb_fill_bulk_urb(port->read_urb, port->serial->dev, + usb_fill_bulk_urb(port->read_urb, port->serial->dev, usb_rcvbulkpipe(port->serial->dev, port->bulk_in_endpointAddress), port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length, ftdi_read_bulk_callback, port); @@ -1845,9 +1844,9 @@ static void ftdi_process_read (void *param) static void ftdi_break_ctl( struct usb_serial_port *port, int break_state ) { struct ftdi_private *priv = usb_get_serial_port_data(port); - __u16 urb_value = 0; + __u16 urb_value = 0; char buf[1]; - + /* break_state = -1 to turn on break, and 0 to turn off break */ /* see drivers/char/tty_io.c to see it used */ /* last_set_data_urb_value NEVER has the break bit set in it */ @@ -1855,20 +1854,20 @@ static void ftdi_break_ctl( struct usb_serial_port *port, int break_state ) if (break_state) { urb_value = priv->last_set_data_urb_value | FTDI_SIO_SET_BREAK; } else { - urb_value = priv->last_set_data_urb_value; + urb_value = priv->last_set_data_urb_value; } - + if (usb_control_msg(port->serial->dev, usb_sndctrlpipe(port->serial->dev, 0), - FTDI_SIO_SET_DATA_REQUEST, + FTDI_SIO_SET_DATA_REQUEST, FTDI_SIO_SET_DATA_REQUEST_TYPE, urb_value , priv->interface, buf, 0, WDR_TIMEOUT) < 0) { err("%s FAILED to enable/disable break state (state was %d)", __FUNCTION__,break_state); - } + } dbg("%s break state is %d - urb is %d", __FUNCTION__,break_state, urb_value); - + } @@ -1884,12 +1883,12 @@ static void ftdi_set_termios (struct usb_serial_port *port, struct termios *old_ struct ftdi_private *priv = usb_get_serial_port_data(port); __u16 urb_value; /* will hold the new flags */ char buf[1]; /* Perhaps I should dynamically alloc this? */ - + // Added for xon/xoff support unsigned int iflag = port->tty->termios->c_iflag; unsigned char vstop; unsigned char vstart; - + dbg("%s", __FUNCTION__); /* Force baud rate if this device requires it, unless it is set to B0. */ @@ -1907,20 +1906,20 @@ static void ftdi_set_termios (struct usb_serial_port *port, struct termios *old_ cflag = port->tty->termios->c_cflag; - /* FIXME -For this cut I don't care if the line is really changing or - not - so just do the change regardless - should be able to + /* FIXME -For this cut I don't care if the line is really changing or + not - so just do the change regardless - should be able to compare old_termios and tty->termios */ - /* NOTE These routines can get interrupted by - ftdi_sio_read_bulk_callback - need to examine what this + /* NOTE These routines can get interrupted by + ftdi_sio_read_bulk_callback - need to examine what this means - don't see any problems yet */ - + /* Set number of data bits, parity, stop bits */ - + urb_value = 0; urb_value |= (cflag & CSTOPB ? FTDI_SIO_SET_DATA_STOP_BITS_2 : FTDI_SIO_SET_DATA_STOP_BITS_1); - urb_value |= (cflag & PARENB ? - (cflag & PARODD ? FTDI_SIO_SET_DATA_PARITY_ODD : + urb_value |= (cflag & PARENB ? + (cflag & PARODD ? FTDI_SIO_SET_DATA_PARITY_ODD : FTDI_SIO_SET_DATA_PARITY_EVEN) : FTDI_SIO_SET_DATA_PARITY_NONE); if (cflag & CSIZE) { @@ -1937,25 +1936,25 @@ static void ftdi_set_termios (struct usb_serial_port *port, struct termios *old_ /* This is needed by the break command since it uses the same command - but is * or'ed with this value */ priv->last_set_data_urb_value = urb_value; - + if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - FTDI_SIO_SET_DATA_REQUEST, + FTDI_SIO_SET_DATA_REQUEST, FTDI_SIO_SET_DATA_REQUEST_TYPE, urb_value , priv->interface, buf, 0, WDR_SHORT_TIMEOUT) < 0) { err("%s FAILED to set databits/stopbits/parity", __FUNCTION__); - } + } /* Now do the baudrate */ if ((cflag & CBAUD) == B0 ) { /* Disable flow control */ if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - FTDI_SIO_SET_FLOW_CTRL_REQUEST, + FTDI_SIO_SET_FLOW_CTRL_REQUEST, FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, - 0, priv->interface, + 0, priv->interface, buf, 0, WDR_TIMEOUT) < 0) { err("%s error from disable flowcontrol urb", __FUNCTION__); - } + } /* Drop RTS and DTR */ clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); } else { @@ -1973,16 +1972,16 @@ static void ftdi_set_termios (struct usb_serial_port *port, struct termios *old_ /* Note device also supports DTR/CD (ugh) and Xon/Xoff in hardware */ if (cflag & CRTSCTS) { dbg("%s Setting to CRTSCTS flow control", __FUNCTION__); - if (usb_control_msg(dev, + if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - FTDI_SIO_SET_FLOW_CTRL_REQUEST, + FTDI_SIO_SET_FLOW_CTRL_REQUEST, FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, 0 , (FTDI_SIO_RTS_CTS_HS | priv->interface), buf, 0, WDR_TIMEOUT) < 0) { err("urb failed to set to rts/cts flow control"); - } - - } else { + } + + } else { /* * Xon/Xoff code * @@ -2012,16 +2011,16 @@ static void ftdi_set_termios (struct usb_serial_port *port, struct termios *old_ /* else clause to only run if cfag ! CRTSCTS and iflag ! XOFF */ /* CHECKME Assuming XON/XOFF handled by tty stack - not by device */ dbg("%s Turning off hardware flow control", __FUNCTION__); - if (usb_control_msg(dev, + if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - FTDI_SIO_SET_FLOW_CTRL_REQUEST, + FTDI_SIO_SET_FLOW_CTRL_REQUEST, FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, - 0, priv->interface, + 0, priv->interface, buf, 0, WDR_TIMEOUT) < 0) { err("urb failed to clear flow control"); - } + } } - + } return; } /* ftdi_termios */ @@ -2037,11 +2036,11 @@ static int ftdi_tiocmget (struct usb_serial_port *port, struct file *file) switch (priv->chip_type) { case SIO: /* Request the status from the device */ - if ((ret = usb_control_msg(port->serial->dev, + if ((ret = usb_control_msg(port->serial->dev, usb_rcvctrlpipe(port->serial->dev, 0), - FTDI_SIO_GET_MODEM_STATUS_REQUEST, + FTDI_SIO_GET_MODEM_STATUS_REQUEST, FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE, - 0, 0, + 0, 0, buf, 1, WDR_TIMEOUT)) < 0 ) { err("%s Could not get modem status of device - err: %d", __FUNCTION__, ret); @@ -2053,11 +2052,11 @@ static int ftdi_tiocmget (struct usb_serial_port *port, struct file *file) case FT2232C: /* the 8U232AM returns a two byte value (the sio is a 1 byte value) - in the same format as the data returned from the in point */ - if ((ret = usb_control_msg(port->serial->dev, + if ((ret = usb_control_msg(port->serial->dev, usb_rcvctrlpipe(port->serial->dev, 0), - FTDI_SIO_GET_MODEM_STATUS_REQUEST, + FTDI_SIO_GET_MODEM_STATUS_REQUEST, FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE, - 0, priv->interface, + 0, priv->interface, buf, 2, WDR_TIMEOUT)) < 0 ) { err("%s Could not get modem status of device - err: %d", __FUNCTION__, ret); @@ -2068,12 +2067,12 @@ static int ftdi_tiocmget (struct usb_serial_port *port, struct file *file) return -EFAULT; break; } - + return (buf[0] & FTDI_SIO_DSR_MASK ? TIOCM_DSR : 0) | (buf[0] & FTDI_SIO_CTS_MASK ? TIOCM_CTS : 0) | (buf[0] & FTDI_SIO_RI_MASK ? TIOCM_RI : 0) | (buf[0] & FTDI_SIO_RLSD_MASK ? TIOCM_CD : 0) | - priv->last_dtr_rts; + priv->last_dtr_rts; } static int ftdi_tiocmset(struct usb_serial_port *port, struct file * file, unsigned int set, unsigned int clear) @@ -2139,11 +2138,11 @@ static int ftdi_ioctl (struct usb_serial_port *port, struct file * file, unsigne break; default: break; - + } - /* This is not necessarily an error - turns out the higher layers will do + /* This is not necessarily an error - turns out the higher layers will do * some ioctls itself (see comment above) */ dbg("%s arg not supported - it was 0x%04x - check /usr/include/asm/ioctls.h", __FUNCTION__, cmd); @@ -2200,7 +2199,7 @@ static int __init ftdi_init (void) if (retval) goto failed_sio_register; retval = usb_register(&ftdi_driver); - if (retval) + if (retval) goto failed_usb_register; info(DRIVER_VERSION ":" DRIVER_DESC); diff --git a/trunk/drivers/usb/serial/ftdi_sio.h b/trunk/drivers/usb/serial/ftdi_sio.h index bae117d359af..f0edb87d2dd5 100644 --- a/trunk/drivers/usb/serial/ftdi_sio.h +++ b/trunk/drivers/usb/serial/ftdi_sio.h @@ -55,9 +55,6 @@ /* iPlus device */ #define FTDI_IPLUS_PID 0xD070 /* Product Id */ -/* DMX4ALL DMX Interfaces */ -#define FTDI_DMX4ALL 0xC850 - /* www.crystalfontz.com devices - thanx for providing free devices for evaluation ! */ /* they use the ftdi chipset for the USB interface and the vendor id is the same */ #define FTDI_XF_632_PID 0xFC08 /* 632: 16x2 Character Display */ @@ -177,16 +174,10 @@ */ #define FTDI_ASK_RDR400_PID 0xC991 /* ASK RDR 400 series card reader */ -/* - * FTDI USB UART chips used in construction projects from the - * Elektor Electronics magazine (http://elektor-electronics.co.uk) - */ -#define ELEKTOR_VID 0x0C7D -#define ELEKTOR_FT323R_PID 0x0005 /* RFID-Reader, issue 09-2006 */ - /* * DSS-20 Sync Station for Sony Ericsson P800 */ + #define FTDI_DSS20_PID 0xFC82 /* diff --git a/trunk/drivers/usb/serial/garmin_gps.c b/trunk/drivers/usb/serial/garmin_gps.c index 6530d391ebed..4b1196a8b09e 100644 --- a/trunk/drivers/usb/serial/garmin_gps.c +++ b/trunk/drivers/usb/serial/garmin_gps.c @@ -1031,7 +1031,7 @@ static void garmin_close (struct usb_serial_port *port, struct file * filp) } -static void garmin_write_bulk_callback (struct urb *urb) +static void garmin_write_bulk_callback (struct urb *urb, struct pt_regs *regs) { unsigned long flags; struct usb_serial_port *port = (struct usb_serial_port *)urb->context; @@ -1274,7 +1274,7 @@ static void garmin_read_process(struct garmin_data * garmin_data_p, } -static void garmin_read_bulk_callback (struct urb *urb) +static void garmin_read_bulk_callback (struct urb *urb, struct pt_regs *regs) { unsigned long flags; struct usb_serial_port *port = (struct usb_serial_port *)urb->context; @@ -1330,7 +1330,7 @@ static void garmin_read_bulk_callback (struct urb *urb) } -static void garmin_read_int_callback (struct urb *urb) +static void garmin_read_int_callback (struct urb *urb, struct pt_regs *regs) { unsigned long flags; int status; @@ -1523,11 +1523,12 @@ static int garmin_attach (struct usb_serial *serial) dbg("%s", __FUNCTION__); - garmin_data_p = kzalloc(sizeof(struct garmin_data), GFP_KERNEL); + garmin_data_p = kmalloc (sizeof(struct garmin_data), GFP_KERNEL); if (garmin_data_p == NULL) { dev_err(&port->dev, "%s - Out of memory\n", __FUNCTION__); return -ENOMEM; } + memset (garmin_data_p, 0, sizeof(struct garmin_data)); init_timer(&garmin_data_p->timer); spin_lock_init(&garmin_data_p->lock); INIT_LIST_HEAD(&garmin_data_p->pktlist); diff --git a/trunk/drivers/usb/serial/generic.c b/trunk/drivers/usb/serial/generic.c index 36042937e77f..21cbaa0fb96b 100644 --- a/trunk/drivers/usb/serial/generic.c +++ b/trunk/drivers/usb/serial/generic.c @@ -248,7 +248,7 @@ int usb_serial_generic_chars_in_buffer (struct usb_serial_port *port) return (chars); } -void usb_serial_generic_read_bulk_callback (struct urb *urb) +void usb_serial_generic_read_bulk_callback (struct urb *urb, struct pt_regs *regs) { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; struct usb_serial *serial = port->serial; @@ -287,7 +287,7 @@ void usb_serial_generic_read_bulk_callback (struct urb *urb) } EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback); -void usb_serial_generic_write_bulk_callback (struct urb *urb) +void usb_serial_generic_write_bulk_callback (struct urb *urb, struct pt_regs *regs) { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; diff --git a/trunk/drivers/usb/serial/io_edgeport.c b/trunk/drivers/usb/serial/io_edgeport.c index d06547a13f28..c49976c3ad52 100644 --- a/trunk/drivers/usb/serial/io_edgeport.c +++ b/trunk/drivers/usb/serial/io_edgeport.c @@ -216,10 +216,10 @@ static int CmdUrbs = 0; /* Number of outstanding Command Write Urbs */ /* local function prototypes */ /* function prototypes for all URB callbacks */ -static void edge_interrupt_callback (struct urb *urb); -static void edge_bulk_in_callback (struct urb *urb); -static void edge_bulk_out_data_callback (struct urb *urb); -static void edge_bulk_out_cmd_callback (struct urb *urb); +static void edge_interrupt_callback (struct urb *urb, struct pt_regs *regs); +static void edge_bulk_in_callback (struct urb *urb, struct pt_regs *regs); +static void edge_bulk_out_data_callback (struct urb *urb, struct pt_regs *regs); +static void edge_bulk_out_cmd_callback (struct urb *urb, struct pt_regs *regs); /* function prototypes for the usbserial callbacks */ static int edge_open (struct usb_serial_port *port, struct file *filp); @@ -534,7 +534,7 @@ static void get_product_info(struct edgeport_serial *edge_serial) * this is the callback function for when we have received data on the * interrupt endpoint. *****************************************************************************/ -static void edge_interrupt_callback (struct urb *urb) +static void edge_interrupt_callback (struct urb *urb, struct pt_regs *regs) { struct edgeport_serial *edge_serial = (struct edgeport_serial *)urb->context; struct edgeport_port *edge_port; @@ -631,7 +631,7 @@ static void edge_interrupt_callback (struct urb *urb) * this is the callback function for when we have received data on the * bulk in endpoint. *****************************************************************************/ -static void edge_bulk_in_callback (struct urb *urb) +static void edge_bulk_in_callback (struct urb *urb, struct pt_regs *regs) { struct edgeport_serial *edge_serial = (struct edgeport_serial *)urb->context; unsigned char *data = urb->transfer_buffer; @@ -687,7 +687,7 @@ static void edge_bulk_in_callback (struct urb *urb) * this is the callback function for when we have finished sending serial data * on the bulk out endpoint. *****************************************************************************/ -static void edge_bulk_out_data_callback (struct urb *urb) +static void edge_bulk_out_data_callback (struct urb *urb, struct pt_regs *regs) { struct edgeport_port *edge_port = (struct edgeport_port *)urb->context; struct tty_struct *tty; @@ -718,7 +718,7 @@ static void edge_bulk_out_data_callback (struct urb *urb) * this is the callback function for when we have finished sending a command * on the bulk out endpoint. *****************************************************************************/ -static void edge_bulk_out_cmd_callback (struct urb *urb) +static void edge_bulk_out_cmd_callback (struct urb *urb, struct pt_regs *regs) { struct edgeport_port *edge_port = (struct edgeport_port *)urb->context; struct tty_struct *tty; @@ -1038,7 +1038,9 @@ static void edge_close (struct usb_serial_port *port, struct file * filp) edge_port->open = FALSE; edge_port->openPending = FALSE; - usb_kill_urb(edge_port->write_urb); + if (edge_port->write_urb) { + usb_kill_urb(edge_port->write_urb); + } if (edge_port->write_urb) { /* if this urb had a transfer buffer already (old transfer) free it */ diff --git a/trunk/drivers/usb/serial/io_ti.c b/trunk/drivers/usb/serial/io_ti.c index ee0c921e1520..17c5b1d2311a 100644 --- a/trunk/drivers/usb/serial/io_ti.c +++ b/trunk/drivers/usb/serial/io_ti.c @@ -1697,7 +1697,7 @@ static void handle_new_lsr (struct edgeport_port *edge_port, int lsr_data, __u8 } -static void edge_interrupt_callback (struct urb *urb) +static void edge_interrupt_callback (struct urb *urb, struct pt_regs *regs) { struct edgeport_serial *edge_serial = (struct edgeport_serial *)urb->context; struct usb_serial_port *port; @@ -1787,7 +1787,7 @@ static void edge_interrupt_callback (struct urb *urb) __FUNCTION__, status); } -static void edge_bulk_in_callback (struct urb *urb) +static void edge_bulk_in_callback (struct urb *urb, struct pt_regs *regs) { struct edgeport_port *edge_port = (struct edgeport_port *)urb->context; unsigned char *data = urb->transfer_buffer; @@ -1879,7 +1879,7 @@ static void edge_tty_recv(struct device *dev, struct tty_struct *tty, unsigned c tty_flip_buffer_push(tty); } -static void edge_bulk_out_callback (struct urb *urb) +static void edge_bulk_out_callback (struct urb *urb, struct pt_regs *regs) { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; struct edgeport_port *edge_port = usb_get_serial_port_data(port); diff --git a/trunk/drivers/usb/serial/ipaq.c b/trunk/drivers/usb/serial/ipaq.c index d72cf8bc7f76..cbc725a6c58e 100644 --- a/trunk/drivers/usb/serial/ipaq.c +++ b/trunk/drivers/usb/serial/ipaq.c @@ -83,8 +83,8 @@ static int ipaq_write(struct usb_serial_port *port, const unsigned char *buf, static int ipaq_write_bulk(struct usb_serial_port *port, const unsigned char *buf, int count); static void ipaq_write_gather(struct usb_serial_port *port); -static void ipaq_read_bulk_callback (struct urb *urb); -static void ipaq_write_bulk_callback(struct urb *urb); +static void ipaq_read_bulk_callback (struct urb *urb, struct pt_regs *regs); +static void ipaq_write_bulk_callback(struct urb *urb, struct pt_regs *regs); static int ipaq_write_room(struct usb_serial_port *port); static int ipaq_chars_in_buffer(struct usb_serial_port *port); static void ipaq_destroy_lists(struct usb_serial_port *port); @@ -320,7 +320,6 @@ static struct usb_device_id ipaq_id_table [] = { { USB_DEVICE(0x0B05, 0x9200) }, /* ASUS USB Sync */ { USB_DEVICE(0x0B05, 0x9202) }, /* ASUS USB Sync */ { USB_DEVICE(0x0BB4, 0x00CE) }, /* HTC USB Sync */ - { USB_DEVICE(0x0BB4, 0x00CF) }, /* HTC USB Modem */ { USB_DEVICE(0x0BB4, 0x0A01) }, /* PocketPC USB Sync */ { USB_DEVICE(0x0BB4, 0x0A02) }, /* PocketPC USB Sync */ { USB_DEVICE(0x0BB4, 0x0A03) }, /* PocketPC USB Sync */ @@ -722,7 +721,7 @@ static void ipaq_close(struct usb_serial_port *port, struct file *filp) /* info ("Bytes In = %d Bytes Out = %d", bytes_in, bytes_out); */ } -static void ipaq_read_bulk_callback(struct urb *urb) +static void ipaq_read_bulk_callback(struct urb *urb, struct pt_regs *regs) { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; struct tty_struct *tty; @@ -860,7 +859,7 @@ static void ipaq_write_gather(struct usb_serial_port *port) return; } -static void ipaq_write_bulk_callback(struct urb *urb) +static void ipaq_write_bulk_callback(struct urb *urb, struct pt_regs *regs) { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; struct ipaq_private *priv = usb_get_serial_port_data(port); diff --git a/trunk/drivers/usb/serial/ipw.c b/trunk/drivers/usb/serial/ipw.c index d3b9a351cef8..812bc213a963 100644 --- a/trunk/drivers/usb/serial/ipw.c +++ b/trunk/drivers/usb/serial/ipw.c @@ -161,7 +161,7 @@ static struct usb_driver usb_ipw_driver = { static int debug; -static void ipw_read_bulk_callback(struct urb *urb) +static void ipw_read_bulk_callback(struct urb *urb, struct pt_regs *regs) { struct usb_serial_port *port = urb->context; unsigned char *data = urb->transfer_buffer; @@ -206,9 +206,10 @@ static int ipw_open(struct usb_serial_port *port, struct file *filp) dbg("%s", __FUNCTION__); - buf_flow_init = kmemdup(buf_flow_static, 16, GFP_KERNEL); + buf_flow_init = kmalloc(16, GFP_KERNEL); if (!buf_flow_init) return -ENOMEM; + memcpy(buf_flow_init, buf_flow_static, 16); if (port->tty) port->tty->low_latency = 1; @@ -366,7 +367,7 @@ static void ipw_close(struct usb_serial_port *port, struct file * filp) usb_kill_urb(port->write_urb); } -static void ipw_write_bulk_callback(struct urb *urb) +static void ipw_write_bulk_callback(struct urb *urb, struct pt_regs *regs) { struct usb_serial_port *port = urb->context; diff --git a/trunk/drivers/usb/serial/ir-usb.c b/trunk/drivers/usb/serial/ir-usb.c index 331bf81556fc..1b348df388ed 100644 --- a/trunk/drivers/usb/serial/ir-usb.c +++ b/trunk/drivers/usb/serial/ir-usb.c @@ -105,8 +105,8 @@ static int ir_startup (struct usb_serial *serial); static int ir_open (struct usb_serial_port *port, struct file *filep); static void ir_close (struct usb_serial_port *port, struct file *filep); static int ir_write (struct usb_serial_port *port, const unsigned char *buf, int count); -static void ir_write_bulk_callback (struct urb *urb); -static void ir_read_bulk_callback (struct urb *urb); +static void ir_write_bulk_callback (struct urb *urb, struct pt_regs *regs); +static void ir_read_bulk_callback (struct urb *urb, struct pt_regs *regs); static void ir_set_termios (struct usb_serial_port *port, struct termios *old_termios); static u8 ir_baud = 0; @@ -388,7 +388,7 @@ static int ir_write (struct usb_serial_port *port, const unsigned char *buf, int return result; } -static void ir_write_bulk_callback (struct urb *urb) +static void ir_write_bulk_callback (struct urb *urb, struct pt_regs *regs) { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; @@ -410,7 +410,7 @@ static void ir_write_bulk_callback (struct urb *urb) usb_serial_port_softint(port); } -static void ir_read_bulk_callback (struct urb *urb) +static void ir_read_bulk_callback (struct urb *urb, struct pt_regs *regs) { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; struct tty_struct *tty; diff --git a/trunk/drivers/usb/serial/keyspan.c b/trunk/drivers/usb/serial/keyspan.c index 7639652cec42..015ad6cc1bbb 100644 --- a/trunk/drivers/usb/serial/keyspan.c +++ b/trunk/drivers/usb/serial/keyspan.c @@ -412,7 +412,7 @@ static int keyspan_write(struct usb_serial_port *port, return count - left; } -static void usa26_indat_callback(struct urb *urb) +static void usa26_indat_callback(struct urb *urb, struct pt_regs *regs) { int i, err; int endpoint; @@ -470,7 +470,7 @@ static void usa26_indat_callback(struct urb *urb) } /* Outdat handling is common for all devices */ -static void usa2x_outdat_callback(struct urb *urb) +static void usa2x_outdat_callback(struct urb *urb, struct pt_regs *regs) { struct usb_serial_port *port; struct keyspan_port_private *p_priv; @@ -483,13 +483,13 @@ static void usa2x_outdat_callback(struct urb *urb) usb_serial_port_softint(port); } -static void usa26_inack_callback(struct urb *urb) +static void usa26_inack_callback(struct urb *urb, struct pt_regs *regs) { dbg ("%s", __FUNCTION__); } -static void usa26_outcont_callback(struct urb *urb) +static void usa26_outcont_callback(struct urb *urb, struct pt_regs *regs) { struct usb_serial_port *port; struct keyspan_port_private *p_priv; @@ -503,7 +503,7 @@ static void usa26_outcont_callback(struct urb *urb) } } -static void usa26_instat_callback(struct urb *urb) +static void usa26_instat_callback(struct urb *urb, struct pt_regs *regs) { unsigned char *data = urb->transfer_buffer; struct keyspan_usa26_portStatusMessage *msg; @@ -565,14 +565,14 @@ static void usa26_instat_callback(struct urb *urb) exit: ; } -static void usa26_glocont_callback(struct urb *urb) +static void usa26_glocont_callback(struct urb *urb, struct pt_regs *regs) { dbg ("%s", __FUNCTION__); } -static void usa28_indat_callback(struct urb *urb) +static void usa28_indat_callback(struct urb *urb, struct pt_regs *regs) { int i, err; struct usb_serial_port *port; @@ -620,12 +620,12 @@ static void usa28_indat_callback(struct urb *urb) } while (urb->status != -EINPROGRESS); } -static void usa28_inack_callback(struct urb *urb) +static void usa28_inack_callback(struct urb *urb, struct pt_regs *regs) { dbg ("%s", __FUNCTION__); } -static void usa28_outcont_callback(struct urb *urb) +static void usa28_outcont_callback(struct urb *urb, struct pt_regs *regs) { struct usb_serial_port *port; struct keyspan_port_private *p_priv; @@ -639,7 +639,7 @@ static void usa28_outcont_callback(struct urb *urb) } } -static void usa28_instat_callback(struct urb *urb) +static void usa28_instat_callback(struct urb *urb, struct pt_regs *regs) { int err; unsigned char *data = urb->transfer_buffer; @@ -700,13 +700,13 @@ static void usa28_instat_callback(struct urb *urb) exit: ; } -static void usa28_glocont_callback(struct urb *urb) +static void usa28_glocont_callback(struct urb *urb, struct pt_regs *regs) { dbg ("%s", __FUNCTION__); } -static void usa49_glocont_callback(struct urb *urb) +static void usa49_glocont_callback(struct urb *urb, struct pt_regs *regs) { struct usb_serial *serial; struct usb_serial_port *port; @@ -730,7 +730,7 @@ static void usa49_glocont_callback(struct urb *urb) /* This is actually called glostat in the Keyspan doco */ -static void usa49_instat_callback(struct urb *urb) +static void usa49_instat_callback(struct urb *urb, struct pt_regs *regs) { int err; unsigned char *data = urb->transfer_buffer; @@ -793,12 +793,12 @@ static void usa49_instat_callback(struct urb *urb) exit: ; } -static void usa49_inack_callback(struct urb *urb) +static void usa49_inack_callback(struct urb *urb, struct pt_regs *regs) { dbg ("%s", __FUNCTION__); } -static void usa49_indat_callback(struct urb *urb) +static void usa49_indat_callback(struct urb *urb, struct pt_regs *regs) { int i, err; int endpoint; @@ -851,12 +851,12 @@ static void usa49_indat_callback(struct urb *urb) } /* not used, usa-49 doesn't have per-port control endpoints */ -static void usa49_outcont_callback(struct urb *urb) +static void usa49_outcont_callback(struct urb *urb, struct pt_regs *regs) { dbg ("%s", __FUNCTION__); } -static void usa90_indat_callback(struct urb *urb) +static void usa90_indat_callback(struct urb *urb, struct pt_regs *regs) { int i, err; int endpoint; @@ -930,7 +930,7 @@ static void usa90_indat_callback(struct urb *urb) } -static void usa90_instat_callback(struct urb *urb) +static void usa90_instat_callback(struct urb *urb, struct pt_regs *regs) { unsigned char *data = urb->transfer_buffer; struct keyspan_usa90_portStatusMessage *msg; @@ -981,7 +981,7 @@ static void usa90_instat_callback(struct urb *urb) ; } -static void usa90_outcont_callback(struct urb *urb) +static void usa90_outcont_callback(struct urb *urb, struct pt_regs *regs) { struct usb_serial_port *port; struct keyspan_port_private *p_priv; @@ -1277,7 +1277,7 @@ static int keyspan_fake_startup (struct usb_serial *serial) /* Helper functions used by keyspan_setup_urbs */ static struct urb *keyspan_setup_urb (struct usb_serial *serial, int endpoint, int dir, void *ctx, char *buf, int len, - void (*callback)(struct urb *)) + void (*callback)(struct urb *, struct pt_regs *regs)) { struct urb *urb; @@ -1300,12 +1300,12 @@ static struct urb *keyspan_setup_urb (struct usb_serial *serial, int endpoint, } static struct callbacks { - void (*instat_callback)(struct urb *); - void (*glocont_callback)(struct urb *); - void (*indat_callback)(struct urb *); - void (*outdat_callback)(struct urb *); - void (*inack_callback)(struct urb *); - void (*outcont_callback)(struct urb *); + void (*instat_callback)(struct urb *, struct pt_regs *regs); + void (*glocont_callback)(struct urb *, struct pt_regs *regs); + void (*indat_callback)(struct urb *, struct pt_regs *regs); + void (*outdat_callback)(struct urb *, struct pt_regs *regs); + void (*inack_callback)(struct urb *, struct pt_regs *regs); + void (*outcont_callback)(struct urb *, struct pt_regs *regs); } keyspan_callbacks[] = { { /* msg_usa26 callbacks */ @@ -2306,16 +2306,22 @@ static void keyspan_shutdown (struct usb_serial *serial) } /* Now free them */ - usb_free_urb(s_priv->instat_urb); - usb_free_urb(s_priv->glocont_urb); + if (s_priv->instat_urb) + usb_free_urb(s_priv->instat_urb); + if (s_priv->glocont_urb) + usb_free_urb(s_priv->glocont_urb); for (i = 0; i < serial->num_ports; ++i) { port = serial->port[i]; p_priv = usb_get_serial_port_data(port); - usb_free_urb(p_priv->inack_urb); - usb_free_urb(p_priv->outcont_urb); + if (p_priv->inack_urb) + usb_free_urb(p_priv->inack_urb); + if (p_priv->outcont_urb) + usb_free_urb(p_priv->outcont_urb); for (j = 0; j < 2; j++) { - usb_free_urb(p_priv->in_urbs[j]); - usb_free_urb(p_priv->out_urbs[j]); + if (p_priv->in_urbs[j]) + usb_free_urb(p_priv->in_urbs[j]); + if (p_priv->out_urbs[j]) + usb_free_urb(p_priv->out_urbs[j]); } } diff --git a/trunk/drivers/usb/serial/keyspan_pda.c b/trunk/drivers/usb/serial/keyspan_pda.c index 909005107ea2..59e777f1e8fd 100644 --- a/trunk/drivers/usb/serial/keyspan_pda.c +++ b/trunk/drivers/usb/serial/keyspan_pda.c @@ -210,7 +210,7 @@ static void keyspan_pda_request_unthrottle( struct usb_serial *serial ) } -static void keyspan_pda_rx_interrupt (struct urb *urb) +static void keyspan_pda_rx_interrupt (struct urb *urb, struct pt_regs *regs) { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; struct tty_struct *tty = port->tty; @@ -601,7 +601,7 @@ static int keyspan_pda_write(struct usb_serial_port *port, } -static void keyspan_pda_write_bulk_callback (struct urb *urb) +static void keyspan_pda_write_bulk_callback (struct urb *urb, struct pt_regs *regs) { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; struct keyspan_pda_private *priv; diff --git a/trunk/drivers/usb/serial/kl5kusb105.c b/trunk/drivers/usb/serial/kl5kusb105.c index 17e205699c2b..2a2f3e2da055 100644 --- a/trunk/drivers/usb/serial/kl5kusb105.c +++ b/trunk/drivers/usb/serial/kl5kusb105.c @@ -80,11 +80,11 @@ static void klsi_105_close (struct usb_serial_port *port, static int klsi_105_write (struct usb_serial_port *port, const unsigned char *buf, int count); -static void klsi_105_write_bulk_callback (struct urb *urb); +static void klsi_105_write_bulk_callback (struct urb *urb, struct pt_regs *regs); static int klsi_105_chars_in_buffer (struct usb_serial_port *port); static int klsi_105_write_room (struct usb_serial_port *port); -static void klsi_105_read_bulk_callback (struct urb *urb); +static void klsi_105_read_bulk_callback (struct urb *urb, struct pt_regs *regs); static void klsi_105_set_termios (struct usb_serial_port *port, struct termios * old); static int klsi_105_ioctl (struct usb_serial_port *port, @@ -556,7 +556,7 @@ static int klsi_105_write (struct usb_serial_port *port, return bytes_sent; /* that's how much we wrote */ } /* klsi_105_write */ -static void klsi_105_write_bulk_callback ( struct urb *urb) +static void klsi_105_write_bulk_callback ( struct urb *urb, struct pt_regs *regs) { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; @@ -616,7 +616,7 @@ static int klsi_105_write_room (struct usb_serial_port *port) -static void klsi_105_read_bulk_callback (struct urb *urb) +static void klsi_105_read_bulk_callback (struct urb *urb, struct pt_regs *regs) { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; struct klsi_105_private *priv = usb_get_serial_port_data(port); diff --git a/trunk/drivers/usb/serial/kobil_sct.c b/trunk/drivers/usb/serial/kobil_sct.c index 237289920f03..d50dce034958 100644 --- a/trunk/drivers/usb/serial/kobil_sct.c +++ b/trunk/drivers/usb/serial/kobil_sct.c @@ -80,8 +80,8 @@ static int kobil_ioctl(struct usb_serial_port *port, struct file *file, static int kobil_tiocmget(struct usb_serial_port *port, struct file *file); static int kobil_tiocmset(struct usb_serial_port *port, struct file *file, unsigned int set, unsigned int clear); -static void kobil_read_int_callback( struct urb *urb ); -static void kobil_write_callback( struct urb *purb ); +static void kobil_read_int_callback( struct urb *urb, struct pt_regs *regs ); +static void kobil_write_callback( struct urb *purb, struct pt_regs *regs ); static struct usb_device_id id_table [] = { @@ -185,11 +185,13 @@ static int kobil_startup (struct usb_serial *serial) for (i = 0; i < altsetting->desc.bNumEndpoints; i++) { endpoint = &altsetting->endpoint[i]; - if (usb_endpoint_is_int_out(&endpoint->desc)) { + if (((endpoint->desc.bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) && + ((endpoint->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)) { dbg("%s Found interrupt out endpoint. Address: %d", __FUNCTION__, endpoint->desc.bEndpointAddress); priv->write_int_endpoint_address = endpoint->desc.bEndpointAddress; } - if (usb_endpoint_is_int_in(&endpoint->desc)) { + if (((endpoint->desc.bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) && + ((endpoint->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)) { dbg("%s Found interrupt in endpoint. Address: %d", __FUNCTION__, endpoint->desc.bEndpointAddress); priv->read_int_endpoint_address = endpoint->desc.bEndpointAddress; } @@ -353,11 +355,12 @@ static void kobil_close (struct usb_serial_port *port, struct file *filp) usb_free_urb( port->write_urb ); port->write_urb = NULL; } - usb_kill_urb(port->interrupt_in_urb); + if (port->interrupt_in_urb) + usb_kill_urb(port->interrupt_in_urb); } -static void kobil_read_int_callback( struct urb *purb) +static void kobil_read_int_callback( struct urb *purb, struct pt_regs *regs) { int result; struct usb_serial_port *port = (struct usb_serial_port *) purb->context; @@ -402,7 +405,7 @@ static void kobil_read_int_callback( struct urb *purb) } -static void kobil_write_callback( struct urb *purb ) +static void kobil_write_callback( struct urb *purb, struct pt_regs *regs ) { } diff --git a/trunk/drivers/usb/serial/mct_u232.c b/trunk/drivers/usb/serial/mct_u232.c index a906e500a02b..f4d4305c2c02 100644 --- a/trunk/drivers/usb/serial/mct_u232.c +++ b/trunk/drivers/usb/serial/mct_u232.c @@ -96,7 +96,7 @@ static int mct_u232_open (struct usb_serial_port *port, struct file *filp); static void mct_u232_close (struct usb_serial_port *port, struct file *filp); -static void mct_u232_read_int_callback (struct urb *urb); +static void mct_u232_read_int_callback (struct urb *urb, struct pt_regs *regs); static void mct_u232_set_termios (struct usb_serial_port *port, struct termios * old); static int mct_u232_ioctl (struct usb_serial_port *port, @@ -358,8 +358,10 @@ static int mct_u232_startup (struct usb_serial *serial) /* Puh, that's dirty */ port = serial->port[0]; rport = serial->port[1]; - /* No unlinking, it wasn't submitted yet. */ - usb_free_urb(port->read_urb); + if (port->read_urb) { + /* No unlinking, it wasn't submitted yet. */ + usb_free_urb(port->read_urb); + } port->read_urb = rport->interrupt_in_urb; rport->interrupt_in_urb = NULL; port->read_urb->context = port; @@ -464,7 +466,7 @@ static void mct_u232_close (struct usb_serial_port *port, struct file *filp) } /* mct_u232_close */ -static void mct_u232_read_int_callback (struct urb *urb) +static void mct_u232_read_int_callback (struct urb *urb, struct pt_regs *regs) { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; struct mct_u232_private *priv = usb_get_serial_port_data(port); diff --git a/trunk/drivers/usb/serial/mos7720.c b/trunk/drivers/usb/serial/mos7720.c deleted file mode 100644 index 82cd15b894b0..000000000000 --- a/trunk/drivers/usb/serial/mos7720.c +++ /dev/null @@ -1,1683 +0,0 @@ -/* - * mos7720.c - * Controls the Moschip 7720 usb to dual port serial convertor - * - * Copyright 2006 Moschip Semiconductor Tech. Ltd. - * - * 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, version 2 of the License. - * - * Developed by: - * VijayaKumar.G.N. - * AjayKumar - * Gurudeva.N. - * - * Cleaned up from the original by: - * Greg Kroah-Hartman - * - * Originally based on drivers/usb/serial/io_edgeport.c which is: - * Copyright (C) 2000 Inside Out Networks, All rights reserved. - * Copyright (C) 2001-2002 Greg Kroah-Hartman - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -/* - * Version Information - */ -#define DRIVER_VERSION "1.0.0.4F" -#define DRIVER_AUTHOR "Aspire Communications pvt Ltd." -#define DRIVER_DESC "Moschip USB Serial Driver" - -/* default urb timeout */ -#define MOS_WDR_TIMEOUT (HZ * 5) - -#define MOS_PORT1 0x0200 -#define MOS_PORT2 0x0300 -#define MOS_VENREG 0x0000 -#define MOS_MAX_PORT 0x02 -#define MOS_WRITE 0x0E -#define MOS_READ 0x0D - -/* Interrupt Rotinue Defines */ -#define SERIAL_IIR_RLS 0x06 -#define SERIAL_IIR_RDA 0x04 -#define SERIAL_IIR_CTI 0x0c -#define SERIAL_IIR_THR 0x02 -#define SERIAL_IIR_MS 0x00 - -#define NUM_URBS 16 /* URB Count */ -#define URB_TRANSFER_BUFFER_SIZE 32 /* URB Size */ - -/* This structure holds all of the local port information */ -struct moschip_port -{ - __u8 shadowLCR; /* last LCR value received */ - __u8 shadowMCR; /* last MCR value received */ - __u8 shadowMSR; /* last MSR value received */ - char open; - struct async_icount icount; - struct usb_serial_port *port; /* loop back to the owner */ - struct urb *write_urb_pool[NUM_URBS]; -}; - -/* This structure holds all of the individual serial device information */ -struct moschip_serial -{ - int interrupt_started; -}; - -static int debug; - -#define USB_VENDOR_ID_MOSCHIP 0x9710 -#define MOSCHIP_DEVICE_ID_7720 0x7720 -#define MOSCHIP_DEVICE_ID_7715 0x7715 - -static struct usb_device_id moschip_port_id_table [] = { - { USB_DEVICE(USB_VENDOR_ID_MOSCHIP,MOSCHIP_DEVICE_ID_7720) }, - { } /* terminating entry */ -}; -MODULE_DEVICE_TABLE(usb, moschip_port_id_table); - - -/* - * mos7720_interrupt_callback - * this is the callback function for when we have received data on the - * interrupt endpoint. - */ -static void mos7720_interrupt_callback(struct urb *urb) -{ - int result; - int length; - __u32 *data; - unsigned int status; - __u8 sp1; - __u8 sp2; - __u8 st; - - dbg("%s"," : Entering\n"); - - if (!urb) { - dbg("%s","Invalid Pointer !!!!:\n"); - return; - } - - switch (urb->status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", __FUNCTION__, - urb->status); - return; - default: - dbg("%s - nonzero urb status received: %d", __FUNCTION__, - urb->status); - goto exit; - } - - length = urb->actual_length; - data = urb->transfer_buffer; - - /* Moschip get 4 bytes - * Byte 1 IIR Port 1 (port.number is 0) - * Byte 2 IIR Port 2 (port.number is 1) - * Byte 3 -------------- - * Byte 4 FIFO status for both */ - if (length && length > 4) { - dbg("Wrong data !!!"); - return; - } - - status = *data; - - sp1 = (status & 0xff000000)>>24; - sp2 = (status & 0x00ff0000)>>16; - st = status & 0x000000ff; - - if ((sp1 & 0x01) || (sp2 & 0x01)) { - /* No Interrupt Pending in both the ports */ - dbg("No Interrupt !!!"); - } else { - switch (sp1 & 0x0f) { - case SERIAL_IIR_RLS: - dbg("Serial Port 1: Receiver status error or address " - "bit detected in 9-bit mode\n"); - break; - case SERIAL_IIR_CTI: - dbg("Serial Port 1: Receiver time out"); - break; - case SERIAL_IIR_MS: - dbg("Serial Port 1: Modem status change"); - break; - } - - switch (sp2 & 0x0f) { - case SERIAL_IIR_RLS: - dbg("Serial Port 2: Receiver status error or address " - "bit detected in 9-bit mode"); - break; - case SERIAL_IIR_CTI: - dbg("Serial Port 2: Receiver time out"); - break; - case SERIAL_IIR_MS: - dbg("Serial Port 2: Modem status change"); - break; - } - } - -exit: - result = usb_submit_urb(urb, GFP_ATOMIC); - if (result) - dev_err(&urb->dev->dev, - "%s - Error %d submitting control urb\n", - __FUNCTION__, result); - return; -} - -/* - * mos7720_bulk_in_callback - * this is the callback function for when we have received data on the - * bulk in endpoint. - */ -static void mos7720_bulk_in_callback(struct urb *urb) -{ - int status; - unsigned char *data ; - struct usb_serial_port *port; - struct moschip_port *mos7720_port; - struct tty_struct *tty; - - if (urb->status) { - dbg("nonzero read bulk status received: %d",urb->status); - return; - } - - mos7720_port = urb->context; - if (!mos7720_port) { - dbg("%s","NULL mos7720_port pointer \n"); - return ; - } - - port = mos7720_port->port; - - dbg("Entering...%s", __FUNCTION__); - - data = urb->transfer_buffer; - - tty = port->tty; - if (tty && urb->actual_length) { - tty_buffer_request_room(tty, urb->actual_length); - tty_insert_flip_string(tty, data, urb->actual_length); - tty_flip_buffer_push(tty); - } - - if (!port->read_urb) { - dbg("URB KILLED !!!"); - return; - } - - if (port->read_urb->status != -EINPROGRESS) { - port->read_urb->dev = port->serial->dev; - - status = usb_submit_urb(port->read_urb, GFP_ATOMIC); - if (status) - dbg("usb_submit_urb(read bulk) failed, status = %d", - status); - } -} - -/* - * mos7720_bulk_out_data_callback - * this is the callback function for when we have finished sending serial - * data on the bulk out endpoint. - */ -static void mos7720_bulk_out_data_callback(struct urb *urb) -{ - struct moschip_port *mos7720_port; - struct tty_struct *tty; - - if (urb->status) { - dbg("nonzero write bulk status received:%d", urb->status); - return; - } - - mos7720_port = urb->context; - if (!mos7720_port) { - dbg("NULL mos7720_port pointer"); - return ; - } - - dbg("Entering ........."); - - tty = mos7720_port->port->tty; - - if (tty && mos7720_port->open) { - /* let the tty driver wakeup if it has a special * - * write_wakeup function */ - if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && - tty->ldisc.write_wakeup) - (tty->ldisc.write_wakeup)(tty); - - /* tell the tty driver that something has changed */ - wake_up_interruptible(&tty->write_wait); - } - - /* schedule_work(&mos7720_port->port->work); */ -} - -/* - * send_mos_cmd - * this function will be used for sending command to device - */ -static int send_mos_cmd(struct usb_serial *serial, __u8 request, __u16 value, - __u16 index, void *data) -{ - int status; - unsigned int pipe; - u16 product = le16_to_cpu(serial->dev->descriptor.idProduct); - __u8 requesttype; - __u16 size = 0x0000; - - if (value < MOS_MAX_PORT) { - if (product == MOSCHIP_DEVICE_ID_7715) { - value = value*0x100+0x100; - } else { - value = value*0x100+0x200; - } - } else { - value = 0x0000; - if ((product == MOSCHIP_DEVICE_ID_7715) && - (index != 0x08)) { - dbg("serial->product== MOSCHIP_DEVICE_ID_7715"); - //index = 0x01 ; - } - } - - if (request == MOS_WRITE) { - request = (__u8)MOS_WRITE; - requesttype = (__u8)0x40; - value = value + (__u16)*((unsigned char *)data); - data = NULL; - pipe = usb_sndctrlpipe(serial->dev, 0); - } else { - request = (__u8)MOS_READ; - requesttype = (__u8)0xC0; - size = 0x01; - pipe = usb_rcvctrlpipe(serial->dev,0); - } - - status = usb_control_msg(serial->dev, pipe, request, requesttype, - value, index, data, size, MOS_WDR_TIMEOUT); - - if (status < 0) - dbg("Command Write failed Value %x index %x\n",value,index); - - return status; -} - -static int mos7720_open(struct usb_serial_port *port, struct file * filp) -{ - struct usb_serial *serial; - struct usb_serial_port *port0; - struct urb *urb; - struct moschip_serial *mos7720_serial; - struct moschip_port *mos7720_port; - int response; - int port_number; - char data; - int j; - - serial = port->serial; - - mos7720_port = usb_get_serial_port_data(port); - if (mos7720_port == NULL) - return -ENODEV; - - port0 = serial->port[0]; - - mos7720_serial = usb_get_serial_data(serial); - - if (mos7720_serial == NULL || port0 == NULL) - return -ENODEV; - - usb_clear_halt(serial->dev, port->write_urb->pipe); - usb_clear_halt(serial->dev, port->read_urb->pipe); - - /* Initialising the write urb pool */ - for (j = 0; j < NUM_URBS; ++j) { - urb = usb_alloc_urb(0,SLAB_ATOMIC); - mos7720_port->write_urb_pool[j] = urb; - - if (urb == NULL) { - err("No more urbs???"); - continue; - } - - urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE, - GFP_KERNEL); - if (!urb->transfer_buffer) { - err("%s-out of memory for urb buffers.", __FUNCTION__); - continue; - } - } - - /* Initialize MCS7720 -- Write Init values to corresponding Registers - * - * Register Index - * 1 : IER - * 2 : FCR - * 3 : LCR - * 4 : MCR - * - * 0x08 : SP1/2 Control Reg - */ - port_number = port->number - port->serial->minor; - send_mos_cmd(port->serial, MOS_READ, port_number, UART_LSR, &data); - dbg("SS::%p LSR:%x\n",mos7720_port, data); - - dbg("Check:Sending Command .........."); - - data = 0x02; - send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 0x01, &data); - data = 0x02; - send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 0x02, &data); - - data = 0x00; - send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data); - data = 0x00; - send_mos_cmd(serial, MOS_WRITE, port_number, 0x02, &data); - - data = 0xCF; - send_mos_cmd(serial, MOS_WRITE, port_number, 0x02, &data); - data = 0x03; - mos7720_port->shadowLCR = data; - send_mos_cmd(serial, MOS_WRITE, port_number, 0x03, &data); - data = 0x0b; - mos7720_port->shadowMCR = data; - send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data); - data = 0x0b; - send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data); - - data = 0x00; - send_mos_cmd(serial, MOS_READ, MOS_MAX_PORT, 0x08, &data); - data = 0x00; - send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 0x08, &data); - -/* data = 0x00; - send_mos_cmd(serial, MOS_READ, MOS_MAX_PORT, port_number + 1, &data); - data = 0x03; - send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, port_number + 1, &data); - data = 0x00; - send_mos_cmd(port->serial, MOS_WRITE, MOS_MAX_PORT, port_number + 1, &data); -*/ - data = 0x00; - send_mos_cmd(serial, MOS_READ, MOS_MAX_PORT, 0x08, &data); - - data = data | (port->number - port->serial->minor + 1); - send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 0x08, &data); - - data = 0x83; - mos7720_port->shadowLCR = data; - send_mos_cmd(serial, MOS_WRITE, port_number, 0x03, &data); - data = 0x0c; - send_mos_cmd(serial, MOS_WRITE, port_number, 0x00, &data); - data = 0x00; - send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data); - data = 0x03; - mos7720_port->shadowLCR = data; - send_mos_cmd(serial, MOS_WRITE, port_number, 0x03, &data); - data = 0x0c; - send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data); - data = 0x0c; - send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data); - -//Matrix - - /* force low_latency on so that our tty_push actually forces * - * the data through,otherwise it is scheduled, and with * - * high data rates (like with OHCI) data can get lost. */ - - if (port->tty) - port->tty->low_latency = 1; - - /* see if we've set up our endpoint info yet * - * (can't set it up in mos7720_startup as the * - * structures were not set up at that time.) */ - if (!mos7720_serial->interrupt_started) { - dbg("Interrupt buffer NULL !!!"); - - /* not set up yet, so do it now */ - mos7720_serial->interrupt_started = 1; - - dbg("To Submit URB !!!"); - - /* set up our interrupt urb */ - usb_fill_int_urb(port0->interrupt_in_urb, serial->dev, - usb_rcvintpipe(serial->dev, - port->interrupt_in_endpointAddress), - port0->interrupt_in_buffer, - port0->interrupt_in_urb->transfer_buffer_length, - mos7720_interrupt_callback, mos7720_port, - port0->interrupt_in_urb->interval); - - /* start interrupt read for this mos7720 this interrupt * - * will continue as long as the mos7720 is connected */ - dbg("Submit URB over !!!"); - response = usb_submit_urb(port0->interrupt_in_urb, GFP_KERNEL); - if (response) - dev_err(&port->dev, - "%s - Error %d submitting control urb", - __FUNCTION__, response); - } - - /* set up our bulk in urb */ - usb_fill_bulk_urb(port->read_urb, serial->dev, - usb_rcvbulkpipe(serial->dev, - port->bulk_in_endpointAddress), - port->bulk_in_buffer, - port->read_urb->transfer_buffer_length, - mos7720_bulk_in_callback, mos7720_port); - response = usb_submit_urb(port->read_urb, GFP_KERNEL); - if (response) - dev_err(&port->dev, - "%s - Error %d submitting read urb", __FUNCTION__, response); - - /* initialize our icount structure */ - memset(&(mos7720_port->icount), 0x00, sizeof(mos7720_port->icount)); - - /* initialize our port settings */ - mos7720_port->shadowMCR = UART_MCR_OUT2; /* Must set to enable ints! */ - - /* send a open port command */ - mos7720_port->open = 1; - - return 0; -} - -/* - * mos7720_chars_in_buffer - * this function is called by the tty driver when it wants to know how many - * bytes of data we currently have outstanding in the port (data that has - * been written, but hasn't made it out the port yet) - * If successful, we return the number of bytes left to be written in the - * system, - * Otherwise we return a negative error number. - */ -static int mos7720_chars_in_buffer(struct usb_serial_port *port) -{ - int i; - int chars = 0; - struct moschip_port *mos7720_port; - - dbg("%s:entering ...........", __FUNCTION__); - - mos7720_port = usb_get_serial_port_data(port); - if (mos7720_port == NULL) { - dbg("%s:leaving ...........", __FUNCTION__); - return -ENODEV; - } - - for (i = 0; i < NUM_URBS; ++i) { - if (mos7720_port->write_urb_pool[i]->status == -EINPROGRESS) - chars += URB_TRANSFER_BUFFER_SIZE; - } - dbg("%s - returns %d", __FUNCTION__, chars); - return chars; -} - -static void mos7720_close(struct usb_serial_port *port, struct file *filp) -{ - struct usb_serial *serial; - struct moschip_port *mos7720_port; - char data; - int j; - - dbg("mos7720_close:entering..."); - - serial = port->serial; - - mos7720_port = usb_get_serial_port_data(port); - if (mos7720_port == NULL) - return; - - for (j = 0; j < NUM_URBS; ++j) - usb_kill_urb(mos7720_port->write_urb_pool[j]); - - /* Freeing Write URBs */ - for (j = 0; j < NUM_URBS; ++j) { - if (mos7720_port->write_urb_pool[j]) { - kfree(mos7720_port->write_urb_pool[j]->transfer_buffer); - usb_free_urb(mos7720_port->write_urb_pool[j]); - } - } - - /* While closing port, shutdown all bulk read, write * - * and interrupt read if they exists */ - if (serial->dev) { - dbg("Shutdown bulk write"); - usb_kill_urb(port->write_urb); - dbg("Shutdown bulk read"); - usb_kill_urb(port->read_urb); - } - - data = 0x00; - send_mos_cmd(serial, MOS_WRITE, port->number - port->serial->minor, - 0x04, &data); - - data = 0x00; - send_mos_cmd(serial, MOS_WRITE, port->number - port->serial->minor, - 0x01, &data); - - mos7720_port->open = 0; - - dbg("Leaving %s", __FUNCTION__); -} - -static void mos7720_break(struct usb_serial_port *port, int break_state) -{ - unsigned char data; - struct usb_serial *serial; - struct moschip_port *mos7720_port; - - dbg("Entering %s", __FUNCTION__); - - serial = port->serial; - - mos7720_port = usb_get_serial_port_data(port); - if (mos7720_port == NULL) - return; - - if (break_state == -1) - data = mos7720_port->shadowLCR | UART_LCR_SBC; - else - data = mos7720_port->shadowLCR & ~UART_LCR_SBC; - - mos7720_port->shadowLCR = data; - send_mos_cmd(serial, MOS_WRITE, port->number - port->serial->minor, - 0x03, &data); - - return; -} - -/* - * mos7720_write_room - * this function is called by the tty driver when it wants to know how many - * bytes of data we can accept for a specific port. - * If successful, we return the amount of room that we have for this port - * Otherwise we return a negative error number. - */ -static int mos7720_write_room(struct usb_serial_port *port) -{ - struct moschip_port *mos7720_port; - int room = 0; - int i; - - dbg("%s:entering ...........", __FUNCTION__); - - mos7720_port = usb_get_serial_port_data(port); - if (mos7720_port == NULL) { - dbg("%s:leaving ...........", __FUNCTION__); - return -ENODEV; - } - - for (i = 0; i < NUM_URBS; ++i) { - if (mos7720_port->write_urb_pool[i]->status != -EINPROGRESS) - room += URB_TRANSFER_BUFFER_SIZE; - } - - dbg("%s - returns %d", __FUNCTION__, room); - return room; -} - -static int mos7720_write(struct usb_serial_port *port, - const unsigned char *data, int count) -{ - int status; - int i; - int bytes_sent = 0; - int transfer_size; - - struct moschip_port *mos7720_port; - struct usb_serial *serial; - struct urb *urb; - const unsigned char *current_position = data; - - dbg("%s:entering ...........", __FUNCTION__); - - serial = port->serial; - - mos7720_port = usb_get_serial_port_data(port); - if (mos7720_port == NULL) { - dbg("mos7720_port is NULL"); - return -ENODEV; - } - - /* try to find a free urb in the list */ - urb = NULL; - - for (i = 0; i < NUM_URBS; ++i) { - if (mos7720_port->write_urb_pool[i]->status != -EINPROGRESS) { - urb = mos7720_port->write_urb_pool[i]; - dbg("URB:%d",i); - break; - } - } - - if (urb == NULL) { - dbg("%s - no more free urbs", __FUNCTION__); - goto exit; - } - - if (urb->transfer_buffer == NULL) { - urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE, - GFP_KERNEL); - if (urb->transfer_buffer == NULL) { - err("%s no more kernel memory...", __FUNCTION__); - goto exit; - } - } - transfer_size = min (count, URB_TRANSFER_BUFFER_SIZE); - - memcpy(urb->transfer_buffer, current_position, transfer_size); - usb_serial_debug_data(debug, &port->dev, __FUNCTION__, transfer_size, - urb->transfer_buffer); - - /* fill urb with data and submit */ - usb_fill_bulk_urb(urb, serial->dev, - usb_sndbulkpipe(serial->dev, - port->bulk_out_endpointAddress), - urb->transfer_buffer, transfer_size, - mos7720_bulk_out_data_callback, mos7720_port); - - /* send it down the pipe */ - status = usb_submit_urb(urb,GFP_ATOMIC); - if (status) { - err("%s - usb_submit_urb(write bulk) failed with status = %d", - __FUNCTION__, status); - bytes_sent = status; - goto exit; - } - bytes_sent = transfer_size; - -exit: - return bytes_sent; -} - -static void mos7720_throttle(struct usb_serial_port *port) -{ - struct moschip_port *mos7720_port; - struct tty_struct *tty; - int status; - - dbg("%s- port %d\n", __FUNCTION__, port->number); - - mos7720_port = usb_get_serial_port_data(port); - - if (mos7720_port == NULL) - return; - - if (!mos7720_port->open) { - dbg("port not opened"); - return; - } - - dbg("%s: Entering ..........", __FUNCTION__); - - tty = port->tty; - if (!tty) { - dbg("%s - no tty available", __FUNCTION__); - return; - } - - /* if we are implementing XON/XOFF, send the stop character */ - if (I_IXOFF(tty)) { - unsigned char stop_char = STOP_CHAR(tty); - status = mos7720_write(port, &stop_char, 1); - if (status <= 0) - return; - } - - /* if we are implementing RTS/CTS, toggle that line */ - if (tty->termios->c_cflag & CRTSCTS) { - mos7720_port->shadowMCR &= ~UART_MCR_RTS; - status = send_mos_cmd(port->serial, MOS_WRITE, - port->number - port->serial->minor, - UART_MCR, &mos7720_port->shadowMCR); - if (status != 0) - return; - } -} - -static void mos7720_unthrottle(struct usb_serial_port *port) -{ - struct tty_struct *tty; - int status; - struct moschip_port *mos7720_port = usb_get_serial_port_data(port); - - if (mos7720_port == NULL) - return; - - if (!mos7720_port->open) { - dbg("%s - port not opened", __FUNCTION__); - return; - } - - dbg("%s: Entering ..........", __FUNCTION__); - - tty = port->tty; - if (!tty) { - dbg("%s - no tty available", __FUNCTION__); - return; - } - - /* if we are implementing XON/XOFF, send the start character */ - if (I_IXOFF(tty)) { - unsigned char start_char = START_CHAR(tty); - status = mos7720_write(port, &start_char, 1); - if (status <= 0) - return; - } - - /* if we are implementing RTS/CTS, toggle that line */ - if (tty->termios->c_cflag & CRTSCTS) { - mos7720_port->shadowMCR |= UART_MCR_RTS; - status = send_mos_cmd(port->serial, MOS_WRITE, - port->number - port->serial->minor, - UART_MCR, &mos7720_port->shadowMCR); - if (status != 0) - return; - } -} - -static int set_higher_rates(struct moschip_port *mos7720_port, - unsigned int baud) -{ - unsigned char data; - struct usb_serial_port *port; - struct usb_serial *serial; - int port_number; - - if (mos7720_port == NULL) - return -EINVAL; - - port = mos7720_port->port; - serial = port->serial; - - /*********************************************** - * Init Sequence for higher rates - ***********************************************/ - dbg("Sending Setting Commands .........."); - port_number = port->number - port->serial->minor; - - data = 0x000; - send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data); - data = 0x000; - send_mos_cmd(serial, MOS_WRITE, port_number, 0x02, &data); - data = 0x0CF; - send_mos_cmd(serial, MOS_WRITE, port->number, 0x02, &data); - data = 0x00b; - mos7720_port->shadowMCR = data; - send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data); - data = 0x00b; - send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data); - - data = 0x000; - send_mos_cmd(serial, MOS_READ, MOS_MAX_PORT, 0x08, &data); - data = 0x000; - send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 0x08, &data); - - - /*********************************************** - * Set for higher rates * - ***********************************************/ - - data = baud * 0x10; - send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, port_number + 1,&data); - - data = 0x003; - send_mos_cmd(serial, MOS_READ, MOS_MAX_PORT, 0x08, &data); - data = 0x003; - send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 0x08, &data); - - data = 0x02b; - mos7720_port->shadowMCR = data; - send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data); - data = 0x02b; - send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data); - - /*********************************************** - * Set DLL/DLM - ***********************************************/ - - data = mos7720_port->shadowLCR | UART_LCR_DLAB; - mos7720_port->shadowLCR = data; - send_mos_cmd(serial, MOS_WRITE, port_number, 0x03, &data); - - data = 0x001; /* DLL */ - send_mos_cmd(serial, MOS_WRITE, port_number, 0x00, &data); - data = 0x000; /* DLM */ - send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data); - - data = mos7720_port->shadowLCR & ~UART_LCR_DLAB; - mos7720_port->shadowLCR = data; - send_mos_cmd(serial, MOS_WRITE, port_number, 0x03, &data); - - return 0; -} - -/* baud rate information */ -struct divisor_table_entry -{ - __u32 baudrate; - __u16 divisor; -}; - -/* Define table of divisors for moschip 7720 hardware * - * These assume a 3.6864MHz crystal, the standard /16, and * - * MCR.7 = 0. */ -static struct divisor_table_entry divisor_table[] = { - { 50, 2304}, - { 110, 1047}, /* 2094.545455 => 230450 => .0217 % over */ - { 134, 857}, /* 1713.011152 => 230398.5 => .00065% under */ - { 150, 768}, - { 300, 384}, - { 600, 192}, - { 1200, 96}, - { 1800, 64}, - { 2400, 48}, - { 4800, 24}, - { 7200, 16}, - { 9600, 12}, - { 19200, 6}, - { 38400, 3}, - { 57600, 2}, - { 115200, 1}, -}; - -/***************************************************************************** - * calc_baud_rate_divisor - * this function calculates the proper baud rate divisor for the specified - * baud rate. - *****************************************************************************/ -static int calc_baud_rate_divisor(int baudrate, int *divisor) -{ - int i; - __u16 custom; - __u16 round1; - __u16 round; - - - dbg("%s - %d", __FUNCTION__, baudrate); - - for (i = 0; i < ARRAY_SIZE(divisor_table); i++) { - if (divisor_table[i].baudrate == baudrate) { - *divisor = divisor_table[i].divisor; - return 0; - } - } - - /* After trying for all the standard baud rates * - * Try calculating the divisor for this baud rate */ - if (baudrate > 75 && baudrate < 230400) { - /* get the divisor */ - custom = (__u16)(230400L / baudrate); - - /* Check for round off */ - round1 = (__u16)(2304000L / baudrate); - round = (__u16)(round1 - (custom * 10)); - if (round > 4) - custom++; - *divisor = custom; - - dbg("Baud %d = %d",baudrate, custom); - return 0; - } - - dbg("Baud calculation Failed..."); - return -EINVAL; -} - -/* - * send_cmd_write_baud_rate - * this function sends the proper command to change the baud rate of the - * specified port. - */ -static int send_cmd_write_baud_rate(struct moschip_port *mos7720_port, - int baudrate) -{ - struct usb_serial_port *port; - struct usb_serial *serial; - int divisor; - int status; - unsigned char data; - unsigned char number; - - if (mos7720_port == NULL) - return -1; - - port = mos7720_port->port; - serial = port->serial; - - dbg("%s: Entering ..........", __FUNCTION__); - - number = port->number - port->serial->minor; - dbg("%s - port = %d, baud = %d", __FUNCTION__, port->number, baudrate); - - /* Calculate the Divisor */ - status = calc_baud_rate_divisor(baudrate, &divisor); - if (status) { - err("%s - bad baud rate", __FUNCTION__); - return status; - } - - /* Enable access to divisor latch */ - data = mos7720_port->shadowLCR | UART_LCR_DLAB; - mos7720_port->shadowLCR = data; - send_mos_cmd(serial, MOS_WRITE, number, UART_LCR, &data); - - /* Write the divisor */ - data = ((unsigned char)(divisor & 0xff)); - send_mos_cmd(serial, MOS_WRITE, number, 0x00, &data); - - data = ((unsigned char)((divisor & 0xff00) >> 8)); - send_mos_cmd(serial, MOS_WRITE, number, 0x01, &data); - - /* Disable access to divisor latch */ - data = mos7720_port->shadowLCR & ~UART_LCR_DLAB; - mos7720_port->shadowLCR = data; - send_mos_cmd(serial, MOS_WRITE, number, 0x03, &data); - - return status; -} - -/* - * change_port_settings - * This routine is called to set the UART on the device to match - * the specified new settings. - */ -static void change_port_settings(struct moschip_port *mos7720_port, - struct termios *old_termios) -{ - struct usb_serial_port *port; - struct usb_serial *serial; - struct tty_struct *tty; - int baud; - unsigned cflag; - unsigned iflag; - __u8 mask = 0xff; - __u8 lData; - __u8 lParity; - __u8 lStop; - int status; - int port_number; - char data; - - if (mos7720_port == NULL) - return ; - - port = mos7720_port->port; - serial = port->serial; - port_number = port->number - port->serial->minor; - - dbg("%s - port %d", __FUNCTION__, port->number); - - if (!mos7720_port->open) { - dbg("%s - port not opened", __FUNCTION__); - return; - } - - tty = mos7720_port->port->tty; - - if ((!tty) || (!tty->termios)) { - dbg("%s - no tty structures", __FUNCTION__); - return; - } - - dbg("%s: Entering ..........", __FUNCTION__); - - lData = UART_LCR_WLEN8; - lStop = 0x00; /* 1 stop bit */ - lParity = 0x00; /* No parity */ - - cflag = tty->termios->c_cflag; - iflag = tty->termios->c_iflag; - - /* Change the number of bits */ - switch (cflag & CSIZE) { - case CS5: - lData = UART_LCR_WLEN5; - mask = 0x1f; - break; - - case CS6: - lData = UART_LCR_WLEN6; - mask = 0x3f; - break; - - case CS7: - lData = UART_LCR_WLEN7; - mask = 0x7f; - break; - default: - case CS8: - lData = UART_LCR_WLEN8; - break; - } - - /* Change the Parity bit */ - if (cflag & PARENB) { - if (cflag & PARODD) { - lParity = UART_LCR_PARITY; - dbg("%s - parity = odd", __FUNCTION__); - } else { - lParity = (UART_LCR_EPAR | UART_LCR_PARITY); - dbg("%s - parity = even", __FUNCTION__); - } - - } else { - dbg("%s - parity = none", __FUNCTION__); - } - - if (cflag & CMSPAR) - lParity = lParity | 0x20; - - /* Change the Stop bit */ - if (cflag & CSTOPB) { - lStop = UART_LCR_STOP; - dbg("%s - stop bits = 2", __FUNCTION__); - } else { - lStop = 0x00; - dbg("%s - stop bits = 1", __FUNCTION__); - } - -#define LCR_BITS_MASK 0x03 /* Mask for bits/char field */ -#define LCR_STOP_MASK 0x04 /* Mask for stop bits field */ -#define LCR_PAR_MASK 0x38 /* Mask for parity field */ - - /* Update the LCR with the correct value */ - mos7720_port->shadowLCR &= ~(LCR_BITS_MASK | LCR_STOP_MASK | LCR_PAR_MASK); - mos7720_port->shadowLCR |= (lData | lParity | lStop); - - - /* Disable Interrupts */ - data = 0x00; - send_mos_cmd(serial,MOS_WRITE,port->number - port->serial->minor, UART_IER, &data); - - data = 0x00; - send_mos_cmd(serial, MOS_WRITE, port_number, UART_FCR, &data); - - data = 0xcf; - send_mos_cmd(serial, MOS_WRITE, port_number, UART_FCR, &data); - - /* Send the updated LCR value to the mos7720 */ - data = mos7720_port->shadowLCR; - send_mos_cmd(serial, MOS_WRITE, port_number, UART_LCR, &data); - - data = 0x00b; - mos7720_port->shadowMCR = data; - send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data); - data = 0x00b; - send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data); - - /* set up the MCR register and send it to the mos7720 */ - mos7720_port->shadowMCR = UART_MCR_OUT2; - if (cflag & CBAUD) - mos7720_port->shadowMCR |= (UART_MCR_DTR | UART_MCR_RTS); - - if (cflag & CRTSCTS) { - mos7720_port->shadowMCR |= (UART_MCR_XONANY); - - /* To set hardware flow control to the specified * - * serial port, in SP1/2_CONTROL_REG */ - if (port->number) { - data = 0x001; - send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, - 0x08, &data); - } else { - data = 0x002; - send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, - 0x08, &data); - } - } else { - mos7720_port->shadowMCR &= ~(UART_MCR_XONANY); - } - - data = mos7720_port->shadowMCR; - send_mos_cmd(serial, MOS_WRITE, port_number, UART_MCR, &data); - - /* Determine divisor based on baud rate */ - baud = tty_get_baud_rate(tty); - if (!baud) { - /* pick a default, any default... */ - dbg("Picked default baud..."); - baud = 9600; - } - - if (baud >= 230400) { - set_higher_rates(mos7720_port, baud); - /* Enable Interrupts */ - data = 0x0c; - send_mos_cmd(serial, MOS_WRITE, port_number, UART_IER, &data); - return; - } - - dbg("%s - baud rate = %d", __FUNCTION__, baud); - status = send_cmd_write_baud_rate(mos7720_port, baud); - - /* Enable Interrupts */ - data = 0x0c; - send_mos_cmd(serial, MOS_WRITE, port_number, UART_IER, &data); - - if (port->read_urb->status != -EINPROGRESS) { - port->read_urb->dev = serial->dev; - - status = usb_submit_urb(port->read_urb, GFP_ATOMIC); - if (status) - dbg("usb_submit_urb(read bulk) failed, status = %d", - status); - } - return; -} - -/* - * mos7720_set_termios - * this function is called by the tty driver when it wants to change the - * termios structure. - */ -static void mos7720_set_termios(struct usb_serial_port *port, - struct termios *old_termios) -{ - int status; - unsigned int cflag; - struct usb_serial *serial; - struct moschip_port *mos7720_port; - struct tty_struct *tty; - - serial = port->serial; - - mos7720_port = usb_get_serial_port_data(port); - - if (mos7720_port == NULL) - return; - - tty = port->tty; - - if (!port->tty || !port->tty->termios) { - dbg("%s - no tty or termios", __FUNCTION__); - return; - } - - if (!mos7720_port->open) { - dbg("%s - port not opened", __FUNCTION__); - return; - } - - dbg("%s\n","setting termios - ASPIRE"); - - cflag = tty->termios->c_cflag; - - if (!cflag) { - printk("%s %s\n",__FUNCTION__,"cflag is NULL"); - return; - } - - /* check that they really want us to change something */ - if (old_termios) { - if ((cflag == old_termios->c_cflag) && - (RELEVANT_IFLAG(tty->termios->c_iflag) == - RELEVANT_IFLAG(old_termios->c_iflag))) { - dbg("Nothing to change"); - return; - } - } - - dbg("%s - clfag %08x iflag %08x", __FUNCTION__, - tty->termios->c_cflag, - RELEVANT_IFLAG(tty->termios->c_iflag)); - - if (old_termios) - dbg("%s - old clfag %08x old iflag %08x", __FUNCTION__, - old_termios->c_cflag, - RELEVANT_IFLAG(old_termios->c_iflag)); - - dbg("%s - port %d", __FUNCTION__, port->number); - - /* change the port settings to the new ones specified */ - change_port_settings(mos7720_port, old_termios); - - if(!port->read_urb) { - dbg("%s","URB KILLED !!!!!\n"); - return; - } - - if(port->read_urb->status != -EINPROGRESS) { - port->read_urb->dev = serial->dev; - status = usb_submit_urb(port->read_urb, GFP_ATOMIC); - if (status) - dbg("usb_submit_urb(read bulk) failed, status = %d", - status); - } - return; -} - -/* - * 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 - * release the bus after transmitting. This must be done when - * 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 int get_lsr_info(struct moschip_port *mos7720_port, - unsigned int __user *value) -{ - int count; - unsigned int result = 0; - - count = mos7720_chars_in_buffer(mos7720_port->port); - if (count == 0) { - dbg("%s -- Empty", __FUNCTION__); - result = TIOCSER_TEMT; - } - - if (copy_to_user(value, &result, sizeof(int))) - return -EFAULT; - return 0; -} - -/* - * get_number_bytes_avail - get number of bytes available - * - * Purpose: Let user call ioctl to get the count of number of bytes available. - */ -static int get_number_bytes_avail(struct moschip_port *mos7720_port, - unsigned int __user *value) -{ - unsigned int result = 0; - struct tty_struct *tty = mos7720_port->port->tty; - - if (!tty) - return -ENOIOCTLCMD; - - result = tty->read_cnt; - - dbg("%s(%d) = %d", __FUNCTION__, mos7720_port->port->number, result); - if (copy_to_user(value, &result, sizeof(int))) - return -EFAULT; - - return -ENOIOCTLCMD; -} - -static int set_modem_info(struct moschip_port *mos7720_port, unsigned int cmd, - unsigned int __user *value) -{ - unsigned int mcr ; - unsigned int arg; - unsigned char data; - - struct usb_serial_port *port; - - if (mos7720_port == NULL) - return -1; - - port = (struct usb_serial_port*)mos7720_port->port; - mcr = mos7720_port->shadowMCR; - - if (copy_from_user(&arg, value, sizeof(int))) - return -EFAULT; - - switch (cmd) { - case TIOCMBIS: - if (arg & TIOCM_RTS) - mcr |= UART_MCR_RTS; - if (arg & TIOCM_DTR) - mcr |= UART_MCR_RTS; - if (arg & TIOCM_LOOP) - mcr |= UART_MCR_LOOP; - break; - - case TIOCMBIC: - if (arg & TIOCM_RTS) - mcr &= ~UART_MCR_RTS; - if (arg & TIOCM_DTR) - mcr &= ~UART_MCR_RTS; - if (arg & TIOCM_LOOP) - mcr &= ~UART_MCR_LOOP; - break; - - case TIOCMSET: - /* turn off the RTS and DTR and LOOPBACK - * and then only turn on what was asked to */ - mcr &= ~(UART_MCR_RTS | UART_MCR_DTR | UART_MCR_LOOP); - mcr |= ((arg & TIOCM_RTS) ? UART_MCR_RTS : 0); - mcr |= ((arg & TIOCM_DTR) ? UART_MCR_DTR : 0); - mcr |= ((arg & TIOCM_LOOP) ? UART_MCR_LOOP : 0); - break; - } - - mos7720_port->shadowMCR = mcr; - - data = mos7720_port->shadowMCR; - send_mos_cmd(port->serial, MOS_WRITE, - port->number - port->serial->minor, UART_MCR, &data); - - return 0; -} - -static int get_modem_info(struct moschip_port *mos7720_port, - unsigned int __user *value) -{ - unsigned int result = 0; - unsigned int msr = mos7720_port->shadowMSR; - unsigned int mcr = mos7720_port->shadowMCR; - - result = ((mcr & UART_MCR_DTR) ? TIOCM_DTR: 0) /* 0x002 */ - | ((mcr & UART_MCR_RTS) ? TIOCM_RTS: 0) /* 0x004 */ - | ((msr & UART_MSR_CTS) ? TIOCM_CTS: 0) /* 0x020 */ - | ((msr & UART_MSR_DCD) ? TIOCM_CAR: 0) /* 0x040 */ - | ((msr & UART_MSR_RI) ? TIOCM_RI: 0) /* 0x080 */ - | ((msr & UART_MSR_DSR) ? TIOCM_DSR: 0); /* 0x100 */ - - - dbg("%s -- %x", __FUNCTION__, result); - - if (copy_to_user(value, &result, sizeof(int))) - return -EFAULT; - return 0; -} - -static int get_serial_info(struct moschip_port *mos7720_port, - struct serial_struct __user *retinfo) -{ - struct serial_struct tmp; - - if (!retinfo) - return -EFAULT; - - memset(&tmp, 0, sizeof(tmp)); - - tmp.type = PORT_16550A; - tmp.line = mos7720_port->port->serial->minor; - tmp.port = mos7720_port->port->number; - tmp.irq = 0; - tmp.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ; - tmp.xmit_fifo_size = NUM_URBS * URB_TRANSFER_BUFFER_SIZE; - tmp.baud_base = 9600; - tmp.close_delay = 5*HZ; - tmp.closing_wait = 30*HZ; - - if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) - return -EFAULT; - return 0; -} - -static int mos7720_ioctl(struct usb_serial_port *port, struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct moschip_port *mos7720_port; - struct async_icount cnow; - struct async_icount cprev; - struct serial_icounter_struct icount; - - mos7720_port = usb_get_serial_port_data(port); - if (mos7720_port == NULL) - return -ENODEV; - - dbg("%s - port %d, cmd = 0x%x", __FUNCTION__, port->number, cmd); - - switch (cmd) { - case TIOCINQ: - /* return number of bytes available */ - dbg("%s (%d) TIOCINQ", __FUNCTION__, port->number); - return get_number_bytes_avail(mos7720_port, - (unsigned int __user *)arg); - break; - - case TIOCSERGETLSR: - dbg("%s (%d) TIOCSERGETLSR", __FUNCTION__, port->number); - return get_lsr_info(mos7720_port, (unsigned int __user *)arg); - return 0; - - case TIOCMBIS: - case TIOCMBIC: - case TIOCMSET: - dbg("%s (%d) TIOCMSET/TIOCMBIC/TIOCMSET", __FUNCTION__, - port->number); - return set_modem_info(mos7720_port, cmd, - (unsigned int __user *)arg); - - case TIOCMGET: - dbg("%s (%d) TIOCMGET", __FUNCTION__, port->number); - return get_modem_info(mos7720_port, - (unsigned int __user *)arg); - - case TIOCGSERIAL: - dbg("%s (%d) TIOCGSERIAL", __FUNCTION__, port->number); - return get_serial_info(mos7720_port, - (struct serial_struct __user *)arg); - - case TIOCSSERIAL: - dbg("%s (%d) TIOCSSERIAL", __FUNCTION__, port->number); - break; - - case TIOCMIWAIT: - dbg("%s (%d) TIOCMIWAIT", __FUNCTION__, port->number); - cprev = mos7720_port->icount; - while (1) { - if (signal_pending(current)) - return -ERESTARTSYS; - cnow = mos7720_port->icount; - if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && - cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) - return -EIO; /* no change => error */ - if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || - ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || - ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || - ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) { - return 0; - } - cprev = cnow; - } - /* NOTREACHED */ - break; - - case TIOCGICOUNT: - cnow = mos7720_port->icount; - icount.cts = cnow.cts; - icount.dsr = cnow.dsr; - icount.rng = cnow.rng; - icount.dcd = cnow.dcd; - icount.rx = cnow.rx; - icount.tx = cnow.tx; - icount.frame = cnow.frame; - icount.overrun = cnow.overrun; - icount.parity = cnow.parity; - icount.brk = cnow.brk; - icount.buf_overrun = cnow.buf_overrun; - - dbg("%s (%d) TIOCGICOUNT RX=%d, TX=%d", __FUNCTION__, - port->number, icount.rx, icount.tx ); - if (copy_to_user((void __user *)arg, &icount, sizeof(icount))) - return -EFAULT; - return 0; - } - - return -ENOIOCTLCMD; -} - -static int mos7720_startup(struct usb_serial *serial) -{ - struct moschip_serial *mos7720_serial; - struct moschip_port *mos7720_port; - struct usb_device *dev; - int i; - char data; - - dbg("%s: Entering ..........", __FUNCTION__); - - if (!serial) { - dbg("Invalid Handler"); - return -ENODEV; - } - - dev = serial->dev; - - /* create our private serial structure */ - mos7720_serial = kzalloc(sizeof(struct moschip_serial), GFP_KERNEL); - if (mos7720_serial == NULL) { - err("%s - Out of memory", __FUNCTION__); - return -ENOMEM; - } - - usb_set_serial_data(serial, mos7720_serial); - - /* we set up the pointers to the endpoints in the mos7720_open * - * function, as the structures aren't created yet. */ - - /* set up port private structures */ - for (i = 0; i < serial->num_ports; ++i) { - mos7720_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL); - if (mos7720_port == NULL) { - err("%s - Out of memory", __FUNCTION__); - usb_set_serial_data(serial, NULL); - kfree(mos7720_serial); - return -ENOMEM; - } - - /* Initialize all port interrupt end point to port 0 int - * endpoint. Our device has only one interrupt endpoint - * comman to all ports */ - serial->port[i]->interrupt_in_endpointAddress = serial->port[0]->interrupt_in_endpointAddress; - - mos7720_port->port = serial->port[i]; - usb_set_serial_port_data(serial->port[i], mos7720_port); - - dbg("port number is %d", serial->port[i]->number); - dbg("serial number is %d", serial->minor); - } - - - /* setting configuration feature to one */ - usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), - (__u8)0x03, 0x00,0x01,0x00, NULL, 0x00, 5*HZ); - - send_mos_cmd(serial,MOS_READ,0x00, UART_LSR, &data); // LSR For Port 1 - dbg("LSR:%x",data); - - send_mos_cmd(serial,MOS_READ,0x01, UART_LSR, &data); // LSR For Port 2 - dbg("LSR:%x",data); - - return 0; -} - -static void mos7720_shutdown(struct usb_serial *serial) -{ - int i; - - /* free private structure allocated for serial port */ - for (i=0; i < serial->num_ports; ++i) { - kfree(usb_get_serial_port_data(serial->port[i])); - usb_set_serial_port_data(serial->port[i], NULL); - } - - /* free private structure allocated for serial device */ - kfree(usb_get_serial_data(serial)); - usb_set_serial_data(serial, NULL); -} - -static struct usb_serial_driver moschip7720_2port_driver = { - .driver = { - .owner = THIS_MODULE, - .name = "moschip7720", - }, - .description = "Moschip 2 port adapter", - .id_table = moschip_port_id_table, - .num_interrupt_in = 1, - .num_bulk_in = 2, - .num_bulk_out = 2, - .num_ports = 2, - .open = mos7720_open, - .close = mos7720_close, - .throttle = mos7720_throttle, - .unthrottle = mos7720_unthrottle, - .attach = mos7720_startup, - .shutdown = mos7720_shutdown, - .ioctl = mos7720_ioctl, - .set_termios = mos7720_set_termios, - .write = mos7720_write, - .write_room = mos7720_write_room, - .chars_in_buffer = mos7720_chars_in_buffer, - .break_ctl = mos7720_break, - .read_bulk_callback = mos7720_bulk_in_callback, -}; - -static struct usb_driver usb_driver = { - .name = "moschip7720", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = moschip_port_id_table, -}; - -static int __init moschip7720_init(void) -{ - int retval; - - dbg("%s: Entering ..........", __FUNCTION__); - - /* Register with the usb serial */ - retval = usb_serial_register(&moschip7720_2port_driver); - if (retval) - goto failed_port_device_register; - - info(DRIVER_DESC " " DRIVER_VERSION); - - /* Register with the usb */ - retval = usb_register(&usb_driver); - if (retval) - goto failed_usb_register; - - return 0; - -failed_usb_register: - usb_serial_deregister(&moschip7720_2port_driver); - -failed_port_device_register: - return retval; -} - -static void __exit moschip7720_exit(void) -{ - usb_deregister(&usb_driver); - usb_serial_deregister(&moschip7720_2port_driver); -} - -module_init(moschip7720_init); -module_exit(moschip7720_exit); - -/* Module information */ -MODULE_AUTHOR( DRIVER_AUTHOR ); -MODULE_DESCRIPTION( DRIVER_DESC ); -MODULE_LICENSE("GPL"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug enabled or not"); diff --git a/trunk/drivers/usb/serial/mos7840.c b/trunk/drivers/usb/serial/mos7840.c index 02c89e10b2cf..95bf57166c59 100644 --- a/trunk/drivers/usb/serial/mos7840.c +++ b/trunk/drivers/usb/serial/mos7840.c @@ -421,7 +421,7 @@ static int mos7840_handle_new_lsr(struct moschip_port *port, __u8 new_lsr) /************************************************************************/ /************************************************************************/ -static void mos7840_control_callback(struct urb *urb) +static void mos7840_control_callback(struct urb *urb, struct pt_regs *regs) { unsigned char *data; struct moschip_port *mos7840_port; @@ -497,7 +497,7 @@ static int mos7840_get_reg(struct moschip_port *mcs, __u16 Wval, __u16 reg, * interrupt endpoint. *****************************************************************************/ -static void mos7840_interrupt_callback(struct urb *urb) +static void mos7840_interrupt_callback(struct urb *urb, struct pt_regs *regs) { int result; int length; @@ -647,7 +647,7 @@ static struct usb_serial *mos7840_get_usb_serial(struct usb_serial_port *port, * bulk in endpoint. *****************************************************************************/ -static void mos7840_bulk_in_callback(struct urb *urb) +static void mos7840_bulk_in_callback(struct urb *urb, struct pt_regs *regs) { int status; unsigned char *data; @@ -726,7 +726,8 @@ static void mos7840_bulk_in_callback(struct urb *urb) * on the bulk out endpoint. *****************************************************************************/ -static void mos7840_bulk_out_data_callback(struct urb *urb) +static void mos7840_bulk_out_data_callback(struct urb *urb, + struct pt_regs *regs) { struct moschip_port *mos7840_port; struct tty_struct *tty; @@ -1087,7 +1088,7 @@ static int mos7840_open(struct usb_serial_port *port, struct file *filp) mos7840_port->icount.tx = 0; mos7840_port->icount.rx = 0; - dbg("\n\nusb_serial serial:%p mos7840_port:%p\n usb_serial_port port:%p\n\n", serial, mos7840_port, port); + dbg("\n\nusb_serial serial:%x mos7840_port:%x\n usb_serial_port port:%x\n\n", (unsigned int)serial, (unsigned int)mos7840_port, (unsigned int)port); return 0; @@ -1420,6 +1421,7 @@ static int mos7840_write(struct usb_serial_port *port, int i; int bytes_sent = 0; int transfer_size; + int from_user = 0; struct moschip_port *mos7840_port; struct usb_serial *serial; @@ -1510,7 +1512,15 @@ static int mos7840_write(struct usb_serial_port *port, } transfer_size = min(count, URB_TRANSFER_BUFFER_SIZE); - memcpy(urb->transfer_buffer, current_position, transfer_size); + if (from_user) { + if (copy_from_user + (urb->transfer_buffer, current_position, transfer_size)) { + bytes_sent = -EFAULT; + goto exit; + } + } else { + memcpy(urb->transfer_buffer, current_position, transfer_size); + } /* fill urb with data and submit */ usb_fill_bulk_urb(urb, @@ -2216,7 +2226,7 @@ static void mos7840_set_termios(struct usb_serial_port *port, *****************************************************************************/ static int mos7840_get_lsr_info(struct moschip_port *mos7840_port, - unsigned int __user *value) + unsigned int *value) { int count; unsigned int result = 0; @@ -2239,7 +2249,7 @@ static int mos7840_get_lsr_info(struct moschip_port *mos7840_port, *****************************************************************************/ static int mos7840_get_bytes_avail(struct moschip_port *mos7840_port, - unsigned int __user *value) + unsigned int *value) { unsigned int result = 0; struct tty_struct *tty = mos7840_port->port->tty; @@ -2262,7 +2272,7 @@ static int mos7840_get_bytes_avail(struct moschip_port *mos7840_port, *****************************************************************************/ static int mos7840_set_modem_info(struct moschip_port *mos7840_port, - unsigned int cmd, unsigned int __user *value) + unsigned int cmd, unsigned int *value) { unsigned int mcr; unsigned int arg; @@ -2332,7 +2342,7 @@ static int mos7840_set_modem_info(struct moschip_port *mos7840_port, *****************************************************************************/ static int mos7840_get_modem_info(struct moschip_port *mos7840_port, - unsigned int __user *value) + unsigned int *value) { unsigned int result = 0; __u16 msr; @@ -2361,7 +2371,7 @@ static int mos7840_get_modem_info(struct moschip_port *mos7840_port, *****************************************************************************/ static int mos7840_get_serial_info(struct moschip_port *mos7840_port, - struct serial_struct __user *retinfo) + struct serial_struct *retinfo) { struct serial_struct tmp; @@ -2396,7 +2406,6 @@ static int mos7840_get_serial_info(struct moschip_port *mos7840_port, static int mos7840_ioctl(struct usb_serial_port *port, struct file *file, unsigned int cmd, unsigned long arg) { - void __user *argp = (void __user *)arg; struct moschip_port *mos7840_port; struct tty_struct *tty; @@ -2413,12 +2422,11 @@ static int mos7840_ioctl(struct usb_serial_port *port, struct file *file, } mos7840_port = mos7840_get_port_private(port); + tty = mos7840_port->port->tty; if (mos7840_port == NULL) return -1; - tty = mos7840_port->port->tty; - dbg("%s - port %d, cmd = 0x%x", __FUNCTION__, port->number, cmd); switch (cmd) { @@ -2426,13 +2434,16 @@ static int mos7840_ioctl(struct usb_serial_port *port, struct file *file, case TIOCINQ: dbg("%s (%d) TIOCINQ", __FUNCTION__, port->number); - return mos7840_get_bytes_avail(mos7840_port, argp); + return mos7840_get_bytes_avail(mos7840_port, + (unsigned int *)arg); + break; case TIOCOUTQ: dbg("%s (%d) TIOCOUTQ", __FUNCTION__, port->number); return put_user(tty->driver->chars_in_buffer ? tty->driver->chars_in_buffer(tty) : 0, (int __user *)arg); + break; case TCFLSH: retval = tty_check_change(tty); @@ -2462,13 +2473,13 @@ static int mos7840_ioctl(struct usb_serial_port *port, struct file *file, case TCGETS: if (kernel_termios_to_user_termios - ((struct termios __user *)argp, tty->termios)) + ((struct termios __user *)arg, tty->termios)) return -EFAULT; return 0; case TIOCSERGETLSR: dbg("%s (%d) TIOCSERGETLSR", __FUNCTION__, port->number); - return mos7840_get_lsr_info(mos7840_port, argp); + return mos7840_get_lsr_info(mos7840_port, (unsigned int *)arg); return 0; case TIOCMBIS: @@ -2477,16 +2488,19 @@ static int mos7840_ioctl(struct usb_serial_port *port, struct file *file, dbg("%s (%d) TIOCMSET/TIOCMBIC/TIOCMSET", __FUNCTION__, port->number); mosret = - mos7840_set_modem_info(mos7840_port, cmd, argp); + mos7840_set_modem_info(mos7840_port, cmd, + (unsigned int *)arg); return mosret; case TIOCMGET: dbg("%s (%d) TIOCMGET", __FUNCTION__, port->number); - return mos7840_get_modem_info(mos7840_port, argp); + return mos7840_get_modem_info(mos7840_port, + (unsigned int *)arg); case TIOCGSERIAL: dbg("%s (%d) TIOCGSERIAL", __FUNCTION__, port->number); - return mos7840_get_serial_info(mos7840_port, argp); + return mos7840_get_serial_info(mos7840_port, + (struct serial_struct *)arg); case TIOCSSERIAL: dbg("%s (%d) TIOCSSERIAL", __FUNCTION__, port->number); @@ -2536,7 +2550,7 @@ static int mos7840_ioctl(struct usb_serial_port *port, struct file *file, dbg("%s (%d) TIOCGICOUNT RX=%d, TX=%d", __FUNCTION__, port->number, icount.rx, icount.tx); - if (copy_to_user(argp, &icount, sizeof(icount))) + if (copy_to_user((void *)arg, &icount, sizeof(icount))) return -EFAULT; return 0; @@ -2596,11 +2610,12 @@ static int mos7840_startup(struct usb_serial *serial) /* set up port private structures */ for (i = 0; i < serial->num_ports; ++i) { - mos7840_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL); + mos7840_port = kmalloc(sizeof(struct moschip_port), GFP_KERNEL); if (mos7840_port == NULL) { err("%s - Out of memory", __FUNCTION__); return -ENOMEM; } + memset(mos7840_port, 0, sizeof(struct moschip_port)); /* Initialize all port interrupt end point to port 0 int endpoint * * Our device has only one interrupt end point comman to all port */ @@ -2803,7 +2818,7 @@ static int mos7840_startup(struct usb_serial *serial) /* setting configuration feature to one */ usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), - (__u8) 0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5 * HZ); + (__u8) 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 5 * HZ); return 0; } diff --git a/trunk/drivers/usb/serial/navman.c b/trunk/drivers/usb/serial/navman.c index 054abee81652..ac3f8b5d2c49 100644 --- a/trunk/drivers/usb/serial/navman.c +++ b/trunk/drivers/usb/serial/navman.c @@ -32,7 +32,7 @@ static struct usb_driver navman_driver = { .no_dynamic_id = 1, }; -static void navman_read_int_callback(struct urb *urb) +static void navman_read_int_callback(struct urb *urb, struct pt_regs *regs) { struct usb_serial_port *port = urb->context; unsigned char *data = urb->transfer_buffer; @@ -95,7 +95,8 @@ static void navman_close(struct usb_serial_port *port, struct file *filp) { dbg("%s - port %d", __FUNCTION__, port->number); - usb_kill_urb(port->interrupt_in_urb); + if (port->interrupt_in_urb) + usb_kill_urb(port->interrupt_in_urb); } static int navman_write(struct usb_serial_port *port, diff --git a/trunk/drivers/usb/serial/omninet.c b/trunk/drivers/usb/serial/omninet.c index bc91d3b726fc..a764ff4e326c 100644 --- a/trunk/drivers/usb/serial/omninet.c +++ b/trunk/drivers/usb/serial/omninet.c @@ -64,8 +64,8 @@ static int debug; /* function prototypes */ static int omninet_open (struct usb_serial_port *port, struct file *filp); static void omninet_close (struct usb_serial_port *port, struct file *filp); -static void omninet_read_bulk_callback (struct urb *urb); -static void omninet_write_bulk_callback (struct urb *urb); +static void omninet_read_bulk_callback (struct urb *urb, struct pt_regs *regs); +static void omninet_write_bulk_callback (struct urb *urb, struct pt_regs *regs); static int omninet_write (struct usb_serial_port *port, const unsigned char *buf, int count); static int omninet_write_room (struct usb_serial_port *port); static void omninet_shutdown (struct usb_serial *serial); @@ -194,7 +194,7 @@ static void omninet_close (struct usb_serial_port *port, struct file * filp) #define OMNINET_HEADERLEN sizeof(struct omninet_header) #define OMNINET_BULKOUTSIZE (64 - OMNINET_HEADERLEN) -static void omninet_read_bulk_callback (struct urb *urb) +static void omninet_read_bulk_callback (struct urb *urb, struct pt_regs *regs) { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; unsigned char *data = urb->transfer_buffer; @@ -306,7 +306,7 @@ static int omninet_write_room (struct usb_serial_port *port) return (room); } -static void omninet_write_bulk_callback (struct urb *urb) +static void omninet_write_bulk_callback (struct urb *urb, struct pt_regs *regs) { /* struct omninet_header *header = (struct omninet_header *) urb->transfer_buffer; */ struct usb_serial_port *port = (struct usb_serial_port *) urb->context; diff --git a/trunk/drivers/usb/serial/option.c b/trunk/drivers/usb/serial/option.c index 130afbbd3fca..c856e6f40e22 100644 --- a/trunk/drivers/usb/serial/option.c +++ b/trunk/drivers/usb/serial/option.c @@ -50,7 +50,7 @@ static void option_rx_throttle(struct usb_serial_port *port); static void option_rx_unthrottle(struct usb_serial_port *port); static int option_write_room(struct usb_serial_port *port); -static void option_instat_callback(struct urb *urb); +static void option_instat_callback(struct urb *urb, struct pt_regs *regs); static int option_write(struct usb_serial_port *port, const unsigned char *buf, int count); @@ -337,7 +337,7 @@ static int option_write(struct usb_serial_port *port, return count; } -static void option_indat_callback(struct urb *urb) +static void option_indat_callback(struct urb *urb, struct pt_regs *regs) { int err; int endpoint; @@ -374,7 +374,7 @@ static void option_indat_callback(struct urb *urb) return; } -static void option_outdat_callback(struct urb *urb) +static void option_outdat_callback(struct urb *urb, struct pt_regs *regs) { struct usb_serial_port *port; @@ -385,7 +385,7 @@ static void option_outdat_callback(struct urb *urb) usb_serial_port_softint(port); } -static void option_instat_callback(struct urb *urb) +static void option_instat_callback(struct urb *urb, struct pt_regs *regs) { int err; struct usb_serial_port *port = (struct usb_serial_port *) urb->context; @@ -565,7 +565,7 @@ static void option_close(struct usb_serial_port *port, struct file *filp) /* Helper functions used by option_setup_urbs */ static struct urb *option_setup_urb(struct usb_serial *serial, int endpoint, int dir, void *ctx, char *buf, int len, - void (*callback)(struct urb *)) + void (*callback)(struct urb *, struct pt_regs *regs)) { struct urb *urb; diff --git a/trunk/drivers/usb/serial/pl2303.c b/trunk/drivers/usb/serial/pl2303.c index bc800c8787a8..9c18173e33fb 100644 --- a/trunk/drivers/usb/serial/pl2303.c +++ b/trunk/drivers/usb/serial/pl2303.c @@ -948,7 +948,7 @@ static void pl2303_update_line_status(struct usb_serial_port *port, wake_up_interruptible(&priv->delta_msr_wait); } -static void pl2303_read_int_callback(struct urb *urb) +static void pl2303_read_int_callback(struct urb *urb, struct pt_regs *regs) { struct usb_serial_port *port = (struct usb_serial_port *) urb->context; unsigned char *data = urb->transfer_buffer; @@ -987,7 +987,7 @@ static void pl2303_read_int_callback(struct urb *urb) __FUNCTION__, status); } -static void pl2303_read_bulk_callback(struct urb *urb) +static void pl2303_read_bulk_callback(struct urb *urb, struct pt_regs *regs) { struct usb_serial_port *port = (struct usb_serial_port *) urb->context; struct pl2303_private *priv = usb_get_serial_port_data(port); @@ -1070,7 +1070,7 @@ static void pl2303_read_bulk_callback(struct urb *urb) return; } -static void pl2303_write_bulk_callback(struct urb *urb) +static void pl2303_write_bulk_callback(struct urb *urb, struct pt_regs *regs) { struct usb_serial_port *port = (struct usb_serial_port *) urb->context; struct pl2303_private *priv = usb_get_serial_port_data(port); diff --git a/trunk/drivers/usb/serial/safe_serial.c b/trunk/drivers/usb/serial/safe_serial.c index 30b7ebc8d45d..1e07dfad6853 100644 --- a/trunk/drivers/usb/serial/safe_serial.c +++ b/trunk/drivers/usb/serial/safe_serial.c @@ -204,7 +204,7 @@ static __u16 __inline__ fcs_compute10 (unsigned char *sp, int len, __u16 fcs) return fcs; } -static void safe_read_bulk_callback (struct urb *urb) +static void safe_read_bulk_callback (struct urb *urb, struct pt_regs *regs) { struct usb_serial_port *port = (struct usb_serial_port *) urb->context; unsigned char *data = urb->transfer_buffer; diff --git a/trunk/drivers/usb/serial/sierra.c b/trunk/drivers/usb/serial/sierra.c index 4b5097fa48d7..d29638daa987 100644 --- a/trunk/drivers/usb/serial/sierra.c +++ b/trunk/drivers/usb/serial/sierra.c @@ -1,713 +1,75 @@ /* - USB Driver for Sierra Wireless - - Copyright (C) 2006 Kevin Lloyd - - IMPORTANT DISCLAIMER: This driver is not commercially supported by - Sierra Wireless. Use at your own risk. - - This driver 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. - - Portions based on the option driver by Matthias Urlichs - Whom based his on the Keyspan driver by Hugh Blemings - - History: -*/ - -#define DRIVER_VERSION "v.1.0.5" -#define DRIVER_AUTHOR "Kevin Lloyd " -#define DRIVER_DESC "USB Driver for Sierra Wireless USB modems" + * Sierra Wireless CDMA Wireless Serial USB driver + * + * Current Copy modified by: Kevin Lloyd + * Original Copyright (C) 2005-2006 Greg Kroah-Hartman + * + * 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 #include #include - static struct usb_device_id id_table [] = { { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */ { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */ { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ - { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */ - { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 for Europe */ { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 */ { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */ - - { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */ - { USB_DEVICE(0x0F3D, 0x0112) }, /* AirPrime/Sierra PC 5220 */ + /* Following devices are supported in the airprime.c driver */ + /* { USB_DEVICE(0x1199, 0x0112) }, */ /* Sierra Wireless AirCard 580 */ + /* { USB_DEVICE(0x0F3D, 0x0112) }, */ /* AirPrime/Sierra PC 5220 */ { } }; MODULE_DEVICE_TABLE(usb, id_table); -static struct usb_device_id id_table_1port [] = { - { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */ - { USB_DEVICE(0x0F3D, 0x0112) }, /* AirPrime/Sierra PC 5220 */ - { } -}; - -static struct usb_device_id id_table_3port [] = { - { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */ - { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */ - { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ - { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ - { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ - { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ - { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */ - { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 for Europe */ - { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 */ - { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */ - { } -}; - static struct usb_driver sierra_driver = { - .name = "sierra", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table, - .no_dynamic_id = 1, -}; - - -static int debug; - -/* per port private data */ -#define N_IN_URB 4 -#define N_OUT_URB 1 -#define IN_BUFLEN 4096 -#define OUT_BUFLEN 128 - -struct sierra_port_private { - /* Input endpoints and buffer for this port */ - struct urb *in_urbs[N_IN_URB]; - char in_buffer[N_IN_URB][IN_BUFLEN]; - /* Output endpoints and buffer for this port */ - struct urb *out_urbs[N_OUT_URB]; - char out_buffer[N_OUT_URB][OUT_BUFLEN]; - - /* Settings for the port */ - int rts_state; /* Handshaking pins (outputs) */ - int dtr_state; - int cts_state; /* Handshaking pins (inputs) */ - int dsr_state; - int dcd_state; - int ri_state; - - unsigned long tx_start_time[N_OUT_URB]; -}; - -static int sierra_send_setup(struct usb_serial_port *port) -{ - struct usb_serial *serial = port->serial; - struct sierra_port_private *portdata; - - dbg("%s", __FUNCTION__); - - portdata = usb_get_serial_port_data(port); - - if (port->tty) { - int val = 0; - if (portdata->dtr_state) - val |= 0x01; - if (portdata->rts_state) - val |= 0x02; - - return usb_control_msg(serial->dev, - usb_rcvctrlpipe(serial->dev, 0), - 0x22,0x21,val,0,NULL,0,USB_CTRL_SET_TIMEOUT); - } - - return 0; -} - -static void sierra_rx_throttle(struct usb_serial_port *port) -{ - dbg("%s", __FUNCTION__); -} - -static void sierra_rx_unthrottle(struct usb_serial_port *port) -{ - dbg("%s", __FUNCTION__); -} - -static void sierra_break_ctl(struct usb_serial_port *port, int break_state) -{ - /* Unfortunately, I don't know how to send a break */ - dbg("%s", __FUNCTION__); -} - -static void sierra_set_termios(struct usb_serial_port *port, - struct termios *old_termios) -{ - dbg("%s", __FUNCTION__); - - sierra_send_setup(port); -} - -static int sierra_tiocmget(struct usb_serial_port *port, struct file *file) -{ - unsigned int value; - struct sierra_port_private *portdata; - - portdata = usb_get_serial_port_data(port); - - value = ((portdata->rts_state) ? TIOCM_RTS : 0) | - ((portdata->dtr_state) ? TIOCM_DTR : 0) | - ((portdata->cts_state) ? TIOCM_CTS : 0) | - ((portdata->dsr_state) ? TIOCM_DSR : 0) | - ((portdata->dcd_state) ? TIOCM_CAR : 0) | - ((portdata->ri_state) ? TIOCM_RNG : 0); - - return value; -} - -static int sierra_tiocmset(struct usb_serial_port *port, struct file *file, - unsigned int set, unsigned int clear) -{ - struct sierra_port_private *portdata; - - portdata = usb_get_serial_port_data(port); - - if (set & TIOCM_RTS) - portdata->rts_state = 1; - if (set & TIOCM_DTR) - portdata->dtr_state = 1; - - if (clear & TIOCM_RTS) - portdata->rts_state = 0; - if (clear & TIOCM_DTR) - portdata->dtr_state = 0; - return sierra_send_setup(port); -} - -static int sierra_ioctl(struct usb_serial_port *port, struct file *file, - unsigned int cmd, unsigned long arg) -{ - return -ENOIOCTLCMD; -} - -/* Write */ -static int sierra_write(struct usb_serial_port *port, - const unsigned char *buf, int count) -{ - struct sierra_port_private *portdata; - int i; - int left, todo; - struct urb *this_urb = NULL; /* spurious */ - int err; - - portdata = usb_get_serial_port_data(port); - - dbg("%s: write (%d chars)", __FUNCTION__, count); - - i = 0; - left = count; - for (i=0; left > 0 && i < N_OUT_URB; i++) { - todo = left; - if (todo > OUT_BUFLEN) - todo = OUT_BUFLEN; - - this_urb = portdata->out_urbs[i]; - if (this_urb->status == -EINPROGRESS) { - if (time_before(jiffies, - portdata->tx_start_time[i] + 10 * HZ)) - continue; - usb_unlink_urb(this_urb); - continue; - } - if (this_urb->status != 0) - dbg("usb_write %p failed (err=%d)", - this_urb, this_urb->status); - - dbg("%s: endpoint %d buf %d", __FUNCTION__, - usb_pipeendpoint(this_urb->pipe), i); - - /* send the data */ - memcpy (this_urb->transfer_buffer, buf, todo); - this_urb->transfer_buffer_length = todo; - - this_urb->dev = port->serial->dev; - err = usb_submit_urb(this_urb, GFP_ATOMIC); - if (err) { - dbg("usb_submit_urb %p (write bulk) failed " - "(%d, has %d)", this_urb, - err, this_urb->status); - continue; - } - portdata->tx_start_time[i] = jiffies; - buf += todo; - left -= todo; - } - - count -= left; - dbg("%s: wrote (did %d)", __FUNCTION__, count); - return count; -} - -static void sierra_indat_callback(struct urb *urb) -{ - int err; - int endpoint; - struct usb_serial_port *port; - struct tty_struct *tty; - unsigned char *data = urb->transfer_buffer; - - dbg("%s: %p", __FUNCTION__, urb); - - endpoint = usb_pipeendpoint(urb->pipe); - port = (struct usb_serial_port *) urb->context; - - if (urb->status) { - dbg("%s: nonzero status: %d on endpoint %02x.", - __FUNCTION__, urb->status, endpoint); - } else { - tty = port->tty; - if (urb->actual_length) { - tty_buffer_request_room(tty, urb->actual_length); - tty_insert_flip_string(tty, data, urb->actual_length); - tty_flip_buffer_push(tty); - } else { - dbg("%s: empty read urb received", __FUNCTION__); - } - - /* Resubmit urb so we continue receiving */ - if (port->open_count && urb->status != -ESHUTDOWN) { - err = usb_submit_urb(urb, GFP_ATOMIC); - if (err) - printk(KERN_ERR "%s: resubmit read urb failed. " - "(%d)", __FUNCTION__, err); - } - } - return; -} - -static void sierra_outdat_callback(struct urb *urb) -{ - struct usb_serial_port *port; - - dbg("%s", __FUNCTION__); - - port = (struct usb_serial_port *) urb->context; - - usb_serial_port_softint(port); -} - -static void sierra_instat_callback(struct urb *urb) -{ - int err; - struct usb_serial_port *port = (struct usb_serial_port *) urb->context; - struct sierra_port_private *portdata = usb_get_serial_port_data(port); - struct usb_serial *serial = port->serial; - - dbg("%s", __FUNCTION__); - dbg("%s: urb %p port %p has data %p", __FUNCTION__,urb,port,portdata); - - if (urb->status == 0) { - struct usb_ctrlrequest *req_pkt = - (struct usb_ctrlrequest *)urb->transfer_buffer; - - if (!req_pkt) { - dbg("%s: NULL req_pkt\n", __FUNCTION__); - return; - } - if ((req_pkt->bRequestType == 0xA1) && - (req_pkt->bRequest == 0x20)) { - int old_dcd_state; - unsigned char signals = *((unsigned char *) - urb->transfer_buffer + - sizeof(struct usb_ctrlrequest)); - - dbg("%s: signal x%x", __FUNCTION__, signals); - - old_dcd_state = portdata->dcd_state; - portdata->cts_state = 1; - portdata->dcd_state = ((signals & 0x01) ? 1 : 0); - portdata->dsr_state = ((signals & 0x02) ? 1 : 0); - portdata->ri_state = ((signals & 0x08) ? 1 : 0); - - if (port->tty && !C_CLOCAL(port->tty) && - old_dcd_state && !portdata->dcd_state) - tty_hangup(port->tty); - } else { - dbg("%s: type %x req %x", __FUNCTION__, - req_pkt->bRequestType,req_pkt->bRequest); - } - } else - dbg("%s: error %d", __FUNCTION__, urb->status); - - /* Resubmit urb so we continue receiving IRQ data */ - if (urb->status != -ESHUTDOWN) { - urb->dev = serial->dev; - err = usb_submit_urb(urb, GFP_ATOMIC); - if (err) - dbg("%s: resubmit intr urb failed. (%d)", - __FUNCTION__, err); - } -} - -static int sierra_write_room(struct usb_serial_port *port) -{ - struct sierra_port_private *portdata; - int i; - int data_len = 0; - struct urb *this_urb; - - portdata = usb_get_serial_port_data(port); - - for (i=0; i < N_OUT_URB; i++) { - this_urb = portdata->out_urbs[i]; - if (this_urb && this_urb->status != -EINPROGRESS) - data_len += OUT_BUFLEN; - } - - dbg("%s: %d", __FUNCTION__, data_len); - return data_len; -} - -static int sierra_chars_in_buffer(struct usb_serial_port *port) -{ - struct sierra_port_private *portdata; - int i; - int data_len = 0; - struct urb *this_urb; - - portdata = usb_get_serial_port_data(port); - - for (i=0; i < N_OUT_URB; i++) { - this_urb = portdata->out_urbs[i]; - if (this_urb && this_urb->status == -EINPROGRESS) - data_len += this_urb->transfer_buffer_length; - } - dbg("%s: %d", __FUNCTION__, data_len); - return data_len; -} - -static int sierra_open(struct usb_serial_port *port, struct file *filp) -{ - struct sierra_port_private *portdata; - struct usb_serial *serial = port->serial; - int i, err; - struct urb *urb; - - portdata = usb_get_serial_port_data(port); - - dbg("%s", __FUNCTION__); - - /* Set some sane defaults */ - portdata->rts_state = 1; - portdata->dtr_state = 1; - - /* Reset low level data toggle and start reading from endpoints */ - for (i = 0; i < N_IN_URB; i++) { - urb = portdata->in_urbs[i]; - if (! urb) - continue; - if (urb->dev != serial->dev) { - dbg("%s: dev %p != %p", __FUNCTION__, - urb->dev, serial->dev); - continue; - } - - /* - * make sure endpoint data toggle is synchronized with the - * device - */ - usb_clear_halt(urb->dev, urb->pipe); - - err = usb_submit_urb(urb, GFP_KERNEL); - if (err) { - dbg("%s: submit urb %d failed (%d) %d", - __FUNCTION__, i, err, - urb->transfer_buffer_length); - } - } - - /* Reset low level data toggle on out endpoints */ - for (i = 0; i < N_OUT_URB; i++) { - urb = portdata->out_urbs[i]; - if (! urb) - continue; - urb->dev = serial->dev; - /* usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), - usb_pipeout(urb->pipe), 0); */ - } - - port->tty->low_latency = 1; - - sierra_send_setup(port); - - return (0); -} - -static inline void stop_urb(struct urb *urb) -{ - if (urb && urb->status == -EINPROGRESS) - usb_kill_urb(urb); -} - -static void sierra_close(struct usb_serial_port *port, struct file *filp) -{ - int i; - struct usb_serial *serial = port->serial; - struct sierra_port_private *portdata; - - dbg("%s", __FUNCTION__); - portdata = usb_get_serial_port_data(port); - - portdata->rts_state = 0; - portdata->dtr_state = 0; - - if (serial->dev) { - sierra_send_setup(port); - - /* Stop reading/writing urbs */ - for (i = 0; i < N_IN_URB; i++) - stop_urb(portdata->in_urbs[i]); - for (i = 0; i < N_OUT_URB; i++) - stop_urb(portdata->out_urbs[i]); - } - port->tty = NULL; -} - -/* Helper functions used by sierra_setup_urbs */ -static struct urb *sierra_setup_urb(struct usb_serial *serial, int endpoint, - int dir, void *ctx, char *buf, int len, - usb_complete_t callback) -{ - struct urb *urb; - - if (endpoint == -1) - return NULL; /* endpoint not needed */ - - urb = usb_alloc_urb(0, GFP_KERNEL); /* No ISO */ - if (urb == NULL) { - dbg("%s: alloc for endpoint %d failed.", __FUNCTION__, endpoint); - return NULL; - } - - /* Fill URB using supplied data. */ - usb_fill_bulk_urb(urb, serial->dev, - usb_sndbulkpipe(serial->dev, endpoint) | dir, - buf, len, callback, ctx); - - return urb; -} - -/* Setup urbs */ -static void sierra_setup_urbs(struct usb_serial *serial) -{ - int i,j; - struct usb_serial_port *port; - struct sierra_port_private *portdata; - - dbg("%s", __FUNCTION__); - - for (i = 0; i < serial->num_ports; i++) { - port = serial->port[i]; - portdata = usb_get_serial_port_data(port); - - /* Do indat endpoints first */ - for (j = 0; j < N_IN_URB; ++j) { - portdata->in_urbs[j] = sierra_setup_urb (serial, - port->bulk_in_endpointAddress, USB_DIR_IN, port, - portdata->in_buffer[j], IN_BUFLEN, sierra_indat_callback); - } - - /* outdat endpoints */ - for (j = 0; j < N_OUT_URB; ++j) { - portdata->out_urbs[j] = sierra_setup_urb (serial, - port->bulk_out_endpointAddress, USB_DIR_OUT, port, - portdata->out_buffer[j], OUT_BUFLEN, sierra_outdat_callback); - } - } -} - -static int sierra_startup(struct usb_serial *serial) -{ - int i, err; - struct usb_serial_port *port; - struct sierra_port_private *portdata; - - dbg("%s", __FUNCTION__); - - /* Now setup per port private data */ - for (i = 0; i < serial->num_ports; i++) { - port = serial->port[i]; - portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); - if (!portdata) { - dbg("%s: kmalloc for sierra_port_private (%d) failed!.", - __FUNCTION__, i); - return (1); - } - - usb_set_serial_port_data(port, portdata); - - if (! port->interrupt_in_urb) - continue; - err = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); - if (err) - dbg("%s: submit irq_in urb failed %d", - __FUNCTION__, err); - } - - sierra_setup_urbs(serial); - - return (0); -} - -static void sierra_shutdown(struct usb_serial *serial) -{ - int i, j; - struct usb_serial_port *port; - struct sierra_port_private *portdata; - - dbg("%s", __FUNCTION__); - - /* Stop reading/writing urbs */ - for (i = 0; i < serial->num_ports; ++i) { - port = serial->port[i]; - portdata = usb_get_serial_port_data(port); - for (j = 0; j < N_IN_URB; j++) - stop_urb(portdata->in_urbs[j]); - for (j = 0; j < N_OUT_URB; j++) - stop_urb(portdata->out_urbs[j]); - } - - /* Now free them */ - for (i = 0; i < serial->num_ports; ++i) { - port = serial->port[i]; - portdata = usb_get_serial_port_data(port); - - for (j = 0; j < N_IN_URB; j++) { - if (portdata->in_urbs[j]) { - usb_free_urb(portdata->in_urbs[j]); - portdata->in_urbs[j] = NULL; - } - } - for (j = 0; j < N_OUT_URB; j++) { - if (portdata->out_urbs[j]) { - usb_free_urb(portdata->out_urbs[j]); - portdata->out_urbs[j] = NULL; - } - } - } - - /* Now free per port private data */ - for (i = 0; i < serial->num_ports; i++) { - port = serial->port[i]; - kfree(usb_get_serial_port_data(port)); - } -} - -static struct usb_serial_driver sierra_1port_device = { - .driver = { - .owner = THIS_MODULE, - .name = "sierra1", - }, - .description = "Sierra USB modem (1 port)", - .id_table = id_table_1port, - .num_interrupt_in = NUM_DONT_CARE, - .num_bulk_in = 1, - .num_bulk_out = 1, - .num_ports = 1, - .open = sierra_open, - .close = sierra_close, - .write = sierra_write, - .write_room = sierra_write_room, - .chars_in_buffer = sierra_chars_in_buffer, - .throttle = sierra_rx_throttle, - .unthrottle = sierra_rx_unthrottle, - .ioctl = sierra_ioctl, - .set_termios = sierra_set_termios, - .break_ctl = sierra_break_ctl, - .tiocmget = sierra_tiocmget, - .tiocmset = sierra_tiocmset, - .attach = sierra_startup, - .shutdown = sierra_shutdown, - .read_int_callback = sierra_instat_callback, + .name = "sierra_wireless", + .probe = usb_serial_probe, + .disconnect = usb_serial_disconnect, + .id_table = id_table, }; -static struct usb_serial_driver sierra_3port_device = { +static struct usb_serial_driver sierra_device = { .driver = { - .owner = THIS_MODULE, - .name = "sierra3", + .owner = THIS_MODULE, + .name = "Sierra_Wireless", }, - .description = "Sierra USB modem (3 port)", - .id_table = id_table_3port, - .num_interrupt_in = NUM_DONT_CARE, - .num_bulk_in = 3, - .num_bulk_out = 3, - .num_ports = 3, - .open = sierra_open, - .close = sierra_close, - .write = sierra_write, - .write_room = sierra_write_room, - .chars_in_buffer = sierra_chars_in_buffer, - .throttle = sierra_rx_throttle, - .unthrottle = sierra_rx_unthrottle, - .ioctl = sierra_ioctl, - .set_termios = sierra_set_termios, - .break_ctl = sierra_break_ctl, - .tiocmget = sierra_tiocmget, - .tiocmset = sierra_tiocmset, - .attach = sierra_startup, - .shutdown = sierra_shutdown, - .read_int_callback = sierra_instat_callback, + .id_table = id_table, + .num_interrupt_in = NUM_DONT_CARE, + .num_bulk_in = NUM_DONT_CARE, + .num_bulk_out = NUM_DONT_CARE, + .num_ports = 3, }; -/* Functions used by new usb-serial code. */ static int __init sierra_init(void) { int retval; - retval = usb_serial_register(&sierra_1port_device); - if (retval) - goto failed_1port_device_register; - retval = usb_serial_register(&sierra_3port_device); - if (retval) - goto failed_3port_device_register; - + retval = usb_serial_register(&sierra_device); + if (retval) + return retval; retval = usb_register(&sierra_driver); if (retval) - goto failed_driver_register; - - info(DRIVER_DESC ": " DRIVER_VERSION); - - return 0; - -failed_driver_register: - usb_serial_deregister(&sierra_3port_device); -failed_3port_device_register: - usb_serial_deregister(&sierra_1port_device); -failed_1port_device_register: + usb_serial_deregister(&sierra_device); return retval; } static void __exit sierra_exit(void) { - usb_deregister (&sierra_driver); - usb_serial_deregister(&sierra_1port_device); - usb_serial_deregister(&sierra_3port_device); + usb_deregister(&sierra_driver); + usb_serial_deregister(&sierra_device); } module_init(sierra_init); module_exit(sierra_exit); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_VERSION(DRIVER_VERSION); MODULE_LICENSE("GPL"); - -#ifdef CONFIG_USB_DEBUG -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug messages"); -#endif - diff --git a/trunk/drivers/usb/serial/ti_usb_3410_5052.c b/trunk/drivers/usb/serial/ti_usb_3410_5052.c index ae98d8cbdbb8..ac9b8ee52d44 100644 --- a/trunk/drivers/usb/serial/ti_usb_3410_5052.c +++ b/trunk/drivers/usb/serial/ti_usb_3410_5052.c @@ -166,9 +166,9 @@ static int ti_tiocmget(struct usb_serial_port *port, struct file *file); static int ti_tiocmset(struct usb_serial_port *port, struct file *file, unsigned int set, unsigned int clear); static void ti_break(struct usb_serial_port *port, int break_state); -static void ti_interrupt_callback(struct urb *urb); -static void ti_bulk_in_callback(struct urb *urb); -static void ti_bulk_out_callback(struct urb *urb); +static void ti_interrupt_callback(struct urb *urb, struct pt_regs *regs); +static void ti_bulk_in_callback(struct urb *urb, struct pt_regs *regs); +static void ti_bulk_out_callback(struct urb *urb, struct pt_regs *regs); static void ti_recv(struct device *dev, struct tty_struct *tty, unsigned char *data, int length); @@ -228,7 +228,6 @@ static int product_5052_count; /* null entry */ static struct usb_device_id ti_id_table_3410[1+TI_EXTRA_VID_PID_COUNT+1] = { { USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) }, - { USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) }, }; static struct usb_device_id ti_id_table_5052[4+TI_EXTRA_VID_PID_COUNT+1] = { @@ -240,7 +239,6 @@ static struct usb_device_id ti_id_table_5052[4+TI_EXTRA_VID_PID_COUNT+1] = { static struct usb_device_id ti_id_table_combined[] = { { USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) }, - { USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) }, { USB_DEVICE(TI_VENDOR_ID, TI_5052_BOOT_PRODUCT_ID) }, { USB_DEVICE(TI_VENDOR_ID, TI_5152_BOOT_PRODUCT_ID) }, { USB_DEVICE(TI_VENDOR_ID, TI_5052_EEPROM_PRODUCT_ID) }, @@ -461,12 +459,13 @@ static int ti_startup(struct usb_serial *serial) /* set up port structures */ for (i = 0; i < serial->num_ports; ++i) { - tport = kzalloc(sizeof(struct ti_port), GFP_KERNEL); + tport = kmalloc(sizeof(struct ti_port), GFP_KERNEL); if (tport == NULL) { dev_err(&dev->dev, "%s - out of memory\n", __FUNCTION__); status = -ENOMEM; goto free_tports; } + memset(tport, 0, sizeof(struct ti_port)); spin_lock_init(&tport->tp_lock); tport->tp_uart_base_addr = (i == 0 ? TI_UART1_BASE_ADDR : TI_UART2_BASE_ADDR); tport->tp_flags = low_latency ? ASYNC_LOW_LATENCY : 0; @@ -1099,7 +1098,7 @@ static void ti_break(struct usb_serial_port *port, int break_state) } -static void ti_interrupt_callback(struct urb *urb) +static void ti_interrupt_callback(struct urb *urb, struct pt_regs *regs) { struct ti_device *tdev = (struct ti_device *)urb->context; struct usb_serial_port *port; @@ -1179,7 +1178,7 @@ static void ti_interrupt_callback(struct urb *urb) } -static void ti_bulk_in_callback(struct urb *urb) +static void ti_bulk_in_callback(struct urb *urb, struct pt_regs *regs) { struct ti_port *tport = (struct ti_port *)urb->context; struct usb_serial_port *port = tport->tp_port; @@ -1242,7 +1241,7 @@ static void ti_bulk_in_callback(struct urb *urb) } -static void ti_bulk_out_callback(struct urb *urb) +static void ti_bulk_out_callback(struct urb *urb, struct pt_regs *regs) { struct ti_port *tport = (struct ti_port *)urb->context; struct usb_serial_port *port = tport->tp_port; diff --git a/trunk/drivers/usb/serial/ti_usb_3410_5052.h b/trunk/drivers/usb/serial/ti_usb_3410_5052.h index b5541bf991ba..02c1aeb9e1b8 100644 --- a/trunk/drivers/usb/serial/ti_usb_3410_5052.h +++ b/trunk/drivers/usb/serial/ti_usb_3410_5052.h @@ -28,7 +28,6 @@ /* Vendor and product ids */ #define TI_VENDOR_ID 0x0451 #define TI_3410_PRODUCT_ID 0x3410 -#define TI_3410_EZ430_ID 0xF430 /* TI ez430 development tool */ #define TI_5052_BOOT_PRODUCT_ID 0x5052 /* no EEPROM, no firmware */ #define TI_5152_BOOT_PRODUCT_ID 0x5152 /* no EEPROM, no firmware */ #define TI_5052_EEPROM_PRODUCT_ID 0x505A /* EEPROM, no firmware */ diff --git a/trunk/drivers/usb/serial/usb-serial.c b/trunk/drivers/usb/serial/usb-serial.c index c1257d5292f5..8006e51c34bb 100644 --- a/trunk/drivers/usb/serial/usb-serial.c +++ b/trunk/drivers/usb/serial/usb-serial.c @@ -952,28 +952,32 @@ int usb_serial_probe(struct usb_interface *interface, port = serial->port[i]; if (!port) continue; - usb_free_urb(port->read_urb); + if (port->read_urb) + usb_free_urb (port->read_urb); kfree(port->bulk_in_buffer); } for (i = 0; i < num_bulk_out; ++i) { port = serial->port[i]; if (!port) continue; - usb_free_urb(port->write_urb); + if (port->write_urb) + usb_free_urb (port->write_urb); kfree(port->bulk_out_buffer); } for (i = 0; i < num_interrupt_in; ++i) { port = serial->port[i]; if (!port) continue; - usb_free_urb(port->interrupt_in_urb); + if (port->interrupt_in_urb) + usb_free_urb (port->interrupt_in_urb); kfree(port->interrupt_in_buffer); } for (i = 0; i < num_interrupt_out; ++i) { port = serial->port[i]; if (!port) continue; - usb_free_urb(port->interrupt_out_urb); + if (port->interrupt_out_urb) + usb_free_urb (port->interrupt_out_urb); kfree(port->interrupt_out_buffer); } diff --git a/trunk/drivers/usb/serial/usb_debug.c b/trunk/drivers/usb/serial/usb_debug.c deleted file mode 100644 index 257a5e436873..000000000000 --- a/trunk/drivers/usb/serial/usb_debug.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * USB Debug cable driver - * - * Copyright (C) 2006 Greg Kroah-Hartman - * - * 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 - -static struct usb_device_id id_table [] = { - { USB_DEVICE(0x0525, 0x127a) }, - { }, -}; -MODULE_DEVICE_TABLE(usb, id_table); - -static struct usb_driver debug_driver = { - .name = "debug", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table, - .no_dynamic_id = 1, -}; - -static struct usb_serial_driver debug_device = { - .driver = { - .owner = THIS_MODULE, - .name = "debug", - }, - .id_table = id_table, - .num_interrupt_in = NUM_DONT_CARE, - .num_bulk_in = NUM_DONT_CARE, - .num_bulk_out = NUM_DONT_CARE, - .num_ports = 1, -}; - -static int __init debug_init(void) -{ - int retval; - - retval = usb_serial_register(&debug_device); - if (retval) - return retval; - retval = usb_register(&debug_driver); - if (retval) - usb_serial_deregister(&debug_device); - return retval; -} - -static void __exit debug_exit(void) -{ - usb_deregister(&debug_driver); - usb_serial_deregister(&debug_device); -} - -module_init(debug_init); -module_exit(debug_exit); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/usb/serial/visor.c b/trunk/drivers/usb/serial/visor.c index eef5eaa5fa0b..88949f7884ca 100644 --- a/trunk/drivers/usb/serial/visor.c +++ b/trunk/drivers/usb/serial/visor.c @@ -47,9 +47,9 @@ static int visor_calc_num_ports(struct usb_serial *serial); static void visor_shutdown (struct usb_serial *serial); static int visor_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg); static void visor_set_termios (struct usb_serial_port *port, struct termios *old_termios); -static void visor_write_bulk_callback (struct urb *urb); -static void visor_read_bulk_callback (struct urb *urb); -static void visor_read_int_callback (struct urb *urb); +static void visor_write_bulk_callback (struct urb *urb, struct pt_regs *regs); +static void visor_read_bulk_callback (struct urb *urb, struct pt_regs *regs); +static void visor_read_int_callback (struct urb *urb, struct pt_regs *regs); static int clie_3_5_startup (struct usb_serial *serial); static int treo_attach (struct usb_serial *serial); static int clie_5_attach (struct usb_serial *serial); @@ -348,7 +348,8 @@ static void visor_close (struct usb_serial_port *port, struct file * filp) /* shutdown our urbs */ usb_kill_urb(port->read_urb); - usb_kill_urb(port->interrupt_in_urb); + if (port->interrupt_in_urb) + usb_kill_urb(port->interrupt_in_urb); /* Try to send shutdown message, if the device is gone, this will just fail. */ transfer_buffer = kmalloc (0x12, GFP_KERNEL); @@ -470,7 +471,7 @@ static int visor_chars_in_buffer (struct usb_serial_port *port) } -static void visor_write_bulk_callback (struct urb *urb) +static void visor_write_bulk_callback (struct urb *urb, struct pt_regs *regs) { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; struct visor_private *priv = usb_get_serial_port_data(port); @@ -493,7 +494,7 @@ static void visor_write_bulk_callback (struct urb *urb) } -static void visor_read_bulk_callback (struct urb *urb) +static void visor_read_bulk_callback (struct urb *urb, struct pt_regs *regs) { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; struct visor_private *priv = usb_get_serial_port_data(port); @@ -538,7 +539,7 @@ static void visor_read_bulk_callback (struct urb *urb) return; } -static void visor_read_int_callback (struct urb *urb) +static void visor_read_int_callback (struct urb *urb, struct pt_regs *regs) { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; int result; diff --git a/trunk/drivers/usb/serial/whiteheat.c b/trunk/drivers/usb/serial/whiteheat.c index 4d1cd7aeccd3..6e6c7934be32 100644 --- a/trunk/drivers/usb/serial/whiteheat.c +++ b/trunk/drivers/usb/serial/whiteheat.c @@ -152,8 +152,8 @@ static void whiteheat_break_ctl (struct usb_serial_port *port, int break_state) static int whiteheat_chars_in_buffer (struct usb_serial_port *port); static void whiteheat_throttle (struct usb_serial_port *port); static void whiteheat_unthrottle (struct usb_serial_port *port); -static void whiteheat_read_callback (struct urb *urb); -static void whiteheat_write_callback (struct urb *urb); +static void whiteheat_read_callback (struct urb *urb, struct pt_regs *regs); +static void whiteheat_write_callback (struct urb *urb, struct pt_regs *regs); static struct usb_serial_driver whiteheat_fake_device = { .driver = { @@ -235,8 +235,8 @@ struct whiteheat_private { /* local function prototypes */ static int start_command_port(struct usb_serial *serial); static void stop_command_port(struct usb_serial *serial); -static void command_port_write_callback(struct urb *urb); -static void command_port_read_callback(struct urb *urb); +static void command_port_write_callback(struct urb *urb, struct pt_regs *regs); +static void command_port_read_callback(struct urb *urb, struct pt_regs *regs); static int start_port_read(struct usb_serial_port *port); static struct whiteheat_urb_wrap *urb_to_wrap(struct urb *urb, struct list_head *head); @@ -958,7 +958,7 @@ static void whiteheat_unthrottle (struct usb_serial_port *port) /***************************************************************************** * Connect Tech's White Heat callback routines *****************************************************************************/ -static void command_port_write_callback (struct urb *urb) +static void command_port_write_callback (struct urb *urb, struct pt_regs *regs) { dbg("%s", __FUNCTION__); @@ -969,7 +969,7 @@ static void command_port_write_callback (struct urb *urb) } -static void command_port_read_callback (struct urb *urb) +static void command_port_read_callback (struct urb *urb, struct pt_regs *regs) { struct usb_serial_port *command_port = (struct usb_serial_port *)urb->context; struct whiteheat_command_private *command_info; @@ -1019,7 +1019,7 @@ static void command_port_read_callback (struct urb *urb) } -static void whiteheat_read_callback(struct urb *urb) +static void whiteheat_read_callback(struct urb *urb, struct pt_regs *regs) { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; struct whiteheat_urb_wrap *wrap; @@ -1061,7 +1061,7 @@ static void whiteheat_read_callback(struct urb *urb) } -static void whiteheat_write_callback(struct urb *urb) +static void whiteheat_write_callback(struct urb *urb, struct pt_regs *regs) { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; struct whiteheat_private *info = usb_get_serial_port_data(port); diff --git a/trunk/drivers/usb/storage/onetouch.c b/trunk/drivers/usb/storage/onetouch.c index 3a158d58441f..f843a0bcf107 100644 --- a/trunk/drivers/usb/storage/onetouch.c +++ b/trunk/drivers/usb/storage/onetouch.c @@ -53,7 +53,7 @@ struct usb_onetouch { unsigned int is_open:1; }; -static void usb_onetouch_irq(struct urb *urb) +static void usb_onetouch_irq(struct urb *urb, struct pt_regs *regs) { struct usb_onetouch *onetouch = urb->context; signed char *data = onetouch->data; @@ -72,6 +72,7 @@ static void usb_onetouch_irq(struct urb *urb) goto resubmit; } + input_regs(dev, regs); input_report_key(dev, ONETOUCH_BUTTON, data[0] & 0x02); input_sync(dev); @@ -142,7 +143,10 @@ int onetouch_connect_input(struct us_data *ss) return -ENODEV; endpoint = &interface->endpoint[2].desc; - if (!usb_endpoint_is_int_in(endpoint)) + if (!(endpoint->bEndpointAddress & USB_DIR_IN)) + return -ENODEV; + if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) + != USB_ENDPOINT_XFER_INT) return -ENODEV; pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress); diff --git a/trunk/drivers/usb/storage/transport.c b/trunk/drivers/usb/storage/transport.c index 47644b5b6155..f23514c4e649 100644 --- a/trunk/drivers/usb/storage/transport.c +++ b/trunk/drivers/usb/storage/transport.c @@ -108,7 +108,7 @@ /* This is the completion handler which will wake us up when an URB * completes. */ -static void usb_stor_blocking_completion(struct urb *urb) +static void usb_stor_blocking_completion(struct urb *urb, struct pt_regs *regs) { struct completion *urb_done_ptr = (struct completion *)urb->context; diff --git a/trunk/drivers/usb/storage/unusual_devs.h b/trunk/drivers/usb/storage/unusual_devs.h index db8b26012c75..c9a8d50106d1 100644 --- a/trunk/drivers/usb/storage/unusual_devs.h +++ b/trunk/drivers/usb/storage/unusual_devs.h @@ -55,8 +55,7 @@ UNUSUAL_DEV( 0x03eb, 0x2002, 0x0100, 0x0100, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_IGNORE_RESIDUE), -/* modified by Tobias Lorenz */ -UNUSUAL_DEV( 0x03ee, 0x6901, 0x0000, 0x0200, +UNUSUAL_DEV( 0x03ee, 0x6901, 0x0000, 0x0100, "Mitsumi", "USB FDD", US_SC_DEVICE, US_PR_DEVICE, NULL, @@ -183,20 +182,6 @@ UNUSUAL_DEV( 0x0421, 0x044e, 0x0100, 0x0100, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_IGNORE_RESIDUE | US_FL_FIX_CAPACITY ), -/* Reported by Bardur Arantsson */ -UNUSUAL_DEV( 0x0421, 0x047c, 0x0370, 0x0370, - "Nokia", - "6131", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_MAX_SECTORS_64 ), - -/* Reported by Alex Corcoles */ -UNUSUAL_DEV( 0x0421, 0x0495, 0x0370, 0x0370, - "Nokia", - "6234", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_MAX_SECTORS_64 ), - /* Reported by Olaf Hering from novell bug #105878 */ UNUSUAL_DEV( 0x0424, 0x0fdc, 0x0210, 0x0210, "SMSC", @@ -1236,7 +1221,7 @@ UNUSUAL_DEV( 0x0e21, 0x0520, 0x0100, 0x0100, "Cowon Systems", "iAUDIO M5", US_SC_DEVICE, US_PR_BULK, NULL, - US_FL_NEED_OVERRIDE ), + 0 ), /* Submitted by Antoine Mairesse */ UNUSUAL_DEV( 0x0ed1, 0x6660, 0x0100, 0x0300, @@ -1309,25 +1294,13 @@ UNUSUAL_DEV( 0x0fce, 0xe030, 0x0000, 0x0000, /* Reported by Kevin Cernekee * Tested on hardware version 1.10. * Entry is needed only for the initializer function override. - * Devices with bcd > 110 seem to not need it while those - * with bcd < 110 appear to need it. */ -UNUSUAL_DEV( 0x1019, 0x0c55, 0x0000, 0x0110, +UNUSUAL_DEV( 0x1019, 0x0c55, 0x0110, 0x0110, "Desknote", "UCR-61S2B", US_SC_DEVICE, US_PR_DEVICE, usb_stor_ucr61s2b_init, 0 ), -/* Reported by Jaco Kroon - * The usb-storage module found on the Digitech GNX4 (and supposedly other - * devices) misbehaves and causes a bunch of invalid I/O errors. - */ -UNUSUAL_DEV( 0x1210, 0x0003, 0x0100, 0x0100, - "Digitech HMG", - "DigiTech Mass Storage", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_IGNORE_RESIDUE ), - /* Reported by Vilius Bilinkevicius endpoint[i].desc; /* Is it a BULK endpoint? */ - if (usb_endpoint_xfer_bulk(ep)) { + if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) + == USB_ENDPOINT_XFER_BULK) { /* BULK in or out? */ - if (usb_endpoint_dir_in(ep)) + if (ep->bEndpointAddress & USB_DIR_IN) ep_in = ep; else ep_out = ep; } /* Is it an interrupt endpoint? */ - else if (usb_endpoint_xfer_int(ep)) { + else if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) + == USB_ENDPOINT_XFER_INT) { ep_int = ep; } } diff --git a/trunk/drivers/usb/usb-skeleton.c b/trunk/drivers/usb/usb-skeleton.c index 296b091cf168..1b51d3187a95 100644 --- a/trunk/drivers/usb/usb-skeleton.c +++ b/trunk/drivers/usb/usb-skeleton.c @@ -158,7 +158,7 @@ static ssize_t skel_read(struct file *file, char *buffer, size_t count, loff_t * return retval; } -static void skel_write_bulk_callback(struct urb *urb) +static void skel_write_bulk_callback(struct urb *urb, struct pt_regs *regs) { struct usb_skel *dev; diff --git a/trunk/drivers/video/Kconfig b/trunk/drivers/video/Kconfig index 7a43020fa583..daaa486159cf 100644 --- a/trunk/drivers/video/Kconfig +++ b/trunk/drivers/video/Kconfig @@ -701,6 +701,7 @@ config FB_NVIDIA depends on FB && PCI select I2C_ALGOBIT if FB_NVIDIA_I2C select I2C if FB_NVIDIA_I2C + select FB_DDC if FB_NVIDIA_I2C select FB_MODE_HELPERS select FB_CFB_FILLRECT select FB_CFB_COPYAREA diff --git a/trunk/drivers/video/amifb.c b/trunk/drivers/video/amifb.c index a4e3fca05891..f1ba54f4fc39 100644 --- a/trunk/drivers/video/amifb.c +++ b/trunk/drivers/video/amifb.c @@ -1144,7 +1144,7 @@ static void amifb_deinit(void); */ static int flash_cursor(void); -static irqreturn_t amifb_interrupt(int irq, void *dev_id); +static irqreturn_t amifb_interrupt(int irq, void *dev_id, struct pt_regs *fp); static u_long chipalloc(u_long size); static void chipfree(void); @@ -2492,7 +2492,7 @@ static int flash_cursor(void) * VBlank Display Interrupt */ -static irqreturn_t amifb_interrupt(int irq, void *dev_id) +static irqreturn_t amifb_interrupt(int irq, void *dev_id, struct pt_regs *fp) { if (do_vmode_pan || do_vmode_full) ami_update_display(); diff --git a/trunk/drivers/video/arcfb.c b/trunk/drivers/video/arcfb.c index ab34b96acc31..70dd8115a4d8 100644 --- a/trunk/drivers/video/arcfb.c +++ b/trunk/drivers/video/arcfb.c @@ -218,7 +218,8 @@ static int arcfb_pan_display(struct fb_var_screeninfo *var, return -EINVAL; } -static irqreturn_t arcfb_interrupt(int vec, void *dev_instance) +static irqreturn_t arcfb_interrupt(int vec, void *dev_instance, + struct pt_regs *regs) { struct fb_info *info = dev_instance; unsigned char ctl2status; diff --git a/trunk/drivers/video/atafb.c b/trunk/drivers/video/atafb.c index 02c41a626fa2..5831893bf7a0 100644 --- a/trunk/drivers/video/atafb.c +++ b/trunk/drivers/video/atafb.c @@ -1521,7 +1521,7 @@ static void falcon_set_par( struct atafb_par *par ) } -static irqreturn_t falcon_vbl_switcher( int irq, void *dummy ) +static irqreturn_t falcon_vbl_switcher( int irq, void *dummy, struct pt_regs *fp ) { struct falcon_hw *hw = &f_new_mode; diff --git a/trunk/drivers/video/aty/atyfb_base.c b/trunk/drivers/video/aty/atyfb_base.c index e815b354c09d..b45c9fd1b330 100644 --- a/trunk/drivers/video/aty/atyfb_base.c +++ b/trunk/drivers/video/aty/atyfb_base.c @@ -406,7 +406,7 @@ static struct { { PCI_CHIP_MACH64LB, "3D RAGE LT PRO (Mach64 LB, AGP)", 236, 75, 100, 135, ATI_CHIP_264LTPRO }, { PCI_CHIP_MACH64LD, "3D RAGE LT PRO (Mach64 LD, AGP)", 230, 100, 100, 135, ATI_CHIP_264LTPRO }, { PCI_CHIP_MACH64LI, "3D RAGE LT PRO (Mach64 LI, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO | M64F_G3_PB_1_1 | M64F_G3_PB_1024x768 }, - { PCI_CHIP_MACH64LP, "3D RAGE LT PRO (Mach64 LP, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO | M64F_G3_PB_1024x768 }, + { PCI_CHIP_MACH64LP, "3D RAGE LT PRO (Mach64 LP, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO }, { PCI_CHIP_MACH64LQ, "3D RAGE LT PRO (Mach64 LQ, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO }, { PCI_CHIP_MACH64GM, "3D RAGE XL (Mach64 GM, AGP 2x)", 230, 83, 63, 135, ATI_CHIP_264XL }, @@ -1532,7 +1532,7 @@ static int atyfb_open(struct fb_info *info, int user) return (0); } -static irqreturn_t aty_irq(int irq, void *dev_id) +static irqreturn_t aty_irq(int irq, void *dev_id, struct pt_regs *fp) { struct atyfb_par *par = dev_id; int handled = 0; diff --git a/trunk/drivers/video/aty/radeon_i2c.c b/trunk/drivers/video/aty/radeon_i2c.c index 869725a13c21..676754520099 100644 --- a/trunk/drivers/video/aty/radeon_i2c.c +++ b/trunk/drivers/video/aty/radeon_i2c.c @@ -139,13 +139,7 @@ void radeon_delete_i2c_busses(struct radeonfb_info *rinfo) int radeon_probe_i2c_connector(struct radeonfb_info *rinfo, int conn, u8 **out_edid) { - u32 reg = rinfo->i2c[conn-1].ddc_reg; - u8 *edid; - - OUTREG(reg, INREG(reg) & - ~(VGA_DDC_DATA_OUTPUT | VGA_DDC_CLK_OUTPUT)); - - edid = fb_ddc_read(&rinfo->i2c[conn-1].adapter); + u8 *edid = fb_ddc_read(&rinfo->i2c[conn-1].adapter); if (out_edid) *out_edid = edid; diff --git a/trunk/drivers/video/au1200fb.c b/trunk/drivers/video/au1200fb.c index dbf4ec3f6d57..c6a5f0ccc107 100644 --- a/trunk/drivers/video/au1200fb.c +++ b/trunk/drivers/video/au1200fb.c @@ -1545,7 +1545,7 @@ static struct fb_ops au1200fb_fb_ops = { /*-------------------------------------------------------------------------*/ -static irqreturn_t au1200fb_handle_irq(int irq, void* dev_id) +static irqreturn_t au1200fb_handle_irq(int irq, void* dev_id, struct pt_regs *regs) { /* Nothing to do for now, just clear any pending interrupt */ lcd->intstatus = lcd->intstatus; diff --git a/trunk/drivers/video/backlight/corgi_bl.c b/trunk/drivers/video/backlight/corgi_bl.c index d07ecb53c68b..2ebbfd95145f 100644 --- a/trunk/drivers/video/backlight/corgi_bl.c +++ b/trunk/drivers/video/backlight/corgi_bl.c @@ -111,7 +111,7 @@ static struct backlight_properties corgibl_data = { .update_status = corgibl_set_intensity, }; -static int corgibl_probe(struct platform_device *pdev) +static int __init corgibl_probe(struct platform_device *pdev) { struct corgibl_machinfo *machinfo = pdev->dev.platform_data; @@ -166,4 +166,4 @@ module_exit(corgibl_exit); MODULE_AUTHOR("Richard Purdie "); MODULE_DESCRIPTION("Corgi Backlight Driver"); -MODULE_LICENSE("GPL"); +MODULE_LICENSE("GPLv2"); diff --git a/trunk/drivers/video/backlight/hp680_bl.c b/trunk/drivers/video/backlight/hp680_bl.c index e3993213d10e..fe1488374f62 100644 --- a/trunk/drivers/video/backlight/hp680_bl.c +++ b/trunk/drivers/video/backlight/hp680_bl.c @@ -19,7 +19,7 @@ #include #include -#include +#include #include #define HP680_MAX_INTENSITY 255 diff --git a/trunk/drivers/video/console/fbcon.c b/trunk/drivers/video/console/fbcon.c index 302174b8e477..8c041daa3a15 100644 --- a/trunk/drivers/video/console/fbcon.c +++ b/trunk/drivers/video/console/fbcon.c @@ -204,7 +204,7 @@ static struct class_device *fbcon_class_device; */ static int vbl_detected; -static irqreturn_t fb_vbl_detect(int irq, void *dummy) +static irqreturn_t fb_vbl_detect(int irq, void *dummy, struct pt_regs *fp) { vbl_detected++; return IRQ_HANDLED; @@ -414,7 +414,7 @@ static void fb_flashcursor(void *private) #if defined(CONFIG_ATARI) || defined(CONFIG_MAC) static int cursor_blink_rate; -static irqreturn_t fb_vbl_handler(int irq, void *dev_id) +static irqreturn_t fb_vbl_handler(int irq, void *dev_id, struct pt_regs *fp) { struct fb_info *info = dev_id; diff --git a/trunk/drivers/video/controlfb.c b/trunk/drivers/video/controlfb.c index 04c6d928189b..8cc6c0e2d27a 100644 --- a/trunk/drivers/video/controlfb.c +++ b/trunk/drivers/video/controlfb.c @@ -415,15 +415,13 @@ static int __init init_control(struct fb_info_control *p) full = p->total_vram == 0x400000; /* Try to pick a video mode out of NVRAM if we have one. */ -#ifdef CONFIG_NVRAM if (default_cmode == CMODE_NVRAM){ cmode = nvram_read_byte(NV_CMODE); if(cmode < CMODE_8 || cmode > CMODE_32) cmode = CMODE_8; } else -#endif cmode=default_cmode; -#ifdef CONFIG_NVRAM + if (default_vmode == VMODE_NVRAM) { vmode = nvram_read_byte(NV_VMODE); if (vmode < 1 || vmode > VMODE_MAX || @@ -434,9 +432,7 @@ static int __init init_control(struct fb_info_control *p) if (control_mac_modes[vmode - 1].m[full] < cmode) vmode = VMODE_640_480_60; } - } else -#endif - { + } else { vmode=default_vmode; if (control_mac_modes[vmode - 1].m[full] < cmode) { if (cmode > CMODE_8) diff --git a/trunk/drivers/video/fb_ddc.c b/trunk/drivers/video/fb_ddc.c index f836137a0eda..3aa6ebf68f17 100644 --- a/trunk/drivers/video/fb_ddc.c +++ b/trunk/drivers/video/fb_ddc.c @@ -20,26 +20,26 @@ static unsigned char *fb_do_probe_ddc_edid(struct i2c_adapter *adapter) { unsigned char start = 0x0; - unsigned char *buf = kmalloc(EDID_LENGTH, GFP_KERNEL); struct i2c_msg msgs[] = { { .addr = DDC_ADDR, - .flags = 0, .len = 1, .buf = &start, }, { .addr = DDC_ADDR, .flags = I2C_M_RD, .len = EDID_LENGTH, - .buf = buf, } }; + unsigned char *buf; + buf = kmalloc(EDID_LENGTH, GFP_KERNEL); if (!buf) { dev_warn(&adapter->dev, "unable to allocate memory for EDID " "block.\n"); return NULL; } + msgs[1].buf = buf; if (i2c_transfer(adapter, msgs, 2) == 2) return buf; diff --git a/trunk/drivers/video/fbmem.c b/trunk/drivers/video/fbmem.c index e973a87fbb01..93ffcdd95f50 100644 --- a/trunk/drivers/video/fbmem.c +++ b/trunk/drivers/video/fbmem.c @@ -1296,14 +1296,14 @@ register_framebuffer(struct fb_info *fb_info) break; fb_info->node = i; - fb_info->dev = device_create(fb_class, fb_info->device, - MKDEV(FB_MAJOR, i), "fb%d", i); - if (IS_ERR(fb_info->dev)) { + fb_info->class_device = class_device_create(fb_class, NULL, MKDEV(FB_MAJOR, i), + fb_info->device, "fb%d", i); + if (IS_ERR(fb_info->class_device)) { /* Not fatal */ - printk(KERN_WARNING "Unable to create device for framebuffer %d; errno = %ld\n", i, PTR_ERR(fb_info->dev)); - fb_info->dev = NULL; + printk(KERN_WARNING "Unable to create class_device for framebuffer %d; errno = %ld\n", i, PTR_ERR(fb_info->class_device)); + fb_info->class_device = NULL; } else - fb_init_device(fb_info); + fb_init_class_device(fb_info); if (fb_info->pixmap.addr == NULL) { fb_info->pixmap.addr = kmalloc(FBPIXMAPSIZE, GFP_KERNEL); @@ -1356,8 +1356,8 @@ unregister_framebuffer(struct fb_info *fb_info) fb_destroy_modelist(&fb_info->modelist); registered_fb[i]=NULL; num_registered_fb--; - fb_cleanup_device(fb_info); - device_destroy(fb_class, MKDEV(FB_MAJOR, i)); + fb_cleanup_class_device(fb_info); + class_device_destroy(fb_class, MKDEV(FB_MAJOR, i)); event.info = fb_info; fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event); return 0; diff --git a/trunk/drivers/video/fbsysfs.c b/trunk/drivers/video/fbsysfs.c index 323bdf6fc7d5..d3a50417ed9a 100644 --- a/trunk/drivers/video/fbsysfs.c +++ b/trunk/drivers/video/fbsysfs.c @@ -73,7 +73,7 @@ EXPORT_SYMBOL(framebuffer_alloc); * * @info: frame buffer info structure * - * Drop the reference count of the device embedded in the + * Drop the reference count of the class_device embedded in the * framebuffer info structure. * */ @@ -120,10 +120,10 @@ static int mode_string(char *buf, unsigned int offset, m, mode->xres, mode->yres, v, mode->refresh); } -static ssize_t store_mode(struct device *device, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t store_mode(struct class_device *class_device, const char * buf, + size_t count) { - struct fb_info *fb_info = dev_get_drvdata(device); + struct fb_info *fb_info = class_get_devdata(class_device); char mstr[100]; struct fb_var_screeninfo var; struct fb_modelist *modelist; @@ -151,10 +151,9 @@ static ssize_t store_mode(struct device *device, struct device_attribute *attr, return -EINVAL; } -static ssize_t show_mode(struct device *device, struct device_attribute *attr, - char *buf) +static ssize_t show_mode(struct class_device *class_device, char *buf) { - struct fb_info *fb_info = dev_get_drvdata(device); + struct fb_info *fb_info = class_get_devdata(class_device); if (!fb_info->mode) return 0; @@ -162,11 +161,10 @@ static ssize_t show_mode(struct device *device, struct device_attribute *attr, return mode_string(buf, 0, fb_info->mode); } -static ssize_t store_modes(struct device *device, - struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t store_modes(struct class_device *class_device, const char * buf, + size_t count) { - struct fb_info *fb_info = dev_get_drvdata(device); + struct fb_info *fb_info = class_get_devdata(class_device); LIST_HEAD(old_list); int i = count / sizeof(struct fb_videomode); @@ -188,10 +186,9 @@ static ssize_t store_modes(struct device *device, return 0; } -static ssize_t show_modes(struct device *device, struct device_attribute *attr, - char *buf) +static ssize_t show_modes(struct class_device *class_device, char *buf) { - struct fb_info *fb_info = dev_get_drvdata(device); + struct fb_info *fb_info = class_get_devdata(class_device); unsigned int i; struct list_head *pos; struct fb_modelist *modelist; @@ -206,10 +203,10 @@ static ssize_t show_modes(struct device *device, struct device_attribute *attr, return i; } -static ssize_t store_bpp(struct device *device, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t store_bpp(struct class_device *class_device, const char * buf, + size_t count) { - struct fb_info *fb_info = dev_get_drvdata(device); + struct fb_info *fb_info = class_get_devdata(class_device); struct fb_var_screeninfo var; char ** last = NULL; int err; @@ -221,18 +218,16 @@ static ssize_t store_bpp(struct device *device, struct device_attribute *attr, return count; } -static ssize_t show_bpp(struct device *device, struct device_attribute *attr, - char *buf) +static ssize_t show_bpp(struct class_device *class_device, char *buf) { - struct fb_info *fb_info = dev_get_drvdata(device); + struct fb_info *fb_info = class_get_devdata(class_device); return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->var.bits_per_pixel); } -static ssize_t store_rotate(struct device *device, - struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t store_rotate(struct class_device *class_device, const char *buf, + size_t count) { - struct fb_info *fb_info = dev_get_drvdata(device); + struct fb_info *fb_info = class_get_devdata(class_device); struct fb_var_screeninfo var; char **last = NULL; int err; @@ -247,19 +242,17 @@ static ssize_t store_rotate(struct device *device, } -static ssize_t show_rotate(struct device *device, - struct device_attribute *attr, char *buf) +static ssize_t show_rotate(struct class_device *class_device, char *buf) { - struct fb_info *fb_info = dev_get_drvdata(device); + struct fb_info *fb_info = class_get_devdata(class_device); return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->var.rotate); } -static ssize_t store_virtual(struct device *device, - struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t store_virtual(struct class_device *class_device, + const char * buf, size_t count) { - struct fb_info *fb_info = dev_get_drvdata(device); + struct fb_info *fb_info = class_get_devdata(class_device); struct fb_var_screeninfo var; char *last = NULL; int err; @@ -276,26 +269,23 @@ static ssize_t store_virtual(struct device *device, return count; } -static ssize_t show_virtual(struct device *device, - struct device_attribute *attr, char *buf) +static ssize_t show_virtual(struct class_device *class_device, char *buf) { - struct fb_info *fb_info = dev_get_drvdata(device); + struct fb_info *fb_info = class_get_devdata(class_device); return snprintf(buf, PAGE_SIZE, "%d,%d\n", fb_info->var.xres_virtual, fb_info->var.yres_virtual); } -static ssize_t show_stride(struct device *device, - struct device_attribute *attr, char *buf) +static ssize_t show_stride(struct class_device *class_device, char *buf) { - struct fb_info *fb_info = dev_get_drvdata(device); + struct fb_info *fb_info = class_get_devdata(class_device); return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->fix.line_length); } -static ssize_t store_blank(struct device *device, - struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t store_blank(struct class_device *class_device, const char * buf, + size_t count) { - struct fb_info *fb_info = dev_get_drvdata(device); + struct fb_info *fb_info = class_get_devdata(class_device); char *last = NULL; int err; @@ -309,48 +299,42 @@ static ssize_t store_blank(struct device *device, return count; } -static ssize_t show_blank(struct device *device, - struct device_attribute *attr, char *buf) +static ssize_t show_blank(struct class_device *class_device, char *buf) { -// struct fb_info *fb_info = dev_get_drvdata(device); +// struct fb_info *fb_info = class_get_devdata(class_device); return 0; } -static ssize_t store_console(struct device *device, - struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t store_console(struct class_device *class_device, + const char * buf, size_t count) { -// struct fb_info *fb_info = dev_get_drvdata(device); +// struct fb_info *fb_info = class_get_devdata(class_device); return 0; } -static ssize_t show_console(struct device *device, - struct device_attribute *attr, char *buf) +static ssize_t show_console(struct class_device *class_device, char *buf) { -// struct fb_info *fb_info = dev_get_drvdata(device); +// struct fb_info *fb_info = class_get_devdata(class_device); return 0; } -static ssize_t store_cursor(struct device *device, - struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t store_cursor(struct class_device *class_device, + const char * buf, size_t count) { -// struct fb_info *fb_info = dev_get_drvdata(device); +// struct fb_info *fb_info = class_get_devdata(class_device); return 0; } -static ssize_t show_cursor(struct device *device, - struct device_attribute *attr, char *buf) +static ssize_t show_cursor(struct class_device *class_device, char *buf) { -// struct fb_info *fb_info = dev_get_drvdata(device); +// struct fb_info *fb_info = class_get_devdata(class_device); return 0; } -static ssize_t store_pan(struct device *device, - struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t store_pan(struct class_device *class_device, const char * buf, + size_t count) { - struct fb_info *fb_info = dev_get_drvdata(device); + struct fb_info *fb_info = class_get_devdata(class_device); struct fb_var_screeninfo var; char *last = NULL; int err; @@ -371,27 +355,24 @@ static ssize_t store_pan(struct device *device, return count; } -static ssize_t show_pan(struct device *device, - struct device_attribute *attr, char *buf) +static ssize_t show_pan(struct class_device *class_device, char *buf) { - struct fb_info *fb_info = dev_get_drvdata(device); + struct fb_info *fb_info = class_get_devdata(class_device); return snprintf(buf, PAGE_SIZE, "%d,%d\n", fb_info->var.xoffset, fb_info->var.xoffset); } -static ssize_t show_name(struct device *device, - struct device_attribute *attr, char *buf) +static ssize_t show_name(struct class_device *class_device, char *buf) { - struct fb_info *fb_info = dev_get_drvdata(device); + struct fb_info *fb_info = class_get_devdata(class_device); return snprintf(buf, PAGE_SIZE, "%s\n", fb_info->fix.id); } -static ssize_t store_fbstate(struct device *device, - struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t store_fbstate(struct class_device *class_device, + const char *buf, size_t count) { - struct fb_info *fb_info = dev_get_drvdata(device); + struct fb_info *fb_info = class_get_devdata(class_device); u32 state; char *last = NULL; @@ -404,19 +385,17 @@ static ssize_t store_fbstate(struct device *device, return count; } -static ssize_t show_fbstate(struct device *device, - struct device_attribute *attr, char *buf) +static ssize_t show_fbstate(struct class_device *class_device, char *buf) { - struct fb_info *fb_info = dev_get_drvdata(device); + struct fb_info *fb_info = class_get_devdata(class_device); return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->state); } #ifdef CONFIG_FB_BACKLIGHT -static ssize_t store_bl_curve(struct device *device, - struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t store_bl_curve(struct class_device *class_device, + const char *buf, size_t count) { - struct fb_info *fb_info = dev_get_drvdata(device); + struct fb_info *fb_info = class_get_devdata(class_device); u8 tmp_curve[FB_BACKLIGHT_LEVELS]; unsigned int i; @@ -453,10 +432,9 @@ static ssize_t store_bl_curve(struct device *device, return count; } -static ssize_t show_bl_curve(struct device *device, - struct device_attribute *attr, char *buf) +static ssize_t show_bl_curve(struct class_device *class_device, char *buf) { - struct fb_info *fb_info = dev_get_drvdata(device); + struct fb_info *fb_info = class_get_devdata(class_device); ssize_t len = 0; unsigned int i; @@ -487,7 +465,7 @@ static ssize_t show_bl_curve(struct device *device, /* When cmap is added back in it should be a binary attribute * not a text one. Consideration should also be given to converting * fbdev to use configfs instead of sysfs */ -static struct device_attribute device_attrs[] = { +static struct class_device_attribute class_device_attrs[] = { __ATTR(bits_per_pixel, S_IRUGO|S_IWUSR, show_bpp, store_bpp), __ATTR(blank, S_IRUGO|S_IWUSR, show_blank, store_blank), __ATTR(console, S_IRUGO|S_IWUSR, show_console, store_console), @@ -505,16 +483,17 @@ static struct device_attribute device_attrs[] = { #endif }; -int fb_init_device(struct fb_info *fb_info) +int fb_init_class_device(struct fb_info *fb_info) { int i, error = 0; - dev_set_drvdata(fb_info->dev, fb_info); + class_set_devdata(fb_info->class_device, fb_info); fb_info->class_flag |= FB_SYSFS_FLAG_ATTR; - for (i = 0; i < ARRAY_SIZE(device_attrs); i++) { - error = device_create_file(fb_info->dev, &device_attrs[i]); + for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) { + error = class_device_create_file(fb_info->class_device, + &class_device_attrs[i]); if (error) break; @@ -522,20 +501,22 @@ int fb_init_device(struct fb_info *fb_info) if (error) { while (--i >= 0) - device_remove_file(fb_info->dev, &device_attrs[i]); + class_device_remove_file(fb_info->class_device, + &class_device_attrs[i]); fb_info->class_flag &= ~FB_SYSFS_FLAG_ATTR; } return 0; } -void fb_cleanup_device(struct fb_info *fb_info) +void fb_cleanup_class_device(struct fb_info *fb_info) { unsigned int i; if (fb_info->class_flag & FB_SYSFS_FLAG_ATTR) { - for (i = 0; i < ARRAY_SIZE(device_attrs); i++) - device_remove_file(fb_info->dev, &device_attrs[i]); + for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) + class_device_remove_file(fb_info->class_device, + &class_device_attrs[i]); fb_info->class_flag &= ~FB_SYSFS_FLAG_ATTR; } diff --git a/trunk/drivers/video/hitfb.c b/trunk/drivers/video/hitfb.c index 3dc49424dc75..3afb472763c0 100644 --- a/trunk/drivers/video/hitfb.c +++ b/trunk/drivers/video/hitfb.c @@ -29,6 +29,7 @@ #include #include #include +#include #define WIDTH 640 diff --git a/trunk/drivers/video/igafb.c b/trunk/drivers/video/igafb.c index e6df492c22a5..67f384f86758 100644 --- a/trunk/drivers/video/igafb.c +++ b/trunk/drivers/video/igafb.c @@ -573,10 +573,3 @@ int __init igafb_setup(char *options) module_init(igafb_init); MODULE_LICENSE("GPL"); -static struct pci_device_id igafb_pci_tbl[] __devinitdata = { - { PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_1682, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { } -}; - -MODULE_DEVICE_TABLE(pci, igafb_pci_tbl); diff --git a/trunk/drivers/video/intelfb/intelfbhw.c b/trunk/drivers/video/intelfb/intelfbhw.c index a95836839e1e..f887f1efd3fe 100644 --- a/trunk/drivers/video/intelfb/intelfbhw.c +++ b/trunk/drivers/video/intelfb/intelfbhw.c @@ -161,7 +161,7 @@ intelfbhw_get_memory(struct pci_dev *pdev, int *aperture_size, return 1; /* Find the bridge device. It is always 0:0.0 */ - if (!(bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0)))) { + if (!(bridge_dev = pci_find_slot(0, PCI_DEVFN(0, 0)))) { ERR_MSG("cannot find bridge device\n"); return 1; } @@ -169,8 +169,6 @@ intelfbhw_get_memory(struct pci_dev *pdev, int *aperture_size, /* Get the fb aperture size and "stolen" memory amount. */ tmp = 0; pci_read_config_word(bridge_dev, INTEL_GMCH_CTRL, &tmp); - pci_dev_put(bridge_dev); - switch (pdev->device) { case PCI_DEVICE_ID_INTEL_915G: case PCI_DEVICE_ID_INTEL_915GM: @@ -664,7 +662,7 @@ intelfbhw_print_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw) int index = dinfo->pll_index; DBG_MSG("intelfbhw_print_hw_state\n"); - if (!hw) + if (!hw || !dinfo) return; /* Read in as much of the HW state as possible. */ printk("hw state dump start\n"); @@ -1954,7 +1952,7 @@ intelfbhw_cursor_reset(struct intelfb_info *dinfo) { } static irqreturn_t -intelfbhw_irq(int irq, void *dev_id) { +intelfbhw_irq(int irq, void *dev_id, struct pt_regs *fp) { int handled = 0; u16 tmp; struct intelfb_info *dinfo = (struct intelfb_info *)dev_id; diff --git a/trunk/drivers/video/matrox/matroxfb_base.c b/trunk/drivers/video/matrox/matroxfb_base.c index e9b4115fcad0..7acf01c181ee 100644 --- a/trunk/drivers/video/matrox/matroxfb_base.c +++ b/trunk/drivers/video/matrox/matroxfb_base.c @@ -198,7 +198,7 @@ static void matroxfb_crtc1_panpos(WPMINFO2) { } } -static irqreturn_t matrox_irq(int irq, void *dev_id) +static irqreturn_t matrox_irq(int irq, void *dev_id, struct pt_regs *fp) { u_int32_t status; int handled = 0; diff --git a/trunk/drivers/video/nvidia/nv_hw.c b/trunk/drivers/video/nvidia/nv_hw.c index ea426115c6f9..9ed640d35728 100644 --- a/trunk/drivers/video/nvidia/nv_hw.c +++ b/trunk/drivers/video/nvidia/nv_hw.c @@ -145,18 +145,12 @@ static void nvGetClocks(struct nvidia_par *par, unsigned int *MClk, if (par->Architecture >= NV_ARCH_40) { pll = NV_RD32(par->PMC, 0x4020); - P = (pll >> 16) & 0x07; + P = (pll >> 16) & 0x03; pll = NV_RD32(par->PMC, 0x4024); M = pll & 0xFF; N = (pll >> 8) & 0xFF; - if (((par->Chipset & 0xfff0) == 0x0290) || - ((par->Chipset & 0xfff0) == 0x0390)) { - MB = 1; - NB = 1; - } else { - MB = (pll >> 16) & 0xFF; - NB = (pll >> 24) & 0xFF; - } + MB = (pll >> 16) & 0xFF; + NB = (pll >> 24) & 0xFF; *MClk = ((N * NB * par->CrystalFreqKHz) / (M * MB)) >> P; pll = NV_RD32(par->PMC, 0x4000); diff --git a/trunk/drivers/video/nvidia/nv_i2c.c b/trunk/drivers/video/nvidia/nv_i2c.c index 19eef3a09023..e48de3c9fd13 100644 --- a/trunk/drivers/video/nvidia/nv_i2c.c +++ b/trunk/drivers/video/nvidia/nv_i2c.c @@ -160,51 +160,12 @@ void nvidia_delete_i2c_busses(struct nvidia_par *par) } -static u8 *nvidia_do_probe_i2c_edid(struct nvidia_i2c_chan *chan) -{ - u8 start = 0x0; - struct i2c_msg msgs[] = { - { - .addr = 0x50, - .len = 1, - .buf = &start, - }, { - .addr = 0x50, - .flags = I2C_M_RD, - .len = EDID_LENGTH, - }, - }; - u8 *buf; - - if (!chan->par) - return NULL; - - buf = kmalloc(EDID_LENGTH, GFP_KERNEL); - if (!buf) { - dev_warn(&chan->par->pci_dev->dev, "Out of memory!\n"); - return NULL; - } - msgs[1].buf = buf; - - if (i2c_transfer(&chan->adapter, msgs, 2) == 2) - return buf; - dev_dbg(&chan->par->pci_dev->dev, "Unable to read EDID block.\n"); - kfree(buf); - return NULL; -} - int nvidia_probe_i2c_connector(struct fb_info *info, int conn, u8 **out_edid) { struct nvidia_par *par = info->par; - u8 *edid = NULL; - int i; - - for (i = 0; i < 3; i++) { - /* Do the real work */ - edid = nvidia_do_probe_i2c_edid(&par->chan[conn - 1]); - if (edid) - break; - } + u8 *edid; + + edid = fb_ddc_read(&par->chan[conn - 1].adapter); if (!edid && conn == 1) { /* try to get from firmware */ diff --git a/trunk/drivers/video/nvidia/nv_setup.c b/trunk/drivers/video/nvidia/nv_setup.c index eab3e282a4de..a18a9aebf05f 100644 --- a/trunk/drivers/video/nvidia/nv_setup.c +++ b/trunk/drivers/video/nvidia/nv_setup.c @@ -262,7 +262,7 @@ static void nv10GetConfig(struct nvidia_par *par) #endif dev = pci_find_slot(0, 1); - if ((par->Chipset & 0xffff) == 0x01a0) { + if ((par->Chipset && 0xffff) == 0x01a0) { int amt = 0; pci_read_config_dword(dev, 0x7c, &amt); @@ -359,7 +359,6 @@ int NVCommonSetup(struct fb_info *info) case 0x0186: case 0x0187: case 0x018D: - case 0x0228: case 0x0286: case 0x028C: case 0x0316: @@ -383,10 +382,6 @@ int NVCommonSetup(struct fb_info *info) case 0x034C: case 0x0160: case 0x0166: - case 0x0169: - case 0x016B: - case 0x016C: - case 0x016D: case 0x00C8: case 0x00CC: case 0x0144: @@ -644,23 +639,12 @@ int NVCommonSetup(struct fb_info *info) par->fpHeight = NV_RD32(par->PRAMDAC, 0x0800) + 1; par->fpSyncs = NV_RD32(par->PRAMDAC, 0x0848) & 0x30000033; - printk("nvidiafb: Panel size is %i x %i\n", par->fpWidth, par->fpHeight); + printk("Panel size is %i x %i\n", par->fpWidth, par->fpHeight); } if (monA) info->monspecs = *monA; - if (!par->FlatPanel || !par->twoHeads) - par->FPDither = 0; - - par->LVDS = 0; - if (par->FlatPanel && par->twoHeads) { - NV_WR32(par->PRAMDAC0, 0x08B0, 0x00010004); - if (par->PRAMDAC0[0x08b4] & 1) - par->LVDS = 1; - printk("nvidiafb: Panel is %s\n", par->LVDS ? "LVDS" : "TMDS"); - } - kfree(edidA); kfree(edidB); done: diff --git a/trunk/drivers/video/nvidia/nv_type.h b/trunk/drivers/video/nvidia/nv_type.h index 86e65dea60d3..acdc26693402 100644 --- a/trunk/drivers/video/nvidia/nv_type.h +++ b/trunk/drivers/video/nvidia/nv_type.h @@ -129,7 +129,6 @@ struct nvidia_par { int fpHeight; int PanelTweak; int paneltweak; - int LVDS; int pm_state; u32 crtcSync_read; u32 fpSyncs; diff --git a/trunk/drivers/video/nvidia/nvidia.c b/trunk/drivers/video/nvidia/nvidia.c index 538e947610e1..eb24107bcc81 100644 --- a/trunk/drivers/video/nvidia/nvidia.c +++ b/trunk/drivers/video/nvidia/nvidia.c @@ -1160,20 +1160,20 @@ static u32 __devinit nvidia_get_arch(struct fb_info *info) case 0x0340: /* GeForceFX 5700 */ arch = NV_ARCH_30; break; - case 0x0040: /* GeForce 6800 */ - case 0x00C0: /* GeForce 6800 */ - case 0x0120: /* GeForce 6800 */ + case 0x0040: + case 0x00C0: + case 0x0120: case 0x0130: - case 0x0140: /* GeForce 6600 */ - case 0x0160: /* GeForce 6200 */ - case 0x01D0: /* GeForce 7200, 7300, 7400 */ - case 0x0090: /* GeForce 7800 */ - case 0x0210: /* GeForce 6800 */ - case 0x0220: /* GeForce 6200 */ + case 0x0140: + case 0x0160: + case 0x01D0: + case 0x0090: + case 0x0210: + case 0x0220: case 0x0230: - case 0x0240: /* GeForce 6100 */ - case 0x0290: /* GeForce 7900 */ - case 0x0390: /* GeForce 7600 */ + case 0x0240: + case 0x0290: + case 0x0390: arch = NV_ARCH_40; break; case 0x0020: /* TNT, TNT2 */ diff --git a/trunk/drivers/video/offb.c b/trunk/drivers/video/offb.c index 9a40bbecf76b..bad0e98fb3b6 100644 --- a/trunk/drivers/video/offb.c +++ b/trunk/drivers/video/offb.c @@ -157,7 +157,7 @@ static int offb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, out_le32(par->cmap_adr + 0xb4, (red << 16 | green << 8 | blue)); break; case cmap_gxt2000: - out_le32(((unsigned __iomem *) par->cmap_adr) + regno, + out_le32((unsigned __iomem *) par->cmap_adr + regno, (red << 16 | green << 8 | blue)); break; } @@ -213,7 +213,7 @@ static int offb_blank(int blank, struct fb_info *info) out_le32(par->cmap_adr + 0xb4, 0); break; case cmap_gxt2000: - out_le32(((unsigned __iomem *) par->cmap_adr) + i, + out_le32((unsigned __iomem *) par->cmap_adr + i, 0); break; } @@ -226,23 +226,13 @@ static int offb_blank(int blank, struct fb_info *info) static void __iomem *offb_map_reg(struct device_node *np, int index, unsigned long offset, unsigned long size) { - const u32 *addrp; - u64 asize, taddr; - unsigned int flags; - - addrp = of_get_pci_address(np, index, &asize, &flags); - if (addrp == NULL) - addrp = of_get_address(np, index, &asize, &flags); - if (addrp == NULL) - return NULL; - if ((flags & (IORESOURCE_IO | IORESOURCE_MEM)) == 0) - return NULL; - if ((offset + size) > asize) - return NULL; - taddr = of_translate_address(np, addrp); - if (taddr == OF_BAD_ADDR) - return NULL; - return ioremap(taddr + offset, size); + struct resource r; + + if (of_address_to_resource(np, index, &r)) + return 0; + if ((r.start + offset + size) > r.end) + return 0; + return ioremap(r.start + offset, size); } static void __init offb_init_fb(const char *name, const char *full_name, @@ -299,6 +289,7 @@ static void __init offb_init_fb(const char *name, const char *full_name, par->cmap_type = cmap_unknown; if (depth == 8) { + /* Palette hacks disabled for now */ if (dp && !strncmp(name, "ATY,Rage128", 11)) { par->cmap_adr = offb_map_reg(dp, 2, 0, 0x1fff); if (par->cmap_adr) @@ -322,8 +313,7 @@ static void __init offb_init_fb(const char *name, const char *full_name, ioremap(base + 0x7ff000, 0x1000) + 0xcc0; par->cmap_data = par->cmap_adr + 1; par->cmap_type = cmap_m64; - } else if (dp && (device_is_compatible(dp, "pci1014,b7") || - device_is_compatible(dp, "pci1014,21c"))) { + } else if (dp && device_is_compatible(dp, "pci1014,b7")) { par->cmap_adr = offb_map_reg(dp, 0, 0x6000, 0x1000); if (par->cmap_adr) par->cmap_type = cmap_gxt2000; @@ -443,7 +433,7 @@ static void __init offb_init_nodriver(struct device_node *dp, int no_real_node) pp = get_property(dp, "linux,bootx-linebytes", &len); if (pp == NULL) pp = get_property(dp, "linebytes", &len); - if (pp && len == sizeof(u32) && (*pp != 0xffffffffu)) + if (pp && len == sizeof(u32)) pitch = *pp; else pitch = width * ((depth + 7) / 8); @@ -506,7 +496,7 @@ static void __init offb_init_nodriver(struct device_node *dp, int no_real_node) offb_init_fb(no_real_node ? "bootx" : dp->name, no_real_node ? "display" : dp->full_name, width, height, depth, pitch, address, - no_real_node ? NULL : dp); + no_real_node ? dp : NULL); } } diff --git a/trunk/drivers/video/platinumfb.c b/trunk/drivers/video/platinumfb.c index fdb33cd21a27..983be3ec2345 100644 --- a/trunk/drivers/video/platinumfb.c +++ b/trunk/drivers/video/platinumfb.c @@ -339,12 +339,11 @@ static int __devinit platinum_init_fb(struct fb_info *info) sense = read_platinum_sense(pinfo); printk(KERN_INFO "platinumfb: Monitor sense value = 0x%x, ", sense); + if (default_vmode == VMODE_NVRAM) { -#ifdef CONFIG_NVRAM default_vmode = nvram_read_byte(NV_VMODE); if (default_vmode <= 0 || default_vmode > VMODE_MAX || !platinum_reg_init[default_vmode-1]) -#endif default_vmode = VMODE_CHOOSE; } if (default_vmode == VMODE_CHOOSE) { @@ -352,10 +351,8 @@ static int __devinit platinum_init_fb(struct fb_info *info) } if (default_vmode <= 0 || default_vmode > VMODE_MAX) default_vmode = VMODE_640_480_60; -#ifdef CONFIG_NVRAM if (default_cmode == CMODE_NVRAM) default_cmode = nvram_read_byte(NV_CMODE); -#endif if (default_cmode < CMODE_8 || default_cmode > CMODE_32) default_cmode = CMODE_8; /* diff --git a/trunk/drivers/video/pnx4008/pnxrgbfb.c b/trunk/drivers/video/pnx4008/pnxrgbfb.c index f29e66e2d774..7d9453c91a42 100644 --- a/trunk/drivers/video/pnx4008/pnxrgbfb.c +++ b/trunk/drivers/video/pnx4008/pnxrgbfb.c @@ -154,8 +154,7 @@ static int __devinit rgbfb_probe(struct platform_device *pdev) goto err1; } - if (!fb_get_options("pnxrgbfb", &option) && option && - !strcmp(option, "nocursor")) + if (!fb_get_options("pnxrgbfb", &option) && !strcmp(option, "nocursor")) rgbfb_ops.fb_cursor = no_cursor; info->node = -1; @@ -192,7 +191,7 @@ static int __devinit rgbfb_probe(struct platform_device *pdev) static struct platform_driver rgbfb_driver = { .driver = { - .name = "pnx4008-rgbfb", + .name = "rgbfb", }, .probe = rgbfb_probe, .remove = rgbfb_remove, diff --git a/trunk/drivers/video/pnx4008/sdum.c b/trunk/drivers/video/pnx4008/sdum.c index d23bf0d659b6..51f0ecc2a511 100644 --- a/trunk/drivers/video/pnx4008/sdum.c +++ b/trunk/drivers/video/pnx4008/sdum.c @@ -848,7 +848,7 @@ static int sdum_remove(struct platform_device *pdev) static struct platform_driver sdum_driver = { .driver = { - .name = "pnx4008-sdum", + .name = "sdum", }, .probe = sdum_probe, .remove = sdum_remove, diff --git a/trunk/drivers/video/pvr2fb.c b/trunk/drivers/video/pvr2fb.c index c7bc80921f16..78dc59a1751b 100644 --- a/trunk/drivers/video/pvr2fb.c +++ b/trunk/drivers/video/pvr2fb.c @@ -209,7 +209,7 @@ static int pvr2fb_set_par(struct fb_info *info); static void pvr2_update_display(struct fb_info *info); static void pvr2_init_display(struct fb_info *info); static void pvr2_do_blank(void); -static irqreturn_t pvr2fb_interrupt(int irq, void *dev_id); +static irqreturn_t pvr2fb_interrupt(int irq, void *dev_id, struct pt_regs *fp); static int pvr2_init_cable(void); static int pvr2_get_param(const struct pvr2_params *p, const char *s, int val, int size); @@ -626,7 +626,7 @@ static void pvr2_do_blank(void) is_blanked = do_blank > 0 ? do_blank : 0; } -static irqreturn_t pvr2fb_interrupt(int irq, void *dev_id) +static irqreturn_t pvr2fb_interrupt(int irq, void *dev_id, struct pt_regs *fp) { struct fb_info *info = dev_id; diff --git a/trunk/drivers/video/pxafb.c b/trunk/drivers/video/pxafb.c index 8a8ae55a7403..3bc5da4a57ca 100644 --- a/trunk/drivers/video/pxafb.c +++ b/trunk/drivers/video/pxafb.c @@ -846,7 +846,7 @@ static void pxafb_disable_controller(struct pxafb_info *fbi) /* * pxafb_handle_irq: Handle 'LCD DONE' interrupts. */ -static irqreturn_t pxafb_handle_irq(int irq, void *dev_id) +static irqreturn_t pxafb_handle_irq(int irq, void *dev_id, struct pt_regs *regs) { struct pxafb_info *fbi = dev_id; unsigned int lcsr = LCSR; diff --git a/trunk/drivers/video/s3c2410fb.c b/trunk/drivers/video/s3c2410fb.c index 59407343cc73..ad3bdd6f1ac1 100644 --- a/trunk/drivers/video/s3c2410fb.c +++ b/trunk/drivers/video/s3c2410fb.c @@ -614,7 +614,7 @@ static void s3c2410fb_write_palette(struct s3c2410fb_info *fbi) } } -static irqreturn_t s3c2410fb_irq(int irq, void *dev_id) +static irqreturn_t s3c2410fb_irq(int irq, void *dev_id, struct pt_regs *r) { struct s3c2410fb_info *fbi = dev_id; unsigned long lcdirq = readl(S3C2410_LCDINTPND); diff --git a/trunk/drivers/video/sa1100fb.c b/trunk/drivers/video/sa1100fb.c index cd10b18150b8..a2e6e7205d7e 100644 --- a/trunk/drivers/video/sa1100fb.c +++ b/trunk/drivers/video/sa1100fb.c @@ -1085,7 +1085,7 @@ static void sa1100fb_disable_controller(struct sa1100fb_info *fbi) /* * sa1100fb_handle_irq: Handle 'LCD DONE' interrupts. */ -static irqreturn_t sa1100fb_handle_irq(int irq, void *dev_id) +static irqreturn_t sa1100fb_handle_irq(int irq, void *dev_id, struct pt_regs *regs) { struct sa1100fb_info *fbi = dev_id; unsigned int lcsr = LCSR; diff --git a/trunk/drivers/video/valkyriefb.c b/trunk/drivers/video/valkyriefb.c index 06fc19a61192..47f27924a7d7 100644 --- a/trunk/drivers/video/valkyriefb.c +++ b/trunk/drivers/video/valkyriefb.c @@ -284,7 +284,7 @@ static void __init valkyrie_choose_mode(struct fb_info_valkyrie *p) printk(KERN_INFO "Monitor sense value = 0x%x\n", p->sense); /* Try to pick a video mode out of NVRAM if we have one. */ -#if !defined(CONFIG_MAC) && defined(CONFIG_NVRAM) +#ifndef CONFIG_MAC if (default_vmode == VMODE_NVRAM) { default_vmode = nvram_read_byte(NV_VMODE); if (default_vmode <= 0 @@ -297,7 +297,7 @@ static void __init valkyrie_choose_mode(struct fb_info_valkyrie *p) default_vmode = mac_map_monitor_sense(p->sense); if (!valkyrie_reg_init[default_vmode - 1]) default_vmode = VMODE_640_480_67; -#if !defined(CONFIG_MAC) && defined(CONFIG_NVRAM) +#ifndef CONFIG_MAC if (default_cmode == CMODE_NVRAM) default_cmode = nvram_read_byte(NV_CMODE); #endif diff --git a/trunk/drivers/w1/Kconfig b/trunk/drivers/w1/Kconfig index c287a9ae4fdd..27c9d05d03ef 100644 --- a/trunk/drivers/w1/Kconfig +++ b/trunk/drivers/w1/Kconfig @@ -2,6 +2,7 @@ menu "Dallas's 1-wire bus" config W1 tristate "Dallas's 1-wire support" + depends on CONNECTOR ---help--- Dallas' 1-wire bus is useful to connect slow 1-pin devices such as iButtons and thermal sensors. diff --git a/trunk/drivers/w1/masters/matrox_w1.c b/trunk/drivers/w1/masters/matrox_w1.c index 6f9d880ab2e9..2788b8ca9bb1 100644 --- a/trunk/drivers/w1/masters/matrox_w1.c +++ b/trunk/drivers/w1/masters/matrox_w1.c @@ -215,8 +215,6 @@ static int __devinit matrox_w1_probe(struct pci_dev *pdev, const struct pci_devi return 0; err_out_free_device: - if (dev->virt_addr) - iounmap(dev->virt_addr); kfree(dev); return err; diff --git a/trunk/fs/Kconfig b/trunk/fs/Kconfig index b3b5aa0edff9..599de54451af 100644 --- a/trunk/fs/Kconfig +++ b/trunk/fs/Kconfig @@ -140,73 +140,6 @@ config EXT3_FS_SECURITY If you are not using a security module that requires using extended attributes for file security labels, say N. -config EXT4DEV_FS - tristate "Ext4dev/ext4 extended fs support development (EXPERIMENTAL)" - depends on EXPERIMENTAL - select JBD2 - help - Ext4dev is a predecessor filesystem of the next generation - extended fs ext4, based on ext3 filesystem code. It will be - renamed ext4 fs later, once ext4dev is mature and stabilized. - - Unlike the change from ext2 filesystem to ext3 filesystem, - the on-disk format of ext4dev is not the same as ext3 any more: - it is based on extent maps and it supports 48-bit physical block - numbers. These combined on-disk format changes will allow - ext4dev/ext4 to handle more than 16 TB filesystem volumes -- - a hard limit that ext3 cannot overcome without changing the - on-disk format. - - Other than extent maps and 48-bit block numbers, ext4dev also is - likely to have other new features such as persistent preallocation, - high resolution time stamps, and larger file support etc. These - features will be added to ext4dev gradually. - - To compile this file system support as a module, choose M here. The - module will be called ext4dev. Be aware, however, that the filesystem - of your root partition (the one containing the directory /) cannot - be compiled as a module, and so this could be dangerous. - - If unsure, say N. - -config EXT4DEV_FS_XATTR - bool "Ext4dev extended attributes" - depends on EXT4DEV_FS - default y - help - Extended attributes are name:value pairs associated with inodes by - the kernel or by users (see the attr(5) manual page, or visit - for details). - - If unsure, say N. - - You need this for POSIX ACL support on ext4dev/ext4. - -config EXT4DEV_FS_POSIX_ACL - bool "Ext4dev POSIX Access Control Lists" - depends on EXT4DEV_FS_XATTR - select FS_POSIX_ACL - help - POSIX Access Control Lists (ACLs) support permissions for users and - groups beyond the owner/group/world scheme. - - To learn more about Access Control Lists, visit the POSIX ACLs for - Linux website . - - If you don't know what Access Control Lists are, say N - -config EXT4DEV_FS_SECURITY - bool "Ext4dev Security Labels" - depends on EXT4DEV_FS_XATTR - help - Security labels support alternative access control models - implemented by security modules like SELinux. This option - enables an extended attribute handler for file security - labels in the ext4dev/ext4 filesystem. - - If you are not using a security module that requires using - extended attributes for file security labels, say N. - config JBD tristate help @@ -239,44 +172,12 @@ config JBD_DEBUG generated. To turn debugging off again, do "echo 0 > /proc/sys/fs/jbd-debug". -config JBD2 - tristate - help - This is a generic journaling layer for block devices that support - both 32-bit and 64-bit block numbers. It is currently used by - the ext4dev/ext4 filesystem, but it could also be used to add - journal support to other file systems or block devices such - as RAID or LVM. - - If you are using ext4dev/ext4, you need to say Y here. If you are not - using ext4dev/ext4 then you will probably want to say N. - - To compile this device as a module, choose M here. The module will be - called jbd2. If you are compiling ext4dev/ext4 into the kernel, - you cannot compile this code as a module. - -config JBD2_DEBUG - bool "JBD2 (ext4dev/ext4) debugging support" - depends on JBD2 - help - If you are using the ext4dev/ext4 journaled file system (or - potentially any other filesystem/device using JBD2), this option - allows you to enable debugging output while the system is running, - in order to help track down any problems you are having. - By default, the debugging output will be turned off. - - If you select Y here, then you will be able to turn on debugging - with "echo N > /proc/sys/fs/jbd2-debug", where N is a number between - 1 and 5. The higher the number, the more debugging output is - generated. To turn debugging off again, do - "echo 0 > /proc/sys/fs/jbd2-debug". - config FS_MBCACHE -# Meta block cache for Extended Attributes (ext2/ext3/ext4) +# Meta block cache for Extended Attributes (ext2/ext3) tristate - depends on EXT2_FS_XATTR || EXT3_FS_XATTR || EXT4DEV_FS_XATTR - default y if EXT2_FS=y || EXT3_FS=y || EXT4DEV_FS=y - default m if EXT2_FS=m || EXT3_FS=m || EXT4DEV_FS=m + depends on EXT2_FS_XATTR || EXT3_FS_XATTR + default y if EXT2_FS=y || EXT3_FS=y + default m if EXT2_FS=m || EXT3_FS=m config REISERFS_FS tristate "Reiserfs support" @@ -634,10 +535,6 @@ config FUSE_FS If you want to develop a userspace FS, or if you want to use a filesystem based on FUSE, answer Y or M. -config GENERIC_ACL - bool - select FS_POSIX_ACL - if BLOCK menu "CD-ROM/DVD Filesystems" @@ -972,7 +869,7 @@ config SYSFS Some system agents rely on the information in sysfs to operate. /sbin/hotplug uses device and object attributes in sysfs to assist in - delegating policy decisions, like persistently naming devices. + delegating policy decisions, like persistantly naming devices. sysfs is currently used by the block subsystem to mount the root partition. If sysfs is disabled you must specify the boot device on @@ -1145,7 +1042,7 @@ config BEFS_FS help The BeOS File System (BeFS) is the native file system of Be, Inc's BeOS. Notable features include support for arbitrary attributes - on files and directories, and database-like indices on selected + on files and directories, and database-like indeces on selected attributes. (Also note that this driver doesn't make those features available at this time). It is a 64 bit filesystem, so it supports extremely large volumes and files. @@ -1777,7 +1674,6 @@ config RPCSEC_GSS_KRB5 select CRYPTO select CRYPTO_MD5 select CRYPTO_DES - select CRYPTO_CBC help Provides for secure RPC calls by means of a gss-api mechanism based on Kerberos V5. This is required for @@ -1796,7 +1692,6 @@ config RPCSEC_GSS_SPKM3 select CRYPTO_MD5 select CRYPTO_DES select CRYPTO_CAST5 - select CRYPTO_CBC help Provides for secure RPC calls by means of a gss-api mechanism based on the SPKM3 public-key mechanism. @@ -1992,7 +1887,7 @@ config CIFS_EXPERIMENTAL config CIFS_UPCALL bool "Kerberos/SPNEGO advanced session setup (EXPERIMENTAL)" depends on CIFS_EXPERIMENTAL - depends on CONNECTOR + select CONNECTOR help Enables an upcall mechanism for CIFS which will be used to contact userspace helper utilities to provide SPNEGO packaged Kerberos @@ -2060,7 +1955,8 @@ config CODA_FS_OLD_API For most cases you probably want to say N. config AFS_FS - tristate "Andrew File System support (AFS) (EXPERIMENTAL)" +# for fs/nls/Config.in + tristate "Andrew File System support (AFS) (Experimental)" depends on INET && EXPERIMENTAL select RXRPC help @@ -2085,6 +1981,10 @@ config 9P_FS If unsure, say N. +config GENERIC_ACL + bool + select FS_POSIX_ACL + endmenu if BLOCK diff --git a/trunk/fs/Makefile b/trunk/fs/Makefile index 9a5ce9323bfd..df614eacee86 100644 --- a/trunk/fs/Makefile +++ b/trunk/fs/Makefile @@ -62,9 +62,7 @@ obj-$(CONFIG_DLM) += dlm/ # Do not add any filesystems before this line obj-$(CONFIG_REISERFS_FS) += reiserfs/ obj-$(CONFIG_EXT3_FS) += ext3/ # Before ext2 so root fs can be ext3 -obj-$(CONFIG_EXT4DEV_FS) += ext4/ # Before ext2 so root fs can be ext4dev obj-$(CONFIG_JBD) += jbd/ -obj-$(CONFIG_JBD2) += jbd2/ obj-$(CONFIG_EXT2_FS) += ext2/ obj-$(CONFIG_CRAMFS) += cramfs/ obj-$(CONFIG_RAMFS) += ramfs/ diff --git a/trunk/fs/afs/dir.c b/trunk/fs/afs/dir.c index a6ec75c56fcf..cf8a2cb28505 100644 --- a/trunk/fs/afs/dir.c +++ b/trunk/fs/afs/dir.c @@ -211,8 +211,8 @@ static int afs_dir_open(struct inode *inode, struct file *file) { _enter("{%lu}", inode->i_ino); - BUILD_BUG_ON(sizeof(union afs_dir_block) != 2048); - BUILD_BUG_ON(sizeof(union afs_dirent) != 32); + BUG_ON(sizeof(union afs_dir_block) != 2048); + BUG_ON(sizeof(union afs_dirent) != 32); if (AFS_FS_I(inode)->flags & AFS_VNODE_DELETED) return -ENOENT; @@ -446,8 +446,8 @@ static struct dentry *afs_dir_lookup(struct inode *dir, struct dentry *dentry, _enter("{%lu},%p{%s}", dir->i_ino, dentry, dentry->d_name.name); /* insanity checks first */ - BUILD_BUG_ON(sizeof(union afs_dir_block) != 2048); - BUILD_BUG_ON(sizeof(union afs_dirent) != 32); + BUG_ON(sizeof(union afs_dir_block) != 2048); + BUG_ON(sizeof(union afs_dirent) != 32); if (dentry->d_name.len > 255) { _leave(" = -ENAMETOOLONG"); diff --git a/trunk/fs/aio.c b/trunk/fs/aio.c index 277a5f2d18ad..94766599db00 100644 --- a/trunk/fs/aio.c +++ b/trunk/fs/aio.c @@ -367,7 +367,8 @@ void fastcall __put_ioctx(struct kioctx *ctx) { unsigned nr_events = ctx->max_reqs; - BUG_ON(ctx->reqs_active); + if (unlikely(ctx->reqs_active)) + BUG(); cancel_delayed_work(&ctx->wq); flush_workqueue(aio_wq); @@ -504,7 +505,8 @@ static int __aio_put_req(struct kioctx *ctx, struct kiocb *req) assert_spin_locked(&ctx->ctx_lock); req->ki_users --; - BUG_ON(req->ki_users < 0); + if (unlikely(req->ki_users < 0)) + BUG(); if (likely(req->ki_users)) return 0; list_del(&req->ki_list); /* remove from active_reqs */ diff --git a/trunk/fs/autofs/autofs_i.h b/trunk/fs/autofs/autofs_i.h index 906ba5ce2261..c7700d9b3f96 100644 --- a/trunk/fs/autofs/autofs_i.h +++ b/trunk/fs/autofs/autofs_i.h @@ -149,7 +149,6 @@ extern const struct file_operations autofs_root_operations; /* Initializing function */ int autofs_fill_super(struct super_block *, void *, int); -void autofs_kill_sb(struct super_block *sb); /* Queue management functions */ diff --git a/trunk/fs/autofs/dirhash.c b/trunk/fs/autofs/dirhash.c index bf8c8af98004..3fded389d06b 100644 --- a/trunk/fs/autofs/dirhash.c +++ b/trunk/fs/autofs/dirhash.c @@ -246,4 +246,5 @@ void autofs_hash_nuke(struct autofs_sb_info *sbi) kfree(ent); } } + shrink_dcache_sb(sbi->sb); } diff --git a/trunk/fs/autofs/init.c b/trunk/fs/autofs/init.c index cea5219b4f37..aca123752406 100644 --- a/trunk/fs/autofs/init.c +++ b/trunk/fs/autofs/init.c @@ -24,7 +24,7 @@ static struct file_system_type autofs_fs_type = { .owner = THIS_MODULE, .name = "autofs", .get_sb = autofs_get_sb, - .kill_sb = autofs_kill_sb, + .kill_sb = kill_anon_super, }; static int __init init_autofs_fs(void) diff --git a/trunk/fs/autofs/inode.c b/trunk/fs/autofs/inode.c index 38ede5c9d6fd..2c9759baad61 100644 --- a/trunk/fs/autofs/inode.c +++ b/trunk/fs/autofs/inode.c @@ -20,19 +20,11 @@ #include "autofs_i.h" #include -void autofs_kill_sb(struct super_block *sb) +static void autofs_put_super(struct super_block *sb) { struct autofs_sb_info *sbi = autofs_sbi(sb); unsigned int n; - /* - * In the event of a failure in get_sb_nodev the superblock - * info is not present so nothing else has been setup, so - * just exit when we are called from deactivate_super. - */ - if (!sbi) - return; - if ( !sbi->catatonic ) autofs_catatonic_mode(sbi); /* Free wait queues, close pipe */ @@ -45,13 +37,13 @@ void autofs_kill_sb(struct super_block *sb) kfree(sb->s_fs_info); DPRINTK(("autofs: shutting down\n")); - kill_anon_super(sb); } static void autofs_read_inode(struct inode *inode); static struct super_operations autofs_sops = { .read_inode = autofs_read_inode, + .put_super = autofs_put_super, .statfs = simple_statfs, }; @@ -144,8 +136,7 @@ int autofs_fill_super(struct super_block *s, void *data, int silent) s->s_fs_info = sbi; sbi->magic = AUTOFS_SBI_MAGIC; - sbi->pipe = NULL; - sbi->catatonic = 1; + sbi->catatonic = 0; sbi->exp_timeout = 0; sbi->oz_pgrp = process_group(current); autofs_initialize_hash(&sbi->dirhash); @@ -189,7 +180,6 @@ int autofs_fill_super(struct super_block *s, void *data, int silent) if ( !pipe->f_op || !pipe->f_op->write ) goto fail_fput; sbi->pipe = pipe; - sbi->catatonic = 0; /* * Success! Install the root dentry now to indicate completion. @@ -208,8 +198,6 @@ int autofs_fill_super(struct super_block *s, void *data, int silent) iput(root_inode); fail_free: kfree(sbi); - s->s_fs_info = NULL; - kill_anon_super(s); fail_unlock: return -EINVAL; } diff --git a/trunk/fs/autofs/waitq.c b/trunk/fs/autofs/waitq.c index 19a9cafb5ddf..633f628005b4 100644 --- a/trunk/fs/autofs/waitq.c +++ b/trunk/fs/autofs/waitq.c @@ -41,7 +41,6 @@ void autofs_catatonic_mode(struct autofs_sb_info *sbi) wq = nwq; } fput(sbi->pipe); /* Close the pipe */ - sbi->pipe = NULL; autofs_hash_dputall(&sbi->dirhash); /* Remove all dentry pointers */ } diff --git a/trunk/fs/autofs4/autofs_i.h b/trunk/fs/autofs4/autofs_i.h index b13f32c8aeee..480ab178cba5 100644 --- a/trunk/fs/autofs4/autofs_i.h +++ b/trunk/fs/autofs4/autofs_i.h @@ -94,6 +94,7 @@ struct autofs_wait_queue { struct autofs_sb_info { u32 magic; + struct dentry *root; int pipefd; struct file *pipe; pid_t oz_pgrp; @@ -228,4 +229,4 @@ static inline int __simple_empty(struct dentry *dentry) } void autofs4_dentry_release(struct dentry *); -extern void autofs4_kill_sb(struct super_block *); + diff --git a/trunk/fs/autofs4/init.c b/trunk/fs/autofs4/init.c index 723a1c5e361b..5d9193332bef 100644 --- a/trunk/fs/autofs4/init.c +++ b/trunk/fs/autofs4/init.c @@ -24,7 +24,7 @@ static struct file_system_type autofs_fs_type = { .owner = THIS_MODULE, .name = "autofs", .get_sb = autofs_get_sb, - .kill_sb = autofs4_kill_sb, + .kill_sb = kill_anon_super, }; static int __init init_autofs4_fs(void) diff --git a/trunk/fs/autofs4/inode.c b/trunk/fs/autofs4/inode.c index ce7c0f1dd529..800ce876caec 100644 --- a/trunk/fs/autofs4/inode.c +++ b/trunk/fs/autofs4/inode.c @@ -96,12 +96,9 @@ void autofs4_free_ino(struct autofs_info *ino) */ static void autofs4_force_release(struct autofs_sb_info *sbi) { - struct dentry *this_parent = sbi->sb->s_root; + struct dentry *this_parent = sbi->root; struct list_head *next; - if (!sbi->sb->s_root) - return; - spin_lock(&dcache_lock); repeat: next = this_parent->d_subdirs.next; @@ -130,7 +127,7 @@ static void autofs4_force_release(struct autofs_sb_info *sbi) spin_lock(&dcache_lock); } - if (this_parent != sbi->sb->s_root) { + if (this_parent != sbi->root) { struct dentry *dentry = this_parent; next = this_parent->d_u.d_child.next; @@ -143,20 +140,18 @@ static void autofs4_force_release(struct autofs_sb_info *sbi) goto resume; } spin_unlock(&dcache_lock); + + dput(sbi->root); + sbi->root = NULL; + shrink_dcache_sb(sbi->sb); + + return; } -void autofs4_kill_sb(struct super_block *sb) +static void autofs4_put_super(struct super_block *sb) { struct autofs_sb_info *sbi = autofs4_sbi(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 exit when we are called from deactivate_super. - */ - if (!sbi) - return; - sb->s_fs_info = NULL; if ( !sbi->catatonic ) @@ -168,7 +163,6 @@ void autofs4_kill_sb(struct super_block *sb) kfree(sbi); DPRINTK("shutting down"); - kill_anon_super(sb); } static int autofs4_show_options(struct seq_file *m, struct vfsmount *mnt) @@ -195,6 +189,7 @@ static int autofs4_show_options(struct seq_file *m, struct vfsmount *mnt) } static struct super_operations autofs4_sops = { + .put_super = autofs4_put_super, .statfs = simple_statfs, .show_options = autofs4_show_options, }; @@ -320,9 +315,9 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent) s->s_fs_info = sbi; sbi->magic = AUTOFS_SBI_MAGIC; + sbi->root = NULL; sbi->pipefd = -1; - sbi->pipe = NULL; - sbi->catatonic = 1; + sbi->catatonic = 0; sbi->exp_timeout = 0; sbi->oz_pgrp = process_group(current); sbi->sb = s; @@ -400,7 +395,13 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent) goto fail_fput; sbi->pipe = pipe; sbi->pipefd = pipefd; - sbi->catatonic = 0; + + /* + * Take a reference to the root dentry so we get a chance to + * clean up the dentry tree on umount. + * See autofs4_force_release. + */ + sbi->root = dget(root); /* * Success! Install the root dentry now to indicate completion. @@ -425,8 +426,6 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent) kfree(ino); fail_free: kfree(sbi); - s->s_fs_info = NULL; - kill_anon_super(s); fail_unlock: return -EINVAL; } diff --git a/trunk/fs/autofs4/waitq.c b/trunk/fs/autofs4/waitq.c index 1e4a539f4417..ce103e7b0bc3 100644 --- a/trunk/fs/autofs4/waitq.c +++ b/trunk/fs/autofs4/waitq.c @@ -41,8 +41,11 @@ void autofs4_catatonic_mode(struct autofs_sb_info *sbi) wake_up_interruptible(&wq->queue); wq = nwq; } - fput(sbi->pipe); /* Close the pipe */ - sbi->pipe = NULL; + if (sbi->pipe) { + fput(sbi->pipe); /* Close the pipe */ + sbi->pipe = NULL; + } + shrink_dcache_sb(sbi->sb); } static int autofs4_write(struct file *file, const void *addr, int bytes) diff --git a/trunk/fs/befs/befs.h b/trunk/fs/befs/befs.h index d9a40abda6b7..057a2c3d73b7 100644 --- a/trunk/fs/befs/befs.h +++ b/trunk/fs/befs/befs.h @@ -94,7 +94,7 @@ void befs_debug(const struct super_block *sb, const char *fmt, ...); void befs_dump_super_block(const struct super_block *sb, befs_super_block *); void befs_dump_inode(const struct super_block *sb, befs_inode *); -void befs_dump_index_entry(const struct super_block *sb, befs_disk_btree_super *); +void befs_dump_index_entry(const struct super_block *sb, befs_btree_super *); void befs_dump_index_node(const struct super_block *sb, befs_btree_nodehead *); /****************************/ @@ -136,7 +136,7 @@ blockno2iaddr(struct super_block *sb, befs_blocknr_t blockno) static inline unsigned int befs_iaddrs_per_block(struct super_block *sb) { - return BEFS_SB(sb)->block_size / sizeof (befs_disk_inode_addr); + return BEFS_SB(sb)->block_size / sizeof (befs_inode_addr); } static inline int @@ -151,6 +151,4 @@ befs_brun_size(struct super_block *sb, befs_block_run run) return BEFS_SB(sb)->block_size * run.len; } -#include "endian.h" - #endif /* _LINUX_BEFS_H */ diff --git a/trunk/fs/befs/befs_fs_types.h b/trunk/fs/befs/befs_fs_types.h index e2595c2c403a..63ef1e18fb84 100644 --- a/trunk/fs/befs/befs_fs_types.h +++ b/trunk/fs/befs/befs_fs_types.h @@ -79,27 +79,17 @@ enum inode_flags { * On-Disk datastructures of BeFS */ -typedef u64 __bitwise fs64; -typedef u32 __bitwise fs32; -typedef u16 __bitwise fs16; - typedef u64 befs_off_t; -typedef fs64 befs_time_t; +typedef u64 befs_time_t; +typedef void befs_binode_etc; /* Block runs */ -typedef struct { - fs32 allocation_group; - fs16 start; - fs16 len; -} PACKED befs_disk_block_run; - typedef struct { u32 allocation_group; u16 start; u16 len; } PACKED befs_block_run; -typedef befs_disk_block_run befs_disk_inode_addr; typedef befs_block_run befs_inode_addr; /* @@ -107,31 +97,31 @@ typedef befs_block_run befs_inode_addr; */ typedef struct { char name[B_OS_NAME_LENGTH]; - fs32 magic1; - fs32 fs_byte_order; + u32 magic1; + u32 fs_byte_order; - fs32 block_size; - fs32 block_shift; + u32 block_size; + u32 block_shift; - fs64 num_blocks; - fs64 used_blocks; + befs_off_t num_blocks; + befs_off_t used_blocks; - fs32 inode_size; + u32 inode_size; - fs32 magic2; - fs32 blocks_per_ag; - fs32 ag_shift; - fs32 num_ags; + u32 magic2; + u32 blocks_per_ag; + u32 ag_shift; + u32 num_ags; - fs32 flags; + u32 flags; - befs_disk_block_run log_blocks; - fs64 log_start; - fs64 log_end; + befs_block_run log_blocks; + befs_off_t log_start; + befs_off_t log_end; - fs32 magic3; - befs_disk_inode_addr root_dir; - befs_disk_inode_addr indices; + u32 magic3; + befs_inode_addr root_dir; + befs_inode_addr indices; } PACKED befs_super_block; @@ -139,16 +129,6 @@ typedef struct { * Note: the indirect and dbl_indir block_runs may * be longer than one block! */ -typedef struct { - befs_disk_block_run direct[BEFS_NUM_DIRECT_BLOCKS]; - fs64 max_direct_range; - befs_disk_block_run indirect; - fs64 max_indirect_range; - befs_disk_block_run double_indirect; - fs64 max_double_indirect_range; - fs64 size; -} PACKED befs_disk_data_stream; - typedef struct { befs_block_run direct[BEFS_NUM_DIRECT_BLOCKS]; befs_off_t max_direct_range; @@ -161,35 +141,35 @@ typedef struct { /* Attribute */ typedef struct { - fs32 type; - fs16 name_size; - fs16 data_size; + u32 type; + u16 name_size; + u16 data_size; char name[1]; } PACKED befs_small_data; /* Inode structure */ typedef struct { - fs32 magic1; - befs_disk_inode_addr inode_num; - fs32 uid; - fs32 gid; - fs32 mode; - fs32 flags; + u32 magic1; + befs_inode_addr inode_num; + u32 uid; + u32 gid; + u32 mode; + u32 flags; befs_time_t create_time; befs_time_t last_modified_time; - befs_disk_inode_addr parent; - befs_disk_inode_addr attributes; - fs32 type; + befs_inode_addr parent; + befs_inode_addr attributes; + u32 type; - fs32 inode_size; - fs32 etc; /* not use */ + u32 inode_size; + u32 etc; /* not use */ union { - befs_disk_data_stream datastream; + befs_data_stream datastream; char symlink[BEFS_SYMLINK_LEN]; } data; - fs32 pad[4]; /* not use */ + u32 pad[4]; /* not use */ befs_small_data small_data[1]; } PACKED befs_inode; @@ -209,16 +189,6 @@ enum btree_types { BTREE_DOUBLE_TYPE = 6 }; -typedef struct { - fs32 magic; - fs32 node_size; - fs32 max_depth; - fs32 data_type; - fs64 root_node_ptr; - fs64 free_node_ptr; - fs64 max_size; -} PACKED befs_disk_btree_super; - typedef struct { u32 magic; u32 node_size; @@ -232,20 +202,12 @@ typedef struct { /* * Header stucture of each btree node */ -typedef struct { - fs64 left; - fs64 right; - fs64 overflow; - fs16 all_key_count; - fs16 all_key_length; -} PACKED befs_btree_nodehead; - typedef struct { befs_off_t left; befs_off_t right; befs_off_t overflow; u16 all_key_count; u16 all_key_length; -} PACKED befs_host_btree_nodehead; +} PACKED befs_btree_nodehead; #endif /* _LINUX_BEFS_FS_TYPES */ diff --git a/trunk/fs/befs/btree.c b/trunk/fs/befs/btree.c index 81b042ee24e6..76e219799409 100644 --- a/trunk/fs/befs/btree.c +++ b/trunk/fs/befs/btree.c @@ -30,6 +30,7 @@ #include "befs.h" #include "btree.h" #include "datastream.h" +#include "endian.h" /* * The btree functions in this file are built on top of the @@ -79,7 +80,7 @@ * In memory structure of each btree node */ typedef struct { - befs_host_btree_nodehead head; /* head of node converted to cpu byteorder */ + befs_btree_nodehead head; /* head of node converted to cpu byteorder */ struct buffer_head *bh; befs_btree_nodehead *od_node; /* on disk node */ } befs_btree_node; @@ -101,9 +102,9 @@ static int befs_bt_read_node(struct super_block *sb, befs_data_stream * ds, static int befs_leafnode(befs_btree_node * node); -static fs16 *befs_bt_keylen_index(befs_btree_node * node); +static u16 *befs_bt_keylen_index(befs_btree_node * node); -static fs64 *befs_bt_valarray(befs_btree_node * node); +static befs_off_t *befs_bt_valarray(befs_btree_node * node); static char *befs_bt_keydata(befs_btree_node * node); @@ -135,7 +136,7 @@ befs_bt_read_super(struct super_block *sb, befs_data_stream * ds, befs_btree_super * sup) { struct buffer_head *bh = NULL; - befs_disk_btree_super *od_sup = NULL; + befs_btree_super *od_sup = NULL; befs_debug(sb, "---> befs_btree_read_super()"); @@ -145,7 +146,7 @@ befs_bt_read_super(struct super_block *sb, befs_data_stream * ds, befs_error(sb, "Couldn't read index header."); goto error; } - od_sup = (befs_disk_btree_super *) bh->b_data; + od_sup = (befs_btree_super *) bh->b_data; befs_dump_index_entry(sb, od_sup); sup->magic = fs32_to_cpu(sb, od_sup->magic); @@ -341,7 +342,7 @@ befs_find_key(struct super_block *sb, befs_btree_node * node, u16 keylen; int findkey_len; char *thiskey; - fs64 *valarray; + befs_off_t *valarray; befs_debug(sb, "---> befs_find_key() %s", findkey); @@ -421,7 +422,7 @@ befs_btree_read(struct super_block *sb, befs_data_stream * ds, befs_btree_super bt_super; befs_off_t node_off = 0; int cur_key; - fs64 *valarray; + befs_off_t *valarray; char *keystart; u16 keylen; int res; @@ -571,7 +572,7 @@ befs_btree_seekleaf(struct super_block *sb, befs_data_stream * ds, this_node->head.overflow); *node_off = this_node->head.overflow; } else { - fs64 *valarray = befs_bt_valarray(this_node); + befs_off_t *valarray = befs_bt_valarray(this_node); *node_off = fs64_to_cpu(sb, valarray[0]); } if (befs_bt_read_node(sb, ds, this_node, *node_off) != BEFS_OK) { @@ -621,7 +622,7 @@ befs_leafnode(befs_btree_node * node) * * Except that rounding up to 8 works, and rounding up to 4 doesn't. */ -static fs16 * +static u16 * befs_bt_keylen_index(befs_btree_node * node) { const int keylen_align = 8; @@ -632,7 +633,7 @@ befs_bt_keylen_index(befs_btree_node * node) if (tmp) off += keylen_align - tmp; - return (fs16 *) ((void *) node->od_node + off); + return (u16 *) ((void *) node->od_node + off); } /** @@ -642,13 +643,13 @@ befs_bt_keylen_index(befs_btree_node * node) * Returns a pointer to the start of the value array * of the node pointed to by the node header */ -static fs64 * +static befs_off_t * befs_bt_valarray(befs_btree_node * node) { void *keylen_index_start = (void *) befs_bt_keylen_index(node); - size_t keylen_index_size = node->head.all_key_count * sizeof (fs16); + size_t keylen_index_size = node->head.all_key_count * sizeof (u16); - return (fs64 *) (keylen_index_start + keylen_index_size); + return (befs_off_t *) (keylen_index_start + keylen_index_size); } /** @@ -680,7 +681,7 @@ befs_bt_get_key(struct super_block *sb, befs_btree_node * node, { int prev_key_end; char *keystart; - fs16 *keylen_index; + u16 *keylen_index; if (index < 0 || index > node->head.all_key_count) { *keylen = 0; diff --git a/trunk/fs/befs/datastream.c b/trunk/fs/befs/datastream.c index aacb4da6298a..b7d6b920f65f 100644 --- a/trunk/fs/befs/datastream.c +++ b/trunk/fs/befs/datastream.c @@ -18,6 +18,7 @@ #include "befs.h" #include "datastream.h" #include "io.h" +#include "endian.h" const befs_inode_addr BAD_IADDR = { 0, 0, 0 }; @@ -311,7 +312,7 @@ befs_find_brun_indirect(struct super_block *sb, befs_blocknr_t indir_start_blk; befs_blocknr_t search_blk; struct buffer_head *indirblock; - befs_disk_block_run *array; + befs_block_run *array; befs_block_run indirect = data->indirect; befs_blocknr_t indirblockno = iaddr2blockno(sb, &indirect); @@ -333,7 +334,7 @@ befs_find_brun_indirect(struct super_block *sb, return BEFS_ERR; } - array = (befs_disk_block_run *) indirblock->b_data; + array = (befs_block_run *) indirblock->b_data; for (j = 0; j < arraylen; ++j) { int len = fs16_to_cpu(sb, array[j].len); @@ -426,7 +427,7 @@ befs_find_brun_dblindirect(struct super_block *sb, struct buffer_head *dbl_indir_block; struct buffer_head *indir_block; befs_block_run indir_run; - befs_disk_inode_addr *iaddr_array = NULL; + befs_inode_addr *iaddr_array = NULL; befs_sb_info *befs_sb = BEFS_SB(sb); befs_blocknr_t indir_start_blk = @@ -481,7 +482,7 @@ befs_find_brun_dblindirect(struct super_block *sb, dbl_block_indx = dblindir_indx - (dbl_which_block * befs_iaddrs_per_block(sb)); - iaddr_array = (befs_disk_inode_addr *) dbl_indir_block->b_data; + iaddr_array = (befs_inode_addr *) dbl_indir_block->b_data; indir_run = fsrun_to_cpu(sb, iaddr_array[dbl_block_indx]); brelse(dbl_indir_block); iaddr_array = NULL; @@ -506,7 +507,7 @@ befs_find_brun_dblindirect(struct super_block *sb, } block_indx = indir_indx - (which_block * befs_iaddrs_per_block(sb)); - iaddr_array = (befs_disk_inode_addr *) indir_block->b_data; + iaddr_array = (befs_inode_addr *) indir_block->b_data; *run = fsrun_to_cpu(sb, iaddr_array[block_indx]); brelse(indir_block); iaddr_array = NULL; diff --git a/trunk/fs/befs/debug.c b/trunk/fs/befs/debug.c index e831a8f30849..875cc0aa318c 100644 --- a/trunk/fs/befs/debug.c +++ b/trunk/fs/befs/debug.c @@ -21,6 +21,7 @@ #endif /* __KERNEL__ */ #include "befs.h" +#include "endian.h" #define ERRBUFSIZE 1024 @@ -124,7 +125,7 @@ befs_dump_inode(const struct super_block *sb, befs_inode * inode) befs_debug(sb, " type %08x", fs32_to_cpu(sb, inode->type)); befs_debug(sb, " inode_size %u", fs32_to_cpu(sb, inode->inode_size)); - if (S_ISLNK(fs32_to_cpu(sb, inode->mode))) { + if (S_ISLNK(inode->mode)) { befs_debug(sb, " Symbolic link [%s]", inode->data.symlink); } else { int i; @@ -230,20 +231,21 @@ befs_dump_small_data(const struct super_block *sb, befs_small_data * sd) /* unused */ void -befs_dump_run(const struct super_block *sb, befs_disk_block_run run) +befs_dump_run(const struct super_block *sb, befs_block_run run) { #ifdef CONFIG_BEFS_DEBUG - befs_block_run n = fsrun_to_cpu(sb, run); + run = fsrun_to_cpu(sb, run); - befs_debug(sb, "[%u, %hu, %hu]", n.allocation_group, n.start, n.len); + befs_debug(sb, "[%u, %hu, %hu]", + run.allocation_group, run.start, run.len); #endif //CONFIG_BEFS_DEBUG } #endif /* 0 */ void -befs_dump_index_entry(const struct super_block *sb, befs_disk_btree_super * super) +befs_dump_index_entry(const struct super_block *sb, befs_btree_super * super) { #ifdef CONFIG_BEFS_DEBUG diff --git a/trunk/fs/befs/endian.h b/trunk/fs/befs/endian.h index e254a20869f4..9ecaea4e3325 100644 --- a/trunk/fs/befs/endian.h +++ b/trunk/fs/befs/endian.h @@ -10,84 +10,85 @@ #define LINUX_BEFS_ENDIAN #include +#include "befs.h" static inline u64 -fs64_to_cpu(const struct super_block *sb, fs64 n) +fs64_to_cpu(const struct super_block *sb, u64 n) { if (BEFS_SB(sb)->byte_order == BEFS_BYTESEX_LE) - return le64_to_cpu((__force __le64)n); + return le64_to_cpu(n); else - return be64_to_cpu((__force __be64)n); + return be64_to_cpu(n); } -static inline fs64 +static inline u64 cpu_to_fs64(const struct super_block *sb, u64 n) { if (BEFS_SB(sb)->byte_order == BEFS_BYTESEX_LE) - return (__force fs64)cpu_to_le64(n); + return cpu_to_le64(n); else - return (__force fs64)cpu_to_be64(n); + return cpu_to_be64(n); } static inline u32 -fs32_to_cpu(const struct super_block *sb, fs32 n) +fs32_to_cpu(const struct super_block *sb, u32 n) { if (BEFS_SB(sb)->byte_order == BEFS_BYTESEX_LE) - return le32_to_cpu((__force __le32)n); + return le32_to_cpu(n); else - return be32_to_cpu((__force __be32)n); + return be32_to_cpu(n); } -static inline fs32 +static inline u32 cpu_to_fs32(const struct super_block *sb, u32 n) { if (BEFS_SB(sb)->byte_order == BEFS_BYTESEX_LE) - return (__force fs32)cpu_to_le32(n); + return cpu_to_le32(n); else - return (__force fs32)cpu_to_be32(n); + return cpu_to_be32(n); } static inline u16 -fs16_to_cpu(const struct super_block *sb, fs16 n) +fs16_to_cpu(const struct super_block *sb, u16 n) { if (BEFS_SB(sb)->byte_order == BEFS_BYTESEX_LE) - return le16_to_cpu((__force __le16)n); + return le16_to_cpu(n); else - return be16_to_cpu((__force __be16)n); + return be16_to_cpu(n); } -static inline fs16 +static inline u16 cpu_to_fs16(const struct super_block *sb, u16 n) { if (BEFS_SB(sb)->byte_order == BEFS_BYTESEX_LE) - return (__force fs16)cpu_to_le16(n); + return cpu_to_le16(n); else - return (__force fs16)cpu_to_be16(n); + return cpu_to_be16(n); } /* Composite types below here */ static inline befs_block_run -fsrun_to_cpu(const struct super_block *sb, befs_disk_block_run n) +fsrun_to_cpu(const struct super_block *sb, befs_block_run n) { befs_block_run run; if (BEFS_SB(sb)->byte_order == BEFS_BYTESEX_LE) { - run.allocation_group = le32_to_cpu((__force __le32)n.allocation_group); - run.start = le16_to_cpu((__force __le16)n.start); - run.len = le16_to_cpu((__force __le16)n.len); + run.allocation_group = le32_to_cpu(n.allocation_group); + run.start = le16_to_cpu(n.start); + run.len = le16_to_cpu(n.len); } else { - run.allocation_group = be32_to_cpu((__force __be32)n.allocation_group); - run.start = be16_to_cpu((__force __be16)n.start); - run.len = be16_to_cpu((__force __be16)n.len); + run.allocation_group = be32_to_cpu(n.allocation_group); + run.start = be16_to_cpu(n.start); + run.len = be16_to_cpu(n.len); } return run; } -static inline befs_disk_block_run +static inline befs_block_run cpu_to_fsrun(const struct super_block *sb, befs_block_run n) { - befs_disk_block_run run; + befs_block_run run; if (BEFS_SB(sb)->byte_order == BEFS_BYTESEX_LE) { run.allocation_group = cpu_to_le32(n.allocation_group); @@ -102,7 +103,7 @@ cpu_to_fsrun(const struct super_block *sb, befs_block_run n) } static inline befs_data_stream -fsds_to_cpu(const struct super_block *sb, befs_disk_data_stream n) +fsds_to_cpu(const struct super_block *sb, befs_data_stream n) { befs_data_stream data; int i; diff --git a/trunk/fs/befs/inode.c b/trunk/fs/befs/inode.c index 94c17f9a9576..d41c9247ae8a 100644 --- a/trunk/fs/befs/inode.c +++ b/trunk/fs/befs/inode.c @@ -8,6 +8,7 @@ #include "befs.h" #include "inode.h" +#include "endian.h" /* Validates the correctness of the befs inode diff --git a/trunk/fs/befs/linuxvfs.c b/trunk/fs/befs/linuxvfs.c index 07f7144f0e2e..57020c7a7e65 100644 --- a/trunk/fs/befs/linuxvfs.c +++ b/trunk/fs/befs/linuxvfs.c @@ -22,6 +22,7 @@ #include "datastream.h" #include "super.h" #include "io.h" +#include "endian.h" MODULE_DESCRIPTION("BeOS File System (BeFS) driver"); MODULE_AUTHOR("Will Dyson"); diff --git a/trunk/fs/befs/super.c b/trunk/fs/befs/super.c index 8c3401ff6d6a..4557acbac528 100644 --- a/trunk/fs/befs/super.c +++ b/trunk/fs/befs/super.c @@ -11,6 +11,7 @@ #include "befs.h" #include "super.h" +#include "endian.h" /** * load_befs_sb -- Read from disk and properly byteswap all the fields diff --git a/trunk/fs/binfmt_elf.c b/trunk/fs/binfmt_elf.c index 79b05a1a4365..06435f3665f4 100644 --- a/trunk/fs/binfmt_elf.c +++ b/trunk/fs/binfmt_elf.c @@ -1152,7 +1152,7 @@ static int dump_write(struct file *file, const void *addr, int nr) static int dump_seek(struct file *file, loff_t off) { if (file->f_op->llseek && file->f_op->llseek != no_llseek) { - if (file->f_op->llseek(file, off, SEEK_CUR) < 0) + if (file->f_op->llseek(file, off, 1) != off) return 0; } else { char *buf = (char *)get_zeroed_page(GFP_KERNEL); @@ -1220,7 +1220,7 @@ static int notesize(struct memelfnote *en) static int alignfile(struct file *file, loff_t *foffset) { - static const char buf[4] = { 0, }; + char buf[4] = { 0, }; DUMP_WRITE(buf, roundup(*foffset, 4) - *foffset, foffset); return 1; } @@ -1569,8 +1569,7 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) DUMP_WRITE(elf, sizeof(*elf)); offset += sizeof(*elf); /* Elf header */ - offset += (segs + 1) * sizeof(struct elf_phdr); /* Program headers */ - foffset = offset; + offset += (segs+1) * sizeof(struct elf_phdr); /* Program headers */ /* Write notes phdr entry */ { @@ -1587,6 +1586,8 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) DUMP_WRITE(&phdr, sizeof(phdr)); } + foffset = offset; + dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE); /* Write program headers for segments dump */ @@ -1611,6 +1612,7 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) phdr.p_align = ELF_EXEC_PAGESIZE; DUMP_WRITE(&phdr, sizeof(phdr)); + foffset += sizeof(phdr); } #ifdef ELF_CORE_WRITE_EXTRA_PHDRS diff --git a/trunk/fs/bio.c b/trunk/fs/bio.c index aa4d09bd4e71..8f93e939f213 100644 --- a/trunk/fs/bio.c +++ b/trunk/fs/bio.c @@ -79,6 +79,7 @@ static struct bio_set *fs_bio_set; static inline struct bio_vec *bvec_alloc_bs(gfp_t gfp_mask, int nr, unsigned long *idx, struct bio_set *bs) { struct bio_vec *bvl; + struct biovec_slab *bp; /* * see comment near bvec_array define! @@ -97,12 +98,10 @@ static inline struct bio_vec *bvec_alloc_bs(gfp_t gfp_mask, int nr, unsigned lon * idx now points to the pool we want to allocate from */ + bp = bvec_slabs + *idx; bvl = mempool_alloc(bs->bvec_pools[*idx], gfp_mask); - if (bvl) { - struct biovec_slab *bp = bvec_slabs + *idx; - + if (bvl) memset(bvl, 0, bp->nr_vecs * sizeof(struct bio_vec)); - } return bvl; } @@ -167,7 +166,7 @@ struct bio *bio_alloc_bioset(gfp_t gfp_mask, int nr_iovecs, struct bio_set *bs) bio_init(bio); if (likely(nr_iovecs)) { - unsigned long idx = 0; /* shut up gcc */ + unsigned long idx; bvl = bvec_alloc_bs(gfp_mask, nr_iovecs, &idx, bs); if (unlikely(!bvl)) { @@ -560,8 +559,10 @@ struct bio *bio_copy_user(request_queue_t *q, unsigned long uaddr, break; } - if (bio_add_pc_page(q, bio, page, bytes, 0) < bytes) + if (bio_add_pc_page(q, bio, page, bytes, 0) < bytes) { + ret = -EINVAL; break; + } len -= bytes; } @@ -620,9 +621,10 @@ static struct bio *__bio_map_user_iov(request_queue_t *q, nr_pages += end - start; /* - * buffer must be aligned to at least hardsector size for now + * transfer and buffer must be aligned to at least hardsector + * size for now, in the future we can relax this restriction */ - if (uaddr & queue_dma_alignment(q)) + if ((uaddr & queue_dma_alignment(q)) || (len & queue_dma_alignment(q))) return ERR_PTR(-EINVAL); } @@ -748,6 +750,7 @@ struct bio *bio_map_user_iov(request_queue_t *q, struct block_device *bdev, int write_to_vm) { struct bio *bio; + int len = 0, i; bio = __bio_map_user_iov(q, bdev, iov, iov_count, write_to_vm); @@ -762,7 +765,18 @@ struct bio *bio_map_user_iov(request_queue_t *q, struct block_device *bdev, */ bio_get(bio); - return bio; + for (i = 0; i < iov_count; i++) + len += iov[i].iov_len; + + if (bio->bi_size == len) + return bio; + + /* + * don't support partial mappings + */ + bio_endio(bio, bio->bi_size, 0); + bio_unmap_user(bio); + return ERR_PTR(-EINVAL); } static void __bio_unmap_user(struct bio *bio) diff --git a/trunk/fs/block_dev.c b/trunk/fs/block_dev.c index 36c0e7af9d0f..bc8f27cc4483 100644 --- a/trunk/fs/block_dev.c +++ b/trunk/fs/block_dev.c @@ -641,48 +641,35 @@ static void free_bd_holder(struct bd_holder *bo) kfree(bo); } -/** - * find_bd_holder - find matching struct bd_holder from the block device - * - * @bdev: struct block device to be searched - * @bo: target struct bd_holder - * - * Returns matching entry with @bo in @bdev->bd_holder_list. - * If found, increment the reference count and return the pointer. - * If not found, returns NULL. - */ -static struct bd_holder *find_bd_holder(struct block_device *bdev, - struct bd_holder *bo) -{ - struct bd_holder *tmp; - - list_for_each_entry(tmp, &bdev->bd_holder_list, list) - if (tmp->sdir == bo->sdir) { - tmp->count++; - return tmp; - } - - return NULL; -} - /** * add_bd_holder - create sysfs symlinks for bd_claim() relationship * * @bdev: block device to be bd_claimed * @bo: preallocated and initialized by alloc_bd_holder() * - * Add @bo to @bdev->bd_holder_list, create symlinks. + * If there is no matching entry with @bo in @bdev->bd_holder_list, + * add @bo to the list, create symlinks. * - * Returns 0 if symlinks are created. - * Returns -ve if something fails. + * Returns 0 if symlinks are created or already there. + * Returns -ve if something fails and @bo can be freed. */ static int add_bd_holder(struct block_device *bdev, struct bd_holder *bo) { + struct bd_holder *tmp; int ret; if (!bo) return -EINVAL; + list_for_each_entry(tmp, &bdev->bd_holder_list, list) { + if (tmp->sdir == bo->sdir) { + tmp->count++; + /* We've already done what we need to do here. */ + free_bd_holder(bo); + return 0; + } + } + if (!bd_holder_grab_dirs(bdev, bo)) return -EBUSY; @@ -753,7 +740,7 @@ static int bd_claim_by_kobject(struct block_device *bdev, void *holder, struct kobject *kobj) { int res; - struct bd_holder *bo, *found; + struct bd_holder *bo; if (!kobj) return -EINVAL; @@ -764,16 +751,9 @@ static int bd_claim_by_kobject(struct block_device *bdev, void *holder, mutex_lock_nested(&bdev->bd_mutex, BD_MUTEX_PARTITION); res = bd_claim(bdev, holder); - if (res == 0) { - found = find_bd_holder(bdev, bo); - if (found == NULL) { - res = add_bd_holder(bdev, bo); - if (res) - bd_release(bdev); - } - } - - if (res || found) + if (res == 0) + res = add_bd_holder(bdev, bo); + if (res) free_bd_holder(bo); mutex_unlock(&bdev->bd_mutex); @@ -1151,8 +1131,6 @@ static int blkdev_open(struct inode * inode, struct file * filp) filp->f_flags |= O_LARGEFILE; bdev = bd_acquire(inode); - if (bdev == NULL) - return -ENOMEM; res = do_open(bdev, filp, BD_MUTEX_NORMAL); if (res) diff --git a/trunk/fs/buffer.c b/trunk/fs/buffer.c index 35527dca1dbc..16cfbcd254f1 100644 --- a/trunk/fs/buffer.c +++ b/trunk/fs/buffer.c @@ -452,7 +452,6 @@ static void end_buffer_async_write(struct buffer_head *bh, int uptodate) bdevname(bh->b_bdev, b)); } set_bit(AS_EIO, &page->mapping->flags); - set_buffer_write_io_error(bh); clear_buffer_uptodate(bh); SetPageError(page); } @@ -572,10 +571,6 @@ EXPORT_SYMBOL(mark_buffer_async_write); static inline void __remove_assoc_queue(struct buffer_head *bh) { list_del_init(&bh->b_assoc_buffers); - WARN_ON(!bh->b_assoc_map); - if (buffer_write_io_error(bh)) - set_bit(AS_EIO, &bh->b_assoc_map->flags); - bh->b_assoc_map = NULL; } int inode_has_buffers(struct inode *inode) @@ -674,7 +669,6 @@ void mark_buffer_dirty_inode(struct buffer_head *bh, struct inode *inode) spin_lock(&buffer_mapping->private_lock); list_move_tail(&bh->b_assoc_buffers, &mapping->private_list); - bh->b_assoc_map = mapping; spin_unlock(&buffer_mapping->private_lock); } } @@ -707,10 +701,7 @@ EXPORT_SYMBOL(mark_buffer_dirty_inode); */ int __set_page_dirty_buffers(struct page *page) { - struct address_space * const mapping = page_mapping(page); - - if (unlikely(!mapping)) - return !TestSetPageDirty(page); + struct address_space * const mapping = page->mapping; spin_lock(&mapping->private_lock); if (page_has_buffers(page)) { @@ -771,7 +762,7 @@ static int fsync_buffers_list(spinlock_t *lock, struct list_head *list) spin_lock(lock); while (!list_empty(list)) { bh = BH_ENTRY(list->next); - __remove_assoc_queue(bh); + list_del_init(&bh->b_assoc_buffers); if (buffer_dirty(bh) || buffer_locked(bh)) { list_add(&bh->b_assoc_buffers, &tmp); if (buffer_dirty(bh)) { @@ -792,7 +783,7 @@ static int fsync_buffers_list(spinlock_t *lock, struct list_head *list) while (!list_empty(&tmp)) { bh = BH_ENTRY(tmp.prev); - list_del_init(&bh->b_assoc_buffers); + __remove_assoc_queue(bh); get_bh(bh); spin_unlock(lock); wait_on_buffer(bh); @@ -1048,21 +1039,8 @@ grow_buffers(struct block_device *bdev, sector_t block, int size) } while ((size << sizebits) < PAGE_SIZE); index = block >> sizebits; - - /* - * Check for a block which wants to lie outside our maximum possible - * pagecache index. (this comparison is done using sector_t types). - */ - if (unlikely(index != block >> sizebits)) { - char b[BDEVNAME_SIZE]; - - printk(KERN_ERR "%s: requested out-of-range block %llu for " - "device %s\n", - __FUNCTION__, (unsigned long long)block, - bdevname(bdev, b)); - return -EIO; - } block = index << sizebits; + /* Create a page with the proper size buffers.. */ page = grow_dev_page(bdev, block, index, size); if (!page) @@ -1089,16 +1067,12 @@ __getblk_slow(struct block_device *bdev, sector_t block, int size) for (;;) { struct buffer_head * bh; - int ret; bh = __find_get_block(bdev, block, size); if (bh) return bh; - ret = grow_buffers(bdev, block, size); - if (ret < 0) - return NULL; - if (ret == 0) + if (!grow_buffers(bdev, block, size)) free_more_memory(); } } @@ -1173,7 +1147,6 @@ void __bforget(struct buffer_head *bh) spin_lock(&buffer_mapping->private_lock); list_del_init(&bh->b_assoc_buffers); - bh->b_assoc_map = NULL; spin_unlock(&buffer_mapping->private_lock); } __brelse(bh); @@ -1861,7 +1834,6 @@ static int __block_prepare_write(struct inode *inode, struct page *page, clear_buffer_new(bh); kaddr = kmap_atomic(page, KM_USER0); memset(kaddr+block_start, 0, bh->b_size); - flush_dcache_page(page); kunmap_atomic(kaddr, KM_USER0); set_buffer_uptodate(bh); mark_buffer_dirty(bh); @@ -2368,7 +2340,6 @@ int nobh_prepare_write(struct page *page, unsigned from, unsigned to, */ kaddr = kmap_atomic(page, KM_USER0); memset(kaddr, 0, PAGE_CACHE_SIZE); - flush_dcache_page(page); kunmap_atomic(kaddr, KM_USER0); SetPageUptodate(page); set_page_dirty(page); diff --git a/trunk/fs/cifs/CHANGES b/trunk/fs/cifs/CHANGES index 0b3c37ef52e0..1eb9a2ec0a3b 100644 --- a/trunk/fs/cifs/CHANGES +++ b/trunk/fs/cifs/CHANGES @@ -1,11 +1,6 @@ Version 1.46 ------------ Support deep tree mounts. Better support OS/2, Win9x (DOS) time stamps. -Allow null user to be specified on mount ("username="). Do not return -EINVAL on readdir when filldir fails due to overwritten blocksize -(fixes FC problem). Return error in rename 2nd attempt retry (ie report -if rename by handle also fails, after rename by path fails, we were -not reporting whether the retry worked or not). Version 1.45 ------------ diff --git a/trunk/fs/cifs/cifsacl.h b/trunk/fs/cifs/cifsacl.h index 5eff35d6e564..d0776ac2b804 100644 --- a/trunk/fs/cifs/cifsacl.h +++ b/trunk/fs/cifs/cifsacl.h @@ -31,8 +31,8 @@ struct cifs_sid { } __attribute__((packed)); /* everyone */ -/* extern const struct cifs_sid sid_everyone;*/ +extern const struct cifs_sid sid_everyone; /* group users */ -/* extern const struct cifs_sid sid_user;*/ +extern const struct cifs_sid sid_user; #endif /* _CIFSACL_H */ diff --git a/trunk/fs/cifs/cifsencrypt.h b/trunk/fs/cifs/cifsencrypt.h index 152fa2dcfc6c..03e359b32861 100644 --- a/trunk/fs/cifs/cifsencrypt.h +++ b/trunk/fs/cifs/cifsencrypt.h @@ -27,6 +27,8 @@ extern void mdfour(unsigned char *out, unsigned char *in, int n); /* smbdes.c */ extern void E_P16(unsigned char *p14, unsigned char *p16); extern void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24); +extern void D_P16(unsigned char *p14, unsigned char *in, unsigned char *out); +extern void E_old_pw_hash(unsigned char *, unsigned char *, unsigned char *); diff --git a/trunk/fs/cifs/cifsfs.c b/trunk/fs/cifs/cifsfs.c index 84976cdbe713..c00c654f2e11 100644 --- a/trunk/fs/cifs/cifsfs.c +++ b/trunk/fs/cifs/cifsfs.c @@ -63,7 +63,6 @@ extern struct task_struct * oplockThread; /* remove sparse warning */ struct task_struct * oplockThread = NULL; extern struct task_struct * dnotifyThread; /* remove sparse warning */ struct task_struct * dnotifyThread = NULL; -static struct super_operations cifs_super_ops; unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE; module_param(CIFSMaxBufSize, int, 0); MODULE_PARM_DESC(CIFSMaxBufSize,"Network buffer size (not including header). Default: 16384 Range: 8192 to 130048"); @@ -199,12 +198,10 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf) /* Only need to call the old QFSInfo if failed on newer one */ if(rc) - if(pTcon->ses->capabilities & CAP_NT_SMBS) - rc = CIFSSMBQFSInfo(xid, pTcon, buf); /* not supported by OS2 */ + rc = CIFSSMBQFSInfo(xid, pTcon, buf); - /* Some old Windows servers also do not support level 103, retry with - older level one if old server failed the previous call or we - bypassed it because we detected that this was an older LANMAN sess */ + /* Old Windows servers do not support level 103, retry with level + one if old server failed the previous call */ if(rc) rc = SMBOldQFSInfo(xid, pTcon, buf); /* @@ -438,21 +435,13 @@ static void cifs_umount_begin(struct vfsmount * vfsmnt, int flags) return; } -#ifdef CONFIG_CIFS_STATS2 -static int cifs_show_stats(struct seq_file *s, struct vfsmount *mnt) -{ - /* BB FIXME */ - return 0; -} -#endif - static int cifs_remount(struct super_block *sb, int *flags, char *data) { *flags |= MS_NODIRATIME; return 0; } -static struct super_operations cifs_super_ops = { +struct super_operations cifs_super_ops = { .read_inode = cifs_read_inode, .put_super = cifs_put_super, .statfs = cifs_statfs, @@ -465,9 +454,6 @@ static struct super_operations cifs_super_ops = { .show_options = cifs_show_options, .umount_begin = cifs_umount_begin, .remount_fs = cifs_remount, -#ifdef CONFIG_CIFS_STATS2 - .show_stats = cifs_show_stats, -#endif }; static int @@ -509,7 +495,7 @@ static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov, static loff_t cifs_llseek(struct file *file, loff_t offset, int origin) { /* origin == SEEK_END => we must revalidate the cached file length */ - if (origin == SEEK_END) { + if (origin == 2) { int retval = cifs_revalidate(file->f_dentry); if (retval < 0) return (loff_t)retval; @@ -917,7 +903,7 @@ init_cifs(void) #ifdef CONFIG_PROC_FS cifs_proc_init(); #endif -/* INIT_LIST_HEAD(&GlobalServerList);*/ /* BB not implemented yet */ + INIT_LIST_HEAD(&GlobalServerList); /* BB not implemented yet */ INIT_LIST_HEAD(&GlobalSMBSessionList); INIT_LIST_HEAD(&GlobalTreeConnectionList); INIT_LIST_HEAD(&GlobalOplock_Q); @@ -945,7 +931,6 @@ init_cifs(void) GlobalCurrentXid = 0; GlobalTotalActiveXid = 0; GlobalMaxActiveXid = 0; - memset(Local_System_Name, 0, 15); rwlock_init(&GlobalSMBSeslock); spin_lock_init(&GlobalMid_Lock); diff --git a/trunk/fs/cifs/cifsfs.h b/trunk/fs/cifs/cifsfs.h index a243f779b363..bea875d9a46a 100644 --- a/trunk/fs/cifs/cifsfs.h +++ b/trunk/fs/cifs/cifsfs.h @@ -36,7 +36,7 @@ extern const struct address_space_operations cifs_addr_ops; extern const struct address_space_operations cifs_addr_ops_smallbuf; /* Functions related to super block operations */ -/* extern struct super_operations cifs_super_ops;*/ +extern struct super_operations cifs_super_ops; extern void cifs_read_inode(struct inode *); extern void cifs_delete_inode(struct inode *); /* extern void cifs_write_inode(struct inode *); *//* BB not needed yet */ diff --git a/trunk/fs/cifs/cifsglob.h b/trunk/fs/cifs/cifsglob.h index 74d3ccbb103b..b24006c47df1 100644 --- a/trunk/fs/cifs/cifsglob.h +++ b/trunk/fs/cifs/cifsglob.h @@ -153,7 +153,7 @@ struct TCP_Server_Info { char sessid[4]; /* unique token id for this session */ /* (returned on Negotiate */ int capabilities; /* allow selective disabling of caps by smb sess */ - int timeAdj; /* Adjust for difference in server time zone in sec */ + __u16 timeZone; __u16 CurrentMid; /* multiplex id - rotating counter */ char cryptKey[CIFS_CRYPTO_KEY_SIZE]; /* 16th byte of RFC1001 workstation name is always null */ @@ -203,14 +203,9 @@ struct cifsSesInfo { char * domainName; char * password; }; -/* no more than one of the following three session flags may be set */ +/* session flags */ #define CIFS_SES_NT4 1 -#define CIFS_SES_OS2 2 -#define CIFS_SES_W9X 4 -/* following flag is set for old servers such as OS2 (and Win95?) - which do not negotiate NTLM or POSIX dialects, but instead - negotiate one of the older LANMAN dialects */ -#define CIFS_SES_LANMAN 8 + /* * there is one of these for each connection to a resource on a particular * session @@ -517,8 +512,7 @@ require use of the stronger protocol */ * This list helps improve performance and eliminate the messages indicating * that we had a communications error talking to the server in this list. */ -/* Feature not supported */ -/* GLOBAL_EXTERN struct servers_not_supported *NotSuppList; */ +GLOBAL_EXTERN struct servers_not_supported *NotSuppList; /*@z4a */ /* * The following is a hash table of all the users we know about. @@ -574,6 +568,7 @@ GLOBAL_EXTERN unsigned int lookupCacheEnabled; GLOBAL_EXTERN unsigned int extended_security; /* if on, session setup sent with more secure ntlmssp2 challenge/resp */ GLOBAL_EXTERN unsigned int sign_CIFS_PDUs; /* enable smb packet signing */ +GLOBAL_EXTERN unsigned int secFlags; GLOBAL_EXTERN unsigned int linuxExtEnabled;/*enable Linux/Unix CIFS extensions*/ GLOBAL_EXTERN unsigned int CIFSMaxBufSize; /* max size not including hdr */ GLOBAL_EXTERN unsigned int cifs_min_rcv; /* min size of big ntwrk buf pool */ diff --git a/trunk/fs/cifs/cifspdu.h b/trunk/fs/cifs/cifspdu.h index 6df9dadba647..81df2bf8e75a 100644 --- a/trunk/fs/cifs/cifspdu.h +++ b/trunk/fs/cifs/cifspdu.h @@ -26,8 +26,7 @@ #ifdef CONFIG_CIFS_WEAK_PW_HASH #define LANMAN_PROT 0 -#define LANMAN2_PROT 1 -#define CIFS_PROT 2 +#define CIFS_PROT 1 #else #define CIFS_PROT 0 #endif @@ -409,8 +408,6 @@ typedef struct negotiate_req { /* Dialect index is 13 for LANMAN */ -#define MIN_TZ_ADJ (15 * 60) /* minimum grid for timezones in seconds */ - typedef struct lanman_neg_rsp { struct smb_hdr hdr; /* wct = 13 */ __le16 DialectIndex; @@ -420,10 +417,7 @@ typedef struct lanman_neg_rsp { __le16 MaxNumberVcs; __le16 RawMode; __le32 SessionKey; - struct { - __le16 Time; - __le16 Date; - } __attribute__((packed)) SrvTime; + __le32 ServerTime; __le16 ServerTimeZone; __le16 EncryptionKeyLength; __le16 Reserved; @@ -680,7 +674,7 @@ typedef union smb_com_tree_disconnect { /* as an altetnative can use flag on typedef struct smb_com_close_req { struct smb_hdr hdr; /* wct = 3 */ __u16 FileID; - __u32 LastWriteTime; /* should be zero or -1 */ + __u32 LastWriteTime; /* should be zero */ __u16 ByteCount; /* 0 */ } __attribute__((packed)) CLOSE_REQ; diff --git a/trunk/fs/cifs/cifsproto.h b/trunk/fs/cifs/cifsproto.h index f1f8225102f0..b35c55c3c8bb 100644 --- a/trunk/fs/cifs/cifsproto.h +++ b/trunk/fs/cifs/cifsproto.h @@ -50,12 +50,12 @@ extern int SendReceive(const unsigned int /* xid */ , struct cifsSesInfo *, extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *, struct kvec *, int /* nvec to send */, int * /* type of buf returned */ , const int long_op); -extern int SendReceiveBlockingLock(const unsigned int /* xid */ , - struct cifsTconInfo *, +extern int SendReceiveBlockingLock(const unsigned int /* xid */ , struct cifsTconInfo *, struct smb_hdr * /* input */ , struct smb_hdr * /* out */ , int * /* bytes returned */); -extern int checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length); +extern int checkSMBhdr(struct smb_hdr *smb, __u16 mid); +extern int checkSMB(struct smb_hdr *smb, __u16 mid, int length); extern int is_valid_oplock_break(struct smb_hdr *smb, struct TCP_Server_Info *); extern int is_size_safe_to_change(struct cifsInodeInfo *); extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *); @@ -80,9 +80,6 @@ extern struct oplock_q_entry * AllocOplockQEntry(struct inode *, u16, extern void DeleteOplockQEntry(struct oplock_q_entry *); extern struct timespec cifs_NTtimeToUnix(u64 /* utc nanoseconds since 1601 */ ); extern u64 cifs_UnixTimeToNT(struct timespec); -extern __le64 cnvrtDosCifsTm(__u16 date, __u16 time); -extern struct timespec cnvrtDosUnixTm(__u16 date, __u16 time); - extern int cifs_get_inode_info(struct inode **pinode, const unsigned char *search_path, FILE_ALL_INFO * pfile_info, @@ -119,7 +116,6 @@ extern int CIFSFindClose(const int, struct cifsTconInfo *tcon, extern int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, const unsigned char *searchName, FILE_ALL_INFO * findData, - int legacy /* whether to use old info level */, const struct nls_table *nls_codepage, int remap); extern int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon, const unsigned char *searchName, @@ -283,6 +279,8 @@ extern void sesInfoFree(struct cifsSesInfo *); extern struct cifsTconInfo *tconInfoAlloc(void); extern void tconInfoFree(struct cifsTconInfo *); +extern int cifs_reconnect(struct TCP_Server_Info *server); + extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *,__u32 *); extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *, __u32 *); diff --git a/trunk/fs/cifs/cifssmb.c b/trunk/fs/cifs/cifssmb.c index 098790eb2aa1..075d8fb3d376 100644 --- a/trunk/fs/cifs/cifssmb.c +++ b/trunk/fs/cifs/cifssmb.c @@ -46,7 +46,6 @@ static struct { } protocols[] = { #ifdef CONFIG_CIFS_WEAK_PW_HASH {LANMAN_PROT, "\2LM1.2X002"}, - {LANMAN2_PROT, "\2LANMAN2.1"}, #endif /* weak password hashing for legacy clients */ {CIFS_PROT, "\2NT LM 0.12"}, {POSIX_PROT, "\2POSIX 2"}, @@ -59,7 +58,6 @@ static struct { } protocols[] = { #ifdef CONFIG_CIFS_WEAK_PW_HASH {LANMAN_PROT, "\2LM1.2X002"}, - {LANMAN2_PROT, "\2LANMAN2.1"}, #endif /* weak password hashing for legacy clients */ {CIFS_PROT, "\2NT LM 0.12"}, {BAD_PROT, "\2"} @@ -69,13 +67,13 @@ static struct { /* define the number of elements in the cifs dialect array */ #ifdef CONFIG_CIFS_POSIX #ifdef CONFIG_CIFS_WEAK_PW_HASH -#define CIFS_NUM_PROT 4 +#define CIFS_NUM_PROT 3 #else #define CIFS_NUM_PROT 2 #endif /* CIFS_WEAK_PW_HASH */ #else /* not posix */ #ifdef CONFIG_CIFS_WEAK_PW_HASH -#define CIFS_NUM_PROT 3 +#define CIFS_NUM_PROT 2 #else #define CIFS_NUM_PROT 1 #endif /* CONFIG_CIFS_WEAK_PW_HASH */ @@ -399,7 +397,6 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) struct TCP_Server_Info * server; u16 count; unsigned int secFlags; - u16 dialect; if(ses->server) server = ses->server; @@ -439,10 +436,9 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) if (rc != 0) goto neg_err_exit; - dialect = le16_to_cpu(pSMBr->DialectIndex); - cFYI(1,("Dialect: %d", dialect)); + cFYI(1,("Dialect: %d", pSMBr->DialectIndex)); /* Check wct = 1 error case */ - if((pSMBr->hdr.WordCount < 13) || (dialect == BAD_PROT)) { + if((pSMBr->hdr.WordCount < 13) || (pSMBr->DialectIndex == BAD_PROT)) { /* core returns wct = 1, but we do not ask for core - otherwise small wct just comes when dialect index is -1 indicating we could not negotiate a common dialect */ @@ -450,9 +446,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) goto neg_err_exit; #ifdef CONFIG_CIFS_WEAK_PW_HASH } else if((pSMBr->hdr.WordCount == 13) - && ((dialect == LANMAN_PROT) - || (dialect == LANMAN2_PROT))) { - __s16 tmp; + && (pSMBr->DialectIndex == LANMAN_PROT)) { struct lanman_neg_rsp * rsp = (struct lanman_neg_rsp *)pSMBr; if((secFlags & CIFSSEC_MAY_LANMAN) || @@ -478,44 +472,12 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) server->maxRw = 0;/* we do not need to use raw anyway */ server->capabilities = CAP_MPX_MODE; } - tmp = (__s16)le16_to_cpu(rsp->ServerTimeZone); - if (tmp == -1) { - /* OS/2 often does not set timezone therefore - * we must use server time to calc time zone. - * Could deviate slightly from the right zone. - * Smallest defined timezone difference is 15 minutes - * (i.e. Nepal). Rounding up/down is done to match - * this requirement. - */ - int val, seconds, remain, result; - struct timespec ts, utc; - utc = CURRENT_TIME; - ts = cnvrtDosUnixTm(le16_to_cpu(rsp->SrvTime.Date), - le16_to_cpu(rsp->SrvTime.Time)); - cFYI(1,("SrvTime: %d sec since 1970 (utc: %d) diff: %d", - (int)ts.tv_sec, (int)utc.tv_sec, - (int)(utc.tv_sec - ts.tv_sec))); - val = (int)(utc.tv_sec - ts.tv_sec); - seconds = val < 0 ? -val : val; - result = (seconds / MIN_TZ_ADJ) * MIN_TZ_ADJ; - remain = seconds % MIN_TZ_ADJ; - if(remain >= (MIN_TZ_ADJ / 2)) - result += MIN_TZ_ADJ; - if(val < 0) - result = - result; - server->timeAdj = result; - } else { - server->timeAdj = (int)tmp; - server->timeAdj *= 60; /* also in seconds */ - } - cFYI(1,("server->timeAdj: %d seconds", server->timeAdj)); - + server->timeZone = le16_to_cpu(rsp->ServerTimeZone); /* BB get server time for time conversions and add code to use it and timezone since this is not UTC */ - if (rsp->EncryptionKeyLength == - cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) { + if (rsp->EncryptionKeyLength == cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) { memcpy(server->cryptKey, rsp->EncryptionKey, CIFS_CRYPTO_KEY_SIZE); } else if (server->secMode & SECMODE_PW_ENCRYPT) { @@ -569,8 +531,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) cFYI(0, ("Max buf = %d", ses->server->maxBuf)); GETU32(ses->server->sessid) = le32_to_cpu(pSMBr->SessionKey); server->capabilities = le32_to_cpu(pSMBr->Capabilities); - server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone); - server->timeAdj *= 60; + server->timeZone = le16_to_cpu(pSMBr->ServerTimeZone); if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) { memcpy(server->cryptKey, pSMBr->u.EncryptionKey, CIFS_CRYPTO_KEY_SIZE); @@ -1656,7 +1617,7 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id) pSMBr = (CLOSE_RSP *)pSMB; /* BB removeme BB */ pSMB->FileID = (__u16) smb_file_id; - pSMB->LastWriteTime = 0xFFFFFFFF; + pSMB->LastWriteTime = 0; pSMB->ByteCount = 0; rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); @@ -2812,11 +2773,9 @@ CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon, /* security id for everyone */ -const static struct cifs_sid sid_everyone = - {1, 1, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0}}; +const struct cifs_sid sid_everyone = {1, 1, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0}}; /* group users */ -const static struct cifs_sid sid_user = - {1, 2 , {0, 0, 0, 0, 0, 5}, {32, 545, 0, 0}}; +const struct cifs_sid sid_user = {1, 2 , {0, 0, 0, 0, 0, 5}, {32, 545, 0, 0}}; /* Convert CIFS ACL to POSIX form */ static int parse_sec_desc(struct cifs_sid * psec_desc, int acl_len) @@ -2897,6 +2856,7 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, return rc; } + /* Legacy Query Path Information call for lookup to old servers such as Win9x/WinME */ int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon, @@ -2938,16 +2898,7 @@ int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon, if (rc) { cFYI(1, ("Send error in QueryInfo = %d", rc)); } else if (pFinfo) { /* decode response */ - struct timespec ts; - __u32 time = le32_to_cpu(pSMBr->last_write_time); - /* BB FIXME - add time zone adjustment BB */ memset(pFinfo, 0, sizeof(FILE_ALL_INFO)); - ts.tv_nsec = 0; - ts.tv_sec = time; - /* decode time fields */ - pFinfo->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts)); - pFinfo->LastWriteTime = pFinfo->ChangeTime; - pFinfo->LastAccessTime = 0; pFinfo->AllocationSize = cpu_to_le64(le32_to_cpu(pSMBr->size)); pFinfo->EndOfFile = pFinfo->AllocationSize; @@ -2971,7 +2922,6 @@ int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, const unsigned char *searchName, FILE_ALL_INFO * pFindData, - int legacy /* old style infolevel */, const struct nls_table *nls_codepage, int remap) { /* level 263 SMB_QUERY_FILE_ALL_INFO */ @@ -3020,10 +2970,7 @@ CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, byte_count = params + 1 /* pad */ ; pSMB->TotalParameterCount = cpu_to_le16(params); pSMB->ParameterCount = pSMB->TotalParameterCount; - if(legacy) - pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD); - else - pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO); + pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO); pSMB->Reserved4 = 0; pSMB->hdr.smb_buf_length += byte_count; pSMB->ByteCount = cpu_to_le16(byte_count); @@ -3035,24 +2982,13 @@ CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, } else { /* decode response */ rc = validate_t2((struct smb_t2_rsp *)pSMBr); - if (rc) /* BB add auto retry on EOPNOTSUPP? */ - rc = -EIO; - else if (!legacy && (pSMBr->ByteCount < 40)) + if (rc || (pSMBr->ByteCount < 40)) rc = -EIO; /* bad smb */ - else if(legacy && (pSMBr->ByteCount < 24)) - rc = -EIO; /* 24 or 26 expected but we do not read last field */ else if (pFindData){ - int size; __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); - if(legacy) /* we do not read the last field, EAsize, fortunately - since it varies by subdialect and on Set vs. Get, is - two bytes or 4 bytes depending but we don't care here */ - size = sizeof(FILE_INFO_STANDARD); - else - size = sizeof(FILE_ALL_INFO); memcpy((char *) pFindData, (char *) &pSMBr->hdr.Protocol + - data_offset, size); + data_offset, sizeof (FILE_ALL_INFO)); } else rc = -ENOMEM; } @@ -3677,14 +3613,6 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses, strncpy(pSMB->RequestFileName, searchName, name_len); } - if(ses->server) { - if(ses->server->secMode & - (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) - pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE; - } - - pSMB->hdr.Uid = ses->Suid; - params = 2 /* level */ + name_len /*includes null */ ; pSMB->TotalDataCount = 0; pSMB->DataCount = 0; diff --git a/trunk/fs/cifs/connect.c b/trunk/fs/cifs/connect.c index 71f77914ce93..c78762051da4 100644 --- a/trunk/fs/cifs/connect.c +++ b/trunk/fs/cifs/connect.c @@ -109,7 +109,7 @@ static int ipv6_connect(struct sockaddr_in6 *psin_server, * wake up waiters on reconnection? - (not needed currently) */ -static int +int cifs_reconnect(struct TCP_Server_Info *server) { int rc = 0; @@ -771,18 +771,13 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol) separator[0] = ','; separator[1] = 0; - if (Local_System_Name[0] != 0) - memcpy(vol->source_rfc1001_name, Local_System_Name,15); - else { - char *nodename = utsname()->nodename; - int n = strnlen(nodename,15); - memset(vol->source_rfc1001_name,0x20,15); - for(i=0 ; i < n ; i++) { - /* does not have to be perfect mapping since field is - informational, only used for servers that do not support - port 445 and it can be overridden at mount time */ - vol->source_rfc1001_name[i] = toupper(nodename[i]); - } + memset(vol->source_rfc1001_name,0x20,15); + for(i=0;i < strnlen(utsname()->nodename,15);i++) { + /* does not have to be a perfect mapping since the field is + informational, only used for servers that do not support + port 445 and it can be overridden at mount time */ + vol->source_rfc1001_name[i] = + toupper(utsname()->nodename[i]); } vol->source_rfc1001_name[15] = 0; /* null target name indicates to use *SMBSERVR default called name @@ -822,13 +817,10 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol) } else if (strnicmp(data, "nouser_xattr",12) == 0) { vol->no_xattr = 1; } else if (strnicmp(data, "user", 4) == 0) { - if (!value) { + if (!value || !*value) { printk(KERN_WARNING "CIFS: invalid or missing username\n"); return 1; /* needs_arg; */ - } else if(!*value) { - /* null user, ie anonymous, authentication */ - vol->nullauth = 1; } if (strnlen(value, 200) < 200) { vol->username = value; @@ -1645,8 +1637,6 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, /* BB fixme parse for domain name here */ cFYI(1, ("Username: %s ", volume_info.username)); - } else if (volume_info.nullauth) { - cFYI(1,("null user")); } else { cifserror("No username specified"); /* In userspace mount helper we can get user name from alternate @@ -3225,9 +3215,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, } /* else do not bother copying these informational fields */ } - if((smb_buffer_response->WordCount == 3) || - (smb_buffer_response->WordCount == 7)) - /* field is in same location */ + if(smb_buffer_response->WordCount == 3) tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport); else tcon->Flags = 0; @@ -3324,21 +3312,19 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo, first_time = 1; } if (!rc) { - pSesInfo->flags = 0; pSesInfo->capabilities = pSesInfo->server->capabilities; if(linuxExtEnabled == 0) pSesInfo->capabilities &= (~CAP_UNIX); /* pSesInfo->sequence_number = 0;*/ - cFYI(1,("Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d", + cFYI(1,("Security Mode: 0x%x Capabilities: 0x%x Time Zone: %d", pSesInfo->server->secMode, pSesInfo->server->capabilities, - pSesInfo->server->timeAdj)); + pSesInfo->server->timeZone)); if(experimEnabled < 2) rc = CIFS_SessSetup(xid, pSesInfo, first_time, nls_info); else if (extended_security - && (pSesInfo->capabilities - & CAP_EXTENDED_SECURITY) + && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY) && (pSesInfo->server->secType == NTLMSSP)) { rc = -EOPNOTSUPP; } else if (extended_security @@ -3352,7 +3338,7 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo, if (!rc) { if(ntlmv2_flag) { char * v2_response; - cFYI(1,("more secure NTLM ver2 hash")); + cFYI(1,("Can use more secure NTLM version 2 password hash")); if(CalcNTLMv2_partial_mac_key(pSesInfo, nls_info)) { rc = -ENOMEM; diff --git a/trunk/fs/cifs/file.c b/trunk/fs/cifs/file.c index 2436ed8fc840..976a691c5a68 100644 --- a/trunk/fs/cifs/file.c +++ b/trunk/fs/cifs/file.c @@ -492,14 +492,10 @@ int cifs_close(struct inode *inode, struct file *file) the struct would be in each open file, but this should give enough time to clear the socket */ -#ifdef CONFIG_CIFS_DEBUG2 - cFYI(1,("close delay, write pending")); -#endif /* DEBUG2 */ + cERROR(1,("close with pending writes")); msleep(timeout); timeout *= 4; - } - if(atomic_read(&pSMBFile->wrtPending)) - cERROR(1,("close with pending writes")); + } rc = CIFSSMBClose(xid, pTcon, pSMBFile->netfid); } @@ -1810,6 +1806,13 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, } if ((rc < 0) || (smb_read_data == NULL)) { cFYI(1, ("Read error in readpages: %d", rc)); + /* clean up remaing pages off list */ + while (!list_empty(page_list) && (i < num_pages)) { + page = list_entry(page_list->prev, struct page, + lru); + list_del(&page->lru); + page_cache_release(page); + } break; } else if (bytes_read > 0) { pSMBr = (struct smb_com_read_rsp *)smb_read_data; @@ -1828,7 +1831,13 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, this case is ok - if we are at server EOF we will hit it on next read */ - /* break; */ + /* while (!list_empty(page_list) && (i < num_pages)) { + page = list_entry(page_list->prev, + struct page, list); + list_del(&page->list); + page_cache_release(page); + } + break; */ } } else { cFYI(1, ("No bytes read (%d) at offset %lld . " @@ -1836,6 +1845,14 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, bytes_read, offset)); /* BB turn off caching and do new lookup on file size at server? */ + while (!list_empty(page_list) && (i < num_pages)) { + page = list_entry(page_list->prev, struct page, + lru); + list_del(&page->lru); + + /* BB removeme - replace with zero of page? */ + page_cache_release(page); + } break; } if (smb_read_data) { diff --git a/trunk/fs/cifs/inode.c b/trunk/fs/cifs/inode.c index c4fa91b8b62f..6b90ef98e4cf 100644 --- a/trunk/fs/cifs/inode.c +++ b/trunk/fs/cifs/inode.c @@ -318,7 +318,6 @@ int cifs_get_inode_info(struct inode **pinode, struct cifs_sb_info *cifs_sb = CIFS_SB(sb); char *tmp_path; char *buf = NULL; - int adjustTZ = FALSE; pTcon = cifs_sb->tcon; cFYI(1,("Getting info on %s", search_path)); @@ -338,7 +337,6 @@ int cifs_get_inode_info(struct inode **pinode, pfindData = (FILE_ALL_INFO *)buf; /* could do find first instead but this returns more info */ rc = CIFSSMBQPathInfo(xid, pTcon, search_path, pfindData, - 0 /* not legacy */, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); /* BB optimize code so we do not make the above call @@ -349,7 +347,6 @@ int cifs_get_inode_info(struct inode **pinode, pfindData, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); - adjustTZ = TRUE; } } @@ -387,10 +384,8 @@ int cifs_get_inode_info(struct inode **pinode, /* get new inode */ if (*pinode == NULL) { *pinode = new_inode(sb); - if (*pinode == NULL) { - kfree(buf); + if (*pinode == NULL) return -ENOMEM; - } /* Is an i_ino of zero legal? Can we use that to check if the server supports returning inode numbers? Are there other sanity checks we can use to ensure that @@ -436,20 +431,13 @@ int cifs_get_inode_info(struct inode **pinode, (pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00;*/ /* Linux can not store file creation time so ignore it */ - if(pfindData->LastAccessTime) - inode->i_atime = cifs_NTtimeToUnix - (le64_to_cpu(pfindData->LastAccessTime)); - else /* do not need to use current_fs_time - time not stored */ - inode->i_atime = CURRENT_TIME; + inode->i_atime = + cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastAccessTime)); inode->i_mtime = cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime)); inode->i_ctime = cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime)); cFYI(0, ("Attributes came in as 0x%x", attr)); - if(adjustTZ && (pTcon->ses) && (pTcon->ses->server)) { - inode->i_ctime.tv_sec += pTcon->ses->server->timeAdj; - inode->i_mtime.tv_sec += pTcon->ses->server->timeAdj; - } /* set default mode. will override for dirs below */ if (atomic_read(&cifsInfo->inUse) == 0) @@ -891,14 +879,10 @@ int cifs_rename(struct inode *source_inode, struct dentry *source_direntry, kmalloc(2 * sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL); if (info_buf_source != NULL) { info_buf_target = info_buf_source + 1; - if (pTcon->ses->capabilities & CAP_UNIX) - rc = CIFSSMBUnixQPathInfo(xid, pTcon, fromName, - info_buf_source, - cifs_sb_source->local_nls, - cifs_sb_source->mnt_cifs_flags & - CIFS_MOUNT_MAP_SPECIAL_CHR); - /* else rc is still EEXIST so will fall through to - unlink the target and retry rename */ + rc = CIFSSMBUnixQPathInfo(xid, pTcon, fromName, + info_buf_source, cifs_sb_source->local_nls, + cifs_sb_source->mnt_cifs_flags & + CIFS_MOUNT_MAP_SPECIAL_CHR); if (rc == 0) { rc = CIFSSMBUnixQPathInfo(xid, pTcon, toName, info_buf_target, @@ -947,7 +931,7 @@ int cifs_rename(struct inode *source_inode, struct dentry *source_direntry, cifs_sb_source->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); if (rc==0) { - rc = CIFSSMBRenameOpenFile(xid, pTcon, netfid, toName, + CIFSSMBRenameOpenFile(xid, pTcon, netfid, toName, cifs_sb_source->local_nls, cifs_sb_source->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); @@ -1095,10 +1079,8 @@ int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) { int err = cifs_revalidate(dentry); - if (!err) { + if (!err) generic_fillattr(dentry->d_inode, stat); - stat->blksize = CIFS_MAX_MSGSIZE; - } return err; } diff --git a/trunk/fs/cifs/link.c b/trunk/fs/cifs/link.c index 8e259969354b..a57f5d6e6213 100644 --- a/trunk/fs/cifs/link.c +++ b/trunk/fs/cifs/link.c @@ -69,30 +69,17 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode, rc = -EOPNOTSUPP; } - d_drop(direntry); /* force new lookup from server of target */ - - /* if source file is cached (oplocked) revalidate will not go to server - until the file is closed or oplock broken so update nlinks locally */ - if(old_file->d_inode) { - cifsInode = CIFS_I(old_file->d_inode); - if(rc == 0) { - old_file->d_inode->i_nlink++; - old_file->d_inode->i_ctime = CURRENT_TIME; - /* parent dir timestamps will update from srv - within a second, would it really be worth it - to set the parent dir cifs inode time to zero - to force revalidate (faster) for it too? */ - } - /* if not oplocked will force revalidate to get info - on source file from srv */ - cifsInode->time = 0; - - /* Will update parent dir timestamps from srv within a second. - Would it really be worth it to set the parent dir (cifs - inode) time field to zero to force revalidate on parent - directory faster ie - CIFS_I(inode)->time = 0; */ +/* if (!rc) */ + { + /* renew_parental_timestamps(old_file); + inode->i_nlink++; + mark_inode_dirty(inode); + d_instantiate(direntry, inode); */ + /* BB add call to either mark inode dirty or refresh its data and timestamp to current time */ } + d_drop(direntry); /* force new lookup from server */ + cifsInode = CIFS_I(old_file->d_inode); + cifsInode->time = 0; /* will force revalidate to go get info when needed */ cifs_hl_exit: kfree(fromName); @@ -267,11 +254,7 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen) tmpbuffer, len - 1, cifs_sb->local_nls); - else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { - cERROR(1,("SFU style symlinks not implemented yet")); - /* add open and read as in fs/cifs/inode.c */ - - } else { + else { rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, GENERIC_READ, OPEN_REPARSE_POINT,&fid, &oplock, NULL, cifs_sb->local_nls, diff --git a/trunk/fs/cifs/md5.c b/trunk/fs/cifs/md5.c index ccebf9b7eb86..7aa23490541f 100644 --- a/trunk/fs/cifs/md5.c +++ b/trunk/fs/cifs/md5.c @@ -252,11 +252,10 @@ MD5Transform(__u32 buf[4], __u32 const in[16]) buf[3] += d; } -#if 0 /* currently unused */ /*********************************************************************** the rfc 2104 version of hmac_md5 initialisation. ***********************************************************************/ -static void +void hmac_md5_init_rfc2104(unsigned char *key, int key_len, struct HMACMD5Context *ctx) { @@ -290,7 +289,6 @@ hmac_md5_init_rfc2104(unsigned char *key, int key_len, MD5Init(&ctx->ctx); MD5Update(&ctx->ctx, ctx->k_ipad, 64); } -#endif /*********************************************************************** the microsoft version of hmac_md5 initialisation. @@ -352,8 +350,7 @@ hmac_md5_final(unsigned char *digest, struct HMACMD5Context *ctx) single function to calculate an HMAC MD5 digest from data. use the microsoft hmacmd5 init method because the key is 16 bytes. ************************************************************/ -#if 0 /* currently unused */ -static void +void hmac_md5(unsigned char key[16], unsigned char *data, int data_len, unsigned char *digest) { @@ -364,4 +361,3 @@ hmac_md5(unsigned char key[16], unsigned char *data, int data_len, } hmac_md5_final(digest, &ctx); } -#endif diff --git a/trunk/fs/cifs/md5.h b/trunk/fs/cifs/md5.h index f7d4f4197bac..00e1c5394fe1 100644 --- a/trunk/fs/cifs/md5.h +++ b/trunk/fs/cifs/md5.h @@ -27,12 +27,12 @@ void MD5Final(unsigned char digest[16], struct MD5Context *context); /* The following definitions come from lib/hmacmd5.c */ -/* void hmac_md5_init_rfc2104(unsigned char *key, int key_len, - struct HMACMD5Context *ctx);*/ +void hmac_md5_init_rfc2104(unsigned char *key, int key_len, + struct HMACMD5Context *ctx); void hmac_md5_init_limK_to_64(const unsigned char *key, int key_len, struct HMACMD5Context *ctx); void hmac_md5_update(const unsigned char *text, int text_len, struct HMACMD5Context *ctx); void hmac_md5_final(unsigned char *digest, struct HMACMD5Context *ctx); -/* void hmac_md5(unsigned char key[16], unsigned char *data, int data_len, - unsigned char *digest);*/ +void hmac_md5(unsigned char key[16], unsigned char *data, int data_len, + unsigned char *digest); diff --git a/trunk/fs/cifs/misc.c b/trunk/fs/cifs/misc.c index bbc9cd34b6ea..22c937e5884f 100644 --- a/trunk/fs/cifs/misc.c +++ b/trunk/fs/cifs/misc.c @@ -389,7 +389,7 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ , return; } -static int +int checkSMBhdr(struct smb_hdr *smb, __u16 mid) { /* Make sure that this really is an SMB, that it is a response, @@ -418,42 +418,26 @@ checkSMBhdr(struct smb_hdr *smb, __u16 mid) } int -checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length) +checkSMB(struct smb_hdr *smb, __u16 mid, int length) { __u32 len = smb->smb_buf_length; __u32 clc_len; /* calculated length */ cFYI(0, ("checkSMB Length: 0x%x, smb_buf_length: 0x%x", length, len)); - - if (length < 2 + sizeof (struct smb_hdr)) { - if ((length >= sizeof (struct smb_hdr) - 1) + if (((unsigned int)length < 2 + sizeof (struct smb_hdr)) || + (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4)) { + if ((unsigned int)length < 2 + sizeof (struct smb_hdr)) { + if (((unsigned int)length >= + sizeof (struct smb_hdr) - 1) && (smb->Status.CifsError != 0)) { - smb->WordCount = 0; - /* some error cases do not return wct and bcc */ - return 0; - } else if ((length == sizeof(struct smb_hdr) + 1) && - (smb->WordCount == 0)) { - char * tmp = (char *)smb; - /* Need to work around a bug in two servers here */ - /* First, check if the part of bcc they sent was zero */ - if (tmp[sizeof(struct smb_hdr)] == 0) { - /* some servers return only half of bcc - * on simple responses (wct, bcc both zero) - * in particular have seen this on - * ulogoffX and FindClose. This leaves - * one byte of bcc potentially unitialized - */ - /* zero rest of bcc */ - tmp[sizeof(struct smb_hdr)+1] = 0; + smb->WordCount = 0; + /* some error cases do not return wct and bcc */ return 0; + } else { + cERROR(1, ("Length less than smb header size")); } - cERROR(1,("rcvd invalid byte count (bcc)")); - } else { - cERROR(1, ("Length less than smb header size")); } - return 1; - } - if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) { - cERROR(1, ("smb length greater than MaxBufSize, mid=%d", + if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) + cERROR(1, ("smb length greater than MaxBufSize, mid=%d", smb->Mid)); return 1; } @@ -462,7 +446,7 @@ checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length) return 1; clc_len = smbCalcSize_LE(smb); - if(4 + len != length) { + if(4 + len != (unsigned int)length) { cERROR(1, ("Length read does not match RFC1001 length %d",len)); return 1; } diff --git a/trunk/fs/cifs/netmisc.c b/trunk/fs/cifs/netmisc.c index 992e80edc720..ce87550e918f 100644 --- a/trunk/fs/cifs/netmisc.c +++ b/trunk/fs/cifs/netmisc.c @@ -909,61 +909,3 @@ cifs_UnixTimeToNT(struct timespec t) /* Convert to 100ns intervals and then add the NTFS time offset. */ return (u64) t.tv_sec * 10000000 + t.tv_nsec/100 + NTFS_TIME_OFFSET; } - -static int total_days_of_prev_months[] = -{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; - - -__le64 cnvrtDosCifsTm(__u16 date, __u16 time) -{ - return cpu_to_le64(cifs_UnixTimeToNT(cnvrtDosUnixTm(date, time))); -} - -struct timespec cnvrtDosUnixTm(__u16 date, __u16 time) -{ - struct timespec ts; - int sec, min, days, month, year; - SMB_TIME * st = (SMB_TIME *)&time; - SMB_DATE * sd = (SMB_DATE *)&date; - - cFYI(1,("date %d time %d",date, time)); - - sec = 2 * st->TwoSeconds; - min = st->Minutes; - if((sec > 59) || (min > 59)) - cERROR(1,("illegal time min %d sec %d", min, sec)); - sec += (min * 60); - sec += 60 * 60 * st->Hours; - if(st->Hours > 24) - cERROR(1,("illegal hours %d",st->Hours)); - days = sd->Day; - month = sd->Month; - if((days > 31) || (month > 12)) - cERROR(1,("illegal date, month %d day: %d", month, days)); - month -= 1; - days += total_days_of_prev_months[month]; - days += 3652; /* account for difference in days between 1980 and 1970 */ - year = sd->Year; - days += year * 365; - days += (year/4); /* leap year */ - /* generalized leap year calculation is more complex, ie no leap year - for years/100 except for years/400, but since the maximum number for DOS - year is 2**7, the last year is 1980+127, which means we need only - consider 2 special case years, ie the years 2000 and 2100, and only - adjust for the lack of leap year for the year 2100, as 2000 was a - leap year (divisable by 400) */ - if(year >= 120) /* the year 2100 */ - days = days - 1; /* do not count leap year for the year 2100 */ - - /* adjust for leap year where we are still before leap day */ - if(year != 120) - days -= ((year & 0x03) == 0) && (month < 2 ? 1 : 0); - sec += 24 * 60 * 60 * days; - - ts.tv_sec = sec; - - /* cFYI(1,("sec after cnvrt dos to unix time %d",sec)); */ - - ts.tv_nsec = 0; - return ts; -} diff --git a/trunk/fs/cifs/readdir.c b/trunk/fs/cifs/readdir.c index ed18c3965f7b..b27b34537bf2 100644 --- a/trunk/fs/cifs/readdir.c +++ b/trunk/fs/cifs/readdir.c @@ -106,17 +106,6 @@ static int construct_dentry(struct qstr *qstring, struct file *file, return rc; } -static void AdjustForTZ(struct cifsTconInfo * tcon, struct inode * inode) -{ - if((tcon) && (tcon->ses) && (tcon->ses->server)) { - inode->i_ctime.tv_sec += tcon->ses->server->timeAdj; - inode->i_mtime.tv_sec += tcon->ses->server->timeAdj; - inode->i_atime.tv_sec += tcon->ses->server->timeAdj; - } - return; -} - - static void fill_in_inode(struct inode *tmp_inode, int new_buf_type, char * buf, int *pobject_type, int isNewInode) { @@ -146,23 +135,16 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type, tmp_inode->i_ctime = cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime)); } else { /* legacy, OS2 and DOS style */ -/* struct timespec ts;*/ FIND_FILE_STANDARD_INFO * pfindData = (FIND_FILE_STANDARD_INFO *)buf; - tmp_inode->i_mtime = cnvrtDosUnixTm( - le16_to_cpu(pfindData->LastWriteDate), - le16_to_cpu(pfindData->LastWriteTime)); - tmp_inode->i_atime = cnvrtDosUnixTm( - le16_to_cpu(pfindData->LastAccessDate), - le16_to_cpu(pfindData->LastAccessTime)); - tmp_inode->i_ctime = cnvrtDosUnixTm( - le16_to_cpu(pfindData->LastWriteDate), - le16_to_cpu(pfindData->LastWriteTime)); - AdjustForTZ(cifs_sb->tcon, tmp_inode); attr = le16_to_cpu(pfindData->Attributes); allocation_size = le32_to_cpu(pfindData->AllocationSize); end_of_file = le32_to_cpu(pfindData->DataSize); + tmp_inode->i_atime = CURRENT_TIME; + /* tmp_inode->i_mtime = BB FIXME - add dos time handling + tmp_inode->i_ctime = 0; BB FIXME */ + } /* Linux can not store file creation time unfortunately so ignore it */ @@ -896,10 +878,6 @@ static int cifs_filldir(char *pfindEntry, struct file *file, tmp_inode->i_ino,obj_type); if(rc) { cFYI(1,("filldir rc = %d",rc)); - /* we can not return filldir errors to the caller - since they are "normal" when the stat blocksize - is too small - we return remapped error instead */ - rc = -EOVERFLOW; } dput(tmp_dentry); @@ -960,7 +938,6 @@ static int cifs_save_resume_key(const char *current_entry, filename = &pFindData->FileName[0]; /* one byte length, no name conversion */ len = (unsigned int)pFindData->FileNameLength; - cifsFile->srch_inf.resume_key = pFindData->ResumeKey; } else { cFYI(1,("Unknown findfirst level %d",level)); return -EINVAL; @@ -1078,11 +1055,6 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir) we want to check for that here? */ rc = cifs_filldir(current_entry, file, filldir, direntry, tmp_buf, max_len); - if(rc == -EOVERFLOW) { - rc = 0; - break; - } - file->f_pos++; if(file->f_pos == cifsFile->srch_inf.index_of_last_entry) { diff --git a/trunk/fs/cifs/sess.c b/trunk/fs/cifs/sess.c index bbdda99dce61..22b4c35dcfe3 100644 --- a/trunk/fs/cifs/sess.c +++ b/trunk/fs/cifs/sess.c @@ -90,9 +90,7 @@ static void unicode_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses, } */ /* copy user */ if(ses->userName == NULL) { - /* null user mount */ - *bcc_ptr = 0; - *(bcc_ptr+1) = 0; + /* BB what about null user mounts - check that we do this BB */ } else { /* 300 should be long enough for any conceivable user name */ bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->userName, 300, nls_cp); @@ -100,13 +98,10 @@ static void unicode_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses, bcc_ptr += 2 * bytes_ret; bcc_ptr += 2; /* account for null termination */ /* copy domain */ - if(ses->domainName == NULL) { - /* Sending null domain better than using a bogus domain name (as - we did briefly in 2.6.18) since server will use its default */ - *bcc_ptr = 0; - *(bcc_ptr+1) = 0; - bytes_ret = 0; - } else + if(ses->domainName == NULL) + bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, + "CIFS_LINUX_DOM", 32, nls_cp); + else bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->domainName, 256, nls_cp); bcc_ptr += 2 * bytes_ret; @@ -149,11 +144,13 @@ static void ascii_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses, /* copy domain */ - if(ses->domainName != NULL) { + if(ses->domainName == NULL) { + strcpy(bcc_ptr, "CIFS_LINUX_DOM"); + bcc_ptr += 14; /* strlen(CIFS_LINUX_DOM) */ + } else { strncpy(bcc_ptr, ses->domainName, 256); bcc_ptr += strnlen(ses->domainName, 256); - } /* else we will send a null domain name - so the server will default to its own domain */ + } *bcc_ptr = 0; bcc_ptr++; @@ -271,10 +268,6 @@ static int decode_ascii_ssetup(char ** pbcc_area, int bleft, struct cifsSesInfo ses->serverOS = kzalloc(len + 1, GFP_KERNEL); if(ses->serverOS) strncpy(ses->serverOS, bcc_ptr, len); - if(strncmp(ses->serverOS, "OS/2",4) == 0) { - cFYI(1,("OS/2 server")); - ses->flags |= CIFS_SES_OS2; - } bcc_ptr += len + 1; bleft -= len + 1; @@ -297,11 +290,16 @@ static int decode_ascii_ssetup(char ** pbcc_area, int bleft, struct cifsSesInfo if(len > bleft) return rc; - /* No domain field in LANMAN case. Domain is - returned by old servers in the SMB negprot response */ - /* BB For newer servers which do not support Unicode, - but thus do return domain here we could add parsing - for it later, but it is not very important */ + if(ses->serverDomain) + kfree(ses->serverDomain); + + ses->serverDomain = kzalloc(len + 1, GFP_KERNEL); + if(ses->serverOS) + strncpy(ses->serverOS, bcc_ptr, len); + + bcc_ptr += len + 1; + bleft -= len + 1; + cFYI(1,("ascii: bytes left %d",bleft)); return rc; @@ -368,8 +366,6 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, str_area = kmalloc(2000, GFP_KERNEL); bcc_ptr = str_area; - ses->flags &= ~CIFS_SES_LANMAN; - if(type == LANMAN) { #ifdef CONFIG_CIFS_WEAK_PW_HASH char lnm_session_key[CIFS_SESS_KEY_SIZE]; @@ -381,7 +377,7 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, /* and copy into bcc */ calc_lanman_hash(ses, lnm_session_key); - ses->flags |= CIFS_SES_LANMAN; + /* #ifdef CONFIG_CIFS_DEBUG2 cifs_dump_mem("cryptkey: ",ses->server->cryptKey, CIFS_SESS_KEY_SIZE); diff --git a/trunk/fs/cifs/smbdes.c b/trunk/fs/cifs/smbdes.c index 7a1b2b961ec8..efaa044523a7 100644 --- a/trunk/fs/cifs/smbdes.c +++ b/trunk/fs/cifs/smbdes.c @@ -364,20 +364,20 @@ E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24) smbhash(p24 + 16, c8, p21 + 14, 1); } -#if 0 /* currently unsued */ -static void +void D_P16(unsigned char *p14, unsigned char *in, unsigned char *out) { smbhash(out, in, p14, 0); smbhash(out + 8, in + 8, p14 + 7, 0); } -static void +void E_old_pw_hash(unsigned char *p14, unsigned char *in, unsigned char *out) { smbhash(out, in, p14, 1); smbhash(out + 8, in + 8, p14 + 7, 1); } +#if 0 /* these routines are currently unneeded, but may be needed later */ void diff --git a/trunk/fs/cifs/smbencrypt.c b/trunk/fs/cifs/smbencrypt.c index 4b25ba92180d..f518c5e45035 100644 --- a/trunk/fs/cifs/smbencrypt.c +++ b/trunk/fs/cifs/smbencrypt.c @@ -51,8 +51,11 @@ void SMBencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24); void E_md4hash(const unsigned char *passwd, unsigned char *p16); +void nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16]); static void SMBOWFencrypt(unsigned char passwd[16], unsigned char *c8, unsigned char p24[24]); +void NTLMSSPOWFencrypt(unsigned char passwd[8], + unsigned char *ntlmchalresp, unsigned char p24[24]); void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24); /* @@ -141,9 +144,8 @@ E_md4hash(const unsigned char *passwd, unsigned char *p16) memset(wpwd,0,129 * 2); } -#if 0 /* currently unused */ /* Does both the NT and LM owfs of a user's password */ -static void +void nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16]) { char passwd[514]; @@ -169,7 +171,6 @@ nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16]) /* clear out local copy of user's password (just being paranoid). */ memset(passwd, '\0', sizeof (passwd)); } -#endif /* Does the NTLMv2 owfs of a user's password */ #if 0 /* function not needed yet - but will be soon */ @@ -222,8 +223,7 @@ SMBOWFencrypt(unsigned char passwd[16], unsigned char *c8, } /* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */ -#if 0 /* currently unused */ -static void +void NTLMSSPOWFencrypt(unsigned char passwd[8], unsigned char *ntlmchalresp, unsigned char p24[24]) { @@ -235,7 +235,6 @@ NTLMSSPOWFencrypt(unsigned char passwd[8], E_P24(p21, ntlmchalresp, p24); } -#endif /* Does the NT MD4 hash then des encryption. */ diff --git a/trunk/fs/compat.c b/trunk/fs/compat.c index 8d0a0018a7d2..4d3fbcb2ddb1 100644 --- a/trunk/fs/compat.c +++ b/trunk/fs/compat.c @@ -1316,7 +1316,7 @@ compat_sys_vmsplice(int fd, const struct compat_iovec __user *iov32, unsigned int nr_segs, unsigned int flags) { unsigned i; - struct iovec __user *iov; + struct iovec *iov; if (nr_segs > UIO_MAXIOV) return -EINVAL; iov = compat_alloc_user_space(nr_segs * sizeof(struct iovec)); @@ -1835,12 +1835,9 @@ asmlinkage long compat_sys_pselect7(int n, compat_ulong_t __user *inp, } while (!ret && !timeout && tsp && (ts.tv_sec || ts.tv_nsec)); - if (tsp) { + if (ret == 0 && tsp && !(current->personality & STICKY_TIMEOUTS)) { struct compat_timespec rts; - if (current->personality & STICKY_TIMEOUTS) - goto sticky; - rts.tv_sec = timeout / HZ; rts.tv_nsec = (timeout % HZ) * (NSEC_PER_SEC/HZ); if (rts.tv_nsec >= NSEC_PER_SEC) { @@ -1849,19 +1846,8 @@ asmlinkage long compat_sys_pselect7(int n, compat_ulong_t __user *inp, } if (compat_timespec_compare(&rts, &ts) >= 0) rts = ts; - if (copy_to_user(tsp, &rts, sizeof(rts))) { -sticky: - /* - * If an application puts its timeval in read-only - * memory, we don't want the Linux-specific update to - * the timeval to cause a fault after the select has - * completed successfully. However, because we're not - * updating the timeval, we can't restart the system - * call. - */ - if (ret == -ERESTARTNOHAND) - ret = -EINTR; - } + if (copy_to_user(tsp, &rts, sizeof(rts))) + ret = -EFAULT; } if (ret == -ERESTARTNOHAND) { diff --git a/trunk/fs/compat_ioctl.c b/trunk/fs/compat_ioctl.c index a91f2628c981..27ca1aa30562 100644 --- a/trunk/fs/compat_ioctl.c +++ b/trunk/fs/compat_ioctl.c @@ -2438,17 +2438,13 @@ HANDLE_IOCTL(0x1260, broken_blkgetsize) HANDLE_IOCTL(BLKFRAGET, w_long) HANDLE_IOCTL(BLKSECTGET, w_long) HANDLE_IOCTL(BLKPG, blkpg_ioctl_trans) -HANDLE_IOCTL(HDIO_GET_UNMASKINTR, hdio_ioctl_trans) -HANDLE_IOCTL(HDIO_GET_MULTCOUNT, hdio_ioctl_trans) HANDLE_IOCTL(HDIO_GET_KEEPSETTINGS, hdio_ioctl_trans) +HANDLE_IOCTL(HDIO_GET_UNMASKINTR, hdio_ioctl_trans) +HANDLE_IOCTL(HDIO_GET_DMA, hdio_ioctl_trans) HANDLE_IOCTL(HDIO_GET_32BIT, hdio_ioctl_trans) +HANDLE_IOCTL(HDIO_GET_MULTCOUNT, hdio_ioctl_trans) HANDLE_IOCTL(HDIO_GET_NOWERR, hdio_ioctl_trans) -HANDLE_IOCTL(HDIO_GET_DMA, hdio_ioctl_trans) HANDLE_IOCTL(HDIO_GET_NICE, hdio_ioctl_trans) -HANDLE_IOCTL(HDIO_GET_WCACHE, hdio_ioctl_trans) -HANDLE_IOCTL(HDIO_GET_ACOUSTIC, hdio_ioctl_trans) -HANDLE_IOCTL(HDIO_GET_ADDRESS, hdio_ioctl_trans) -HANDLE_IOCTL(HDIO_GET_BUSSTATE, hdio_ioctl_trans) HANDLE_IOCTL(FDSETPRM32, fd_ioctl_trans) HANDLE_IOCTL(FDDEFPRM32, fd_ioctl_trans) HANDLE_IOCTL(FDGETPRM32, fd_ioctl_trans) diff --git a/trunk/fs/configfs/file.c b/trunk/fs/configfs/file.c index cf33fac68c84..e6d5754a715e 100644 --- a/trunk/fs/configfs/file.c +++ b/trunk/fs/configfs/file.c @@ -275,14 +275,13 @@ static int check_perm(struct inode * inode, struct file * file) * it in file->private_data for easy access. */ buffer = kzalloc(sizeof(struct configfs_buffer),GFP_KERNEL); - if (!buffer) { + if (buffer) { + init_MUTEX(&buffer->sem); + buffer->needs_read_fill = 1; + buffer->ops = ops; + file->private_data = buffer; + } else error = -ENOMEM; - goto Enomem; - } - init_MUTEX(&buffer->sem); - buffer->needs_read_fill = 1; - buffer->ops = ops; - file->private_data = buffer; goto Done; Einval: @@ -290,7 +289,6 @@ static int check_perm(struct inode * inode, struct file * file) goto Done; Eaccess: error = -EACCES; - Enomem: module_put(attr->ca_owner); Done: if (error && item) diff --git a/trunk/fs/dcache.c b/trunk/fs/dcache.c index fd4a428998ef..2355bddad8de 100644 --- a/trunk/fs/dcache.c +++ b/trunk/fs/dcache.c @@ -478,12 +478,11 @@ static void prune_dcache(int count, struct super_block *sb) up_read(s_umount); } spin_unlock(&dentry->d_lock); - /* - * Insert dentry at the head of the list as inserting at the - * tail leads to a cycle. + /* Cannot remove the first dentry, and it isn't appropriate + * to move it to the head of the list, so give up, and try + * later */ - list_add(&dentry->d_lru, &dentry_unused); - dentry_stat.nr_unused++; + break; } spin_unlock(&dcache_lock); } @@ -549,142 +548,6 @@ void shrink_dcache_sb(struct super_block * sb) spin_unlock(&dcache_lock); } -/* - * destroy a single subtree of dentries for unmount - * - see the comments on shrink_dcache_for_umount() for a description of the - * locking - */ -static void shrink_dcache_for_umount_subtree(struct dentry *dentry) -{ - struct dentry *parent; - unsigned detached = 0; - - BUG_ON(!IS_ROOT(dentry)); - - /* detach this root from the system */ - spin_lock(&dcache_lock); - if (!list_empty(&dentry->d_lru)) { - dentry_stat.nr_unused--; - list_del_init(&dentry->d_lru); - } - __d_drop(dentry); - spin_unlock(&dcache_lock); - - for (;;) { - /* descend to the first leaf in the current subtree */ - while (!list_empty(&dentry->d_subdirs)) { - struct dentry *loop; - - /* this is a branch with children - detach all of them - * from the system in one go */ - spin_lock(&dcache_lock); - list_for_each_entry(loop, &dentry->d_subdirs, - d_u.d_child) { - if (!list_empty(&loop->d_lru)) { - dentry_stat.nr_unused--; - list_del_init(&loop->d_lru); - } - - __d_drop(loop); - cond_resched_lock(&dcache_lock); - } - spin_unlock(&dcache_lock); - - /* move to the first child */ - dentry = list_entry(dentry->d_subdirs.next, - struct dentry, d_u.d_child); - } - - /* consume the dentries from this leaf up through its parents - * until we find one with children or run out altogether */ - do { - struct inode *inode; - - if (atomic_read(&dentry->d_count) != 0) { - printk(KERN_ERR - "BUG: Dentry %p{i=%lx,n=%s}" - " still in use (%d)" - " [unmount of %s %s]\n", - dentry, - dentry->d_inode ? - dentry->d_inode->i_ino : 0UL, - dentry->d_name.name, - atomic_read(&dentry->d_count), - dentry->d_sb->s_type->name, - dentry->d_sb->s_id); - BUG(); - } - - parent = dentry->d_parent; - if (parent == dentry) - parent = NULL; - else - atomic_dec(&parent->d_count); - - list_del(&dentry->d_u.d_child); - detached++; - - inode = dentry->d_inode; - if (inode) { - dentry->d_inode = NULL; - list_del_init(&dentry->d_alias); - if (dentry->d_op && dentry->d_op->d_iput) - dentry->d_op->d_iput(dentry, inode); - else - iput(inode); - } - - d_free(dentry); - - /* finished when we fall off the top of the tree, - * otherwise we ascend to the parent and move to the - * next sibling if there is one */ - if (!parent) - goto out; - - dentry = parent; - - } while (list_empty(&dentry->d_subdirs)); - - dentry = list_entry(dentry->d_subdirs.next, - struct dentry, d_u.d_child); - } -out: - /* several dentries were freed, need to correct nr_dentry */ - spin_lock(&dcache_lock); - dentry_stat.nr_dentry -= detached; - spin_unlock(&dcache_lock); -} - -/* - * destroy the dentries attached to a superblock on unmounting - * - we don't need to use dentry->d_lock, and only need dcache_lock when - * removing the dentry from the system lists and hashes because: - * - the superblock is detached from all mountings and open files, so the - * dentry trees will not be rearranged by the VFS - * - s_umount is write-locked, so the memory pressure shrinker will ignore - * any dentries belonging to this superblock that it comes across - * - the filesystem itself is no longer permitted to rearrange the dentries - * in this superblock - */ -void shrink_dcache_for_umount(struct super_block *sb) -{ - struct dentry *dentry; - - if (down_read_trylock(&sb->s_umount)) - BUG(); - - dentry = sb->s_root; - sb->s_root = NULL; - atomic_dec(&dentry->d_count); - shrink_dcache_for_umount_subtree(dentry); - - while (!hlist_empty(&sb->s_anon)) { - dentry = hlist_entry(sb->s_anon.first, struct dentry, d_hash); - shrink_dcache_for_umount_subtree(dentry); - } -} - /* * Search for at least 1 mount point in the dentry's subdirs. * We descend to the next level whenever the d_subdirs @@ -1476,21 +1339,23 @@ static void switch_names(struct dentry *dentry, struct dentry *target) * deleted it. */ -/* - * d_move_locked - move a dentry +/** + * d_move - move a dentry * @dentry: entry to move * @target: new dentry * * Update the dcache to reflect the move of a file name. Negative * dcache entries should not be moved in this way. */ -static void d_move_locked(struct dentry * dentry, struct dentry * target) + +void d_move(struct dentry * dentry, struct dentry * target) { struct hlist_head *list; if (!dentry->d_inode) printk(KERN_WARNING "VFS: moving negative dcache entry\n"); + spin_lock(&dcache_lock); write_seqlock(&rename_lock); /* * XXXX: do we really need to take target->d_lock? @@ -1541,81 +1406,7 @@ static void d_move_locked(struct dentry * dentry, struct dentry * target) fsnotify_d_move(dentry); spin_unlock(&dentry->d_lock); write_sequnlock(&rename_lock); -} - -/** - * d_move - move a dentry - * @dentry: entry to move - * @target: new dentry - * - * Update the dcache to reflect the move of a file name. Negative - * dcache entries should not be moved in this way. - */ - -void d_move(struct dentry * dentry, struct dentry * target) -{ - spin_lock(&dcache_lock); - d_move_locked(dentry, target); - spin_unlock(&dcache_lock); -} - -/* - * Helper that returns 1 if p1 is a parent of p2, else 0 - */ -static int d_isparent(struct dentry *p1, struct dentry *p2) -{ - struct dentry *p; - - for (p = p2; p->d_parent != p; p = p->d_parent) { - if (p->d_parent == p1) - return 1; - } - return 0; -} - -/* - * This helper attempts to cope with remotely renamed directories - * - * It assumes that the caller is already holding - * dentry->d_parent->d_inode->i_mutex and the dcache_lock - * - * Note: If ever the locking in lock_rename() changes, then please - * remember to update this too... - * - * On return, dcache_lock will have been unlocked. - */ -static struct dentry *__d_unalias(struct dentry *dentry, struct dentry *alias) -{ - struct mutex *m1 = NULL, *m2 = NULL; - struct dentry *ret; - - /* If alias and dentry share a parent, then no extra locks required */ - if (alias->d_parent == dentry->d_parent) - goto out_unalias; - - /* Check for loops */ - ret = ERR_PTR(-ELOOP); - if (d_isparent(alias, dentry)) - goto out_err; - - /* See lock_rename() */ - ret = ERR_PTR(-EBUSY); - if (!mutex_trylock(&dentry->d_sb->s_vfs_rename_mutex)) - goto out_err; - m1 = &dentry->d_sb->s_vfs_rename_mutex; - if (!mutex_trylock(&alias->d_parent->d_inode->i_mutex)) - goto out_err; - m2 = &alias->d_parent->d_inode->i_mutex; -out_unalias: - d_move_locked(alias, dentry); - ret = alias; -out_err: spin_unlock(&dcache_lock); - if (m2) - mutex_unlock(m2); - if (m1) - mutex_unlock(m1); - return ret; } /* @@ -1660,7 +1451,7 @@ static void __d_materialise_dentry(struct dentry *dentry, struct dentry *anon) */ struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode) { - struct dentry *actual; + struct dentry *alias, *actual; BUG_ON(!d_unhashed(dentry)); @@ -1672,27 +1463,26 @@ struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode) goto found_lock; } - if (S_ISDIR(inode->i_mode)) { - struct dentry *alias; - - /* Does an aliased dentry already exist? */ - alias = __d_find_alias(inode, 0); - if (alias) { - actual = alias; - /* Is this an anonymous mountpoint that we could splice - * into our tree? */ - if (IS_ROOT(alias)) { - spin_lock(&alias->d_lock); - __d_materialise_dentry(dentry, alias); - __d_drop(alias); - goto found; - } - /* Nope, but we must(!) avoid directory aliasing */ - actual = __d_unalias(dentry, alias); - if (IS_ERR(actual)) - dput(alias); - goto out_nolock; - } + /* See if a disconnected directory already exists as an anonymous root + * that we should splice into the tree instead */ + if (S_ISDIR(inode->i_mode) && (alias = __d_find_alias(inode, 1))) { + spin_lock(&alias->d_lock); + + /* Is this a mountpoint that we could splice into our tree? */ + if (IS_ROOT(alias)) + goto connect_mountpoint; + + if (alias->d_name.len == dentry->d_name.len && + alias->d_parent == dentry->d_parent && + memcmp(alias->d_name.name, + dentry->d_name.name, + dentry->d_name.len) == 0) + goto replace_with_alias; + + spin_unlock(&alias->d_lock); + + /* Doh! Seem to be aliasing directories for some reason... */ + dput(alias); } /* Add a unique reference */ @@ -1708,7 +1498,7 @@ struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode) _d_rehash(actual); spin_unlock(&actual->d_lock); spin_unlock(&dcache_lock); -out_nolock: + if (actual == dentry) { security_d_instantiate(dentry, inode); return NULL; @@ -1717,6 +1507,16 @@ struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode) iput(inode); return actual; + /* Convert the anonymous/root alias into an ordinary dentry */ +connect_mountpoint: + __d_materialise_dentry(dentry, alias); + + /* Replace the candidate dentry with the alias in the tree */ +replace_with_alias: + __d_drop(alias); + actual = alias; + goto found; + shouldnt_be_hashed: spin_unlock(&dcache_lock); BUG(); diff --git a/trunk/fs/debugfs/inode.c b/trunk/fs/debugfs/inode.c index 137d76c3f90a..e77676df6713 100644 --- a/trunk/fs/debugfs/inode.c +++ b/trunk/fs/debugfs/inode.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include @@ -148,13 +147,13 @@ static int debugfs_create_by_name(const char *name, mode_t mode, *dentry = NULL; mutex_lock(&parent->d_inode->i_mutex); *dentry = lookup_one_len(name, parent, strlen(name)); - if (!IS_ERR(*dentry)) { + if (!IS_ERR(dentry)) { if ((mode & S_IFMT) == S_IFDIR) error = debugfs_mkdir(parent->d_inode, *dentry, mode); else error = debugfs_create(parent->d_inode, *dentry, mode); } else - error = PTR_ERR(*dentry); + error = PTR_ERR(dentry); mutex_unlock(&parent->d_inode->i_mutex); return error; diff --git a/trunk/fs/dlm/Kconfig b/trunk/fs/dlm/Kconfig index 81b2c6465eeb..490f85b3fa59 100644 --- a/trunk/fs/dlm/Kconfig +++ b/trunk/fs/dlm/Kconfig @@ -1,9 +1,10 @@ menu "Distributed Lock Manager" - depends on INET && IP_SCTP && EXPERIMENTAL + depends on INET && EXPERIMENTAL config DLM tristate "Distributed Lock Manager (DLM)" depends on IPV6 || IPV6=n + depends on IP_SCTP select CONFIGFS_FS help A general purpose distributed lock manager for kernel or userspace diff --git a/trunk/fs/dlm/lockspace.c b/trunk/fs/dlm/lockspace.c index f8842ca443c2..109333c8ecb9 100644 --- a/trunk/fs/dlm/lockspace.c +++ b/trunk/fs/dlm/lockspace.c @@ -43,10 +43,6 @@ static ssize_t dlm_control_store(struct dlm_ls *ls, const char *buf, size_t len) ssize_t ret = len; int n = simple_strtol(buf, NULL, 0); - ls = dlm_find_lockspace_local(ls->ls_local_handle); - if (!ls) - return -EINVAL; - switch (n) { case 0: dlm_ls_stop(ls); @@ -57,7 +53,6 @@ static ssize_t dlm_control_store(struct dlm_ls *ls, const char *buf, size_t len) default: ret = -EINVAL; } - dlm_put_lockspace(ls); return ret; } @@ -148,12 +143,6 @@ static ssize_t dlm_attr_store(struct kobject *kobj, struct attribute *attr, return a->store ? a->store(ls, buf, len) : len; } -static void lockspace_kobj_release(struct kobject *k) -{ - struct dlm_ls *ls = container_of(k, struct dlm_ls, ls_kobj); - kfree(ls); -} - static struct sysfs_ops dlm_attr_ops = { .show = dlm_attr_show, .store = dlm_attr_store, @@ -162,7 +151,6 @@ static struct sysfs_ops dlm_attr_ops = { static struct kobj_type dlm_ktype = { .default_attrs = dlm_attrs, .sysfs_ops = &dlm_attr_ops, - .release = lockspace_kobj_release, }; static struct kset dlm_kset = { @@ -690,7 +678,7 @@ static int release_lockspace(struct dlm_ls *ls, int force) dlm_clear_members_gone(ls); kfree(ls->ls_node_array); kobject_unregister(&ls->ls_kobj); - /* The ls structure will be freed when the kobject is done with */ + kfree(ls); mutex_lock(&ls_lock); ls_count--; diff --git a/trunk/fs/dlm/lowcomms.c b/trunk/fs/dlm/lowcomms.c index 6da6b14d5a61..23f5ce12080b 100644 --- a/trunk/fs/dlm/lowcomms.c +++ b/trunk/fs/dlm/lowcomms.c @@ -174,7 +174,7 @@ static int nodeid_to_addr(int nodeid, struct sockaddr *retaddr) return 0; } -static struct nodeinfo *nodeid2nodeinfo(int nodeid, gfp_t alloc) +static struct nodeinfo *nodeid2nodeinfo(int nodeid, int alloc) { struct nodeinfo *ni; int r; @@ -519,7 +519,6 @@ static int receive_from_sock(void) msg.msg_flags = 0; msg.msg_control = incmsg; msg.msg_controllen = sizeof(incmsg); - msg.msg_iovlen = 1; /* I don't see why this circular buffer stuff is necessary for SCTP * which is a packet-based protocol, but the whole thing breaks under @@ -549,7 +548,7 @@ static int receive_from_sock(void) } len = iov[0].iov_len + iov[1].iov_len; - r = ret = kernel_recvmsg(sctp_con.sock, &msg, iov, msg.msg_iovlen, len, + r = ret = kernel_recvmsg(sctp_con.sock, &msg, iov, 1, len, MSG_NOSIGNAL | MSG_DONTWAIT); if (ret <= 0) goto out_close; @@ -727,7 +726,7 @@ static int init_sock(void) } -static struct writequeue_entry *new_writequeue_entry(gfp_t allocation) +static struct writequeue_entry *new_writequeue_entry(int allocation) { struct writequeue_entry *entry; @@ -749,7 +748,7 @@ static struct writequeue_entry *new_writequeue_entry(gfp_t allocation) return entry; } -void *dlm_lowcomms_get_buffer(int nodeid, int len, gfp_t allocation, char **ppc) +void *dlm_lowcomms_get_buffer(int nodeid, int len, int allocation, char **ppc) { struct writequeue_entry *e; int offset = 0; diff --git a/trunk/fs/dlm/lowcomms.h b/trunk/fs/dlm/lowcomms.h index 2d045e0daae1..6c04bb09cfa8 100644 --- a/trunk/fs/dlm/lowcomms.h +++ b/trunk/fs/dlm/lowcomms.h @@ -19,7 +19,7 @@ void dlm_lowcomms_exit(void); int dlm_lowcomms_start(void); void dlm_lowcomms_stop(void); int dlm_lowcomms_close(int nodeid); -void *dlm_lowcomms_get_buffer(int nodeid, int len, gfp_t allocation, char **ppc); +void *dlm_lowcomms_get_buffer(int nodeid, int len, int allocation, char **ppc); void dlm_lowcomms_commit_buffer(void *mh); #endif /* __LOWCOMMS_DOT_H__ */ diff --git a/trunk/fs/ecryptfs/crypto.c b/trunk/fs/ecryptfs/crypto.c index f63a7755fe86..ed35a9712fa1 100644 --- a/trunk/fs/ecryptfs/crypto.c +++ b/trunk/fs/ecryptfs/crypto.c @@ -94,53 +94,25 @@ static int ecryptfs_calculate_md5(char *dst, struct ecryptfs_crypt_stat *crypt_stat, char *src, int len) { - struct scatterlist sg; - struct hash_desc desc = { - .tfm = crypt_stat->hash_tfm, - .flags = CRYPTO_TFM_REQ_MAY_SLEEP - }; int rc = 0; + struct scatterlist sg; - mutex_lock(&crypt_stat->cs_hash_tfm_mutex); + mutex_lock(&crypt_stat->cs_md5_tfm_mutex); sg_init_one(&sg, (u8 *)src, len); - if (!desc.tfm) { - desc.tfm = crypto_alloc_hash(ECRYPTFS_DEFAULT_HASH, 0, - CRYPTO_ALG_ASYNC); - if (IS_ERR(desc.tfm)) { - rc = PTR_ERR(desc.tfm); + if (!crypt_stat->md5_tfm) { + crypt_stat->md5_tfm = + crypto_alloc_tfm("md5", CRYPTO_TFM_REQ_MAY_SLEEP); + if (!crypt_stat->md5_tfm) { + rc = -ENOMEM; ecryptfs_printk(KERN_ERR, "Error attempting to " - "allocate crypto context; rc = [%d]\n", - rc); + "allocate crypto context\n"); goto out; } - crypt_stat->hash_tfm = desc.tfm; } - crypto_hash_init(&desc); - crypto_hash_update(&desc, &sg, len); - crypto_hash_final(&desc, dst); - mutex_unlock(&crypt_stat->cs_hash_tfm_mutex); -out: - return rc; -} - -int ecryptfs_crypto_api_algify_cipher_name(char **algified_name, - char *cipher_name, - char *chaining_modifier) -{ - int cipher_name_len = strlen(cipher_name); - int chaining_modifier_len = strlen(chaining_modifier); - int algified_name_len; - int rc; - - algified_name_len = (chaining_modifier_len + cipher_name_len + 3); - (*algified_name) = kmalloc(algified_name_len, GFP_KERNEL); - if (!(*algified_name)) { - rc = -ENOMEM; - goto out; - } - snprintf((*algified_name), algified_name_len, "%s(%s)", - chaining_modifier, cipher_name); - rc = 0; + crypto_digest_init(crypt_stat->md5_tfm); + crypto_digest_update(crypt_stat->md5_tfm, &sg, 1); + crypto_digest_final(crypt_stat->md5_tfm, dst); + mutex_unlock(&crypt_stat->cs_md5_tfm_mutex); out: return rc; } @@ -206,7 +178,7 @@ ecryptfs_init_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat) memset((void *)crypt_stat, 0, sizeof(struct ecryptfs_crypt_stat)); mutex_init(&crypt_stat->cs_mutex); mutex_init(&crypt_stat->cs_tfm_mutex); - mutex_init(&crypt_stat->cs_hash_tfm_mutex); + mutex_init(&crypt_stat->cs_md5_tfm_mutex); ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_STRUCT_INITIALIZED); } @@ -219,9 +191,9 @@ ecryptfs_init_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat) void ecryptfs_destruct_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat) { if (crypt_stat->tfm) - crypto_free_blkcipher(crypt_stat->tfm); - if (crypt_stat->hash_tfm) - crypto_free_hash(crypt_stat->hash_tfm); + crypto_free_tfm(crypt_stat->tfm); + if (crypt_stat->md5_tfm) + crypto_free_tfm(crypt_stat->md5_tfm); memset(crypt_stat, 0, sizeof(struct ecryptfs_crypt_stat)); } @@ -231,7 +203,7 @@ void ecryptfs_destruct_mount_crypt_stat( if (mount_crypt_stat->global_auth_tok_key) key_put(mount_crypt_stat->global_auth_tok_key); if (mount_crypt_stat->global_key_tfm) - crypto_free_blkcipher(mount_crypt_stat->global_key_tfm); + crypto_free_tfm(mount_crypt_stat->global_key_tfm); memset(mount_crypt_stat, 0, sizeof(struct ecryptfs_mount_crypt_stat)); } @@ -297,11 +269,6 @@ static int encrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat, struct scatterlist *src_sg, int size, unsigned char *iv) { - struct blkcipher_desc desc = { - .tfm = crypt_stat->tfm, - .info = iv, - .flags = CRYPTO_TFM_REQ_MAY_SLEEP - }; int rc = 0; BUG_ON(!crypt_stat || !crypt_stat->tfm @@ -315,8 +282,8 @@ static int encrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat, } /* Consider doing this once, when the file is opened */ mutex_lock(&crypt_stat->cs_tfm_mutex); - rc = crypto_blkcipher_setkey(crypt_stat->tfm, crypt_stat->key, - crypt_stat->key_size); + rc = crypto_cipher_setkey(crypt_stat->tfm, crypt_stat->key, + crypt_stat->key_size); if (rc) { ecryptfs_printk(KERN_ERR, "Error setting key; rc = [%d]\n", rc); @@ -325,7 +292,7 @@ static int encrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat, goto out; } ecryptfs_printk(KERN_DEBUG, "Encrypting [%d] bytes.\n", size); - crypto_blkcipher_encrypt_iv(&desc, dest_sg, src_sg, size); + crypto_cipher_encrypt_iv(crypt_stat->tfm, dest_sg, src_sg, size, iv); mutex_unlock(&crypt_stat->cs_tfm_mutex); out: return rc; @@ -708,17 +675,12 @@ static int decrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat, struct scatterlist *src_sg, int size, unsigned char *iv) { - struct blkcipher_desc desc = { - .tfm = crypt_stat->tfm, - .info = iv, - .flags = CRYPTO_TFM_REQ_MAY_SLEEP - }; int rc = 0; /* Consider doing this once, when the file is opened */ mutex_lock(&crypt_stat->cs_tfm_mutex); - rc = crypto_blkcipher_setkey(crypt_stat->tfm, crypt_stat->key, - crypt_stat->key_size); + rc = crypto_cipher_setkey(crypt_stat->tfm, crypt_stat->key, + crypt_stat->key_size); if (rc) { ecryptfs_printk(KERN_ERR, "Error setting key; rc = [%d]\n", rc); @@ -727,7 +689,8 @@ static int decrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat, goto out; } ecryptfs_printk(KERN_DEBUG, "Decrypting [%d] bytes.\n", size); - rc = crypto_blkcipher_decrypt_iv(&desc, dest_sg, src_sg, size); + rc = crypto_cipher_decrypt_iv(crypt_stat->tfm, dest_sg, src_sg, size, + iv); mutex_unlock(&crypt_stat->cs_tfm_mutex); if (rc) { ecryptfs_printk(KERN_ERR, "Error decrypting; rc = [%d]\n", @@ -796,7 +759,6 @@ ecryptfs_decrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat, */ int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat) { - char *full_alg_name; int rc = -EINVAL; if (!crypt_stat->cipher) { @@ -813,25 +775,16 @@ int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat) goto out; } mutex_lock(&crypt_stat->cs_tfm_mutex); - rc = ecryptfs_crypto_api_algify_cipher_name(&full_alg_name, - crypt_stat->cipher, "cbc"); - if (rc) - goto out; - crypt_stat->tfm = crypto_alloc_blkcipher(full_alg_name, 0, - CRYPTO_ALG_ASYNC); - kfree(full_alg_name); - if (IS_ERR(crypt_stat->tfm)) { - rc = PTR_ERR(crypt_stat->tfm); + crypt_stat->tfm = crypto_alloc_tfm(crypt_stat->cipher, + ECRYPTFS_DEFAULT_CHAINING_MODE + | CRYPTO_TFM_REQ_WEAK_KEY); + mutex_unlock(&crypt_stat->cs_tfm_mutex); + if (!crypt_stat->tfm) { ecryptfs_printk(KERN_ERR, "cryptfs: init_crypt_ctx(): " "Error initializing cipher [%s]\n", crypt_stat->cipher); - mutex_unlock(&crypt_stat->cs_tfm_mutex); goto out; } - crypto_blkcipher_set_flags(crypt_stat->tfm, - (ECRYPTFS_DEFAULT_CHAINING_MODE - | CRYPTO_TFM_REQ_WEAK_KEY)); - mutex_unlock(&crypt_stat->cs_tfm_mutex); rc = 0; out: return rc; @@ -1192,28 +1145,28 @@ int ecryptfs_cipher_code_to_string(char *str, u16 cipher_code) int ecryptfs_read_header_region(char *data, struct dentry *dentry, struct vfsmount *mnt) { - struct file *lower_file; + struct file *file; mm_segment_t oldfs; int rc; - if ((rc = ecryptfs_open_lower_file(&lower_file, dentry, mnt, - O_RDONLY))) { - printk(KERN_ERR - "Error opening lower_file to read header region\n"); + mnt = mntget(mnt); + file = dentry_open(dentry, mnt, O_RDONLY); + if (IS_ERR(file)) { + ecryptfs_printk(KERN_DEBUG, "Error opening file to " + "read header region\n"); + mntput(mnt); + rc = PTR_ERR(file); goto out; } - lower_file->f_pos = 0; + file->f_pos = 0; oldfs = get_fs(); set_fs(get_ds()); /* For releases 0.1 and 0.2, all of the header information * fits in the first data extent-sized region. */ - rc = lower_file->f_op->read(lower_file, (char __user *)data, - ECRYPTFS_DEFAULT_EXTENT_SIZE, &lower_file->f_pos); + rc = file->f_op->read(file, (char __user *)data, + ECRYPTFS_DEFAULT_EXTENT_SIZE, &file->f_pos); set_fs(oldfs); - if ((rc = ecryptfs_close_lower_file(lower_file))) { - printk(KERN_ERR "Error closing lower_file\n"); - goto out; - } + fput(file); rc = 0; out: return rc; @@ -1620,52 +1573,84 @@ ecryptfs_decode_filename(struct ecryptfs_crypt_stat *crypt_stat, /** * ecryptfs_process_cipher - Perform cipher initialization. + * @tfm: Crypto context set by this function * @key_tfm: Crypto context for key material, set by this function - * @cipher_name: Name of the cipher - * @key_size: Size of the key in bytes + * @cipher_name: Name of the cipher. + * @key_size: Size of the key in bytes. * * Returns zero on success. Any crypto_tfm structs allocated here * should be released by other functions, such as on a superblock put * event, regardless of whether this function succeeds for fails. */ int -ecryptfs_process_cipher(struct crypto_blkcipher **key_tfm, char *cipher_name, - size_t *key_size) +ecryptfs_process_cipher(struct crypto_tfm **tfm, struct crypto_tfm **key_tfm, + char *cipher_name, size_t key_size) { char dummy_key[ECRYPTFS_MAX_KEY_BYTES]; - char *full_alg_name; int rc; - *key_tfm = NULL; - if (*key_size > ECRYPTFS_MAX_KEY_BYTES) { + *tfm = *key_tfm = NULL; + if (key_size > ECRYPTFS_MAX_KEY_BYTES) { rc = -EINVAL; printk(KERN_ERR "Requested key size is [%Zd] bytes; maximum " - "allowable is [%d]\n", *key_size, ECRYPTFS_MAX_KEY_BYTES); + "allowable is [%d]\n", key_size, ECRYPTFS_MAX_KEY_BYTES); goto out; } - rc = ecryptfs_crypto_api_algify_cipher_name(&full_alg_name, cipher_name, - "ecb"); - if (rc) + *tfm = crypto_alloc_tfm(cipher_name, (ECRYPTFS_DEFAULT_CHAINING_MODE + | CRYPTO_TFM_REQ_WEAK_KEY)); + if (!(*tfm)) { + rc = -EINVAL; + printk(KERN_ERR "Unable to allocate crypto cipher with name " + "[%s]\n", cipher_name); goto out; - *key_tfm = crypto_alloc_blkcipher(full_alg_name, 0, CRYPTO_ALG_ASYNC); - kfree(full_alg_name); - if (IS_ERR(*key_tfm)) { - rc = PTR_ERR(*key_tfm); + } + *key_tfm = crypto_alloc_tfm(cipher_name, CRYPTO_TFM_REQ_WEAK_KEY); + if (!(*key_tfm)) { + rc = -EINVAL; printk(KERN_ERR "Unable to allocate crypto cipher with name " - "[%s]; rc = [%d]\n", cipher_name, rc); + "[%s]\n", cipher_name); goto out; } - crypto_blkcipher_set_flags(*key_tfm, CRYPTO_TFM_REQ_WEAK_KEY); - if (*key_size == 0) { - struct blkcipher_alg *alg = crypto_blkcipher_alg(*key_tfm); - - *key_size = alg->max_keysize; + if (key_size < crypto_tfm_alg_min_keysize(*tfm)) { + rc = -EINVAL; + printk(KERN_ERR "Request key size is [%Zd]; minimum key size " + "supported by cipher [%s] is [%d]\n", key_size, + cipher_name, crypto_tfm_alg_min_keysize(*tfm)); + goto out; + } + if (key_size < crypto_tfm_alg_min_keysize(*key_tfm)) { + rc = -EINVAL; + printk(KERN_ERR "Request key size is [%Zd]; minimum key size " + "supported by cipher [%s] is [%d]\n", key_size, + cipher_name, crypto_tfm_alg_min_keysize(*key_tfm)); + goto out; + } + if (key_size > crypto_tfm_alg_max_keysize(*tfm)) { + rc = -EINVAL; + printk(KERN_ERR "Request key size is [%Zd]; maximum key size " + "supported by cipher [%s] is [%d]\n", key_size, + cipher_name, crypto_tfm_alg_min_keysize(*tfm)); + goto out; + } + if (key_size > crypto_tfm_alg_max_keysize(*key_tfm)) { + rc = -EINVAL; + printk(KERN_ERR "Request key size is [%Zd]; maximum key size " + "supported by cipher [%s] is [%d]\n", key_size, + cipher_name, crypto_tfm_alg_min_keysize(*key_tfm)); + goto out; + } + get_random_bytes(dummy_key, key_size); + rc = crypto_cipher_setkey(*tfm, dummy_key, key_size); + if (rc) { + printk(KERN_ERR "Error attempting to set key of size [%Zd] for " + "cipher [%s]; rc = [%d]\n", key_size, cipher_name, rc); + rc = -EINVAL; + goto out; } - get_random_bytes(dummy_key, *key_size); - rc = crypto_blkcipher_setkey(*key_tfm, dummy_key, *key_size); + rc = crypto_cipher_setkey(*key_tfm, dummy_key, key_size); if (rc) { printk(KERN_ERR "Error attempting to set key of size [%Zd] for " - "cipher [%s]; rc = [%d]\n", *key_size, cipher_name, rc); + "cipher [%s]; rc = [%d]\n", key_size, cipher_name, rc); rc = -EINVAL; goto out; } diff --git a/trunk/fs/ecryptfs/dentry.c b/trunk/fs/ecryptfs/dentry.c index 52d1e36dc746..f0d2a433242b 100644 --- a/trunk/fs/ecryptfs/dentry.c +++ b/trunk/fs/ecryptfs/dentry.c @@ -24,7 +24,6 @@ #include #include -#include #include "ecryptfs_kernel.h" /** @@ -57,12 +56,6 @@ static int ecryptfs_d_revalidate(struct dentry *dentry, struct nameidata *nd) rc = lower_dentry->d_op->d_revalidate(lower_dentry, nd); nd->dentry = dentry_save; nd->mnt = vfsmount_save; - if (dentry->d_inode) { - struct inode *lower_inode = - ecryptfs_inode_to_lower(dentry->d_inode); - - ecryptfs_copy_attr_all(dentry->d_inode, lower_inode); - } out: return rc; } @@ -83,13 +76,8 @@ static void ecryptfs_d_release(struct dentry *dentry) if (ecryptfs_dentry_to_private(dentry)) kmem_cache_free(ecryptfs_dentry_info_cache, ecryptfs_dentry_to_private(dentry)); - if (lower_dentry) { - struct vfsmount *lower_mnt = - ecryptfs_dentry_to_lower_mnt(dentry); - - mntput(lower_mnt); + if (lower_dentry) dput(lower_dentry); - } return; } diff --git a/trunk/fs/ecryptfs/ecryptfs_kernel.h b/trunk/fs/ecryptfs/ecryptfs_kernel.h index f992533d1692..872c9958531a 100644 --- a/trunk/fs/ecryptfs/ecryptfs_kernel.h +++ b/trunk/fs/ecryptfs/ecryptfs_kernel.h @@ -175,7 +175,6 @@ ecryptfs_get_key_payload_data(struct key *key) #define ECRYPTFS_DEFAULT_CIPHER "aes" #define ECRYPTFS_DEFAULT_KEY_BYTES 16 #define ECRYPTFS_DEFAULT_CHAINING_MODE CRYPTO_TFM_MODE_CBC -#define ECRYPTFS_DEFAULT_HASH "md5" #define ECRYPTFS_TAG_3_PACKET_TYPE 0x8C #define ECRYPTFS_TAG_11_PACKET_TYPE 0xED #define MD5_DIGEST_SIZE 16 @@ -205,15 +204,15 @@ struct ecryptfs_crypt_stat { size_t extent_shift; unsigned int extent_mask; struct ecryptfs_mount_crypt_stat *mount_crypt_stat; - struct crypto_blkcipher *tfm; - struct crypto_hash *hash_tfm; /* Crypto context for generating - * the initialization vectors */ + struct crypto_tfm *tfm; + struct crypto_tfm *md5_tfm; /* Crypto context for generating + * the initialization vectors */ unsigned char cipher[ECRYPTFS_MAX_CIPHER_NAME_SIZE]; unsigned char key[ECRYPTFS_MAX_KEY_BYTES]; unsigned char root_iv[ECRYPTFS_MAX_IV_BYTES]; unsigned char keysigs[ECRYPTFS_MAX_NUM_KEYSIGS][ECRYPTFS_SIG_SIZE_HEX]; struct mutex cs_tfm_mutex; - struct mutex cs_hash_tfm_mutex; + struct mutex cs_md5_tfm_mutex; struct mutex cs_mutex; }; @@ -245,7 +244,7 @@ struct ecryptfs_mount_crypt_stat { struct ecryptfs_auth_tok *global_auth_tok; struct key *global_auth_tok_key; size_t global_default_cipher_key_size; - struct crypto_blkcipher *global_key_tfm; + struct crypto_tfm *global_key_tfm; struct mutex global_key_tfm_mutex; unsigned char global_default_cipher_name[ECRYPTFS_MAX_CIPHER_NAME_SIZE + 1]; @@ -426,9 +425,6 @@ void ecryptfs_destruct_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat); void ecryptfs_destruct_mount_crypt_stat( struct ecryptfs_mount_crypt_stat *mount_crypt_stat); int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat); -int ecryptfs_crypto_api_algify_cipher_name(char **algified_name, - char *cipher_name, - char *chaining_modifier); int ecryptfs_write_inode_size_to_header(struct file *lower_file, struct inode *lower_inode, struct inode *inode); @@ -477,14 +473,10 @@ ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat, unsigned char *src, struct dentry *ecryptfs_dentry); int ecryptfs_truncate(struct dentry *dentry, loff_t new_length); int -ecryptfs_process_cipher(struct crypto_blkcipher **key_tfm, char *cipher_name, - size_t *key_size); +ecryptfs_process_cipher(struct crypto_tfm **tfm, struct crypto_tfm **key_tfm, + char *cipher_name, size_t key_size); int ecryptfs_inode_test(struct inode *inode, void *candidate_lower_inode); int ecryptfs_inode_set(struct inode *inode, void *lower_inode); void ecryptfs_init_inode(struct inode *inode, struct inode *lower_inode); -int ecryptfs_open_lower_file(struct file **lower_file, - struct dentry *lower_dentry, - struct vfsmount *lower_mnt, int flags); -int ecryptfs_close_lower_file(struct file *lower_file); #endif /* #ifndef ECRYPTFS_KERNEL_H */ diff --git a/trunk/fs/ecryptfs/file.c b/trunk/fs/ecryptfs/file.c index a92ef05eff8f..c8550c9f9cd2 100644 --- a/trunk/fs/ecryptfs/file.c +++ b/trunk/fs/ecryptfs/file.c @@ -198,33 +198,6 @@ static int ecryptfs_readdir(struct file *file, void *dirent, filldir_t filldir) struct kmem_cache *ecryptfs_file_info_cache; -int ecryptfs_open_lower_file(struct file **lower_file, - struct dentry *lower_dentry, - struct vfsmount *lower_mnt, int flags) -{ - int rc = 0; - - dget(lower_dentry); - mntget(lower_mnt); - *lower_file = dentry_open(lower_dentry, lower_mnt, flags); - if (IS_ERR(*lower_file)) { - printk(KERN_ERR "Error opening lower file for lower_dentry " - "[0x%p], lower_mnt [0x%p], and flags [0x%x]\n", - lower_dentry, lower_mnt, flags); - rc = PTR_ERR(*lower_file); - *lower_file = NULL; - goto out; - } -out: - return rc; -} - -int ecryptfs_close_lower_file(struct file *lower_file) -{ - fput(lower_file); - return 0; -} - /** * ecryptfs_open * @inode: inode speciying file to open @@ -271,15 +244,19 @@ static int ecryptfs_open(struct inode *inode, struct file *file) ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED); } mutex_unlock(&crypt_stat->cs_mutex); + /* This mntget & dget is undone via fput when the file is released */ + dget(lower_dentry); lower_flags = file->f_flags; if ((lower_flags & O_ACCMODE) == O_WRONLY) lower_flags = (lower_flags & O_ACCMODE) | O_RDWR; if (file->f_flags & O_APPEND) lower_flags &= ~O_APPEND; lower_mnt = ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry); + mntget(lower_mnt); /* Corresponding fput() in ecryptfs_release() */ - if ((rc = ecryptfs_open_lower_file(&lower_file, lower_dentry, lower_mnt, - lower_flags))) { + lower_file = dentry_open(lower_dentry, lower_mnt, lower_flags); + if (IS_ERR(lower_file)) { + rc = PTR_ERR(lower_file); ecryptfs_printk(KERN_ERR, "Error opening lower file\n"); goto out_puts; } @@ -364,16 +341,11 @@ static int ecryptfs_release(struct inode *inode, struct file *file) struct file *lower_file = ecryptfs_file_to_lower(file); struct ecryptfs_file_info *file_info = ecryptfs_file_to_private(file); struct inode *lower_inode = ecryptfs_inode_to_lower(inode); - int rc; - if ((rc = ecryptfs_close_lower_file(lower_file))) { - printk(KERN_ERR "Error closing lower_file\n"); - goto out; - } + fput(lower_file); inode->i_blocks = lower_inode->i_blocks; kmem_cache_free(ecryptfs_file_info_cache, file_info); -out: - return rc; + return 0; } static int diff --git a/trunk/fs/ecryptfs/inode.c b/trunk/fs/ecryptfs/inode.c index dfcc68484f47..efdd2b7b62d7 100644 --- a/trunk/fs/ecryptfs/inode.c +++ b/trunk/fs/ecryptfs/inode.c @@ -231,6 +231,7 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry) int lower_flags; struct ecryptfs_crypt_stat *crypt_stat; struct dentry *lower_dentry; + struct dentry *tlower_dentry = NULL; struct file *lower_file; struct inode *inode, *lower_inode; struct vfsmount *lower_mnt; @@ -240,19 +241,30 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry) lower_dentry->d_name.name); inode = ecryptfs_dentry->d_inode; crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat; + tlower_dentry = dget(lower_dentry); + if (!tlower_dentry) { + rc = -ENOMEM; + ecryptfs_printk(KERN_ERR, "Error dget'ing lower_dentry\n"); + goto out; + } lower_flags = ((O_CREAT | O_WRONLY | O_TRUNC) & O_ACCMODE) | O_RDWR; #if BITS_PER_LONG != 32 lower_flags |= O_LARGEFILE; #endif lower_mnt = ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry); + mntget(lower_mnt); /* Corresponding fput() at end of this function */ - if ((rc = ecryptfs_open_lower_file(&lower_file, lower_dentry, lower_mnt, - lower_flags))) { + lower_file = dentry_open(tlower_dentry, lower_mnt, lower_flags); + if (IS_ERR(lower_file)) { + rc = PTR_ERR(lower_file); ecryptfs_printk(KERN_ERR, "Error opening dentry; rc = [%i]\n", rc); goto out; } - lower_inode = lower_dentry->d_inode; + /* fput(lower_file) should handle the puts if we do this */ + lower_file->f_dentry = tlower_dentry; + lower_file->f_vfsmnt = lower_mnt; + lower_inode = tlower_dentry->d_inode; if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) { ecryptfs_printk(KERN_DEBUG, "This is a directory\n"); ECRYPTFS_CLEAR_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED); @@ -273,8 +285,7 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry) } rc = grow_file(ecryptfs_dentry, lower_file, inode, lower_inode); out_fput: - if ((rc = ecryptfs_close_lower_file(lower_file))) - printk(KERN_ERR "Error closing lower_file\n"); + fput(lower_file); out: return rc; } @@ -325,6 +336,7 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry, struct dentry *lower_dir_dentry; struct dentry *lower_dentry; struct vfsmount *lower_mnt; + struct dentry *tlower_dentry = NULL; char *encoded_name; unsigned int encoded_namelen; struct ecryptfs_crypt_stat *crypt_stat = NULL; @@ -335,32 +347,27 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry, lower_dir_dentry = ecryptfs_dentry_to_lower(dentry->d_parent); dentry->d_op = &ecryptfs_dops; if ((dentry->d_name.len == 1 && !strcmp(dentry->d_name.name, ".")) - || (dentry->d_name.len == 2 - && !strcmp(dentry->d_name.name, ".."))) { - d_drop(dentry); - goto out; - } + || (dentry->d_name.len == 2 && !strcmp(dentry->d_name.name, ".."))) + goto out_drop; encoded_namelen = ecryptfs_encode_filename(crypt_stat, dentry->d_name.name, dentry->d_name.len, &encoded_name); if (encoded_namelen < 0) { rc = encoded_namelen; - d_drop(dentry); - goto out; + goto out_drop; } ecryptfs_printk(KERN_DEBUG, "encoded_name = [%s]; encoded_namelen " "= [%d]\n", encoded_name, encoded_namelen); lower_dentry = lookup_one_len(encoded_name, lower_dir_dentry, encoded_namelen - 1); kfree(encoded_name); + lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt(dentry->d_parent)); if (IS_ERR(lower_dentry)) { ecryptfs_printk(KERN_ERR, "ERR from lower_dentry\n"); rc = PTR_ERR(lower_dentry); - d_drop(dentry); - goto out; + goto out_drop; } - lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt(dentry->d_parent)); ecryptfs_printk(KERN_DEBUG, "lower_dentry = [%p]; lower_dentry->" "d_name.name = [%s]\n", lower_dentry, lower_dentry->d_name.name); @@ -401,6 +408,12 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry, "as we *think* we are about to unlink\n"); goto out; } + tlower_dentry = dget(lower_dentry); + if (!tlower_dentry || IS_ERR(tlower_dentry)) { + rc = -ENOMEM; + ecryptfs_printk(KERN_ERR, "Cannot dget lower_dentry\n"); + goto out_dput; + } /* Released in this function */ page_virt = (char *)kmem_cache_alloc(ecryptfs_header_cache_2, @@ -412,7 +425,7 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry, goto out_dput; } memset(page_virt, 0, PAGE_CACHE_SIZE); - rc = ecryptfs_read_header_region(page_virt, lower_dentry, nd->mnt); + rc = ecryptfs_read_header_region(page_virt, tlower_dentry, nd->mnt); crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_POLICY_APPLIED)) ecryptfs_set_default_sizes(crypt_stat); @@ -435,6 +448,9 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry, out_dput: dput(lower_dentry); + if (tlower_dentry) + dput(tlower_dentry); +out_drop: d_drop(dentry); out: return ERR_PTR(rc); @@ -470,9 +486,8 @@ static int ecryptfs_link(struct dentry *old_dentry, struct inode *dir, unlock_dir(lower_dir_dentry); dput(lower_new_dentry); dput(lower_old_dentry); - d_drop(lower_old_dentry); - d_drop(new_dentry); - d_drop(old_dentry); + if (!new_dentry->d_inode) + d_drop(new_dentry); return rc; } @@ -485,7 +500,7 @@ static int ecryptfs_unlink(struct inode *dir, struct dentry *dentry) lock_parent(lower_dentry); rc = vfs_unlink(lower_dir_inode, lower_dentry); if (rc) { - printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc); + ecryptfs_printk(KERN_ERR, "Error in vfs_unlink\n"); goto out_unlock; } ecryptfs_copy_attr_times(dir, lower_dir_inode); @@ -561,24 +576,41 @@ static int ecryptfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry) { + int rc = 0; + struct dentry *tdentry = NULL; struct dentry *lower_dentry; + struct dentry *tlower_dentry = NULL; struct dentry *lower_dir_dentry; - int rc; lower_dentry = ecryptfs_dentry_to_lower(dentry); - dget(dentry); + if (!(tdentry = dget(dentry))) { + rc = -EINVAL; + ecryptfs_printk(KERN_ERR, "Error dget'ing dentry [%p]\n", + dentry); + goto out; + } lower_dir_dentry = lock_parent(lower_dentry); - dget(lower_dentry); + if (!(tlower_dentry = dget(lower_dentry))) { + rc = -EINVAL; + ecryptfs_printk(KERN_ERR, "Error dget'ing lower_dentry " + "[%p]\n", lower_dentry); + goto out; + } rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry); - dput(lower_dentry); - if (!rc) - d_delete(lower_dentry); + if (!rc) { + d_delete(tlower_dentry); + tlower_dentry = NULL; + } ecryptfs_copy_attr_times(dir, lower_dir_dentry->d_inode); dir->i_nlink = lower_dir_dentry->d_inode->i_nlink; unlock_dir(lower_dir_dentry); if (!rc) d_drop(dentry); - dput(dentry); +out: + if (tdentry) + dput(tdentry); + if (tlower_dentry) + dput(tlower_dentry); return rc; } @@ -631,8 +663,6 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry, ecryptfs_copy_attr_all(old_dir, lower_old_dir_dentry->d_inode); out_lock: unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry); - dput(lower_new_dentry->d_parent); - dput(lower_old_dentry->d_parent); dput(lower_new_dentry); dput(lower_old_dentry); return rc; @@ -802,11 +832,12 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length) } lower_dentry = ecryptfs_dentry_to_lower(dentry); /* This dget & mntget is released through fput at out_fput: */ + dget(lower_dentry); lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); - if ((rc = ecryptfs_open_lower_file(&lower_file, lower_dentry, lower_mnt, - O_RDWR))) { - ecryptfs_printk(KERN_ERR, - "Error opening dentry; rc = [%i]\n", rc); + mntget(lower_mnt); + lower_file = dentry_open(lower_dentry, lower_mnt, O_RDWR); + if (unlikely(IS_ERR(lower_file))) { + rc = PTR_ERR(lower_file); goto out_free; } ecryptfs_set_file_lower(&fake_ecryptfs_file, lower_file); @@ -848,8 +879,7 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length) = CURRENT_TIME; mark_inode_dirty_sync(inode); out_fput: - if ((rc = ecryptfs_close_lower_file(lower_file))) - printk(KERN_ERR "Error closing lower_file\n"); + fput(lower_file); out_free: if (ecryptfs_file_to_private(&fake_ecryptfs_file)) kmem_cache_free(ecryptfs_file_info_cache, diff --git a/trunk/fs/ecryptfs/keystore.c b/trunk/fs/ecryptfs/keystore.c index c3746f56d162..ba454785a0c5 100644 --- a/trunk/fs/ecryptfs/keystore.c +++ b/trunk/fs/ecryptfs/keystore.c @@ -458,16 +458,14 @@ parse_tag_11_packet(unsigned char *data, unsigned char *contents, static int decrypt_session_key(struct ecryptfs_auth_tok *auth_tok, struct ecryptfs_crypt_stat *crypt_stat) { + int rc = 0; struct ecryptfs_password *password_s_ptr; + struct crypto_tfm *tfm = NULL; struct scatterlist src_sg[2], dst_sg[2]; struct mutex *tfm_mutex = NULL; /* TODO: Use virt_to_scatterlist for these */ char *encrypted_session_key; char *session_key; - struct blkcipher_desc desc = { - .flags = CRYPTO_TFM_REQ_MAY_SLEEP - }; - int rc = 0; password_s_ptr = &auth_tok->token.password; if (ECRYPTFS_CHECK_FLAG(password_s_ptr->flags, @@ -484,37 +482,30 @@ static int decrypt_session_key(struct ecryptfs_auth_tok *auth_tok, if (!strcmp(crypt_stat->cipher, crypt_stat->mount_crypt_stat->global_default_cipher_name) && crypt_stat->mount_crypt_stat->global_key_tfm) { - desc.tfm = crypt_stat->mount_crypt_stat->global_key_tfm; + tfm = crypt_stat->mount_crypt_stat->global_key_tfm; tfm_mutex = &crypt_stat->mount_crypt_stat->global_key_tfm_mutex; } else { - char *full_alg_name; - - rc = ecryptfs_crypto_api_algify_cipher_name(&full_alg_name, - crypt_stat->cipher, - "ecb"); - if (rc) - goto out; - desc.tfm = crypto_alloc_blkcipher(full_alg_name, 0, - CRYPTO_ALG_ASYNC); - kfree(full_alg_name); - if (IS_ERR(desc.tfm)) { - rc = PTR_ERR(desc.tfm); - printk(KERN_ERR "Error allocating crypto context; " - "rc = [%d]\n", rc); + tfm = crypto_alloc_tfm(crypt_stat->cipher, + CRYPTO_TFM_REQ_WEAK_KEY); + if (!tfm) { + printk(KERN_ERR "Error allocating crypto context\n"); + rc = -ENOMEM; goto out; } - crypto_blkcipher_set_flags(desc.tfm, CRYPTO_TFM_REQ_WEAK_KEY); } - if (tfm_mutex) - mutex_lock(tfm_mutex); - rc = crypto_blkcipher_setkey(desc.tfm, - password_s_ptr->session_key_encryption_key, - crypt_stat->key_size); - if (rc < 0) { - printk(KERN_ERR "Error setting key for crypto context\n"); + if (password_s_ptr->session_key_encryption_key_bytes + < crypto_tfm_alg_min_keysize(tfm)) { + printk(KERN_WARNING "Session key encryption key is [%d] bytes; " + "minimum keysize for selected cipher is [%d] bytes.\n", + password_s_ptr->session_key_encryption_key_bytes, + crypto_tfm_alg_min_keysize(tfm)); rc = -EINVAL; - goto out_free_tfm; + goto out; } + if (tfm_mutex) + mutex_lock(tfm_mutex); + crypto_cipher_setkey(tfm, password_s_ptr->session_key_encryption_key, + crypt_stat->key_size); /* TODO: virt_to_scatterlist */ encrypted_session_key = (char *)__get_free_page(GFP_KERNEL); if (!encrypted_session_key) { @@ -540,12 +531,9 @@ static int decrypt_session_key(struct ecryptfs_auth_tok *auth_tok, auth_tok->session_key.decrypted_key_size = auth_tok->session_key.encrypted_key_size; dst_sg[0].length = auth_tok->session_key.encrypted_key_size; - rc = crypto_blkcipher_decrypt(&desc, dst_sg, src_sg, - auth_tok->session_key.encrypted_key_size); - if (rc) { - printk(KERN_ERR "Error decrypting; rc = [%d]\n", rc); - goto out_free_memory; - } + /* TODO: Handle error condition */ + crypto_cipher_decrypt(tfm, dst_sg, src_sg, + auth_tok->session_key.encrypted_key_size); auth_tok->session_key.decrypted_key_size = auth_tok->session_key.encrypted_key_size; memcpy(auth_tok->session_key.decrypted_key, session_key, @@ -558,7 +546,6 @@ static int decrypt_session_key(struct ecryptfs_auth_tok *auth_tok, if (ecryptfs_verbosity > 0) ecryptfs_dump_hex(crypt_stat->key, crypt_stat->key_size); -out_free_memory: memset(encrypted_session_key, 0, PAGE_CACHE_SIZE); free_page((unsigned long)encrypted_session_key); memset(session_key, 0, PAGE_CACHE_SIZE); @@ -567,7 +554,7 @@ static int decrypt_session_key(struct ecryptfs_auth_tok *auth_tok, if (tfm_mutex) mutex_unlock(tfm_mutex); else - crypto_free_blkcipher(desc.tfm); + crypto_free_tfm(tfm); out: return rc; } @@ -816,21 +803,19 @@ write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok, struct ecryptfs_crypt_stat *crypt_stat, struct ecryptfs_key_record *key_rec, size_t *packet_size) { + int rc = 0; + size_t i; size_t signature_is_valid = 0; size_t encrypted_session_key_valid = 0; char session_key_encryption_key[ECRYPTFS_MAX_KEY_BYTES]; struct scatterlist dest_sg[2]; struct scatterlist src_sg[2]; + struct crypto_tfm *tfm = NULL; struct mutex *tfm_mutex = NULL; size_t key_rec_size; size_t packet_size_length; size_t cipher_code; - struct blkcipher_desc desc = { - .tfm = NULL, - .flags = CRYPTO_TFM_REQ_MAY_SLEEP - }; - int rc = 0; (*packet_size) = 0; /* Check for a valid signature on the auth_tok */ @@ -897,48 +882,33 @@ write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok, if (!strcmp(crypt_stat->cipher, crypt_stat->mount_crypt_stat->global_default_cipher_name) && crypt_stat->mount_crypt_stat->global_key_tfm) { - desc.tfm = crypt_stat->mount_crypt_stat->global_key_tfm; + tfm = crypt_stat->mount_crypt_stat->global_key_tfm; tfm_mutex = &crypt_stat->mount_crypt_stat->global_key_tfm_mutex; - } else { - char *full_alg_name; - - rc = ecryptfs_crypto_api_algify_cipher_name(&full_alg_name, - crypt_stat->cipher, - "ecb"); - if (rc) - goto out; - desc.tfm = crypto_alloc_blkcipher(full_alg_name, 0, - CRYPTO_ALG_ASYNC); - kfree(full_alg_name); - if (IS_ERR(desc.tfm)) { - rc = PTR_ERR(desc.tfm); - ecryptfs_printk(KERN_ERR, "Could not initialize crypto " - "context for cipher [%s]; rc = [%d]\n", - crypt_stat->cipher, rc); - goto out; - } - crypto_blkcipher_set_flags(desc.tfm, CRYPTO_TFM_REQ_WEAK_KEY); + } else + tfm = crypto_alloc_tfm(crypt_stat->cipher, 0); + if (!tfm) { + ecryptfs_printk(KERN_ERR, "Could not initialize crypto " + "context for cipher [%s]\n", + crypt_stat->cipher); + rc = -EINVAL; + goto out; } if (tfm_mutex) mutex_lock(tfm_mutex); - rc = crypto_blkcipher_setkey(desc.tfm, session_key_encryption_key, - crypt_stat->key_size); + rc = crypto_cipher_setkey(tfm, session_key_encryption_key, + crypt_stat->key_size); if (rc < 0) { if (tfm_mutex) mutex_unlock(tfm_mutex); ecryptfs_printk(KERN_ERR, "Error setting key for crypto " - "context; rc = [%d]\n", rc); + "context\n"); goto out; } rc = 0; ecryptfs_printk(KERN_DEBUG, "Encrypting [%d] bytes of the key\n", crypt_stat->key_size); - rc = crypto_blkcipher_encrypt(&desc, dest_sg, src_sg, - (*key_rec).enc_key_size); - if (rc) { - printk(KERN_ERR "Error encrypting; rc = [%d]\n", rc); - goto out; - } + crypto_cipher_encrypt(tfm, dest_sg, src_sg, + (*key_rec).enc_key_size); if (tfm_mutex) mutex_unlock(tfm_mutex); ecryptfs_printk(KERN_DEBUG, "This should be the encrypted key:\n"); @@ -1001,8 +971,8 @@ write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok, (*key_rec).enc_key_size); (*packet_size) += (*key_rec).enc_key_size; out: - if (desc.tfm && !tfm_mutex) - crypto_free_blkcipher(desc.tfm); + if (tfm && !tfm_mutex) + crypto_free_tfm(tfm); if (rc) (*packet_size) = 0; return rc; diff --git a/trunk/fs/ecryptfs/main.c b/trunk/fs/ecryptfs/main.c index a78d87d14baf..7a11b8ae6644 100644 --- a/trunk/fs/ecryptfs/main.c +++ b/trunk/fs/ecryptfs/main.c @@ -104,7 +104,10 @@ int ecryptfs_interpose(struct dentry *lower_dentry, struct dentry *dentry, inode->i_op = &ecryptfs_dir_iops; if (S_ISDIR(lower_inode->i_mode)) inode->i_fop = &ecryptfs_dir_fops; - if (special_file(lower_inode->i_mode)) + /* TODO: Is there a better way to identify if the inode is + * special? */ + if (S_ISBLK(lower_inode->i_mode) || S_ISCHR(lower_inode->i_mode) || + S_ISFIFO(lower_inode->i_mode) || S_ISSOCK(lower_inode->i_mode)) init_special_inode(inode, lower_inode->i_mode, lower_inode->i_rdev); dentry->d_op = &ecryptfs_dops; @@ -208,6 +211,7 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options) char *cipher_name_dst; char *cipher_name_src; char *cipher_key_bytes_src; + struct crypto_tfm *tmp_tfm; int cipher_name_len; if (!options) { @@ -304,19 +308,25 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options) = '\0'; } if (!cipher_key_bytes_set) { - mount_crypt_stat->global_default_cipher_key_size = 0; + mount_crypt_stat->global_default_cipher_key_size = + ECRYPTFS_DEFAULT_KEY_BYTES; + ecryptfs_printk(KERN_DEBUG, "Cipher key size was not " + "specified. Defaulting to [%d]\n", + mount_crypt_stat-> + global_default_cipher_key_size); } rc = ecryptfs_process_cipher( + &tmp_tfm, &mount_crypt_stat->global_key_tfm, mount_crypt_stat->global_default_cipher_name, - &mount_crypt_stat->global_default_cipher_key_size); + mount_crypt_stat->global_default_cipher_key_size); + if (tmp_tfm) + crypto_free_tfm(tmp_tfm); if (rc) { printk(KERN_ERR "Error attempting to initialize cipher [%s] " "with key size [%Zd] bytes; rc = [%d]\n", mount_crypt_stat->global_default_cipher_name, mount_crypt_stat->global_default_cipher_key_size, rc); - mount_crypt_stat->global_key_tfm = NULL; - mount_crypt_stat->global_auth_tok_key = NULL; rc = -EINVAL; goto out; } diff --git a/trunk/fs/ecryptfs/super.c b/trunk/fs/ecryptfs/super.c index 825757ae4867..c337c0410fb1 100644 --- a/trunk/fs/ecryptfs/super.c +++ b/trunk/fs/ecryptfs/super.c @@ -137,6 +137,23 @@ static void ecryptfs_clear_inode(struct inode *inode) iput(ecryptfs_inode_to_lower(inode)); } +/** + * ecryptfs_umount_begin + * + * Called in do_umount(). + */ +static void ecryptfs_umount_begin(struct vfsmount *vfsmnt, int flags) +{ + struct vfsmount *lower_mnt = + ecryptfs_dentry_to_lower_mnt(vfsmnt->mnt_sb->s_root); + struct super_block *lower_sb; + + mntput(lower_mnt); + lower_sb = lower_mnt->mnt_sb; + if (lower_sb->s_op->umount_begin) + lower_sb->s_op->umount_begin(lower_mnt, flags); +} + /** * ecryptfs_show_options * @@ -176,5 +193,6 @@ struct super_operations ecryptfs_sops = { .statfs = ecryptfs_statfs, .remount_fs = NULL, .clear_inode = ecryptfs_clear_inode, + .umount_begin = ecryptfs_umount_begin, .show_options = ecryptfs_show_options }; diff --git a/trunk/fs/eventpoll.c b/trunk/fs/eventpoll.c index ae228ec54e94..557d5b614fae 100644 --- a/trunk/fs/eventpoll.c +++ b/trunk/fs/eventpoll.c @@ -105,8 +105,6 @@ /* Maximum msec timeout value storeable in a long int */ #define EP_MAX_MSTIMEO min(1000ULL * MAX_SCHEDULE_TIMEOUT / HZ, (LONG_MAX - 999ULL) / HZ) -#define EP_MAX_EVENTS (INT_MAX / sizeof(struct epoll_event)) - struct epoll_filefd { struct file *file; @@ -499,7 +497,7 @@ void eventpoll_release_file(struct file *file) */ asmlinkage long sys_epoll_create(int size) { - int error, fd = -1; + int error, fd; struct eventpoll *ep; struct inode *inode; struct file *file; @@ -642,6 +640,7 @@ sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event __user *event) return error; } +#define MAX_EVENTS (INT_MAX / sizeof(struct epoll_event)) /* * Implement the event wait interface for the eventpoll file. It is the kernel @@ -658,7 +657,7 @@ asmlinkage long sys_epoll_wait(int epfd, struct epoll_event __user *events, current, epfd, events, maxevents, timeout)); /* The maximum number of event must be greater than zero */ - if (maxevents <= 0 || maxevents > EP_MAX_EVENTS) + if (maxevents <= 0 || maxevents > MAX_EVENTS) return -EINVAL; /* Verify that the area passed by the user is writeable */ @@ -700,55 +699,6 @@ asmlinkage long sys_epoll_wait(int epfd, struct epoll_event __user *events, } -#ifdef TIF_RESTORE_SIGMASK - -/* - * Implement the event wait interface for the eventpoll file. It is the kernel - * part of the user space epoll_pwait(2). - */ -asmlinkage long sys_epoll_pwait(int epfd, struct epoll_event __user *events, - int maxevents, int timeout, const sigset_t __user *sigmask, - size_t sigsetsize) -{ - int error; - sigset_t ksigmask, sigsaved; - - /* - * If the caller wants a certain signal mask to be set during the wait, - * we apply it here. - */ - if (sigmask) { - if (sigsetsize != sizeof(sigset_t)) - return -EINVAL; - if (copy_from_user(&ksigmask, sigmask, sizeof(ksigmask))) - return -EFAULT; - sigdelsetmask(&ksigmask, sigmask(SIGKILL) | sigmask(SIGSTOP)); - sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved); - } - - error = sys_epoll_wait(epfd, events, maxevents, timeout); - - /* - * If we changed the signal mask, we need to restore the original one. - * In case we've got a signal while waiting, we do not restore the - * signal mask yet, and we allow do_signal() to deliver the signal on - * the way back to userspace, before the signal mask is restored. - */ - if (sigmask) { - if (error == -EINTR) { - memcpy(¤t->saved_sigmask, &sigsaved, - sizeof(sigsaved)); - set_thread_flag(TIF_RESTORE_SIGMASK); - } else - sigprocmask(SIG_SETMASK, &sigsaved, NULL); - } - - return error; -} - -#endif /* #ifdef TIF_RESTORE_SIGMASK */ - - /* * Creates the file descriptor to be used by the epoll interface. */ diff --git a/trunk/fs/ext2/super.c b/trunk/fs/ext2/super.c index d8b9abd95d07..513cd421ac0b 100644 --- a/trunk/fs/ext2/super.c +++ b/trunk/fs/ext2/super.c @@ -364,6 +364,7 @@ static int parse_options (char * options, { char * p; substring_t args[MAX_OPT_ARGS]; + unsigned long kind = EXT2_MOUNT_ERRORS_CONT; int option; if (!options) @@ -403,19 +404,13 @@ static int parse_options (char * options, /* *sb_block = match_int(&args[0]); */ break; case Opt_err_panic: - clear_opt (sbi->s_mount_opt, ERRORS_CONT); - clear_opt (sbi->s_mount_opt, ERRORS_RO); - set_opt (sbi->s_mount_opt, ERRORS_PANIC); + kind = EXT2_MOUNT_ERRORS_PANIC; break; case Opt_err_ro: - clear_opt (sbi->s_mount_opt, ERRORS_CONT); - clear_opt (sbi->s_mount_opt, ERRORS_PANIC); - set_opt (sbi->s_mount_opt, ERRORS_RO); + kind = EXT2_MOUNT_ERRORS_RO; break; case Opt_err_cont: - clear_opt (sbi->s_mount_opt, ERRORS_RO); - clear_opt (sbi->s_mount_opt, ERRORS_PANIC); - set_opt (sbi->s_mount_opt, ERRORS_CONT); + kind = EXT2_MOUNT_ERRORS_CONT; break; case Opt_nouid32: set_opt (sbi->s_mount_opt, NO_UID32); @@ -494,6 +489,7 @@ static int parse_options (char * options, return 0; } } + sbi->s_mount_opt |= kind; return 1; } @@ -719,8 +715,6 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) set_opt(sbi->s_mount_opt, ERRORS_PANIC); else if (le16_to_cpu(sbi->s_es->s_errors) == EXT2_ERRORS_RO) set_opt(sbi->s_mount_opt, ERRORS_RO); - else - set_opt(sbi->s_mount_opt, ERRORS_CONT); sbi->s_resuid = le16_to_cpu(es->s_def_resuid); sbi->s_resgid = le16_to_cpu(es->s_def_resgid); diff --git a/trunk/fs/ext3/super.c b/trunk/fs/ext3/super.c index afc2d4f42d77..8bfd56ef18ca 100644 --- a/trunk/fs/ext3/super.c +++ b/trunk/fs/ext3/super.c @@ -1470,8 +1470,6 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent) set_opt(sbi->s_mount_opt, ERRORS_PANIC); else if (le16_to_cpu(sbi->s_es->s_errors) == EXT3_ERRORS_RO) set_opt(sbi->s_mount_opt, ERRORS_RO); - else - set_opt(sbi->s_mount_opt, ERRORS_CONT); sbi->s_resuid = le16_to_cpu(es->s_def_resuid); sbi->s_resgid = le16_to_cpu(es->s_def_resgid); diff --git a/trunk/fs/ext4/Makefile b/trunk/fs/ext4/Makefile deleted file mode 100644 index a6acb96ebeb9..000000000000 --- a/trunk/fs/ext4/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# -# Makefile for the linux ext4-filesystem routines. -# - -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 - -ext4dev-$(CONFIG_EXT4DEV_FS_XATTR) += xattr.o xattr_user.o xattr_trusted.o -ext4dev-$(CONFIG_EXT4DEV_FS_POSIX_ACL) += acl.o -ext4dev-$(CONFIG_EXT4DEV_FS_SECURITY) += xattr_security.o diff --git a/trunk/fs/ext4/acl.c b/trunk/fs/ext4/acl.c deleted file mode 100644 index 9e882546d91a..000000000000 --- a/trunk/fs/ext4/acl.c +++ /dev/null @@ -1,551 +0,0 @@ -/* - * linux/fs/ext4/acl.c - * - * Copyright (C) 2001-2003 Andreas Gruenbacher, - */ - -#include -#include -#include -#include -#include -#include -#include -#include "xattr.h" -#include "acl.h" - -/* - * Convert from filesystem to in-memory representation. - */ -static struct posix_acl * -ext4_acl_from_disk(const void *value, size_t size) -{ - const char *end = (char *)value + size; - int n, count; - struct posix_acl *acl; - - if (!value) - return NULL; - if (size < sizeof(ext4_acl_header)) - return ERR_PTR(-EINVAL); - if (((ext4_acl_header *)value)->a_version != - cpu_to_le32(EXT4_ACL_VERSION)) - return ERR_PTR(-EINVAL); - value = (char *)value + sizeof(ext4_acl_header); - count = ext4_acl_count(size); - if (count < 0) - return ERR_PTR(-EINVAL); - if (count == 0) - return NULL; - acl = posix_acl_alloc(count, GFP_KERNEL); - if (!acl) - return ERR_PTR(-ENOMEM); - for (n=0; n < count; n++) { - ext4_acl_entry *entry = - (ext4_acl_entry *)value; - if ((char *)value + sizeof(ext4_acl_entry_short) > end) - goto fail; - acl->a_entries[n].e_tag = le16_to_cpu(entry->e_tag); - acl->a_entries[n].e_perm = le16_to_cpu(entry->e_perm); - switch(acl->a_entries[n].e_tag) { - case ACL_USER_OBJ: - case ACL_GROUP_OBJ: - case ACL_MASK: - case ACL_OTHER: - value = (char *)value + - sizeof(ext4_acl_entry_short); - acl->a_entries[n].e_id = ACL_UNDEFINED_ID; - break; - - case ACL_USER: - case ACL_GROUP: - value = (char *)value + sizeof(ext4_acl_entry); - if ((char *)value > end) - goto fail; - acl->a_entries[n].e_id = - le32_to_cpu(entry->e_id); - break; - - default: - goto fail; - } - } - if (value != end) - goto fail; - return acl; - -fail: - posix_acl_release(acl); - return ERR_PTR(-EINVAL); -} - -/* - * Convert from in-memory to filesystem representation. - */ -static void * -ext4_acl_to_disk(const struct posix_acl *acl, size_t *size) -{ - ext4_acl_header *ext_acl; - char *e; - size_t n; - - *size = ext4_acl_size(acl->a_count); - ext_acl = kmalloc(sizeof(ext4_acl_header) + acl->a_count * - sizeof(ext4_acl_entry), GFP_KERNEL); - if (!ext_acl) - return ERR_PTR(-ENOMEM); - ext_acl->a_version = cpu_to_le32(EXT4_ACL_VERSION); - e = (char *)ext_acl + sizeof(ext4_acl_header); - for (n=0; n < acl->a_count; n++) { - ext4_acl_entry *entry = (ext4_acl_entry *)e; - entry->e_tag = cpu_to_le16(acl->a_entries[n].e_tag); - entry->e_perm = cpu_to_le16(acl->a_entries[n].e_perm); - switch(acl->a_entries[n].e_tag) { - case ACL_USER: - case ACL_GROUP: - entry->e_id = - cpu_to_le32(acl->a_entries[n].e_id); - e += sizeof(ext4_acl_entry); - break; - - case ACL_USER_OBJ: - case ACL_GROUP_OBJ: - case ACL_MASK: - case ACL_OTHER: - e += sizeof(ext4_acl_entry_short); - break; - - default: - goto fail; - } - } - return (char *)ext_acl; - -fail: - kfree(ext_acl); - return ERR_PTR(-EINVAL); -} - -static inline struct posix_acl * -ext4_iget_acl(struct inode *inode, struct posix_acl **i_acl) -{ - struct posix_acl *acl = EXT4_ACL_NOT_CACHED; - - spin_lock(&inode->i_lock); - if (*i_acl != EXT4_ACL_NOT_CACHED) - acl = posix_acl_dup(*i_acl); - spin_unlock(&inode->i_lock); - - return acl; -} - -static inline void -ext4_iset_acl(struct inode *inode, struct posix_acl **i_acl, - struct posix_acl *acl) -{ - spin_lock(&inode->i_lock); - if (*i_acl != EXT4_ACL_NOT_CACHED) - posix_acl_release(*i_acl); - *i_acl = posix_acl_dup(acl); - spin_unlock(&inode->i_lock); -} - -/* - * Inode operation get_posix_acl(). - * - * inode->i_mutex: don't care - */ -static struct posix_acl * -ext4_get_acl(struct inode *inode, int type) -{ - struct ext4_inode_info *ei = EXT4_I(inode); - int name_index; - char *value = NULL; - struct posix_acl *acl; - int retval; - - if (!test_opt(inode->i_sb, POSIX_ACL)) - return NULL; - - switch(type) { - case ACL_TYPE_ACCESS: - acl = ext4_iget_acl(inode, &ei->i_acl); - if (acl != EXT4_ACL_NOT_CACHED) - return acl; - name_index = EXT4_XATTR_INDEX_POSIX_ACL_ACCESS; - break; - - case ACL_TYPE_DEFAULT: - acl = ext4_iget_acl(inode, &ei->i_default_acl); - if (acl != EXT4_ACL_NOT_CACHED) - return acl; - name_index = EXT4_XATTR_INDEX_POSIX_ACL_DEFAULT; - break; - - default: - return ERR_PTR(-EINVAL); - } - retval = ext4_xattr_get(inode, name_index, "", NULL, 0); - if (retval > 0) { - value = kmalloc(retval, GFP_KERNEL); - if (!value) - return ERR_PTR(-ENOMEM); - retval = ext4_xattr_get(inode, name_index, "", value, retval); - } - if (retval > 0) - acl = ext4_acl_from_disk(value, retval); - else if (retval == -ENODATA || retval == -ENOSYS) - acl = NULL; - else - acl = ERR_PTR(retval); - kfree(value); - - if (!IS_ERR(acl)) { - switch(type) { - case ACL_TYPE_ACCESS: - ext4_iset_acl(inode, &ei->i_acl, acl); - break; - - case ACL_TYPE_DEFAULT: - ext4_iset_acl(inode, &ei->i_default_acl, acl); - break; - } - } - return acl; -} - -/* - * Set the access or default ACL of an inode. - * - * inode->i_mutex: down unless called from ext4_new_inode - */ -static int -ext4_set_acl(handle_t *handle, struct inode *inode, int type, - struct posix_acl *acl) -{ - struct ext4_inode_info *ei = EXT4_I(inode); - int name_index; - void *value = NULL; - size_t size = 0; - int error; - - if (S_ISLNK(inode->i_mode)) - return -EOPNOTSUPP; - - switch(type) { - case ACL_TYPE_ACCESS: - name_index = EXT4_XATTR_INDEX_POSIX_ACL_ACCESS; - if (acl) { - mode_t mode = inode->i_mode; - error = posix_acl_equiv_mode(acl, &mode); - if (error < 0) - return error; - else { - inode->i_mode = mode; - ext4_mark_inode_dirty(handle, inode); - if (error == 0) - acl = NULL; - } - } - break; - - case ACL_TYPE_DEFAULT: - name_index = EXT4_XATTR_INDEX_POSIX_ACL_DEFAULT; - if (!S_ISDIR(inode->i_mode)) - return acl ? -EACCES : 0; - break; - - default: - return -EINVAL; - } - if (acl) { - value = ext4_acl_to_disk(acl, &size); - if (IS_ERR(value)) - return (int)PTR_ERR(value); - } - - error = ext4_xattr_set_handle(handle, inode, name_index, "", - value, size, 0); - - kfree(value); - if (!error) { - switch(type) { - case ACL_TYPE_ACCESS: - ext4_iset_acl(inode, &ei->i_acl, acl); - break; - - case ACL_TYPE_DEFAULT: - ext4_iset_acl(inode, &ei->i_default_acl, acl); - break; - } - } - return error; -} - -static int -ext4_check_acl(struct inode *inode, int mask) -{ - struct posix_acl *acl = ext4_get_acl(inode, ACL_TYPE_ACCESS); - - if (IS_ERR(acl)) - return PTR_ERR(acl); - if (acl) { - int error = posix_acl_permission(inode, acl, mask); - posix_acl_release(acl); - return error; - } - - return -EAGAIN; -} - -int -ext4_permission(struct inode *inode, int mask, struct nameidata *nd) -{ - return generic_permission(inode, mask, ext4_check_acl); -} - -/* - * Initialize the ACLs of a new inode. Called from ext4_new_inode. - * - * dir->i_mutex: down - * inode->i_mutex: up (access to inode is still exclusive) - */ -int -ext4_init_acl(handle_t *handle, struct inode *inode, struct inode *dir) -{ - struct posix_acl *acl = NULL; - int error = 0; - - if (!S_ISLNK(inode->i_mode)) { - if (test_opt(dir->i_sb, POSIX_ACL)) { - acl = ext4_get_acl(dir, ACL_TYPE_DEFAULT); - if (IS_ERR(acl)) - return PTR_ERR(acl); - } - if (!acl) - inode->i_mode &= ~current->fs->umask; - } - if (test_opt(inode->i_sb, POSIX_ACL) && acl) { - struct posix_acl *clone; - mode_t mode; - - if (S_ISDIR(inode->i_mode)) { - error = ext4_set_acl(handle, inode, - ACL_TYPE_DEFAULT, acl); - if (error) - goto cleanup; - } - clone = posix_acl_clone(acl, GFP_KERNEL); - error = -ENOMEM; - if (!clone) - goto cleanup; - - mode = inode->i_mode; - error = posix_acl_create_masq(clone, &mode); - if (error >= 0) { - inode->i_mode = mode; - if (error > 0) { - /* This is an extended ACL */ - error = ext4_set_acl(handle, inode, - ACL_TYPE_ACCESS, clone); - } - } - posix_acl_release(clone); - } -cleanup: - posix_acl_release(acl); - return error; -} - -/* - * Does chmod for an inode that may have an Access Control List. The - * inode->i_mode field must be updated to the desired value by the caller - * before calling this function. - * Returns 0 on success, or a negative error number. - * - * We change the ACL rather than storing some ACL entries in the file - * mode permission bits (which would be more efficient), because that - * would break once additional permissions (like ACL_APPEND, ACL_DELETE - * for directories) are added. There are no more bits available in the - * file mode. - * - * inode->i_mutex: down - */ -int -ext4_acl_chmod(struct inode *inode) -{ - struct posix_acl *acl, *clone; - int error; - - if (S_ISLNK(inode->i_mode)) - return -EOPNOTSUPP; - if (!test_opt(inode->i_sb, POSIX_ACL)) - return 0; - acl = ext4_get_acl(inode, ACL_TYPE_ACCESS); - if (IS_ERR(acl) || !acl) - return PTR_ERR(acl); - clone = posix_acl_clone(acl, GFP_KERNEL); - posix_acl_release(acl); - if (!clone) - return -ENOMEM; - error = posix_acl_chmod_masq(clone, inode->i_mode); - if (!error) { - handle_t *handle; - int retries = 0; - - retry: - handle = ext4_journal_start(inode, - EXT4_DATA_TRANS_BLOCKS(inode->i_sb)); - if (IS_ERR(handle)) { - error = PTR_ERR(handle); - ext4_std_error(inode->i_sb, error); - goto out; - } - error = ext4_set_acl(handle, inode, ACL_TYPE_ACCESS, clone); - ext4_journal_stop(handle); - if (error == -ENOSPC && - ext4_should_retry_alloc(inode->i_sb, &retries)) - goto retry; - } -out: - posix_acl_release(clone); - return error; -} - -/* - * Extended attribute handlers - */ -static size_t -ext4_xattr_list_acl_access(struct inode *inode, char *list, size_t list_len, - const char *name, size_t name_len) -{ - const size_t size = sizeof(POSIX_ACL_XATTR_ACCESS); - - if (!test_opt(inode->i_sb, POSIX_ACL)) - return 0; - if (list && size <= list_len) - memcpy(list, POSIX_ACL_XATTR_ACCESS, size); - return size; -} - -static size_t -ext4_xattr_list_acl_default(struct inode *inode, char *list, size_t list_len, - const char *name, size_t name_len) -{ - const size_t size = sizeof(POSIX_ACL_XATTR_DEFAULT); - - if (!test_opt(inode->i_sb, POSIX_ACL)) - return 0; - if (list && size <= list_len) - memcpy(list, POSIX_ACL_XATTR_DEFAULT, size); - return size; -} - -static int -ext4_xattr_get_acl(struct inode *inode, int type, void *buffer, size_t size) -{ - struct posix_acl *acl; - int error; - - if (!test_opt(inode->i_sb, POSIX_ACL)) - return -EOPNOTSUPP; - - acl = ext4_get_acl(inode, type); - if (IS_ERR(acl)) - return PTR_ERR(acl); - if (acl == NULL) - return -ENODATA; - error = posix_acl_to_xattr(acl, buffer, size); - posix_acl_release(acl); - - return error; -} - -static int -ext4_xattr_get_acl_access(struct inode *inode, const char *name, - void *buffer, size_t size) -{ - if (strcmp(name, "") != 0) - return -EINVAL; - return ext4_xattr_get_acl(inode, ACL_TYPE_ACCESS, buffer, size); -} - -static int -ext4_xattr_get_acl_default(struct inode *inode, const char *name, - void *buffer, size_t size) -{ - if (strcmp(name, "") != 0) - return -EINVAL; - return ext4_xattr_get_acl(inode, ACL_TYPE_DEFAULT, buffer, size); -} - -static int -ext4_xattr_set_acl(struct inode *inode, int type, const void *value, - size_t size) -{ - handle_t *handle; - struct posix_acl *acl; - int error, retries = 0; - - if (!test_opt(inode->i_sb, POSIX_ACL)) - return -EOPNOTSUPP; - if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER)) - return -EPERM; - - if (value) { - acl = posix_acl_from_xattr(value, size); - if (IS_ERR(acl)) - return PTR_ERR(acl); - else if (acl) { - error = posix_acl_valid(acl); - if (error) - goto release_and_out; - } - } else - acl = NULL; - -retry: - handle = ext4_journal_start(inode, EXT4_DATA_TRANS_BLOCKS(inode->i_sb)); - if (IS_ERR(handle)) - return PTR_ERR(handle); - error = ext4_set_acl(handle, inode, type, acl); - ext4_journal_stop(handle); - if (error == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) - goto retry; - -release_and_out: - posix_acl_release(acl); - return error; -} - -static int -ext4_xattr_set_acl_access(struct inode *inode, const char *name, - const void *value, size_t size, int flags) -{ - if (strcmp(name, "") != 0) - return -EINVAL; - return ext4_xattr_set_acl(inode, ACL_TYPE_ACCESS, value, size); -} - -static int -ext4_xattr_set_acl_default(struct inode *inode, const char *name, - const void *value, size_t size, int flags) -{ - if (strcmp(name, "") != 0) - return -EINVAL; - return ext4_xattr_set_acl(inode, ACL_TYPE_DEFAULT, value, size); -} - -struct xattr_handler ext4_xattr_acl_access_handler = { - .prefix = POSIX_ACL_XATTR_ACCESS, - .list = ext4_xattr_list_acl_access, - .get = ext4_xattr_get_acl_access, - .set = ext4_xattr_set_acl_access, -}; - -struct xattr_handler ext4_xattr_acl_default_handler = { - .prefix = POSIX_ACL_XATTR_DEFAULT, - .list = ext4_xattr_list_acl_default, - .get = ext4_xattr_get_acl_default, - .set = ext4_xattr_set_acl_default, -}; diff --git a/trunk/fs/ext4/acl.h b/trunk/fs/ext4/acl.h deleted file mode 100644 index 26a5c1abf147..000000000000 --- a/trunk/fs/ext4/acl.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - File: fs/ext4/acl.h - - (C) 2001 Andreas Gruenbacher, -*/ - -#include - -#define EXT4_ACL_VERSION 0x0001 - -typedef struct { - __le16 e_tag; - __le16 e_perm; - __le32 e_id; -} ext4_acl_entry; - -typedef struct { - __le16 e_tag; - __le16 e_perm; -} ext4_acl_entry_short; - -typedef struct { - __le32 a_version; -} ext4_acl_header; - -static inline size_t ext4_acl_size(int count) -{ - if (count <= 4) { - return sizeof(ext4_acl_header) + - count * sizeof(ext4_acl_entry_short); - } else { - return sizeof(ext4_acl_header) + - 4 * sizeof(ext4_acl_entry_short) + - (count - 4) * sizeof(ext4_acl_entry); - } -} - -static inline int ext4_acl_count(size_t size) -{ - ssize_t s; - size -= sizeof(ext4_acl_header); - s = size - 4 * sizeof(ext4_acl_entry_short); - if (s < 0) { - if (size % sizeof(ext4_acl_entry_short)) - return -1; - return size / sizeof(ext4_acl_entry_short); - } else { - if (s % sizeof(ext4_acl_entry)) - return -1; - return s / sizeof(ext4_acl_entry) + 4; - } -} - -#ifdef CONFIG_EXT4DEV_FS_POSIX_ACL - -/* Value for inode->u.ext4_i.i_acl and inode->u.ext4_i.i_default_acl - if the ACL has not been cached */ -#define EXT4_ACL_NOT_CACHED ((void *)-1) - -/* acl.c */ -extern int ext4_permission (struct inode *, int, struct nameidata *); -extern int ext4_acl_chmod (struct inode *); -extern int ext4_init_acl (handle_t *, struct inode *, struct inode *); - -#else /* CONFIG_EXT4DEV_FS_POSIX_ACL */ -#include -#define ext4_permission NULL - -static inline int -ext4_acl_chmod(struct inode *inode) -{ - return 0; -} - -static inline int -ext4_init_acl(handle_t *handle, struct inode *inode, struct inode *dir) -{ - return 0; -} -#endif /* CONFIG_EXT4DEV_FS_POSIX_ACL */ - diff --git a/trunk/fs/ext4/balloc.c b/trunk/fs/ext4/balloc.c deleted file mode 100644 index 5d45582f9517..000000000000 --- a/trunk/fs/ext4/balloc.c +++ /dev/null @@ -1,1833 +0,0 @@ -/* - * linux/fs/ext4/balloc.c - * - * Copyright (C) 1992, 1993, 1994, 1995 - * Remy Card (card@masi.ibp.fr) - * Laboratoire MASI - Institut Blaise Pascal - * Universite Pierre et Marie Curie (Paris VI) - * - * Enhanced block allocation by Stephen Tweedie (sct@redhat.com), 1993 - * Big-endian to little-endian byte-swapping/bitmaps by - * David S. Miller (davem@caip.rutgers.edu), 1995 - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * balloc.c contains the blocks allocation and deallocation routines - */ - -/* - * Calculate the block group number and offset, given a block number - */ -void ext4_get_group_no_and_offset(struct super_block *sb, ext4_fsblk_t blocknr, - unsigned long *blockgrpp, ext4_grpblk_t *offsetp) -{ - struct ext4_super_block *es = EXT4_SB(sb)->s_es; - ext4_grpblk_t offset; - - blocknr = blocknr - le32_to_cpu(es->s_first_data_block); - offset = do_div(blocknr, EXT4_BLOCKS_PER_GROUP(sb)); - if (offsetp) - *offsetp = offset; - if (blockgrpp) - *blockgrpp = blocknr; - -} - -/* - * The free blocks are managed by bitmaps. A file system contains several - * blocks groups. Each group contains 1 bitmap block for blocks, 1 bitmap - * block for inodes, N blocks for the inode table and data blocks. - * - * The file system contains group descriptors which are located after the - * super block. Each descriptor contains the number of the bitmap block and - * the free blocks count in the block. The descriptors are loaded in memory - * when a file system is mounted (see ext4_read_super). - */ - - -#define in_range(b, first, len) ((b) >= (first) && (b) <= (first) + (len) - 1) - -/** - * ext4_get_group_desc() -- load group descriptor from disk - * @sb: super block - * @block_group: given block group - * @bh: pointer to the buffer head to store the block - * group descriptor - */ -struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb, - unsigned int block_group, - struct buffer_head ** bh) -{ - unsigned long group_desc; - unsigned long offset; - struct ext4_group_desc * desc; - struct ext4_sb_info *sbi = EXT4_SB(sb); - - if (block_group >= sbi->s_groups_count) { - ext4_error (sb, "ext4_get_group_desc", - "block_group >= groups_count - " - "block_group = %d, groups_count = %lu", - block_group, sbi->s_groups_count); - - return NULL; - } - smp_rmb(); - - group_desc = block_group >> EXT4_DESC_PER_BLOCK_BITS(sb); - offset = block_group & (EXT4_DESC_PER_BLOCK(sb) - 1); - if (!sbi->s_group_desc[group_desc]) { - ext4_error (sb, "ext4_get_group_desc", - "Group descriptor not loaded - " - "block_group = %d, group_desc = %lu, desc = %lu", - block_group, group_desc, offset); - return NULL; - } - - desc = (struct ext4_group_desc *)( - (__u8 *)sbi->s_group_desc[group_desc]->b_data + - offset * EXT4_DESC_SIZE(sb)); - if (bh) - *bh = sbi->s_group_desc[group_desc]; - return desc; -} - -/** - * read_block_bitmap() - * @sb: super block - * @block_group: given block group - * - * Read the bitmap for a given block_group, reading into the specified - * slot in the superblock's bitmap cache. - * - * Return buffer_head on success or NULL in case of failure. - */ -static struct buffer_head * -read_block_bitmap(struct super_block *sb, unsigned int block_group) -{ - struct ext4_group_desc * desc; - struct buffer_head * bh = NULL; - - desc = ext4_get_group_desc (sb, block_group, NULL); - if (!desc) - goto error_out; - bh = sb_bread(sb, ext4_block_bitmap(sb, desc)); - if (!bh) - ext4_error (sb, "read_block_bitmap", - "Cannot read block bitmap - " - "block_group = %d, block_bitmap = %llu", - block_group, - ext4_block_bitmap(sb, desc)); -error_out: - return bh; -} -/* - * The reservation window structure operations - * -------------------------------------------- - * Operations include: - * dump, find, add, remove, is_empty, find_next_reservable_window, etc. - * - * We use a red-black tree to represent per-filesystem reservation - * windows. - * - */ - -/** - * __rsv_window_dump() -- Dump the filesystem block allocation reservation map - * @rb_root: root of per-filesystem reservation rb tree - * @verbose: verbose mode - * @fn: function which wishes to dump the reservation map - * - * If verbose is turned on, it will print the whole block reservation - * windows(start, end). Otherwise, it will only print out the "bad" windows, - * those windows that overlap with their immediate neighbors. - */ -#if 1 -static void __rsv_window_dump(struct rb_root *root, int verbose, - const char *fn) -{ - struct rb_node *n; - struct ext4_reserve_window_node *rsv, *prev; - int bad; - -restart: - n = rb_first(root); - bad = 0; - prev = NULL; - - printk("Block Allocation Reservation Windows Map (%s):\n", fn); - while (n) { - rsv = list_entry(n, struct ext4_reserve_window_node, rsv_node); - if (verbose) - printk("reservation window 0x%p " - "start: %llu, end: %llu\n", - rsv, rsv->rsv_start, rsv->rsv_end); - if (rsv->rsv_start && rsv->rsv_start >= rsv->rsv_end) { - printk("Bad reservation %p (start >= end)\n", - rsv); - bad = 1; - } - if (prev && prev->rsv_end >= rsv->rsv_start) { - printk("Bad reservation %p (prev->end >= start)\n", - rsv); - bad = 1; - } - if (bad) { - if (!verbose) { - printk("Restarting reservation walk in verbose mode\n"); - verbose = 1; - goto restart; - } - } - n = rb_next(n); - prev = rsv; - } - printk("Window map complete.\n"); - if (bad) - BUG(); -} -#define rsv_window_dump(root, verbose) \ - __rsv_window_dump((root), (verbose), __FUNCTION__) -#else -#define rsv_window_dump(root, verbose) do {} while (0) -#endif - -/** - * goal_in_my_reservation() - * @rsv: inode's reservation window - * @grp_goal: given goal block relative to the allocation block group - * @group: the current allocation block group - * @sb: filesystem super block - * - * Test if the given goal block (group relative) is within the file's - * own block reservation window range. - * - * If the reservation window is outside the goal allocation group, return 0; - * grp_goal (given goal block) could be -1, which means no specific - * goal block. In this case, always return 1. - * If the goal block is within the reservation window, return 1; - * otherwise, return 0; - */ -static int -goal_in_my_reservation(struct ext4_reserve_window *rsv, ext4_grpblk_t grp_goal, - unsigned int group, struct super_block * sb) -{ - ext4_fsblk_t group_first_block, group_last_block; - - group_first_block = ext4_group_first_block_no(sb, group); - group_last_block = group_first_block + (EXT4_BLOCKS_PER_GROUP(sb) - 1); - - if ((rsv->_rsv_start > group_last_block) || - (rsv->_rsv_end < group_first_block)) - return 0; - if ((grp_goal >= 0) && ((grp_goal + group_first_block < rsv->_rsv_start) - || (grp_goal + group_first_block > rsv->_rsv_end))) - return 0; - return 1; -} - -/** - * search_reserve_window() - * @rb_root: root of reservation tree - * @goal: target allocation block - * - * Find the reserved window which includes the goal, or the previous one - * if the goal is not in any window. - * Returns NULL if there are no windows or if all windows start after the goal. - */ -static struct ext4_reserve_window_node * -search_reserve_window(struct rb_root *root, ext4_fsblk_t goal) -{ - struct rb_node *n = root->rb_node; - struct ext4_reserve_window_node *rsv; - - if (!n) - return NULL; - - do { - rsv = rb_entry(n, struct ext4_reserve_window_node, rsv_node); - - if (goal < rsv->rsv_start) - n = n->rb_left; - else if (goal > rsv->rsv_end) - n = n->rb_right; - else - return rsv; - } while (n); - /* - * We've fallen off the end of the tree: the goal wasn't inside - * any particular node. OK, the previous node must be to one - * side of the interval containing the goal. If it's the RHS, - * we need to back up one. - */ - if (rsv->rsv_start > goal) { - n = rb_prev(&rsv->rsv_node); - rsv = rb_entry(n, struct ext4_reserve_window_node, rsv_node); - } - return rsv; -} - -/** - * ext4_rsv_window_add() -- Insert a window to the block reservation rb tree. - * @sb: super block - * @rsv: reservation window to add - * - * Must be called with rsv_lock hold. - */ -void ext4_rsv_window_add(struct super_block *sb, - struct ext4_reserve_window_node *rsv) -{ - struct rb_root *root = &EXT4_SB(sb)->s_rsv_window_root; - struct rb_node *node = &rsv->rsv_node; - ext4_fsblk_t start = rsv->rsv_start; - - struct rb_node ** p = &root->rb_node; - struct rb_node * parent = NULL; - struct ext4_reserve_window_node *this; - - while (*p) - { - parent = *p; - this = rb_entry(parent, struct ext4_reserve_window_node, rsv_node); - - if (start < this->rsv_start) - p = &(*p)->rb_left; - else if (start > this->rsv_end) - p = &(*p)->rb_right; - else { - rsv_window_dump(root, 1); - BUG(); - } - } - - rb_link_node(node, parent, p); - rb_insert_color(node, root); -} - -/** - * ext4_rsv_window_remove() -- unlink a window from the reservation rb tree - * @sb: super block - * @rsv: reservation window to remove - * - * Mark the block reservation window as not allocated, and unlink it - * from the filesystem reservation window rb tree. Must be called with - * rsv_lock hold. - */ -static void rsv_window_remove(struct super_block *sb, - struct ext4_reserve_window_node *rsv) -{ - rsv->rsv_start = EXT4_RESERVE_WINDOW_NOT_ALLOCATED; - rsv->rsv_end = EXT4_RESERVE_WINDOW_NOT_ALLOCATED; - rsv->rsv_alloc_hit = 0; - rb_erase(&rsv->rsv_node, &EXT4_SB(sb)->s_rsv_window_root); -} - -/* - * rsv_is_empty() -- Check if the reservation window is allocated. - * @rsv: given reservation window to check - * - * returns 1 if the end block is EXT4_RESERVE_WINDOW_NOT_ALLOCATED. - */ -static inline int rsv_is_empty(struct ext4_reserve_window *rsv) -{ - /* a valid reservation end block could not be 0 */ - return rsv->_rsv_end == EXT4_RESERVE_WINDOW_NOT_ALLOCATED; -} - -/** - * ext4_init_block_alloc_info() - * @inode: file inode structure - * - * Allocate and initialize the reservation window structure, and - * link the window to the ext4 inode structure at last - * - * The reservation window structure is only dynamically allocated - * and linked to ext4 inode the first time the open file - * needs a new block. So, before every ext4_new_block(s) call, for - * regular files, we should check whether the reservation window - * structure exists or not. In the latter case, this function is called. - * Fail to do so will result in block reservation being turned off for that - * open file. - * - * This function is called from ext4_get_blocks_handle(), also called - * when setting the reservation window size through ioctl before the file - * is open for write (needs block allocation). - * - * Needs truncate_mutex protection prior to call this function. - */ -void ext4_init_block_alloc_info(struct inode *inode) -{ - struct ext4_inode_info *ei = EXT4_I(inode); - struct ext4_block_alloc_info *block_i = ei->i_block_alloc_info; - struct super_block *sb = inode->i_sb; - - block_i = kmalloc(sizeof(*block_i), GFP_NOFS); - if (block_i) { - struct ext4_reserve_window_node *rsv = &block_i->rsv_window_node; - - rsv->rsv_start = EXT4_RESERVE_WINDOW_NOT_ALLOCATED; - rsv->rsv_end = EXT4_RESERVE_WINDOW_NOT_ALLOCATED; - - /* - * if filesystem is mounted with NORESERVATION, the goal - * reservation window size is set to zero to indicate - * block reservation is off - */ - if (!test_opt(sb, RESERVATION)) - rsv->rsv_goal_size = 0; - else - rsv->rsv_goal_size = EXT4_DEFAULT_RESERVE_BLOCKS; - rsv->rsv_alloc_hit = 0; - block_i->last_alloc_logical_block = 0; - block_i->last_alloc_physical_block = 0; - } - ei->i_block_alloc_info = block_i; -} - -/** - * ext4_discard_reservation() - * @inode: inode - * - * Discard(free) block reservation window on last file close, or truncate - * or at last iput(). - * - * It is being called in three cases: - * ext4_release_file(): last writer close the file - * ext4_clear_inode(): last iput(), when nobody link to this file. - * ext4_truncate(): when the block indirect map is about to change. - * - */ -void ext4_discard_reservation(struct inode *inode) -{ - struct ext4_inode_info *ei = EXT4_I(inode); - struct ext4_block_alloc_info *block_i = ei->i_block_alloc_info; - struct ext4_reserve_window_node *rsv; - spinlock_t *rsv_lock = &EXT4_SB(inode->i_sb)->s_rsv_window_lock; - - if (!block_i) - return; - - rsv = &block_i->rsv_window_node; - if (!rsv_is_empty(&rsv->rsv_window)) { - spin_lock(rsv_lock); - if (!rsv_is_empty(&rsv->rsv_window)) - rsv_window_remove(inode->i_sb, rsv); - spin_unlock(rsv_lock); - } -} - -/** - * ext4_free_blocks_sb() -- Free given blocks and update quota - * @handle: handle to this transaction - * @sb: super block - * @block: start physcial block to free - * @count: number of blocks to free - * @pdquot_freed_blocks: pointer to quota - */ -void ext4_free_blocks_sb(handle_t *handle, struct super_block *sb, - ext4_fsblk_t block, unsigned long count, - unsigned long *pdquot_freed_blocks) -{ - struct buffer_head *bitmap_bh = NULL; - struct buffer_head *gd_bh; - unsigned long block_group; - ext4_grpblk_t bit; - unsigned long i; - unsigned long overflow; - struct ext4_group_desc * desc; - struct ext4_super_block * es; - struct ext4_sb_info *sbi; - int err = 0, ret; - ext4_grpblk_t group_freed; - - *pdquot_freed_blocks = 0; - sbi = EXT4_SB(sb); - es = sbi->s_es; - if (block < le32_to_cpu(es->s_first_data_block) || - block + count < block || - block + count > ext4_blocks_count(es)) { - ext4_error (sb, "ext4_free_blocks", - "Freeing blocks not in datazone - " - "block = %llu, count = %lu", block, count); - goto error_return; - } - - ext4_debug ("freeing block(s) %llu-%llu\n", block, block + count - 1); - -do_more: - overflow = 0; - ext4_get_group_no_and_offset(sb, block, &block_group, &bit); - /* - * Check to see if we are freeing blocks across a group - * boundary. - */ - if (bit + count > EXT4_BLOCKS_PER_GROUP(sb)) { - overflow = bit + count - EXT4_BLOCKS_PER_GROUP(sb); - count -= overflow; - } - brelse(bitmap_bh); - bitmap_bh = read_block_bitmap(sb, block_group); - if (!bitmap_bh) - goto error_return; - desc = ext4_get_group_desc (sb, block_group, &gd_bh); - if (!desc) - goto error_return; - - if (in_range(ext4_block_bitmap(sb, desc), block, count) || - in_range(ext4_inode_bitmap(sb, desc), block, count) || - in_range(block, ext4_inode_table(sb, desc), sbi->s_itb_per_group) || - in_range(block + count - 1, ext4_inode_table(sb, desc), - sbi->s_itb_per_group)) - ext4_error (sb, "ext4_free_blocks", - "Freeing blocks in system zones - " - "Block = %llu, count = %lu", - block, count); - - /* - * We are about to start releasing blocks in the bitmap, - * so we need undo access. - */ - /* @@@ check errors */ - BUFFER_TRACE(bitmap_bh, "getting undo access"); - err = ext4_journal_get_undo_access(handle, bitmap_bh); - if (err) - goto error_return; - - /* - * We are about to modify some metadata. Call the journal APIs - * to unshare ->b_data if a currently-committing transaction is - * using it - */ - BUFFER_TRACE(gd_bh, "get_write_access"); - err = ext4_journal_get_write_access(handle, gd_bh); - if (err) - goto error_return; - - jbd_lock_bh_state(bitmap_bh); - - for (i = 0, group_freed = 0; i < count; i++) { - /* - * An HJ special. This is expensive... - */ -#ifdef CONFIG_JBD_DEBUG - jbd_unlock_bh_state(bitmap_bh); - { - struct buffer_head *debug_bh; - debug_bh = sb_find_get_block(sb, block + i); - if (debug_bh) { - BUFFER_TRACE(debug_bh, "Deleted!"); - if (!bh2jh(bitmap_bh)->b_committed_data) - BUFFER_TRACE(debug_bh, - "No commited data in bitmap"); - BUFFER_TRACE2(debug_bh, bitmap_bh, "bitmap"); - __brelse(debug_bh); - } - } - jbd_lock_bh_state(bitmap_bh); -#endif - if (need_resched()) { - jbd_unlock_bh_state(bitmap_bh); - cond_resched(); - jbd_lock_bh_state(bitmap_bh); - } - /* @@@ This prevents newly-allocated data from being - * freed and then reallocated within the same - * transaction. - * - * Ideally we would want to allow that to happen, but to - * do so requires making jbd2_journal_forget() capable of - * revoking the queued write of a data block, which - * implies blocking on the journal lock. *forget() - * cannot block due to truncate races. - * - * Eventually we can fix this by making jbd2_journal_forget() - * return a status indicating whether or not it was able - * to revoke the buffer. On successful revoke, it is - * safe not to set the allocation bit in the committed - * bitmap, because we know that there is no outstanding - * activity on the buffer any more and so it is safe to - * reallocate it. - */ - BUFFER_TRACE(bitmap_bh, "set in b_committed_data"); - J_ASSERT_BH(bitmap_bh, - bh2jh(bitmap_bh)->b_committed_data != NULL); - ext4_set_bit_atomic(sb_bgl_lock(sbi, block_group), bit + i, - bh2jh(bitmap_bh)->b_committed_data); - - /* - * We clear the bit in the bitmap after setting the committed - * data bit, because this is the reverse order to that which - * the allocator uses. - */ - BUFFER_TRACE(bitmap_bh, "clear bit"); - if (!ext4_clear_bit_atomic(sb_bgl_lock(sbi, block_group), - bit + i, bitmap_bh->b_data)) { - jbd_unlock_bh_state(bitmap_bh); - ext4_error(sb, __FUNCTION__, - "bit already cleared for block %llu", - (ext4_fsblk_t)(block + i)); - jbd_lock_bh_state(bitmap_bh); - BUFFER_TRACE(bitmap_bh, "bit already cleared"); - } else { - group_freed++; - } - } - jbd_unlock_bh_state(bitmap_bh); - - spin_lock(sb_bgl_lock(sbi, block_group)); - desc->bg_free_blocks_count = - cpu_to_le16(le16_to_cpu(desc->bg_free_blocks_count) + - group_freed); - spin_unlock(sb_bgl_lock(sbi, block_group)); - percpu_counter_mod(&sbi->s_freeblocks_counter, count); - - /* We dirtied the bitmap block */ - BUFFER_TRACE(bitmap_bh, "dirtied bitmap block"); - err = ext4_journal_dirty_metadata(handle, bitmap_bh); - - /* And the group descriptor block */ - BUFFER_TRACE(gd_bh, "dirtied group descriptor block"); - ret = ext4_journal_dirty_metadata(handle, gd_bh); - if (!err) err = ret; - *pdquot_freed_blocks += group_freed; - - if (overflow && !err) { - block += count; - count = overflow; - goto do_more; - } - sb->s_dirt = 1; -error_return: - brelse(bitmap_bh); - ext4_std_error(sb, err); - return; -} - -/** - * ext4_free_blocks() -- Free given blocks and update quota - * @handle: handle for this transaction - * @inode: inode - * @block: start physical block to free - * @count: number of blocks to count - */ -void ext4_free_blocks(handle_t *handle, struct inode *inode, - ext4_fsblk_t block, unsigned long count) -{ - struct super_block * sb; - unsigned long dquot_freed_blocks; - - sb = inode->i_sb; - if (!sb) { - printk ("ext4_free_blocks: nonexistent device"); - return; - } - ext4_free_blocks_sb(handle, sb, block, count, &dquot_freed_blocks); - if (dquot_freed_blocks) - DQUOT_FREE_BLOCK(inode, dquot_freed_blocks); - return; -} - -/** - * ext4_test_allocatable() - * @nr: given allocation block group - * @bh: bufferhead contains the bitmap of the given block group - * - * For ext4 allocations, we must not reuse any blocks which are - * allocated in the bitmap buffer's "last committed data" copy. This - * prevents deletes from freeing up the page for reuse until we have - * committed the delete transaction. - * - * If we didn't do this, then deleting something and reallocating it as - * data would allow the old block to be overwritten before the - * transaction committed (because we force data to disk before commit). - * This would lead to corruption if we crashed between overwriting the - * data and committing the delete. - * - * @@@ We may want to make this allocation behaviour conditional on - * data-writes at some point, and disable it for metadata allocations or - * sync-data inodes. - */ -static int ext4_test_allocatable(ext4_grpblk_t nr, struct buffer_head *bh) -{ - int ret; - struct journal_head *jh = bh2jh(bh); - - if (ext4_test_bit(nr, bh->b_data)) - return 0; - - jbd_lock_bh_state(bh); - if (!jh->b_committed_data) - ret = 1; - else - ret = !ext4_test_bit(nr, jh->b_committed_data); - jbd_unlock_bh_state(bh); - return ret; -} - -/** - * bitmap_search_next_usable_block() - * @start: the starting block (group relative) of the search - * @bh: bufferhead contains the block group bitmap - * @maxblocks: the ending block (group relative) of the reservation - * - * The bitmap search --- search forward alternately through the actual - * bitmap on disk and the last-committed copy in journal, until we find a - * bit free in both bitmaps. - */ -static ext4_grpblk_t -bitmap_search_next_usable_block(ext4_grpblk_t start, struct buffer_head *bh, - ext4_grpblk_t maxblocks) -{ - ext4_grpblk_t next; - struct journal_head *jh = bh2jh(bh); - - while (start < maxblocks) { - next = ext4_find_next_zero_bit(bh->b_data, maxblocks, start); - if (next >= maxblocks) - return -1; - if (ext4_test_allocatable(next, bh)) - return next; - jbd_lock_bh_state(bh); - if (jh->b_committed_data) - start = ext4_find_next_zero_bit(jh->b_committed_data, - maxblocks, next); - jbd_unlock_bh_state(bh); - } - return -1; -} - -/** - * find_next_usable_block() - * @start: the starting block (group relative) to find next - * allocatable block in bitmap. - * @bh: bufferhead contains the block group bitmap - * @maxblocks: the ending block (group relative) for the search - * - * Find an allocatable block in a bitmap. We honor both the bitmap and - * its last-committed copy (if that exists), and perform the "most - * appropriate allocation" algorithm of looking for a free block near - * the initial goal; then for a free byte somewhere in the bitmap; then - * for any free bit in the bitmap. - */ -static ext4_grpblk_t -find_next_usable_block(ext4_grpblk_t start, struct buffer_head *bh, - ext4_grpblk_t maxblocks) -{ - ext4_grpblk_t here, next; - char *p, *r; - - if (start > 0) { - /* - * The goal was occupied; search forward for a free - * block within the next XX blocks. - * - * end_goal is more or less random, but it has to be - * less than EXT4_BLOCKS_PER_GROUP. Aligning up to the - * next 64-bit boundary is simple.. - */ - ext4_grpblk_t end_goal = (start + 63) & ~63; - if (end_goal > maxblocks) - end_goal = maxblocks; - here = ext4_find_next_zero_bit(bh->b_data, end_goal, start); - if (here < end_goal && ext4_test_allocatable(here, bh)) - return here; - ext4_debug("Bit not found near goal\n"); - } - - here = start; - if (here < 0) - here = 0; - - p = ((char *)bh->b_data) + (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)) - return next; - - /* - * The bitmap search --- search forward alternately through the actual - * bitmap and the last-committed copy until we find a bit free in - * both - */ - here = bitmap_search_next_usable_block(here, bh, maxblocks); - return here; -} - -/** - * claim_block() - * @block: the free block (group relative) to allocate - * @bh: the bufferhead containts the block group bitmap - * - * We think we can allocate this block in this bitmap. Try to set the bit. - * If that succeeds then check that nobody has allocated and then freed the - * block since we saw that is was not marked in b_committed_data. If it _was_ - * allocated and freed then clear the bit in the bitmap again and return - * zero (failure). - */ -static inline int -claim_block(spinlock_t *lock, ext4_grpblk_t block, struct buffer_head *bh) -{ - struct journal_head *jh = bh2jh(bh); - int ret; - - if (ext4_set_bit_atomic(lock, block, bh->b_data)) - return 0; - jbd_lock_bh_state(bh); - if (jh->b_committed_data && ext4_test_bit(block,jh->b_committed_data)) { - ext4_clear_bit_atomic(lock, block, bh->b_data); - ret = 0; - } else { - ret = 1; - } - jbd_unlock_bh_state(bh); - return ret; -} - -/** - * ext4_try_to_allocate() - * @sb: superblock - * @handle: handle to this transaction - * @group: given allocation block group - * @bitmap_bh: bufferhead holds the block bitmap - * @grp_goal: given target block within the group - * @count: target number of blocks to allocate - * @my_rsv: reservation window - * - * Attempt to allocate blocks within a give range. Set the range of allocation - * first, then find the first free bit(s) from the bitmap (within the range), - * and at last, allocate the blocks by claiming the found free bit as allocated. - * - * To set the range of this allocation: - * if there is a reservation window, only try to allocate block(s) from the - * file's own reservation window; - * Otherwise, the allocation range starts from the give goal block, ends at - * the block group's last block. - * - * If we failed to allocate the desired block then we may end up crossing to a - * new bitmap. In that case we must release write access to the old one via - * ext4_journal_release_buffer(), else we'll run out of credits. - */ -static ext4_grpblk_t -ext4_try_to_allocate(struct super_block *sb, handle_t *handle, int group, - struct buffer_head *bitmap_bh, ext4_grpblk_t grp_goal, - unsigned long *count, struct ext4_reserve_window *my_rsv) -{ - ext4_fsblk_t group_first_block; - ext4_grpblk_t start, end; - unsigned long num = 0; - - /* we do allocation within the reservation window if we have a window */ - if (my_rsv) { - group_first_block = ext4_group_first_block_no(sb, group); - if (my_rsv->_rsv_start >= group_first_block) - start = my_rsv->_rsv_start - group_first_block; - else - /* reservation window cross group boundary */ - start = 0; - end = my_rsv->_rsv_end - group_first_block + 1; - if (end > EXT4_BLOCKS_PER_GROUP(sb)) - /* reservation window crosses group boundary */ - end = EXT4_BLOCKS_PER_GROUP(sb); - if ((start <= grp_goal) && (grp_goal < end)) - start = grp_goal; - else - grp_goal = -1; - } else { - if (grp_goal > 0) - start = grp_goal; - else - start = 0; - end = EXT4_BLOCKS_PER_GROUP(sb); - } - - BUG_ON(start > EXT4_BLOCKS_PER_GROUP(sb)); - -repeat: - if (grp_goal < 0 || !ext4_test_allocatable(grp_goal, bitmap_bh)) { - grp_goal = find_next_usable_block(start, bitmap_bh, end); - if (grp_goal < 0) - goto fail_access; - if (!my_rsv) { - int i; - - for (i = 0; i < 7 && grp_goal > start && - ext4_test_allocatable(grp_goal - 1, - bitmap_bh); - i++, grp_goal--) - ; - } - } - start = grp_goal; - - if (!claim_block(sb_bgl_lock(EXT4_SB(sb), group), - grp_goal, bitmap_bh)) { - /* - * The block was allocated by another thread, or it was - * allocated and then freed by another thread - */ - start++; - grp_goal++; - if (start >= end) - goto fail_access; - goto repeat; - } - num++; - grp_goal++; - while (num < *count && grp_goal < end - && ext4_test_allocatable(grp_goal, bitmap_bh) - && claim_block(sb_bgl_lock(EXT4_SB(sb), group), - grp_goal, bitmap_bh)) { - num++; - grp_goal++; - } - *count = num; - return grp_goal - num; -fail_access: - *count = num; - return -1; -} - -/** - * find_next_reservable_window(): - * find a reservable space within the given range. - * It does not allocate the reservation window for now: - * alloc_new_reservation() will do the work later. - * - * @search_head: the head of the searching list; - * This is not necessarily the list head of the whole filesystem - * - * We have both head and start_block to assist the search - * for the reservable space. The list starts from head, - * but we will shift to the place where start_block is, - * then start from there, when looking for a reservable space. - * - * @size: the target new reservation window size - * - * @group_first_block: the first block we consider to start - * the real search from - * - * @last_block: - * the maximum block number that our goal reservable space - * could start from. This is normally the last block in this - * group. The search will end when we found the start of next - * possible reservable space is out of this boundary. - * This could handle the cross boundary reservation window - * request. - * - * basically we search from the given range, rather than the whole - * reservation double linked list, (start_block, last_block) - * to find a free region that is of my size and has not - * been reserved. - * - */ -static int find_next_reservable_window( - struct ext4_reserve_window_node *search_head, - struct ext4_reserve_window_node *my_rsv, - struct super_block * sb, - ext4_fsblk_t start_block, - ext4_fsblk_t last_block) -{ - struct rb_node *next; - struct ext4_reserve_window_node *rsv, *prev; - ext4_fsblk_t cur; - int size = my_rsv->rsv_goal_size; - - /* TODO: make the start of the reservation window byte-aligned */ - /* cur = *start_block & ~7;*/ - cur = start_block; - rsv = search_head; - if (!rsv) - return -1; - - while (1) { - if (cur <= rsv->rsv_end) - cur = rsv->rsv_end + 1; - - /* TODO? - * in the case we could not find a reservable space - * that is what is expected, during the re-search, we could - * remember what's the largest reservable space we could have - * and return that one. - * - * For now it will fail if we could not find the reservable - * space with expected-size (or more)... - */ - if (cur > last_block) - return -1; /* fail */ - - prev = rsv; - next = rb_next(&rsv->rsv_node); - rsv = list_entry(next,struct ext4_reserve_window_node,rsv_node); - - /* - * Reached the last reservation, we can just append to the - * previous one. - */ - if (!next) - break; - - if (cur + size <= rsv->rsv_start) { - /* - * Found a reserveable space big enough. We could - * have a reservation across the group boundary here - */ - break; - } - } - /* - * we come here either : - * when we reach the end of the whole list, - * and there is empty reservable space after last entry in the list. - * append it to the end of the list. - * - * or we found one reservable space in the middle of the list, - * return the reservation window that we could append to. - * succeed. - */ - - if ((prev != my_rsv) && (!rsv_is_empty(&my_rsv->rsv_window))) - rsv_window_remove(sb, my_rsv); - - /* - * Let's book the whole avaliable window for now. We will check the - * disk bitmap later and then, if there are free blocks then we adjust - * the window size if it's larger than requested. - * Otherwise, we will remove this node from the tree next time - * call find_next_reservable_window. - */ - my_rsv->rsv_start = cur; - my_rsv->rsv_end = cur + size - 1; - my_rsv->rsv_alloc_hit = 0; - - if (prev != my_rsv) - ext4_rsv_window_add(sb, my_rsv); - - return 0; -} - -/** - * alloc_new_reservation()--allocate a new reservation window - * - * To make a new reservation, we search part of the filesystem - * reservation list (the list that inside the group). We try to - * allocate a new reservation window near the allocation goal, - * or the beginning of the group, if there is no goal. - * - * We first find a reservable space after the goal, then from - * there, we check the bitmap for the first free block after - * it. If there is no free block until the end of group, then the - * whole group is full, we failed. Otherwise, check if the free - * block is inside the expected reservable space, if so, we - * succeed. - * If the first free block is outside the reservable space, then - * start from the first free block, we search for next available - * space, and go on. - * - * on succeed, a new reservation will be found and inserted into the list - * It contains at least one free block, and it does not overlap with other - * reservation windows. - * - * failed: we failed to find a reservation window in this group - * - * @rsv: the reservation - * - * @grp_goal: The goal (group-relative). It is where the search for a - * free reservable space should start from. - * if we have a grp_goal(grp_goal >0 ), then start from there, - * no grp_goal(grp_goal = -1), we start from the first block - * of the group. - * - * @sb: the super block - * @group: the group we are trying to allocate in - * @bitmap_bh: the block group block bitmap - * - */ -static int alloc_new_reservation(struct ext4_reserve_window_node *my_rsv, - ext4_grpblk_t grp_goal, struct super_block *sb, - unsigned int group, struct buffer_head *bitmap_bh) -{ - struct ext4_reserve_window_node *search_head; - ext4_fsblk_t group_first_block, group_end_block, start_block; - ext4_grpblk_t first_free_block; - struct rb_root *fs_rsv_root = &EXT4_SB(sb)->s_rsv_window_root; - unsigned long size; - int ret; - spinlock_t *rsv_lock = &EXT4_SB(sb)->s_rsv_window_lock; - - group_first_block = ext4_group_first_block_no(sb, group); - group_end_block = group_first_block + (EXT4_BLOCKS_PER_GROUP(sb) - 1); - - if (grp_goal < 0) - start_block = group_first_block; - else - start_block = grp_goal + group_first_block; - - size = my_rsv->rsv_goal_size; - - if (!rsv_is_empty(&my_rsv->rsv_window)) { - /* - * if the old reservation is cross group boundary - * and if the goal is inside the old reservation window, - * we will come here when we just failed to allocate from - * the first part of the window. We still have another part - * that belongs to the next group. In this case, there is no - * point to discard our window and try to allocate a new one - * in this group(which will fail). we should - * keep the reservation window, just simply move on. - * - * Maybe we could shift the start block of the reservation - * window to the first block of next group. - */ - - if ((my_rsv->rsv_start <= group_end_block) && - (my_rsv->rsv_end > group_end_block) && - (start_block >= my_rsv->rsv_start)) - return -1; - - if ((my_rsv->rsv_alloc_hit > - (my_rsv->rsv_end - my_rsv->rsv_start + 1) / 2)) { - /* - * if the previously allocation hit ratio is - * greater than 1/2, then we double the size of - * the reservation window the next time, - * otherwise we keep the same size window - */ - size = size * 2; - if (size > EXT4_MAX_RESERVE_BLOCKS) - size = EXT4_MAX_RESERVE_BLOCKS; - my_rsv->rsv_goal_size= size; - } - } - - spin_lock(rsv_lock); - /* - * shift the search start to the window near the goal block - */ - search_head = search_reserve_window(fs_rsv_root, start_block); - - /* - * find_next_reservable_window() simply finds a reservable window - * inside the given range(start_block, group_end_block). - * - * To make sure the reservation window has a free bit inside it, we - * need to check the bitmap after we found a reservable window. - */ -retry: - ret = find_next_reservable_window(search_head, my_rsv, sb, - start_block, group_end_block); - - if (ret == -1) { - if (!rsv_is_empty(&my_rsv->rsv_window)) - rsv_window_remove(sb, my_rsv); - spin_unlock(rsv_lock); - return -1; - } - - /* - * On success, find_next_reservable_window() returns the - * reservation window where there is a reservable space after it. - * Before we reserve this reservable space, we need - * to make sure there is at least a free block inside this region. - * - * searching the first free bit on the block bitmap and copy of - * last committed bitmap alternatively, until we found a allocatable - * block. Search start from the start block of the reservable space - * we just found. - */ - spin_unlock(rsv_lock); - first_free_block = bitmap_search_next_usable_block( - my_rsv->rsv_start - group_first_block, - bitmap_bh, group_end_block - group_first_block + 1); - - if (first_free_block < 0) { - /* - * no free block left on the bitmap, no point - * to reserve the space. return failed. - */ - spin_lock(rsv_lock); - if (!rsv_is_empty(&my_rsv->rsv_window)) - rsv_window_remove(sb, my_rsv); - spin_unlock(rsv_lock); - return -1; /* failed */ - } - - start_block = first_free_block + group_first_block; - /* - * 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) - return 0; /* success */ - /* - * if the first free bit we found is out of the reservable space - * continue search for next reservable space, - * start from where the free block is, - * we also shift the list head to where we stopped last time - */ - search_head = my_rsv; - spin_lock(rsv_lock); - goto retry; -} - -/** - * try_to_extend_reservation() - * @my_rsv: given reservation window - * @sb: super block - * @size: the delta to extend - * - * Attempt to expand the reservation window large enough to have - * required number of free blocks - * - * Since ext4_try_to_allocate() will always allocate blocks within - * the reservation window range, if the window size is too small, - * multiple blocks allocation has to stop at the end of the reservation - * window. To make this more efficient, given the total number of - * blocks needed and the current size of the window, we try to - * expand the reservation window size if necessary on a best-effort - * basis before ext4_new_blocks() tries to allocate blocks, - */ -static void try_to_extend_reservation(struct ext4_reserve_window_node *my_rsv, - struct super_block *sb, int size) -{ - struct ext4_reserve_window_node *next_rsv; - struct rb_node *next; - spinlock_t *rsv_lock = &EXT4_SB(sb)->s_rsv_window_lock; - - if (!spin_trylock(rsv_lock)) - return; - - next = rb_next(&my_rsv->rsv_node); - - if (!next) - my_rsv->rsv_end += size; - else { - 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; - else - my_rsv->rsv_end = next_rsv->rsv_start - 1; - } - spin_unlock(rsv_lock); -} - -/** - * ext4_try_to_allocate_with_rsv() - * @sb: superblock - * @handle: handle to this transaction - * @group: given allocation block group - * @bitmap_bh: bufferhead holds the block bitmap - * @grp_goal: given target block within the group - * @count: target number of blocks to allocate - * @my_rsv: reservation window - * @errp: pointer to store the error code - * - * This is the main function used to allocate a new block and its reservation - * window. - * - * Each time when a new block allocation is need, first try to allocate from - * its own reservation. If it does not have a reservation window, instead of - * looking for a free bit on bitmap first, then look up the reservation list to - * see if it is inside somebody else's reservation window, we try to allocate a - * reservation window for it starting from the goal first. Then do the block - * allocation within the reservation window. - * - * This will avoid keeping on searching the reservation list again and - * again when somebody is looking for a free block (without - * reservation), and there are lots of free blocks, but they are all - * being reserved. - * - * We use a red-black tree for the per-filesystem reservation list. - * - */ -static ext4_grpblk_t -ext4_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle, - unsigned int group, struct buffer_head *bitmap_bh, - ext4_grpblk_t grp_goal, - struct ext4_reserve_window_node * my_rsv, - unsigned long *count, int *errp) -{ - ext4_fsblk_t group_first_block, group_last_block; - ext4_grpblk_t ret = 0; - int fatal; - unsigned long num = *count; - - *errp = 0; - - /* - * Make sure we use undo access for the bitmap, because it is critical - * that we do the frozen_data COW on bitmap buffers in all cases even - * if the buffer is in BJ_Forget state in the committing transaction. - */ - BUFFER_TRACE(bitmap_bh, "get undo access for new block"); - fatal = ext4_journal_get_undo_access(handle, bitmap_bh); - if (fatal) { - *errp = fatal; - return -1; - } - - /* - * we don't deal with reservation when - * filesystem is mounted without reservation - * or the file is not a regular file - * or last attempt to allocate a block with reservation turned on failed - */ - if (my_rsv == NULL ) { - ret = ext4_try_to_allocate(sb, handle, group, bitmap_bh, - grp_goal, count, NULL); - goto out; - } - /* - * grp_goal is a group relative block number (if there is a goal) - * 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 - */ - group_first_block = ext4_group_first_block_no(sb, group); - group_last_block = group_first_block + (EXT4_BLOCKS_PER_GROUP(sb) - 1); - - /* - * Basically we will allocate a new block from inode's reservation - * window. - * - * We need to allocate a new reservation window, if: - * a) inode does not have a reservation window; or - * b) last attempt to allocate a block from existing reservation - * failed; or - * c) we come here with a goal and with a reservation window - * - * We do not need to allocate a new reservation window if we come here - * at the beginning with a goal and the goal is inside the window, or - * we don't have a goal but already have a reservation window. - * then we could go to allocate from the reservation window directly. - */ - while (1) { - if (rsv_is_empty(&my_rsv->rsv_window) || (ret < 0) || - !goal_in_my_reservation(&my_rsv->rsv_window, - grp_goal, group, sb)) { - if (my_rsv->rsv_goal_size < *count) - my_rsv->rsv_goal_size = *count; - ret = alloc_new_reservation(my_rsv, grp_goal, sb, - group, bitmap_bh); - if (ret < 0) - break; /* failed */ - - if (!goal_in_my_reservation(&my_rsv->rsv_window, - grp_goal, group, sb)) - grp_goal = -1; - } 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)) { - rsv_window_dump(&EXT4_SB(sb)->s_rsv_window_root, 1); - BUG(); - } - ret = ext4_try_to_allocate(sb, handle, group, bitmap_bh, - grp_goal, &num, &my_rsv->rsv_window); - if (ret >= 0) { - my_rsv->rsv_alloc_hit += num; - *count = num; - break; /* succeed */ - } - num = *count; - } -out: - if (ret >= 0) { - BUFFER_TRACE(bitmap_bh, "journal_dirty_metadata for " - "bitmap block"); - fatal = ext4_journal_dirty_metadata(handle, bitmap_bh); - if (fatal) { - *errp = fatal; - return -1; - } - return ret; - } - - BUFFER_TRACE(bitmap_bh, "journal_release_buffer"); - ext4_journal_release_buffer(handle, bitmap_bh); - return ret; -} - -/** - * ext4_has_free_blocks() - * @sbi: in-core super block structure. - * - * Check if filesystem has at least 1 free block available for allocation. - */ -static int ext4_has_free_blocks(struct ext4_sb_info *sbi) -{ - ext4_fsblk_t free_blocks, root_blocks; - - free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter); - root_blocks = ext4_r_blocks_count(sbi->s_es); - if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) && - sbi->s_resuid != current->fsuid && - (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) { - return 0; - } - return 1; -} - -/** - * ext4_should_retry_alloc() - * @sb: super block - * @retries number of attemps has been made - * - * ext4_should_retry_alloc() is called when ENOSPC is returned, and if - * it is profitable to retry the operation, this function will wait - * for the current or commiting transaction to complete, and then - * return TRUE. - * - * if the total number of retries exceed three times, return FALSE. - */ -int ext4_should_retry_alloc(struct super_block *sb, int *retries) -{ - if (!ext4_has_free_blocks(EXT4_SB(sb)) || (*retries)++ > 3) - return 0; - - jbd_debug(1, "%s: retrying operation after ENOSPC\n", sb->s_id); - - return jbd2_journal_force_commit_nested(EXT4_SB(sb)->s_journal); -} - -/** - * ext4_new_blocks() -- core block(s) allocation function - * @handle: handle to this transaction - * @inode: file inode - * @goal: given target block(filesystem wide) - * @count: target number of blocks to allocate - * @errp: error code - * - * ext4_new_blocks uses a goal block to assist allocation. It tries to - * allocate block(s) from the block group contains the goal block first. If that - * fails, it will try to allocate block(s) from other block groups without - * any specific goal block. - * - */ -ext4_fsblk_t ext4_new_blocks(handle_t *handle, struct inode *inode, - ext4_fsblk_t goal, unsigned long *count, int *errp) -{ - struct buffer_head *bitmap_bh = NULL; - struct buffer_head *gdp_bh; - unsigned long group_no; - int goal_group; - ext4_grpblk_t grp_target_blk; /* blockgroup relative goal block */ - ext4_grpblk_t grp_alloc_blk; /* blockgroup-relative allocated block*/ - ext4_fsblk_t ret_block; /* filesyetem-wide allocated block */ - int bgi; /* blockgroup iteration index */ - int fatal = 0, err; - int performed_allocation = 0; - ext4_grpblk_t free_blocks; /* number of free blocks in a group */ - struct super_block *sb; - struct ext4_group_desc *gdp; - struct ext4_super_block *es; - struct ext4_sb_info *sbi; - struct ext4_reserve_window_node *my_rsv = NULL; - struct ext4_block_alloc_info *block_i; - unsigned short windowsz = 0; -#ifdef EXT4FS_DEBUG - static int goal_hits, goal_attempts; -#endif - unsigned long ngroups; - unsigned long num = *count; - - *errp = -ENOSPC; - sb = inode->i_sb; - if (!sb) { - printk("ext4_new_block: nonexistent device"); - return 0; - } - - /* - * Check quota for allocation of this block. - */ - if (DQUOT_ALLOC_BLOCK(inode, num)) { - *errp = -EDQUOT; - return 0; - } - - sbi = EXT4_SB(sb); - es = EXT4_SB(sb)->s_es; - ext4_debug("goal=%lu.\n", goal); - /* - * Allocate a block from reservation only when - * filesystem is mounted with reservation(default,-o reservation), and - * it's a regular file, and - * the desired window size is greater than 0 (One could use ioctl - * command EXT4_IOC_SETRSVSZ to set the window size to 0 to turn off - * reservation on that particular file) - */ - block_i = EXT4_I(inode)->i_block_alloc_info; - if (block_i && ((windowsz = block_i->rsv_window_node.rsv_goal_size) > 0)) - my_rsv = &block_i->rsv_window_node; - - if (!ext4_has_free_blocks(sbi)) { - *errp = -ENOSPC; - goto out; - } - - /* - * First, test whether the goal block is free. - */ - if (goal < le32_to_cpu(es->s_first_data_block) || - goal >= ext4_blocks_count(es)) - goal = le32_to_cpu(es->s_first_data_block); - ext4_get_group_no_and_offset(sb, goal, &group_no, &grp_target_blk); - goal_group = group_no; -retry_alloc: - gdp = ext4_get_group_desc(sb, group_no, &gdp_bh); - if (!gdp) - goto io_error; - - free_blocks = le16_to_cpu(gdp->bg_free_blocks_count); - /* - * if there is not enough free blocks to make a new resevation - * turn off reservation for this allocation - */ - if (my_rsv && (free_blocks < windowsz) - && (rsv_is_empty(&my_rsv->rsv_window))) - my_rsv = NULL; - - if (free_blocks > 0) { - bitmap_bh = read_block_bitmap(sb, group_no); - if (!bitmap_bh) - goto io_error; - grp_alloc_blk = ext4_try_to_allocate_with_rsv(sb, handle, - group_no, bitmap_bh, grp_target_blk, - my_rsv, &num, &fatal); - if (fatal) - goto out; - if (grp_alloc_blk >= 0) - goto allocated; - } - - ngroups = EXT4_SB(sb)->s_groups_count; - smp_rmb(); - - /* - * Now search the rest of the groups. We assume that - * i and gdp correctly point to the last group visited. - */ - for (bgi = 0; bgi < ngroups; bgi++) { - group_no++; - if (group_no >= ngroups) - group_no = 0; - gdp = ext4_get_group_desc(sb, group_no, &gdp_bh); - if (!gdp) { - *errp = -EIO; - goto out; - } - free_blocks = le16_to_cpu(gdp->bg_free_blocks_count); - /* - * skip this group if the number of - * free blocks is less than half of the reservation - * window size. - */ - if (free_blocks <= (windowsz/2)) - continue; - - brelse(bitmap_bh); - bitmap_bh = read_block_bitmap(sb, group_no); - if (!bitmap_bh) - goto io_error; - /* - * try to allocate block(s) from this group, without a goal(-1). - */ - grp_alloc_blk = ext4_try_to_allocate_with_rsv(sb, handle, - group_no, bitmap_bh, -1, my_rsv, - &num, &fatal); - if (fatal) - goto out; - if (grp_alloc_blk >= 0) - goto allocated; - } - /* - * We may end up a bogus ealier ENOSPC error due to - * filesystem is "full" of reservations, but - * there maybe indeed free blocks avaliable on disk - * In this case, we just forget about the reservations - * just do block allocation as without reservations. - */ - if (my_rsv) { - my_rsv = NULL; - group_no = goal_group; - goto retry_alloc; - } - /* No space left on the device */ - *errp = -ENOSPC; - goto out; - -allocated: - - ext4_debug("using block group %d(%d)\n", - group_no, gdp->bg_free_blocks_count); - - BUFFER_TRACE(gdp_bh, "get_write_access"); - fatal = ext4_journal_get_write_access(handle, gdp_bh); - if (fatal) - goto out; - - ret_block = grp_alloc_blk + ext4_group_first_block_no(sb, group_no); - - if (in_range(ext4_block_bitmap(sb, gdp), ret_block, num) || - in_range(ext4_block_bitmap(sb, gdp), ret_block, num) || - in_range(ret_block, ext4_inode_table(sb, gdp), - EXT4_SB(sb)->s_itb_per_group) || - in_range(ret_block + num - 1, ext4_inode_table(sb, gdp), - EXT4_SB(sb)->s_itb_per_group)) - ext4_error(sb, "ext4_new_block", - "Allocating block in system zone - " - "blocks from %llu, length %lu", - ret_block, num); - - performed_allocation = 1; - -#ifdef CONFIG_JBD_DEBUG - { - struct buffer_head *debug_bh; - - /* Record bitmap buffer state in the newly allocated block */ - debug_bh = sb_find_get_block(sb, ret_block); - if (debug_bh) { - BUFFER_TRACE(debug_bh, "state when allocated"); - BUFFER_TRACE2(debug_bh, bitmap_bh, "bitmap state"); - brelse(debug_bh); - } - } - jbd_lock_bh_state(bitmap_bh); - spin_lock(sb_bgl_lock(sbi, group_no)); - if (buffer_jbd(bitmap_bh) && bh2jh(bitmap_bh)->b_committed_data) { - int i; - - for (i = 0; i < num; i++) { - if (ext4_test_bit(grp_alloc_blk+i, - bh2jh(bitmap_bh)->b_committed_data)) { - printk("%s: block was unexpectedly set in " - "b_committed_data\n", __FUNCTION__); - } - } - } - ext4_debug("found bit %d\n", grp_alloc_blk); - spin_unlock(sb_bgl_lock(sbi, group_no)); - jbd_unlock_bh_state(bitmap_bh); -#endif - - if (ret_block + num - 1 >= ext4_blocks_count(es)) { - ext4_error(sb, "ext4_new_block", - "block(%llu) >= blocks count(%llu) - " - "block_group = %lu, es == %p ", ret_block, - ext4_blocks_count(es), group_no, es); - goto out; - } - - /* - * It is up to the caller to add the new buffer to a journal - * list of some description. We don't know in advance whether - * the caller wants to use it as metadata or data. - */ - ext4_debug("allocating block %lu. Goal hits %d of %d.\n", - ret_block, goal_hits, goal_attempts); - - spin_lock(sb_bgl_lock(sbi, group_no)); - gdp->bg_free_blocks_count = - cpu_to_le16(le16_to_cpu(gdp->bg_free_blocks_count)-num); - spin_unlock(sb_bgl_lock(sbi, group_no)); - percpu_counter_mod(&sbi->s_freeblocks_counter, -num); - - BUFFER_TRACE(gdp_bh, "journal_dirty_metadata for group descriptor"); - err = ext4_journal_dirty_metadata(handle, gdp_bh); - if (!fatal) - fatal = err; - - sb->s_dirt = 1; - if (fatal) - goto out; - - *errp = 0; - brelse(bitmap_bh); - DQUOT_FREE_BLOCK(inode, *count-num); - *count = num; - return ret_block; - -io_error: - *errp = -EIO; -out: - if (fatal) { - *errp = fatal; - ext4_std_error(sb, fatal); - } - /* - * Undo the block allocation - */ - if (!performed_allocation) - DQUOT_FREE_BLOCK(inode, *count); - brelse(bitmap_bh); - return 0; -} - -ext4_fsblk_t ext4_new_block(handle_t *handle, struct inode *inode, - ext4_fsblk_t goal, int *errp) -{ - unsigned long count = 1; - - return ext4_new_blocks(handle, inode, goal, &count, errp); -} - -/** - * ext4_count_free_blocks() -- count filesystem free blocks - * @sb: superblock - * - * Adds up the number of free blocks from each block group. - */ -ext4_fsblk_t ext4_count_free_blocks(struct super_block *sb) -{ - ext4_fsblk_t desc_count; - struct ext4_group_desc *gdp; - int i; - unsigned long ngroups = EXT4_SB(sb)->s_groups_count; -#ifdef EXT4FS_DEBUG - struct ext4_super_block *es; - ext4_fsblk_t bitmap_count; - unsigned long x; - struct buffer_head *bitmap_bh = NULL; - - es = EXT4_SB(sb)->s_es; - desc_count = 0; - bitmap_count = 0; - gdp = NULL; - - smp_rmb(); - for (i = 0; i < ngroups; i++) { - gdp = ext4_get_group_desc(sb, i, NULL); - if (!gdp) - continue; - desc_count += le16_to_cpu(gdp->bg_free_blocks_count); - brelse(bitmap_bh); - bitmap_bh = read_block_bitmap(sb, i); - if (bitmap_bh == NULL) - continue; - - x = ext4_count_free(bitmap_bh, sb->s_blocksize); - printk("group %d: stored = %d, counted = %lu\n", - i, le16_to_cpu(gdp->bg_free_blocks_count), x); - bitmap_count += x; - } - brelse(bitmap_bh); - printk("ext4_count_free_blocks: stored = %llu" - ", computed = %llu, %llu\n", - EXT4_FREE_BLOCKS_COUNT(es), - desc_count, bitmap_count); - return bitmap_count; -#else - desc_count = 0; - smp_rmb(); - for (i = 0; i < ngroups; i++) { - gdp = ext4_get_group_desc(sb, i, NULL); - if (!gdp) - continue; - desc_count += le16_to_cpu(gdp->bg_free_blocks_count); - } - - return desc_count; -#endif -} - -static inline int -block_in_use(ext4_fsblk_t block, struct super_block *sb, unsigned char *map) -{ - ext4_grpblk_t offset; - - ext4_get_group_no_and_offset(sb, block, NULL, &offset); - return ext4_test_bit (offset, map); -} - -static inline int test_root(int a, int b) -{ - int num = b; - - while (a > num) - num *= b; - return num == a; -} - -static int ext4_group_sparse(int group) -{ - if (group <= 1) - return 1; - if (!(group & 1)) - return 0; - return (test_root(group, 7) || test_root(group, 5) || - test_root(group, 3)); -} - -/** - * ext4_bg_has_super - number of blocks used by the superblock in group - * @sb: superblock for filesystem - * @group: group number to check - * - * Return the number of blocks used by the superblock (primary or backup) - * in this group. Currently this will be only 0 or 1. - */ -int ext4_bg_has_super(struct super_block *sb, int group) -{ - if (EXT4_HAS_RO_COMPAT_FEATURE(sb, - EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER) && - !ext4_group_sparse(group)) - return 0; - return 1; -} - -static unsigned long ext4_bg_num_gdb_meta(struct super_block *sb, int group) -{ - unsigned long metagroup = group / EXT4_DESC_PER_BLOCK(sb); - unsigned long first = metagroup * EXT4_DESC_PER_BLOCK(sb); - unsigned long last = first + EXT4_DESC_PER_BLOCK(sb) - 1; - - if (group == first || group == first + 1 || group == last) - return 1; - return 0; -} - -static unsigned long ext4_bg_num_gdb_nometa(struct super_block *sb, int group) -{ - if (EXT4_HAS_RO_COMPAT_FEATURE(sb, - EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER) && - !ext4_group_sparse(group)) - return 0; - return EXT4_SB(sb)->s_gdb_count; -} - -/** - * ext4_bg_num_gdb - number of blocks used by the group table in group - * @sb: superblock for filesystem - * @group: group number to check - * - * Return the number of blocks used by the group descriptor table - * (primary or backup) in this group. In the future there may be a - * different number of descriptor blocks in each group. - */ -unsigned long ext4_bg_num_gdb(struct super_block *sb, int group) -{ - unsigned long first_meta_bg = - le32_to_cpu(EXT4_SB(sb)->s_es->s_first_meta_bg); - unsigned long metagroup = group / EXT4_DESC_PER_BLOCK(sb); - - if (!EXT4_HAS_INCOMPAT_FEATURE(sb,EXT4_FEATURE_INCOMPAT_META_BG) || - metagroup < first_meta_bg) - return ext4_bg_num_gdb_nometa(sb,group); - - return ext4_bg_num_gdb_meta(sb,group); - -} diff --git a/trunk/fs/ext4/bitmap.c b/trunk/fs/ext4/bitmap.c deleted file mode 100644 index 11e93c169bcf..000000000000 --- a/trunk/fs/ext4/bitmap.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - * linux/fs/ext4/bitmap.c - * - * Copyright (C) 1992, 1993, 1994, 1995 - * Remy Card (card@masi.ibp.fr) - * Laboratoire MASI - Institut Blaise Pascal - * Universite Pierre et Marie Curie (Paris VI) - */ - -#include -#include -#include - -#ifdef EXT4FS_DEBUG - -static int nibblemap[] = {4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0}; - -unsigned long ext4_count_free (struct buffer_head * map, unsigned int numchars) -{ - unsigned int i; - unsigned long sum = 0; - - if (!map) - return (0); - for (i = 0; i < numchars; i++) - sum += nibblemap[map->b_data[i] & 0xf] + - nibblemap[(map->b_data[i] >> 4) & 0xf]; - return (sum); -} - -#endif /* EXT4FS_DEBUG */ - diff --git a/trunk/fs/ext4/dir.c b/trunk/fs/ext4/dir.c deleted file mode 100644 index f8595787a70e..000000000000 --- a/trunk/fs/ext4/dir.c +++ /dev/null @@ -1,518 +0,0 @@ -/* - * linux/fs/ext4/dir.c - * - * Copyright (C) 1992, 1993, 1994, 1995 - * Remy Card (card@masi.ibp.fr) - * Laboratoire MASI - Institut Blaise Pascal - * Universite Pierre et Marie Curie (Paris VI) - * - * from - * - * linux/fs/minix/dir.c - * - * Copyright (C) 1991, 1992 Linus Torvalds - * - * ext4 directory handling functions - * - * Big-endian to little-endian byte-swapping/bitmaps by - * David S. Miller (davem@caip.rutgers.edu), 1995 - * - * Hash Tree Directory indexing (c) 2001 Daniel Phillips - * - */ - -#include -#include -#include -#include -#include -#include -#include - -static unsigned char ext4_filetype_table[] = { - DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK, DT_FIFO, DT_SOCK, DT_LNK -}; - -static int ext4_readdir(struct file *, void *, filldir_t); -static int ext4_dx_readdir(struct file * filp, - void * dirent, filldir_t filldir); -static int ext4_release_dir (struct inode * inode, - struct file * filp); - -const struct file_operations ext4_dir_operations = { - .llseek = generic_file_llseek, - .read = generic_read_dir, - .readdir = ext4_readdir, /* we take BKL. needed?*/ - .ioctl = ext4_ioctl, /* BKL held */ -#ifdef CONFIG_COMPAT - .compat_ioctl = ext4_compat_ioctl, -#endif - .fsync = ext4_sync_file, /* BKL held */ -#ifdef CONFIG_EXT4_INDEX - .release = ext4_release_dir, -#endif -}; - - -static unsigned char get_dtype(struct super_block *sb, int filetype) -{ - if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FILETYPE) || - (filetype >= EXT4_FT_MAX)) - return DT_UNKNOWN; - - return (ext4_filetype_table[filetype]); -} - - -int ext4_check_dir_entry (const char * function, struct inode * dir, - struct ext4_dir_entry_2 * de, - struct buffer_head * bh, - unsigned long offset) -{ - const char * error_msg = NULL; - const int rlen = le16_to_cpu(de->rec_len); - - if (rlen < EXT4_DIR_REC_LEN(1)) - error_msg = "rec_len is smaller than minimal"; - else if (rlen % 4 != 0) - error_msg = "rec_len % 4 != 0"; - else if (rlen < EXT4_DIR_REC_LEN(de->name_len)) - error_msg = "rec_len is too small for name_len"; - else if (((char *) de - bh->b_data) + rlen > dir->i_sb->s_blocksize) - error_msg = "directory entry across blocks"; - else if (le32_to_cpu(de->inode) > - le32_to_cpu(EXT4_SB(dir->i_sb)->s_es->s_inodes_count)) - error_msg = "inode out of bounds"; - - if (error_msg != NULL) - ext4_error (dir->i_sb, function, - "bad entry in directory #%lu: %s - " - "offset=%lu, inode=%lu, rec_len=%d, name_len=%d", - dir->i_ino, error_msg, offset, - (unsigned long) le32_to_cpu(de->inode), - rlen, de->name_len); - return error_msg == NULL ? 1 : 0; -} - -static int ext4_readdir(struct file * filp, - void * dirent, filldir_t filldir) -{ - int error = 0; - unsigned long offset; - int i, stored; - struct ext4_dir_entry_2 *de; - struct super_block *sb; - int err; - struct inode *inode = filp->f_dentry->d_inode; - int ret = 0; - - sb = inode->i_sb; - -#ifdef CONFIG_EXT4_INDEX - if (EXT4_HAS_COMPAT_FEATURE(inode->i_sb, - EXT4_FEATURE_COMPAT_DIR_INDEX) && - ((EXT4_I(inode)->i_flags & EXT4_INDEX_FL) || - ((inode->i_size >> sb->s_blocksize_bits) == 1))) { - err = ext4_dx_readdir(filp, dirent, filldir); - if (err != ERR_BAD_DX_DIR) { - ret = err; - goto out; - } - /* - * We don't set the inode dirty flag since it's not - * critical that it get flushed back to the disk. - */ - EXT4_I(filp->f_dentry->d_inode)->i_flags &= ~EXT4_INDEX_FL; - } -#endif - stored = 0; - offset = filp->f_pos & (sb->s_blocksize - 1); - - while (!error && !stored && filp->f_pos < inode->i_size) { - unsigned long blk = filp->f_pos >> EXT4_BLOCK_SIZE_BITS(sb); - struct buffer_head map_bh; - struct buffer_head *bh = NULL; - - map_bh.b_state = 0; - err = ext4_get_blocks_wrap(NULL, inode, blk, 1, &map_bh, 0, 0); - if (err > 0) { - page_cache_readahead(sb->s_bdev->bd_inode->i_mapping, - &filp->f_ra, - filp, - map_bh.b_blocknr >> - (PAGE_CACHE_SHIFT - inode->i_blkbits), - 1); - bh = ext4_bread(NULL, inode, blk, 0, &err); - } - - /* - * We ignore I/O errors on directories so users have a chance - * of recovering data when there's a bad sector - */ - if (!bh) { - ext4_error (sb, "ext4_readdir", - "directory #%lu contains a hole at offset %lu", - inode->i_ino, (unsigned long)filp->f_pos); - filp->f_pos += sb->s_blocksize - offset; - continue; - } - -revalidate: - /* If the dir block has changed since the last call to - * readdir(2), then we might be pointing to an invalid - * dirent right now. Scan from the start of the block - * to make sure. */ - if (filp->f_version != inode->i_version) { - for (i = 0; i < sb->s_blocksize && i < offset; ) { - de = (struct ext4_dir_entry_2 *) - (bh->b_data + i); - /* It's too expensive to do a full - * dirent test each time round this - * loop, but we do have to test at - * least that it is non-zero. A - * failure will be detected in the - * dirent test below. */ - if (le16_to_cpu(de->rec_len) < - EXT4_DIR_REC_LEN(1)) - break; - i += le16_to_cpu(de->rec_len); - } - offset = i; - filp->f_pos = (filp->f_pos & ~(sb->s_blocksize - 1)) - | offset; - filp->f_version = inode->i_version; - } - - while (!error && filp->f_pos < inode->i_size - && offset < sb->s_blocksize) { - de = (struct ext4_dir_entry_2 *) (bh->b_data + offset); - if (!ext4_check_dir_entry ("ext4_readdir", inode, de, - bh, offset)) { - /* - * On error, skip the f_pos to the next block - */ - filp->f_pos = (filp->f_pos | - (sb->s_blocksize - 1)) + 1; - brelse (bh); - ret = stored; - goto out; - } - offset += le16_to_cpu(de->rec_len); - if (le32_to_cpu(de->inode)) { - /* We might block in the next section - * if the data destination is - * currently swapped out. So, use a - * version stamp to detect whether or - * not the directory has been modified - * during the copy operation. - */ - unsigned long version = filp->f_version; - - error = filldir(dirent, de->name, - de->name_len, - filp->f_pos, - le32_to_cpu(de->inode), - get_dtype(sb, de->file_type)); - if (error) - break; - if (version != filp->f_version) - goto revalidate; - stored ++; - } - filp->f_pos += le16_to_cpu(de->rec_len); - } - offset = 0; - brelse (bh); - } -out: - return ret; -} - -#ifdef CONFIG_EXT4_INDEX -/* - * These functions convert from the major/minor hash to an f_pos - * value. - * - * Currently we only use major hash numer. This is unfortunate, but - * on 32-bit machines, the same VFS interface is used for lseek and - * llseek, so if we use the 64 bit offset, then the 32-bit versions of - * lseek/telldir/seekdir will blow out spectacularly, and from within - * the ext2 low-level routine, we don't know if we're being called by - * a 64-bit version of the system call or the 32-bit version of the - * system call. Worse yet, NFSv2 only allows for a 32-bit readdir - * cookie. Sigh. - */ -#define hash2pos(major, minor) (major >> 1) -#define pos2maj_hash(pos) ((pos << 1) & 0xffffffff) -#define pos2min_hash(pos) (0) - -/* - * This structure holds the nodes of the red-black tree used to store - * the directory entry in hash order. - */ -struct fname { - __u32 hash; - __u32 minor_hash; - struct rb_node rb_hash; - struct fname *next; - __u32 inode; - __u8 name_len; - __u8 file_type; - char name[0]; -}; - -/* - * This functoin implements a non-recursive way of freeing all of the - * nodes in the red-black tree. - */ -static void free_rb_tree_fname(struct rb_root *root) -{ - struct rb_node *n = root->rb_node; - struct rb_node *parent; - struct fname *fname; - - while (n) { - /* Do the node's children first */ - if ((n)->rb_left) { - n = n->rb_left; - continue; - } - if (n->rb_right) { - n = n->rb_right; - continue; - } - /* - * The node has no children; free it, and then zero - * out parent's link to it. Finally go to the - * beginning of the loop and try to free the parent - * node. - */ - parent = rb_parent(n); - fname = rb_entry(n, struct fname, rb_hash); - while (fname) { - struct fname * old = fname; - fname = fname->next; - kfree (old); - } - if (!parent) - root->rb_node = NULL; - else if (parent->rb_left == n) - parent->rb_left = NULL; - else if (parent->rb_right == n) - parent->rb_right = NULL; - n = parent; - } - root->rb_node = NULL; -} - - -static struct dir_private_info *create_dir_info(loff_t pos) -{ - struct dir_private_info *p; - - p = kmalloc(sizeof(struct dir_private_info), GFP_KERNEL); - if (!p) - return NULL; - p->root.rb_node = NULL; - p->curr_node = NULL; - p->extra_fname = NULL; - p->last_pos = 0; - p->curr_hash = pos2maj_hash(pos); - p->curr_minor_hash = pos2min_hash(pos); - p->next_hash = 0; - return p; -} - -void ext4_htree_free_dir_info(struct dir_private_info *p) -{ - free_rb_tree_fname(&p->root); - kfree(p); -} - -/* - * Given a directory entry, enter it into the fname rb tree. - */ -int ext4_htree_store_dirent(struct file *dir_file, __u32 hash, - __u32 minor_hash, - struct ext4_dir_entry_2 *dirent) -{ - struct rb_node **p, *parent = NULL; - struct fname * fname, *new_fn; - struct dir_private_info *info; - int len; - - info = (struct dir_private_info *) dir_file->private_data; - p = &info->root.rb_node; - - /* Create and allocate the fname structure */ - len = sizeof(struct fname) + dirent->name_len + 1; - new_fn = kzalloc(len, GFP_KERNEL); - if (!new_fn) - return -ENOMEM; - new_fn->hash = hash; - new_fn->minor_hash = minor_hash; - new_fn->inode = le32_to_cpu(dirent->inode); - new_fn->name_len = dirent->name_len; - new_fn->file_type = dirent->file_type; - memcpy(new_fn->name, dirent->name, dirent->name_len); - new_fn->name[dirent->name_len] = 0; - - while (*p) { - parent = *p; - fname = rb_entry(parent, struct fname, rb_hash); - - /* - * If the hash and minor hash match up, then we put - * them on a linked list. This rarely happens... - */ - if ((new_fn->hash == fname->hash) && - (new_fn->minor_hash == fname->minor_hash)) { - new_fn->next = fname->next; - fname->next = new_fn; - return 0; - } - - if (new_fn->hash < fname->hash) - p = &(*p)->rb_left; - else if (new_fn->hash > fname->hash) - p = &(*p)->rb_right; - else if (new_fn->minor_hash < fname->minor_hash) - p = &(*p)->rb_left; - else /* if (new_fn->minor_hash > fname->minor_hash) */ - p = &(*p)->rb_right; - } - - rb_link_node(&new_fn->rb_hash, parent, p); - rb_insert_color(&new_fn->rb_hash, &info->root); - return 0; -} - - - -/* - * This is a helper function for ext4_dx_readdir. It calls filldir - * for all entres on the fname linked list. (Normally there is only - * one entry on the linked list, unless there are 62 bit hash collisions.) - */ -static int call_filldir(struct file * filp, void * dirent, - filldir_t filldir, struct fname *fname) -{ - struct dir_private_info *info = filp->private_data; - loff_t curr_pos; - struct inode *inode = filp->f_dentry->d_inode; - struct super_block * sb; - int error; - - sb = inode->i_sb; - - if (!fname) { - printk("call_filldir: called with null fname?!?\n"); - return 0; - } - curr_pos = hash2pos(fname->hash, fname->minor_hash); - while (fname) { - error = filldir(dirent, fname->name, - fname->name_len, curr_pos, - fname->inode, - get_dtype(sb, fname->file_type)); - if (error) { - filp->f_pos = curr_pos; - info->extra_fname = fname->next; - return error; - } - fname = fname->next; - } - return 0; -} - -static int ext4_dx_readdir(struct file * filp, - void * dirent, filldir_t filldir) -{ - struct dir_private_info *info = filp->private_data; - struct inode *inode = filp->f_dentry->d_inode; - struct fname *fname; - int ret; - - if (!info) { - info = create_dir_info(filp->f_pos); - if (!info) - return -ENOMEM; - filp->private_data = info; - } - - if (filp->f_pos == EXT4_HTREE_EOF) - return 0; /* EOF */ - - /* Some one has messed with f_pos; reset the world */ - if (info->last_pos != filp->f_pos) { - free_rb_tree_fname(&info->root); - info->curr_node = NULL; - info->extra_fname = NULL; - info->curr_hash = pos2maj_hash(filp->f_pos); - info->curr_minor_hash = pos2min_hash(filp->f_pos); - } - - /* - * If there are any leftover names on the hash collision - * chain, return them first. - */ - if (info->extra_fname && - call_filldir(filp, dirent, filldir, info->extra_fname)) - goto finished; - - if (!info->curr_node) - info->curr_node = rb_first(&info->root); - - while (1) { - /* - * Fill the rbtree if we have no more entries, - * or the inode has changed since we last read in the - * cached entries. - */ - if ((!info->curr_node) || - (filp->f_version != inode->i_version)) { - info->curr_node = NULL; - free_rb_tree_fname(&info->root); - filp->f_version = inode->i_version; - ret = ext4_htree_fill_tree(filp, info->curr_hash, - info->curr_minor_hash, - &info->next_hash); - if (ret < 0) - return ret; - if (ret == 0) { - filp->f_pos = EXT4_HTREE_EOF; - break; - } - info->curr_node = rb_first(&info->root); - } - - fname = rb_entry(info->curr_node, struct fname, rb_hash); - info->curr_hash = fname->hash; - info->curr_minor_hash = fname->minor_hash; - if (call_filldir(filp, dirent, filldir, fname)) - break; - - info->curr_node = rb_next(info->curr_node); - if (!info->curr_node) { - if (info->next_hash == ~0) { - filp->f_pos = EXT4_HTREE_EOF; - break; - } - info->curr_hash = info->next_hash; - info->curr_minor_hash = 0; - } - } -finished: - info->last_pos = filp->f_pos; - return 0; -} - -static int ext4_release_dir (struct inode * inode, struct file * filp) -{ - if (filp->private_data) - ext4_htree_free_dir_info(filp->private_data); - - return 0; -} - -#endif diff --git a/trunk/fs/ext4/extents.c b/trunk/fs/ext4/extents.c deleted file mode 100644 index 2608dce18f3e..000000000000 --- a/trunk/fs/ext4/extents.c +++ /dev/null @@ -1,2152 +0,0 @@ -/* - * Copyright (c) 2003-2006, Cluster File Systems, Inc, info@clusterfs.com - * Written by Alex Tomas - * - * Architecture independence: - * Copyright (c) 2005, Bull S.A. - * Written by Pierre Peiffer - * - * 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. - * - * 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 Licens - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111- - */ - -/* - * Extents support for EXT4 - * - * TODO: - * - ext4*_error() should be used in some situations - * - analyze all BUG()/BUG_ON(), use -EIO where appropriate - * - smart tree reduction - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -/* - * ext_pblock: - * combine low and high parts of physical block number into ext4_fsblk_t - */ -static inline ext4_fsblk_t ext_pblock(struct ext4_extent *ex) -{ - ext4_fsblk_t block; - - block = le32_to_cpu(ex->ee_start); - block |= ((ext4_fsblk_t) le16_to_cpu(ex->ee_start_hi) << 31) << 1; - return block; -} - -/* - * idx_pblock: - * combine low and high parts of a leaf physical block number into ext4_fsblk_t - */ -static inline ext4_fsblk_t idx_pblock(struct ext4_extent_idx *ix) -{ - ext4_fsblk_t block; - - block = le32_to_cpu(ix->ei_leaf); - block |= ((ext4_fsblk_t) le16_to_cpu(ix->ei_leaf_hi) << 31) << 1; - return block; -} - -/* - * ext4_ext_store_pblock: - * stores a large physical block number into an extent struct, - * breaking it into parts - */ -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); -} - -/* - * ext4_idx_store_pblock: - * stores a large physical block number into an index struct, - * breaking it into parts - */ -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); -} - -static int ext4_ext_check_header(const char *function, struct inode *inode, - struct ext4_extent_header *eh) -{ - const char *error_msg = NULL; - - if (unlikely(eh->eh_magic != EXT4_EXT_MAGIC)) { - error_msg = "invalid magic"; - goto corrupted; - } - if (unlikely(eh->eh_max == 0)) { - error_msg = "invalid eh_max"; - goto corrupted; - } - if (unlikely(le16_to_cpu(eh->eh_entries) > le16_to_cpu(eh->eh_max))) { - error_msg = "invalid eh_entries"; - goto corrupted; - } - return 0; - -corrupted: - ext4_error(inode->i_sb, function, - "bad header in inode #%lu: %s - magic %x, " - "entries %u, max %u, depth %u", - inode->i_ino, error_msg, le16_to_cpu(eh->eh_magic), - le16_to_cpu(eh->eh_entries), le16_to_cpu(eh->eh_max), - le16_to_cpu(eh->eh_depth)); - - return -EIO; -} - -static handle_t *ext4_ext_journal_restart(handle_t *handle, int needed) -{ - int err; - - if (handle->h_buffer_credits > needed) - return handle; - if (!ext4_journal_extend(handle, needed)) - return handle; - err = ext4_journal_restart(handle, needed); - - return handle; -} - -/* - * could return: - * - EROFS - * - ENOMEM - */ -static int ext4_ext_get_access(handle_t *handle, struct inode *inode, - struct ext4_ext_path *path) -{ - if (path->p_bh) { - /* path points to block */ - return ext4_journal_get_write_access(handle, path->p_bh); - } - /* path points to leaf/index in inode body */ - /* we use in-core data, no need to protect them */ - return 0; -} - -/* - * could return: - * - EROFS - * - ENOMEM - * - EIO - */ -static int ext4_ext_dirty(handle_t *handle, struct inode *inode, - struct ext4_ext_path *path) -{ - int err; - if (path->p_bh) { - /* path points to block */ - err = ext4_journal_dirty_metadata(handle, path->p_bh); - } else { - /* path points to leaf/index in inode body */ - err = ext4_mark_inode_dirty(handle, inode); - } - return err; -} - -static ext4_fsblk_t ext4_ext_find_goal(struct inode *inode, - struct ext4_ext_path *path, - ext4_fsblk_t block) -{ - struct ext4_inode_info *ei = EXT4_I(inode); - ext4_fsblk_t bg_start; - ext4_grpblk_t colour; - int depth; - - if (path) { - struct ext4_extent *ex; - depth = path->p_depth; - - /* try to predict block placement */ - if ((ex = path[depth].p_ext)) - return ext_pblock(ex)+(block-le32_to_cpu(ex->ee_block)); - - /* it looks like index is empty; - * try to find starting block from index itself */ - if (path[depth].p_bh) - return path[depth].p_bh->b_blocknr; - } - - /* OK. use inode's group */ - bg_start = (ei->i_block_group * EXT4_BLOCKS_PER_GROUP(inode->i_sb)) + - le32_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_first_data_block); - colour = (current->pid % 16) * - (EXT4_BLOCKS_PER_GROUP(inode->i_sb) / 16); - return bg_start + colour + block; -} - -static ext4_fsblk_t -ext4_ext_new_block(handle_t *handle, struct inode *inode, - struct ext4_ext_path *path, - struct ext4_extent *ex, int *err) -{ - ext4_fsblk_t goal, newblock; - - goal = ext4_ext_find_goal(inode, path, le32_to_cpu(ex->ee_block)); - newblock = ext4_new_block(handle, inode, goal, err); - return newblock; -} - -static inline int ext4_ext_space_block(struct inode *inode) -{ - int size; - - size = (inode->i_sb->s_blocksize - sizeof(struct ext4_extent_header)) - / sizeof(struct ext4_extent); -#ifdef AGRESSIVE_TEST - if (size > 6) - size = 6; -#endif - return size; -} - -static inline int ext4_ext_space_block_idx(struct inode *inode) -{ - int size; - - size = (inode->i_sb->s_blocksize - sizeof(struct ext4_extent_header)) - / sizeof(struct ext4_extent_idx); -#ifdef AGRESSIVE_TEST - if (size > 5) - size = 5; -#endif - return size; -} - -static inline int ext4_ext_space_root(struct inode *inode) -{ - int size; - - size = sizeof(EXT4_I(inode)->i_data); - size -= sizeof(struct ext4_extent_header); - size /= sizeof(struct ext4_extent); -#ifdef AGRESSIVE_TEST - if (size > 3) - size = 3; -#endif - return size; -} - -static inline int ext4_ext_space_root_idx(struct inode *inode) -{ - int size; - - size = sizeof(EXT4_I(inode)->i_data); - size -= sizeof(struct ext4_extent_header); - size /= sizeof(struct ext4_extent_idx); -#ifdef AGRESSIVE_TEST - if (size > 4) - size = 4; -#endif - return size; -} - -#ifdef EXT_DEBUG -static void ext4_ext_show_path(struct inode *inode, struct ext4_ext_path *path) -{ - int k, l = path->p_depth; - - ext_debug("path:"); - for (k = 0; k <= l; k++, path++) { - if (path->p_idx) { - ext_debug(" %d->%llu", le32_to_cpu(path->p_idx->ei_block), - idx_pblock(path->p_idx)); - } else if (path->p_ext) { - ext_debug(" %d:%d:%llu ", - le32_to_cpu(path->p_ext->ee_block), - le16_to_cpu(path->p_ext->ee_len), - ext_pblock(path->p_ext)); - } else - ext_debug(" []"); - } - ext_debug("\n"); -} - -static void ext4_ext_show_leaf(struct inode *inode, struct ext4_ext_path *path) -{ - int depth = ext_depth(inode); - struct ext4_extent_header *eh; - struct ext4_extent *ex; - int i; - - if (!path) - return; - - eh = path[depth].p_hdr; - ex = EXT_FIRST_EXTENT(eh); - - for (i = 0; i < le16_to_cpu(eh->eh_entries); i++, ex++) { - ext_debug("%d:%d:%llu ", le32_to_cpu(ex->ee_block), - le16_to_cpu(ex->ee_len), ext_pblock(ex)); - } - ext_debug("\n"); -} -#else -#define ext4_ext_show_path(inode,path) -#define ext4_ext_show_leaf(inode,path) -#endif - -static void ext4_ext_drop_refs(struct ext4_ext_path *path) -{ - int depth = path->p_depth; - int i; - - for (i = 0; i <= depth; i++, path++) - if (path->p_bh) { - brelse(path->p_bh); - path->p_bh = NULL; - } -} - -/* - * ext4_ext_binsearch_idx: - * binary search for the closest index of the given block - */ -static void -ext4_ext_binsearch_idx(struct inode *inode, struct ext4_ext_path *path, int block) -{ - struct ext4_extent_header *eh = path->p_hdr; - struct ext4_extent_idx *r, *l, *m; - - BUG_ON(eh->eh_magic != EXT4_EXT_MAGIC); - BUG_ON(le16_to_cpu(eh->eh_entries) > le16_to_cpu(eh->eh_max)); - BUG_ON(le16_to_cpu(eh->eh_entries) <= 0); - - ext_debug("binsearch for %d(idx): ", block); - - l = EXT_FIRST_INDEX(eh) + 1; - r = EXT_FIRST_INDEX(eh) + le16_to_cpu(eh->eh_entries) - 1; - while (l <= r) { - m = l + (r - l) / 2; - if (block < le32_to_cpu(m->ei_block)) - r = m - 1; - else - l = m + 1; - ext_debug("%p(%u):%p(%u):%p(%u) ", l, l->ei_block, - m, m->ei_block, r, r->ei_block); - } - - path->p_idx = l - 1; - ext_debug(" -> %d->%lld ", le32_to_cpu(path->p_idx->ei_block), - idx_block(path->p_idx)); - -#ifdef CHECK_BINSEARCH - { - struct ext4_extent_idx *chix, *ix; - int k; - - chix = ix = EXT_FIRST_INDEX(eh); - for (k = 0; k < le16_to_cpu(eh->eh_entries); k++, ix++) { - if (k != 0 && - le32_to_cpu(ix->ei_block) <= le32_to_cpu(ix[-1].ei_block)) { - printk("k=%d, ix=0x%p, first=0x%p\n", k, - ix, EXT_FIRST_INDEX(eh)); - printk("%u <= %u\n", - le32_to_cpu(ix->ei_block), - le32_to_cpu(ix[-1].ei_block)); - } - BUG_ON(k && le32_to_cpu(ix->ei_block) - <= le32_to_cpu(ix[-1].ei_block)); - if (block < le32_to_cpu(ix->ei_block)) - break; - chix = ix; - } - BUG_ON(chix != path->p_idx); - } -#endif - -} - -/* - * ext4_ext_binsearch: - * binary search for closest extent of the given block - */ -static void -ext4_ext_binsearch(struct inode *inode, struct ext4_ext_path *path, int block) -{ - struct ext4_extent_header *eh = path->p_hdr; - struct ext4_extent *r, *l, *m; - - BUG_ON(eh->eh_magic != EXT4_EXT_MAGIC); - BUG_ON(le16_to_cpu(eh->eh_entries) > le16_to_cpu(eh->eh_max)); - - if (eh->eh_entries == 0) { - /* - * this leaf is empty: - * we get such a leaf in split/add case - */ - return; - } - - ext_debug("binsearch for %d: ", block); - - l = EXT_FIRST_EXTENT(eh) + 1; - r = EXT_FIRST_EXTENT(eh) + le16_to_cpu(eh->eh_entries) - 1; - - while (l <= r) { - m = l + (r - l) / 2; - if (block < le32_to_cpu(m->ee_block)) - r = m - 1; - else - l = m + 1; - ext_debug("%p(%u):%p(%u):%p(%u) ", l, l->ee_block, - m, m->ee_block, r, r->ee_block); - } - - path->p_ext = l - 1; - ext_debug(" -> %d:%llu:%d ", - le32_to_cpu(path->p_ext->ee_block), - ext_pblock(path->p_ext), - le16_to_cpu(path->p_ext->ee_len)); - -#ifdef CHECK_BINSEARCH - { - struct ext4_extent *chex, *ex; - int k; - - chex = ex = EXT_FIRST_EXTENT(eh); - for (k = 0; k < le16_to_cpu(eh->eh_entries); k++, ex++) { - BUG_ON(k && le32_to_cpu(ex->ee_block) - <= le32_to_cpu(ex[-1].ee_block)); - if (block < le32_to_cpu(ex->ee_block)) - break; - chex = ex; - } - BUG_ON(chex != path->p_ext); - } -#endif - -} - -int ext4_ext_tree_init(handle_t *handle, struct inode *inode) -{ - struct ext4_extent_header *eh; - - eh = ext_inode_hdr(inode); - eh->eh_depth = 0; - eh->eh_entries = 0; - eh->eh_magic = EXT4_EXT_MAGIC; - eh->eh_max = cpu_to_le16(ext4_ext_space_root(inode)); - ext4_mark_inode_dirty(handle, inode); - ext4_ext_invalidate_cache(inode); - return 0; -} - -struct ext4_ext_path * -ext4_ext_find_extent(struct inode *inode, int block, struct ext4_ext_path *path) -{ - struct ext4_extent_header *eh; - struct buffer_head *bh; - short int depth, i, ppos = 0, alloc = 0; - - eh = ext_inode_hdr(inode); - BUG_ON(eh == NULL); - if (ext4_ext_check_header(__FUNCTION__, inode, eh)) - return ERR_PTR(-EIO); - - i = depth = ext_depth(inode); - - /* account possible depth increase */ - if (!path) { - 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 */ - while (i) { - ext_debug("depth %d: num %d, max %d\n", - ppos, le16_to_cpu(eh->eh_entries), le16_to_cpu(eh->eh_max)); - ext4_ext_binsearch_idx(inode, path + ppos, block); - path[ppos].p_block = idx_pblock(path[ppos].p_idx); - path[ppos].p_depth = i; - path[ppos].p_ext = NULL; - - bh = sb_bread(inode->i_sb, path[ppos].p_block); - if (!bh) - goto err; - - eh = ext_block_hdr(bh); - ppos++; - BUG_ON(ppos > depth); - path[ppos].p_bh = bh; - path[ppos].p_hdr = eh; - i--; - - if (ext4_ext_check_header(__FUNCTION__, inode, eh)) - goto err; - } - - path[ppos].p_depth = i; - path[ppos].p_hdr = eh; - path[ppos].p_ext = NULL; - path[ppos].p_idx = NULL; - - if (ext4_ext_check_header(__FUNCTION__, inode, eh)) - goto err; - - /* find extent */ - ext4_ext_binsearch(inode, path + ppos, block); - - ext4_ext_show_path(inode, path); - - return path; - -err: - ext4_ext_drop_refs(path); - if (alloc) - kfree(path); - return ERR_PTR(-EIO); -} - -/* - * ext4_ext_insert_index: - * insert new index [@logical;@ptr] into the block at @curp; - * check where to insert: before @curp or after @curp - */ -static int ext4_ext_insert_index(handle_t *handle, struct inode *inode, - struct ext4_ext_path *curp, - int logical, ext4_fsblk_t ptr) -{ - struct ext4_extent_idx *ix; - int len, err; - - if ((err = ext4_ext_get_access(handle, inode, curp))) - return err; - - BUG_ON(logical == le32_to_cpu(curp->p_idx->ei_block)); - len = EXT_MAX_INDEX(curp->p_hdr) - curp->p_idx; - if (logical > le32_to_cpu(curp->p_idx->ei_block)) { - /* insert after */ - if (curp->p_idx != EXT_LAST_INDEX(curp->p_hdr)) { - len = (len - 1) * sizeof(struct ext4_extent_idx); - len = len < 0 ? 0 : len; - ext_debug("insert new index %d after: %d. " - "move %d from 0x%p to 0x%p\n", - logical, ptr, len, - (curp->p_idx + 1), (curp->p_idx + 2)); - memmove(curp->p_idx + 2, curp->p_idx + 1, len); - } - ix = curp->p_idx + 1; - } else { - /* insert before */ - len = len * sizeof(struct ext4_extent_idx); - len = len < 0 ? 0 : len; - ext_debug("insert new index %d before: %d. " - "move %d from 0x%p to 0x%p\n", - logical, ptr, len, - curp->p_idx, (curp->p_idx + 1)); - memmove(curp->p_idx + 1, curp->p_idx, len); - ix = curp->p_idx; - } - - ix->ei_block = cpu_to_le32(logical); - ext4_idx_store_pblock(ix, ptr); - curp->p_hdr->eh_entries = cpu_to_le16(le16_to_cpu(curp->p_hdr->eh_entries)+1); - - BUG_ON(le16_to_cpu(curp->p_hdr->eh_entries) - > le16_to_cpu(curp->p_hdr->eh_max)); - BUG_ON(ix > EXT_LAST_INDEX(curp->p_hdr)); - - err = ext4_ext_dirty(handle, inode, curp); - ext4_std_error(inode->i_sb, err); - - return err; -} - -/* - * ext4_ext_split: - * inserts new subtree into the path, using free index entry - * at depth @at: - * - allocates all needed blocks (new leaf and all intermediate index blocks) - * - makes decision where to split - * - moves remaining extents and index entries (right to the split point) - * into the newly allocated blocks - * - initializes subtree - */ -static int ext4_ext_split(handle_t *handle, struct inode *inode, - struct ext4_ext_path *path, - struct ext4_extent *newext, int at) -{ - struct buffer_head *bh = NULL; - int depth = ext_depth(inode); - struct ext4_extent_header *neh; - struct ext4_extent_idx *fidx; - struct ext4_extent *ex; - int i = at, k, m, a; - ext4_fsblk_t newblock, oldblock; - __le32 border; - ext4_fsblk_t *ablocks = NULL; /* array of allocated blocks */ - int err = 0; - - /* make decision: where to split? */ - /* FIXME: now decision is simplest: at current extent */ - - /* if current leaf will be split, then we should use - * border from split point */ - BUG_ON(path[depth].p_ext > EXT_MAX_EXTENT(path[depth].p_hdr)); - if (path[depth].p_ext != EXT_MAX_EXTENT(path[depth].p_hdr)) { - border = path[depth].p_ext[1].ee_block; - ext_debug("leaf will be split." - " next leaf starts at %d\n", - le32_to_cpu(border)); - } else { - border = newext->ee_block; - ext_debug("leaf will be added." - " next leaf starts at %d\n", - le32_to_cpu(border)); - } - - /* - * If error occurs, then we break processing - * and mark filesystem read-only. index won't - * be inserted and tree will be in consistent - * state. Next mount will repair buffers too. - */ - - /* - * Get array to track all allocated blocks. - * We need this to handle errors and free blocks - * upon them. - */ - 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); - for (a = 0; a < depth - at; a++) { - newblock = ext4_ext_new_block(handle, inode, path, newext, &err); - if (newblock == 0) - goto cleanup; - ablocks[a] = newblock; - } - - /* initialize new leaf */ - newblock = ablocks[--a]; - BUG_ON(newblock == 0); - bh = sb_getblk(inode->i_sb, newblock); - if (!bh) { - err = -EIO; - goto cleanup; - } - lock_buffer(bh); - - if ((err = ext4_journal_get_create_access(handle, bh))) - goto cleanup; - - neh = ext_block_hdr(bh); - neh->eh_entries = 0; - neh->eh_max = cpu_to_le16(ext4_ext_space_block(inode)); - neh->eh_magic = EXT4_EXT_MAGIC; - neh->eh_depth = 0; - ex = EXT_FIRST_EXTENT(neh); - - /* move remainder of path[depth] to the new leaf */ - BUG_ON(path[depth].p_hdr->eh_entries != path[depth].p_hdr->eh_max); - /* start copy from next extent */ - /* TODO: we could do it by single memmove */ - m = 0; - path[depth].p_ext++; - while (path[depth].p_ext <= - EXT_MAX_EXTENT(path[depth].p_hdr)) { - ext_debug("move %d:%llu:%d in new leaf %llu\n", - le32_to_cpu(path[depth].p_ext->ee_block), - ext_pblock(path[depth].p_ext), - le16_to_cpu(path[depth].p_ext->ee_len), - newblock); - /*memmove(ex++, path[depth].p_ext++, - sizeof(struct ext4_extent)); - neh->eh_entries++;*/ - path[depth].p_ext++; - m++; - } - if (m) { - memmove(ex, path[depth].p_ext-m, sizeof(struct ext4_extent)*m); - neh->eh_entries = cpu_to_le16(le16_to_cpu(neh->eh_entries)+m); - } - - set_buffer_uptodate(bh); - unlock_buffer(bh); - - if ((err = ext4_journal_dirty_metadata(handle, bh))) - goto cleanup; - brelse(bh); - bh = NULL; - - /* correct old leaf */ - if (m) { - 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); - if ((err = ext4_ext_dirty(handle, inode, path + depth))) - goto cleanup; - - } - - /* create intermediate indexes */ - k = depth - at - 1; - BUG_ON(k < 0); - if (k) - ext_debug("create %d intermediate indices\n", k); - /* insert new index into current index block */ - /* current depth stored in i var */ - i = depth - 1; - while (k--) { - oldblock = newblock; - newblock = ablocks[--a]; - bh = sb_getblk(inode->i_sb, (ext4_fsblk_t)newblock); - if (!bh) { - err = -EIO; - goto cleanup; - } - lock_buffer(bh); - - if ((err = ext4_journal_get_create_access(handle, bh))) - goto cleanup; - - neh = ext_block_hdr(bh); - neh->eh_entries = cpu_to_le16(1); - neh->eh_magic = EXT4_EXT_MAGIC; - neh->eh_max = cpu_to_le16(ext4_ext_space_block_idx(inode)); - neh->eh_depth = cpu_to_le16(depth - i); - fidx = EXT_FIRST_INDEX(neh); - fidx->ei_block = border; - ext4_idx_store_pblock(fidx, oldblock); - - ext_debug("int.index at %d (block %llu): %lu -> %llu\n", i, - newblock, (unsigned long) le32_to_cpu(border), - oldblock); - /* copy indexes */ - m = 0; - path[i].p_idx++; - - ext_debug("cur 0x%p, last 0x%p\n", path[i].p_idx, - EXT_MAX_INDEX(path[i].p_hdr)); - BUG_ON(EXT_MAX_INDEX(path[i].p_hdr) != - EXT_LAST_INDEX(path[i].p_hdr)); - while (path[i].p_idx <= EXT_MAX_INDEX(path[i].p_hdr)) { - ext_debug("%d: move %d:%d in new index %llu\n", i, - le32_to_cpu(path[i].p_idx->ei_block), - idx_pblock(path[i].p_idx), - newblock); - /*memmove(++fidx, path[i].p_idx++, - sizeof(struct ext4_extent_idx)); - neh->eh_entries++; - BUG_ON(neh->eh_entries > neh->eh_max);*/ - path[i].p_idx++; - m++; - } - if (m) { - memmove(++fidx, path[i].p_idx - m, - sizeof(struct ext4_extent_idx) * m); - neh->eh_entries = - cpu_to_le16(le16_to_cpu(neh->eh_entries) + m); - } - set_buffer_uptodate(bh); - unlock_buffer(bh); - - if ((err = ext4_journal_dirty_metadata(handle, bh))) - goto cleanup; - brelse(bh); - bh = NULL; - - /* correct old index */ - if (m) { - err = ext4_ext_get_access(handle, inode, path + i); - if (err) - goto cleanup; - path[i].p_hdr->eh_entries = cpu_to_le16(le16_to_cpu(path[i].p_hdr->eh_entries)-m); - err = ext4_ext_dirty(handle, inode, path + i); - if (err) - goto cleanup; - } - - i--; - } - - /* insert new index */ - if (err) - goto cleanup; - - err = ext4_ext_insert_index(handle, inode, path + at, - le32_to_cpu(border), newblock); - -cleanup: - if (bh) { - if (buffer_locked(bh)) - unlock_buffer(bh); - brelse(bh); - } - - if (err) { - /* free all allocated blocks in error case */ - for (i = 0; i < depth; i++) { - if (!ablocks[i]) - continue; - ext4_free_blocks(handle, inode, ablocks[i], 1); - } - } - kfree(ablocks); - - return err; -} - -/* - * ext4_ext_grow_indepth: - * implements tree growing procedure: - * - allocates new block - * - moves top-level data (index block or leaf) into the new block - * - initializes new top-level, creating index that points to the - * just created block - */ -static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode, - struct ext4_ext_path *path, - struct ext4_extent *newext) -{ - struct ext4_ext_path *curp = path; - struct ext4_extent_header *neh; - struct ext4_extent_idx *fidx; - struct buffer_head *bh; - ext4_fsblk_t newblock; - int err = 0; - - newblock = ext4_ext_new_block(handle, inode, path, newext, &err); - if (newblock == 0) - return err; - - bh = sb_getblk(inode->i_sb, newblock); - if (!bh) { - err = -EIO; - ext4_std_error(inode->i_sb, err); - return err; - } - lock_buffer(bh); - - if ((err = ext4_journal_get_create_access(handle, bh))) { - unlock_buffer(bh); - goto out; - } - - /* move top-level index/leaf into new block */ - memmove(bh->b_data, curp->p_hdr, sizeof(EXT4_I(inode)->i_data)); - - /* set size of new block */ - neh = ext_block_hdr(bh); - /* old root could have indexes or leaves - * so calculate e_max right way */ - if (ext_depth(inode)) - neh->eh_max = cpu_to_le16(ext4_ext_space_block_idx(inode)); - else - neh->eh_max = cpu_to_le16(ext4_ext_space_block(inode)); - neh->eh_magic = EXT4_EXT_MAGIC; - set_buffer_uptodate(bh); - unlock_buffer(bh); - - if ((err = ext4_journal_dirty_metadata(handle, bh))) - goto out; - - /* create index in new top-level index: num,max,pointer */ - if ((err = ext4_ext_get_access(handle, inode, curp))) - goto out; - - curp->p_hdr->eh_magic = EXT4_EXT_MAGIC; - curp->p_hdr->eh_max = cpu_to_le16(ext4_ext_space_root_idx(inode)); - curp->p_hdr->eh_entries = cpu_to_le16(1); - curp->p_idx = EXT_FIRST_INDEX(curp->p_hdr); - /* FIXME: it works, but actually path[0] can be index */ - curp->p_idx->ei_block = EXT_FIRST_EXTENT(path[0].p_hdr)->ee_block; - ext4_idx_store_pblock(curp->p_idx, newblock); - - neh = ext_inode_hdr(inode); - fidx = EXT_FIRST_INDEX(neh); - ext_debug("new root: num %d(%d), lblock %d, ptr %llu\n", - le16_to_cpu(neh->eh_entries), le16_to_cpu(neh->eh_max), - le32_to_cpu(fidx->ei_block), idx_pblock(fidx)); - - neh->eh_depth = cpu_to_le16(path->p_depth + 1); - err = ext4_ext_dirty(handle, inode, curp); -out: - brelse(bh); - - return err; -} - -/* - * ext4_ext_create_new_leaf: - * finds empty index and adds new leaf. - * if no free index is found, then it requests in-depth growing. - */ -static int ext4_ext_create_new_leaf(handle_t *handle, struct inode *inode, - struct ext4_ext_path *path, - struct ext4_extent *newext) -{ - struct ext4_ext_path *curp; - int depth, i, err = 0; - -repeat: - i = depth = ext_depth(inode); - - /* walk up to the tree and look for free index entry */ - curp = path + depth; - while (i > 0 && !EXT_HAS_FREE_INDEX(curp)) { - i--; - curp--; - } - - /* we use already allocated block for index block, - * so subsequent data blocks should be contiguous */ - if (EXT_HAS_FREE_INDEX(curp)) { - /* if we found index with free entry, then use that - * entry: create all needed subtree and add new leaf */ - err = ext4_ext_split(handle, inode, path, newext, i); - - /* refill path */ - ext4_ext_drop_refs(path); - path = ext4_ext_find_extent(inode, - le32_to_cpu(newext->ee_block), - path); - if (IS_ERR(path)) - err = PTR_ERR(path); - } else { - /* tree is full, time to grow in depth */ - err = ext4_ext_grow_indepth(handle, inode, path, newext); - if (err) - goto out; - - /* refill path */ - ext4_ext_drop_refs(path); - path = ext4_ext_find_extent(inode, - le32_to_cpu(newext->ee_block), - path); - if (IS_ERR(path)) { - err = PTR_ERR(path); - goto out; - } - - /* - * only first (depth 0 -> 1) produces free space; - * in all other cases we have to split the grown tree - */ - depth = ext_depth(inode); - if (path[depth].p_hdr->eh_entries == path[depth].p_hdr->eh_max) { - /* now we need to split */ - goto repeat; - } - } - -out: - return err; -} - -/* - * ext4_ext_next_allocated_block: - * returns allocated block in subsequent extent or EXT_MAX_BLOCK. - * NOTE: it considers block number from index entry as - * allocated block. Thus, index entries have to be consistent - * with leaves. - */ -static unsigned long -ext4_ext_next_allocated_block(struct ext4_ext_path *path) -{ - int depth; - - BUG_ON(path == NULL); - depth = path->p_depth; - - if (depth == 0 && path->p_ext == NULL) - return EXT_MAX_BLOCK; - - while (depth >= 0) { - if (depth == path->p_depth) { - /* leaf */ - if (path[depth].p_ext != - EXT_LAST_EXTENT(path[depth].p_hdr)) - return le32_to_cpu(path[depth].p_ext[1].ee_block); - } else { - /* index */ - if (path[depth].p_idx != - EXT_LAST_INDEX(path[depth].p_hdr)) - return le32_to_cpu(path[depth].p_idx[1].ei_block); - } - depth--; - } - - return EXT_MAX_BLOCK; -} - -/* - * ext4_ext_next_leaf_block: - * returns first allocated block from next leaf or EXT_MAX_BLOCK - */ -static unsigned ext4_ext_next_leaf_block(struct inode *inode, - struct ext4_ext_path *path) -{ - int depth; - - BUG_ON(path == NULL); - depth = path->p_depth; - - /* zero-tree has no leaf blocks at all */ - if (depth == 0) - return EXT_MAX_BLOCK; - - /* go to index block */ - depth--; - - while (depth >= 0) { - if (path[depth].p_idx != - EXT_LAST_INDEX(path[depth].p_hdr)) - return le32_to_cpu(path[depth].p_idx[1].ei_block); - depth--; - } - - return EXT_MAX_BLOCK; -} - -/* - * ext4_ext_correct_indexes: - * if leaf gets modified and modified extent is first in the leaf, - * then we have to correct all indexes above. - * TODO: do we need to correct tree in all cases? - */ -int ext4_ext_correct_indexes(handle_t *handle, struct inode *inode, - struct ext4_ext_path *path) -{ - struct ext4_extent_header *eh; - int depth = ext_depth(inode); - struct ext4_extent *ex; - __le32 border; - int k, err = 0; - - eh = path[depth].p_hdr; - ex = path[depth].p_ext; - BUG_ON(ex == NULL); - BUG_ON(eh == NULL); - - if (depth == 0) { - /* there is no tree at all */ - return 0; - } - - if (ex != EXT_FIRST_EXTENT(eh)) { - /* we correct tree if first leaf got modified only */ - return 0; - } - - /* - * TODO: we need correction if border is smaller than current one - */ - k = depth - 1; - border = path[depth].p_ext->ee_block; - if ((err = ext4_ext_get_access(handle, inode, path + k))) - return err; - path[k].p_idx->ei_block = border; - 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; - if ((err = ext4_ext_get_access(handle, inode, path + k))) - break; - path[k].p_idx->ei_block = border; - if ((err = ext4_ext_dirty(handle, inode, path + k))) - break; - } - - return err; -} - -static int inline -ext4_can_extents_be_merged(struct inode *inode, struct ext4_extent *ex1, - struct ext4_extent *ex2) -{ - if (le32_to_cpu(ex1->ee_block) + le16_to_cpu(ex1->ee_len) != - le32_to_cpu(ex2->ee_block)) - return 0; - - /* - * To allow future support for preallocated extents to be added - * as an RO_COMPAT feature, refuse to merge to extents if - * this can result in the top bit of ee_len being set. - */ - if (le16_to_cpu(ex1->ee_len) + le16_to_cpu(ex2->ee_len) > EXT_MAX_LEN) - return 0; -#ifdef AGRESSIVE_TEST - if (le16_to_cpu(ex1->ee_len) >= 4) - return 0; -#endif - - if (ext_pblock(ex1) + le16_to_cpu(ex1->ee_len) == ext_pblock(ex2)) - return 1; - return 0; -} - -/* - * ext4_ext_insert_extent: - * tries to merge requsted extent into the existing extent or - * inserts requested extent as new one into the tree, - * creating new leaf in the no-space case. - */ -int ext4_ext_insert_extent(handle_t *handle, struct inode *inode, - struct ext4_ext_path *path, - struct ext4_extent *newext) -{ - struct ext4_extent_header * eh; - struct ext4_extent *ex, *fex; - struct ext4_extent *nearex; /* nearest extent */ - struct ext4_ext_path *npath = NULL; - int depth, len, err, next; - - BUG_ON(newext->ee_len == 0); - depth = ext_depth(inode); - ex = path[depth].p_ext; - BUG_ON(path[depth].p_hdr == NULL); - - /* try to insert block into found extent and return */ - if (ex && ext4_can_extents_be_merged(inode, ex, newext)) { - ext_debug("append %d block to %d:%d (from %llu)\n", - le16_to_cpu(newext->ee_len), - le32_to_cpu(ex->ee_block), - le16_to_cpu(ex->ee_len), ext_pblock(ex)); - 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)); - eh = path[depth].p_hdr; - nearex = ex; - goto merge; - } - -repeat: - depth = ext_depth(inode); - eh = path[depth].p_hdr; - if (le16_to_cpu(eh->eh_entries) < le16_to_cpu(eh->eh_max)) - goto has_space; - - /* probably next leaf has space for us? */ - fex = EXT_LAST_EXTENT(eh); - next = ext4_ext_next_leaf_block(inode, path); - if (le32_to_cpu(newext->ee_block) > le32_to_cpu(fex->ee_block) - && next != EXT_MAX_BLOCK) { - ext_debug("next leaf block - %d\n", next); - BUG_ON(npath != NULL); - npath = ext4_ext_find_extent(inode, next, NULL); - if (IS_ERR(npath)) - return PTR_ERR(npath); - BUG_ON(npath->p_depth != path->p_depth); - eh = npath[depth].p_hdr; - if (le16_to_cpu(eh->eh_entries) < le16_to_cpu(eh->eh_max)) { - ext_debug("next leaf isnt full(%d)\n", - le16_to_cpu(eh->eh_entries)); - path = npath; - goto repeat; - } - ext_debug("next leaf has no free space(%d,%d)\n", - le16_to_cpu(eh->eh_entries), le16_to_cpu(eh->eh_max)); - } - - /* - * There is no free space in the found leaf. - * We're gonna add a new leaf in the tree. - */ - err = ext4_ext_create_new_leaf(handle, inode, path, newext); - if (err) - goto cleanup; - depth = ext_depth(inode); - eh = path[depth].p_hdr; - -has_space: - nearex = path[depth].p_ext; - - if ((err = ext4_ext_get_access(handle, inode, path + depth))) - goto cleanup; - - if (!nearex) { - /* there is no extent in this leaf, create first one */ - ext_debug("first extent in the leaf: %d:%llu:%d\n", - le32_to_cpu(newext->ee_block), - ext_pblock(newext), - le16_to_cpu(newext->ee_len)); - path[depth].p_ext = EXT_FIRST_EXTENT(eh); - } else if (le32_to_cpu(newext->ee_block) - > le32_to_cpu(nearex->ee_block)) { -/* BUG_ON(newext->ee_block == nearex->ee_block); */ - if (nearex != EXT_LAST_EXTENT(eh)) { - len = EXT_MAX_EXTENT(eh) - nearex; - len = (len - 1) * sizeof(struct ext4_extent); - len = len < 0 ? 0 : len; - ext_debug("insert %d:%llu:%d after: nearest 0x%p, " - "move %d from 0x%p to 0x%p\n", - le32_to_cpu(newext->ee_block), - ext_pblock(newext), - le16_to_cpu(newext->ee_len), - nearex, len, nearex + 1, nearex + 2); - memmove(nearex + 2, nearex + 1, len); - } - path[depth].p_ext = nearex + 1; - } else { - BUG_ON(newext->ee_block == nearex->ee_block); - len = (EXT_MAX_EXTENT(eh) - nearex) * sizeof(struct ext4_extent); - len = len < 0 ? 0 : len; - ext_debug("insert %d:%llu:%d before: nearest 0x%p, " - "move %d from 0x%p to 0x%p\n", - le32_to_cpu(newext->ee_block), - ext_pblock(newext), - le16_to_cpu(newext->ee_len), - nearex, len, nearex + 1, nearex + 2); - memmove(nearex + 1, nearex, len); - path[depth].p_ext = nearex; - } - - eh->eh_entries = cpu_to_le16(le16_to_cpu(eh->eh_entries)+1); - nearex = path[depth].p_ext; - nearex->ee_block = newext->ee_block; - nearex->ee_start = newext->ee_start; - nearex->ee_start_hi = newext->ee_start_hi; - nearex->ee_len = newext->ee_len; - -merge: - /* try to merge extents to the right */ - while (nearex < EXT_LAST_EXTENT(eh)) { - if (!ext4_can_extents_be_merged(inode, nearex, nearex + 1)) - break; - /* merge with next extent! */ - nearex->ee_len = cpu_to_le16(le16_to_cpu(nearex->ee_len) - + le16_to_cpu(nearex[1].ee_len)); - if (nearex + 1 < EXT_LAST_EXTENT(eh)) { - len = (EXT_LAST_EXTENT(eh) - nearex - 1) - * sizeof(struct ext4_extent); - memmove(nearex + 1, nearex + 2, len); - } - eh->eh_entries = cpu_to_le16(le16_to_cpu(eh->eh_entries)-1); - BUG_ON(eh->eh_entries == 0); - } - - /* try to merge extents to the left */ - - /* time to correct all indexes above */ - err = ext4_ext_correct_indexes(handle, inode, path); - if (err) - goto cleanup; - - err = ext4_ext_dirty(handle, inode, path + depth); - -cleanup: - if (npath) { - ext4_ext_drop_refs(npath); - kfree(npath); - } - ext4_ext_tree_changed(inode); - ext4_ext_invalidate_cache(inode); - return err; -} - -int ext4_ext_walk_space(struct inode *inode, unsigned long block, - unsigned long num, ext_prepare_callback func, - void *cbdata) -{ - struct ext4_ext_path *path = NULL; - struct ext4_ext_cache cbex; - struct ext4_extent *ex; - unsigned long next, start = 0, end = 0; - unsigned long last = block + num; - int depth, exists, err = 0; - - BUG_ON(func == NULL); - BUG_ON(inode == NULL); - - while (block < last && block != EXT_MAX_BLOCK) { - num = last - block; - /* find extent for this block */ - path = ext4_ext_find_extent(inode, block, path); - if (IS_ERR(path)) { - err = PTR_ERR(path); - path = NULL; - break; - } - - depth = ext_depth(inode); - BUG_ON(path[depth].p_hdr == NULL); - ex = path[depth].p_ext; - next = ext4_ext_next_allocated_block(path); - - exists = 0; - if (!ex) { - /* there is no extent yet, so try to allocate - * all requested space */ - start = block; - end = block + num; - } else if (le32_to_cpu(ex->ee_block) > block) { - /* need to allocate space before found extent */ - start = block; - end = le32_to_cpu(ex->ee_block); - if (block + num < end) - end = block + num; - } else if (block >= - le32_to_cpu(ex->ee_block) + le16_to_cpu(ex->ee_len)) { - /* need to allocate space after found extent */ - start = block; - end = block + num; - if (end >= next) - end = next; - } else if (block >= le32_to_cpu(ex->ee_block)) { - /* - * some part of requested space is covered - * by found extent - */ - start = block; - end = le32_to_cpu(ex->ee_block) + le16_to_cpu(ex->ee_len); - if (block + num < end) - end = block + num; - exists = 1; - } else { - BUG(); - } - BUG_ON(end <= start); - - if (!exists) { - cbex.ec_block = start; - cbex.ec_len = end - start; - cbex.ec_start = 0; - cbex.ec_type = EXT4_EXT_CACHE_GAP; - } else { - cbex.ec_block = le32_to_cpu(ex->ee_block); - cbex.ec_len = le16_to_cpu(ex->ee_len); - cbex.ec_start = ext_pblock(ex); - cbex.ec_type = EXT4_EXT_CACHE_EXTENT; - } - - BUG_ON(cbex.ec_len == 0); - err = func(inode, path, &cbex, cbdata); - ext4_ext_drop_refs(path); - - if (err < 0) - break; - if (err == EXT_REPEAT) - continue; - else if (err == EXT_BREAK) { - err = 0; - break; - } - - if (ext_depth(inode) != depth) { - /* depth was changed. we have to realloc path */ - kfree(path); - path = NULL; - } - - block = cbex.ec_block + cbex.ec_len; - } - - if (path) { - ext4_ext_drop_refs(path); - kfree(path); - } - - return err; -} - -static inline void -ext4_ext_put_in_cache(struct inode *inode, __u32 block, - __u32 len, __u32 start, int type) -{ - struct ext4_ext_cache *cex; - BUG_ON(len == 0); - cex = &EXT4_I(inode)->i_cached_extent; - cex->ec_type = type; - cex->ec_block = block; - cex->ec_len = len; - cex->ec_start = start; -} - -/* - * ext4_ext_put_gap_in_cache: - * calculate boundaries of the gap that the requested block fits into - * and cache this gap - */ -static inline void -ext4_ext_put_gap_in_cache(struct inode *inode, struct ext4_ext_path *path, - unsigned long block) -{ - int depth = ext_depth(inode); - unsigned long lblock, len; - struct ext4_extent *ex; - - ex = path[depth].p_ext; - if (ex == NULL) { - /* there is no extent yet, so gap is [0;-] */ - lblock = 0; - len = EXT_MAX_BLOCK; - ext_debug("cache gap(whole file):"); - } else if (block < le32_to_cpu(ex->ee_block)) { - lblock = block; - len = le32_to_cpu(ex->ee_block) - block; - ext_debug("cache gap(before): %lu [%lu:%lu]", - (unsigned long) block, - (unsigned long) le32_to_cpu(ex->ee_block), - (unsigned long) le16_to_cpu(ex->ee_len)); - } else if (block >= le32_to_cpu(ex->ee_block) - + le16_to_cpu(ex->ee_len)) { - lblock = le32_to_cpu(ex->ee_block) - + le16_to_cpu(ex->ee_len); - len = ext4_ext_next_allocated_block(path); - ext_debug("cache gap(after): [%lu:%lu] %lu", - (unsigned long) le32_to_cpu(ex->ee_block), - (unsigned long) le16_to_cpu(ex->ee_len), - (unsigned long) block); - BUG_ON(len == lblock); - len = len - lblock; - } else { - lblock = len = 0; - BUG(); - } - - ext_debug(" -> %lu:%lu\n", (unsigned long) lblock, len); - ext4_ext_put_in_cache(inode, lblock, len, 0, EXT4_EXT_CACHE_GAP); -} - -static inline int -ext4_ext_in_cache(struct inode *inode, unsigned long block, - struct ext4_extent *ex) -{ - struct ext4_ext_cache *cex; - - cex = &EXT4_I(inode)->i_cached_extent; - - /* has cache valid data? */ - if (cex->ec_type == EXT4_EXT_CACHE_NO) - return EXT4_EXT_CACHE_NO; - - BUG_ON(cex->ec_type != EXT4_EXT_CACHE_GAP && - cex->ec_type != EXT4_EXT_CACHE_EXTENT); - if (block >= cex->ec_block && block < cex->ec_block + cex->ec_len) { - ex->ee_block = cpu_to_le32(cex->ec_block); - ext4_ext_store_pblock(ex, cex->ec_start); - ex->ee_len = cpu_to_le16(cex->ec_len); - ext_debug("%lu cached by %lu:%lu:%llu\n", - (unsigned long) block, - (unsigned long) cex->ec_block, - (unsigned long) cex->ec_len, - cex->ec_start); - return cex->ec_type; - } - - /* not in cache */ - return EXT4_EXT_CACHE_NO; -} - -/* - * ext4_ext_rm_idx: - * removes index from the index block. - * It's used in truncate case only, thus all requests are for - * last index in the block only. - */ -int ext4_ext_rm_idx(handle_t *handle, struct inode *inode, - struct ext4_ext_path *path) -{ - struct buffer_head *bh; - int err; - ext4_fsblk_t leaf; - - /* free index block */ - path--; - leaf = idx_pblock(path->p_idx); - BUG_ON(path->p_hdr->eh_entries == 0); - 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); - 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); - ext4_forget(handle, 1, inode, bh, leaf); - ext4_free_blocks(handle, inode, leaf, 1); - return err; -} - -/* - * ext4_ext_calc_credits_for_insert: - * This routine returns max. credits that the extent tree can consume. - * It should be OK for low-performance paths like ->writepage() - * To allow many writing processes to fit into a single transaction, - * the caller should calculate credits under truncate_mutex and - * pass the actual path. - */ -int inline ext4_ext_calc_credits_for_insert(struct inode *inode, - struct ext4_ext_path *path) -{ - int depth, needed; - - if (path) { - /* probably there is space in leaf? */ - depth = ext_depth(inode); - if (le16_to_cpu(path[depth].p_hdr->eh_entries) - < le16_to_cpu(path[depth].p_hdr->eh_max)) - return 1; - } - - /* - * given 32-bit logical block (4294967296 blocks), max. tree - * can be 4 levels in depth -- 4 * 340^4 == 53453440000. - * Let's also add one more level for imbalance. - */ - depth = 5; - - /* allocation of new data block(s) */ - needed = 2; - - /* - * tree can be full, so it would need to grow in depth: - * allocation + old root + new root - */ - 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); - - /* any allocation modifies superblock */ - needed += 1; - - return needed; -} - -static int ext4_remove_blocks(handle_t *handle, struct inode *inode, - struct ext4_extent *ex, - unsigned long from, unsigned long to) -{ - struct buffer_head *bh; - int i; - -#ifdef EXTENTS_STATS - { - struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); - unsigned short ee_len = le16_to_cpu(ex->ee_len); - spin_lock(&sbi->s_ext_stats_lock); - sbi->s_ext_blocks += ee_len; - sbi->s_ext_extents++; - if (ee_len < sbi->s_ext_min) - sbi->s_ext_min = ee_len; - if (ee_len > sbi->s_ext_max) - sbi->s_ext_max = ee_len; - if (ext_depth(inode) > sbi->s_depth_max) - sbi->s_depth_max = ext_depth(inode); - spin_unlock(&sbi->s_ext_stats_lock); - } -#endif - if (from >= le32_to_cpu(ex->ee_block) - && to == le32_to_cpu(ex->ee_block) + le16_to_cpu(ex->ee_len) - 1) { - /* tail removal */ - unsigned long num; - ext4_fsblk_t start; - num = le32_to_cpu(ex->ee_block) + le16_to_cpu(ex->ee_len) - from; - start = ext_pblock(ex) + le16_to_cpu(ex->ee_len) - num; - ext_debug("free last %lu blocks starting %llu\n", num, start); - for (i = 0; i < num; i++) { - bh = sb_find_get_block(inode->i_sb, start + i); - ext4_forget(handle, 0, inode, bh, start + i); - } - ext4_free_blocks(handle, inode, start, num); - } else if (from == le32_to_cpu(ex->ee_block) - && to <= le32_to_cpu(ex->ee_block) + le16_to_cpu(ex->ee_len) - 1) { - printk("strange request: removal %lu-%lu from %u:%u\n", - from, to, le32_to_cpu(ex->ee_block), le16_to_cpu(ex->ee_len)); - } else { - printk("strange request: removal(2) %lu-%lu from %u:%u\n", - from, to, le32_to_cpu(ex->ee_block), le16_to_cpu(ex->ee_len)); - } - return 0; -} - -static int -ext4_ext_rm_leaf(handle_t *handle, struct inode *inode, - struct ext4_ext_path *path, unsigned long start) -{ - int err = 0, correct_index = 0; - int depth = ext_depth(inode), credits; - struct ext4_extent_header *eh; - unsigned a, b, block, num; - unsigned long ex_ee_block; - unsigned short ex_ee_len; - struct ext4_extent *ex; - - ext_debug("truncate since %lu in leaf\n", start); - if (!path[depth].p_hdr) - path[depth].p_hdr = ext_block_hdr(path[depth].p_bh); - eh = path[depth].p_hdr; - BUG_ON(eh == NULL); - BUG_ON(le16_to_cpu(eh->eh_entries) > le16_to_cpu(eh->eh_max)); - BUG_ON(eh->eh_magic != EXT4_EXT_MAGIC); - - /* find where to start removing */ - ex = EXT_LAST_EXTENT(eh); - - ex_ee_block = le32_to_cpu(ex->ee_block); - ex_ee_len = le16_to_cpu(ex->ee_len); - - while (ex >= EXT_FIRST_EXTENT(eh) && - ex_ee_block + ex_ee_len > start) { - ext_debug("remove ext %lu:%u\n", ex_ee_block, ex_ee_len); - path[depth].p_ext = ex; - - a = ex_ee_block > start ? ex_ee_block : start; - b = ex_ee_block + ex_ee_len - 1 < EXT_MAX_BLOCK ? - ex_ee_block + ex_ee_len - 1 : EXT_MAX_BLOCK; - - ext_debug(" border %u:%u\n", a, b); - - if (a != ex_ee_block && b != ex_ee_block + ex_ee_len - 1) { - block = 0; - num = 0; - BUG(); - } else if (a != ex_ee_block) { - /* remove tail of the extent */ - block = ex_ee_block; - num = a - block; - } else if (b != ex_ee_block + ex_ee_len - 1) { - /* remove head of the extent */ - block = a; - num = b - a; - /* there is no "make a hole" API yet */ - BUG(); - } else { - /* remove whole extent: excellent! */ - block = ex_ee_block; - num = 0; - BUG_ON(a != ex_ee_block); - BUG_ON(b != ex_ee_block + ex_ee_len - 1); - } - - /* at present, extent can't cross block group: */ - /* leaf + bitmap + group desc + sb + inode */ - credits = 5; - if (ex == EXT_FIRST_EXTENT(eh)) { - correct_index = 1; - credits += (ext_depth(inode)) + 1; - } -#ifdef CONFIG_QUOTA - credits += 2 * EXT4_QUOTA_TRANS_BLOCKS(inode->i_sb); -#endif - - handle = ext4_ext_journal_restart(handle, credits); - if (IS_ERR(handle)) { - err = PTR_ERR(handle); - goto out; - } - - err = ext4_ext_get_access(handle, inode, path + depth); - if (err) - goto out; - - err = ext4_remove_blocks(handle, inode, ex, a, b); - if (err) - goto out; - - if (num == 0) { - /* this extent is removed; mark slot entirely unused */ - ext4_ext_store_pblock(ex, 0); - eh->eh_entries = cpu_to_le16(le16_to_cpu(eh->eh_entries)-1); - } - - ex->ee_block = cpu_to_le32(block); - ex->ee_len = cpu_to_le16(num); - - err = ext4_ext_dirty(handle, inode, path + depth); - if (err) - goto out; - - ext_debug("new extent: %u:%u:%llu\n", block, num, - ext_pblock(ex)); - ex--; - ex_ee_block = le32_to_cpu(ex->ee_block); - ex_ee_len = le16_to_cpu(ex->ee_len); - } - - if (correct_index && eh->eh_entries) - err = ext4_ext_correct_indexes(handle, inode, path); - - /* if this leaf is free, then we should - * remove it from index block above */ - if (err == 0 && eh->eh_entries == 0 && path[depth].p_bh != NULL) - err = ext4_ext_rm_idx(handle, inode, path + depth); - -out: - return err; -} - -/* - * ext4_ext_more_to_rm: - * returns 1 if current index has to be freed (even partial) - */ -static int inline -ext4_ext_more_to_rm(struct ext4_ext_path *path) -{ - BUG_ON(path->p_idx == NULL); - - if (path->p_idx < EXT_FIRST_INDEX(path->p_hdr)) - return 0; - - /* - * if truncate on deeper level happened, it wasn't partial, - * so we have to consider current index for truncation - */ - if (le16_to_cpu(path->p_hdr->eh_entries) == path->p_block) - return 0; - return 1; -} - -int ext4_ext_remove_space(struct inode *inode, unsigned long start) -{ - struct super_block *sb = inode->i_sb; - int depth = ext_depth(inode); - struct ext4_ext_path *path; - handle_t *handle; - int i = 0, err = 0; - - ext_debug("truncate since %lu\n", start); - - /* probably first extent we're gonna free will be last in block */ - handle = ext4_journal_start(inode, depth + 1); - if (IS_ERR(handle)) - return PTR_ERR(handle); - - ext4_ext_invalidate_cache(inode); - - /* - * We start scanning from right side, freeing all the blocks - * after i_size and walking into the tree depth-wise. - */ - 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; - goto out; - } - path[0].p_depth = depth; - - while (i >= 0 && err == 0) { - if (i == depth) { - /* this is leaf block */ - err = ext4_ext_rm_leaf(handle, inode, path, start); - /* root level has p_bh == NULL, brelse() eats this */ - brelse(path[i].p_bh); - path[i].p_bh = NULL; - i--; - continue; - } - - /* this is index block */ - if (!path[i].p_hdr) { - ext_debug("initialize header\n"); - path[i].p_hdr = ext_block_hdr(path[i].p_bh); - if (ext4_ext_check_header(__FUNCTION__, inode, - path[i].p_hdr)) { - err = -EIO; - goto out; - } - } - - BUG_ON(le16_to_cpu(path[i].p_hdr->eh_entries) - > le16_to_cpu(path[i].p_hdr->eh_max)); - BUG_ON(path[i].p_hdr->eh_magic != EXT4_EXT_MAGIC); - - if (!path[i].p_idx) { - /* this level hasn't been touched yet */ - path[i].p_idx = EXT_LAST_INDEX(path[i].p_hdr); - path[i].p_block = le16_to_cpu(path[i].p_hdr->eh_entries)+1; - ext_debug("init index ptr: hdr 0x%p, num %d\n", - path[i].p_hdr, - le16_to_cpu(path[i].p_hdr->eh_entries)); - } else { - /* we were already here, see at next index */ - path[i].p_idx--; - } - - ext_debug("level %d - index, first 0x%p, cur 0x%p\n", - i, EXT_FIRST_INDEX(path[i].p_hdr), - path[i].p_idx); - if (ext4_ext_more_to_rm(path + i)) { - /* go to the next level */ - ext_debug("move to level %d (block %llu)\n", - i + 1, idx_pblock(path[i].p_idx)); - memset(path + i + 1, 0, sizeof(*path)); - path[i+1].p_bh = - sb_bread(sb, idx_pblock(path[i].p_idx)); - if (!path[i+1].p_bh) { - /* should we reset i_size? */ - err = -EIO; - break; - } - - /* save actual number of indexes since this - * number is changed at the next iteration */ - path[i].p_block = le16_to_cpu(path[i].p_hdr->eh_entries); - i++; - } else { - /* we finished processing this index, go up */ - if (path[i].p_hdr->eh_entries == 0 && i > 0) { - /* index is empty, remove it; - * handle must be already prepared by the - * truncatei_leaf() */ - err = ext4_ext_rm_idx(handle, inode, path + i); - } - /* root level has p_bh == NULL, brelse() eats this */ - brelse(path[i].p_bh); - path[i].p_bh = NULL; - i--; - ext_debug("return to level %d\n", i); - } - } - - /* TODO: flexible tree reduction should be here */ - if (path->p_hdr->eh_entries == 0) { - /* - * truncate to zero freed all the tree, - * so we need to correct eh_depth - */ - err = ext4_ext_get_access(handle, inode, path); - if (err == 0) { - ext_inode_hdr(inode)->eh_depth = 0; - ext_inode_hdr(inode)->eh_max = - cpu_to_le16(ext4_ext_space_root(inode)); - err = ext4_ext_dirty(handle, inode, path); - } - } -out: - ext4_ext_tree_changed(inode); - ext4_ext_drop_refs(path); - kfree(path); - ext4_journal_stop(handle); - - return err; -} - -/* - * called at mount time - */ -void ext4_ext_init(struct super_block *sb) -{ - /* - * possible initialization would be here - */ - - if (test_opt(sb, EXTENTS)) { - printk("EXT4-fs: file extents enabled"); -#ifdef AGRESSIVE_TEST - printk(", agressive tests"); -#endif -#ifdef CHECK_BINSEARCH - printk(", check binsearch"); -#endif -#ifdef EXTENTS_STATS - printk(", stats"); -#endif - printk("\n"); -#ifdef EXTENTS_STATS - spin_lock_init(&EXT4_SB(sb)->s_ext_stats_lock); - EXT4_SB(sb)->s_ext_min = 1 << 30; - EXT4_SB(sb)->s_ext_max = 0; -#endif - } -} - -/* - * called at umount time - */ -void ext4_ext_release(struct super_block *sb) -{ - if (!test_opt(sb, EXTENTS)) - return; - -#ifdef EXTENTS_STATS - if (EXT4_SB(sb)->s_ext_blocks && EXT4_SB(sb)->s_ext_extents) { - struct ext4_sb_info *sbi = EXT4_SB(sb); - printk(KERN_ERR "EXT4-fs: %lu blocks in %lu extents (%lu ave)\n", - sbi->s_ext_blocks, sbi->s_ext_extents, - sbi->s_ext_blocks / sbi->s_ext_extents); - printk(KERN_ERR "EXT4-fs: extents: %lu min, %lu max, max depth %lu\n", - sbi->s_ext_min, sbi->s_ext_max, sbi->s_depth_max); - } -#endif -} - -int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, - ext4_fsblk_t iblock, - unsigned long max_blocks, struct buffer_head *bh_result, - int create, int extend_disksize) -{ - struct ext4_ext_path *path = NULL; - struct ext4_extent newex, *ex; - ext4_fsblk_t goal, newblock; - int err = 0, depth; - unsigned long allocated = 0; - - __clear_bit(BH_New, &bh_result->b_state); - ext_debug("blocks %d/%lu requested for inode %u\n", (int) iblock, - max_blocks, (unsigned) inode->i_ino); - mutex_lock(&EXT4_I(inode)->truncate_mutex); - - /* check in cache */ - if ((goal = ext4_ext_in_cache(inode, iblock, &newex))) { - if (goal == EXT4_EXT_CACHE_GAP) { - if (!create) { - /* block isn't allocated yet and - * user doesn't want to allocate it */ - goto out2; - } - /* we should allocate requested block */ - } else if (goal == EXT4_EXT_CACHE_EXTENT) { - /* block is already allocated */ - newblock = iblock - - le32_to_cpu(newex.ee_block) - + ext_pblock(&newex); - /* number of remaining blocks in the extent */ - allocated = le16_to_cpu(newex.ee_len) - - (iblock - le32_to_cpu(newex.ee_block)); - goto out; - } else { - BUG(); - } - } - - /* find extent for this block */ - path = ext4_ext_find_extent(inode, iblock, NULL); - if (IS_ERR(path)) { - err = PTR_ERR(path); - path = NULL; - goto out2; - } - - depth = ext_depth(inode); - - /* - * consistent leaf must not be empty; - * this situation is possible, though, _during_ tree modification; - * this is why assert can't be put in ext4_ext_find_extent() - */ - BUG_ON(path[depth].p_ext == NULL && depth != 0); - - 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); - - /* - * Allow future support for preallocated extents to be added - * as an RO_COMPAT feature: - * Uninitialized extents are treated as holes, except that - * we avoid (fail) allocating new blocks during a write. - */ - if (ee_len > EXT_MAX_LEN) - goto out2; - /* if found extent covers block, simply return it */ - if (iblock >= ee_block && iblock < ee_block + ee_len) { - newblock = iblock - ee_block + ee_start; - /* number of remaining blocks in the extent */ - allocated = ee_len - (iblock - ee_block); - ext_debug("%d fit into %lu:%d -> %llu\n", (int) iblock, - ee_block, ee_len, newblock); - ext4_ext_put_in_cache(inode, ee_block, ee_len, - ee_start, EXT4_EXT_CACHE_EXTENT); - goto out; - } - } - - /* - * requested block isn't allocated yet; - * we couldn't try to create block if create flag is zero - */ - if (!create) { - /* put just found gap into cache to speed up - * subsequent requests */ - ext4_ext_put_gap_in_cache(inode, path, iblock); - goto out2; - } - /* - * Okay, we need to do block allocation. Lazily initialize the block - * allocation info here if necessary. - */ - if (S_ISREG(inode->i_mode) && (!EXT4_I(inode)->i_block_alloc_info)) - ext4_init_block_alloc_info(inode); - - /* allocate new block */ - goal = ext4_ext_find_goal(inode, path, iblock); - allocated = max_blocks; - newblock = ext4_new_blocks(handle, inode, goal, &allocated, &err); - if (!newblock) - goto out2; - ext_debug("allocate new block: goal %llu, found %llu/%lu\n", - goal, newblock, allocated); - - /* try to insert new extent into found leaf and return */ - newex.ee_block = cpu_to_le32(iblock); - ext4_ext_store_pblock(&newex, newblock); - newex.ee_len = cpu_to_le16(allocated); - err = ext4_ext_insert_extent(handle, inode, path, &newex); - if (err) - goto out2; - - if (extend_disksize && inode->i_size > EXT4_I(inode)->i_disksize) - EXT4_I(inode)->i_disksize = inode->i_size; - - /* previous routine could use block we allocated */ - newblock = ext_pblock(&newex); - __set_bit(BH_New, &bh_result->b_state); - - ext4_ext_put_in_cache(inode, iblock, allocated, newblock, - EXT4_EXT_CACHE_EXTENT); -out: - if (allocated > max_blocks) - allocated = max_blocks; - ext4_ext_show_leaf(inode, path); - __set_bit(BH_Mapped, &bh_result->b_state); - bh_result->b_bdev = inode->i_sb->s_bdev; - bh_result->b_blocknr = newblock; -out2: - if (path) { - ext4_ext_drop_refs(path); - kfree(path); - } - mutex_unlock(&EXT4_I(inode)->truncate_mutex); - - return err ? err : allocated; -} - -void ext4_ext_truncate(struct inode * inode, struct page *page) -{ - struct address_space *mapping = inode->i_mapping; - struct super_block *sb = inode->i_sb; - unsigned long last_block; - handle_t *handle; - int err = 0; - - /* - * probably first extent we're gonna free will be last in block - */ - err = ext4_writepage_trans_blocks(inode) + 3; - handle = ext4_journal_start(inode, err); - if (IS_ERR(handle)) { - if (page) { - clear_highpage(page); - flush_dcache_page(page); - unlock_page(page); - page_cache_release(page); - } - return; - } - - if (page) - ext4_block_truncate_page(handle, page, mapping, inode->i_size); - - mutex_lock(&EXT4_I(inode)->truncate_mutex); - ext4_ext_invalidate_cache(inode); - - /* - * TODO: optimization is possible here. - * Probably we need not scan at all, - * because page truncation is enough. - */ - if (ext4_orphan_add(handle, inode)) - goto out_stop; - - /* we have to know where to truncate from in crash case */ - EXT4_I(inode)->i_disksize = inode->i_size; - ext4_mark_inode_dirty(handle, inode); - - last_block = (inode->i_size + sb->s_blocksize - 1) - >> EXT4_BLOCK_SIZE_BITS(sb); - err = ext4_ext_remove_space(inode, last_block); - - /* In a multi-transaction truncate, we only make the final - * transaction synchronous. */ - if (IS_SYNC(inode)) - handle->h_sync = 1; - -out_stop: - /* - * If this was a simple ftruncate() and the file will remain alive, - * then we need to clear up the orphan record which we created above. - * However, if this was a real unlink then we were called by - * ext4_delete_inode(), and we allow that function to clean up the - * orphan info for us. - */ - if (inode->i_nlink) - ext4_orphan_del(handle, inode); - - mutex_unlock(&EXT4_I(inode)->truncate_mutex); - ext4_journal_stop(handle); -} - -/* - * ext4_ext_writepage_trans_blocks: - * calculate max number of blocks we could modify - * in order to allocate new block for an inode - */ -int ext4_ext_writepage_trans_blocks(struct inode *inode, int num) -{ - int needed; - - needed = ext4_ext_calc_credits_for_insert(inode, NULL); - - /* caller wants to allocate num blocks, but note it includes sb */ - needed = needed * num - (num - 1); - -#ifdef CONFIG_QUOTA - needed += 2 * EXT4_QUOTA_TRANS_BLOCKS(inode->i_sb); -#endif - - return needed; -} - -EXPORT_SYMBOL(ext4_mark_inode_dirty); -EXPORT_SYMBOL(ext4_ext_invalidate_cache); -EXPORT_SYMBOL(ext4_ext_insert_extent); -EXPORT_SYMBOL(ext4_ext_walk_space); -EXPORT_SYMBOL(ext4_ext_find_goal); -EXPORT_SYMBOL(ext4_ext_calc_credits_for_insert); - diff --git a/trunk/fs/ext4/file.c b/trunk/fs/ext4/file.c deleted file mode 100644 index 0b622c0624b7..000000000000 --- a/trunk/fs/ext4/file.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * linux/fs/ext4/file.c - * - * Copyright (C) 1992, 1993, 1994, 1995 - * Remy Card (card@masi.ibp.fr) - * Laboratoire MASI - Institut Blaise Pascal - * Universite Pierre et Marie Curie (Paris VI) - * - * from - * - * linux/fs/minix/file.c - * - * Copyright (C) 1991, 1992 Linus Torvalds - * - * ext4 fs regular file handling primitives - * - * 64-bit file support on 64-bit platforms by Jakub Jelinek - * (jj@sunsite.ms.mff.cuni.cz) - */ - -#include -#include -#include -#include -#include -#include "xattr.h" -#include "acl.h" - -/* - * Called when an inode is released. Note that this is different - * from ext4_file_open: open gets called at every open, but release - * gets called only when /all/ the files are closed. - */ -static int ext4_release_file (struct inode * inode, struct file * filp) -{ - /* if we are the last writer on the inode, drop the block reservation */ - if ((filp->f_mode & FMODE_WRITE) && - (atomic_read(&inode->i_writecount) == 1)) - { - mutex_lock(&EXT4_I(inode)->truncate_mutex); - ext4_discard_reservation(inode); - mutex_unlock(&EXT4_I(inode)->truncate_mutex); - } - if (is_dx(inode) && filp->private_data) - ext4_htree_free_dir_info(filp->private_data); - - return 0; -} - -static ssize_t -ext4_file_write(struct kiocb *iocb, const struct iovec *iov, - unsigned long nr_segs, loff_t pos) -{ - struct file *file = iocb->ki_filp; - struct inode *inode = file->f_dentry->d_inode; - ssize_t ret; - int err; - - ret = generic_file_aio_write(iocb, iov, nr_segs, pos); - - /* - * Skip flushing if there was an error, or if nothing was written. - */ - if (ret <= 0) - return ret; - - /* - * If the inode is IS_SYNC, or is O_SYNC and we are doing data - * journalling then we need to make sure that we force the transaction - * to disk to keep all metadata uptodate synchronously. - */ - if (file->f_flags & O_SYNC) { - /* - * If we are non-data-journaled, then the dirty data has - * already been flushed to backing store by generic_osync_inode, - * and the inode has been flushed too if there have been any - * modifications other than mere timestamp updates. - * - * Open question --- do we care about flushing timestamps too - * if the inode is IS_SYNC? - */ - if (!ext4_should_journal_data(inode)) - return ret; - - goto force_commit; - } - - /* - * So we know that there has been no forced data flush. If the inode - * is marked IS_SYNC, we need to force one ourselves. - */ - if (!IS_SYNC(inode)) - return ret; - - /* - * Open question #2 --- should we force data to disk here too? If we - * don't, the only impact is that data=writeback filesystems won't - * flush data to disk automatically on IS_SYNC, only metadata (but - * historically, that is what ext2 has done.) - */ - -force_commit: - err = ext4_force_commit(inode->i_sb); - if (err) - return err; - return ret; -} - -const struct file_operations ext4_file_operations = { - .llseek = generic_file_llseek, - .read = do_sync_read, - .write = do_sync_write, - .aio_read = generic_file_aio_read, - .aio_write = ext4_file_write, - .ioctl = ext4_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = ext4_compat_ioctl, -#endif - .mmap = generic_file_mmap, - .open = generic_file_open, - .release = ext4_release_file, - .fsync = ext4_sync_file, - .sendfile = generic_file_sendfile, - .splice_read = generic_file_splice_read, - .splice_write = generic_file_splice_write, -}; - -struct inode_operations ext4_file_inode_operations = { - .truncate = ext4_truncate, - .setattr = ext4_setattr, -#ifdef CONFIG_EXT4DEV_FS_XATTR - .setxattr = generic_setxattr, - .getxattr = generic_getxattr, - .listxattr = ext4_listxattr, - .removexattr = generic_removexattr, -#endif - .permission = ext4_permission, -}; - diff --git a/trunk/fs/ext4/fsync.c b/trunk/fs/ext4/fsync.c deleted file mode 100644 index 2a167d7131fa..000000000000 --- a/trunk/fs/ext4/fsync.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * linux/fs/ext4/fsync.c - * - * Copyright (C) 1993 Stephen Tweedie (sct@redhat.com) - * from - * Copyright (C) 1992 Remy Card (card@masi.ibp.fr) - * Laboratoire MASI - Institut Blaise Pascal - * Universite Pierre et Marie Curie (Paris VI) - * from - * linux/fs/minix/truncate.c Copyright (C) 1991, 1992 Linus Torvalds - * - * ext4fs fsync primitive - * - * Big-endian to little-endian byte-swapping/bitmaps by - * David S. Miller (davem@caip.rutgers.edu), 1995 - * - * Removed unnecessary code duplication for little endian machines - * and excessive __inline__s. - * Andi Kleen, 1997 - * - * Major simplications and cleanup - we only need to do the metadata, because - * we can depend on generic_block_fdatasync() to sync the data blocks. - */ - -#include -#include -#include -#include -#include -#include -#include - -/* - * akpm: A new design for ext4_sync_file(). - * - * This is only called from sys_fsync(), sys_fdatasync() and sys_msync(). - * There cannot be a transaction open by this task. - * Another task could have dirtied this inode. Its data can be in any - * state in the journalling system. - * - * What we do is just kick off a commit and wait on it. This will snapshot the - * inode to disk. - */ - -int ext4_sync_file(struct file * file, struct dentry *dentry, int datasync) -{ - struct inode *inode = dentry->d_inode; - int ret = 0; - - J_ASSERT(ext4_journal_current_handle() == 0); - - /* - * data=writeback: - * The caller's filemap_fdatawrite()/wait will sync the data. - * sync_inode() will sync the metadata - * - * data=ordered: - * The caller's filemap_fdatawrite() will write the data and - * sync_inode() will write the inode if it is dirty. Then the caller's - * filemap_fdatawait() will wait on the pages. - * - * data=journal: - * filemap_fdatawrite won't do anything (the buffers are clean). - * ext4_force_commit will write the file data into the journal and - * will wait on that. - * filemap_fdatawait() will encounter a ton of newly-dirtied pages - * (they were dirtied by commit). But that's OK - the blocks are - * safe in-journal, which is all fsync() needs to ensure. - */ - if (ext4_should_journal_data(inode)) { - ret = ext4_force_commit(inode->i_sb); - goto out; - } - - /* - * The VFS has written the file data. If the inode is unaltered - * then we need not start a commit. - */ - if (inode->i_state & (I_DIRTY_SYNC|I_DIRTY_DATASYNC)) { - struct writeback_control wbc = { - .sync_mode = WB_SYNC_ALL, - .nr_to_write = 0, /* sys_fsync did this */ - }; - ret = sync_inode(inode, &wbc); - } -out: - return ret; -} diff --git a/trunk/fs/ext4/hash.c b/trunk/fs/ext4/hash.c deleted file mode 100644 index a67966385e06..000000000000 --- a/trunk/fs/ext4/hash.c +++ /dev/null @@ -1,152 +0,0 @@ -/* - * linux/fs/ext4/hash.c - * - * Copyright (C) 2002 by Theodore Ts'o - * - * This file is released under the GPL v2. - * - * This file may be redistributed under the terms of the GNU Public - * License. - */ - -#include -#include -#include -#include -#include - -#define DELTA 0x9E3779B9 - -static void TEA_transform(__u32 buf[4], __u32 const in[]) -{ - __u32 sum = 0; - __u32 b0 = buf[0], b1 = buf[1]; - __u32 a = in[0], b = in[1], c = in[2], d = in[3]; - int n = 16; - - do { - sum += DELTA; - b0 += ((b1 << 4)+a) ^ (b1+sum) ^ ((b1 >> 5)+b); - b1 += ((b0 << 4)+c) ^ (b0+sum) ^ ((b0 >> 5)+d); - } while(--n); - - buf[0] += b0; - buf[1] += b1; -} - - -/* The old legacy hash */ -static __u32 dx_hack_hash (const char *name, int len) -{ - __u32 hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9; - while (len--) { - __u32 hash = hash1 + (hash0 ^ (*name++ * 7152373)); - - if (hash & 0x80000000) hash -= 0x7fffffff; - hash1 = hash0; - hash0 = hash; - } - return (hash0 << 1); -} - -static void str2hashbuf(const char *msg, int len, __u32 *buf, int num) -{ - __u32 pad, val; - int i; - - pad = (__u32)len | ((__u32)len << 8); - pad |= pad << 16; - - val = pad; - if (len > num*4) - len = num * 4; - for (i=0; i < len; i++) { - if ((i % 4) == 0) - val = pad; - val = msg[i] + (val << 8); - if ((i % 4) == 3) { - *buf++ = val; - val = pad; - num--; - } - } - if (--num >= 0) - *buf++ = val; - while (--num >= 0) - *buf++ = pad; -} - -/* - * Returns the hash of a filename. If len is 0 and name is NULL, then - * this function can be used to test whether or not a hash version is - * supported. - * - * The seed is an 4 longword (32 bits) "secret" which can be used to - * uniquify a hash. If the seed is all zero's, then some default seed - * may be used. - * - * A particular hash version specifies whether or not the seed is - * represented, and whether or not the returned hash is 32 bits or 64 - * bits. 32 bit hashes will return 0 for the minor hash. - */ -int ext4fs_dirhash(const char *name, int len, struct dx_hash_info *hinfo) -{ - __u32 hash; - __u32 minor_hash = 0; - const char *p; - int i; - __u32 in[8], buf[4]; - - /* Initialize the default seed for the hash checksum functions */ - buf[0] = 0x67452301; - buf[1] = 0xefcdab89; - buf[2] = 0x98badcfe; - buf[3] = 0x10325476; - - /* Check to see if the seed is all zero's */ - if (hinfo->seed) { - for (i=0; i < 4; i++) { - if (hinfo->seed[i]) - break; - } - if (i < 4) - memcpy(buf, hinfo->seed, sizeof(buf)); - } - - switch (hinfo->hash_version) { - case DX_HASH_LEGACY: - hash = dx_hack_hash(name, len); - break; - case DX_HASH_HALF_MD4: - p = name; - while (len > 0) { - str2hashbuf(p, len, in, 8); - half_md4_transform(buf, in); - len -= 32; - p += 32; - } - minor_hash = buf[2]; - hash = buf[1]; - break; - case DX_HASH_TEA: - p = name; - while (len > 0) { - str2hashbuf(p, len, in, 4); - TEA_transform(buf, in); - len -= 16; - p += 16; - } - hash = buf[0]; - minor_hash = buf[1]; - break; - default: - hinfo->hash = 0; - return -1; - } - hash = hash & ~1; - if (hash == (EXT4_HTREE_EOF << 1)) - hash = (EXT4_HTREE_EOF-1) << 1; - hinfo->hash = hash; - hinfo->minor_hash = minor_hash; - return 0; -} diff --git a/trunk/fs/ext4/ialloc.c b/trunk/fs/ext4/ialloc.c deleted file mode 100644 index c88b439ba5cd..000000000000 --- a/trunk/fs/ext4/ialloc.c +++ /dev/null @@ -1,772 +0,0 @@ -/* - * linux/fs/ext4/ialloc.c - * - * Copyright (C) 1992, 1993, 1994, 1995 - * Remy Card (card@masi.ibp.fr) - * Laboratoire MASI - Institut Blaise Pascal - * Universite Pierre et Marie Curie (Paris VI) - * - * BSD ufs-inspired inode and directory allocation by - * Stephen Tweedie (sct@redhat.com), 1993 - * Big-endian to little-endian byte-swapping/bitmaps by - * David S. Miller (davem@caip.rutgers.edu), 1995 - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "xattr.h" -#include "acl.h" - -/* - * ialloc.c contains the inodes allocation and deallocation routines - */ - -/* - * The free inodes are managed by bitmaps. A file system contains several - * blocks groups. Each group contains 1 bitmap block for blocks, 1 bitmap - * block for inodes, N blocks for the inode table and data blocks. - * - * The file system contains group descriptors which are located after the - * super block. Each descriptor contains the number of the bitmap block and - * the free blocks count in the block. - */ - - -/* - * Read the inode allocation bitmap for a given block_group, reading - * into the specified slot in the superblock's bitmap cache. - * - * Return buffer_head of bitmap on success or NULL. - */ -static struct buffer_head * -read_inode_bitmap(struct super_block * sb, unsigned long block_group) -{ - struct ext4_group_desc *desc; - struct buffer_head *bh = NULL; - - desc = ext4_get_group_desc(sb, block_group, NULL); - if (!desc) - goto error_out; - - bh = sb_bread(sb, ext4_inode_bitmap(sb, desc)); - if (!bh) - ext4_error(sb, "read_inode_bitmap", - "Cannot read inode bitmap - " - "block_group = %lu, inode_bitmap = %llu", - block_group, ext4_inode_bitmap(sb, desc)); -error_out: - return bh; -} - -/* - * NOTE! When we get the inode, we're the only people - * that have access to it, and as such there are no - * race conditions we have to worry about. The inode - * is not on the hash-lists, and it cannot be reached - * through the filesystem because the directory entry - * has been deleted earlier. - * - * HOWEVER: we must make sure that we get no aliases, - * which means that we have to call "clear_inode()" - * _before_ we mark the inode not in use in the inode - * bitmaps. Otherwise a newly created file might use - * the same inode number (not actually the same pointer - * though), and then we'd have two inodes sharing the - * same inode number and space on the harddisk. - */ -void ext4_free_inode (handle_t *handle, struct inode * inode) -{ - struct super_block * sb = inode->i_sb; - int is_directory; - unsigned long ino; - struct buffer_head *bitmap_bh = NULL; - struct buffer_head *bh2; - unsigned long block_group; - unsigned long bit; - struct ext4_group_desc * gdp; - struct ext4_super_block * es; - struct ext4_sb_info *sbi; - int fatal = 0, err; - - if (atomic_read(&inode->i_count) > 1) { - printk ("ext4_free_inode: inode has count=%d\n", - atomic_read(&inode->i_count)); - return; - } - if (inode->i_nlink) { - printk ("ext4_free_inode: inode has nlink=%d\n", - inode->i_nlink); - return; - } - if (!sb) { - printk("ext4_free_inode: inode on nonexistent device\n"); - return; - } - sbi = EXT4_SB(sb); - - ino = inode->i_ino; - ext4_debug ("freeing inode %lu\n", ino); - - /* - * Note: we must free any quota before locking the superblock, - * as writing the quota to disk may need the lock as well. - */ - DQUOT_INIT(inode); - ext4_xattr_delete_inode(handle, inode); - DQUOT_FREE_INODE(inode); - DQUOT_DROP(inode); - - is_directory = S_ISDIR(inode->i_mode); - - /* Do this BEFORE marking the inode not in use or returning an error */ - clear_inode (inode); - - es = EXT4_SB(sb)->s_es; - if (ino < EXT4_FIRST_INO(sb) || ino > le32_to_cpu(es->s_inodes_count)) { - ext4_error (sb, "ext4_free_inode", - "reserved or nonexistent inode %lu", ino); - goto error_return; - } - block_group = (ino - 1) / EXT4_INODES_PER_GROUP(sb); - bit = (ino - 1) % EXT4_INODES_PER_GROUP(sb); - bitmap_bh = read_inode_bitmap(sb, block_group); - if (!bitmap_bh) - goto error_return; - - BUFFER_TRACE(bitmap_bh, "get_write_access"); - fatal = ext4_journal_get_write_access(handle, bitmap_bh); - if (fatal) - goto error_return; - - /* Ok, now we can actually update the inode bitmaps.. */ - if (!ext4_clear_bit_atomic(sb_bgl_lock(sbi, block_group), - bit, bitmap_bh->b_data)) - ext4_error (sb, "ext4_free_inode", - "bit already cleared for inode %lu", ino); - else { - gdp = ext4_get_group_desc (sb, block_group, &bh2); - - BUFFER_TRACE(bh2, "get_write_access"); - fatal = ext4_journal_get_write_access(handle, bh2); - if (fatal) goto error_return; - - if (gdp) { - spin_lock(sb_bgl_lock(sbi, block_group)); - gdp->bg_free_inodes_count = cpu_to_le16( - le16_to_cpu(gdp->bg_free_inodes_count) + 1); - if (is_directory) - gdp->bg_used_dirs_count = cpu_to_le16( - le16_to_cpu(gdp->bg_used_dirs_count) - 1); - spin_unlock(sb_bgl_lock(sbi, block_group)); - percpu_counter_inc(&sbi->s_freeinodes_counter); - if (is_directory) - percpu_counter_dec(&sbi->s_dirs_counter); - - } - BUFFER_TRACE(bh2, "call ext4_journal_dirty_metadata"); - err = ext4_journal_dirty_metadata(handle, bh2); - if (!fatal) fatal = err; - } - BUFFER_TRACE(bitmap_bh, "call ext4_journal_dirty_metadata"); - err = ext4_journal_dirty_metadata(handle, bitmap_bh); - if (!fatal) - fatal = err; - sb->s_dirt = 1; -error_return: - brelse(bitmap_bh); - ext4_std_error(sb, fatal); -} - -/* - * There are two policies for allocating an inode. If the new inode is - * a directory, then a forward search is made for a block group with both - * free space and a low directory-to-inode ratio; if that fails, then of - * the groups with above-average free space, that group with the fewest - * directories already is chosen. - * - * For other inodes, search forward from the parent directory\'s block - * group to find a free inode. - */ -static int find_group_dir(struct super_block *sb, struct inode *parent) -{ - int ngroups = EXT4_SB(sb)->s_groups_count; - unsigned int freei, avefreei; - struct ext4_group_desc *desc, *best_desc = NULL; - struct buffer_head *bh; - int group, best_group = -1; - - freei = percpu_counter_read_positive(&EXT4_SB(sb)->s_freeinodes_counter); - avefreei = freei / ngroups; - - for (group = 0; group < ngroups; group++) { - desc = ext4_get_group_desc (sb, group, &bh); - if (!desc || !desc->bg_free_inodes_count) - continue; - if (le16_to_cpu(desc->bg_free_inodes_count) < avefreei) - continue; - if (!best_desc || - (le16_to_cpu(desc->bg_free_blocks_count) > - le16_to_cpu(best_desc->bg_free_blocks_count))) { - best_group = group; - best_desc = desc; - } - } - return best_group; -} - -/* - * Orlov's allocator for directories. - * - * We always try to spread first-level directories. - * - * If there are blockgroups with both free inodes and free blocks counts - * not worse than average we return one with smallest directory count. - * Otherwise we simply return a random group. - * - * For the rest rules look so: - * - * It's OK to put directory into a group unless - * it has too many directories already (max_dirs) or - * it has too few free inodes left (min_inodes) or - * it has too few free blocks left (min_blocks) or - * it's already running too large debt (max_debt). - * Parent's group is prefered, if it doesn't satisfy these - * conditions we search cyclically through the rest. If none - * of the groups look good we just look for a group with more - * free inodes than average (starting at parent's group). - * - * Debt is incremented each time we allocate a directory and decremented - * when we allocate an inode, within 0--255. - */ - -#define INODE_COST 64 -#define BLOCK_COST 256 - -static int find_group_orlov(struct super_block *sb, struct inode *parent) -{ - int parent_group = EXT4_I(parent)->i_block_group; - struct ext4_sb_info *sbi = EXT4_SB(sb); - struct ext4_super_block *es = sbi->s_es; - int ngroups = sbi->s_groups_count; - int inodes_per_group = EXT4_INODES_PER_GROUP(sb); - unsigned int freei, avefreei; - ext4_fsblk_t freeb, avefreeb; - ext4_fsblk_t blocks_per_dir; - unsigned int ndirs; - int max_debt, max_dirs, min_inodes; - ext4_grpblk_t min_blocks; - int group = -1, i; - struct ext4_group_desc *desc; - struct buffer_head *bh; - - freei = percpu_counter_read_positive(&sbi->s_freeinodes_counter); - avefreei = freei / ngroups; - freeb = percpu_counter_read_positive(&sbi->s_freeblocks_counter); - avefreeb = freeb; - do_div(avefreeb, ngroups); - ndirs = percpu_counter_read_positive(&sbi->s_dirs_counter); - - if ((parent == sb->s_root->d_inode) || - (EXT4_I(parent)->i_flags & EXT4_TOPDIR_FL)) { - int best_ndir = inodes_per_group; - int best_group = -1; - - get_random_bytes(&group, sizeof(group)); - parent_group = (unsigned)group % ngroups; - for (i = 0; i < ngroups; i++) { - group = (parent_group + i) % ngroups; - desc = ext4_get_group_desc (sb, group, &bh); - if (!desc || !desc->bg_free_inodes_count) - continue; - if (le16_to_cpu(desc->bg_used_dirs_count) >= best_ndir) - continue; - if (le16_to_cpu(desc->bg_free_inodes_count) < avefreei) - continue; - if (le16_to_cpu(desc->bg_free_blocks_count) < avefreeb) - continue; - best_group = group; - best_ndir = le16_to_cpu(desc->bg_used_dirs_count); - } - if (best_group >= 0) - return best_group; - goto fallback; - } - - blocks_per_dir = ext4_blocks_count(es) - freeb; - do_div(blocks_per_dir, ndirs); - - max_dirs = ndirs / ngroups + inodes_per_group / 16; - min_inodes = avefreei - inodes_per_group / 4; - min_blocks = avefreeb - EXT4_BLOCKS_PER_GROUP(sb) / 4; - - max_debt = EXT4_BLOCKS_PER_GROUP(sb); - max_debt /= max_t(int, blocks_per_dir, BLOCK_COST); - if (max_debt * INODE_COST > inodes_per_group) - max_debt = inodes_per_group / INODE_COST; - if (max_debt > 255) - max_debt = 255; - if (max_debt == 0) - max_debt = 1; - - for (i = 0; i < ngroups; i++) { - group = (parent_group + i) % ngroups; - desc = ext4_get_group_desc (sb, group, &bh); - if (!desc || !desc->bg_free_inodes_count) - continue; - if (le16_to_cpu(desc->bg_used_dirs_count) >= max_dirs) - continue; - if (le16_to_cpu(desc->bg_free_inodes_count) < min_inodes) - continue; - if (le16_to_cpu(desc->bg_free_blocks_count) < min_blocks) - continue; - return group; - } - -fallback: - for (i = 0; i < ngroups; i++) { - group = (parent_group + i) % ngroups; - desc = ext4_get_group_desc (sb, group, &bh); - if (!desc || !desc->bg_free_inodes_count) - continue; - if (le16_to_cpu(desc->bg_free_inodes_count) >= avefreei) - return group; - } - - if (avefreei) { - /* - * The free-inodes counter is approximate, and for really small - * filesystems the above test can fail to find any blockgroups - */ - avefreei = 0; - goto fallback; - } - - return -1; -} - -static int find_group_other(struct super_block *sb, struct inode *parent) -{ - int parent_group = EXT4_I(parent)->i_block_group; - int ngroups = EXT4_SB(sb)->s_groups_count; - struct ext4_group_desc *desc; - struct buffer_head *bh; - int group, i; - - /* - * Try to place the inode in its parent directory - */ - group = parent_group; - desc = ext4_get_group_desc (sb, group, &bh); - if (desc && le16_to_cpu(desc->bg_free_inodes_count) && - le16_to_cpu(desc->bg_free_blocks_count)) - return group; - - /* - * We're going to place this inode in a different blockgroup from its - * parent. We want to cause files in a common directory to all land in - * the same blockgroup. But we want files which are in a different - * directory which shares a blockgroup with our parent to land in a - * different blockgroup. - * - * So add our directory's i_ino into the starting point for the hash. - */ - group = (group + parent->i_ino) % ngroups; - - /* - * Use a quadratic hash to find a group with a free inode and some free - * blocks. - */ - for (i = 1; i < ngroups; i <<= 1) { - group += i; - if (group >= ngroups) - group -= ngroups; - desc = ext4_get_group_desc (sb, group, &bh); - if (desc && le16_to_cpu(desc->bg_free_inodes_count) && - le16_to_cpu(desc->bg_free_blocks_count)) - return group; - } - - /* - * That failed: try linear search for a free inode, even if that group - * has no free blocks. - */ - group = parent_group; - for (i = 0; i < ngroups; i++) { - if (++group >= ngroups) - group = 0; - desc = ext4_get_group_desc (sb, group, &bh); - if (desc && le16_to_cpu(desc->bg_free_inodes_count)) - return group; - } - - return -1; -} - -/* - * There are two policies for allocating an inode. If the new inode is - * a directory, then a forward search is made for a block group with both - * free space and a low directory-to-inode ratio; if that fails, then of - * the groups with above-average free space, that group with the fewest - * directories already is chosen. - * - * For other inodes, search forward from the parent directory's block - * group to find a free inode. - */ -struct inode *ext4_new_inode(handle_t *handle, struct inode * dir, int mode) -{ - struct super_block *sb; - struct buffer_head *bitmap_bh = NULL; - struct buffer_head *bh2; - int group; - unsigned long ino = 0; - struct inode * inode; - struct ext4_group_desc * gdp = NULL; - struct ext4_super_block * es; - struct ext4_inode_info *ei; - struct ext4_sb_info *sbi; - int err = 0; - struct inode *ret; - int i; - - /* Cannot create files in a deleted directory */ - if (!dir || !dir->i_nlink) - return ERR_PTR(-EPERM); - - sb = dir->i_sb; - inode = new_inode(sb); - if (!inode) - return ERR_PTR(-ENOMEM); - ei = EXT4_I(inode); - - sbi = EXT4_SB(sb); - es = sbi->s_es; - if (S_ISDIR(mode)) { - if (test_opt (sb, OLDALLOC)) - group = find_group_dir(sb, dir); - else - group = find_group_orlov(sb, dir); - } else - group = find_group_other(sb, dir); - - err = -ENOSPC; - if (group == -1) - goto out; - - for (i = 0; i < sbi->s_groups_count; i++) { - err = -EIO; - - gdp = ext4_get_group_desc(sb, group, &bh2); - if (!gdp) - goto fail; - - brelse(bitmap_bh); - bitmap_bh = read_inode_bitmap(sb, group); - if (!bitmap_bh) - goto fail; - - ino = 0; - -repeat_in_this_group: - ino = ext4_find_next_zero_bit((unsigned long *) - bitmap_bh->b_data, EXT4_INODES_PER_GROUP(sb), ino); - if (ino < EXT4_INODES_PER_GROUP(sb)) { - - BUFFER_TRACE(bitmap_bh, "get_write_access"); - err = ext4_journal_get_write_access(handle, bitmap_bh); - if (err) - goto fail; - - if (!ext4_set_bit_atomic(sb_bgl_lock(sbi, group), - ino, bitmap_bh->b_data)) { - /* we won it */ - BUFFER_TRACE(bitmap_bh, - "call ext4_journal_dirty_metadata"); - err = ext4_journal_dirty_metadata(handle, - bitmap_bh); - if (err) - goto fail; - goto got; - } - /* we lost it */ - jbd2_journal_release_buffer(handle, bitmap_bh); - - if (++ino < EXT4_INODES_PER_GROUP(sb)) - goto repeat_in_this_group; - } - - /* - * This case is possible in concurrent environment. It is very - * rare. We cannot repeat the find_group_xxx() call because - * that will simply return the same blockgroup, because the - * group descriptor metadata has not yet been updated. - * So we just go onto the next blockgroup. - */ - if (++group == sbi->s_groups_count) - group = 0; - } - err = -ENOSPC; - goto out; - -got: - ino += group * EXT4_INODES_PER_GROUP(sb) + 1; - if (ino < EXT4_FIRST_INO(sb) || ino > le32_to_cpu(es->s_inodes_count)) { - ext4_error (sb, "ext4_new_inode", - "reserved inode or inode > inodes count - " - "block_group = %d, inode=%lu", group, ino); - err = -EIO; - goto fail; - } - - BUFFER_TRACE(bh2, "get_write_access"); - err = ext4_journal_get_write_access(handle, bh2); - if (err) goto fail; - spin_lock(sb_bgl_lock(sbi, group)); - gdp->bg_free_inodes_count = - cpu_to_le16(le16_to_cpu(gdp->bg_free_inodes_count) - 1); - if (S_ISDIR(mode)) { - gdp->bg_used_dirs_count = - cpu_to_le16(le16_to_cpu(gdp->bg_used_dirs_count) + 1); - } - spin_unlock(sb_bgl_lock(sbi, group)); - BUFFER_TRACE(bh2, "call ext4_journal_dirty_metadata"); - err = ext4_journal_dirty_metadata(handle, bh2); - if (err) goto fail; - - percpu_counter_dec(&sbi->s_freeinodes_counter); - if (S_ISDIR(mode)) - percpu_counter_inc(&sbi->s_dirs_counter); - sb->s_dirt = 1; - - inode->i_uid = current->fsuid; - if (test_opt (sb, GRPID)) - inode->i_gid = dir->i_gid; - else if (dir->i_mode & S_ISGID) { - inode->i_gid = dir->i_gid; - if (S_ISDIR(mode)) - mode |= S_ISGID; - } else - inode->i_gid = current->fsgid; - inode->i_mode = mode; - - inode->i_ino = ino; - /* This is the optimal IO size (for stat), not the fs block size */ - inode->i_blocks = 0; - inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC; - - memset(ei->i_data, 0, sizeof(ei->i_data)); - ei->i_dir_start_lookup = 0; - ei->i_disksize = 0; - - ei->i_flags = EXT4_I(dir)->i_flags & ~EXT4_INDEX_FL; - if (S_ISLNK(mode)) - ei->i_flags &= ~(EXT4_IMMUTABLE_FL|EXT4_APPEND_FL); - /* dirsync only applies to directories */ - if (!S_ISDIR(mode)) - ei->i_flags &= ~EXT4_DIRSYNC_FL; -#ifdef EXT4_FRAGMENTS - ei->i_faddr = 0; - ei->i_frag_no = 0; - ei->i_frag_size = 0; -#endif - ei->i_file_acl = 0; - ei->i_dir_acl = 0; - ei->i_dtime = 0; - ei->i_block_alloc_info = NULL; - ei->i_block_group = group; - - ext4_set_inode_flags(inode); - if (IS_DIRSYNC(inode)) - handle->h_sync = 1; - insert_inode_hash(inode); - spin_lock(&sbi->s_next_gen_lock); - inode->i_generation = sbi->s_next_generation++; - spin_unlock(&sbi->s_next_gen_lock); - - ei->i_state = EXT4_STATE_NEW; - ei->i_extra_isize = - (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE) ? - sizeof(struct ext4_inode) - EXT4_GOOD_OLD_INODE_SIZE : 0; - - ret = inode; - if(DQUOT_ALLOC_INODE(inode)) { - err = -EDQUOT; - goto fail_drop; - } - - err = ext4_init_acl(handle, inode, dir); - if (err) - goto fail_free_drop; - - err = ext4_init_security(handle,inode, dir); - if (err) - goto fail_free_drop; - - err = ext4_mark_inode_dirty(handle, inode); - if (err) { - ext4_std_error(sb, err); - goto fail_free_drop; - } - if (test_opt(sb, EXTENTS)) { - EXT4_I(inode)->i_flags |= EXT4_EXTENTS_FL; - ext4_ext_tree_init(handle, inode); - if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS)) { - err = ext4_journal_get_write_access(handle, EXT4_SB(sb)->s_sbh); - if (err) goto fail; - EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS); - BUFFER_TRACE(EXT4_SB(sb)->s_sbh, "call ext4_journal_dirty_metadata"); - err = ext4_journal_dirty_metadata(handle, EXT4_SB(sb)->s_sbh); - } - } - - ext4_debug("allocating inode %lu\n", inode->i_ino); - goto really_out; -fail: - ext4_std_error(sb, err); -out: - iput(inode); - ret = ERR_PTR(err); -really_out: - brelse(bitmap_bh); - return ret; - -fail_free_drop: - DQUOT_FREE_INODE(inode); - -fail_drop: - DQUOT_DROP(inode); - inode->i_flags |= S_NOQUOTA; - inode->i_nlink = 0; - iput(inode); - brelse(bitmap_bh); - return ERR_PTR(err); -} - -/* Verify that we are loading a valid orphan from disk */ -struct inode *ext4_orphan_get(struct super_block *sb, unsigned long ino) -{ - unsigned long max_ino = le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count); - unsigned long block_group; - int bit; - struct buffer_head *bitmap_bh = NULL; - struct inode *inode = NULL; - - /* Error cases - e2fsck has already cleaned up for us */ - if (ino > max_ino) { - ext4_warning(sb, __FUNCTION__, - "bad orphan ino %lu! e2fsck was run?", ino); - goto out; - } - - block_group = (ino - 1) / EXT4_INODES_PER_GROUP(sb); - bit = (ino - 1) % EXT4_INODES_PER_GROUP(sb); - bitmap_bh = read_inode_bitmap(sb, block_group); - if (!bitmap_bh) { - ext4_warning(sb, __FUNCTION__, - "inode bitmap error for orphan %lu", ino); - goto out; - } - - /* Having the inode bit set should be a 100% indicator that this - * is a valid orphan (no e2fsck run on fs). Orphans also include - * inodes that were being truncated, so we can't check i_nlink==0. - */ - if (!ext4_test_bit(bit, bitmap_bh->b_data) || - !(inode = iget(sb, ino)) || is_bad_inode(inode) || - NEXT_ORPHAN(inode) > max_ino) { - ext4_warning(sb, __FUNCTION__, - "bad orphan inode %lu! e2fsck was run?", ino); - printk(KERN_NOTICE "ext4_test_bit(bit=%d, block=%llu) = %d\n", - bit, (unsigned long long)bitmap_bh->b_blocknr, - ext4_test_bit(bit, bitmap_bh->b_data)); - printk(KERN_NOTICE "inode=%p\n", inode); - if (inode) { - printk(KERN_NOTICE "is_bad_inode(inode)=%d\n", - is_bad_inode(inode)); - printk(KERN_NOTICE "NEXT_ORPHAN(inode)=%u\n", - NEXT_ORPHAN(inode)); - printk(KERN_NOTICE "max_ino=%lu\n", max_ino); - } - /* Avoid freeing blocks if we got a bad deleted inode */ - if (inode && inode->i_nlink == 0) - inode->i_blocks = 0; - iput(inode); - inode = NULL; - } -out: - brelse(bitmap_bh); - return inode; -} - -unsigned long ext4_count_free_inodes (struct super_block * sb) -{ - unsigned long desc_count; - struct ext4_group_desc *gdp; - int i; -#ifdef EXT4FS_DEBUG - struct ext4_super_block *es; - unsigned long bitmap_count, x; - struct buffer_head *bitmap_bh = NULL; - - es = EXT4_SB(sb)->s_es; - desc_count = 0; - bitmap_count = 0; - gdp = NULL; - for (i = 0; i < EXT4_SB(sb)->s_groups_count; i++) { - gdp = ext4_get_group_desc (sb, i, NULL); - if (!gdp) - continue; - desc_count += le16_to_cpu(gdp->bg_free_inodes_count); - brelse(bitmap_bh); - bitmap_bh = read_inode_bitmap(sb, i); - if (!bitmap_bh) - continue; - - x = ext4_count_free(bitmap_bh, EXT4_INODES_PER_GROUP(sb) / 8); - printk("group %d: stored = %d, counted = %lu\n", - i, le16_to_cpu(gdp->bg_free_inodes_count), x); - bitmap_count += x; - } - brelse(bitmap_bh); - printk("ext4_count_free_inodes: stored = %u, computed = %lu, %lu\n", - le32_to_cpu(es->s_free_inodes_count), desc_count, bitmap_count); - return desc_count; -#else - desc_count = 0; - for (i = 0; i < EXT4_SB(sb)->s_groups_count; i++) { - gdp = ext4_get_group_desc (sb, i, NULL); - if (!gdp) - continue; - desc_count += le16_to_cpu(gdp->bg_free_inodes_count); - cond_resched(); - } - return desc_count; -#endif -} - -/* Called at mount-time, super-block is locked */ -unsigned long ext4_count_dirs (struct super_block * sb) -{ - unsigned long count = 0; - int i; - - for (i = 0; i < EXT4_SB(sb)->s_groups_count; i++) { - struct ext4_group_desc *gdp = ext4_get_group_desc (sb, i, NULL); - if (!gdp) - continue; - count += le16_to_cpu(gdp->bg_used_dirs_count); - } - return count; -} - diff --git a/trunk/fs/ext4/inode.c b/trunk/fs/ext4/inode.c deleted file mode 100644 index 0a60ec5a16db..000000000000 --- a/trunk/fs/ext4/inode.c +++ /dev/null @@ -1,3233 +0,0 @@ -/* - * linux/fs/ext4/inode.c - * - * Copyright (C) 1992, 1993, 1994, 1995 - * Remy Card (card@masi.ibp.fr) - * Laboratoire MASI - Institut Blaise Pascal - * Universite Pierre et Marie Curie (Paris VI) - * - * from - * - * linux/fs/minix/inode.c - * - * Copyright (C) 1991, 1992 Linus Torvalds - * - * Goal-directed block allocation by Stephen Tweedie - * (sct@redhat.com), 1993, 1998 - * Big-endian to little-endian byte-swapping/bitmaps by - * David S. Miller (davem@caip.rutgers.edu), 1995 - * 64-bit file support on 64-bit platforms by Jakub Jelinek - * (jj@sunsite.ms.mff.cuni.cz) - * - * Assorted race fixes, rewrite of ext4_get_block() by Al Viro, 2000 - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "xattr.h" -#include "acl.h" - -/* - * Test whether an inode is a fast symlink. - */ -static int ext4_inode_is_fast_symlink(struct inode *inode) -{ - int ea_blocks = EXT4_I(inode)->i_file_acl ? - (inode->i_sb->s_blocksize >> 9) : 0; - - return (S_ISLNK(inode->i_mode) && inode->i_blocks - ea_blocks == 0); -} - -/* - * The ext4 forget function must perform a revoke if we are freeing data - * which has been journaled. Metadata (eg. indirect blocks) must be - * revoked in all cases. - * - * "bh" may be NULL: a metadata block may have been freed from memory - * but there may still be a record of it in the journal, and that record - * still needs to be revoked. - */ -int ext4_forget(handle_t *handle, int is_metadata, struct inode *inode, - struct buffer_head *bh, ext4_fsblk_t blocknr) -{ - int err; - - might_sleep(); - - BUFFER_TRACE(bh, "enter"); - - jbd_debug(4, "forgetting bh %p: is_metadata = %d, mode %o, " - "data mode %lx\n", - bh, is_metadata, inode->i_mode, - test_opt(inode->i_sb, DATA_FLAGS)); - - /* Never use the revoke function if we are doing full data - * journaling: there is no need to, and a V1 superblock won't - * support it. Otherwise, only skip the revoke on un-journaled - * data blocks. */ - - if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA || - (!is_metadata && !ext4_should_journal_data(inode))) { - if (bh) { - BUFFER_TRACE(bh, "call jbd2_journal_forget"); - return ext4_journal_forget(handle, bh); - } - return 0; - } - - /* - * data!=journal && (is_metadata || should_journal_data(inode)) - */ - BUFFER_TRACE(bh, "call ext4_journal_revoke"); - err = ext4_journal_revoke(handle, blocknr, bh); - if (err) - ext4_abort(inode->i_sb, __FUNCTION__, - "error %d when attempting revoke", err); - BUFFER_TRACE(bh, "exit"); - return err; -} - -/* - * Work out how many blocks we need to proceed with the next chunk of a - * truncate transaction. - */ -static unsigned long blocks_for_truncate(struct inode *inode) -{ - unsigned long needed; - - needed = inode->i_blocks >> (inode->i_sb->s_blocksize_bits - 9); - - /* Give ourselves just enough room to cope with inodes in which - * i_blocks is corrupt: we've seen disk corruptions in the past - * which resulted in random data in an inode which looked enough - * like a regular file for ext4 to try to delete it. Things - * will go a bit crazy if that happens, but at least we should - * try not to panic the whole kernel. */ - if (needed < 2) - needed = 2; - - /* But we need to bound the transaction so we don't overflow the - * journal. */ - if (needed > EXT4_MAX_TRANS_DATA) - needed = EXT4_MAX_TRANS_DATA; - - return EXT4_DATA_TRANS_BLOCKS(inode->i_sb) + needed; -} - -/* - * Truncate transactions can be complex and absolutely huge. So we need to - * be able to restart the transaction at a conventient checkpoint to make - * sure we don't overflow the journal. - * - * start_transaction gets us a new handle for a truncate transaction, - * and extend_transaction tries to extend the existing one a bit. If - * extend fails, we need to propagate the failure up and restart the - * transaction in the top-level truncate loop. --sct - */ -static handle_t *start_transaction(struct inode *inode) -{ - handle_t *result; - - result = ext4_journal_start(inode, blocks_for_truncate(inode)); - if (!IS_ERR(result)) - return result; - - ext4_std_error(inode->i_sb, PTR_ERR(result)); - return result; -} - -/* - * Try to extend this transaction for the purposes of truncation. - * - * Returns 0 if we managed to create more room. If we can't create more - * room, and the transaction must be restarted we return 1. - */ -static int try_to_extend_transaction(handle_t *handle, struct inode *inode) -{ - if (handle->h_buffer_credits > EXT4_RESERVE_TRANS_BLOCKS) - return 0; - if (!ext4_journal_extend(handle, blocks_for_truncate(inode))) - return 0; - return 1; -} - -/* - * Restart the transaction associated with *handle. This does a commit, - * so before we call here everything must be consistently dirtied against - * this transaction. - */ -static int ext4_journal_test_restart(handle_t *handle, struct inode *inode) -{ - jbd_debug(2, "restarting handle %p\n", handle); - return ext4_journal_restart(handle, blocks_for_truncate(inode)); -} - -/* - * Called at the last iput() if i_nlink is zero. - */ -void ext4_delete_inode (struct inode * inode) -{ - handle_t *handle; - - truncate_inode_pages(&inode->i_data, 0); - - if (is_bad_inode(inode)) - goto no_delete; - - handle = start_transaction(inode); - if (IS_ERR(handle)) { - /* - * If we're going to skip the normal cleanup, we still need to - * make sure that the in-core orphan linked list is properly - * cleaned up. - */ - ext4_orphan_del(NULL, inode); - goto no_delete; - } - - if (IS_SYNC(inode)) - handle->h_sync = 1; - inode->i_size = 0; - if (inode->i_blocks) - ext4_truncate(inode); - /* - * Kill off the orphan record which ext4_truncate created. - * AKPM: I think this can be inside the above `if'. - * Note that ext4_orphan_del() has to be able to cope with the - * deletion of a non-existent orphan - this is because we don't - * know if ext4_truncate() actually created an orphan record. - * (Well, we could do this if we need to, but heck - it works) - */ - ext4_orphan_del(handle, inode); - EXT4_I(inode)->i_dtime = get_seconds(); - - /* - * One subtle ordering requirement: if anything has gone wrong - * (transaction abort, IO errors, whatever), then we can still - * do these next steps (the fs will already have been marked as - * having errors), but we can't free the inode if the mark_dirty - * fails. - */ - if (ext4_mark_inode_dirty(handle, inode)) - /* If that failed, just do the required in-core inode clear. */ - clear_inode(inode); - else - ext4_free_inode(handle, inode); - ext4_journal_stop(handle); - return; -no_delete: - clear_inode(inode); /* We must guarantee clearing of inode... */ -} - -typedef struct { - __le32 *p; - __le32 key; - struct buffer_head *bh; -} Indirect; - -static inline void add_chain(Indirect *p, struct buffer_head *bh, __le32 *v) -{ - p->key = *(p->p = v); - p->bh = bh; -} - -static int verify_chain(Indirect *from, Indirect *to) -{ - while (from <= to && from->key == *from->p) - from++; - return (from > to); -} - -/** - * ext4_block_to_path - parse the block number into array of offsets - * @inode: inode in question (we are only interested in its superblock) - * @i_block: block number to be parsed - * @offsets: array to store the offsets in - * @boundary: set this non-zero if the referred-to block is likely to be - * followed (on disk) by an indirect block. - * - * To store the locations of file's data ext4 uses a data structure common - * for UNIX filesystems - tree of pointers anchored in the inode, with - * data blocks at leaves and indirect blocks in intermediate nodes. - * This function translates the block number into path in that tree - - * return value is the path length and @offsets[n] is the offset of - * pointer to (n+1)th node in the nth one. If @block is out of range - * (negative or too large) warning is printed and zero returned. - * - * Note: function doesn't find node addresses, so no IO is needed. All - * we need to know is the capacity of indirect blocks (taken from the - * inode->i_sb). - */ - -/* - * Portability note: the last comparison (check that we fit into triple - * indirect block) is spelled differently, because otherwise on an - * architecture with 32-bit longs and 8Kb pages we might get into trouble - * if our filesystem had 8Kb blocks. We might use long long, but that would - * kill us on x86. Oh, well, at least the sign propagation does not matter - - * i_block would have to be negative in the very beginning, so we would not - * get there at all. - */ - -static int ext4_block_to_path(struct inode *inode, - long i_block, int offsets[4], int *boundary) -{ - int ptrs = EXT4_ADDR_PER_BLOCK(inode->i_sb); - int ptrs_bits = EXT4_ADDR_PER_BLOCK_BITS(inode->i_sb); - const long direct_blocks = EXT4_NDIR_BLOCKS, - indirect_blocks = ptrs, - double_blocks = (1 << (ptrs_bits * 2)); - int n = 0; - int final = 0; - - if (i_block < 0) { - ext4_warning (inode->i_sb, "ext4_block_to_path", "block < 0"); - } else if (i_block < direct_blocks) { - offsets[n++] = i_block; - final = direct_blocks; - } else if ( (i_block -= direct_blocks) < indirect_blocks) { - offsets[n++] = EXT4_IND_BLOCK; - offsets[n++] = i_block; - final = ptrs; - } else if ((i_block -= indirect_blocks) < double_blocks) { - offsets[n++] = EXT4_DIND_BLOCK; - offsets[n++] = i_block >> ptrs_bits; - offsets[n++] = i_block & (ptrs - 1); - final = ptrs; - } else if (((i_block -= double_blocks) >> (ptrs_bits * 2)) < ptrs) { - offsets[n++] = EXT4_TIND_BLOCK; - offsets[n++] = i_block >> (ptrs_bits * 2); - offsets[n++] = (i_block >> ptrs_bits) & (ptrs - 1); - offsets[n++] = i_block & (ptrs - 1); - final = ptrs; - } else { - ext4_warning(inode->i_sb, "ext4_block_to_path", "block > big"); - } - if (boundary) - *boundary = final - 1 - (i_block & (ptrs - 1)); - return n; -} - -/** - * ext4_get_branch - read the chain of indirect blocks leading to data - * @inode: inode in question - * @depth: depth of the chain (1 - direct pointer, etc.) - * @offsets: offsets of pointers in inode/indirect blocks - * @chain: place to store the result - * @err: here we store the error value - * - * Function fills the array of triples and returns %NULL - * if everything went OK or the pointer to the last filled triple - * (incomplete one) otherwise. Upon the return chain[i].key contains - * the number of (i+1)-th block in the chain (as it is stored in memory, - * i.e. little-endian 32-bit), chain[i].p contains the address of that - * number (it points into struct inode for i==0 and into the bh->b_data - * for i>0) and chain[i].bh points to the buffer_head of i-th indirect - * block for i>0 and NULL for i==0. In other words, it holds the block - * numbers of the chain, addresses they were taken from (and where we can - * verify that chain did not change) and buffer_heads hosting these - * numbers. - * - * Function stops when it stumbles upon zero pointer (absent block) - * (pointer to last triple returned, *@err == 0) - * or when it gets an IO error reading an indirect block - * (ditto, *@err == -EIO) - * or when it notices that chain had been changed while it was reading - * (ditto, *@err == -EAGAIN) - * or when it reads all @depth-1 indirect blocks successfully and finds - * the whole chain, all way to the data (returns %NULL, *err == 0). - */ -static Indirect *ext4_get_branch(struct inode *inode, int depth, int *offsets, - Indirect chain[4], int *err) -{ - struct super_block *sb = inode->i_sb; - Indirect *p = chain; - struct buffer_head *bh; - - *err = 0; - /* i_data is not going away, no lock needed */ - add_chain (chain, NULL, EXT4_I(inode)->i_data + *offsets); - if (!p->key) - goto no_block; - while (--depth) { - bh = sb_bread(sb, le32_to_cpu(p->key)); - if (!bh) - goto failure; - /* Reader: pointers */ - if (!verify_chain(chain, p)) - goto changed; - add_chain(++p, bh, (__le32*)bh->b_data + *++offsets); - /* Reader: end */ - if (!p->key) - goto no_block; - } - return NULL; - -changed: - brelse(bh); - *err = -EAGAIN; - goto no_block; -failure: - *err = -EIO; -no_block: - return p; -} - -/** - * ext4_find_near - find a place for allocation with sufficient locality - * @inode: owner - * @ind: descriptor of indirect block. - * - * This function returns the prefered place for block allocation. - * It is used when heuristic for sequential allocation fails. - * Rules are: - * + if there is a block to the left of our position - allocate near it. - * + if pointer will live in indirect block - allocate near that block. - * + if pointer will live in inode - allocate in the same - * cylinder group. - * - * In the latter case we colour the starting block by the callers PID to - * prevent it from clashing with concurrent allocations for a different inode - * in the same block group. The PID is used here so that functionally related - * files will be close-by on-disk. - * - * Caller must make sure that @ind is valid and will stay that way. - */ -static ext4_fsblk_t ext4_find_near(struct inode *inode, Indirect *ind) -{ - struct ext4_inode_info *ei = EXT4_I(inode); - __le32 *start = ind->bh ? (__le32*) ind->bh->b_data : ei->i_data; - __le32 *p; - ext4_fsblk_t bg_start; - ext4_grpblk_t colour; - - /* Try to find previous block */ - for (p = ind->p - 1; p >= start; p--) { - if (*p) - return le32_to_cpu(*p); - } - - /* No such thing, so let's try location of indirect block */ - if (ind->bh) - return ind->bh->b_blocknr; - - /* - * It is going to be referred to from the inode itself? OK, just put it - * into the same cylinder group then. - */ - bg_start = ext4_group_first_block_no(inode->i_sb, ei->i_block_group); - colour = (current->pid % 16) * - (EXT4_BLOCKS_PER_GROUP(inode->i_sb) / 16); - return bg_start + colour; -} - -/** - * ext4_find_goal - find a prefered place for allocation. - * @inode: owner - * @block: block we want - * @chain: chain of indirect blocks - * @partial: pointer to the last triple within a chain - * @goal: place to store the result. - * - * Normally this function find the prefered place for block allocation, - * stores it in *@goal and returns zero. - */ - -static ext4_fsblk_t ext4_find_goal(struct inode *inode, long block, - Indirect chain[4], Indirect *partial) -{ - struct ext4_block_alloc_info *block_i; - - block_i = EXT4_I(inode)->i_block_alloc_info; - - /* - * try the heuristic for sequential allocation, - * failing that at least try to get decent locality. - */ - if (block_i && (block == block_i->last_alloc_logical_block + 1) - && (block_i->last_alloc_physical_block != 0)) { - return block_i->last_alloc_physical_block + 1; - } - - return ext4_find_near(inode, partial); -} - -/** - * ext4_blks_to_allocate: Look up the block map and count the number - * of direct blocks need to be allocated for the given branch. - * - * @branch: chain of indirect blocks - * @k: number of blocks need for indirect blocks - * @blks: number of data blocks to be mapped. - * @blocks_to_boundary: the offset in the indirect block - * - * return the total number of blocks to be allocate, including the - * direct and indirect blocks. - */ -static int ext4_blks_to_allocate(Indirect *branch, int k, unsigned long blks, - int blocks_to_boundary) -{ - unsigned long count = 0; - - /* - * Simple case, [t,d]Indirect block(s) has not allocated yet - * then it's clear blocks on that path have not allocated - */ - if (k > 0) { - /* right now we don't handle cross boundary allocation */ - if (blks < blocks_to_boundary + 1) - count += blks; - else - count += blocks_to_boundary + 1; - return count; - } - - count++; - while (count < blks && count <= blocks_to_boundary && - le32_to_cpu(*(branch[0].p + count)) == 0) { - count++; - } - return count; -} - -/** - * ext4_alloc_blocks: multiple allocate blocks needed for a branch - * @indirect_blks: the number of blocks need to allocate for indirect - * blocks - * - * @new_blocks: on return it will store the new block numbers for - * the indirect blocks(if needed) and the first direct block, - * @blks: on return it will store the total number of allocated - * direct blocks - */ -static int ext4_alloc_blocks(handle_t *handle, struct inode *inode, - ext4_fsblk_t goal, int indirect_blks, int blks, - ext4_fsblk_t new_blocks[4], int *err) -{ - int target, i; - unsigned long count = 0; - int index = 0; - ext4_fsblk_t current_block = 0; - int ret = 0; - - /* - * Here we try to allocate the requested multiple blocks at once, - * on a best-effort basis. - * To build a branch, we should allocate blocks for - * the indirect blocks(if not allocated yet), and at least - * the first direct block of this branch. That's the - * minimum number of blocks need to allocate(required) - */ - target = blks + indirect_blks; - - while (1) { - count = target; - /* allocating blocks for indirect blocks and direct blocks */ - current_block = ext4_new_blocks(handle,inode,goal,&count,err); - if (*err) - goto failed_out; - - target -= count; - /* allocate blocks for indirect blocks */ - while (index < indirect_blks && count) { - new_blocks[index++] = current_block++; - count--; - } - - if (count > 0) - break; - } - - /* save the new block number for the first direct block */ - new_blocks[index] = current_block; - - /* total number of blocks allocated for direct blocks */ - ret = count; - *err = 0; - return ret; -failed_out: - for (i = 0; i key). Upon the exit we have the same - * picture as after the successful ext4_get_block(), except that in one - * place chain is disconnected - *branch->p is still zero (we did not - * set the last link), but branch->key contains the number that should - * be placed into *branch->p to fill that gap. - * - * If allocation fails we free all blocks we've allocated (and forget - * their buffer_heads) and return the error value the from failed - * ext4_alloc_block() (normally -ENOSPC). Otherwise we set the chain - * as described above and return 0. - */ -static int ext4_alloc_branch(handle_t *handle, struct inode *inode, - int indirect_blks, int *blks, ext4_fsblk_t goal, - int *offsets, Indirect *branch) -{ - int blocksize = inode->i_sb->s_blocksize; - int i, n = 0; - int err = 0; - struct buffer_head *bh; - int num; - ext4_fsblk_t new_blocks[4]; - ext4_fsblk_t current_block; - - num = ext4_alloc_blocks(handle, inode, goal, indirect_blks, - *blks, new_blocks, &err); - if (err) - return err; - - branch[0].key = cpu_to_le32(new_blocks[0]); - /* - * metadata blocks and data blocks are allocated. - */ - for (n = 1; n <= indirect_blks; n++) { - /* - * Get buffer_head for parent block, zero it out - * and set the pointer to new one, then send - * parent to disk. - */ - bh = sb_getblk(inode->i_sb, new_blocks[n-1]); - branch[n].bh = bh; - lock_buffer(bh); - BUFFER_TRACE(bh, "call get_create_access"); - err = ext4_journal_get_create_access(handle, bh); - if (err) { - unlock_buffer(bh); - brelse(bh); - goto failed; - } - - memset(bh->b_data, 0, blocksize); - branch[n].p = (__le32 *) bh->b_data + offsets[n]; - branch[n].key = cpu_to_le32(new_blocks[n]); - *branch[n].p = branch[n].key; - if ( n == indirect_blks) { - current_block = new_blocks[n]; - /* - * End of chain, update the last new metablock of - * the chain to point to the new allocated - * data blocks numbers - */ - for (i=1; i < num; i++) - *(branch[n].p + i) = cpu_to_le32(++current_block); - } - BUFFER_TRACE(bh, "marking uptodate"); - set_buffer_uptodate(bh); - unlock_buffer(bh); - - BUFFER_TRACE(bh, "call ext4_journal_dirty_metadata"); - err = ext4_journal_dirty_metadata(handle, bh); - if (err) - goto failed; - } - *blks = num; - return err; -failed: - /* Allocation failed, free what we already allocated */ - for (i = 1; i <= n ; i++) { - BUFFER_TRACE(branch[i].bh, "call jbd2_journal_forget"); - ext4_journal_forget(handle, branch[i].bh); - } - for (i = 0; i i_blocks, etc.). In case of success we end up with the full - * chain to new block and return 0. - */ -static int ext4_splice_branch(handle_t *handle, struct inode *inode, - long block, Indirect *where, int num, int blks) -{ - int i; - int err = 0; - struct ext4_block_alloc_info *block_i; - ext4_fsblk_t current_block; - - block_i = EXT4_I(inode)->i_block_alloc_info; - /* - * If we're splicing into a [td]indirect block (as opposed to the - * inode) then we need to get write access to the [td]indirect block - * before the splice. - */ - if (where->bh) { - BUFFER_TRACE(where->bh, "get_write_access"); - err = ext4_journal_get_write_access(handle, where->bh); - if (err) - goto err_out; - } - /* That's it */ - - *where->p = where->key; - - /* - * Update the host buffer_head or inode to point to more just allocated - * direct blocks blocks - */ - if (num == 0 && blks > 1) { - current_block = le32_to_cpu(where->key) + 1; - for (i = 1; i < blks; i++) - *(where->p + i ) = cpu_to_le32(current_block++); - } - - /* - * update the most recently allocated logical & physical block - * in i_block_alloc_info, to assist find the proper goal block for next - * allocation - */ - if (block_i) { - block_i->last_alloc_logical_block = block + blks - 1; - block_i->last_alloc_physical_block = - le32_to_cpu(where[num].key) + blks - 1; - } - - /* We are done with atomic stuff, now do the rest of housekeeping */ - - inode->i_ctime = CURRENT_TIME_SEC; - ext4_mark_inode_dirty(handle, inode); - - /* had we spliced it onto indirect block? */ - if (where->bh) { - /* - * If we spliced it onto an indirect block, we haven't - * altered the inode. Note however that if it is being spliced - * onto an indirect block at the very end of the file (the - * file is growing) then we *will* alter the inode to reflect - * the new i_size. But that is not done here - it is done in - * generic_commit_write->__mark_inode_dirty->ext4_dirty_inode. - */ - jbd_debug(5, "splicing indirect only\n"); - BUFFER_TRACE(where->bh, "call ext4_journal_dirty_metadata"); - err = ext4_journal_dirty_metadata(handle, where->bh); - if (err) - goto err_out; - } else { - /* - * OK, we spliced it into the inode itself on a direct block. - * Inode was dirtied above. - */ - jbd_debug(5, "splicing direct\n"); - } - return err; - -err_out: - for (i = 1; i <= num; i++) { - BUFFER_TRACE(where[i].bh, "call jbd2_journal_forget"); - ext4_journal_forget(handle, where[i].bh); - ext4_free_blocks(handle,inode,le32_to_cpu(where[i-1].key),1); - } - ext4_free_blocks(handle, inode, le32_to_cpu(where[num].key), blks); - - return err; -} - -/* - * Allocation strategy is simple: if we have to allocate something, we will - * have to go the whole way to leaf. So let's do it before attaching anything - * to tree, set linkage between the newborn blocks, write them if sync is - * required, recheck the path, free and repeat if check fails, otherwise - * set the last missing link (that will protect us from any truncate-generated - * removals - all blocks on the path are immune now) and possibly force the - * write on the parent block. - * That has a nice additional property: no special recovery from the failed - * allocations is needed - we simply release blocks and do not touch anything - * reachable from inode. - * - * `handle' can be NULL if create == 0. - * - * The BKL may not be held on entry here. Be sure to take it early. - * return > 0, # of blocks mapped or allocated. - * return = 0, if plain lookup failed. - * return < 0, error case. - */ -int ext4_get_blocks_handle(handle_t *handle, struct inode *inode, - sector_t iblock, unsigned long maxblocks, - struct buffer_head *bh_result, - int create, int extend_disksize) -{ - int err = -EIO; - int offsets[4]; - Indirect chain[4]; - Indirect *partial; - ext4_fsblk_t goal; - int indirect_blks; - int blocks_to_boundary = 0; - int depth; - struct ext4_inode_info *ei = EXT4_I(inode); - int count = 0; - ext4_fsblk_t first_block = 0; - - - J_ASSERT(!(EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL)); - J_ASSERT(handle != NULL || create == 0); - depth = ext4_block_to_path(inode,iblock,offsets,&blocks_to_boundary); - - if (depth == 0) - goto out; - - partial = ext4_get_branch(inode, depth, offsets, chain, &err); - - /* Simplest case - block found, no allocation needed */ - if (!partial) { - first_block = le32_to_cpu(chain[depth - 1].key); - clear_buffer_new(bh_result); - count++; - /*map more blocks*/ - while (count < maxblocks && count <= blocks_to_boundary) { - ext4_fsblk_t blk; - - if (!verify_chain(chain, partial)) { - /* - * Indirect block might be removed by - * truncate while we were reading it. - * Handling of that case: forget what we've - * got now. Flag the err as EAGAIN, so it - * will reread. - */ - err = -EAGAIN; - count = 0; - break; - } - blk = le32_to_cpu(*(chain[depth-1].p + count)); - - if (blk == first_block + count) - count++; - else - break; - } - if (err != -EAGAIN) - goto got_it; - } - - /* Next simple case - plain lookup or failed read of indirect block */ - if (!create || err == -EIO) - goto cleanup; - - mutex_lock(&ei->truncate_mutex); - - /* - * If the indirect block is missing while we are reading - * the chain(ext4_get_branch() returns -EAGAIN err), or - * if the chain has been changed after we grab the semaphore, - * (either because another process truncated this branch, or - * another get_block allocated this branch) re-grab the chain to see if - * the request block has been allocated or not. - * - * Since we already block the truncate/other get_block - * at this point, we will have the current copy of the chain when we - * splice the branch into the tree. - */ - if (err == -EAGAIN || !verify_chain(chain, partial)) { - while (partial > chain) { - brelse(partial->bh); - partial--; - } - partial = ext4_get_branch(inode, depth, offsets, chain, &err); - if (!partial) { - count++; - mutex_unlock(&ei->truncate_mutex); - if (err) - goto cleanup; - clear_buffer_new(bh_result); - goto got_it; - } - } - - /* - * Okay, we need to do block allocation. Lazily initialize the block - * allocation info here if necessary - */ - if (S_ISREG(inode->i_mode) && (!ei->i_block_alloc_info)) - ext4_init_block_alloc_info(inode); - - goal = ext4_find_goal(inode, iblock, chain, partial); - - /* the number of blocks need to allocate for [d,t]indirect blocks */ - indirect_blks = (chain + depth) - partial - 1; - - /* - * Next look up the indirect map to count the totoal number of - * direct blocks to allocate for this branch. - */ - count = ext4_blks_to_allocate(partial, indirect_blks, - maxblocks, blocks_to_boundary); - /* - * Block out ext4_truncate while we alter the tree - */ - err = ext4_alloc_branch(handle, inode, indirect_blks, &count, goal, - offsets + (partial - chain), partial); - - /* - * The ext4_splice_branch call will free and forget any buffers - * on the new chain if there is a failure, but that risks using - * up transaction credits, especially for bitmaps where the - * credits cannot be returned. Can we handle this somehow? We - * may need to return -EAGAIN upwards in the worst case. --sct - */ - if (!err) - err = ext4_splice_branch(handle, inode, iblock, - partial, indirect_blks, count); - /* - * i_disksize growing is protected by truncate_mutex. Don't forget to - * protect it if you're about to implement concurrent - * ext4_get_block() -bzzz - */ - if (!err && extend_disksize && inode->i_size > ei->i_disksize) - ei->i_disksize = inode->i_size; - mutex_unlock(&ei->truncate_mutex); - if (err) - goto cleanup; - - set_buffer_new(bh_result); -got_it: - map_bh(bh_result, inode->i_sb, le32_to_cpu(chain[depth-1].key)); - if (count > blocks_to_boundary) - set_buffer_boundary(bh_result); - err = count; - /* Clean up and exit */ - partial = chain + depth - 1; /* the whole chain */ -cleanup: - while (partial > chain) { - BUFFER_TRACE(partial->bh, "call brelse"); - brelse(partial->bh); - partial--; - } - BUFFER_TRACE(bh_result, "returned"); -out: - return err; -} - -#define DIO_CREDITS (EXT4_RESERVE_TRANS_BLOCKS + 32) - -static int ext4_get_block(struct inode *inode, sector_t iblock, - struct buffer_head *bh_result, int create) -{ - handle_t *handle = journal_current_handle(); - int ret = 0; - unsigned max_blocks = bh_result->b_size >> inode->i_blkbits; - - if (!create) - goto get_block; /* A read */ - - if (max_blocks == 1) - goto get_block; /* A single block get */ - - if (handle->h_transaction->t_state == T_LOCKED) { - /* - * Huge direct-io writes can hold off commits for long - * periods of time. Let this commit run. - */ - ext4_journal_stop(handle); - handle = ext4_journal_start(inode, DIO_CREDITS); - if (IS_ERR(handle)) - ret = PTR_ERR(handle); - goto get_block; - } - - if (handle->h_buffer_credits <= EXT4_RESERVE_TRANS_BLOCKS) { - /* - * Getting low on buffer credits... - */ - ret = ext4_journal_extend(handle, DIO_CREDITS); - if (ret > 0) { - /* - * Couldn't extend the transaction. Start a new one. - */ - ret = ext4_journal_restart(handle, DIO_CREDITS); - } - } - -get_block: - if (ret == 0) { - ret = ext4_get_blocks_wrap(handle, inode, iblock, - max_blocks, bh_result, create, 0); - if (ret > 0) { - bh_result->b_size = (ret << inode->i_blkbits); - ret = 0; - } - } - return ret; -} - -/* - * `handle' can be NULL if create is zero - */ -struct buffer_head *ext4_getblk(handle_t *handle, struct inode *inode, - long block, int create, int *errp) -{ - struct buffer_head dummy; - int fatal = 0, err; - - J_ASSERT(handle != NULL || create == 0); - - dummy.b_state = 0; - dummy.b_blocknr = -1000; - buffer_trace_init(&dummy.b_history); - err = ext4_get_blocks_wrap(handle, inode, block, 1, - &dummy, create, 1); - /* - * ext4_get_blocks_handle() returns number of blocks - * mapped. 0 in case of a HOLE. - */ - if (err > 0) { - if (err > 1) - WARN_ON(1); - err = 0; - } - *errp = err; - if (!err && buffer_mapped(&dummy)) { - struct buffer_head *bh; - bh = sb_getblk(inode->i_sb, dummy.b_blocknr); - if (!bh) { - *errp = -EIO; - goto err; - } - if (buffer_new(&dummy)) { - J_ASSERT(create != 0); - J_ASSERT(handle != 0); - - /* - * Now that we do not always journal data, we should - * keep in mind whether this should always journal the - * new buffer as metadata. For now, regular file - * writes use ext4_get_block instead, so it's not a - * problem. - */ - lock_buffer(bh); - BUFFER_TRACE(bh, "call get_create_access"); - fatal = ext4_journal_get_create_access(handle, bh); - if (!fatal && !buffer_uptodate(bh)) { - memset(bh->b_data,0,inode->i_sb->s_blocksize); - set_buffer_uptodate(bh); - } - unlock_buffer(bh); - BUFFER_TRACE(bh, "call ext4_journal_dirty_metadata"); - err = ext4_journal_dirty_metadata(handle, bh); - if (!fatal) - fatal = err; - } else { - BUFFER_TRACE(bh, "not a new buffer"); - } - if (fatal) { - *errp = fatal; - brelse(bh); - bh = NULL; - } - return bh; - } -err: - return NULL; -} - -struct buffer_head *ext4_bread(handle_t *handle, struct inode *inode, - int block, int create, int *err) -{ - struct buffer_head * bh; - - bh = ext4_getblk(handle, inode, block, create, err); - if (!bh) - return bh; - if (buffer_uptodate(bh)) - return bh; - ll_rw_block(READ_META, 1, &bh); - wait_on_buffer(bh); - if (buffer_uptodate(bh)) - return bh; - put_bh(bh); - *err = -EIO; - return NULL; -} - -static int walk_page_buffers( handle_t *handle, - struct buffer_head *head, - unsigned from, - unsigned to, - int *partial, - int (*fn)( handle_t *handle, - struct buffer_head *bh)) -{ - struct buffer_head *bh; - unsigned block_start, block_end; - unsigned blocksize = head->b_size; - int err, ret = 0; - struct buffer_head *next; - - for ( bh = head, block_start = 0; - ret == 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 || block_start >= to) { - if (partial && !buffer_uptodate(bh)) - *partial = 1; - continue; - } - err = (*fn)(handle, bh); - if (!ret) - ret = err; - } - return ret; -} - -/* - * To preserve ordering, it is essential that the hole instantiation and - * the data write be encapsulated in a single transaction. We cannot - * close off a transaction and start a new one between the ext4_get_block() - * and the commit_write(). So doing the jbd2_journal_start at the start of - * prepare_write() is the right place. - * - * Also, this function can nest inside ext4_writepage() -> - * block_write_full_page(). In that case, we *know* that ext4_writepage() - * has generated enough buffer credits to do the whole page. So we won't - * block on the journal in that case, which is good, because the caller may - * be PF_MEMALLOC. - * - * By accident, ext4 can be reentered when a transaction is open via - * quota file writes. If we were to commit the transaction while thus - * reentered, there can be a deadlock - we would be holding a quota - * lock, and the commit would never complete if another thread had a - * transaction open and was blocking on the quota lock - a ranking - * violation. - * - * So what we do is to rely on the fact that jbd2_journal_stop/journal_start - * will _not_ run commit under these circumstances because handle->h_ref - * is elevated. We'll still have enough credits for the tiny quotafile - * write. - */ -static int do_journal_get_write_access(handle_t *handle, - struct buffer_head *bh) -{ - if (!buffer_mapped(bh) || buffer_freed(bh)) - return 0; - return ext4_journal_get_write_access(handle, bh); -} - -static int ext4_prepare_write(struct file *file, struct page *page, - unsigned from, unsigned to) -{ - struct inode *inode = page->mapping->host; - 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)) { - 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 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); - } -prepare_write_failed: - if (ret) - ext4_journal_stop(handle); - if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) - goto retry; -out: - return ret; -} - -int ext4_journal_dirty_data(handle_t *handle, struct buffer_head *bh) -{ - int err = jbd2_journal_dirty_data(handle, bh); - if (err) - ext4_journal_abort_handle(__FUNCTION__, __FUNCTION__, - bh, handle,err); - return err; -} - -/* For commit_write() in data=journal mode */ -static int commit_write_fn(handle_t *handle, struct buffer_head *bh) -{ - if (!buffer_mapped(bh) || buffer_freed(bh)) - return 0; - set_buffer_uptodate(bh); - return ext4_journal_dirty_metadata(handle, bh); -} - -/* - * We need to pick up the new inode size which generic_commit_write gave us - * `file' can be NULL - eg, when called from page_symlink(). - * - * ext4 never places buffers on inode->i_mapping->private_list. metadata - * buffers are managed internally. - */ -static int ext4_ordered_commit_write(struct file *file, struct page *page, - unsigned from, unsigned to) -{ - handle_t *handle = ext4_journal_current_handle(); - struct inode *inode = page->mapping->host; - int ret = 0, ret2; - - ret = walk_page_buffers(handle, page_buffers(page), - from, to, NULL, ext4_journal_dirty_data); - - if (ret == 0) { - /* - * generic_commit_write() will run mark_inode_dirty() if i_size - * changes. So let's piggyback the i_disksize mark_inode_dirty - * into that. - */ - loff_t new_i_size; - - new_i_size = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to; - if (new_i_size > EXT4_I(inode)->i_disksize) - EXT4_I(inode)->i_disksize = new_i_size; - ret = generic_commit_write(file, page, from, to); - } - ret2 = ext4_journal_stop(handle); - if (!ret) - ret = ret2; - return ret; -} - -static int ext4_writeback_commit_write(struct file *file, struct page *page, - unsigned from, unsigned to) -{ - handle_t *handle = ext4_journal_current_handle(); - struct inode *inode = page->mapping->host; - int ret = 0, ret2; - loff_t new_i_size; - - new_i_size = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to; - if (new_i_size > EXT4_I(inode)->i_disksize) - EXT4_I(inode)->i_disksize = new_i_size; - - if (test_opt(inode->i_sb, NOBH) && ext4_should_writeback_data(inode)) - ret = nobh_commit_write(file, page, from, to); - else - ret = generic_commit_write(file, page, from, to); - - ret2 = ext4_journal_stop(handle); - if (!ret) - ret = ret2; - return ret; -} - -static int ext4_journalled_commit_write(struct file *file, - struct page *page, unsigned from, unsigned to) -{ - handle_t *handle = ext4_journal_current_handle(); - struct inode *inode = page->mapping->host; - int ret = 0, ret2; - int partial = 0; - loff_t pos; - - /* - * Here we duplicate the generic_commit_write() functionality - */ - pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to; - - ret = walk_page_buffers(handle, page_buffers(page), from, - to, &partial, commit_write_fn); - if (!partial) - SetPageUptodate(page); - if (pos > inode->i_size) - i_size_write(inode, pos); - EXT4_I(inode)->i_state |= EXT4_STATE_JDATA; - if (inode->i_size > EXT4_I(inode)->i_disksize) { - EXT4_I(inode)->i_disksize = inode->i_size; - ret2 = ext4_mark_inode_dirty(handle, inode); - if (!ret) - ret = ret2; - } - ret2 = ext4_journal_stop(handle); - if (!ret) - ret = ret2; - return ret; -} - -/* - * bmap() is special. It gets used by applications such as lilo and by - * the swapper to find the on-disk block of a specific piece of data. - * - * Naturally, this is dangerous if the block concerned is still in the - * journal. If somebody makes a swapfile on an ext4 data-journaling - * filesystem and enables swap, then they may get a nasty shock when the - * data getting swapped to that swapfile suddenly gets overwritten by - * the original zero's written out previously to the journal and - * awaiting writeback in the kernel's buffer cache. - * - * So, if we see any bmap calls here on a modified, data-journaled file, - * take extra steps to flush any blocks which might be in the cache. - */ -static sector_t ext4_bmap(struct address_space *mapping, sector_t block) -{ - struct inode *inode = mapping->host; - journal_t *journal; - int err; - - if (EXT4_I(inode)->i_state & EXT4_STATE_JDATA) { - /* - * This is a REALLY heavyweight approach, but the use of - * bmap on dirty files is expected to be extremely rare: - * only if we run lilo or swapon on a freshly made file - * do we expect this to happen. - * - * (bmap requires CAP_SYS_RAWIO so this does not - * represent an unprivileged user DOS attack --- we'd be - * in trouble if mortal users could trigger this path at - * will.) - * - * NB. EXT4_STATE_JDATA is not set on files other than - * regular files. If somebody wants to bmap a directory - * or symlink and gets confused because the buffer - * hasn't yet been flushed to disk, they deserve - * everything they get. - */ - - EXT4_I(inode)->i_state &= ~EXT4_STATE_JDATA; - journal = EXT4_JOURNAL(inode); - jbd2_journal_lock_updates(journal); - err = jbd2_journal_flush(journal); - jbd2_journal_unlock_updates(journal); - - if (err) - return 0; - } - - return generic_block_bmap(mapping,block,ext4_get_block); -} - -static int bget_one(handle_t *handle, struct buffer_head *bh) -{ - get_bh(bh); - return 0; -} - -static int bput_one(handle_t *handle, struct buffer_head *bh) -{ - put_bh(bh); - return 0; -} - -static int jbd2_journal_dirty_data_fn(handle_t *handle, struct buffer_head *bh) -{ - if (buffer_mapped(bh)) - return ext4_journal_dirty_data(handle, bh); - return 0; -} - -/* - * Note that we always start a transaction even if we're not journalling - * data. This is to preserve ordering: any hole instantiation within - * __block_write_full_page -> ext4_get_block() should be journalled - * along with the data so we don't crash and then get metadata which - * refers to old data. - * - * In all journalling modes block_write_full_page() will start the I/O. - * - * Problem: - * - * ext4_writepage() -> kmalloc() -> __alloc_pages() -> page_launder() -> - * ext4_writepage() - * - * Similar for: - * - * ext4_file_write() -> generic_file_write() -> __alloc_pages() -> ... - * - * Same applies to ext4_get_block(). We will deadlock on various things like - * lock_journal and i_truncate_mutex. - * - * Setting PF_MEMALLOC here doesn't work - too many internal memory - * allocations fail. - * - * 16May01: If we're reentered then journal_current_handle() will be - * non-zero. We simply *return*. - * - * 1 July 2001: @@@ FIXME: - * In journalled data mode, a data buffer may be metadata against the - * current transaction. But the same file is part of a shared mapping - * and someone does a writepage() on it. - * - * We will move the buffer onto the async_data list, but *after* it has - * been dirtied. So there's a small window where we have dirty data on - * BJ_Metadata. - * - * Note that this only applies to the last partial page in the file. The - * bit which block_write_full_page() uses prepare/commit for. (That's - * broken code anyway: it's wrong for msync()). - * - * It's a rare case: affects the final partial page, for journalled data - * where the file is subject to bith write() and writepage() in the same - * transction. To fix it we'll need a custom block_write_full_page(). - * We'll probably need that anyway for journalling writepage() output. - * - * We don't honour synchronous mounts for writepage(). That would be - * disastrous. Any write() or metadata operation will sync the fs for - * us. - * - * AKPM2: if all the page's buffers are mapped to disk and !data=journal, - * we don't need to open a transaction here. - */ -static int ext4_ordered_writepage(struct page *page, - struct writeback_control *wbc) -{ - struct inode *inode = page->mapping->host; - struct buffer_head *page_bufs; - handle_t *handle = NULL; - int ret = 0; - int err; - - J_ASSERT(PageLocked(page)); - - /* - * We give up here if we're reentered, because it might be for a - * different filesystem. - */ - if (ext4_journal_current_handle()) - goto out_fail; - - handle = ext4_journal_start(inode, ext4_writepage_trans_blocks(inode)); - - if (IS_ERR(handle)) { - ret = PTR_ERR(handle); - goto out_fail; - } - - if (!page_has_buffers(page)) { - create_empty_buffers(page, inode->i_sb->s_blocksize, - (1 << BH_Dirty)|(1 << BH_Uptodate)); - } - page_bufs = page_buffers(page); - walk_page_buffers(handle, page_bufs, 0, - PAGE_CACHE_SIZE, NULL, bget_one); - - ret = block_write_full_page(page, ext4_get_block, wbc); - - /* - * The page can become unlocked at any point now, and - * truncate can then come in and change things. So we - * can't touch *page from now on. But *page_bufs is - * safe due to elevated refcount. - */ - - /* - * And attach them to the current transaction. But only if - * block_write_full_page() succeeded. Otherwise they are unmapped, - * and generally junk. - */ - if (ret == 0) { - err = walk_page_buffers(handle, page_bufs, 0, PAGE_CACHE_SIZE, - NULL, jbd2_journal_dirty_data_fn); - if (!ret) - ret = err; - } - walk_page_buffers(handle, page_bufs, 0, - PAGE_CACHE_SIZE, NULL, bput_one); - err = ext4_journal_stop(handle); - if (!ret) - ret = err; - return ret; - -out_fail: - redirty_page_for_writepage(wbc, page); - unlock_page(page); - return ret; -} - -static int ext4_writeback_writepage(struct page *page, - struct writeback_control *wbc) -{ - struct inode *inode = page->mapping->host; - handle_t *handle = NULL; - int ret = 0; - int err; - - if (ext4_journal_current_handle()) - goto out_fail; - - handle = ext4_journal_start(inode, ext4_writepage_trans_blocks(inode)); - if (IS_ERR(handle)) { - ret = PTR_ERR(handle); - goto out_fail; - } - - if (test_opt(inode->i_sb, NOBH) && ext4_should_writeback_data(inode)) - ret = nobh_writepage(page, ext4_get_block, wbc); - else - ret = block_write_full_page(page, ext4_get_block, wbc); - - err = ext4_journal_stop(handle); - if (!ret) - ret = err; - return ret; - -out_fail: - redirty_page_for_writepage(wbc, page); - unlock_page(page); - return ret; -} - -static int ext4_journalled_writepage(struct page *page, - struct writeback_control *wbc) -{ - struct inode *inode = page->mapping->host; - handle_t *handle = NULL; - int ret = 0; - int err; - - if (ext4_journal_current_handle()) - goto no_write; - - handle = ext4_journal_start(inode, ext4_writepage_trans_blocks(inode)); - if (IS_ERR(handle)) { - ret = PTR_ERR(handle); - goto no_write; - } - - if (!page_has_buffers(page) || PageChecked(page)) { - /* - * It's mmapped pagecache. Add buffers and journal it. There - * doesn't seem much point in redirtying the page here. - */ - ClearPageChecked(page); - ret = block_prepare_write(page, 0, PAGE_CACHE_SIZE, - ext4_get_block); - if (ret != 0) { - ext4_journal_stop(handle); - goto out_unlock; - } - ret = walk_page_buffers(handle, page_buffers(page), 0, - PAGE_CACHE_SIZE, NULL, do_journal_get_write_access); - - err = walk_page_buffers(handle, page_buffers(page), 0, - PAGE_CACHE_SIZE, NULL, commit_write_fn); - if (ret == 0) - ret = err; - EXT4_I(inode)->i_state |= EXT4_STATE_JDATA; - unlock_page(page); - } else { - /* - * It may be a page full of checkpoint-mode buffers. We don't - * really know unless we go poke around in the buffer_heads. - * But block_write_full_page will do the right thing. - */ - ret = block_write_full_page(page, ext4_get_block, wbc); - } - err = ext4_journal_stop(handle); - if (!ret) - ret = err; -out: - return ret; - -no_write: - redirty_page_for_writepage(wbc, page); -out_unlock: - unlock_page(page); - goto out; -} - -static int ext4_readpage(struct file *file, struct page *page) -{ - return mpage_readpage(page, ext4_get_block); -} - -static int -ext4_readpages(struct file *file, struct address_space *mapping, - struct list_head *pages, unsigned nr_pages) -{ - return mpage_readpages(mapping, pages, nr_pages, ext4_get_block); -} - -static void ext4_invalidatepage(struct page *page, unsigned long offset) -{ - journal_t *journal = EXT4_JOURNAL(page->mapping->host); - - /* - * If it's a full truncate we just forget about the pending dirtying - */ - if (offset == 0) - ClearPageChecked(page); - - jbd2_journal_invalidatepage(journal, page, offset); -} - -static int ext4_releasepage(struct page *page, gfp_t wait) -{ - journal_t *journal = EXT4_JOURNAL(page->mapping->host); - - WARN_ON(PageChecked(page)); - if (!page_has_buffers(page)) - return 0; - return jbd2_journal_try_to_free_buffers(journal, page, wait); -} - -/* - * If the O_DIRECT write will extend the file then add this inode to the - * orphan list. So recovery will truncate it back to the original size - * if the machine crashes during the write. - * - * If the O_DIRECT write is intantiating holes inside i_size and the machine - * crashes then stale disk data _may_ be exposed inside the file. - */ -static ssize_t ext4_direct_IO(int rw, struct kiocb *iocb, - const struct iovec *iov, loff_t offset, - unsigned long nr_segs) -{ - struct file *file = iocb->ki_filp; - struct inode *inode = file->f_mapping->host; - struct ext4_inode_info *ei = EXT4_I(inode); - handle_t *handle = NULL; - ssize_t ret; - int orphan = 0; - size_t count = iov_length(iov, nr_segs); - - if (rw == WRITE) { - loff_t final_size = offset + count; - - handle = ext4_journal_start(inode, DIO_CREDITS); - if (IS_ERR(handle)) { - ret = PTR_ERR(handle); - goto out; - } - if (final_size > inode->i_size) { - ret = ext4_orphan_add(handle, inode); - if (ret) - goto out_stop; - orphan = 1; - ei->i_disksize = inode->i_size; - } - } - - ret = blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov, - offset, nr_segs, - ext4_get_block, NULL); - - /* - * Reacquire the handle: ext4_get_block() can restart the transaction - */ - handle = journal_current_handle(); - -out_stop: - if (handle) { - int err; - - if (orphan && inode->i_nlink) - ext4_orphan_del(handle, inode); - if (orphan && ret > 0) { - loff_t end = offset + ret; - if (end > inode->i_size) { - ei->i_disksize = end; - i_size_write(inode, end); - /* - * We're going to return a positive `ret' - * here due to non-zero-length I/O, so there's - * no way of reporting error returns from - * ext4_mark_inode_dirty() to userspace. So - * ignore it. - */ - ext4_mark_inode_dirty(handle, inode); - } - } - err = ext4_journal_stop(handle); - if (ret == 0) - ret = err; - } -out: - return ret; -} - -/* - * Pages can be marked dirty completely asynchronously from ext4's journalling - * activity. By filemap_sync_pte(), try_to_unmap_one(), etc. We cannot do - * much here because ->set_page_dirty is called under VFS locks. The page is - * not necessarily locked. - * - * We cannot just dirty the page and leave attached buffers clean, because the - * buffers' dirty state is "definitive". We cannot just set the buffers dirty - * or jbddirty because all the journalling code will explode. - * - * So what we do is to mark the page "pending dirty" and next time writepage - * is called, propagate that into the buffers appropriately. - */ -static int ext4_journalled_set_page_dirty(struct page *page) -{ - SetPageChecked(page); - return __set_page_dirty_nobuffers(page); -} - -static const struct address_space_operations ext4_ordered_aops = { - .readpage = ext4_readpage, - .readpages = ext4_readpages, - .writepage = ext4_ordered_writepage, - .sync_page = block_sync_page, - .prepare_write = ext4_prepare_write, - .commit_write = ext4_ordered_commit_write, - .bmap = ext4_bmap, - .invalidatepage = ext4_invalidatepage, - .releasepage = ext4_releasepage, - .direct_IO = ext4_direct_IO, - .migratepage = buffer_migrate_page, -}; - -static const struct address_space_operations ext4_writeback_aops = { - .readpage = ext4_readpage, - .readpages = ext4_readpages, - .writepage = ext4_writeback_writepage, - .sync_page = block_sync_page, - .prepare_write = ext4_prepare_write, - .commit_write = ext4_writeback_commit_write, - .bmap = ext4_bmap, - .invalidatepage = ext4_invalidatepage, - .releasepage = ext4_releasepage, - .direct_IO = ext4_direct_IO, - .migratepage = buffer_migrate_page, -}; - -static const struct address_space_operations ext4_journalled_aops = { - .readpage = ext4_readpage, - .readpages = ext4_readpages, - .writepage = ext4_journalled_writepage, - .sync_page = block_sync_page, - .prepare_write = ext4_prepare_write, - .commit_write = ext4_journalled_commit_write, - .set_page_dirty = ext4_journalled_set_page_dirty, - .bmap = ext4_bmap, - .invalidatepage = ext4_invalidatepage, - .releasepage = ext4_releasepage, -}; - -void ext4_set_aops(struct inode *inode) -{ - if (ext4_should_order_data(inode)) - inode->i_mapping->a_ops = &ext4_ordered_aops; - else if (ext4_should_writeback_data(inode)) - inode->i_mapping->a_ops = &ext4_writeback_aops; - else - inode->i_mapping->a_ops = &ext4_journalled_aops; -} - -/* - * ext4_block_truncate_page() zeroes out a mapping from file offset `from' - * up to the end of the block which corresponds to `from'. - * This required during truncate. We need to physically zero the tail end - * of that block so it doesn't yield old data if the file is later grown. - */ -int ext4_block_truncate_page(handle_t *handle, struct page *page, - struct address_space *mapping, loff_t from) -{ - ext4_fsblk_t index = from >> PAGE_CACHE_SHIFT; - unsigned offset = from & (PAGE_CACHE_SIZE-1); - unsigned blocksize, iblock, length, pos; - struct inode *inode = mapping->host; - struct buffer_head *bh; - int err = 0; - void *kaddr; - - blocksize = inode->i_sb->s_blocksize; - length = blocksize - (offset & (blocksize - 1)); - iblock = index << (PAGE_CACHE_SHIFT - inode->i_sb->s_blocksize_bits); - - /* - * For "nobh" option, we can only work if we don't need to - * read-in the page - otherwise we create buffers to do the IO. - */ - if (!page_has_buffers(page) && test_opt(inode->i_sb, NOBH) && - ext4_should_writeback_data(inode) && PageUptodate(page)) { - kaddr = kmap_atomic(page, KM_USER0); - memset(kaddr + offset, 0, length); - flush_dcache_page(page); - kunmap_atomic(kaddr, KM_USER0); - set_page_dirty(page); - goto unlock; - } - - if (!page_has_buffers(page)) - create_empty_buffers(page, blocksize, 0); - - /* Find the buffer that contains "offset" */ - bh = page_buffers(page); - pos = blocksize; - while (offset >= pos) { - bh = bh->b_this_page; - iblock++; - pos += blocksize; - } - - err = 0; - if (buffer_freed(bh)) { - BUFFER_TRACE(bh, "freed: skip"); - goto unlock; - } - - if (!buffer_mapped(bh)) { - BUFFER_TRACE(bh, "unmapped"); - ext4_get_block(inode, iblock, bh, 0); - /* unmapped? It's a hole - nothing to do */ - if (!buffer_mapped(bh)) { - BUFFER_TRACE(bh, "still unmapped"); - goto unlock; - } - } - - /* Ok, it's mapped. Make sure it's up-to-date */ - if (PageUptodate(page)) - set_buffer_uptodate(bh); - - if (!buffer_uptodate(bh)) { - err = -EIO; - ll_rw_block(READ, 1, &bh); - wait_on_buffer(bh); - /* Uhhuh. Read error. Complain and punt. */ - if (!buffer_uptodate(bh)) - goto unlock; - } - - if (ext4_should_journal_data(inode)) { - BUFFER_TRACE(bh, "get write access"); - err = ext4_journal_get_write_access(handle, bh); - if (err) - goto unlock; - } - - kaddr = kmap_atomic(page, KM_USER0); - memset(kaddr + offset, 0, length); - flush_dcache_page(page); - kunmap_atomic(kaddr, KM_USER0); - - BUFFER_TRACE(bh, "zeroed end of block"); - - err = 0; - if (ext4_should_journal_data(inode)) { - err = ext4_journal_dirty_metadata(handle, bh); - } else { - if (ext4_should_order_data(inode)) - err = ext4_journal_dirty_data(handle, bh); - mark_buffer_dirty(bh); - } - -unlock: - unlock_page(page); - page_cache_release(page); - return err; -} - -/* - * Probably it should be a library function... search for first non-zero word - * or memcmp with zero_page, whatever is better for particular architecture. - * Linus? - */ -static inline int all_zeroes(__le32 *p, __le32 *q) -{ - while (p < q) - if (*p++) - return 0; - return 1; -} - -/** - * ext4_find_shared - find the indirect blocks for partial truncation. - * @inode: inode in question - * @depth: depth of the affected branch - * @offsets: offsets of pointers in that branch (see ext4_block_to_path) - * @chain: place to store the pointers to partial indirect blocks - * @top: place to the (detached) top of branch - * - * This is a helper function used by ext4_truncate(). - * - * When we do truncate() we may have to clean the ends of several - * indirect blocks but leave the blocks themselves alive. Block is - * partially truncated if some data below the new i_size is refered - * from it (and it is on the path to the first completely truncated - * data block, indeed). We have to free the top of that path along - * with everything to the right of the path. Since no allocation - * past the truncation point is possible until ext4_truncate() - * finishes, we may safely do the latter, but top of branch may - * require special attention - pageout below the truncation point - * might try to populate it. - * - * We atomically detach the top of branch from the tree, store the - * block number of its root in *@top, pointers to buffer_heads of - * partially truncated blocks - in @chain[].bh and pointers to - * their last elements that should not be removed - in - * @chain[].p. Return value is the pointer to last filled element - * of @chain. - * - * The work left to caller to do the actual freeing of subtrees: - * a) free the subtree starting from *@top - * b) free the subtrees whose roots are stored in - * (@chain[i].p+1 .. end of @chain[i].bh->b_data) - * c) free the subtrees growing from the inode past the @chain[0]. - * (no partially truncated stuff there). */ - -static Indirect *ext4_find_shared(struct inode *inode, int depth, - int offsets[4], Indirect chain[4], __le32 *top) -{ - Indirect *partial, *p; - int k, err; - - *top = 0; - /* Make k index the deepest non-null offest + 1 */ - for (k = depth; k > 1 && !offsets[k-1]; k--) - ; - partial = ext4_get_branch(inode, k, offsets, chain, &err); - /* Writer: pointers */ - if (!partial) - partial = chain + k-1; - /* - * If the branch acquired continuation since we've looked at it - - * fine, it should all survive and (new) top doesn't belong to us. - */ - if (!partial->key && *partial->p) - /* Writer: end */ - goto no_top; - for (p=partial; p>chain && all_zeroes((__le32*)p->bh->b_data,p->p); p--) - ; - /* - * OK, we've found the last block that must survive. The rest of our - * branch should be detached before unlocking. However, if that rest - * of branch is all ours and does not grow immediately from the inode - * it's easier to cheat and just decrement partial->p. - */ - if (p == chain + k - 1 && p > chain) { - p->p--; - } else { - *top = *p->p; - /* Nope, don't do this in ext4. Must leave the tree intact */ -#if 0 - *p->p = 0; -#endif - } - /* Writer: end */ - - while(partial > p) { - brelse(partial->bh); - partial--; - } -no_top: - return partial; -} - -/* - * Zero a number of block pointers in either an inode or an indirect block. - * If we restart the transaction we must again get write access to the - * indirect block for further modification. - * - * We release `count' blocks on disk, but (last - first) may be greater - * than `count' because there can be holes in there. - */ -static void ext4_clear_blocks(handle_t *handle, struct inode *inode, - struct buffer_head *bh, ext4_fsblk_t block_to_free, - unsigned long count, __le32 *first, __le32 *last) -{ - __le32 *p; - if (try_to_extend_transaction(handle, inode)) { - if (bh) { - BUFFER_TRACE(bh, "call ext4_journal_dirty_metadata"); - ext4_journal_dirty_metadata(handle, bh); - } - ext4_mark_inode_dirty(handle, inode); - ext4_journal_test_restart(handle, inode); - if (bh) { - BUFFER_TRACE(bh, "retaking write access"); - ext4_journal_get_write_access(handle, bh); - } - } - - /* - * Any buffers which are on the journal will be in memory. We find - * them on the hash table so jbd2_journal_revoke() will run jbd2_journal_forget() - * on them. We've already detached each block from the file, so - * bforget() in jbd2_journal_forget() should be safe. - * - * AKPM: turn on bforget in jbd2_journal_forget()!!! - */ - for (p = first; p < last; p++) { - u32 nr = le32_to_cpu(*p); - if (nr) { - struct buffer_head *bh; - - *p = 0; - bh = sb_find_get_block(inode->i_sb, nr); - ext4_forget(handle, 0, inode, bh, nr); - } - } - - ext4_free_blocks(handle, inode, block_to_free, count); -} - -/** - * ext4_free_data - free a list of data blocks - * @handle: handle for this transaction - * @inode: inode we are dealing with - * @this_bh: indirect buffer_head which contains *@first and *@last - * @first: array of block numbers - * @last: points immediately past the end of array - * - * We are freeing all blocks refered from that array (numbers are stored as - * little-endian 32-bit) and updating @inode->i_blocks appropriately. - * - * We accumulate contiguous runs of blocks to free. Conveniently, if these - * blocks are contiguous then releasing them at one time will only affect one - * or two bitmap blocks (+ group descriptor(s) and superblock) and we won't - * actually use a lot of journal space. - * - * @this_bh will be %NULL if @first and @last point into the inode's direct - * block pointers. - */ -static void ext4_free_data(handle_t *handle, struct inode *inode, - struct buffer_head *this_bh, - __le32 *first, __le32 *last) -{ - ext4_fsblk_t block_to_free = 0; /* Starting block # of a run */ - unsigned long count = 0; /* Number of blocks in the run */ - __le32 *block_to_free_p = NULL; /* Pointer into inode/ind - corresponding to - block_to_free */ - ext4_fsblk_t nr; /* Current block # */ - __le32 *p; /* Pointer into inode/ind - for current block */ - int err; - - if (this_bh) { /* For indirect block */ - BUFFER_TRACE(this_bh, "get_write_access"); - err = ext4_journal_get_write_access(handle, this_bh); - /* Important: if we can't update the indirect pointers - * to the blocks, we can't free them. */ - if (err) - return; - } - - for (p = first; p < last; p++) { - nr = le32_to_cpu(*p); - if (nr) { - /* accumulate blocks to free if they're contiguous */ - if (count == 0) { - block_to_free = nr; - block_to_free_p = p; - count = 1; - } else if (nr == block_to_free + count) { - count++; - } else { - ext4_clear_blocks(handle, inode, this_bh, - block_to_free, - count, block_to_free_p, p); - block_to_free = nr; - block_to_free_p = p; - count = 1; - } - } - } - - if (count > 0) - ext4_clear_blocks(handle, inode, this_bh, block_to_free, - count, block_to_free_p, p); - - if (this_bh) { - BUFFER_TRACE(this_bh, "call ext4_journal_dirty_metadata"); - ext4_journal_dirty_metadata(handle, this_bh); - } -} - -/** - * ext4_free_branches - free an array of branches - * @handle: JBD handle for this transaction - * @inode: inode we are dealing with - * @parent_bh: the buffer_head which contains *@first and *@last - * @first: array of block numbers - * @last: pointer immediately past the end of array - * @depth: depth of the branches to free - * - * We are freeing all blocks refered from these branches (numbers are - * stored as little-endian 32-bit) and updating @inode->i_blocks - * appropriately. - */ -static void ext4_free_branches(handle_t *handle, struct inode *inode, - struct buffer_head *parent_bh, - __le32 *first, __le32 *last, int depth) -{ - ext4_fsblk_t nr; - __le32 *p; - - if (is_handle_aborted(handle)) - return; - - if (depth--) { - struct buffer_head *bh; - int addr_per_block = EXT4_ADDR_PER_BLOCK(inode->i_sb); - p = last; - while (--p >= first) { - nr = le32_to_cpu(*p); - if (!nr) - continue; /* A hole */ - - /* Go read the buffer for the next level down */ - bh = sb_bread(inode->i_sb, nr); - - /* - * A read failure? Report error and clear slot - * (should be rare). - */ - if (!bh) { - ext4_error(inode->i_sb, "ext4_free_branches", - "Read failure, inode=%lu, block=%llu", - inode->i_ino, nr); - continue; - } - - /* This zaps the entire block. Bottom up. */ - BUFFER_TRACE(bh, "free child branches"); - ext4_free_branches(handle, inode, bh, - (__le32*)bh->b_data, - (__le32*)bh->b_data + addr_per_block, - depth); - - /* - * We've probably journalled the indirect block several - * times during the truncate. But it's no longer - * needed and we now drop it from the transaction via - * jbd2_journal_revoke(). - * - * That's easy if it's exclusively part of this - * transaction. But if it's part of the committing - * transaction then jbd2_journal_forget() will simply - * brelse() it. That means that if the underlying - * block is reallocated in ext4_get_block(), - * unmap_underlying_metadata() will find this block - * and will try to get rid of it. damn, damn. - * - * If this block has already been committed to the - * journal, a revoke record will be written. And - * revoke records must be emitted *before* clearing - * this block's bit in the bitmaps. - */ - ext4_forget(handle, 1, inode, bh, bh->b_blocknr); - - /* - * Everything below this this pointer has been - * released. Now let this top-of-subtree go. - * - * We want the freeing of this indirect block to be - * atomic in the journal with the updating of the - * bitmap block which owns it. So make some room in - * the journal. - * - * We zero the parent pointer *after* freeing its - * pointee in the bitmaps, so if extend_transaction() - * for some reason fails to put the bitmap changes and - * the release into the same transaction, recovery - * will merely complain about releasing a free block, - * rather than leaking blocks. - */ - if (is_handle_aborted(handle)) - return; - if (try_to_extend_transaction(handle, inode)) { - ext4_mark_inode_dirty(handle, inode); - ext4_journal_test_restart(handle, inode); - } - - ext4_free_blocks(handle, inode, nr, 1); - - if (parent_bh) { - /* - * The block which we have just freed is - * pointed to by an indirect block: journal it - */ - BUFFER_TRACE(parent_bh, "get_write_access"); - if (!ext4_journal_get_write_access(handle, - parent_bh)){ - *p = 0; - BUFFER_TRACE(parent_bh, - "call ext4_journal_dirty_metadata"); - ext4_journal_dirty_metadata(handle, - parent_bh); - } - } - } - } else { - /* We have reached the bottom of the tree. */ - BUFFER_TRACE(parent_bh, "free data blocks"); - ext4_free_data(handle, inode, parent_bh, first, last); - } -} - -/* - * ext4_truncate() - * - * We block out ext4_get_block() block instantiations across the entire - * transaction, and VFS/VM ensures that ext4_truncate() cannot run - * simultaneously on behalf of the same inode. - * - * As we work through the truncate and commmit bits of it to the journal there - * is one core, guiding principle: the file's tree must always be consistent on - * disk. We must be able to restart the truncate after a crash. - * - * The file's tree may be transiently inconsistent in memory (although it - * probably isn't), but whenever we close off and commit a journal transaction, - * the contents of (the filesystem + the journal) must be consistent and - * restartable. It's pretty simple, really: bottom up, right to left (although - * left-to-right works OK too). - * - * Note that at recovery time, journal replay occurs *before* the restart of - * truncate against the orphan inode list. - * - * The committed inode has the new, desired i_size (which is the same as - * i_disksize in this case). After a crash, ext4_orphan_cleanup() will see - * that this inode's truncate did not complete and it will again call - * ext4_truncate() to have another go. So there will be instantiated blocks - * to the right of the truncation point in a crashed ext4 filesystem. But - * that's fine - as long as they are linked from the inode, the post-crash - * ext4_truncate() run will find them and release them. - */ -void ext4_truncate(struct inode *inode) -{ - handle_t *handle; - struct ext4_inode_info *ei = EXT4_I(inode); - __le32 *i_data = ei->i_data; - int addr_per_block = EXT4_ADDR_PER_BLOCK(inode->i_sb); - struct address_space *mapping = inode->i_mapping; - int offsets[4]; - Indirect chain[4]; - Indirect *partial; - __le32 nr = 0; - int n; - long last_block; - unsigned blocksize = inode->i_sb->s_blocksize; - struct page *page; - - if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || - S_ISLNK(inode->i_mode))) - return; - if (ext4_inode_is_fast_symlink(inode)) - return; - if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) - return; - - /* - * We have to lock the EOF page here, because lock_page() nests - * outside jbd2_journal_start(). - */ - if ((inode->i_size & (blocksize - 1)) == 0) { - /* Block boundary? Nothing to do */ - page = NULL; - } else { - page = grab_cache_page(mapping, - inode->i_size >> PAGE_CACHE_SHIFT); - if (!page) - return; - } - - if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) - return ext4_ext_truncate(inode, page); - - handle = start_transaction(inode); - if (IS_ERR(handle)) { - if (page) { - clear_highpage(page); - flush_dcache_page(page); - unlock_page(page); - page_cache_release(page); - } - return; /* AKPM: return what? */ - } - - last_block = (inode->i_size + blocksize-1) - >> EXT4_BLOCK_SIZE_BITS(inode->i_sb); - - if (page) - ext4_block_truncate_page(handle, page, mapping, inode->i_size); - - n = ext4_block_to_path(inode, last_block, offsets, NULL); - if (n == 0) - goto out_stop; /* error */ - - /* - * OK. This truncate is going to happen. We add the inode to the - * orphan list, so that if this truncate spans multiple transactions, - * and we crash, we will resume the truncate when the filesystem - * recovers. It also marks the inode dirty, to catch the new size. - * - * Implication: the file must always be in a sane, consistent - * truncatable state while each transaction commits. - */ - if (ext4_orphan_add(handle, inode)) - goto out_stop; - - /* - * The orphan list entry will now protect us from any crash which - * occurs before the truncate completes, so it is now safe to propagate - * the new, shorter inode size (held for now in i_size) into the - * on-disk inode. We do this via i_disksize, which is the value which - * ext4 *really* writes onto the disk inode. - */ - ei->i_disksize = inode->i_size; - - /* - * From here we block out all ext4_get_block() callers who want to - * modify the block allocation tree. - */ - mutex_lock(&ei->truncate_mutex); - - if (n == 1) { /* direct blocks */ - ext4_free_data(handle, inode, NULL, i_data+offsets[0], - i_data + EXT4_NDIR_BLOCKS); - goto do_indirects; - } - - partial = ext4_find_shared(inode, n, offsets, chain, &nr); - /* Kill the top of shared branch (not detached) */ - if (nr) { - if (partial == chain) { - /* Shared branch grows from the inode */ - ext4_free_branches(handle, inode, NULL, - &nr, &nr+1, (chain+n-1) - partial); - *partial->p = 0; - /* - * We mark the inode dirty prior to restart, - * and prior to stop. No need for it here. - */ - } else { - /* Shared branch grows from an indirect block */ - BUFFER_TRACE(partial->bh, "get_write_access"); - ext4_free_branches(handle, inode, partial->bh, - partial->p, - partial->p+1, (chain+n-1) - partial); - } - } - /* Clear the ends of indirect blocks on the shared branch */ - while (partial > chain) { - ext4_free_branches(handle, inode, partial->bh, partial->p + 1, - (__le32*)partial->bh->b_data+addr_per_block, - (chain+n-1) - partial); - BUFFER_TRACE(partial->bh, "call brelse"); - brelse (partial->bh); - partial--; - } -do_indirects: - /* Kill the remaining (whole) subtrees */ - switch (offsets[0]) { - default: - nr = i_data[EXT4_IND_BLOCK]; - if (nr) { - ext4_free_branches(handle, inode, NULL, &nr, &nr+1, 1); - i_data[EXT4_IND_BLOCK] = 0; - } - case EXT4_IND_BLOCK: - nr = i_data[EXT4_DIND_BLOCK]; - if (nr) { - ext4_free_branches(handle, inode, NULL, &nr, &nr+1, 2); - i_data[EXT4_DIND_BLOCK] = 0; - } - case EXT4_DIND_BLOCK: - nr = i_data[EXT4_TIND_BLOCK]; - if (nr) { - ext4_free_branches(handle, inode, NULL, &nr, &nr+1, 3); - i_data[EXT4_TIND_BLOCK] = 0; - } - case EXT4_TIND_BLOCK: - ; - } - - ext4_discard_reservation(inode); - - mutex_unlock(&ei->truncate_mutex); - inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC; - ext4_mark_inode_dirty(handle, inode); - - /* - * In a multi-transaction truncate, we only make the final transaction - * synchronous - */ - if (IS_SYNC(inode)) - handle->h_sync = 1; -out_stop: - /* - * If this was a simple ftruncate(), and the file will remain alive - * then we need to clear up the orphan record which we created above. - * However, if this was a real unlink then we were called by - * ext4_delete_inode(), and we allow that function to clean up the - * orphan info for us. - */ - if (inode->i_nlink) - ext4_orphan_del(handle, inode); - - ext4_journal_stop(handle); -} - -static ext4_fsblk_t ext4_get_inode_block(struct super_block *sb, - unsigned long ino, struct ext4_iloc *iloc) -{ - unsigned long desc, group_desc, block_group; - unsigned long offset; - ext4_fsblk_t block; - struct buffer_head *bh; - struct ext4_group_desc * gdp; - - if (!ext4_valid_inum(sb, ino)) { - /* - * This error is already checked for in namei.c unless we are - * looking at an NFS filehandle, in which case no error - * report is needed - */ - return 0; - } - - block_group = (ino - 1) / EXT4_INODES_PER_GROUP(sb); - if (block_group >= EXT4_SB(sb)->s_groups_count) { - ext4_error(sb,"ext4_get_inode_block","group >= groups count"); - return 0; - } - smp_rmb(); - group_desc = block_group >> EXT4_DESC_PER_BLOCK_BITS(sb); - desc = block_group & (EXT4_DESC_PER_BLOCK(sb) - 1); - bh = EXT4_SB(sb)->s_group_desc[group_desc]; - if (!bh) { - ext4_error (sb, "ext4_get_inode_block", - "Descriptor not loaded"); - return 0; - } - - gdp = (struct ext4_group_desc *)((__u8 *)bh->b_data + - desc * EXT4_DESC_SIZE(sb)); - /* - * Figure out the offset within the block group inode table - */ - offset = ((ino - 1) % EXT4_INODES_PER_GROUP(sb)) * - EXT4_INODE_SIZE(sb); - block = ext4_inode_table(sb, gdp) + - (offset >> EXT4_BLOCK_SIZE_BITS(sb)); - - iloc->block_group = block_group; - iloc->offset = offset & (EXT4_BLOCK_SIZE(sb) - 1); - return block; -} - -/* - * ext4_get_inode_loc returns with an extra refcount against the inode's - * underlying buffer_head on success. If 'in_mem' is true, we have all - * data in memory that is needed to recreate the on-disk version of this - * inode. - */ -static int __ext4_get_inode_loc(struct inode *inode, - struct ext4_iloc *iloc, int in_mem) -{ - ext4_fsblk_t block; - struct buffer_head *bh; - - block = ext4_get_inode_block(inode->i_sb, inode->i_ino, iloc); - if (!block) - return -EIO; - - bh = sb_getblk(inode->i_sb, block); - if (!bh) { - ext4_error (inode->i_sb, "ext4_get_inode_loc", - "unable to read inode block - " - "inode=%lu, block=%llu", - inode->i_ino, block); - return -EIO; - } - if (!buffer_uptodate(bh)) { - lock_buffer(bh); - if (buffer_uptodate(bh)) { - /* someone brought it uptodate while we waited */ - unlock_buffer(bh); - goto has_buffer; - } - - /* - * If we have all information of the inode in memory and this - * is the only valid inode in the block, we need not read the - * block. - */ - if (in_mem) { - struct buffer_head *bitmap_bh; - struct ext4_group_desc *desc; - int inodes_per_buffer; - int inode_offset, i; - int block_group; - int start; - - block_group = (inode->i_ino - 1) / - EXT4_INODES_PER_GROUP(inode->i_sb); - inodes_per_buffer = bh->b_size / - EXT4_INODE_SIZE(inode->i_sb); - inode_offset = ((inode->i_ino - 1) % - EXT4_INODES_PER_GROUP(inode->i_sb)); - start = inode_offset & ~(inodes_per_buffer - 1); - - /* Is the inode bitmap in cache? */ - desc = ext4_get_group_desc(inode->i_sb, - block_group, NULL); - if (!desc) - goto make_io; - - bitmap_bh = sb_getblk(inode->i_sb, - ext4_inode_bitmap(inode->i_sb, desc)); - if (!bitmap_bh) - goto make_io; - - /* - * If the inode bitmap isn't in cache then the - * optimisation may end up performing two reads instead - * of one, so skip it. - */ - if (!buffer_uptodate(bitmap_bh)) { - brelse(bitmap_bh); - goto make_io; - } - for (i = start; i < start + inodes_per_buffer; i++) { - if (i == inode_offset) - continue; - if (ext4_test_bit(i, bitmap_bh->b_data)) - break; - } - brelse(bitmap_bh); - if (i == start + inodes_per_buffer) { - /* all other inodes are free, so skip I/O */ - memset(bh->b_data, 0, bh->b_size); - set_buffer_uptodate(bh); - unlock_buffer(bh); - goto has_buffer; - } - } - -make_io: - /* - * There are other valid inodes in the buffer, this inode - * has in-inode xattrs, or we don't have this inode in memory. - * Read the block from disk. - */ - get_bh(bh); - bh->b_end_io = end_buffer_read_sync; - submit_bh(READ_META, bh); - wait_on_buffer(bh); - if (!buffer_uptodate(bh)) { - ext4_error(inode->i_sb, "ext4_get_inode_loc", - "unable to read inode block - " - "inode=%lu, block=%llu", - inode->i_ino, block); - brelse(bh); - return -EIO; - } - } -has_buffer: - iloc->bh = bh; - return 0; -} - -int ext4_get_inode_loc(struct inode *inode, struct ext4_iloc *iloc) -{ - /* We have all inode data except xattrs in memory here. */ - return __ext4_get_inode_loc(inode, iloc, - !(EXT4_I(inode)->i_state & EXT4_STATE_XATTR)); -} - -void ext4_set_inode_flags(struct inode *inode) -{ - unsigned int flags = EXT4_I(inode)->i_flags; - - inode->i_flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC); - if (flags & EXT4_SYNC_FL) - inode->i_flags |= S_SYNC; - if (flags & EXT4_APPEND_FL) - inode->i_flags |= S_APPEND; - if (flags & EXT4_IMMUTABLE_FL) - inode->i_flags |= S_IMMUTABLE; - if (flags & EXT4_NOATIME_FL) - inode->i_flags |= S_NOATIME; - if (flags & EXT4_DIRSYNC_FL) - inode->i_flags |= S_DIRSYNC; -} - -void ext4_read_inode(struct inode * inode) -{ - struct ext4_iloc iloc; - struct ext4_inode *raw_inode; - struct ext4_inode_info *ei = EXT4_I(inode); - struct buffer_head *bh; - int block; - -#ifdef CONFIG_EXT4DEV_FS_POSIX_ACL - ei->i_acl = EXT4_ACL_NOT_CACHED; - ei->i_default_acl = EXT4_ACL_NOT_CACHED; -#endif - ei->i_block_alloc_info = NULL; - - if (__ext4_get_inode_loc(inode, &iloc, 0)) - goto bad_inode; - bh = iloc.bh; - raw_inode = ext4_raw_inode(&iloc); - inode->i_mode = le16_to_cpu(raw_inode->i_mode); - inode->i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low); - inode->i_gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low); - if(!(test_opt (inode->i_sb, NO_UID32))) { - inode->i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16; - inode->i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16; - } - inode->i_nlink = le16_to_cpu(raw_inode->i_links_count); - inode->i_size = le32_to_cpu(raw_inode->i_size); - inode->i_atime.tv_sec = le32_to_cpu(raw_inode->i_atime); - inode->i_ctime.tv_sec = le32_to_cpu(raw_inode->i_ctime); - inode->i_mtime.tv_sec = le32_to_cpu(raw_inode->i_mtime); - inode->i_atime.tv_nsec = inode->i_ctime.tv_nsec = inode->i_mtime.tv_nsec = 0; - - ei->i_state = 0; - ei->i_dir_start_lookup = 0; - ei->i_dtime = le32_to_cpu(raw_inode->i_dtime); - /* We now have enough fields to check if the inode was active or not. - * This is needed because nfsd might try to access dead inodes - * the test is that same one that e2fsck uses - * NeilBrown 1999oct15 - */ - if (inode->i_nlink == 0) { - if (inode->i_mode == 0 || - !(EXT4_SB(inode->i_sb)->s_mount_state & EXT4_ORPHAN_FS)) { - /* this inode is deleted */ - brelse (bh); - goto bad_inode; - } - /* The only unlinked inodes we let through here have - * valid i_mode and are being read by the orphan - * recovery code: that's fine, we're about to complete - * the process of deleting those. */ - } - inode->i_blocks = le32_to_cpu(raw_inode->i_blocks); - ei->i_flags = le32_to_cpu(raw_inode->i_flags); -#ifdef EXT4_FRAGMENTS - ei->i_faddr = le32_to_cpu(raw_inode->i_faddr); - ei->i_frag_no = raw_inode->i_frag; - ei->i_frag_size = raw_inode->i_fsize; -#endif - ei->i_file_acl = le32_to_cpu(raw_inode->i_file_acl); - if (EXT4_SB(inode->i_sb)->s_es->s_creator_os != - cpu_to_le32(EXT4_OS_HURD)) - ei->i_file_acl |= - ((__u64)le16_to_cpu(raw_inode->i_file_acl_high)) << 32; - if (!S_ISREG(inode->i_mode)) { - ei->i_dir_acl = le32_to_cpu(raw_inode->i_dir_acl); - } else { - inode->i_size |= - ((__u64)le32_to_cpu(raw_inode->i_size_high)) << 32; - } - ei->i_disksize = inode->i_size; - inode->i_generation = le32_to_cpu(raw_inode->i_generation); - ei->i_block_group = iloc.block_group; - /* - * NOTE! The in-memory inode i_data array is in little-endian order - * even on big-endian machines: we do NOT byteswap the block numbers! - */ - for (block = 0; block < EXT4_N_BLOCKS; block++) - ei->i_data[block] = raw_inode->i_block[block]; - INIT_LIST_HEAD(&ei->i_orphan); - - if (inode->i_ino >= EXT4_FIRST_INO(inode->i_sb) + 1 && - EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE) { - /* - * When mke2fs creates big inodes it does not zero out - * the unused bytes above EXT4_GOOD_OLD_INODE_SIZE, - * so ignore those first few inodes. - */ - ei->i_extra_isize = le16_to_cpu(raw_inode->i_extra_isize); - if (EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize > - EXT4_INODE_SIZE(inode->i_sb)) - goto bad_inode; - if (ei->i_extra_isize == 0) { - /* The extra space is currently unused. Use it. */ - ei->i_extra_isize = sizeof(struct ext4_inode) - - EXT4_GOOD_OLD_INODE_SIZE; - } else { - __le32 *magic = (void *)raw_inode + - EXT4_GOOD_OLD_INODE_SIZE + - ei->i_extra_isize; - if (*magic == cpu_to_le32(EXT4_XATTR_MAGIC)) - ei->i_state |= EXT4_STATE_XATTR; - } - } else - ei->i_extra_isize = 0; - - if (S_ISREG(inode->i_mode)) { - inode->i_op = &ext4_file_inode_operations; - inode->i_fop = &ext4_file_operations; - ext4_set_aops(inode); - } else if (S_ISDIR(inode->i_mode)) { - inode->i_op = &ext4_dir_inode_operations; - inode->i_fop = &ext4_dir_operations; - } else if (S_ISLNK(inode->i_mode)) { - if (ext4_inode_is_fast_symlink(inode)) - inode->i_op = &ext4_fast_symlink_inode_operations; - else { - inode->i_op = &ext4_symlink_inode_operations; - ext4_set_aops(inode); - } - } else { - inode->i_op = &ext4_special_inode_operations; - if (raw_inode->i_block[0]) - init_special_inode(inode, inode->i_mode, - old_decode_dev(le32_to_cpu(raw_inode->i_block[0]))); - else - init_special_inode(inode, inode->i_mode, - new_decode_dev(le32_to_cpu(raw_inode->i_block[1]))); - } - brelse (iloc.bh); - ext4_set_inode_flags(inode); - return; - -bad_inode: - make_bad_inode(inode); - return; -} - -/* - * Post the struct inode info into an on-disk inode location in the - * buffer-cache. This gobbles the caller's reference to the - * buffer_head in the inode location struct. - * - * The caller must have write access to iloc->bh. - */ -static int ext4_do_update_inode(handle_t *handle, - struct inode *inode, - struct ext4_iloc *iloc) -{ - struct ext4_inode *raw_inode = ext4_raw_inode(iloc); - struct ext4_inode_info *ei = EXT4_I(inode); - struct buffer_head *bh = iloc->bh; - int err = 0, rc, block; - - /* For fields not not tracking in the in-memory inode, - * initialise them to zero for new inodes. */ - if (ei->i_state & EXT4_STATE_NEW) - memset(raw_inode, 0, EXT4_SB(inode->i_sb)->s_inode_size); - - raw_inode->i_mode = cpu_to_le16(inode->i_mode); - if(!(test_opt(inode->i_sb, NO_UID32))) { - raw_inode->i_uid_low = cpu_to_le16(low_16_bits(inode->i_uid)); - raw_inode->i_gid_low = cpu_to_le16(low_16_bits(inode->i_gid)); -/* - * Fix up interoperability with old kernels. Otherwise, old inodes get - * re-used with the upper 16 bits of the uid/gid intact - */ - if(!ei->i_dtime) { - raw_inode->i_uid_high = - cpu_to_le16(high_16_bits(inode->i_uid)); - raw_inode->i_gid_high = - cpu_to_le16(high_16_bits(inode->i_gid)); - } else { - raw_inode->i_uid_high = 0; - raw_inode->i_gid_high = 0; - } - } else { - raw_inode->i_uid_low = - cpu_to_le16(fs_high2lowuid(inode->i_uid)); - raw_inode->i_gid_low = - cpu_to_le16(fs_high2lowgid(inode->i_gid)); - raw_inode->i_uid_high = 0; - raw_inode->i_gid_high = 0; - } - raw_inode->i_links_count = cpu_to_le16(inode->i_nlink); - raw_inode->i_size = cpu_to_le32(ei->i_disksize); - raw_inode->i_atime = cpu_to_le32(inode->i_atime.tv_sec); - raw_inode->i_ctime = cpu_to_le32(inode->i_ctime.tv_sec); - raw_inode->i_mtime = cpu_to_le32(inode->i_mtime.tv_sec); - raw_inode->i_blocks = cpu_to_le32(inode->i_blocks); - raw_inode->i_dtime = cpu_to_le32(ei->i_dtime); - raw_inode->i_flags = cpu_to_le32(ei->i_flags); -#ifdef EXT4_FRAGMENTS - raw_inode->i_faddr = cpu_to_le32(ei->i_faddr); - raw_inode->i_frag = ei->i_frag_no; - raw_inode->i_fsize = ei->i_frag_size; -#endif - if (EXT4_SB(inode->i_sb)->s_es->s_creator_os != - cpu_to_le32(EXT4_OS_HURD)) - raw_inode->i_file_acl_high = - cpu_to_le16(ei->i_file_acl >> 32); - raw_inode->i_file_acl = cpu_to_le32(ei->i_file_acl); - if (!S_ISREG(inode->i_mode)) { - raw_inode->i_dir_acl = cpu_to_le32(ei->i_dir_acl); - } else { - raw_inode->i_size_high = - cpu_to_le32(ei->i_disksize >> 32); - if (ei->i_disksize > 0x7fffffffULL) { - struct super_block *sb = inode->i_sb; - if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, - EXT4_FEATURE_RO_COMPAT_LARGE_FILE) || - EXT4_SB(sb)->s_es->s_rev_level == - cpu_to_le32(EXT4_GOOD_OLD_REV)) { - /* If this is the first large file - * created, add a flag to the superblock. - */ - err = ext4_journal_get_write_access(handle, - EXT4_SB(sb)->s_sbh); - if (err) - goto out_brelse; - ext4_update_dynamic_rev(sb); - EXT4_SET_RO_COMPAT_FEATURE(sb, - EXT4_FEATURE_RO_COMPAT_LARGE_FILE); - sb->s_dirt = 1; - handle->h_sync = 1; - err = ext4_journal_dirty_metadata(handle, - EXT4_SB(sb)->s_sbh); - } - } - } - raw_inode->i_generation = cpu_to_le32(inode->i_generation); - if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) { - if (old_valid_dev(inode->i_rdev)) { - raw_inode->i_block[0] = - cpu_to_le32(old_encode_dev(inode->i_rdev)); - raw_inode->i_block[1] = 0; - } else { - raw_inode->i_block[0] = 0; - raw_inode->i_block[1] = - cpu_to_le32(new_encode_dev(inode->i_rdev)); - raw_inode->i_block[2] = 0; - } - } else for (block = 0; block < EXT4_N_BLOCKS; block++) - raw_inode->i_block[block] = ei->i_data[block]; - - if (ei->i_extra_isize) - raw_inode->i_extra_isize = cpu_to_le16(ei->i_extra_isize); - - BUFFER_TRACE(bh, "call ext4_journal_dirty_metadata"); - rc = ext4_journal_dirty_metadata(handle, bh); - if (!err) - err = rc; - ei->i_state &= ~EXT4_STATE_NEW; - -out_brelse: - brelse (bh); - ext4_std_error(inode->i_sb, err); - return err; -} - -/* - * ext4_write_inode() - * - * We are called from a few places: - * - * - Within generic_file_write() for O_SYNC files. - * Here, there will be no transaction running. We wait for any running - * trasnaction to commit. - * - * - Within sys_sync(), kupdate and such. - * We wait on commit, if tol to. - * - * - Within prune_icache() (PF_MEMALLOC == true) - * Here we simply return. We can't afford to block kswapd on the - * journal commit. - * - * In all cases it is actually safe for us to return without doing anything, - * because the inode has been copied into a raw inode buffer in - * ext4_mark_inode_dirty(). This is a correctness thing for O_SYNC and for - * knfsd. - * - * Note that we are absolutely dependent upon all inode dirtiers doing the - * right thing: they *must* call mark_inode_dirty() after dirtying info in - * which we are interested. - * - * It would be a bug for them to not do this. The code: - * - * mark_inode_dirty(inode) - * stuff(); - * inode->i_size = expr; - * - * is in error because a kswapd-driven write_inode() could occur while - * `stuff()' is running, and the new i_size will be lost. Plus the inode - * will no longer be on the superblock's dirty inode list. - */ -int ext4_write_inode(struct inode *inode, int wait) -{ - if (current->flags & PF_MEMALLOC) - return 0; - - if (ext4_journal_current_handle()) { - jbd_debug(0, "called recursively, non-PF_MEMALLOC!\n"); - dump_stack(); - return -EIO; - } - - if (!wait) - return 0; - - return ext4_force_commit(inode->i_sb); -} - -/* - * ext4_setattr() - * - * Called from notify_change. - * - * We want to trap VFS attempts to truncate the file as soon as - * possible. In particular, we want to make sure that when the VFS - * shrinks i_size, we put the inode on the orphan list and modify - * i_disksize immediately, so that during the subsequent flushing of - * dirty pages and freeing of disk blocks, we can guarantee that any - * commit will leave the blocks being flushed in an unused state on - * disk. (On recovery, the inode will get truncated and the blocks will - * be freed, so we have a strong guarantee that no future commit will - * leave these blocks visible to the user.) - * - * Called with inode->sem down. - */ -int ext4_setattr(struct dentry *dentry, struct iattr *attr) -{ - struct inode *inode = dentry->d_inode; - int error, rc = 0; - const unsigned int ia_valid = attr->ia_valid; - - error = inode_change_ok(inode, attr); - if (error) - return error; - - if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) || - (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) { - handle_t *handle; - - /* (user+group)*(old+new) structure, inode write (sb, - * inode block, ? - but truncate inode update has it) */ - handle = ext4_journal_start(inode, 2*(EXT4_QUOTA_INIT_BLOCKS(inode->i_sb)+ - EXT4_QUOTA_DEL_BLOCKS(inode->i_sb))+3); - if (IS_ERR(handle)) { - error = PTR_ERR(handle); - goto err_out; - } - error = DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0; - if (error) { - ext4_journal_stop(handle); - return error; - } - /* Update corresponding info in inode so that everything is in - * one transaction */ - if (attr->ia_valid & ATTR_UID) - inode->i_uid = attr->ia_uid; - if (attr->ia_valid & ATTR_GID) - inode->i_gid = attr->ia_gid; - error = ext4_mark_inode_dirty(handle, inode); - ext4_journal_stop(handle); - } - - if (S_ISREG(inode->i_mode) && - attr->ia_valid & ATTR_SIZE && attr->ia_size < inode->i_size) { - handle_t *handle; - - handle = ext4_journal_start(inode, 3); - if (IS_ERR(handle)) { - error = PTR_ERR(handle); - goto err_out; - } - - error = ext4_orphan_add(handle, inode); - EXT4_I(inode)->i_disksize = attr->ia_size; - rc = ext4_mark_inode_dirty(handle, inode); - if (!error) - error = rc; - ext4_journal_stop(handle); - } - - rc = inode_setattr(inode, attr); - - /* If inode_setattr's call to ext4_truncate failed to get a - * transaction handle at all, we need to clean up the in-core - * orphan list manually. */ - if (inode->i_nlink) - ext4_orphan_del(NULL, inode); - - if (!rc && (ia_valid & ATTR_MODE)) - rc = ext4_acl_chmod(inode); - -err_out: - ext4_std_error(inode->i_sb, error); - if (!error) - error = rc; - return error; -} - - -/* - * How many blocks doth make a writepage()? - * - * With N blocks per page, it may be: - * N data blocks - * 2 indirect block - * 2 dindirect - * 1 tindirect - * N+5 bitmap blocks (from the above) - * N+5 group descriptor summary blocks - * 1 inode block - * 1 superblock. - * 2 * EXT4_SINGLEDATA_TRANS_BLOCKS for the quote files - * - * 3 * (N + 5) + 2 + 2 * EXT4_SINGLEDATA_TRANS_BLOCKS - * - * With ordered or writeback data it's the same, less the N data blocks. - * - * If the inode's direct blocks can hold an integral number of pages then a - * page cannot straddle two indirect blocks, and we can only touch one indirect - * and dindirect block, and the "5" above becomes "3". - * - * This still overestimates under most circumstances. If we were to pass the - * start and end offsets in here as well we could do block_to_path() on each - * block and work out the exact number of indirects which are touched. Pah. - */ - -int ext4_writepage_trans_blocks(struct inode *inode) -{ - int bpp = ext4_journal_blocks_per_page(inode); - int indirects = (EXT4_NDIR_BLOCKS % bpp) ? 5 : 3; - int ret; - - if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) - return ext4_ext_writepage_trans_blocks(inode, bpp); - - if (ext4_should_journal_data(inode)) - ret = 3 * (bpp + indirects) + 2; - else - ret = 2 * (bpp + indirects) + 2; - -#ifdef CONFIG_QUOTA - /* We know that structure was already allocated during DQUOT_INIT so - * we will be updating only the data blocks + inodes */ - ret += 2*EXT4_QUOTA_TRANS_BLOCKS(inode->i_sb); -#endif - - return ret; -} - -/* - * The caller must have previously called ext4_reserve_inode_write(). - * Give this, we know that the caller already has write access to iloc->bh. - */ -int ext4_mark_iloc_dirty(handle_t *handle, - struct inode *inode, struct ext4_iloc *iloc) -{ - int err = 0; - - /* the do_update_inode consumes one bh->b_count */ - get_bh(iloc->bh); - - /* ext4_do_update_inode() does jbd2_journal_dirty_metadata */ - err = ext4_do_update_inode(handle, inode, iloc); - put_bh(iloc->bh); - return err; -} - -/* - * On success, We end up with an outstanding reference count against - * iloc->bh. This _must_ be cleaned up later. - */ - -int -ext4_reserve_inode_write(handle_t *handle, struct inode *inode, - struct ext4_iloc *iloc) -{ - int err = 0; - if (handle) { - err = ext4_get_inode_loc(inode, iloc); - if (!err) { - BUFFER_TRACE(iloc->bh, "get_write_access"); - err = ext4_journal_get_write_access(handle, iloc->bh); - if (err) { - brelse(iloc->bh); - iloc->bh = NULL; - } - } - } - ext4_std_error(inode->i_sb, err); - return err; -} - -/* - * What we do here is to mark the in-core inode as clean with respect to inode - * dirtiness (it may still be data-dirty). - * This means that the in-core inode may be reaped by prune_icache - * without having to perform any I/O. This is a very good thing, - * because *any* task may call prune_icache - even ones which - * have a transaction open against a different journal. - * - * Is this cheating? Not really. Sure, we haven't written the - * inode out, but prune_icache isn't a user-visible syncing function. - * Whenever the user wants stuff synced (sys_sync, sys_msync, sys_fsync) - * we start and wait on commits. - * - * Is this efficient/effective? Well, we're being nice to the system - * by cleaning up our inodes proactively so they can be reaped - * without I/O. But we are potentially leaving up to five seconds' - * worth of inodes floating about which prune_icache wants us to - * write out. One way to fix that would be to get prune_icache() - * to do a write_super() to free up some memory. It has the desired - * effect. - */ -int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode) -{ - struct ext4_iloc iloc; - int err; - - might_sleep(); - err = ext4_reserve_inode_write(handle, inode, &iloc); - if (!err) - err = ext4_mark_iloc_dirty(handle, inode, &iloc); - return err; -} - -/* - * ext4_dirty_inode() is called from __mark_inode_dirty() - * - * We're really interested in the case where a file is being extended. - * i_size has been changed by generic_commit_write() and we thus need - * to include the updated inode in the current transaction. - * - * Also, DQUOT_ALLOC_SPACE() will always dirty the inode when blocks - * are allocated to the file. - * - * If the inode is marked synchronous, we don't honour that here - doing - * so would cause a commit on atime updates, which we don't bother doing. - * We handle synchronous inodes at the highest possible level. - */ -void ext4_dirty_inode(struct inode *inode) -{ - handle_t *current_handle = ext4_journal_current_handle(); - handle_t *handle; - - handle = ext4_journal_start(inode, 2); - if (IS_ERR(handle)) - goto out; - if (current_handle && - current_handle->h_transaction != handle->h_transaction) { - /* This task has a transaction open against a different fs */ - printk(KERN_EMERG "%s: transactions do not match!\n", - __FUNCTION__); - } else { - jbd_debug(5, "marking dirty. outer handle=%p\n", - current_handle); - ext4_mark_inode_dirty(handle, inode); - } - ext4_journal_stop(handle); -out: - return; -} - -#if 0 -/* - * Bind an inode's backing buffer_head into this transaction, to prevent - * it from being flushed to disk early. Unlike - * ext4_reserve_inode_write, this leaves behind no bh reference and - * returns no iloc structure, so the caller needs to repeat the iloc - * lookup to mark the inode dirty later. - */ -static int ext4_pin_inode(handle_t *handle, struct inode *inode) -{ - struct ext4_iloc iloc; - - int err = 0; - if (handle) { - err = ext4_get_inode_loc(inode, &iloc); - if (!err) { - BUFFER_TRACE(iloc.bh, "get_write_access"); - err = jbd2_journal_get_write_access(handle, iloc.bh); - if (!err) - err = ext4_journal_dirty_metadata(handle, - iloc.bh); - brelse(iloc.bh); - } - } - ext4_std_error(inode->i_sb, err); - return err; -} -#endif - -int ext4_change_inode_journal_flag(struct inode *inode, int val) -{ - journal_t *journal; - handle_t *handle; - int err; - - /* - * We have to be very careful here: changing a data block's - * journaling status dynamically is dangerous. If we write a - * data block to the journal, change the status and then delete - * that block, we risk forgetting to revoke the old log record - * from the journal and so a subsequent replay can corrupt data. - * So, first we make sure that the journal is empty and that - * nobody is changing anything. - */ - - journal = EXT4_JOURNAL(inode); - if (is_journal_aborted(journal) || IS_RDONLY(inode)) - return -EROFS; - - jbd2_journal_lock_updates(journal); - jbd2_journal_flush(journal); - - /* - * OK, there are no updates running now, and all cached data is - * synced to disk. We are now in a completely consistent state - * which doesn't have anything in the journal, and we know that - * no filesystem updates are running, so it is safe to modify - * the inode's in-core data-journaling state flag now. - */ - - if (val) - EXT4_I(inode)->i_flags |= EXT4_JOURNAL_DATA_FL; - else - EXT4_I(inode)->i_flags &= ~EXT4_JOURNAL_DATA_FL; - ext4_set_aops(inode); - - jbd2_journal_unlock_updates(journal); - - /* Finally we can mark the inode as dirty. */ - - handle = ext4_journal_start(inode, 1); - if (IS_ERR(handle)) - return PTR_ERR(handle); - - err = ext4_mark_inode_dirty(handle, inode); - handle->h_sync = 1; - ext4_journal_stop(handle); - ext4_std_error(inode->i_sb, err); - - return err; -} diff --git a/trunk/fs/ext4/ioctl.c b/trunk/fs/ext4/ioctl.c deleted file mode 100644 index 22a737c306c7..000000000000 --- a/trunk/fs/ext4/ioctl.c +++ /dev/null @@ -1,306 +0,0 @@ -/* - * linux/fs/ext4/ioctl.c - * - * Copyright (C) 1993, 1994, 1995 - * Remy Card (card@masi.ibp.fr) - * Laboratoire MASI - Institut Blaise Pascal - * Universite Pierre et Marie Curie (Paris VI) - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -int ext4_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, - unsigned long arg) -{ - struct ext4_inode_info *ei = EXT4_I(inode); - unsigned int flags; - unsigned short rsv_window_size; - - ext4_debug ("cmd = %u, arg = %lu\n", cmd, arg); - - switch (cmd) { - case EXT4_IOC_GETFLAGS: - flags = ei->i_flags & EXT4_FL_USER_VISIBLE; - return put_user(flags, (int __user *) arg); - case EXT4_IOC_SETFLAGS: { - handle_t *handle = NULL; - int err; - struct ext4_iloc iloc; - unsigned int oldflags; - unsigned int jflag; - - if (IS_RDONLY(inode)) - return -EROFS; - - if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER)) - return -EACCES; - - if (get_user(flags, (int __user *) arg)) - return -EFAULT; - - if (!S_ISDIR(inode->i_mode)) - flags &= ~EXT4_DIRSYNC_FL; - - mutex_lock(&inode->i_mutex); - oldflags = ei->i_flags; - - /* The JOURNAL_DATA flag is modifiable only by root */ - jflag = flags & EXT4_JOURNAL_DATA_FL; - - /* - * The IMMUTABLE and APPEND_ONLY flags can only be changed by - * the relevant capability. - * - * This test looks nicer. Thanks to Pauline Middelink - */ - if ((flags ^ oldflags) & (EXT4_APPEND_FL | EXT4_IMMUTABLE_FL)) { - if (!capable(CAP_LINUX_IMMUTABLE)) { - mutex_unlock(&inode->i_mutex); - return -EPERM; - } - } - - /* - * The JOURNAL_DATA flag can only be changed by - * the relevant capability. - */ - if ((jflag ^ oldflags) & (EXT4_JOURNAL_DATA_FL)) { - if (!capable(CAP_SYS_RESOURCE)) { - mutex_unlock(&inode->i_mutex); - return -EPERM; - } - } - - - handle = ext4_journal_start(inode, 1); - if (IS_ERR(handle)) { - mutex_unlock(&inode->i_mutex); - return PTR_ERR(handle); - } - if (IS_SYNC(inode)) - handle->h_sync = 1; - err = ext4_reserve_inode_write(handle, inode, &iloc); - if (err) - goto flags_err; - - flags = flags & EXT4_FL_USER_MODIFIABLE; - flags |= oldflags & ~EXT4_FL_USER_MODIFIABLE; - ei->i_flags = flags; - - ext4_set_inode_flags(inode); - inode->i_ctime = CURRENT_TIME_SEC; - - err = ext4_mark_iloc_dirty(handle, inode, &iloc); -flags_err: - ext4_journal_stop(handle); - if (err) { - mutex_unlock(&inode->i_mutex); - return err; - } - - if ((jflag ^ oldflags) & (EXT4_JOURNAL_DATA_FL)) - err = ext4_change_inode_journal_flag(inode, jflag); - mutex_unlock(&inode->i_mutex); - return err; - } - case EXT4_IOC_GETVERSION: - case EXT4_IOC_GETVERSION_OLD: - return put_user(inode->i_generation, (int __user *) arg); - case EXT4_IOC_SETVERSION: - case EXT4_IOC_SETVERSION_OLD: { - handle_t *handle; - struct ext4_iloc iloc; - __u32 generation; - int err; - - if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER)) - return -EPERM; - if (IS_RDONLY(inode)) - return -EROFS; - if (get_user(generation, (int __user *) arg)) - return -EFAULT; - - handle = ext4_journal_start(inode, 1); - if (IS_ERR(handle)) - return PTR_ERR(handle); - err = ext4_reserve_inode_write(handle, inode, &iloc); - if (err == 0) { - inode->i_ctime = CURRENT_TIME_SEC; - inode->i_generation = generation; - err = ext4_mark_iloc_dirty(handle, inode, &iloc); - } - ext4_journal_stop(handle); - return err; - } -#ifdef CONFIG_JBD_DEBUG - case EXT4_IOC_WAIT_FOR_READONLY: - /* - * This is racy - by the time we're woken up and running, - * the superblock could be released. And the module could - * have been unloaded. So sue me. - * - * Returns 1 if it slept, else zero. - */ - { - struct super_block *sb = inode->i_sb; - DECLARE_WAITQUEUE(wait, current); - int ret = 0; - - set_current_state(TASK_INTERRUPTIBLE); - add_wait_queue(&EXT4_SB(sb)->ro_wait_queue, &wait); - if (timer_pending(&EXT4_SB(sb)->turn_ro_timer)) { - schedule(); - ret = 1; - } - remove_wait_queue(&EXT4_SB(sb)->ro_wait_queue, &wait); - return ret; - } -#endif - case EXT4_IOC_GETRSVSZ: - if (test_opt(inode->i_sb, RESERVATION) - && S_ISREG(inode->i_mode) - && ei->i_block_alloc_info) { - rsv_window_size = ei->i_block_alloc_info->rsv_window_node.rsv_goal_size; - return put_user(rsv_window_size, (int __user *)arg); - } - return -ENOTTY; - case EXT4_IOC_SETRSVSZ: { - - if (!test_opt(inode->i_sb, RESERVATION) ||!S_ISREG(inode->i_mode)) - return -ENOTTY; - - if (IS_RDONLY(inode)) - return -EROFS; - - if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER)) - return -EACCES; - - if (get_user(rsv_window_size, (int __user *)arg)) - return -EFAULT; - - if (rsv_window_size > EXT4_MAX_RESERVE_BLOCKS) - rsv_window_size = EXT4_MAX_RESERVE_BLOCKS; - - /* - * need to allocate reservation structure for this inode - * before set the window size - */ - mutex_lock(&ei->truncate_mutex); - if (!ei->i_block_alloc_info) - ext4_init_block_alloc_info(inode); - - if (ei->i_block_alloc_info){ - struct ext4_reserve_window_node *rsv = &ei->i_block_alloc_info->rsv_window_node; - rsv->rsv_goal_size = rsv_window_size; - } - mutex_unlock(&ei->truncate_mutex); - return 0; - } - case EXT4_IOC_GROUP_EXTEND: { - ext4_fsblk_t n_blocks_count; - struct super_block *sb = inode->i_sb; - int err; - - if (!capable(CAP_SYS_RESOURCE)) - return -EPERM; - - if (IS_RDONLY(inode)) - return -EROFS; - - if (get_user(n_blocks_count, (__u32 __user *)arg)) - return -EFAULT; - - err = ext4_group_extend(sb, EXT4_SB(sb)->s_es, n_blocks_count); - jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal); - jbd2_journal_flush(EXT4_SB(sb)->s_journal); - jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); - - return err; - } - case EXT4_IOC_GROUP_ADD: { - struct ext4_new_group_data input; - struct super_block *sb = inode->i_sb; - int err; - - if (!capable(CAP_SYS_RESOURCE)) - return -EPERM; - - if (IS_RDONLY(inode)) - return -EROFS; - - if (copy_from_user(&input, (struct ext4_new_group_input __user *)arg, - sizeof(input))) - return -EFAULT; - - err = ext4_group_add(sb, &input); - jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal); - jbd2_journal_flush(EXT4_SB(sb)->s_journal); - jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); - - return err; - } - - default: - return -ENOTTY; - } -} - -#ifdef CONFIG_COMPAT -long ext4_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct inode *inode = file->f_dentry->d_inode; - int ret; - - /* These are just misnamed, they actually get/put from/to user an int */ - switch (cmd) { - case EXT4_IOC32_GETFLAGS: - cmd = EXT4_IOC_GETFLAGS; - break; - case EXT4_IOC32_SETFLAGS: - cmd = EXT4_IOC_SETFLAGS; - break; - case EXT4_IOC32_GETVERSION: - cmd = EXT4_IOC_GETVERSION; - break; - case EXT4_IOC32_SETVERSION: - cmd = EXT4_IOC_SETVERSION; - break; - case EXT4_IOC32_GROUP_EXTEND: - cmd = EXT4_IOC_GROUP_EXTEND; - break; - case EXT4_IOC32_GETVERSION_OLD: - cmd = EXT4_IOC_GETVERSION_OLD; - break; - case EXT4_IOC32_SETVERSION_OLD: - cmd = EXT4_IOC_SETVERSION_OLD; - break; -#ifdef CONFIG_JBD_DEBUG - case EXT4_IOC32_WAIT_FOR_READONLY: - cmd = EXT4_IOC_WAIT_FOR_READONLY; - break; -#endif - case EXT4_IOC32_GETRSVSZ: - cmd = EXT4_IOC_GETRSVSZ; - break; - case EXT4_IOC32_SETRSVSZ: - cmd = EXT4_IOC_SETRSVSZ; - break; - case EXT4_IOC_GROUP_ADD: - break; - default: - return -ENOIOCTLCMD; - } - lock_kernel(); - ret = ext4_ioctl(inode, file, cmd, (unsigned long) compat_ptr(arg)); - unlock_kernel(); - return ret; -} -#endif diff --git a/trunk/fs/ext4/namei.c b/trunk/fs/ext4/namei.c deleted file mode 100644 index 8b1bd03d20f5..000000000000 --- a/trunk/fs/ext4/namei.c +++ /dev/null @@ -1,2395 +0,0 @@ -/* - * linux/fs/ext4/namei.c - * - * Copyright (C) 1992, 1993, 1994, 1995 - * Remy Card (card@masi.ibp.fr) - * Laboratoire MASI - Institut Blaise Pascal - * Universite Pierre et Marie Curie (Paris VI) - * - * from - * - * linux/fs/minix/namei.c - * - * Copyright (C) 1991, 1992 Linus Torvalds - * - * Big-endian to little-endian byte-swapping/bitmaps by - * David S. Miller (davem@caip.rutgers.edu), 1995 - * Directory entry file type support and forward compatibility hooks - * for B-tree directories by Theodore Ts'o (tytso@mit.edu), 1998 - * Hash Tree Directory indexing (c) - * Daniel Phillips, 2001 - * Hash Tree Directory indexing porting - * Christopher Li, 2002 - * Hash Tree Directory indexing cleanup - * Theodore Ts'o, 2002 - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "namei.h" -#include "xattr.h" -#include "acl.h" - -/* - * define how far ahead to read directories while searching them. - */ -#define NAMEI_RA_CHUNKS 2 -#define NAMEI_RA_BLOCKS 4 -#define NAMEI_RA_SIZE (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS) -#define NAMEI_RA_INDEX(c,b) (((c) * NAMEI_RA_BLOCKS) + (b)) - -static struct buffer_head *ext4_append(handle_t *handle, - struct inode *inode, - u32 *block, int *err) -{ - struct buffer_head *bh; - - *block = inode->i_size >> inode->i_sb->s_blocksize_bits; - - if ((bh = ext4_bread(handle, inode, *block, 1, err))) { - inode->i_size += inode->i_sb->s_blocksize; - EXT4_I(inode)->i_disksize = inode->i_size; - ext4_journal_get_write_access(handle,bh); - } - return bh; -} - -#ifndef assert -#define assert(test) J_ASSERT(test) -#endif - -#ifndef swap -#define swap(x, y) do { typeof(x) z = x; x = y; y = z; } while (0) -#endif - -#ifdef DX_DEBUG -#define dxtrace(command) command -#else -#define dxtrace(command) -#endif - -struct fake_dirent -{ - __le32 inode; - __le16 rec_len; - u8 name_len; - u8 file_type; -}; - -struct dx_countlimit -{ - __le16 limit; - __le16 count; -}; - -struct dx_entry -{ - __le32 hash; - __le32 block; -}; - -/* - * dx_root_info is laid out so that if it should somehow get overlaid by a - * dirent the two low bits of the hash version will be zero. Therefore, the - * hash version mod 4 should never be 0. Sincerely, the paranoia department. - */ - -struct dx_root -{ - struct fake_dirent dot; - char dot_name[4]; - struct fake_dirent dotdot; - char dotdot_name[4]; - struct dx_root_info - { - __le32 reserved_zero; - u8 hash_version; - u8 info_length; /* 8 */ - u8 indirect_levels; - u8 unused_flags; - } - info; - struct dx_entry entries[0]; -}; - -struct dx_node -{ - struct fake_dirent fake; - struct dx_entry entries[0]; -}; - - -struct dx_frame -{ - struct buffer_head *bh; - struct dx_entry *entries; - struct dx_entry *at; -}; - -struct dx_map_entry -{ - u32 hash; - u32 offs; -}; - -#ifdef CONFIG_EXT4_INDEX -static inline unsigned dx_get_block (struct dx_entry *entry); -static void dx_set_block (struct dx_entry *entry, unsigned value); -static inline unsigned dx_get_hash (struct dx_entry *entry); -static void dx_set_hash (struct dx_entry *entry, unsigned value); -static unsigned dx_get_count (struct dx_entry *entries); -static unsigned dx_get_limit (struct dx_entry *entries); -static void dx_set_count (struct dx_entry *entries, unsigned value); -static void dx_set_limit (struct dx_entry *entries, unsigned value); -static unsigned dx_root_limit (struct inode *dir, unsigned infosize); -static unsigned dx_node_limit (struct inode *dir); -static struct dx_frame *dx_probe(struct dentry *dentry, - struct inode *dir, - struct dx_hash_info *hinfo, - struct dx_frame *frame, - int *err); -static void dx_release (struct dx_frame *frames); -static int dx_make_map (struct ext4_dir_entry_2 *de, int size, - struct dx_hash_info *hinfo, struct dx_map_entry map[]); -static void dx_sort_map(struct dx_map_entry *map, unsigned count); -static struct ext4_dir_entry_2 *dx_move_dirents (char *from, char *to, - struct dx_map_entry *offsets, int count); -static struct ext4_dir_entry_2* dx_pack_dirents (char *base, int size); -static void dx_insert_block (struct dx_frame *frame, u32 hash, u32 block); -static int ext4_htree_next_block(struct inode *dir, __u32 hash, - struct dx_frame *frame, - struct dx_frame *frames, - __u32 *start_hash); -static struct buffer_head * ext4_dx_find_entry(struct dentry *dentry, - struct ext4_dir_entry_2 **res_dir, int *err); -static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry, - struct inode *inode); - -/* - * Future: use high four bits of block for coalesce-on-delete flags - * Mask them off for now. - */ - -static inline unsigned dx_get_block (struct dx_entry *entry) -{ - return le32_to_cpu(entry->block) & 0x00ffffff; -} - -static inline void dx_set_block (struct dx_entry *entry, unsigned value) -{ - entry->block = cpu_to_le32(value); -} - -static inline unsigned dx_get_hash (struct dx_entry *entry) -{ - return le32_to_cpu(entry->hash); -} - -static inline void dx_set_hash (struct dx_entry *entry, unsigned value) -{ - entry->hash = cpu_to_le32(value); -} - -static inline unsigned dx_get_count (struct dx_entry *entries) -{ - return le16_to_cpu(((struct dx_countlimit *) entries)->count); -} - -static inline unsigned dx_get_limit (struct dx_entry *entries) -{ - return le16_to_cpu(((struct dx_countlimit *) entries)->limit); -} - -static inline void dx_set_count (struct dx_entry *entries, unsigned value) -{ - ((struct dx_countlimit *) entries)->count = cpu_to_le16(value); -} - -static inline void dx_set_limit (struct dx_entry *entries, unsigned value) -{ - ((struct dx_countlimit *) entries)->limit = cpu_to_le16(value); -} - -static inline unsigned dx_root_limit (struct inode *dir, unsigned infosize) -{ - unsigned entry_space = dir->i_sb->s_blocksize - EXT4_DIR_REC_LEN(1) - - EXT4_DIR_REC_LEN(2) - infosize; - return 0? 20: entry_space / sizeof(struct dx_entry); -} - -static inline unsigned dx_node_limit (struct inode *dir) -{ - unsigned entry_space = dir->i_sb->s_blocksize - EXT4_DIR_REC_LEN(0); - return 0? 22: entry_space / sizeof(struct dx_entry); -} - -/* - * Debug - */ -#ifdef DX_DEBUG -static void dx_show_index (char * label, struct dx_entry *entries) -{ - int i, n = dx_get_count (entries); - printk("%s index ", label); - for (i = 0; i < n; i++) { - printk("%x->%u ", i? dx_get_hash(entries + i) : - 0, dx_get_block(entries + i)); - } - printk("\n"); -} - -struct stats -{ - unsigned names; - unsigned space; - unsigned bcount; -}; - -static struct stats dx_show_leaf(struct dx_hash_info *hinfo, struct ext4_dir_entry_2 *de, - int size, int show_names) -{ - unsigned names = 0, space = 0; - char *base = (char *) de; - struct dx_hash_info h = *hinfo; - - printk("names: "); - while ((char *) de < base + size) - { - if (de->inode) - { - if (show_names) - { - int len = de->name_len; - char *name = de->name; - while (len--) printk("%c", *name++); - ext4fs_dirhash(de->name, de->name_len, &h); - printk(":%x.%u ", h.hash, - ((char *) de - base)); - } - space += EXT4_DIR_REC_LEN(de->name_len); - names++; - } - de = (struct ext4_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len)); - } - printk("(%i)\n", names); - return (struct stats) { names, space, 1 }; -} - -struct stats dx_show_entries(struct dx_hash_info *hinfo, struct inode *dir, - struct dx_entry *entries, int levels) -{ - unsigned blocksize = dir->i_sb->s_blocksize; - unsigned count = dx_get_count (entries), names = 0, space = 0, i; - unsigned bcount = 0; - struct buffer_head *bh; - int err; - printk("%i indexed blocks...\n", count); - for (i = 0; i < count; i++, entries++) - { - u32 block = dx_get_block(entries), hash = i? dx_get_hash(entries): 0; - u32 range = i < count - 1? (dx_get_hash(entries + 1) - hash): ~hash; - struct stats stats; - printk("%s%3u:%03u hash %8x/%8x ",levels?"":" ", i, block, hash, range); - if (!(bh = ext4_bread (NULL,dir, block, 0,&err))) continue; - stats = levels? - dx_show_entries(hinfo, dir, ((struct dx_node *) bh->b_data)->entries, levels - 1): - dx_show_leaf(hinfo, (struct ext4_dir_entry_2 *) bh->b_data, blocksize, 0); - names += stats.names; - space += stats.space; - bcount += stats.bcount; - brelse (bh); - } - if (bcount) - printk("%snames %u, fullness %u (%u%%)\n", levels?"":" ", - names, space/bcount,(space/bcount)*100/blocksize); - return (struct stats) { names, space, bcount}; -} -#endif /* DX_DEBUG */ - -/* - * Probe for a directory leaf block to search. - * - * dx_probe can return ERR_BAD_DX_DIR, which means there was a format - * error in the directory index, and the caller should fall back to - * searching the directory normally. The callers of dx_probe **MUST** - * check for this error code, and make sure it never gets reflected - * back to userspace. - */ -static struct dx_frame * -dx_probe(struct dentry *dentry, struct inode *dir, - struct dx_hash_info *hinfo, struct dx_frame *frame_in, int *err) -{ - unsigned count, indirect; - struct dx_entry *at, *entries, *p, *q, *m; - struct dx_root *root; - struct buffer_head *bh; - struct dx_frame *frame = frame_in; - u32 hash; - - frame->bh = NULL; - if (dentry) - dir = dentry->d_parent->d_inode; - if (!(bh = ext4_bread (NULL,dir, 0, 0, err))) - goto fail; - root = (struct dx_root *) bh->b_data; - if (root->info.hash_version != DX_HASH_TEA && - root->info.hash_version != DX_HASH_HALF_MD4 && - root->info.hash_version != DX_HASH_LEGACY) { - ext4_warning(dir->i_sb, __FUNCTION__, - "Unrecognised inode hash code %d", - root->info.hash_version); - brelse(bh); - *err = ERR_BAD_DX_DIR; - goto fail; - } - hinfo->hash_version = root->info.hash_version; - hinfo->seed = EXT4_SB(dir->i_sb)->s_hash_seed; - if (dentry) - ext4fs_dirhash(dentry->d_name.name, dentry->d_name.len, hinfo); - hash = hinfo->hash; - - if (root->info.unused_flags & 1) { - ext4_warning(dir->i_sb, __FUNCTION__, - "Unimplemented inode hash flags: %#06x", - root->info.unused_flags); - brelse(bh); - *err = ERR_BAD_DX_DIR; - goto fail; - } - - if ((indirect = root->info.indirect_levels) > 1) { - ext4_warning(dir->i_sb, __FUNCTION__, - "Unimplemented inode hash depth: %#06x", - root->info.indirect_levels); - brelse(bh); - *err = ERR_BAD_DX_DIR; - goto fail; - } - - entries = (struct dx_entry *) (((char *)&root->info) + - root->info.info_length); - assert(dx_get_limit(entries) == dx_root_limit(dir, - root->info.info_length)); - dxtrace (printk("Look up %x", hash)); - while (1) - { - count = dx_get_count(entries); - assert (count && count <= dx_get_limit(entries)); - p = entries + 1; - q = entries + count - 1; - while (p <= q) - { - m = p + (q - p)/2; - dxtrace(printk(".")); - if (dx_get_hash(m) > hash) - q = m - 1; - else - p = m + 1; - } - - if (0) // linear search cross check - { - unsigned n = count - 1; - at = entries; - while (n--) - { - dxtrace(printk(",")); - if (dx_get_hash(++at) > hash) - { - at--; - break; - } - } - assert (at == p - 1); - } - - at = p - 1; - dxtrace(printk(" %x->%u\n", at == entries? 0: dx_get_hash(at), dx_get_block(at))); - frame->bh = bh; - frame->entries = entries; - frame->at = at; - if (!indirect--) return frame; - if (!(bh = ext4_bread (NULL,dir, dx_get_block(at), 0, err))) - goto fail2; - at = entries = ((struct dx_node *) bh->b_data)->entries; - assert (dx_get_limit(entries) == dx_node_limit (dir)); - frame++; - } -fail2: - while (frame >= frame_in) { - brelse(frame->bh); - frame--; - } -fail: - return NULL; -} - -static void dx_release (struct dx_frame *frames) -{ - if (frames[0].bh == NULL) - return; - - if (((struct dx_root *) frames[0].bh->b_data)->info.indirect_levels) - brelse(frames[1].bh); - brelse(frames[0].bh); -} - -/* - * This function increments the frame pointer to search the next leaf - * block, and reads in the necessary intervening nodes if the search - * should be necessary. Whether or not the search is necessary is - * controlled by the hash parameter. If the hash value is even, then - * the search is only continued if the next block starts with that - * hash value. This is used if we are searching for a specific file. - * - * If the hash value is HASH_NB_ALWAYS, then always go to the next block. - * - * This function returns 1 if the caller should continue to search, - * or 0 if it should not. If there is an error reading one of the - * index blocks, it will a negative error code. - * - * If start_hash is non-null, it will be filled in with the starting - * hash of the next page. - */ -static int ext4_htree_next_block(struct inode *dir, __u32 hash, - struct dx_frame *frame, - struct dx_frame *frames, - __u32 *start_hash) -{ - struct dx_frame *p; - struct buffer_head *bh; - int err, num_frames = 0; - __u32 bhash; - - p = frame; - /* - * Find the next leaf page by incrementing the frame pointer. - * If we run out of entries in the interior node, loop around and - * increment pointer in the parent node. When we break out of - * this loop, num_frames indicates the number of interior - * nodes need to be read. - */ - while (1) { - if (++(p->at) < p->entries + dx_get_count(p->entries)) - break; - if (p == frames) - return 0; - num_frames++; - p--; - } - - /* - * If the hash is 1, then continue only if the next page has a - * continuation hash of any value. This is used for readdir - * handling. Otherwise, check to see if the hash matches the - * desired contiuation hash. If it doesn't, return since - * there's no point to read in the successive index pages. - */ - bhash = dx_get_hash(p->at); - if (start_hash) - *start_hash = bhash; - if ((hash & 1) == 0) { - if ((bhash & ~1) != hash) - return 0; - } - /* - * If the hash is HASH_NB_ALWAYS, we always go to the next - * block so no check is necessary - */ - while (num_frames--) { - if (!(bh = ext4_bread(NULL, dir, dx_get_block(p->at), - 0, &err))) - return err; /* Failure */ - p++; - brelse (p->bh); - p->bh = bh; - p->at = p->entries = ((struct dx_node *) bh->b_data)->entries; - } - return 1; -} - - -/* - * p is at least 6 bytes before the end of page - */ -static inline struct ext4_dir_entry_2 *ext4_next_entry(struct ext4_dir_entry_2 *p) -{ - return (struct ext4_dir_entry_2 *)((char*)p + le16_to_cpu(p->rec_len)); -} - -/* - * This function fills a red-black tree with information from a - * directory block. It returns the number directory entries loaded - * into the tree. If there is an error it is returned in err. - */ -static int htree_dirblock_to_tree(struct file *dir_file, - struct inode *dir, int block, - struct dx_hash_info *hinfo, - __u32 start_hash, __u32 start_minor_hash) -{ - struct buffer_head *bh; - struct ext4_dir_entry_2 *de, *top; - int err, count = 0; - - dxtrace(printk("In htree dirblock_to_tree: block %d\n", block)); - if (!(bh = ext4_bread (NULL, dir, block, 0, &err))) - return err; - - de = (struct ext4_dir_entry_2 *) bh->b_data; - top = (struct ext4_dir_entry_2 *) ((char *) de + - dir->i_sb->s_blocksize - - EXT4_DIR_REC_LEN(0)); - for (; de < top; de = ext4_next_entry(de)) { - ext4fs_dirhash(de->name, de->name_len, hinfo); - if ((hinfo->hash < start_hash) || - ((hinfo->hash == start_hash) && - (hinfo->minor_hash < start_minor_hash))) - continue; - if (de->inode == 0) - continue; - if ((err = ext4_htree_store_dirent(dir_file, - hinfo->hash, hinfo->minor_hash, de)) != 0) { - brelse(bh); - return err; - } - count++; - } - brelse(bh); - return count; -} - - -/* - * This function fills a red-black tree with information from a - * directory. We start scanning the directory in hash order, starting - * at start_hash and start_minor_hash. - * - * This function returns the number of entries inserted into the tree, - * or a negative error code. - */ -int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash, - __u32 start_minor_hash, __u32 *next_hash) -{ - struct dx_hash_info hinfo; - struct ext4_dir_entry_2 *de; - struct dx_frame frames[2], *frame; - struct inode *dir; - int block, err; - int count = 0; - int ret; - __u32 hashval; - - dxtrace(printk("In htree_fill_tree, start hash: %x:%x\n", start_hash, - start_minor_hash)); - dir = dir_file->f_dentry->d_inode; - if (!(EXT4_I(dir)->i_flags & EXT4_INDEX_FL)) { - hinfo.hash_version = EXT4_SB(dir->i_sb)->s_def_hash_version; - hinfo.seed = EXT4_SB(dir->i_sb)->s_hash_seed; - count = htree_dirblock_to_tree(dir_file, dir, 0, &hinfo, - start_hash, start_minor_hash); - *next_hash = ~0; - return count; - } - hinfo.hash = start_hash; - hinfo.minor_hash = 0; - frame = dx_probe(NULL, dir_file->f_dentry->d_inode, &hinfo, frames, &err); - if (!frame) - return err; - - /* Add '.' and '..' from the htree header */ - if (!start_hash && !start_minor_hash) { - de = (struct ext4_dir_entry_2 *) frames[0].bh->b_data; - if ((err = ext4_htree_store_dirent(dir_file, 0, 0, de)) != 0) - goto errout; - count++; - } - if (start_hash < 2 || (start_hash ==2 && start_minor_hash==0)) { - de = (struct ext4_dir_entry_2 *) frames[0].bh->b_data; - de = ext4_next_entry(de); - if ((err = ext4_htree_store_dirent(dir_file, 2, 0, de)) != 0) - goto errout; - count++; - } - - while (1) { - block = dx_get_block(frame->at); - ret = htree_dirblock_to_tree(dir_file, dir, block, &hinfo, - start_hash, start_minor_hash); - if (ret < 0) { - err = ret; - goto errout; - } - count += ret; - hashval = ~0; - ret = ext4_htree_next_block(dir, HASH_NB_ALWAYS, - frame, frames, &hashval); - *next_hash = hashval; - if (ret < 0) { - err = ret; - goto errout; - } - /* - * Stop if: (a) there are no more entries, or - * (b) we have inserted at least one entry and the - * next hash value is not a continuation - */ - if ((ret == 0) || - (count && ((hashval & 1) == 0))) - break; - } - dx_release(frames); - dxtrace(printk("Fill tree: returned %d entries, next hash: %x\n", - count, *next_hash)); - return count; -errout: - dx_release(frames); - return (err); -} - - -/* - * Directory block splitting, compacting - */ - -static int dx_make_map (struct ext4_dir_entry_2 *de, int size, - struct dx_hash_info *hinfo, struct dx_map_entry *map_tail) -{ - int count = 0; - char *base = (char *) de; - struct dx_hash_info h = *hinfo; - - while ((char *) de < base + size) - { - if (de->name_len && de->inode) { - ext4fs_dirhash(de->name, de->name_len, &h); - map_tail--; - map_tail->hash = h.hash; - map_tail->offs = (u32) ((char *) de - base); - count++; - cond_resched(); - } - /* XXX: do we need to check rec_len == 0 case? -Chris */ - de = (struct ext4_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len)); - } - return count; -} - -static void dx_sort_map (struct dx_map_entry *map, unsigned count) -{ - struct dx_map_entry *p, *q, *top = map + count - 1; - int more; - /* Combsort until bubble sort doesn't suck */ - while (count > 2) { - count = count*10/13; - if (count - 9 < 2) /* 9, 10 -> 11 */ - count = 11; - for (p = top, q = p - count; q >= map; p--, q--) - if (p->hash < q->hash) - swap(*p, *q); - } - /* Garden variety bubble sort */ - do { - more = 0; - q = top; - while (q-- > map) { - if (q[1].hash >= q[0].hash) - continue; - swap(*(q+1), *q); - more = 1; - } - } while(more); -} - -static void dx_insert_block(struct dx_frame *frame, u32 hash, u32 block) -{ - struct dx_entry *entries = frame->entries; - struct dx_entry *old = frame->at, *new = old + 1; - int count = dx_get_count(entries); - - assert(count < dx_get_limit(entries)); - assert(old < entries + count); - memmove(new + 1, new, (char *)(entries + count) - (char *)(new)); - dx_set_hash(new, hash); - dx_set_block(new, block); - dx_set_count(entries, count + 1); -} -#endif - - -static void ext4_update_dx_flag(struct inode *inode) -{ - if (!EXT4_HAS_COMPAT_FEATURE(inode->i_sb, - EXT4_FEATURE_COMPAT_DIR_INDEX)) - EXT4_I(inode)->i_flags &= ~EXT4_INDEX_FL; -} - -/* - * NOTE! unlike strncmp, ext4_match returns 1 for success, 0 for failure. - * - * `len <= EXT4_NAME_LEN' is guaranteed by caller. - * `de != NULL' is guaranteed by caller. - */ -static inline int ext4_match (int len, const char * const name, - struct ext4_dir_entry_2 * de) -{ - if (len != de->name_len) - return 0; - if (!de->inode) - return 0; - return !memcmp(name, de->name, len); -} - -/* - * Returns 0 if not found, -1 on failure, and 1 on success - */ -static inline int search_dirblock(struct buffer_head * bh, - struct inode *dir, - struct dentry *dentry, - unsigned long offset, - struct ext4_dir_entry_2 ** res_dir) -{ - struct ext4_dir_entry_2 * de; - char * dlimit; - int de_len; - const char *name = dentry->d_name.name; - int namelen = dentry->d_name.len; - - de = (struct ext4_dir_entry_2 *) bh->b_data; - dlimit = bh->b_data + dir->i_sb->s_blocksize; - while ((char *) de < dlimit) { - /* this code is executed quadratically often */ - /* do minimal checking `by hand' */ - - if ((char *) de + namelen <= dlimit && - ext4_match (namelen, name, de)) { - /* found a match - just to be sure, do a full check */ - if (!ext4_check_dir_entry("ext4_find_entry", - dir, de, bh, offset)) - return -1; - *res_dir = de; - return 1; - } - /* prevent looping on a bad block */ - de_len = le16_to_cpu(de->rec_len); - if (de_len <= 0) - return -1; - offset += de_len; - de = (struct ext4_dir_entry_2 *) ((char *) de + de_len); - } - return 0; -} - - -/* - * ext4_find_entry() - * - * finds an entry in the specified directory with the wanted name. It - * returns the cache buffer in which the entry was found, and the entry - * itself (as a parameter - res_dir). It does NOT read the inode of the - * entry - you'll have to do that yourself if you want to. - * - * The returned buffer_head has ->b_count elevated. The caller is expected - * to brelse() it when appropriate. - */ -static struct buffer_head * ext4_find_entry (struct dentry *dentry, - struct ext4_dir_entry_2 ** res_dir) -{ - struct super_block * sb; - struct buffer_head * bh_use[NAMEI_RA_SIZE]; - struct buffer_head * bh, *ret = NULL; - unsigned long start, block, b; - int ra_max = 0; /* Number of bh's in the readahead - buffer, bh_use[] */ - int ra_ptr = 0; /* Current index into readahead - buffer */ - int num = 0; - int nblocks, i, err; - struct inode *dir = dentry->d_parent->d_inode; - int namelen; - const u8 *name; - unsigned blocksize; - - *res_dir = NULL; - sb = dir->i_sb; - blocksize = sb->s_blocksize; - namelen = dentry->d_name.len; - name = dentry->d_name.name; - if (namelen > EXT4_NAME_LEN) - return NULL; -#ifdef CONFIG_EXT4_INDEX - if (is_dx(dir)) { - bh = ext4_dx_find_entry(dentry, res_dir, &err); - /* - * On success, or if the error was file not found, - * return. Otherwise, fall back to doing a search the - * old fashioned way. - */ - if (bh || (err != ERR_BAD_DX_DIR)) - return bh; - dxtrace(printk("ext4_find_entry: dx failed, falling back\n")); - } -#endif - nblocks = dir->i_size >> EXT4_BLOCK_SIZE_BITS(sb); - start = EXT4_I(dir)->i_dir_start_lookup; - if (start >= nblocks) - start = 0; - block = start; -restart: - do { - /* - * We deal with the read-ahead logic here. - */ - if (ra_ptr >= ra_max) { - /* Refill the readahead buffer */ - ra_ptr = 0; - b = block; - for (ra_max = 0; ra_max < NAMEI_RA_SIZE; ra_max++) { - /* - * Terminate if we reach the end of the - * directory and must wrap, or if our - * search has finished at this block. - */ - if (b >= nblocks || (num && block == start)) { - bh_use[ra_max] = NULL; - break; - } - num++; - bh = ext4_getblk(NULL, dir, b++, 0, &err); - bh_use[ra_max] = bh; - if (bh) - ll_rw_block(READ_META, 1, &bh); - } - } - if ((bh = bh_use[ra_ptr++]) == NULL) - goto next; - wait_on_buffer(bh); - if (!buffer_uptodate(bh)) { - /* read error, skip block & hope for the best */ - ext4_error(sb, __FUNCTION__, "reading directory #%lu " - "offset %lu", dir->i_ino, block); - brelse(bh); - goto next; - } - i = search_dirblock(bh, dir, dentry, - block << EXT4_BLOCK_SIZE_BITS(sb), res_dir); - if (i == 1) { - EXT4_I(dir)->i_dir_start_lookup = block; - ret = bh; - goto cleanup_and_exit; - } else { - brelse(bh); - if (i < 0) - goto cleanup_and_exit; - } - next: - if (++block >= nblocks) - block = 0; - } while (block != start); - - /* - * If the directory has grown while we were searching, then - * search the last part of the directory before giving up. - */ - block = nblocks; - nblocks = dir->i_size >> EXT4_BLOCK_SIZE_BITS(sb); - if (block < nblocks) { - start = 0; - goto restart; - } - -cleanup_and_exit: - /* Clean up the read-ahead blocks */ - for (; ra_ptr < ra_max; ra_ptr++) - brelse (bh_use[ra_ptr]); - return ret; -} - -#ifdef CONFIG_EXT4_INDEX -static struct buffer_head * ext4_dx_find_entry(struct dentry *dentry, - struct ext4_dir_entry_2 **res_dir, int *err) -{ - struct super_block * sb; - struct dx_hash_info hinfo; - u32 hash; - struct dx_frame frames[2], *frame; - struct ext4_dir_entry_2 *de, *top; - struct buffer_head *bh; - unsigned long block; - int retval; - int namelen = dentry->d_name.len; - const u8 *name = dentry->d_name.name; - struct inode *dir = dentry->d_parent->d_inode; - - sb = dir->i_sb; - /* NFS may look up ".." - look at dx_root directory block */ - if (namelen > 2 || name[0] != '.'||(name[1] != '.' && name[1] != '\0')){ - if (!(frame = dx_probe(dentry, NULL, &hinfo, frames, err))) - return NULL; - } else { - frame = frames; - frame->bh = NULL; /* for dx_release() */ - frame->at = (struct dx_entry *)frames; /* hack for zero entry*/ - dx_set_block(frame->at, 0); /* dx_root block is 0 */ - } - hash = hinfo.hash; - do { - block = dx_get_block(frame->at); - if (!(bh = ext4_bread (NULL,dir, block, 0, err))) - goto errout; - de = (struct ext4_dir_entry_2 *) bh->b_data; - top = (struct ext4_dir_entry_2 *) ((char *) de + sb->s_blocksize - - EXT4_DIR_REC_LEN(0)); - for (; de < top; de = ext4_next_entry(de)) - if (ext4_match (namelen, name, de)) { - if (!ext4_check_dir_entry("ext4_find_entry", - dir, de, bh, - (block<b_data))) { - brelse (bh); - goto errout; - } - *res_dir = de; - dx_release (frames); - return bh; - } - brelse (bh); - /* Check to see if we should continue to search */ - retval = ext4_htree_next_block(dir, hash, frame, - frames, NULL); - if (retval < 0) { - ext4_warning(sb, __FUNCTION__, - "error reading index page in directory #%lu", - dir->i_ino); - *err = retval; - goto errout; - } - } while (retval == 1); - - *err = -ENOENT; -errout: - dxtrace(printk("%s not found\n", name)); - dx_release (frames); - return NULL; -} -#endif - -static struct dentry *ext4_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd) -{ - struct inode * inode; - struct ext4_dir_entry_2 * de; - struct buffer_head * bh; - - if (dentry->d_name.len > EXT4_NAME_LEN) - return ERR_PTR(-ENAMETOOLONG); - - bh = ext4_find_entry(dentry, &de); - inode = NULL; - if (bh) { - unsigned long ino = le32_to_cpu(de->inode); - brelse (bh); - if (!ext4_valid_inum(dir->i_sb, ino)) { - ext4_error(dir->i_sb, "ext4_lookup", - "bad inode number: %lu", ino); - inode = NULL; - } else - inode = iget(dir->i_sb, ino); - - if (!inode) - return ERR_PTR(-EACCES); - } - return d_splice_alias(inode, dentry); -} - - -struct dentry *ext4_get_parent(struct dentry *child) -{ - unsigned long ino; - struct dentry *parent; - struct inode *inode; - struct dentry dotdot; - struct ext4_dir_entry_2 * de; - struct buffer_head *bh; - - dotdot.d_name.name = ".."; - dotdot.d_name.len = 2; - dotdot.d_parent = child; /* confusing, isn't it! */ - - bh = ext4_find_entry(&dotdot, &de); - inode = NULL; - if (!bh) - return ERR_PTR(-ENOENT); - ino = le32_to_cpu(de->inode); - brelse(bh); - - if (!ext4_valid_inum(child->d_inode->i_sb, ino)) { - ext4_error(child->d_inode->i_sb, "ext4_get_parent", - "bad inode number: %lu", ino); - inode = NULL; - } else - inode = iget(child->d_inode->i_sb, ino); - - if (!inode) - return ERR_PTR(-EACCES); - - parent = d_alloc_anon(inode); - if (!parent) { - iput(inode); - parent = ERR_PTR(-ENOMEM); - } - return parent; -} - -#define S_SHIFT 12 -static unsigned char ext4_type_by_mode[S_IFMT >> S_SHIFT] = { - [S_IFREG >> S_SHIFT] = EXT4_FT_REG_FILE, - [S_IFDIR >> S_SHIFT] = EXT4_FT_DIR, - [S_IFCHR >> S_SHIFT] = EXT4_FT_CHRDEV, - [S_IFBLK >> S_SHIFT] = EXT4_FT_BLKDEV, - [S_IFIFO >> S_SHIFT] = EXT4_FT_FIFO, - [S_IFSOCK >> S_SHIFT] = EXT4_FT_SOCK, - [S_IFLNK >> S_SHIFT] = EXT4_FT_SYMLINK, -}; - -static inline void ext4_set_de_type(struct super_block *sb, - struct ext4_dir_entry_2 *de, - umode_t mode) { - if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FILETYPE)) - de->file_type = ext4_type_by_mode[(mode & S_IFMT)>>S_SHIFT]; -} - -#ifdef CONFIG_EXT4_INDEX -static struct ext4_dir_entry_2 * -dx_move_dirents(char *from, char *to, struct dx_map_entry *map, int count) -{ - unsigned rec_len = 0; - - while (count--) { - struct ext4_dir_entry_2 *de = (struct ext4_dir_entry_2 *) (from + map->offs); - rec_len = EXT4_DIR_REC_LEN(de->name_len); - memcpy (to, de, rec_len); - ((struct ext4_dir_entry_2 *) to)->rec_len = - cpu_to_le16(rec_len); - de->inode = 0; - map++; - to += rec_len; - } - return (struct ext4_dir_entry_2 *) (to - rec_len); -} - -static struct ext4_dir_entry_2* dx_pack_dirents(char *base, int size) -{ - struct ext4_dir_entry_2 *next, *to, *prev, *de = (struct ext4_dir_entry_2 *) base; - unsigned rec_len = 0; - - prev = to = de; - while ((char*)de < base + size) { - next = (struct ext4_dir_entry_2 *) ((char *) de + - le16_to_cpu(de->rec_len)); - if (de->inode && de->name_len) { - rec_len = EXT4_DIR_REC_LEN(de->name_len); - if (de > to) - memmove(to, de, rec_len); - to->rec_len = cpu_to_le16(rec_len); - prev = to; - to = (struct ext4_dir_entry_2 *) (((char *) to) + rec_len); - } - de = next; - } - return prev; -} - -static struct ext4_dir_entry_2 *do_split(handle_t *handle, struct inode *dir, - struct buffer_head **bh,struct dx_frame *frame, - struct dx_hash_info *hinfo, int *error) -{ - unsigned blocksize = dir->i_sb->s_blocksize; - unsigned count, continued; - struct buffer_head *bh2; - u32 newblock; - u32 hash2; - struct dx_map_entry *map; - char *data1 = (*bh)->b_data, *data2; - unsigned split; - struct ext4_dir_entry_2 *de = NULL, *de2; - int err; - - bh2 = ext4_append (handle, dir, &newblock, error); - if (!(bh2)) { - brelse(*bh); - *bh = NULL; - goto errout; - } - - BUFFER_TRACE(*bh, "get_write_access"); - err = ext4_journal_get_write_access(handle, *bh); - if (err) { - journal_error: - brelse(*bh); - brelse(bh2); - *bh = NULL; - ext4_std_error(dir->i_sb, err); - goto errout; - } - BUFFER_TRACE(frame->bh, "get_write_access"); - err = ext4_journal_get_write_access(handle, frame->bh); - if (err) - goto journal_error; - - data2 = bh2->b_data; - - /* create map in the end of data2 block */ - map = (struct dx_map_entry *) (data2 + blocksize); - count = dx_make_map ((struct ext4_dir_entry_2 *) data1, - blocksize, hinfo, map); - map -= count; - split = count/2; // need to adjust to actual middle - dx_sort_map (map, count); - hash2 = map[split].hash; - continued = hash2 == map[split - 1].hash; - dxtrace(printk("Split block %i at %x, %i/%i\n", - dx_get_block(frame->at), hash2, split, count-split)); - - /* Fancy dance to stay within two buffers */ - de2 = dx_move_dirents(data1, data2, map + split, count - split); - de = dx_pack_dirents(data1,blocksize); - de->rec_len = cpu_to_le16(data1 + blocksize - (char *) de); - de2->rec_len = cpu_to_le16(data2 + blocksize - (char *) de2); - dxtrace(dx_show_leaf (hinfo, (struct ext4_dir_entry_2 *) data1, blocksize, 1)); - dxtrace(dx_show_leaf (hinfo, (struct ext4_dir_entry_2 *) data2, blocksize, 1)); - - /* Which block gets the new entry? */ - if (hinfo->hash >= hash2) - { - swap(*bh, bh2); - de = de2; - } - dx_insert_block (frame, hash2 + continued, newblock); - err = ext4_journal_dirty_metadata (handle, bh2); - if (err) - goto journal_error; - err = ext4_journal_dirty_metadata (handle, frame->bh); - if (err) - goto journal_error; - brelse (bh2); - dxtrace(dx_show_index ("frame", frame->entries)); -errout: - return de; -} -#endif - - -/* - * Add a new entry into a directory (leaf) block. If de is non-NULL, - * it points to a directory entry which is guaranteed to be large - * enough for new directory entry. If de is NULL, then - * add_dirent_to_buf will attempt search the directory block for - * space. It will return -ENOSPC if no space is available, and -EIO - * and -EEXIST if directory entry already exists. - * - * NOTE! bh is NOT released in the case where ENOSPC is returned. In - * all other cases bh is released. - */ -static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry, - struct inode *inode, struct ext4_dir_entry_2 *de, - struct buffer_head * bh) -{ - struct inode *dir = dentry->d_parent->d_inode; - const char *name = dentry->d_name.name; - int namelen = dentry->d_name.len; - unsigned long offset = 0; - unsigned short reclen; - int nlen, rlen, err; - char *top; - - reclen = EXT4_DIR_REC_LEN(namelen); - if (!de) { - de = (struct ext4_dir_entry_2 *)bh->b_data; - top = bh->b_data + dir->i_sb->s_blocksize - reclen; - while ((char *) de <= top) { - if (!ext4_check_dir_entry("ext4_add_entry", dir, de, - bh, offset)) { - brelse (bh); - return -EIO; - } - if (ext4_match (namelen, name, de)) { - brelse (bh); - return -EEXIST; - } - nlen = EXT4_DIR_REC_LEN(de->name_len); - rlen = le16_to_cpu(de->rec_len); - if ((de->inode? rlen - nlen: rlen) >= reclen) - break; - de = (struct ext4_dir_entry_2 *)((char *)de + rlen); - offset += rlen; - } - if ((char *) de > top) - return -ENOSPC; - } - BUFFER_TRACE(bh, "get_write_access"); - err = ext4_journal_get_write_access(handle, bh); - if (err) { - ext4_std_error(dir->i_sb, err); - brelse(bh); - return err; - } - - /* By now the buffer is marked for journaling */ - nlen = EXT4_DIR_REC_LEN(de->name_len); - rlen = le16_to_cpu(de->rec_len); - if (de->inode) { - struct ext4_dir_entry_2 *de1 = (struct ext4_dir_entry_2 *)((char *)de + nlen); - de1->rec_len = cpu_to_le16(rlen - nlen); - de->rec_len = cpu_to_le16(nlen); - de = de1; - } - de->file_type = EXT4_FT_UNKNOWN; - if (inode) { - de->inode = cpu_to_le32(inode->i_ino); - ext4_set_de_type(dir->i_sb, de, inode->i_mode); - } else - de->inode = 0; - de->name_len = namelen; - memcpy (de->name, name, namelen); - /* - * XXX shouldn't update any times until successful - * completion of syscall, but too many callers depend - * on this. - * - * XXX similarly, too many callers depend on - * ext4_new_inode() setting the times, but error - * recovery deletes the inode, so the worst that can - * happen is that the times are slightly out of date - * and/or different from the directory change time. - */ - dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; - ext4_update_dx_flag(dir); - dir->i_version++; - ext4_mark_inode_dirty(handle, dir); - BUFFER_TRACE(bh, "call ext4_journal_dirty_metadata"); - err = ext4_journal_dirty_metadata(handle, bh); - if (err) - ext4_std_error(dir->i_sb, err); - brelse(bh); - return 0; -} - -#ifdef CONFIG_EXT4_INDEX -/* - * This converts a one block unindexed directory to a 3 block indexed - * directory, and adds the dentry to the indexed directory. - */ -static int make_indexed_dir(handle_t *handle, struct dentry *dentry, - struct inode *inode, struct buffer_head *bh) -{ - struct inode *dir = dentry->d_parent->d_inode; - const char *name = dentry->d_name.name; - int namelen = dentry->d_name.len; - struct buffer_head *bh2; - struct dx_root *root; - struct dx_frame frames[2], *frame; - struct dx_entry *entries; - struct ext4_dir_entry_2 *de, *de2; - char *data1, *top; - unsigned len; - int retval; - unsigned blocksize; - struct dx_hash_info hinfo; - u32 block; - struct fake_dirent *fde; - - blocksize = dir->i_sb->s_blocksize; - dxtrace(printk("Creating index\n")); - retval = ext4_journal_get_write_access(handle, bh); - if (retval) { - ext4_std_error(dir->i_sb, retval); - brelse(bh); - return retval; - } - root = (struct dx_root *) bh->b_data; - - bh2 = ext4_append (handle, dir, &block, &retval); - if (!(bh2)) { - brelse(bh); - return retval; - } - EXT4_I(dir)->i_flags |= EXT4_INDEX_FL; - data1 = bh2->b_data; - - /* The 0th block becomes the root, move the dirents out */ - fde = &root->dotdot; - de = (struct ext4_dir_entry_2 *)((char *)fde + le16_to_cpu(fde->rec_len)); - len = ((char *) root) + blocksize - (char *) de; - memcpy (data1, de, len); - de = (struct ext4_dir_entry_2 *) data1; - top = data1 + len; - while ((char *)(de2=(void*)de+le16_to_cpu(de->rec_len)) < top) - de = de2; - de->rec_len = cpu_to_le16(data1 + blocksize - (char *) de); - /* Initialize the root; the dot dirents already exist */ - de = (struct ext4_dir_entry_2 *) (&root->dotdot); - de->rec_len = cpu_to_le16(blocksize - EXT4_DIR_REC_LEN(2)); - memset (&root->info, 0, sizeof(root->info)); - root->info.info_length = sizeof(root->info); - root->info.hash_version = EXT4_SB(dir->i_sb)->s_def_hash_version; - entries = root->entries; - dx_set_block (entries, 1); - dx_set_count (entries, 1); - dx_set_limit (entries, dx_root_limit(dir, sizeof(root->info))); - - /* Initialize as for dx_probe */ - hinfo.hash_version = root->info.hash_version; - hinfo.seed = EXT4_SB(dir->i_sb)->s_hash_seed; - ext4fs_dirhash(name, namelen, &hinfo); - frame = frames; - frame->entries = entries; - frame->at = entries; - frame->bh = bh; - bh = bh2; - de = do_split(handle,dir, &bh, frame, &hinfo, &retval); - dx_release (frames); - if (!(de)) - return retval; - - return add_dirent_to_buf(handle, dentry, inode, de, bh); -} -#endif - -/* - * ext4_add_entry() - * - * adds a file entry to the specified directory, using the same - * semantics as ext4_find_entry(). It returns NULL if it failed. - * - * NOTE!! The inode part of 'de' is left at 0 - which means you - * may not sleep between calling this and putting something into - * the entry, as someone else might have used it while you slept. - */ -static int ext4_add_entry (handle_t *handle, struct dentry *dentry, - struct inode *inode) -{ - struct inode *dir = dentry->d_parent->d_inode; - unsigned long offset; - struct buffer_head * bh; - struct ext4_dir_entry_2 *de; - struct super_block * sb; - int retval; -#ifdef CONFIG_EXT4_INDEX - int dx_fallback=0; -#endif - unsigned blocksize; - u32 block, blocks; - - sb = dir->i_sb; - blocksize = sb->s_blocksize; - if (!dentry->d_name.len) - return -EINVAL; -#ifdef CONFIG_EXT4_INDEX - if (is_dx(dir)) { - retval = ext4_dx_add_entry(handle, dentry, inode); - if (!retval || (retval != ERR_BAD_DX_DIR)) - return retval; - EXT4_I(dir)->i_flags &= ~EXT4_INDEX_FL; - dx_fallback++; - ext4_mark_inode_dirty(handle, dir); - } -#endif - blocks = dir->i_size >> sb->s_blocksize_bits; - for (block = 0, offset = 0; block < blocks; block++) { - bh = ext4_bread(handle, dir, block, 0, &retval); - if(!bh) - return retval; - retval = add_dirent_to_buf(handle, dentry, inode, NULL, bh); - if (retval != -ENOSPC) - return retval; - -#ifdef CONFIG_EXT4_INDEX - if (blocks == 1 && !dx_fallback && - EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_DIR_INDEX)) - return make_indexed_dir(handle, dentry, inode, bh); -#endif - brelse(bh); - } - bh = ext4_append(handle, dir, &block, &retval); - if (!bh) - return retval; - de = (struct ext4_dir_entry_2 *) bh->b_data; - de->inode = 0; - de->rec_len = cpu_to_le16(blocksize); - return add_dirent_to_buf(handle, dentry, inode, de, bh); -} - -#ifdef CONFIG_EXT4_INDEX -/* - * Returns 0 for success, or a negative error value - */ -static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry, - struct inode *inode) -{ - struct dx_frame frames[2], *frame; - struct dx_entry *entries, *at; - struct dx_hash_info hinfo; - struct buffer_head * bh; - struct inode *dir = dentry->d_parent->d_inode; - struct super_block * sb = dir->i_sb; - struct ext4_dir_entry_2 *de; - int err; - - frame = dx_probe(dentry, NULL, &hinfo, frames, &err); - if (!frame) - return err; - entries = frame->entries; - at = frame->at; - - if (!(bh = ext4_bread(handle,dir, dx_get_block(frame->at), 0, &err))) - goto cleanup; - - BUFFER_TRACE(bh, "get_write_access"); - err = ext4_journal_get_write_access(handle, bh); - if (err) - goto journal_error; - - err = add_dirent_to_buf(handle, dentry, inode, NULL, bh); - if (err != -ENOSPC) { - bh = NULL; - goto cleanup; - } - - /* Block full, should compress but for now just split */ - dxtrace(printk("using %u of %u node entries\n", - dx_get_count(entries), dx_get_limit(entries))); - /* Need to split index? */ - if (dx_get_count(entries) == dx_get_limit(entries)) { - u32 newblock; - unsigned icount = dx_get_count(entries); - int levels = frame - frames; - struct dx_entry *entries2; - struct dx_node *node2; - struct buffer_head *bh2; - - if (levels && (dx_get_count(frames->entries) == - dx_get_limit(frames->entries))) { - ext4_warning(sb, __FUNCTION__, - "Directory index full!"); - err = -ENOSPC; - goto cleanup; - } - bh2 = ext4_append (handle, dir, &newblock, &err); - if (!(bh2)) - goto cleanup; - node2 = (struct dx_node *)(bh2->b_data); - entries2 = node2->entries; - node2->fake.rec_len = cpu_to_le16(sb->s_blocksize); - node2->fake.inode = 0; - BUFFER_TRACE(frame->bh, "get_write_access"); - err = ext4_journal_get_write_access(handle, frame->bh); - if (err) - goto journal_error; - if (levels) { - unsigned icount1 = icount/2, icount2 = icount - icount1; - unsigned hash2 = dx_get_hash(entries + icount1); - dxtrace(printk("Split index %i/%i\n", icount1, icount2)); - - BUFFER_TRACE(frame->bh, "get_write_access"); /* index root */ - err = ext4_journal_get_write_access(handle, - frames[0].bh); - if (err) - goto journal_error; - - memcpy ((char *) entries2, (char *) (entries + icount1), - icount2 * sizeof(struct dx_entry)); - dx_set_count (entries, icount1); - dx_set_count (entries2, icount2); - dx_set_limit (entries2, dx_node_limit(dir)); - - /* Which index block gets the new entry? */ - if (at - entries >= icount1) { - frame->at = at = at - entries - icount1 + entries2; - frame->entries = entries = entries2; - swap(frame->bh, bh2); - } - dx_insert_block (frames + 0, hash2, newblock); - dxtrace(dx_show_index ("node", frames[1].entries)); - dxtrace(dx_show_index ("node", - ((struct dx_node *) bh2->b_data)->entries)); - err = ext4_journal_dirty_metadata(handle, bh2); - if (err) - goto journal_error; - brelse (bh2); - } else { - dxtrace(printk("Creating second level index...\n")); - memcpy((char *) entries2, (char *) entries, - icount * sizeof(struct dx_entry)); - dx_set_limit(entries2, dx_node_limit(dir)); - - /* Set up root */ - dx_set_count(entries, 1); - dx_set_block(entries + 0, newblock); - ((struct dx_root *) frames[0].bh->b_data)->info.indirect_levels = 1; - - /* Add new access path frame */ - frame = frames + 1; - frame->at = at = at - entries + entries2; - frame->entries = entries = entries2; - frame->bh = bh2; - err = ext4_journal_get_write_access(handle, - frame->bh); - if (err) - goto journal_error; - } - ext4_journal_dirty_metadata(handle, frames[0].bh); - } - de = do_split(handle, dir, &bh, frame, &hinfo, &err); - if (!de) - goto cleanup; - err = add_dirent_to_buf(handle, dentry, inode, de, bh); - bh = NULL; - goto cleanup; - -journal_error: - ext4_std_error(dir->i_sb, err); -cleanup: - if (bh) - brelse(bh); - dx_release(frames); - return err; -} -#endif - -/* - * ext4_delete_entry deletes a directory entry by merging it with the - * previous entry - */ -static int ext4_delete_entry (handle_t *handle, - struct inode * dir, - struct ext4_dir_entry_2 * de_del, - struct buffer_head * bh) -{ - struct ext4_dir_entry_2 * de, * pde; - int i; - - i = 0; - pde = NULL; - de = (struct ext4_dir_entry_2 *) bh->b_data; - while (i < bh->b_size) { - if (!ext4_check_dir_entry("ext4_delete_entry", dir, de, bh, i)) - return -EIO; - if (de == de_del) { - BUFFER_TRACE(bh, "get_write_access"); - ext4_journal_get_write_access(handle, bh); - if (pde) - pde->rec_len = - cpu_to_le16(le16_to_cpu(pde->rec_len) + - le16_to_cpu(de->rec_len)); - else - de->inode = 0; - dir->i_version++; - BUFFER_TRACE(bh, "call ext4_journal_dirty_metadata"); - ext4_journal_dirty_metadata(handle, bh); - return 0; - } - i += le16_to_cpu(de->rec_len); - pde = de; - de = (struct ext4_dir_entry_2 *) - ((char *) de + le16_to_cpu(de->rec_len)); - } - return -ENOENT; -} - -/* - * ext4_mark_inode_dirty is somewhat expensive, so unlike ext2 we - * do not perform it in these functions. We perform it at the call site, - * if it is needed. - */ -static inline void ext4_inc_count(handle_t *handle, struct inode *inode) -{ - inc_nlink(inode); -} - -static inline void ext4_dec_count(handle_t *handle, struct inode *inode) -{ - drop_nlink(inode); -} - -static int ext4_add_nondir(handle_t *handle, - struct dentry *dentry, struct inode *inode) -{ - int err = ext4_add_entry(handle, dentry, inode); - if (!err) { - ext4_mark_inode_dirty(handle, inode); - d_instantiate(dentry, inode); - return 0; - } - ext4_dec_count(handle, inode); - iput(inode); - return err; -} - -/* - * By the time this is called, we already have created - * the directory cache entry for the new file, but it - * is so far negative - it has no inode. - * - * If the create succeeds, we fill in the inode information - * with d_instantiate(). - */ -static int ext4_create (struct inode * dir, struct dentry * dentry, int mode, - struct nameidata *nd) -{ - handle_t *handle; - struct inode * inode; - int err, retries = 0; - -retry: - handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) + - EXT4_INDEX_EXTRA_TRANS_BLOCKS + 3 + - 2*EXT4_QUOTA_INIT_BLOCKS(dir->i_sb)); - if (IS_ERR(handle)) - return PTR_ERR(handle); - - if (IS_DIRSYNC(dir)) - handle->h_sync = 1; - - inode = ext4_new_inode (handle, dir, mode); - err = PTR_ERR(inode); - if (!IS_ERR(inode)) { - inode->i_op = &ext4_file_inode_operations; - inode->i_fop = &ext4_file_operations; - ext4_set_aops(inode); - err = ext4_add_nondir(handle, dentry, inode); - } - ext4_journal_stop(handle); - if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries)) - goto retry; - return err; -} - -static int ext4_mknod (struct inode * dir, struct dentry *dentry, - int mode, dev_t rdev) -{ - handle_t *handle; - struct inode *inode; - int err, retries = 0; - - if (!new_valid_dev(rdev)) - return -EINVAL; - -retry: - handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) + - EXT4_INDEX_EXTRA_TRANS_BLOCKS + 3 + - 2*EXT4_QUOTA_INIT_BLOCKS(dir->i_sb)); - if (IS_ERR(handle)) - return PTR_ERR(handle); - - if (IS_DIRSYNC(dir)) - handle->h_sync = 1; - - inode = ext4_new_inode (handle, dir, mode); - err = PTR_ERR(inode); - if (!IS_ERR(inode)) { - init_special_inode(inode, inode->i_mode, rdev); -#ifdef CONFIG_EXT4DEV_FS_XATTR - inode->i_op = &ext4_special_inode_operations; -#endif - err = ext4_add_nondir(handle, dentry, inode); - } - ext4_journal_stop(handle); - if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries)) - goto retry; - return err; -} - -static int ext4_mkdir(struct inode * dir, struct dentry * dentry, int mode) -{ - handle_t *handle; - struct inode * inode; - struct buffer_head * dir_block; - struct ext4_dir_entry_2 * de; - int err, retries = 0; - - if (dir->i_nlink >= EXT4_LINK_MAX) - return -EMLINK; - -retry: - handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) + - EXT4_INDEX_EXTRA_TRANS_BLOCKS + 3 + - 2*EXT4_QUOTA_INIT_BLOCKS(dir->i_sb)); - if (IS_ERR(handle)) - return PTR_ERR(handle); - - if (IS_DIRSYNC(dir)) - handle->h_sync = 1; - - inode = ext4_new_inode (handle, dir, S_IFDIR | mode); - err = PTR_ERR(inode); - if (IS_ERR(inode)) - goto out_stop; - - inode->i_op = &ext4_dir_inode_operations; - inode->i_fop = &ext4_dir_operations; - inode->i_size = EXT4_I(inode)->i_disksize = inode->i_sb->s_blocksize; - dir_block = ext4_bread (handle, inode, 0, 1, &err); - if (!dir_block) { - drop_nlink(inode); /* is this nlink == 0? */ - ext4_mark_inode_dirty(handle, inode); - iput (inode); - goto out_stop; - } - BUFFER_TRACE(dir_block, "get_write_access"); - ext4_journal_get_write_access(handle, dir_block); - de = (struct ext4_dir_entry_2 *) dir_block->b_data; - de->inode = cpu_to_le32(inode->i_ino); - de->name_len = 1; - de->rec_len = cpu_to_le16(EXT4_DIR_REC_LEN(de->name_len)); - strcpy (de->name, "."); - ext4_set_de_type(dir->i_sb, de, S_IFDIR); - de = (struct ext4_dir_entry_2 *) - ((char *) de + le16_to_cpu(de->rec_len)); - de->inode = cpu_to_le32(dir->i_ino); - de->rec_len = cpu_to_le16(inode->i_sb->s_blocksize-EXT4_DIR_REC_LEN(1)); - de->name_len = 2; - strcpy (de->name, ".."); - ext4_set_de_type(dir->i_sb, de, S_IFDIR); - inode->i_nlink = 2; - BUFFER_TRACE(dir_block, "call ext4_journal_dirty_metadata"); - ext4_journal_dirty_metadata(handle, dir_block); - brelse (dir_block); - ext4_mark_inode_dirty(handle, inode); - err = ext4_add_entry (handle, dentry, inode); - if (err) { - inode->i_nlink = 0; - ext4_mark_inode_dirty(handle, inode); - iput (inode); - goto out_stop; - } - inc_nlink(dir); - ext4_update_dx_flag(dir); - ext4_mark_inode_dirty(handle, dir); - d_instantiate(dentry, inode); -out_stop: - ext4_journal_stop(handle); - if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries)) - goto retry; - return err; -} - -/* - * routine to check that the specified directory is empty (for rmdir) - */ -static int empty_dir (struct inode * inode) -{ - unsigned long offset; - struct buffer_head * bh; - struct ext4_dir_entry_2 * de, * de1; - struct super_block * sb; - int err = 0; - - sb = inode->i_sb; - if (inode->i_size < EXT4_DIR_REC_LEN(1) + EXT4_DIR_REC_LEN(2) || - !(bh = ext4_bread (NULL, inode, 0, 0, &err))) { - if (err) - ext4_error(inode->i_sb, __FUNCTION__, - "error %d reading directory #%lu offset 0", - err, inode->i_ino); - else - ext4_warning(inode->i_sb, __FUNCTION__, - "bad directory (dir #%lu) - no data block", - inode->i_ino); - return 1; - } - de = (struct ext4_dir_entry_2 *) bh->b_data; - de1 = (struct ext4_dir_entry_2 *) - ((char *) de + le16_to_cpu(de->rec_len)); - if (le32_to_cpu(de->inode) != inode->i_ino || - !le32_to_cpu(de1->inode) || - strcmp (".", de->name) || - strcmp ("..", de1->name)) { - ext4_warning (inode->i_sb, "empty_dir", - "bad directory (dir #%lu) - no `.' or `..'", - inode->i_ino); - brelse (bh); - return 1; - } - offset = le16_to_cpu(de->rec_len) + le16_to_cpu(de1->rec_len); - de = (struct ext4_dir_entry_2 *) - ((char *) de1 + le16_to_cpu(de1->rec_len)); - while (offset < inode->i_size ) { - if (!bh || - (void *) de >= (void *) (bh->b_data+sb->s_blocksize)) { - err = 0; - brelse (bh); - bh = ext4_bread (NULL, inode, - offset >> EXT4_BLOCK_SIZE_BITS(sb), 0, &err); - if (!bh) { - if (err) - ext4_error(sb, __FUNCTION__, - "error %d reading directory" - " #%lu offset %lu", - err, inode->i_ino, offset); - offset += sb->s_blocksize; - continue; - } - de = (struct ext4_dir_entry_2 *) bh->b_data; - } - if (!ext4_check_dir_entry("empty_dir", inode, de, bh, offset)) { - de = (struct ext4_dir_entry_2 *)(bh->b_data + - sb->s_blocksize); - offset = (offset | (sb->s_blocksize - 1)) + 1; - continue; - } - if (le32_to_cpu(de->inode)) { - brelse (bh); - return 0; - } - offset += le16_to_cpu(de->rec_len); - de = (struct ext4_dir_entry_2 *) - ((char *) de + le16_to_cpu(de->rec_len)); - } - brelse (bh); - return 1; -} - -/* ext4_orphan_add() links an unlinked or truncated inode into a list of - * such inodes, starting at the superblock, in case we crash before the - * file is closed/deleted, or in case the inode truncate spans multiple - * transactions and the last transaction is not recovered after a crash. - * - * At filesystem recovery time, we walk this list deleting unlinked - * inodes and truncating linked inodes in ext4_orphan_cleanup(). - */ -int ext4_orphan_add(handle_t *handle, struct inode *inode) -{ - struct super_block *sb = inode->i_sb; - struct ext4_iloc iloc; - int err = 0, rc; - - lock_super(sb); - if (!list_empty(&EXT4_I(inode)->i_orphan)) - goto out_unlock; - - /* Orphan handling is only valid for files with data blocks - * being truncated, or files being unlinked. */ - - /* @@@ FIXME: Observation from aviro: - * I think I can trigger J_ASSERT in ext4_orphan_add(). We block - * here (on lock_super()), so race with ext4_link() which might bump - * ->i_nlink. For, say it, character device. Not a regular file, - * not a directory, not a symlink and ->i_nlink > 0. - */ - J_ASSERT ((S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || - S_ISLNK(inode->i_mode)) || inode->i_nlink == 0); - - BUFFER_TRACE(EXT4_SB(sb)->s_sbh, "get_write_access"); - err = ext4_journal_get_write_access(handle, EXT4_SB(sb)->s_sbh); - if (err) - goto out_unlock; - - err = ext4_reserve_inode_write(handle, inode, &iloc); - if (err) - goto out_unlock; - - /* Insert this inode at the head of the on-disk orphan list... */ - NEXT_ORPHAN(inode) = le32_to_cpu(EXT4_SB(sb)->s_es->s_last_orphan); - EXT4_SB(sb)->s_es->s_last_orphan = cpu_to_le32(inode->i_ino); - err = ext4_journal_dirty_metadata(handle, EXT4_SB(sb)->s_sbh); - rc = ext4_mark_iloc_dirty(handle, inode, &iloc); - if (!err) - err = rc; - - /* Only add to the head of the in-memory list if all the - * previous operations succeeded. If the orphan_add is going to - * fail (possibly taking the journal offline), we can't risk - * leaving the inode on the orphan list: stray orphan-list - * entries can cause panics at unmount time. - * - * This is safe: on error we're going to ignore the orphan list - * anyway on the next recovery. */ - if (!err) - list_add(&EXT4_I(inode)->i_orphan, &EXT4_SB(sb)->s_orphan); - - jbd_debug(4, "superblock will point to %lu\n", inode->i_ino); - jbd_debug(4, "orphan inode %lu will point to %d\n", - inode->i_ino, NEXT_ORPHAN(inode)); -out_unlock: - unlock_super(sb); - ext4_std_error(inode->i_sb, err); - return err; -} - -/* - * ext4_orphan_del() removes an unlinked or truncated inode from the list - * of such inodes stored on disk, because it is finally being cleaned up. - */ -int ext4_orphan_del(handle_t *handle, struct inode *inode) -{ - struct list_head *prev; - struct ext4_inode_info *ei = EXT4_I(inode); - struct ext4_sb_info *sbi; - unsigned long ino_next; - struct ext4_iloc iloc; - int err = 0; - - lock_super(inode->i_sb); - if (list_empty(&ei->i_orphan)) { - unlock_super(inode->i_sb); - return 0; - } - - ino_next = NEXT_ORPHAN(inode); - prev = ei->i_orphan.prev; - sbi = EXT4_SB(inode->i_sb); - - jbd_debug(4, "remove inode %lu from orphan list\n", inode->i_ino); - - list_del_init(&ei->i_orphan); - - /* If we're on an error path, we may not have a valid - * transaction handle with which to update the orphan list on - * disk, but we still need to remove the inode from the linked - * list in memory. */ - if (!handle) - goto out; - - err = ext4_reserve_inode_write(handle, inode, &iloc); - if (err) - goto out_err; - - if (prev == &sbi->s_orphan) { - jbd_debug(4, "superblock will point to %lu\n", ino_next); - BUFFER_TRACE(sbi->s_sbh, "get_write_access"); - err = ext4_journal_get_write_access(handle, sbi->s_sbh); - if (err) - goto out_brelse; - sbi->s_es->s_last_orphan = cpu_to_le32(ino_next); - err = ext4_journal_dirty_metadata(handle, sbi->s_sbh); - } else { - struct ext4_iloc iloc2; - struct inode *i_prev = - &list_entry(prev, struct ext4_inode_info, i_orphan)->vfs_inode; - - jbd_debug(4, "orphan inode %lu will point to %lu\n", - i_prev->i_ino, ino_next); - err = ext4_reserve_inode_write(handle, i_prev, &iloc2); - if (err) - goto out_brelse; - NEXT_ORPHAN(i_prev) = ino_next; - err = ext4_mark_iloc_dirty(handle, i_prev, &iloc2); - } - if (err) - goto out_brelse; - NEXT_ORPHAN(inode) = 0; - err = ext4_mark_iloc_dirty(handle, inode, &iloc); - -out_err: - ext4_std_error(inode->i_sb, err); -out: - unlock_super(inode->i_sb); - return err; - -out_brelse: - brelse(iloc.bh); - goto out_err; -} - -static int ext4_rmdir (struct inode * dir, struct dentry *dentry) -{ - int retval; - struct inode * inode; - struct buffer_head * bh; - struct ext4_dir_entry_2 * de; - handle_t *handle; - - /* Initialize quotas before so that eventual writes go in - * separate transaction */ - DQUOT_INIT(dentry->d_inode); - handle = ext4_journal_start(dir, EXT4_DELETE_TRANS_BLOCKS(dir->i_sb)); - if (IS_ERR(handle)) - return PTR_ERR(handle); - - retval = -ENOENT; - bh = ext4_find_entry (dentry, &de); - if (!bh) - goto end_rmdir; - - if (IS_DIRSYNC(dir)) - handle->h_sync = 1; - - inode = dentry->d_inode; - - retval = -EIO; - if (le32_to_cpu(de->inode) != inode->i_ino) - goto end_rmdir; - - retval = -ENOTEMPTY; - if (!empty_dir (inode)) - goto end_rmdir; - - retval = ext4_delete_entry(handle, dir, de, bh); - if (retval) - goto end_rmdir; - if (inode->i_nlink != 2) - ext4_warning (inode->i_sb, "ext4_rmdir", - "empty directory has nlink!=2 (%d)", - inode->i_nlink); - inode->i_version++; - clear_nlink(inode); - /* There's no need to set i_disksize: the fact that i_nlink is - * zero will ensure that the right thing happens during any - * recovery. */ - inode->i_size = 0; - ext4_orphan_add(handle, inode); - inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC; - ext4_mark_inode_dirty(handle, inode); - drop_nlink(dir); - ext4_update_dx_flag(dir); - ext4_mark_inode_dirty(handle, dir); - -end_rmdir: - ext4_journal_stop(handle); - brelse (bh); - return retval; -} - -static int ext4_unlink(struct inode * dir, struct dentry *dentry) -{ - int retval; - struct inode * inode; - struct buffer_head * bh; - struct ext4_dir_entry_2 * de; - handle_t *handle; - - /* Initialize quotas before so that eventual writes go - * in separate transaction */ - DQUOT_INIT(dentry->d_inode); - handle = ext4_journal_start(dir, EXT4_DELETE_TRANS_BLOCKS(dir->i_sb)); - if (IS_ERR(handle)) - return PTR_ERR(handle); - - if (IS_DIRSYNC(dir)) - handle->h_sync = 1; - - retval = -ENOENT; - bh = ext4_find_entry (dentry, &de); - if (!bh) - goto end_unlink; - - inode = dentry->d_inode; - - retval = -EIO; - if (le32_to_cpu(de->inode) != inode->i_ino) - goto end_unlink; - - if (!inode->i_nlink) { - ext4_warning (inode->i_sb, "ext4_unlink", - "Deleting nonexistent file (%lu), %d", - inode->i_ino, inode->i_nlink); - inode->i_nlink = 1; - } - retval = ext4_delete_entry(handle, dir, de, bh); - if (retval) - goto end_unlink; - dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC; - ext4_update_dx_flag(dir); - ext4_mark_inode_dirty(handle, dir); - drop_nlink(inode); - if (!inode->i_nlink) - ext4_orphan_add(handle, inode); - inode->i_ctime = dir->i_ctime; - ext4_mark_inode_dirty(handle, inode); - retval = 0; - -end_unlink: - ext4_journal_stop(handle); - brelse (bh); - return retval; -} - -static int ext4_symlink (struct inode * dir, - struct dentry *dentry, const char * symname) -{ - handle_t *handle; - struct inode * inode; - int l, err, retries = 0; - - l = strlen(symname)+1; - if (l > dir->i_sb->s_blocksize) - return -ENAMETOOLONG; - -retry: - handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) + - EXT4_INDEX_EXTRA_TRANS_BLOCKS + 5 + - 2*EXT4_QUOTA_INIT_BLOCKS(dir->i_sb)); - if (IS_ERR(handle)) - return PTR_ERR(handle); - - if (IS_DIRSYNC(dir)) - handle->h_sync = 1; - - inode = ext4_new_inode (handle, dir, S_IFLNK|S_IRWXUGO); - err = PTR_ERR(inode); - if (IS_ERR(inode)) - goto out_stop; - - if (l > sizeof (EXT4_I(inode)->i_data)) { - inode->i_op = &ext4_symlink_inode_operations; - ext4_set_aops(inode); - /* - * page_symlink() calls into ext4_prepare/commit_write. - * We have a transaction open. All is sweetness. It also sets - * i_size in generic_commit_write(). - */ - err = __page_symlink(inode, symname, l, - mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS); - if (err) { - ext4_dec_count(handle, inode); - ext4_mark_inode_dirty(handle, inode); - iput (inode); - goto out_stop; - } - } else { - inode->i_op = &ext4_fast_symlink_inode_operations; - memcpy((char*)&EXT4_I(inode)->i_data,symname,l); - inode->i_size = l-1; - } - EXT4_I(inode)->i_disksize = inode->i_size; - err = ext4_add_nondir(handle, dentry, inode); -out_stop: - ext4_journal_stop(handle); - if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries)) - goto retry; - return err; -} - -static int ext4_link (struct dentry * old_dentry, - struct inode * dir, struct dentry *dentry) -{ - handle_t *handle; - struct inode *inode = old_dentry->d_inode; - int err, retries = 0; - - if (inode->i_nlink >= EXT4_LINK_MAX) - return -EMLINK; - -retry: - handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) + - EXT4_INDEX_EXTRA_TRANS_BLOCKS); - if (IS_ERR(handle)) - return PTR_ERR(handle); - - if (IS_DIRSYNC(dir)) - handle->h_sync = 1; - - inode->i_ctime = CURRENT_TIME_SEC; - ext4_inc_count(handle, inode); - atomic_inc(&inode->i_count); - - err = ext4_add_nondir(handle, dentry, inode); - ext4_journal_stop(handle); - if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries)) - goto retry; - return err; -} - -#define PARENT_INO(buffer) \ - ((struct ext4_dir_entry_2 *) ((char *) buffer + \ - le16_to_cpu(((struct ext4_dir_entry_2 *) buffer)->rec_len)))->inode - -/* - * Anybody can rename anything with this: the permission checks are left to the - * higher-level routines. - */ -static int ext4_rename (struct inode * old_dir, struct dentry *old_dentry, - struct inode * new_dir,struct dentry *new_dentry) -{ - handle_t *handle; - struct inode * old_inode, * new_inode; - struct buffer_head * old_bh, * new_bh, * dir_bh; - struct ext4_dir_entry_2 * old_de, * new_de; - int retval; - - old_bh = new_bh = dir_bh = NULL; - - /* Initialize quotas before so that eventual writes go - * in separate transaction */ - if (new_dentry->d_inode) - DQUOT_INIT(new_dentry->d_inode); - handle = ext4_journal_start(old_dir, 2 * - EXT4_DATA_TRANS_BLOCKS(old_dir->i_sb) + - EXT4_INDEX_EXTRA_TRANS_BLOCKS + 2); - if (IS_ERR(handle)) - return PTR_ERR(handle); - - if (IS_DIRSYNC(old_dir) || IS_DIRSYNC(new_dir)) - handle->h_sync = 1; - - old_bh = ext4_find_entry (old_dentry, &old_de); - /* - * Check for inode number is _not_ due to possible IO errors. - * We might rmdir the source, keep it as pwd of some process - * and merrily kill the link to whatever was created under the - * same name. Goodbye sticky bit ;-< - */ - old_inode = old_dentry->d_inode; - retval = -ENOENT; - if (!old_bh || le32_to_cpu(old_de->inode) != old_inode->i_ino) - goto end_rename; - - new_inode = new_dentry->d_inode; - new_bh = ext4_find_entry (new_dentry, &new_de); - if (new_bh) { - if (!new_inode) { - brelse (new_bh); - new_bh = NULL; - } - } - if (S_ISDIR(old_inode->i_mode)) { - if (new_inode) { - retval = -ENOTEMPTY; - if (!empty_dir (new_inode)) - goto end_rename; - } - retval = -EIO; - dir_bh = ext4_bread (handle, old_inode, 0, 0, &retval); - if (!dir_bh) - goto end_rename; - if (le32_to_cpu(PARENT_INO(dir_bh->b_data)) != old_dir->i_ino) - goto end_rename; - retval = -EMLINK; - if (!new_inode && new_dir!=old_dir && - new_dir->i_nlink >= EXT4_LINK_MAX) - goto end_rename; - } - if (!new_bh) { - retval = ext4_add_entry (handle, new_dentry, old_inode); - if (retval) - goto end_rename; - } else { - BUFFER_TRACE(new_bh, "get write access"); - ext4_journal_get_write_access(handle, new_bh); - new_de->inode = cpu_to_le32(old_inode->i_ino); - if (EXT4_HAS_INCOMPAT_FEATURE(new_dir->i_sb, - EXT4_FEATURE_INCOMPAT_FILETYPE)) - new_de->file_type = old_de->file_type; - new_dir->i_version++; - BUFFER_TRACE(new_bh, "call ext4_journal_dirty_metadata"); - ext4_journal_dirty_metadata(handle, new_bh); - brelse(new_bh); - new_bh = NULL; - } - - /* - * Like most other Unix systems, set the ctime for inodes on a - * rename. - */ - old_inode->i_ctime = CURRENT_TIME_SEC; - ext4_mark_inode_dirty(handle, old_inode); - - /* - * ok, that's it - */ - if (le32_to_cpu(old_de->inode) != old_inode->i_ino || - old_de->name_len != old_dentry->d_name.len || - strncmp(old_de->name, old_dentry->d_name.name, old_de->name_len) || - (retval = ext4_delete_entry(handle, old_dir, - old_de, old_bh)) == -ENOENT) { - /* old_de could have moved from under us during htree split, so - * make sure that we are deleting the right entry. We might - * also be pointing to a stale entry in the unused part of - * old_bh so just checking inum and the name isn't enough. */ - struct buffer_head *old_bh2; - struct ext4_dir_entry_2 *old_de2; - - old_bh2 = ext4_find_entry(old_dentry, &old_de2); - if (old_bh2) { - retval = ext4_delete_entry(handle, old_dir, - old_de2, old_bh2); - brelse(old_bh2); - } - } - if (retval) { - ext4_warning(old_dir->i_sb, "ext4_rename", - "Deleting old file (%lu), %d, error=%d", - old_dir->i_ino, old_dir->i_nlink, retval); - } - - if (new_inode) { - drop_nlink(new_inode); - new_inode->i_ctime = CURRENT_TIME_SEC; - } - old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME_SEC; - ext4_update_dx_flag(old_dir); - if (dir_bh) { - BUFFER_TRACE(dir_bh, "get_write_access"); - ext4_journal_get_write_access(handle, dir_bh); - PARENT_INO(dir_bh->b_data) = cpu_to_le32(new_dir->i_ino); - BUFFER_TRACE(dir_bh, "call ext4_journal_dirty_metadata"); - ext4_journal_dirty_metadata(handle, dir_bh); - drop_nlink(old_dir); - if (new_inode) { - drop_nlink(new_inode); - } else { - inc_nlink(new_dir); - ext4_update_dx_flag(new_dir); - ext4_mark_inode_dirty(handle, new_dir); - } - } - ext4_mark_inode_dirty(handle, old_dir); - if (new_inode) { - ext4_mark_inode_dirty(handle, new_inode); - if (!new_inode->i_nlink) - ext4_orphan_add(handle, new_inode); - } - retval = 0; - -end_rename: - brelse (dir_bh); - brelse (old_bh); - brelse (new_bh); - ext4_journal_stop(handle); - return retval; -} - -/* - * directories can handle most operations... - */ -struct inode_operations ext4_dir_inode_operations = { - .create = ext4_create, - .lookup = ext4_lookup, - .link = ext4_link, - .unlink = ext4_unlink, - .symlink = ext4_symlink, - .mkdir = ext4_mkdir, - .rmdir = ext4_rmdir, - .mknod = ext4_mknod, - .rename = ext4_rename, - .setattr = ext4_setattr, -#ifdef CONFIG_EXT4DEV_FS_XATTR - .setxattr = generic_setxattr, - .getxattr = generic_getxattr, - .listxattr = ext4_listxattr, - .removexattr = generic_removexattr, -#endif - .permission = ext4_permission, -}; - -struct inode_operations ext4_special_inode_operations = { - .setattr = ext4_setattr, -#ifdef CONFIG_EXT4DEV_FS_XATTR - .setxattr = generic_setxattr, - .getxattr = generic_getxattr, - .listxattr = ext4_listxattr, - .removexattr = generic_removexattr, -#endif - .permission = ext4_permission, -}; diff --git a/trunk/fs/ext4/namei.h b/trunk/fs/ext4/namei.h deleted file mode 100644 index 5e4dfff36a00..000000000000 --- a/trunk/fs/ext4/namei.h +++ /dev/null @@ -1,8 +0,0 @@ -/* linux/fs/ext4/namei.h - * - * Copyright (C) 2005 Simtec Electronics - * Ben Dooks - * -*/ - -extern struct dentry *ext4_get_parent(struct dentry *child); diff --git a/trunk/fs/ext4/resize.c b/trunk/fs/ext4/resize.c deleted file mode 100644 index 4fe49c3661b2..000000000000 --- a/trunk/fs/ext4/resize.c +++ /dev/null @@ -1,1050 +0,0 @@ -/* - * linux/fs/ext4/resize.c - * - * Support for resizing an ext4 filesystem while it is mounted. - * - * Copyright (C) 2001, 2002 Andreas Dilger - * - * This could probably be made into a module, because it is not often in use. - */ - - -#define EXT4FS_DEBUG - -#include -#include -#include - -#include -#include - - -#define outside(b, first, last) ((b) < (first) || (b) >= (last)) -#define inside(b, first, last) ((b) >= (first) && (b) < (last)) - -static int verify_group_input(struct super_block *sb, - struct ext4_new_group_data *input) -{ - struct ext4_sb_info *sbi = EXT4_SB(sb); - struct ext4_super_block *es = sbi->s_es; - ext4_fsblk_t start = ext4_blocks_count(es); - ext4_fsblk_t end = start + input->blocks_count; - unsigned group = input->group; - ext4_fsblk_t itend = input->inode_table + sbi->s_itb_per_group; - unsigned overhead = ext4_bg_has_super(sb, group) ? - (1 + ext4_bg_num_gdb(sb, group) + - le16_to_cpu(es->s_reserved_gdt_blocks)) : 0; - ext4_fsblk_t metaend = start + overhead; - struct buffer_head *bh = NULL; - ext4_grpblk_t free_blocks_count, offset; - int err = -EINVAL; - - input->free_blocks_count = free_blocks_count = - input->blocks_count - 2 - overhead - sbi->s_itb_per_group; - - if (test_opt(sb, DEBUG)) - printk(KERN_DEBUG "EXT4-fs: adding %s group %u: %u blocks " - "(%d free, %u reserved)\n", - ext4_bg_has_super(sb, input->group) ? "normal" : - "no-super", input->group, input->blocks_count, - free_blocks_count, input->reserved_blocks); - - ext4_get_group_no_and_offset(sb, start, NULL, &offset); - if (group != sbi->s_groups_count) - ext4_warning(sb, __FUNCTION__, - "Cannot add at group %u (only %lu groups)", - input->group, sbi->s_groups_count); - else if (offset != 0) - ext4_warning(sb, __FUNCTION__, "Last group not full"); - else if (input->reserved_blocks > input->blocks_count / 5) - ext4_warning(sb, __FUNCTION__, "Reserved blocks too high (%u)", - input->reserved_blocks); - else if (free_blocks_count < 0) - ext4_warning(sb, __FUNCTION__, "Bad blocks count %u", - input->blocks_count); - else if (!(bh = sb_bread(sb, end - 1))) - ext4_warning(sb, __FUNCTION__, - "Cannot read last block (%llu)", - end - 1); - else if (outside(input->block_bitmap, start, end)) - ext4_warning(sb, __FUNCTION__, - "Block bitmap not in group (block %llu)", - (unsigned long long)input->block_bitmap); - else if (outside(input->inode_bitmap, start, end)) - ext4_warning(sb, __FUNCTION__, - "Inode bitmap not in group (block %llu)", - (unsigned long long)input->inode_bitmap); - else if (outside(input->inode_table, start, end) || - outside(itend - 1, start, end)) - ext4_warning(sb, __FUNCTION__, - "Inode table not in group (blocks %llu-%llu)", - (unsigned long long)input->inode_table, itend - 1); - else if (input->inode_bitmap == input->block_bitmap) - ext4_warning(sb, __FUNCTION__, - "Block bitmap same as inode bitmap (%llu)", - (unsigned long long)input->block_bitmap); - else if (inside(input->block_bitmap, input->inode_table, itend)) - ext4_warning(sb, __FUNCTION__, - "Block bitmap (%llu) in inode table (%llu-%llu)", - (unsigned long long)input->block_bitmap, - (unsigned long long)input->inode_table, itend - 1); - else if (inside(input->inode_bitmap, input->inode_table, itend)) - ext4_warning(sb, __FUNCTION__, - "Inode bitmap (%llu) in inode table (%llu-%llu)", - (unsigned long long)input->inode_bitmap, - (unsigned long long)input->inode_table, itend - 1); - else if (inside(input->block_bitmap, start, metaend)) - ext4_warning(sb, __FUNCTION__, - "Block bitmap (%llu) in GDT table" - " (%llu-%llu)", - (unsigned long long)input->block_bitmap, - start, metaend - 1); - else if (inside(input->inode_bitmap, start, metaend)) - ext4_warning(sb, __FUNCTION__, - "Inode bitmap (%llu) in GDT table" - " (%llu-%llu)", - (unsigned long long)input->inode_bitmap, - start, metaend - 1); - else if (inside(input->inode_table, start, metaend) || - inside(itend - 1, start, metaend)) - ext4_warning(sb, __FUNCTION__, - "Inode table (%llu-%llu) overlaps" - "GDT table (%llu-%llu)", - (unsigned long long)input->inode_table, - itend - 1, start, metaend - 1); - else - err = 0; - brelse(bh); - - return err; -} - -static struct buffer_head *bclean(handle_t *handle, struct super_block *sb, - ext4_fsblk_t blk) -{ - struct buffer_head *bh; - int err; - - bh = sb_getblk(sb, blk); - if (!bh) - return ERR_PTR(-EIO); - if ((err = ext4_journal_get_write_access(handle, bh))) { - brelse(bh); - bh = ERR_PTR(err); - } else { - lock_buffer(bh); - memset(bh->b_data, 0, sb->s_blocksize); - set_buffer_uptodate(bh); - unlock_buffer(bh); - } - - return bh; -} - -/* - * To avoid calling the atomic setbit hundreds or thousands of times, we only - * need to use it within a single byte (to ensure we get endianness right). - * We can use memset for the rest of the bitmap as there are no other users. - */ -static void mark_bitmap_end(int start_bit, int end_bit, char *bitmap) -{ - int i; - - if (start_bit >= end_bit) - return; - - ext4_debug("mark end bits +%d through +%d used\n", start_bit, end_bit); - for (i = start_bit; i < ((start_bit + 7) & ~7UL); i++) - ext4_set_bit(i, bitmap); - if (i < end_bit) - memset(bitmap + (i >> 3), 0xff, (end_bit - i) >> 3); -} - -/* - * Set up the block and inode bitmaps, and the inode table for the new group. - * This doesn't need to be part of the main transaction, since we are only - * changing blocks outside the actual filesystem. We still do journaling to - * ensure the recovery is correct in case of a failure just after resize. - * If any part of this fails, we simply abort the resize. - */ -static int setup_new_group_blocks(struct super_block *sb, - struct ext4_new_group_data *input) -{ - struct ext4_sb_info *sbi = EXT4_SB(sb); - ext4_fsblk_t start = ext4_group_first_block_no(sb, input->group); - int reserved_gdb = ext4_bg_has_super(sb, input->group) ? - le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks) : 0; - unsigned long gdblocks = ext4_bg_num_gdb(sb, input->group); - struct buffer_head *bh; - handle_t *handle; - ext4_fsblk_t block; - ext4_grpblk_t bit; - int i; - int err = 0, err2; - - handle = ext4_journal_start_sb(sb, reserved_gdb + gdblocks + - 2 + sbi->s_itb_per_group); - if (IS_ERR(handle)) - return PTR_ERR(handle); - - lock_super(sb); - if (input->group != sbi->s_groups_count) { - err = -EBUSY; - goto exit_journal; - } - - if (IS_ERR(bh = bclean(handle, sb, input->block_bitmap))) { - err = PTR_ERR(bh); - goto exit_journal; - } - - if (ext4_bg_has_super(sb, input->group)) { - ext4_debug("mark backup superblock %#04lx (+0)\n", start); - ext4_set_bit(0, bh->b_data); - } - - /* Copy all of the GDT blocks into the backup in this group */ - for (i = 0, bit = 1, block = start + 1; - i < gdblocks; i++, block++, bit++) { - struct buffer_head *gdb; - - ext4_debug("update backup group %#04lx (+%d)\n", block, bit); - - gdb = sb_getblk(sb, block); - if (!gdb) { - err = -EIO; - goto exit_bh; - } - if ((err = ext4_journal_get_write_access(handle, gdb))) { - brelse(gdb); - goto exit_bh; - } - lock_buffer(bh); - memcpy(gdb->b_data, sbi->s_group_desc[i]->b_data, bh->b_size); - set_buffer_uptodate(gdb); - unlock_buffer(bh); - ext4_journal_dirty_metadata(handle, gdb); - ext4_set_bit(bit, bh->b_data); - brelse(gdb); - } - - /* Zero out all of the reserved backup group descriptor table blocks */ - for (i = 0, bit = gdblocks + 1, block = start + bit; - i < reserved_gdb; i++, block++, bit++) { - struct buffer_head *gdb; - - ext4_debug("clear reserved block %#04lx (+%d)\n", block, bit); - - if (IS_ERR(gdb = bclean(handle, sb, block))) { - err = PTR_ERR(bh); - goto exit_bh; - } - ext4_journal_dirty_metadata(handle, gdb); - ext4_set_bit(bit, bh->b_data); - brelse(gdb); - } - ext4_debug("mark block bitmap %#04x (+%ld)\n", input->block_bitmap, - input->block_bitmap - start); - ext4_set_bit(input->block_bitmap - start, bh->b_data); - ext4_debug("mark inode bitmap %#04x (+%ld)\n", input->inode_bitmap, - input->inode_bitmap - start); - ext4_set_bit(input->inode_bitmap - start, bh->b_data); - - /* Zero out all of the inode table blocks */ - for (i = 0, block = input->inode_table, bit = block - start; - i < sbi->s_itb_per_group; i++, bit++, block++) { - struct buffer_head *it; - - ext4_debug("clear inode block %#04lx (+%d)\n", block, bit); - if (IS_ERR(it = bclean(handle, sb, block))) { - err = PTR_ERR(it); - goto exit_bh; - } - ext4_journal_dirty_metadata(handle, it); - brelse(it); - ext4_set_bit(bit, bh->b_data); - } - mark_bitmap_end(input->blocks_count, EXT4_BLOCKS_PER_GROUP(sb), - bh->b_data); - ext4_journal_dirty_metadata(handle, bh); - brelse(bh); - - /* Mark unused entries in inode bitmap used */ - ext4_debug("clear inode bitmap %#04x (+%ld)\n", - input->inode_bitmap, input->inode_bitmap - start); - if (IS_ERR(bh = bclean(handle, sb, input->inode_bitmap))) { - err = PTR_ERR(bh); - goto exit_journal; - } - - mark_bitmap_end(EXT4_INODES_PER_GROUP(sb), EXT4_BLOCKS_PER_GROUP(sb), - bh->b_data); - ext4_journal_dirty_metadata(handle, bh); -exit_bh: - brelse(bh); - -exit_journal: - unlock_super(sb); - if ((err2 = ext4_journal_stop(handle)) && !err) - err = err2; - - return err; -} - - -/* - * Iterate through the groups which hold BACKUP superblock/GDT copies in an - * ext4 filesystem. The counters should be initialized to 1, 5, and 7 before - * calling this for the first time. In a sparse filesystem it will be the - * sequence of powers of 3, 5, and 7: 1, 3, 5, 7, 9, 25, 27, 49, 81, ... - * For a non-sparse filesystem it will be every group: 1, 2, 3, 4, ... - */ -static unsigned ext4_list_backups(struct super_block *sb, unsigned *three, - unsigned *five, unsigned *seven) -{ - unsigned *min = three; - int mult = 3; - unsigned ret; - - if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, - EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER)) { - ret = *min; - *min += 1; - return ret; - } - - if (*five < *min) { - min = five; - mult = 5; - } - if (*seven < *min) { - min = seven; - mult = 7; - } - - ret = *min; - *min *= mult; - - return ret; -} - -/* - * Check that all of the backup GDT blocks are held in the primary GDT block. - * It is assumed that they are stored in group order. Returns the number of - * groups in current filesystem that have BACKUPS, or -ve error code. - */ -static int verify_reserved_gdb(struct super_block *sb, - struct buffer_head *primary) -{ - const ext4_fsblk_t blk = primary->b_blocknr; - const unsigned long end = EXT4_SB(sb)->s_groups_count; - unsigned three = 1; - unsigned five = 5; - unsigned seven = 7; - unsigned grp; - __le32 *p = (__le32 *)primary->b_data; - int gdbackups = 0; - - while ((grp = ext4_list_backups(sb, &three, &five, &seven)) < end) { - if (le32_to_cpu(*p++) != - grp * EXT4_BLOCKS_PER_GROUP(sb) + blk){ - ext4_warning(sb, __FUNCTION__, - "reserved GDT %llu" - " missing grp %d (%llu)", - blk, grp, - grp * - (ext4_fsblk_t)EXT4_BLOCKS_PER_GROUP(sb) + - blk); - return -EINVAL; - } - if (++gdbackups > EXT4_ADDR_PER_BLOCK(sb)) - return -EFBIG; - } - - return gdbackups; -} - -/* - * Called when we need to bring a reserved group descriptor table block into - * use from the resize inode. The primary copy of the new GDT block currently - * is an indirect block (under the double indirect block in the resize inode). - * The new backup GDT blocks will be stored as leaf blocks in this indirect - * block, in group order. Even though we know all the block numbers we need, - * we check to ensure that the resize inode has actually reserved these blocks. - * - * Don't need to update the block bitmaps because the blocks are still in use. - * - * We get all of the error cases out of the way, so that we are sure to not - * fail once we start modifying the data on disk, because JBD has no rollback. - */ -static int add_new_gdb(handle_t *handle, struct inode *inode, - struct ext4_new_group_data *input, - struct buffer_head **primary) -{ - struct super_block *sb = inode->i_sb; - struct ext4_super_block *es = EXT4_SB(sb)->s_es; - unsigned long gdb_num = input->group / EXT4_DESC_PER_BLOCK(sb); - ext4_fsblk_t gdblock = EXT4_SB(sb)->s_sbh->b_blocknr + 1 + gdb_num; - struct buffer_head **o_group_desc, **n_group_desc; - struct buffer_head *dind; - int gdbackups; - struct ext4_iloc iloc; - __le32 *data; - int err; - - if (test_opt(sb, DEBUG)) - printk(KERN_DEBUG - "EXT4-fs: ext4_add_new_gdb: adding group block %lu\n", - gdb_num); - - /* - * If we are not using the primary superblock/GDT copy don't resize, - * because the user tools have no way of handling this. Probably a - * bad time to do it anyways. - */ - if (EXT4_SB(sb)->s_sbh->b_blocknr != - le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block)) { - ext4_warning(sb, __FUNCTION__, - "won't resize using backup superblock at %llu", - (unsigned long long)EXT4_SB(sb)->s_sbh->b_blocknr); - return -EPERM; - } - - *primary = sb_bread(sb, gdblock); - if (!*primary) - return -EIO; - - if ((gdbackups = verify_reserved_gdb(sb, *primary)) < 0) { - err = gdbackups; - goto exit_bh; - } - - data = EXT4_I(inode)->i_data + EXT4_DIND_BLOCK; - dind = sb_bread(sb, le32_to_cpu(*data)); - if (!dind) { - err = -EIO; - goto exit_bh; - } - - data = (__le32 *)dind->b_data; - if (le32_to_cpu(data[gdb_num % EXT4_ADDR_PER_BLOCK(sb)]) != gdblock) { - ext4_warning(sb, __FUNCTION__, - "new group %u GDT block %llu not reserved", - input->group, gdblock); - err = -EINVAL; - goto exit_dind; - } - - if ((err = ext4_journal_get_write_access(handle, EXT4_SB(sb)->s_sbh))) - goto exit_dind; - - if ((err = ext4_journal_get_write_access(handle, *primary))) - goto exit_sbh; - - if ((err = ext4_journal_get_write_access(handle, dind))) - goto exit_primary; - - /* ext4_reserve_inode_write() gets a reference on the iloc */ - if ((err = ext4_reserve_inode_write(handle, inode, &iloc))) - goto exit_dindj; - - n_group_desc = kmalloc((gdb_num + 1) * sizeof(struct buffer_head *), - GFP_KERNEL); - if (!n_group_desc) { - err = -ENOMEM; - ext4_warning (sb, __FUNCTION__, - "not enough memory for %lu groups", gdb_num + 1); - goto exit_inode; - } - - /* - * Finally, we have all of the possible failures behind us... - * - * Remove new GDT block from inode double-indirect block and clear out - * the new GDT block for use (which also "frees" the backup GDT blocks - * from the reserved inode). We don't need to change the bitmaps for - * these blocks, because they are marked as in-use from being in the - * reserved inode, and will become GDT blocks (primary and backup). - */ - data[gdb_num % EXT4_ADDR_PER_BLOCK(sb)] = 0; - ext4_journal_dirty_metadata(handle, dind); - brelse(dind); - inode->i_blocks -= (gdbackups + 1) * sb->s_blocksize >> 9; - ext4_mark_iloc_dirty(handle, inode, &iloc); - memset((*primary)->b_data, 0, sb->s_blocksize); - ext4_journal_dirty_metadata(handle, *primary); - - o_group_desc = EXT4_SB(sb)->s_group_desc; - memcpy(n_group_desc, o_group_desc, - EXT4_SB(sb)->s_gdb_count * sizeof(struct buffer_head *)); - n_group_desc[gdb_num] = *primary; - EXT4_SB(sb)->s_group_desc = n_group_desc; - EXT4_SB(sb)->s_gdb_count++; - kfree(o_group_desc); - - es->s_reserved_gdt_blocks = - cpu_to_le16(le16_to_cpu(es->s_reserved_gdt_blocks) - 1); - ext4_journal_dirty_metadata(handle, EXT4_SB(sb)->s_sbh); - - return 0; - -exit_inode: - //ext4_journal_release_buffer(handle, iloc.bh); - brelse(iloc.bh); -exit_dindj: - //ext4_journal_release_buffer(handle, dind); -exit_primary: - //ext4_journal_release_buffer(handle, *primary); -exit_sbh: - //ext4_journal_release_buffer(handle, *primary); -exit_dind: - brelse(dind); -exit_bh: - brelse(*primary); - - ext4_debug("leaving with error %d\n", err); - return err; -} - -/* - * Called when we are adding a new group which has a backup copy of each of - * the GDT blocks (i.e. sparse group) and there are reserved GDT blocks. - * We need to add these reserved backup GDT blocks to the resize inode, so - * that they are kept for future resizing and not allocated to files. - * - * Each reserved backup GDT block will go into a different indirect block. - * The indirect blocks are actually the primary reserved GDT blocks, - * so we know in advance what their block numbers are. We only get the - * double-indirect block to verify it is pointing to the primary reserved - * GDT blocks so we don't overwrite a data block by accident. The reserved - * backup GDT blocks are stored in their reserved primary GDT block. - */ -static int reserve_backup_gdb(handle_t *handle, struct inode *inode, - struct ext4_new_group_data *input) -{ - struct super_block *sb = inode->i_sb; - int reserved_gdb =le16_to_cpu(EXT4_SB(sb)->s_es->s_reserved_gdt_blocks); - struct buffer_head **primary; - struct buffer_head *dind; - struct ext4_iloc iloc; - ext4_fsblk_t blk; - __le32 *data, *end; - int gdbackups = 0; - int res, i; - int err; - - primary = kmalloc(reserved_gdb * sizeof(*primary), GFP_KERNEL); - if (!primary) - return -ENOMEM; - - data = EXT4_I(inode)->i_data + EXT4_DIND_BLOCK; - dind = sb_bread(sb, le32_to_cpu(*data)); - if (!dind) { - err = -EIO; - goto exit_free; - } - - blk = EXT4_SB(sb)->s_sbh->b_blocknr + 1 + EXT4_SB(sb)->s_gdb_count; - data = (__le32 *)dind->b_data + EXT4_SB(sb)->s_gdb_count; - end = (__le32 *)dind->b_data + EXT4_ADDR_PER_BLOCK(sb); - - /* Get each reserved primary GDT block and verify it holds backups */ - for (res = 0; res < reserved_gdb; res++, blk++) { - if (le32_to_cpu(*data) != blk) { - ext4_warning(sb, __FUNCTION__, - "reserved block %llu" - " not at offset %ld", - blk, - (long)(data - (__le32 *)dind->b_data)); - err = -EINVAL; - goto exit_bh; - } - primary[res] = sb_bread(sb, blk); - if (!primary[res]) { - err = -EIO; - goto exit_bh; - } - if ((gdbackups = verify_reserved_gdb(sb, primary[res])) < 0) { - brelse(primary[res]); - err = gdbackups; - goto exit_bh; - } - if (++data >= end) - data = (__le32 *)dind->b_data; - } - - for (i = 0; i < reserved_gdb; i++) { - if ((err = ext4_journal_get_write_access(handle, primary[i]))) { - /* - int j; - for (j = 0; j < i; j++) - ext4_journal_release_buffer(handle, primary[j]); - */ - goto exit_bh; - } - } - - if ((err = ext4_reserve_inode_write(handle, inode, &iloc))) - goto exit_bh; - - /* - * Finally we can add each of the reserved backup GDT blocks from - * the new group to its reserved primary GDT block. - */ - blk = input->group * EXT4_BLOCKS_PER_GROUP(sb); - for (i = 0; i < reserved_gdb; i++) { - int err2; - data = (__le32 *)primary[i]->b_data; - /* printk("reserving backup %lu[%u] = %lu\n", - primary[i]->b_blocknr, gdbackups, - blk + primary[i]->b_blocknr); */ - data[gdbackups] = cpu_to_le32(blk + primary[i]->b_blocknr); - err2 = ext4_journal_dirty_metadata(handle, primary[i]); - if (!err) - err = err2; - } - inode->i_blocks += reserved_gdb * sb->s_blocksize >> 9; - ext4_mark_iloc_dirty(handle, inode, &iloc); - -exit_bh: - while (--res >= 0) - brelse(primary[res]); - brelse(dind); - -exit_free: - kfree(primary); - - return err; -} - -/* - * Update the backup copies of the ext4 metadata. These don't need to be part - * of the main resize transaction, because e2fsck will re-write them if there - * is a problem (basically only OOM will cause a problem). However, we - * _should_ update the backups if possible, in case the primary gets trashed - * for some reason and we need to run e2fsck from a backup superblock. The - * important part is that the new block and inode counts are in the backup - * superblocks, and the location of the new group metadata in the GDT backups. - * - * We do not need lock_super() for this, because these blocks are not - * otherwise touched by the filesystem code when it is mounted. We don't - * need to worry about last changing from sbi->s_groups_count, because the - * worst that can happen is that we do not copy the full number of backups - * at this time. The resize which changed s_groups_count will backup again. - */ -static void update_backups(struct super_block *sb, - int blk_off, char *data, int size) -{ - struct ext4_sb_info *sbi = EXT4_SB(sb); - const unsigned long last = sbi->s_groups_count; - const int bpg = EXT4_BLOCKS_PER_GROUP(sb); - unsigned three = 1; - unsigned five = 5; - unsigned seven = 7; - unsigned group; - int rest = sb->s_blocksize - size; - handle_t *handle; - int err = 0, err2; - - handle = ext4_journal_start_sb(sb, EXT4_MAX_TRANS_DATA); - if (IS_ERR(handle)) { - group = 1; - err = PTR_ERR(handle); - goto exit_err; - } - - while ((group = ext4_list_backups(sb, &three, &five, &seven)) < last) { - struct buffer_head *bh; - - /* Out of journal space, and can't get more - abort - so sad */ - if (handle->h_buffer_credits == 0 && - ext4_journal_extend(handle, EXT4_MAX_TRANS_DATA) && - (err = ext4_journal_restart(handle, EXT4_MAX_TRANS_DATA))) - break; - - bh = sb_getblk(sb, group * bpg + blk_off); - if (!bh) { - err = -EIO; - break; - } - ext4_debug("update metadata backup %#04lx\n", - (unsigned long)bh->b_blocknr); - if ((err = ext4_journal_get_write_access(handle, bh))) - break; - lock_buffer(bh); - memcpy(bh->b_data, data, size); - if (rest) - memset(bh->b_data + size, 0, rest); - set_buffer_uptodate(bh); - unlock_buffer(bh); - ext4_journal_dirty_metadata(handle, bh); - brelse(bh); - } - if ((err2 = ext4_journal_stop(handle)) && !err) - err = err2; - - /* - * Ugh! Need to have e2fsck write the backup copies. It is too - * late to revert the resize, we shouldn't fail just because of - * the backup copies (they are only needed in case of corruption). - * - * However, if we got here we have a journal problem too, so we - * can't really start a transaction to mark the superblock. - * Chicken out and just set the flag on the hope it will be written - * to disk, and if not - we will simply wait until next fsck. - */ -exit_err: - if (err) { - ext4_warning(sb, __FUNCTION__, - "can't update backup for group %d (err %d), " - "forcing fsck on next reboot", group, err); - sbi->s_mount_state &= ~EXT4_VALID_FS; - sbi->s_es->s_state &= cpu_to_le16(~EXT4_VALID_FS); - mark_buffer_dirty(sbi->s_sbh); - } -} - -/* Add group descriptor data to an existing or new group descriptor block. - * Ensure we handle all possible error conditions _before_ we start modifying - * the filesystem, because we cannot abort the transaction and not have it - * write the data to disk. - * - * If we are on a GDT block boundary, we need to get the reserved GDT block. - * Otherwise, we may need to add backup GDT blocks for a sparse group. - * - * We only need to hold the superblock lock while we are actually adding - * in the new group's counts to the superblock. Prior to that we have - * not really "added" the group at all. We re-check that we are still - * adding in the last group in case things have changed since verifying. - */ -int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input) -{ - struct ext4_sb_info *sbi = EXT4_SB(sb); - struct ext4_super_block *es = sbi->s_es; - int reserved_gdb = ext4_bg_has_super(sb, input->group) ? - le16_to_cpu(es->s_reserved_gdt_blocks) : 0; - struct buffer_head *primary = NULL; - struct ext4_group_desc *gdp; - struct inode *inode = NULL; - handle_t *handle; - int gdb_off, gdb_num; - int err, err2; - - gdb_num = input->group / EXT4_DESC_PER_BLOCK(sb); - gdb_off = input->group % EXT4_DESC_PER_BLOCK(sb); - - if (gdb_off == 0 && !EXT4_HAS_RO_COMPAT_FEATURE(sb, - EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER)) { - ext4_warning(sb, __FUNCTION__, - "Can't resize non-sparse filesystem further"); - return -EPERM; - } - - if (ext4_blocks_count(es) + input->blocks_count < - ext4_blocks_count(es)) { - ext4_warning(sb, __FUNCTION__, "blocks_count overflow\n"); - return -EINVAL; - } - - if (le32_to_cpu(es->s_inodes_count) + EXT4_INODES_PER_GROUP(sb) < - le32_to_cpu(es->s_inodes_count)) { - ext4_warning(sb, __FUNCTION__, "inodes_count overflow\n"); - return -EINVAL; - } - - if (reserved_gdb || gdb_off == 0) { - if (!EXT4_HAS_COMPAT_FEATURE(sb, - EXT4_FEATURE_COMPAT_RESIZE_INODE)){ - ext4_warning(sb, __FUNCTION__, - "No reserved GDT blocks, can't resize"); - return -EPERM; - } - inode = iget(sb, EXT4_RESIZE_INO); - if (!inode || is_bad_inode(inode)) { - ext4_warning(sb, __FUNCTION__, - "Error opening resize inode"); - iput(inode); - return -ENOENT; - } - } - - if ((err = verify_group_input(sb, input))) - goto exit_put; - - if ((err = setup_new_group_blocks(sb, input))) - goto exit_put; - - /* - * We will always be modifying at least the superblock and a GDT - * block. If we are adding a group past the last current GDT block, - * we will also modify the inode and the dindirect block. If we - * are adding a group with superblock/GDT backups we will also - * modify each of the reserved GDT dindirect blocks. - */ - handle = ext4_journal_start_sb(sb, - ext4_bg_has_super(sb, input->group) ? - 3 + reserved_gdb : 4); - if (IS_ERR(handle)) { - err = PTR_ERR(handle); - goto exit_put; - } - - lock_super(sb); - if (input->group != sbi->s_groups_count) { - ext4_warning(sb, __FUNCTION__, - "multiple resizers run on filesystem!"); - err = -EBUSY; - goto exit_journal; - } - - if ((err = ext4_journal_get_write_access(handle, sbi->s_sbh))) - goto exit_journal; - - /* - * We will only either add reserved group blocks to a backup group - * or remove reserved blocks for the first group in a new group block. - * Doing both would be mean more complex code, and sane people don't - * use non-sparse filesystems anymore. This is already checked above. - */ - if (gdb_off) { - primary = sbi->s_group_desc[gdb_num]; - if ((err = ext4_journal_get_write_access(handle, primary))) - goto exit_journal; - - if (reserved_gdb && ext4_bg_num_gdb(sb, input->group) && - (err = reserve_backup_gdb(handle, inode, input))) - goto exit_journal; - } else if ((err = add_new_gdb(handle, inode, input, &primary))) - goto exit_journal; - - /* - * OK, now we've set up the new group. Time to make it active. - * - * Current kernels don't lock all allocations via lock_super(), - * so we have to be safe wrt. concurrent accesses the group - * data. So we need to be careful to set all of the relevant - * group descriptor data etc. *before* we enable the group. - * - * The key field here is sbi->s_groups_count: as long as - * that retains its old value, nobody is going to access the new - * group. - * - * So first we update all the descriptor metadata for the new - * group; then we update the total disk blocks count; then we - * update the groups count to enable the group; then finally we - * update the free space counts so that the system can start - * using the new disk blocks. - */ - - /* Update group descriptor block for new group */ - gdp = (struct ext4_group_desc *)primary->b_data + gdb_off; - - ext4_block_bitmap_set(sb, gdp, input->block_bitmap); /* LV FIXME */ - ext4_inode_bitmap_set(sb, gdp, input->inode_bitmap); /* LV FIXME */ - ext4_inode_table_set(sb, gdp, input->inode_table); /* LV FIXME */ - gdp->bg_free_blocks_count = cpu_to_le16(input->free_blocks_count); - gdp->bg_free_inodes_count = cpu_to_le16(EXT4_INODES_PER_GROUP(sb)); - - /* - * Make the new blocks and inodes valid next. We do this before - * increasing the group count so that once the group is enabled, - * all of its blocks and inodes are already valid. - * - * We always allocate group-by-group, then block-by-block or - * inode-by-inode within a group, so enabling these - * blocks/inodes before the group is live won't actually let us - * allocate the new space yet. - */ - ext4_blocks_count_set(es, ext4_blocks_count(es) + - input->blocks_count); - es->s_inodes_count = cpu_to_le32(le32_to_cpu(es->s_inodes_count) + - EXT4_INODES_PER_GROUP(sb)); - - /* - * We need to protect s_groups_count against other CPUs seeing - * inconsistent state in the superblock. - * - * The precise rules we use are: - * - * * Writers of s_groups_count *must* hold lock_super - * AND - * * Writers must perform a smp_wmb() after updating all dependent - * data and before modifying the groups count - * - * * Readers must hold lock_super() over the access - * OR - * * Readers must perform an smp_rmb() after reading the groups count - * and before reading any dependent data. - * - * NB. These rules can be relaxed when checking the group count - * while freeing data, as we can only allocate from a block - * group after serialising against the group count, and we can - * only then free after serialising in turn against that - * allocation. - */ - smp_wmb(); - - /* Update the global fs size fields */ - sbi->s_groups_count++; - - ext4_journal_dirty_metadata(handle, primary); - - /* Update the reserved block counts only once the new group is - * active. */ - ext4_r_blocks_count_set(es, ext4_r_blocks_count(es) + - input->reserved_blocks); - - /* Update the free space counts */ - percpu_counter_mod(&sbi->s_freeblocks_counter, - input->free_blocks_count); - percpu_counter_mod(&sbi->s_freeinodes_counter, - EXT4_INODES_PER_GROUP(sb)); - - ext4_journal_dirty_metadata(handle, sbi->s_sbh); - sb->s_dirt = 1; - -exit_journal: - unlock_super(sb); - if ((err2 = ext4_journal_stop(handle)) && !err) - err = err2; - if (!err) { - update_backups(sb, sbi->s_sbh->b_blocknr, (char *)es, - sizeof(struct ext4_super_block)); - update_backups(sb, primary->b_blocknr, primary->b_data, - primary->b_size); - } -exit_put: - iput(inode); - return err; -} /* ext4_group_add */ - -/* Extend the filesystem to the new number of blocks specified. This entry - * point is only used to extend the current filesystem to the end of the last - * existing group. It can be accessed via ioctl, or by "remount,resize=" - * for emergencies (because it has no dependencies on reserved blocks). - * - * If we _really_ wanted, we could use default values to call ext4_group_add() - * allow the "remount" trick to work for arbitrary resizing, assuming enough - * GDT blocks are reserved to grow to the desired size. - */ -int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es, - ext4_fsblk_t n_blocks_count) -{ - ext4_fsblk_t o_blocks_count; - unsigned long o_groups_count; - ext4_grpblk_t last; - ext4_grpblk_t add; - struct buffer_head * bh; - handle_t *handle; - int err; - unsigned long freed_blocks; - - /* We don't need to worry about locking wrt other resizers just - * yet: we're going to revalidate es->s_blocks_count after - * taking lock_super() below. */ - o_blocks_count = ext4_blocks_count(es); - o_groups_count = EXT4_SB(sb)->s_groups_count; - - if (test_opt(sb, DEBUG)) - printk(KERN_DEBUG "EXT4-fs: extending last group from %llu uto %llu blocks\n", - o_blocks_count, n_blocks_count); - - if (n_blocks_count == 0 || n_blocks_count == o_blocks_count) - return 0; - - if (n_blocks_count > (sector_t)(~0ULL) >> (sb->s_blocksize_bits - 9)) { - printk(KERN_ERR "EXT4-fs: filesystem on %s:" - " too large to resize to %llu blocks safely\n", - sb->s_id, n_blocks_count); - if (sizeof(sector_t) < 8) - ext4_warning(sb, __FUNCTION__, - "CONFIG_LBD not enabled\n"); - return -EINVAL; - } - - if (n_blocks_count < o_blocks_count) { - ext4_warning(sb, __FUNCTION__, - "can't shrink FS - resize aborted"); - return -EBUSY; - } - - /* Handle the remaining blocks in the last group only. */ - ext4_get_group_no_and_offset(sb, o_blocks_count, NULL, &last); - - if (last == 0) { - ext4_warning(sb, __FUNCTION__, - "need to use ext2online to resize further"); - return -EPERM; - } - - add = EXT4_BLOCKS_PER_GROUP(sb) - last; - - if (o_blocks_count + add < o_blocks_count) { - ext4_warning(sb, __FUNCTION__, "blocks_count overflow"); - return -EINVAL; - } - - if (o_blocks_count + add > n_blocks_count) - add = n_blocks_count - o_blocks_count; - - if (o_blocks_count + add < n_blocks_count) - ext4_warning(sb, __FUNCTION__, - "will only finish group (%llu" - " blocks, %u new)", - o_blocks_count + add, add); - - /* See if the device is actually as big as what was requested */ - bh = sb_bread(sb, o_blocks_count + add -1); - if (!bh) { - ext4_warning(sb, __FUNCTION__, - "can't read last block, resize aborted"); - return -ENOSPC; - } - brelse(bh); - - /* We will update the superblock, one block bitmap, and - * one group descriptor via ext4_free_blocks(). - */ - handle = ext4_journal_start_sb(sb, 3); - if (IS_ERR(handle)) { - err = PTR_ERR(handle); - ext4_warning(sb, __FUNCTION__, "error %d on journal start",err); - goto exit_put; - } - - lock_super(sb); - if (o_blocks_count != ext4_blocks_count(es)) { - ext4_warning(sb, __FUNCTION__, - "multiple resizers run on filesystem!"); - unlock_super(sb); - err = -EBUSY; - goto exit_put; - } - - if ((err = ext4_journal_get_write_access(handle, - EXT4_SB(sb)->s_sbh))) { - ext4_warning(sb, __FUNCTION__, - "error %d on journal write access", err); - unlock_super(sb); - ext4_journal_stop(handle); - goto exit_put; - } - ext4_blocks_count_set(es, o_blocks_count + add); - ext4_journal_dirty_metadata(handle, EXT4_SB(sb)->s_sbh); - sb->s_dirt = 1; - unlock_super(sb); - ext4_debug("freeing blocks %lu through %llu\n", o_blocks_count, - o_blocks_count + add); - ext4_free_blocks_sb(handle, sb, o_blocks_count, add, &freed_blocks); - ext4_debug("freed blocks %llu through %llu\n", o_blocks_count, - o_blocks_count + add); - if ((err = ext4_journal_stop(handle))) - goto exit_put; - if (test_opt(sb, DEBUG)) - printk(KERN_DEBUG "EXT4-fs: extended group to %llu blocks\n", - ext4_blocks_count(es)); - update_backups(sb, EXT4_SB(sb)->s_sbh->b_blocknr, (char *)es, - sizeof(struct ext4_super_block)); -exit_put: - return err; -} /* ext4_group_extend */ diff --git a/trunk/fs/ext4/super.c b/trunk/fs/ext4/super.c deleted file mode 100644 index b4b022aa2bc2..000000000000 --- a/trunk/fs/ext4/super.c +++ /dev/null @@ -1,2829 +0,0 @@ -/* - * linux/fs/ext4/super.c - * - * Copyright (C) 1992, 1993, 1994, 1995 - * Remy Card (card@masi.ibp.fr) - * Laboratoire MASI - Institut Blaise Pascal - * Universite Pierre et Marie Curie (Paris VI) - * - * from - * - * linux/fs/minix/inode.c - * - * Copyright (C) 1991, 1992 Linus Torvalds - * - * Big-endian to little-endian byte-swapping/bitmaps by - * David S. Miller (davem@caip.rutgers.edu), 1995 - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "xattr.h" -#include "acl.h" -#include "namei.h" - -static int ext4_load_journal(struct super_block *, struct ext4_super_block *, - unsigned long journal_devnum); -static int ext4_create_journal(struct super_block *, struct ext4_super_block *, - unsigned int); -static void ext4_commit_super (struct super_block * sb, - struct ext4_super_block * es, - int sync); -static void ext4_mark_recovery_complete(struct super_block * sb, - struct ext4_super_block * es); -static void ext4_clear_journal_err(struct super_block * sb, - struct ext4_super_block * es); -static int ext4_sync_fs(struct super_block *sb, int wait); -static const char *ext4_decode_error(struct super_block * sb, int errno, - char nbuf[16]); -static int ext4_remount (struct super_block * sb, int * flags, char * data); -static int ext4_statfs (struct dentry * dentry, struct kstatfs * buf); -static void ext4_unlockfs(struct super_block *sb); -static void ext4_write_super (struct super_block * sb); -static void ext4_write_super_lockfs(struct super_block *sb); - - -ext4_fsblk_t ext4_block_bitmap(struct super_block *sb, - struct ext4_group_desc *bg) -{ - return le32_to_cpu(bg->bg_block_bitmap) | - (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ? - (ext4_fsblk_t)le32_to_cpu(bg->bg_block_bitmap_hi) << 32 : 0); -} - -ext4_fsblk_t ext4_inode_bitmap(struct super_block *sb, - struct ext4_group_desc *bg) -{ - return le32_to_cpu(bg->bg_inode_bitmap) | - (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ? - (ext4_fsblk_t)le32_to_cpu(bg->bg_inode_bitmap_hi) << 32 : 0); -} - -ext4_fsblk_t ext4_inode_table(struct super_block *sb, - struct ext4_group_desc *bg) -{ - return le32_to_cpu(bg->bg_inode_table) | - (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ? - (ext4_fsblk_t)le32_to_cpu(bg->bg_inode_table_hi) << 32 : 0); -} - -void ext4_block_bitmap_set(struct super_block *sb, - struct ext4_group_desc *bg, ext4_fsblk_t blk) -{ - bg->bg_block_bitmap = cpu_to_le32((u32)blk); - if (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT) - bg->bg_block_bitmap_hi = cpu_to_le32(blk >> 32); -} - -void ext4_inode_bitmap_set(struct super_block *sb, - struct ext4_group_desc *bg, ext4_fsblk_t blk) -{ - bg->bg_inode_bitmap = cpu_to_le32((u32)blk); - if (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT) - bg->bg_inode_bitmap_hi = cpu_to_le32(blk >> 32); -} - -void ext4_inode_table_set(struct super_block *sb, - struct ext4_group_desc *bg, ext4_fsblk_t blk) -{ - bg->bg_inode_table = cpu_to_le32((u32)blk); - if (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT) - bg->bg_inode_table_hi = cpu_to_le32(blk >> 32); -} - -/* - * Wrappers for jbd2_journal_start/end. - * - * The only special thing we need to do here is to make sure that all - * journal_end calls result in the superblock being marked dirty, so - * that sync() will call the filesystem's write_super callback if - * appropriate. - */ -handle_t *ext4_journal_start_sb(struct super_block *sb, int nblocks) -{ - journal_t *journal; - - if (sb->s_flags & MS_RDONLY) - return ERR_PTR(-EROFS); - - /* Special case here: if the journal has aborted behind our - * backs (eg. EIO in the commit thread), then we still need to - * take the FS itself readonly cleanly. */ - journal = EXT4_SB(sb)->s_journal; - if (is_journal_aborted(journal)) { - ext4_abort(sb, __FUNCTION__, - "Detected aborted journal"); - return ERR_PTR(-EROFS); - } - - return jbd2_journal_start(journal, nblocks); -} - -/* - * The only special thing we need to do here is to make sure that all - * jbd2_journal_stop calls result in the superblock being marked dirty, so - * that sync() will call the filesystem's write_super callback if - * appropriate. - */ -int __ext4_journal_stop(const char *where, handle_t *handle) -{ - struct super_block *sb; - int err; - int rc; - - sb = handle->h_transaction->t_journal->j_private; - err = handle->h_err; - rc = jbd2_journal_stop(handle); - - if (!err) - err = rc; - if (err) - __ext4_std_error(sb, where, err); - return err; -} - -void ext4_journal_abort_handle(const char *caller, const char *err_fn, - struct buffer_head *bh, handle_t *handle, int err) -{ - char nbuf[16]; - const char *errstr = ext4_decode_error(NULL, err, nbuf); - - if (bh) - BUFFER_TRACE(bh, "abort"); - - if (!handle->h_err) - handle->h_err = err; - - if (is_handle_aborted(handle)) - return; - - printk(KERN_ERR "%s: aborting transaction: %s in %s\n", - caller, errstr, err_fn); - - jbd2_journal_abort_handle(handle); -} - -/* Deal with the reporting of failure conditions on a filesystem such as - * inconsistencies detected or read IO failures. - * - * On ext2, we can store the error state of the filesystem in the - * superblock. That is not possible on ext4, because we may have other - * write ordering constraints on the superblock which prevent us from - * writing it out straight away; and given that the journal is about to - * be aborted, we can't rely on the current, or future, transactions to - * write out the superblock safely. - * - * We'll just use the jbd2_journal_abort() error code to record an error in - * the journal instead. On recovery, the journal will compain about - * that error until we've noted it down and cleared it. - */ - -static void ext4_handle_error(struct super_block *sb) -{ - struct ext4_super_block *es = EXT4_SB(sb)->s_es; - - EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; - es->s_state |= cpu_to_le16(EXT4_ERROR_FS); - - if (sb->s_flags & MS_RDONLY) - return; - - if (!test_opt (sb, ERRORS_CONT)) { - journal_t *journal = EXT4_SB(sb)->s_journal; - - EXT4_SB(sb)->s_mount_opt |= EXT4_MOUNT_ABORT; - if (journal) - jbd2_journal_abort(journal, -EIO); - } - if (test_opt (sb, ERRORS_RO)) { - printk (KERN_CRIT "Remounting filesystem read-only\n"); - sb->s_flags |= MS_RDONLY; - } - ext4_commit_super(sb, es, 1); - if (test_opt(sb, ERRORS_PANIC)) - panic("EXT4-fs (device %s): panic forced after error\n", - sb->s_id); -} - -void ext4_error (struct super_block * sb, const char * function, - const char * fmt, ...) -{ - va_list args; - - va_start(args, fmt); - printk(KERN_CRIT "EXT4-fs error (device %s): %s: ",sb->s_id, function); - vprintk(fmt, args); - printk("\n"); - va_end(args); - - ext4_handle_error(sb); -} - -static const char *ext4_decode_error(struct super_block * sb, int errno, - char nbuf[16]) -{ - char *errstr = NULL; - - switch (errno) { - case -EIO: - errstr = "IO failure"; - break; - case -ENOMEM: - errstr = "Out of memory"; - break; - case -EROFS: - if (!sb || EXT4_SB(sb)->s_journal->j_flags & JBD2_ABORT) - errstr = "Journal has aborted"; - else - errstr = "Readonly filesystem"; - break; - default: - /* If the caller passed in an extra buffer for unknown - * errors, textualise them now. Else we just return - * NULL. */ - if (nbuf) { - /* Check for truncated error codes... */ - if (snprintf(nbuf, 16, "error %d", -errno) >= 0) - errstr = nbuf; - } - break; - } - - return errstr; -} - -/* __ext4_std_error decodes expected errors from journaling functions - * automatically and invokes the appropriate error response. */ - -void __ext4_std_error (struct super_block * sb, const char * function, - int errno) -{ - char nbuf[16]; - const char *errstr; - - /* Special case: if the error is EROFS, and we're not already - * inside a transaction, then there's really no point in logging - * an error. */ - if (errno == -EROFS && journal_current_handle() == NULL && - (sb->s_flags & MS_RDONLY)) - return; - - errstr = ext4_decode_error(sb, errno, nbuf); - printk (KERN_CRIT "EXT4-fs error (device %s) in %s: %s\n", - sb->s_id, function, errstr); - - ext4_handle_error(sb); -} - -/* - * ext4_abort is a much stronger failure handler than ext4_error. The - * abort function may be used to deal with unrecoverable failures such - * as journal IO errors or ENOMEM at a critical moment in log management. - * - * We unconditionally force the filesystem into an ABORT|READONLY state, - * unless the error response on the fs has been set to panic in which - * case we take the easy way out and panic immediately. - */ - -void ext4_abort (struct super_block * sb, const char * function, - const char * fmt, ...) -{ - va_list args; - - printk (KERN_CRIT "ext4_abort called.\n"); - - va_start(args, fmt); - printk(KERN_CRIT "EXT4-fs error (device %s): %s: ",sb->s_id, function); - vprintk(fmt, args); - printk("\n"); - va_end(args); - - if (test_opt(sb, ERRORS_PANIC)) - panic("EXT4-fs panic from previous error\n"); - - if (sb->s_flags & MS_RDONLY) - return; - - printk(KERN_CRIT "Remounting filesystem read-only\n"); - EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; - sb->s_flags |= MS_RDONLY; - EXT4_SB(sb)->s_mount_opt |= EXT4_MOUNT_ABORT; - jbd2_journal_abort(EXT4_SB(sb)->s_journal, -EIO); -} - -void ext4_warning (struct super_block * sb, const char * function, - const char * fmt, ...) -{ - va_list args; - - va_start(args, fmt); - printk(KERN_WARNING "EXT4-fs warning (device %s): %s: ", - sb->s_id, function); - vprintk(fmt, args); - printk("\n"); - va_end(args); -} - -void ext4_update_dynamic_rev(struct super_block *sb) -{ - struct ext4_super_block *es = EXT4_SB(sb)->s_es; - - if (le32_to_cpu(es->s_rev_level) > EXT4_GOOD_OLD_REV) - return; - - ext4_warning(sb, __FUNCTION__, - "updating to rev %d because of new feature flag, " - "running e2fsck is recommended", - EXT4_DYNAMIC_REV); - - es->s_first_ino = cpu_to_le32(EXT4_GOOD_OLD_FIRST_INO); - es->s_inode_size = cpu_to_le16(EXT4_GOOD_OLD_INODE_SIZE); - es->s_rev_level = cpu_to_le32(EXT4_DYNAMIC_REV); - /* leave es->s_feature_*compat flags alone */ - /* es->s_uuid will be set by e2fsck if empty */ - - /* - * The rest of the superblock fields should be zero, and if not it - * means they are likely already in use, so leave them alone. We - * can leave it up to e2fsck to clean up any inconsistencies there. - */ -} - -/* - * Open the external journal device - */ -static struct block_device *ext4_blkdev_get(dev_t dev) -{ - struct block_device *bdev; - char b[BDEVNAME_SIZE]; - - bdev = open_by_devnum(dev, FMODE_READ|FMODE_WRITE); - if (IS_ERR(bdev)) - goto fail; - return bdev; - -fail: - printk(KERN_ERR "EXT4: failed to open journal device %s: %ld\n", - __bdevname(dev, b), PTR_ERR(bdev)); - return NULL; -} - -/* - * Release the journal device - */ -static int ext4_blkdev_put(struct block_device *bdev) -{ - bd_release(bdev); - return blkdev_put(bdev); -} - -static int ext4_blkdev_remove(struct ext4_sb_info *sbi) -{ - struct block_device *bdev; - int ret = -ENODEV; - - bdev = sbi->journal_bdev; - if (bdev) { - ret = ext4_blkdev_put(bdev); - sbi->journal_bdev = NULL; - } - return ret; -} - -static inline struct inode *orphan_list_entry(struct list_head *l) -{ - return &list_entry(l, struct ext4_inode_info, i_orphan)->vfs_inode; -} - -static void dump_orphan_list(struct super_block *sb, struct ext4_sb_info *sbi) -{ - struct list_head *l; - - printk(KERN_ERR "sb orphan head is %d\n", - le32_to_cpu(sbi->s_es->s_last_orphan)); - - printk(KERN_ERR "sb_info orphan list:\n"); - list_for_each(l, &sbi->s_orphan) { - struct inode *inode = orphan_list_entry(l); - printk(KERN_ERR " " - "inode %s:%lu at %p: mode %o, nlink %d, next %d\n", - inode->i_sb->s_id, inode->i_ino, inode, - inode->i_mode, inode->i_nlink, - NEXT_ORPHAN(inode)); - } -} - -static void ext4_put_super (struct super_block * sb) -{ - struct ext4_sb_info *sbi = EXT4_SB(sb); - struct ext4_super_block *es = sbi->s_es; - int i; - - ext4_ext_release(sb); - ext4_xattr_put_super(sb); - jbd2_journal_destroy(sbi->s_journal); - if (!(sb->s_flags & MS_RDONLY)) { - EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); - es->s_state = cpu_to_le16(sbi->s_mount_state); - BUFFER_TRACE(sbi->s_sbh, "marking dirty"); - mark_buffer_dirty(sbi->s_sbh); - ext4_commit_super(sb, es, 1); - } - - for (i = 0; i < sbi->s_gdb_count; i++) - brelse(sbi->s_group_desc[i]); - kfree(sbi->s_group_desc); - percpu_counter_destroy(&sbi->s_freeblocks_counter); - percpu_counter_destroy(&sbi->s_freeinodes_counter); - percpu_counter_destroy(&sbi->s_dirs_counter); - brelse(sbi->s_sbh); -#ifdef CONFIG_QUOTA - for (i = 0; i < MAXQUOTAS; i++) - kfree(sbi->s_qf_names[i]); -#endif - - /* Debugging code just in case the in-memory inode orphan list - * isn't empty. The on-disk one can be non-empty if we've - * detected an error and taken the fs readonly, but the - * in-memory list had better be clean by this point. */ - if (!list_empty(&sbi->s_orphan)) - dump_orphan_list(sb, sbi); - J_ASSERT(list_empty(&sbi->s_orphan)); - - invalidate_bdev(sb->s_bdev, 0); - if (sbi->journal_bdev && sbi->journal_bdev != sb->s_bdev) { - /* - * Invalidate the journal device's buffers. We don't want them - * floating about in memory - the physical journal device may - * hotswapped, and it breaks the `ro-after' testing code. - */ - sync_blockdev(sbi->journal_bdev); - invalidate_bdev(sbi->journal_bdev, 0); - ext4_blkdev_remove(sbi); - } - sb->s_fs_info = NULL; - kfree(sbi); - return; -} - -static kmem_cache_t *ext4_inode_cachep; - -/* - * Called inside transaction, so use GFP_NOFS - */ -static struct inode *ext4_alloc_inode(struct super_block *sb) -{ - struct ext4_inode_info *ei; - - ei = kmem_cache_alloc(ext4_inode_cachep, SLAB_NOFS); - if (!ei) - return NULL; -#ifdef CONFIG_EXT4DEV_FS_POSIX_ACL - ei->i_acl = EXT4_ACL_NOT_CACHED; - ei->i_default_acl = EXT4_ACL_NOT_CACHED; -#endif - ei->i_block_alloc_info = NULL; - ei->vfs_inode.i_version = 1; - memset(&ei->i_cached_extent, 0, sizeof(struct ext4_ext_cache)); - return &ei->vfs_inode; -} - -static void ext4_destroy_inode(struct inode *inode) -{ - kmem_cache_free(ext4_inode_cachep, EXT4_I(inode)); -} - -static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) -{ - struct ext4_inode_info *ei = (struct ext4_inode_info *) foo; - - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) { - INIT_LIST_HEAD(&ei->i_orphan); -#ifdef CONFIG_EXT4DEV_FS_XATTR - init_rwsem(&ei->xattr_sem); -#endif - mutex_init(&ei->truncate_mutex); - inode_init_once(&ei->vfs_inode); - } -} - -static int init_inodecache(void) -{ - ext4_inode_cachep = kmem_cache_create("ext4_inode_cache", - sizeof(struct ext4_inode_info), - 0, (SLAB_RECLAIM_ACCOUNT| - SLAB_MEM_SPREAD), - init_once, NULL); - if (ext4_inode_cachep == NULL) - return -ENOMEM; - return 0; -} - -static void destroy_inodecache(void) -{ - kmem_cache_destroy(ext4_inode_cachep); -} - -static void ext4_clear_inode(struct inode *inode) -{ - struct ext4_block_alloc_info *rsv = EXT4_I(inode)->i_block_alloc_info; -#ifdef CONFIG_EXT4DEV_FS_POSIX_ACL - if (EXT4_I(inode)->i_acl && - EXT4_I(inode)->i_acl != EXT4_ACL_NOT_CACHED) { - posix_acl_release(EXT4_I(inode)->i_acl); - EXT4_I(inode)->i_acl = EXT4_ACL_NOT_CACHED; - } - if (EXT4_I(inode)->i_default_acl && - EXT4_I(inode)->i_default_acl != EXT4_ACL_NOT_CACHED) { - posix_acl_release(EXT4_I(inode)->i_default_acl); - EXT4_I(inode)->i_default_acl = EXT4_ACL_NOT_CACHED; - } -#endif - ext4_discard_reservation(inode); - EXT4_I(inode)->i_block_alloc_info = NULL; - if (unlikely(rsv)) - kfree(rsv); -} - -static inline void ext4_show_quota_options(struct seq_file *seq, struct super_block *sb) -{ -#if defined(CONFIG_QUOTA) - struct ext4_sb_info *sbi = EXT4_SB(sb); - - if (sbi->s_jquota_fmt) - seq_printf(seq, ",jqfmt=%s", - (sbi->s_jquota_fmt == QFMT_VFS_OLD) ? "vfsold": "vfsv0"); - - if (sbi->s_qf_names[USRQUOTA]) - seq_printf(seq, ",usrjquota=%s", sbi->s_qf_names[USRQUOTA]); - - if (sbi->s_qf_names[GRPQUOTA]) - seq_printf(seq, ",grpjquota=%s", sbi->s_qf_names[GRPQUOTA]); - - if (sbi->s_mount_opt & EXT4_MOUNT_USRQUOTA) - seq_puts(seq, ",usrquota"); - - if (sbi->s_mount_opt & EXT4_MOUNT_GRPQUOTA) - seq_puts(seq, ",grpquota"); -#endif -} - -static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs) -{ - struct super_block *sb = vfs->mnt_sb; - - if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) - seq_puts(seq, ",data=journal"); - else if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_ORDERED_DATA) - seq_puts(seq, ",data=ordered"); - else if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA) - seq_puts(seq, ",data=writeback"); - - ext4_show_quota_options(seq, sb); - - return 0; -} - - -static struct dentry *ext4_get_dentry(struct super_block *sb, void *vobjp) -{ - __u32 *objp = vobjp; - unsigned long ino = objp[0]; - __u32 generation = objp[1]; - struct inode *inode; - struct dentry *result; - - if (ino < EXT4_FIRST_INO(sb) && ino != EXT4_ROOT_INO) - return ERR_PTR(-ESTALE); - if (ino > le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count)) - return ERR_PTR(-ESTALE); - - /* iget isn't really right if the inode is currently unallocated!! - * - * ext4_read_inode will return a bad_inode if the inode had been - * deleted, so we should be safe. - * - * Currently we don't know the generation for parent directory, so - * a generation of 0 means "accept any" - */ - inode = iget(sb, ino); - if (inode == NULL) - return ERR_PTR(-ENOMEM); - if (is_bad_inode(inode) || - (generation && inode->i_generation != generation)) { - iput(inode); - return ERR_PTR(-ESTALE); - } - /* now to find a dentry. - * If possible, get a well-connected one - */ - result = d_alloc_anon(inode); - if (!result) { - iput(inode); - return ERR_PTR(-ENOMEM); - } - return result; -} - -#ifdef CONFIG_QUOTA -#define QTYPE2NAME(t) ((t)==USRQUOTA?"user":"group") -#define QTYPE2MOPT(on, t) ((t)==USRQUOTA?((on)##USRJQUOTA):((on)##GRPJQUOTA)) - -static int ext4_dquot_initialize(struct inode *inode, int type); -static int ext4_dquot_drop(struct inode *inode); -static int ext4_write_dquot(struct dquot *dquot); -static int ext4_acquire_dquot(struct dquot *dquot); -static int ext4_release_dquot(struct dquot *dquot); -static int ext4_mark_dquot_dirty(struct dquot *dquot); -static int ext4_write_info(struct super_block *sb, int type); -static int ext4_quota_on(struct super_block *sb, int type, int format_id, char *path); -static int ext4_quota_on_mount(struct super_block *sb, int type); -static ssize_t ext4_quota_read(struct super_block *sb, int type, char *data, - size_t len, loff_t off); -static ssize_t ext4_quota_write(struct super_block *sb, int type, - const char *data, size_t len, loff_t off); - -static struct dquot_operations ext4_quota_operations = { - .initialize = ext4_dquot_initialize, - .drop = ext4_dquot_drop, - .alloc_space = dquot_alloc_space, - .alloc_inode = dquot_alloc_inode, - .free_space = dquot_free_space, - .free_inode = dquot_free_inode, - .transfer = dquot_transfer, - .write_dquot = ext4_write_dquot, - .acquire_dquot = ext4_acquire_dquot, - .release_dquot = ext4_release_dquot, - .mark_dirty = ext4_mark_dquot_dirty, - .write_info = ext4_write_info -}; - -static struct quotactl_ops ext4_qctl_operations = { - .quota_on = ext4_quota_on, - .quota_off = vfs_quota_off, - .quota_sync = vfs_quota_sync, - .get_info = vfs_get_dqinfo, - .set_info = vfs_set_dqinfo, - .get_dqblk = vfs_get_dqblk, - .set_dqblk = vfs_set_dqblk -}; -#endif - -static struct super_operations ext4_sops = { - .alloc_inode = ext4_alloc_inode, - .destroy_inode = ext4_destroy_inode, - .read_inode = ext4_read_inode, - .write_inode = ext4_write_inode, - .dirty_inode = ext4_dirty_inode, - .delete_inode = ext4_delete_inode, - .put_super = ext4_put_super, - .write_super = ext4_write_super, - .sync_fs = ext4_sync_fs, - .write_super_lockfs = ext4_write_super_lockfs, - .unlockfs = ext4_unlockfs, - .statfs = ext4_statfs, - .remount_fs = ext4_remount, - .clear_inode = ext4_clear_inode, - .show_options = ext4_show_options, -#ifdef CONFIG_QUOTA - .quota_read = ext4_quota_read, - .quota_write = ext4_quota_write, -#endif -}; - -static struct export_operations ext4_export_ops = { - .get_parent = ext4_get_parent, - .get_dentry = ext4_get_dentry, -}; - -enum { - Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid, - Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic, Opt_err_ro, - Opt_nouid32, Opt_nocheck, Opt_debug, Opt_oldalloc, Opt_orlov, - Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl, - Opt_reservation, Opt_noreservation, Opt_noload, Opt_nobh, Opt_bh, - Opt_commit, Opt_journal_update, Opt_journal_inum, Opt_journal_dev, - Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback, - Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, - Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota, - Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota, - Opt_grpquota, Opt_extents, -}; - -static match_table_t tokens = { - {Opt_bsd_df, "bsddf"}, - {Opt_minix_df, "minixdf"}, - {Opt_grpid, "grpid"}, - {Opt_grpid, "bsdgroups"}, - {Opt_nogrpid, "nogrpid"}, - {Opt_nogrpid, "sysvgroups"}, - {Opt_resgid, "resgid=%u"}, - {Opt_resuid, "resuid=%u"}, - {Opt_sb, "sb=%u"}, - {Opt_err_cont, "errors=continue"}, - {Opt_err_panic, "errors=panic"}, - {Opt_err_ro, "errors=remount-ro"}, - {Opt_nouid32, "nouid32"}, - {Opt_nocheck, "nocheck"}, - {Opt_nocheck, "check=none"}, - {Opt_debug, "debug"}, - {Opt_oldalloc, "oldalloc"}, - {Opt_orlov, "orlov"}, - {Opt_user_xattr, "user_xattr"}, - {Opt_nouser_xattr, "nouser_xattr"}, - {Opt_acl, "acl"}, - {Opt_noacl, "noacl"}, - {Opt_reservation, "reservation"}, - {Opt_noreservation, "noreservation"}, - {Opt_noload, "noload"}, - {Opt_nobh, "nobh"}, - {Opt_bh, "bh"}, - {Opt_commit, "commit=%u"}, - {Opt_journal_update, "journal=update"}, - {Opt_journal_inum, "journal=%u"}, - {Opt_journal_dev, "journal_dev=%u"}, - {Opt_abort, "abort"}, - {Opt_data_journal, "data=journal"}, - {Opt_data_ordered, "data=ordered"}, - {Opt_data_writeback, "data=writeback"}, - {Opt_offusrjquota, "usrjquota="}, - {Opt_usrjquota, "usrjquota=%s"}, - {Opt_offgrpjquota, "grpjquota="}, - {Opt_grpjquota, "grpjquota=%s"}, - {Opt_jqfmt_vfsold, "jqfmt=vfsold"}, - {Opt_jqfmt_vfsv0, "jqfmt=vfsv0"}, - {Opt_grpquota, "grpquota"}, - {Opt_noquota, "noquota"}, - {Opt_quota, "quota"}, - {Opt_usrquota, "usrquota"}, - {Opt_barrier, "barrier=%u"}, - {Opt_extents, "extents"}, - {Opt_err, NULL}, - {Opt_resize, "resize"}, -}; - -static ext4_fsblk_t get_sb_block(void **data) -{ - ext4_fsblk_t sb_block; - char *options = (char *) *data; - - if (!options || strncmp(options, "sb=", 3) != 0) - return 1; /* Default location */ - options += 3; - /*todo: use simple_strtoll with >32bit ext4 */ - sb_block = simple_strtoul(options, &options, 0); - if (*options && *options != ',') { - printk("EXT4-fs: Invalid sb specification: %s\n", - (char *) *data); - return 1; - } - if (*options == ',') - options++; - *data = (void *) options; - return sb_block; -} - -static int parse_options (char *options, struct super_block *sb, - unsigned int *inum, unsigned long *journal_devnum, - ext4_fsblk_t *n_blocks_count, int is_remount) -{ - struct ext4_sb_info *sbi = EXT4_SB(sb); - char * p; - substring_t args[MAX_OPT_ARGS]; - int data_opt = 0; - int option; -#ifdef CONFIG_QUOTA - int qtype; - char *qname; -#endif - - if (!options) - return 1; - - while ((p = strsep (&options, ",")) != NULL) { - int token; - if (!*p) - continue; - - token = match_token(p, tokens, args); - switch (token) { - case Opt_bsd_df: - clear_opt (sbi->s_mount_opt, MINIX_DF); - break; - case Opt_minix_df: - set_opt (sbi->s_mount_opt, MINIX_DF); - break; - case Opt_grpid: - set_opt (sbi->s_mount_opt, GRPID); - break; - case Opt_nogrpid: - clear_opt (sbi->s_mount_opt, GRPID); - break; - case Opt_resuid: - if (match_int(&args[0], &option)) - return 0; - sbi->s_resuid = option; - break; - case Opt_resgid: - if (match_int(&args[0], &option)) - return 0; - sbi->s_resgid = option; - break; - case Opt_sb: - /* handled by get_sb_block() instead of here */ - /* *sb_block = match_int(&args[0]); */ - break; - case Opt_err_panic: - clear_opt (sbi->s_mount_opt, ERRORS_CONT); - clear_opt (sbi->s_mount_opt, ERRORS_RO); - set_opt (sbi->s_mount_opt, ERRORS_PANIC); - break; - case Opt_err_ro: - clear_opt (sbi->s_mount_opt, ERRORS_CONT); - clear_opt (sbi->s_mount_opt, ERRORS_PANIC); - set_opt (sbi->s_mount_opt, ERRORS_RO); - break; - case Opt_err_cont: - clear_opt (sbi->s_mount_opt, ERRORS_RO); - clear_opt (sbi->s_mount_opt, ERRORS_PANIC); - set_opt (sbi->s_mount_opt, ERRORS_CONT); - break; - case Opt_nouid32: - set_opt (sbi->s_mount_opt, NO_UID32); - break; - case Opt_nocheck: - clear_opt (sbi->s_mount_opt, CHECK); - break; - case Opt_debug: - set_opt (sbi->s_mount_opt, DEBUG); - break; - case Opt_oldalloc: - set_opt (sbi->s_mount_opt, OLDALLOC); - break; - case Opt_orlov: - clear_opt (sbi->s_mount_opt, OLDALLOC); - break; -#ifdef CONFIG_EXT4DEV_FS_XATTR - case Opt_user_xattr: - set_opt (sbi->s_mount_opt, XATTR_USER); - break; - case Opt_nouser_xattr: - clear_opt (sbi->s_mount_opt, XATTR_USER); - break; -#else - case Opt_user_xattr: - case Opt_nouser_xattr: - printk("EXT4 (no)user_xattr options not supported\n"); - break; -#endif -#ifdef CONFIG_EXT4DEV_FS_POSIX_ACL - case Opt_acl: - set_opt(sbi->s_mount_opt, POSIX_ACL); - break; - case Opt_noacl: - clear_opt(sbi->s_mount_opt, POSIX_ACL); - break; -#else - case Opt_acl: - case Opt_noacl: - printk("EXT4 (no)acl options not supported\n"); - break; -#endif - case Opt_reservation: - set_opt(sbi->s_mount_opt, RESERVATION); - break; - case Opt_noreservation: - clear_opt(sbi->s_mount_opt, RESERVATION); - break; - case Opt_journal_update: - /* @@@ FIXME */ - /* Eventually we will want to be able to create - a journal file here. For now, only allow the - user to specify an existing inode to be the - journal file. */ - if (is_remount) { - printk(KERN_ERR "EXT4-fs: cannot specify " - "journal on remount\n"); - return 0; - } - set_opt (sbi->s_mount_opt, UPDATE_JOURNAL); - break; - case Opt_journal_inum: - if (is_remount) { - printk(KERN_ERR "EXT4-fs: cannot specify " - "journal on remount\n"); - return 0; - } - if (match_int(&args[0], &option)) - return 0; - *inum = option; - break; - case Opt_journal_dev: - if (is_remount) { - printk(KERN_ERR "EXT4-fs: cannot specify " - "journal on remount\n"); - return 0; - } - if (match_int(&args[0], &option)) - return 0; - *journal_devnum = option; - break; - case Opt_noload: - set_opt (sbi->s_mount_opt, NOLOAD); - break; - case Opt_commit: - if (match_int(&args[0], &option)) - return 0; - if (option < 0) - return 0; - if (option == 0) - option = JBD_DEFAULT_MAX_COMMIT_AGE; - sbi->s_commit_interval = HZ * option; - break; - case Opt_data_journal: - data_opt = EXT4_MOUNT_JOURNAL_DATA; - goto datacheck; - case Opt_data_ordered: - data_opt = EXT4_MOUNT_ORDERED_DATA; - goto datacheck; - case Opt_data_writeback: - data_opt = EXT4_MOUNT_WRITEBACK_DATA; - datacheck: - if (is_remount) { - if ((sbi->s_mount_opt & EXT4_MOUNT_DATA_FLAGS) - != data_opt) { - printk(KERN_ERR - "EXT4-fs: cannot change data " - "mode on remount\n"); - return 0; - } - } else { - sbi->s_mount_opt &= ~EXT4_MOUNT_DATA_FLAGS; - sbi->s_mount_opt |= data_opt; - } - break; -#ifdef CONFIG_QUOTA - case Opt_usrjquota: - qtype = USRQUOTA; - goto set_qf_name; - case Opt_grpjquota: - qtype = GRPQUOTA; -set_qf_name: - if (sb_any_quota_enabled(sb)) { - printk(KERN_ERR - "EXT4-fs: Cannot change journalled " - "quota options when quota turned on.\n"); - return 0; - } - qname = match_strdup(&args[0]); - if (!qname) { - printk(KERN_ERR - "EXT4-fs: not enough memory for " - "storing quotafile name.\n"); - return 0; - } - if (sbi->s_qf_names[qtype] && - strcmp(sbi->s_qf_names[qtype], qname)) { - printk(KERN_ERR - "EXT4-fs: %s quota file already " - "specified.\n", QTYPE2NAME(qtype)); - kfree(qname); - return 0; - } - sbi->s_qf_names[qtype] = qname; - if (strchr(sbi->s_qf_names[qtype], '/')) { - printk(KERN_ERR - "EXT4-fs: quotafile must be on " - "filesystem root.\n"); - kfree(sbi->s_qf_names[qtype]); - sbi->s_qf_names[qtype] = NULL; - return 0; - } - set_opt(sbi->s_mount_opt, QUOTA); - break; - case Opt_offusrjquota: - qtype = USRQUOTA; - goto clear_qf_name; - case Opt_offgrpjquota: - qtype = GRPQUOTA; -clear_qf_name: - if (sb_any_quota_enabled(sb)) { - printk(KERN_ERR "EXT4-fs: Cannot change " - "journalled quota options when " - "quota turned on.\n"); - return 0; - } - /* - * The space will be released later when all options - * are confirmed to be correct - */ - sbi->s_qf_names[qtype] = NULL; - break; - case Opt_jqfmt_vfsold: - sbi->s_jquota_fmt = QFMT_VFS_OLD; - break; - case Opt_jqfmt_vfsv0: - sbi->s_jquota_fmt = QFMT_VFS_V0; - break; - case Opt_quota: - case Opt_usrquota: - set_opt(sbi->s_mount_opt, QUOTA); - set_opt(sbi->s_mount_opt, USRQUOTA); - break; - case Opt_grpquota: - set_opt(sbi->s_mount_opt, QUOTA); - set_opt(sbi->s_mount_opt, GRPQUOTA); - break; - case Opt_noquota: - if (sb_any_quota_enabled(sb)) { - printk(KERN_ERR "EXT4-fs: Cannot change quota " - "options when quota turned on.\n"); - return 0; - } - clear_opt(sbi->s_mount_opt, QUOTA); - clear_opt(sbi->s_mount_opt, USRQUOTA); - clear_opt(sbi->s_mount_opt, GRPQUOTA); - break; -#else - case Opt_quota: - case Opt_usrquota: - case Opt_grpquota: - case Opt_usrjquota: - case Opt_grpjquota: - case Opt_offusrjquota: - case Opt_offgrpjquota: - case Opt_jqfmt_vfsold: - case Opt_jqfmt_vfsv0: - printk(KERN_ERR - "EXT4-fs: journalled quota options not " - "supported.\n"); - break; - case Opt_noquota: - break; -#endif - case Opt_abort: - set_opt(sbi->s_mount_opt, ABORT); - break; - case Opt_barrier: - if (match_int(&args[0], &option)) - return 0; - if (option) - set_opt(sbi->s_mount_opt, BARRIER); - else - clear_opt(sbi->s_mount_opt, BARRIER); - break; - case Opt_ignore: - break; - case Opt_resize: - if (!is_remount) { - printk("EXT4-fs: resize option only available " - "for remount\n"); - return 0; - } - if (match_int(&args[0], &option) != 0) - return 0; - *n_blocks_count = option; - break; - case Opt_nobh: - set_opt(sbi->s_mount_opt, NOBH); - break; - case Opt_bh: - clear_opt(sbi->s_mount_opt, NOBH); - break; - case Opt_extents: - set_opt (sbi->s_mount_opt, EXTENTS); - break; - default: - printk (KERN_ERR - "EXT4-fs: Unrecognized mount option \"%s\" " - "or missing value\n", p); - return 0; - } - } -#ifdef CONFIG_QUOTA - if (sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]) { - if ((sbi->s_mount_opt & EXT4_MOUNT_USRQUOTA) && - sbi->s_qf_names[USRQUOTA]) - clear_opt(sbi->s_mount_opt, USRQUOTA); - - if ((sbi->s_mount_opt & EXT4_MOUNT_GRPQUOTA) && - sbi->s_qf_names[GRPQUOTA]) - clear_opt(sbi->s_mount_opt, GRPQUOTA); - - if ((sbi->s_qf_names[USRQUOTA] && - (sbi->s_mount_opt & EXT4_MOUNT_GRPQUOTA)) || - (sbi->s_qf_names[GRPQUOTA] && - (sbi->s_mount_opt & EXT4_MOUNT_USRQUOTA))) { - printk(KERN_ERR "EXT4-fs: old and new quota " - "format mixing.\n"); - return 0; - } - - if (!sbi->s_jquota_fmt) { - printk(KERN_ERR "EXT4-fs: journalled quota format " - "not specified.\n"); - return 0; - } - } else { - if (sbi->s_jquota_fmt) { - printk(KERN_ERR "EXT4-fs: journalled quota format " - "specified with no journalling " - "enabled.\n"); - return 0; - } - } -#endif - return 1; -} - -static int ext4_setup_super(struct super_block *sb, struct ext4_super_block *es, - int read_only) -{ - struct ext4_sb_info *sbi = EXT4_SB(sb); - int res = 0; - - if (le32_to_cpu(es->s_rev_level) > EXT4_MAX_SUPP_REV) { - printk (KERN_ERR "EXT4-fs warning: revision level too high, " - "forcing read-only mode\n"); - res = MS_RDONLY; - } - if (read_only) - return res; - if (!(sbi->s_mount_state & EXT4_VALID_FS)) - printk (KERN_WARNING "EXT4-fs warning: mounting unchecked fs, " - "running e2fsck is recommended\n"); - else if ((sbi->s_mount_state & EXT4_ERROR_FS)) - printk (KERN_WARNING - "EXT4-fs warning: mounting fs with errors, " - "running e2fsck is recommended\n"); - else if ((__s16) le16_to_cpu(es->s_max_mnt_count) >= 0 && - le16_to_cpu(es->s_mnt_count) >= - (unsigned short) (__s16) le16_to_cpu(es->s_max_mnt_count)) - printk (KERN_WARNING - "EXT4-fs warning: maximal mount count reached, " - "running e2fsck is recommended\n"); - else if (le32_to_cpu(es->s_checkinterval) && - (le32_to_cpu(es->s_lastcheck) + - le32_to_cpu(es->s_checkinterval) <= get_seconds())) - printk (KERN_WARNING - "EXT4-fs warning: checktime reached, " - "running e2fsck is recommended\n"); -#if 0 - /* @@@ We _will_ want to clear the valid bit if we find - * inconsistencies, to force a fsck at reboot. But for - * a plain journaled filesystem we can keep it set as - * valid forever! :) - */ - es->s_state = cpu_to_le16(le16_to_cpu(es->s_state) & ~EXT4_VALID_FS); -#endif - if (!(__s16) le16_to_cpu(es->s_max_mnt_count)) - es->s_max_mnt_count = cpu_to_le16(EXT4_DFL_MAX_MNT_COUNT); - es->s_mnt_count=cpu_to_le16(le16_to_cpu(es->s_mnt_count) + 1); - es->s_mtime = cpu_to_le32(get_seconds()); - ext4_update_dynamic_rev(sb); - EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); - - ext4_commit_super(sb, es, 1); - if (test_opt(sb, DEBUG)) - printk(KERN_INFO "[EXT4 FS bs=%lu, gc=%lu, " - "bpg=%lu, ipg=%lu, mo=%04lx]\n", - sb->s_blocksize, - sbi->s_groups_count, - EXT4_BLOCKS_PER_GROUP(sb), - EXT4_INODES_PER_GROUP(sb), - sbi->s_mount_opt); - - printk(KERN_INFO "EXT4 FS on %s, ", sb->s_id); - if (EXT4_SB(sb)->s_journal->j_inode == NULL) { - char b[BDEVNAME_SIZE]; - - printk("external journal on %s\n", - bdevname(EXT4_SB(sb)->s_journal->j_dev, b)); - } else { - printk("internal journal\n"); - } - return res; -} - -/* Called at mount-time, super-block is locked */ -static int ext4_check_descriptors (struct super_block * sb) -{ - struct ext4_sb_info *sbi = EXT4_SB(sb); - ext4_fsblk_t first_block = le32_to_cpu(sbi->s_es->s_first_data_block); - ext4_fsblk_t last_block; - ext4_fsblk_t block_bitmap; - ext4_fsblk_t inode_bitmap; - ext4_fsblk_t inode_table; - struct ext4_group_desc * gdp = NULL; - int desc_block = 0; - int i; - - ext4_debug ("Checking group descriptors"); - - for (i = 0; i < sbi->s_groups_count; i++) - { - if (i == sbi->s_groups_count - 1) - last_block = ext4_blocks_count(sbi->s_es) - 1; - else - last_block = first_block + - (EXT4_BLOCKS_PER_GROUP(sb) - 1); - - if ((i % EXT4_DESC_PER_BLOCK(sb)) == 0) - gdp = (struct ext4_group_desc *) - sbi->s_group_desc[desc_block++]->b_data; - block_bitmap = ext4_block_bitmap(sb, gdp); - if (block_bitmap < first_block || block_bitmap > last_block) - { - ext4_error (sb, "ext4_check_descriptors", - "Block bitmap for group %d" - " not in group (block %llu)!", - i, block_bitmap); - return 0; - } - inode_bitmap = ext4_inode_bitmap(sb, gdp); - if (inode_bitmap < first_block || inode_bitmap > last_block) - { - ext4_error (sb, "ext4_check_descriptors", - "Inode bitmap for group %d" - " not in group (block %llu)!", - i, inode_bitmap); - return 0; - } - inode_table = ext4_inode_table(sb, gdp); - if (inode_table < first_block || - inode_table + sbi->s_itb_per_group > last_block) - { - ext4_error (sb, "ext4_check_descriptors", - "Inode table for group %d" - " not in group (block %llu)!", - i, inode_table); - return 0; - } - first_block += EXT4_BLOCKS_PER_GROUP(sb); - gdp = (struct ext4_group_desc *) - ((__u8 *)gdp + EXT4_DESC_SIZE(sb)); - } - - ext4_free_blocks_count_set(sbi->s_es, ext4_count_free_blocks(sb)); - sbi->s_es->s_free_inodes_count=cpu_to_le32(ext4_count_free_inodes(sb)); - return 1; -} - - -/* ext4_orphan_cleanup() walks a singly-linked list of inodes (starting at - * the superblock) which were deleted from all directories, but held open by - * a process at the time of a crash. We walk the list and try to delete these - * inodes at recovery time (only with a read-write filesystem). - * - * In order to keep the orphan inode chain consistent during traversal (in - * case of crash during recovery), we link each inode into the superblock - * orphan list_head and handle it the same way as an inode deletion during - * normal operation (which journals the operations for us). - * - * We only do an iget() and an iput() on each inode, which is very safe if we - * accidentally point at an in-use or already deleted inode. The worst that - * can happen in this case is that we get a "bit already cleared" message from - * ext4_free_inode(). The only reason we would point at a wrong inode is if - * e2fsck was run on this filesystem, and it must have already done the orphan - * inode cleanup for us, so we can safely abort without any further action. - */ -static void ext4_orphan_cleanup (struct super_block * sb, - struct ext4_super_block * es) -{ - unsigned int s_flags = sb->s_flags; - int nr_orphans = 0, nr_truncates = 0; -#ifdef CONFIG_QUOTA - int i; -#endif - if (!es->s_last_orphan) { - jbd_debug(4, "no orphan inodes to clean up\n"); - return; - } - - if (EXT4_SB(sb)->s_mount_state & EXT4_ERROR_FS) { - if (es->s_last_orphan) - jbd_debug(1, "Errors on filesystem, " - "clearing orphan list.\n"); - es->s_last_orphan = 0; - jbd_debug(1, "Skipping orphan recovery on fs with errors.\n"); - return; - } - - if (s_flags & MS_RDONLY) { - printk(KERN_INFO "EXT4-fs: %s: orphan cleanup on readonly fs\n", - sb->s_id); - sb->s_flags &= ~MS_RDONLY; - } -#ifdef CONFIG_QUOTA - /* Needed for iput() to work correctly and not trash data */ - sb->s_flags |= MS_ACTIVE; - /* Turn on quotas so that they are updated correctly */ - for (i = 0; i < MAXQUOTAS; i++) { - if (EXT4_SB(sb)->s_qf_names[i]) { - int ret = ext4_quota_on_mount(sb, i); - if (ret < 0) - printk(KERN_ERR - "EXT4-fs: Cannot turn on journalled " - "quota: error %d\n", ret); - } - } -#endif - - while (es->s_last_orphan) { - struct inode *inode; - - if (!(inode = - ext4_orphan_get(sb, le32_to_cpu(es->s_last_orphan)))) { - es->s_last_orphan = 0; - break; - } - - list_add(&EXT4_I(inode)->i_orphan, &EXT4_SB(sb)->s_orphan); - DQUOT_INIT(inode); - if (inode->i_nlink) { - printk(KERN_DEBUG - "%s: truncating inode %lu to %Ld bytes\n", - __FUNCTION__, inode->i_ino, inode->i_size); - jbd_debug(2, "truncating inode %lu to %Ld bytes\n", - inode->i_ino, inode->i_size); - ext4_truncate(inode); - nr_truncates++; - } else { - printk(KERN_DEBUG - "%s: deleting unreferenced inode %lu\n", - __FUNCTION__, inode->i_ino); - jbd_debug(2, "deleting unreferenced inode %lu\n", - inode->i_ino); - nr_orphans++; - } - iput(inode); /* The delete magic happens here! */ - } - -#define PLURAL(x) (x), ((x)==1) ? "" : "s" - - if (nr_orphans) - printk(KERN_INFO "EXT4-fs: %s: %d orphan inode%s deleted\n", - sb->s_id, PLURAL(nr_orphans)); - if (nr_truncates) - printk(KERN_INFO "EXT4-fs: %s: %d truncate%s cleaned up\n", - sb->s_id, PLURAL(nr_truncates)); -#ifdef CONFIG_QUOTA - /* Turn quotas off */ - for (i = 0; i < MAXQUOTAS; i++) { - if (sb_dqopt(sb)->files[i]) - vfs_quota_off(sb, i); - } -#endif - sb->s_flags = s_flags; /* Restore MS_RDONLY status */ -} - -#define log2(n) ffz(~(n)) - -/* - * Maximal file size. There is a direct, and {,double-,triple-}indirect - * block limit, and also a limit of (2^32 - 1) 512-byte sectors in i_blocks. - * We need to be 1 filesystem block less than the 2^32 sector limit. - */ -static loff_t ext4_max_size(int bits) -{ - loff_t res = EXT4_NDIR_BLOCKS; - /* This constant is calculated to be the largest file size for a - * dense, 4k-blocksize file such that the total number of - * sectors in the file, including data and all indirect blocks, - * does not exceed 2^32. */ - const loff_t upper_limit = 0x1ff7fffd000LL; - - res += 1LL << (bits-2); - res += 1LL << (2*(bits-2)); - res += 1LL << (3*(bits-2)); - res <<= bits; - if (res > upper_limit) - res = upper_limit; - return res; -} - -static ext4_fsblk_t descriptor_loc(struct super_block *sb, - ext4_fsblk_t logical_sb_block, int nr) -{ - struct ext4_sb_info *sbi = EXT4_SB(sb); - unsigned long bg, first_meta_bg; - int has_super = 0; - - first_meta_bg = le32_to_cpu(sbi->s_es->s_first_meta_bg); - - if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_META_BG) || - nr < first_meta_bg) - return logical_sb_block + nr + 1; - bg = sbi->s_desc_per_block * nr; - if (ext4_bg_has_super(sb, bg)) - has_super = 1; - return (has_super + ext4_group_first_block_no(sb, bg)); -} - - -static int ext4_fill_super (struct super_block *sb, void *data, int silent) -{ - struct buffer_head * bh; - struct ext4_super_block *es = NULL; - struct ext4_sb_info *sbi; - ext4_fsblk_t block; - ext4_fsblk_t sb_block = get_sb_block(&data); - ext4_fsblk_t logical_sb_block; - unsigned long offset = 0; - unsigned int journal_inum = 0; - unsigned long journal_devnum = 0; - unsigned long def_mount_opts; - struct inode *root; - int blocksize; - int hblock; - int db_count; - int i; - int needs_recovery; - __le32 features; - __u64 blocks_count; - - sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); - if (!sbi) - return -ENOMEM; - sb->s_fs_info = sbi; - sbi->s_mount_opt = 0; - sbi->s_resuid = EXT4_DEF_RESUID; - sbi->s_resgid = EXT4_DEF_RESGID; - - unlock_kernel(); - - blocksize = sb_min_blocksize(sb, EXT4_MIN_BLOCK_SIZE); - if (!blocksize) { - printk(KERN_ERR "EXT4-fs: unable to set blocksize\n"); - goto out_fail; - } - - /* - * The ext4 superblock will not be buffer aligned for other than 1kB - * block sizes. We need to calculate the offset from buffer start. - */ - if (blocksize != EXT4_MIN_BLOCK_SIZE) { - logical_sb_block = sb_block * EXT4_MIN_BLOCK_SIZE; - offset = do_div(logical_sb_block, blocksize); - } else { - logical_sb_block = sb_block; - } - - if (!(bh = sb_bread(sb, logical_sb_block))) { - printk (KERN_ERR "EXT4-fs: unable to read superblock\n"); - goto out_fail; - } - /* - * Note: s_es must be initialized as soon as possible because - * some ext4 macro-instructions depend on its value - */ - es = (struct ext4_super_block *) (((char *)bh->b_data) + offset); - sbi->s_es = es; - sb->s_magic = le16_to_cpu(es->s_magic); - if (sb->s_magic != EXT4_SUPER_MAGIC) - goto cantfind_ext4; - - /* Set defaults before we parse the mount options */ - def_mount_opts = le32_to_cpu(es->s_default_mount_opts); - if (def_mount_opts & EXT4_DEFM_DEBUG) - set_opt(sbi->s_mount_opt, DEBUG); - if (def_mount_opts & EXT4_DEFM_BSDGROUPS) - set_opt(sbi->s_mount_opt, GRPID); - if (def_mount_opts & EXT4_DEFM_UID16) - set_opt(sbi->s_mount_opt, NO_UID32); - if (def_mount_opts & EXT4_DEFM_XATTR_USER) - set_opt(sbi->s_mount_opt, XATTR_USER); - if (def_mount_opts & EXT4_DEFM_ACL) - set_opt(sbi->s_mount_opt, POSIX_ACL); - if ((def_mount_opts & EXT4_DEFM_JMODE) == EXT4_DEFM_JMODE_DATA) - sbi->s_mount_opt |= EXT4_MOUNT_JOURNAL_DATA; - else if ((def_mount_opts & EXT4_DEFM_JMODE) == EXT4_DEFM_JMODE_ORDERED) - sbi->s_mount_opt |= EXT4_MOUNT_ORDERED_DATA; - else if ((def_mount_opts & EXT4_DEFM_JMODE) == EXT4_DEFM_JMODE_WBACK) - sbi->s_mount_opt |= EXT4_MOUNT_WRITEBACK_DATA; - - if (le16_to_cpu(sbi->s_es->s_errors) == EXT4_ERRORS_PANIC) - set_opt(sbi->s_mount_opt, ERRORS_PANIC); - else if (le16_to_cpu(sbi->s_es->s_errors) == EXT4_ERRORS_RO) - set_opt(sbi->s_mount_opt, ERRORS_RO); - else - set_opt(sbi->s_mount_opt, ERRORS_CONT); - - sbi->s_resuid = le16_to_cpu(es->s_def_resuid); - sbi->s_resgid = le16_to_cpu(es->s_def_resgid); - - set_opt(sbi->s_mount_opt, RESERVATION); - - if (!parse_options ((char *) data, sb, &journal_inum, &journal_devnum, - NULL, 0)) - goto failed_mount; - - sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | - ((sbi->s_mount_opt & EXT4_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0); - - if (le32_to_cpu(es->s_rev_level) == EXT4_GOOD_OLD_REV && - (EXT4_HAS_COMPAT_FEATURE(sb, ~0U) || - EXT4_HAS_RO_COMPAT_FEATURE(sb, ~0U) || - EXT4_HAS_INCOMPAT_FEATURE(sb, ~0U))) - printk(KERN_WARNING - "EXT4-fs warning: feature flags set on rev 0 fs, " - "running e2fsck is recommended\n"); - /* - * Check feature flags regardless of the revision level, since we - * previously didn't change the revision level when setting the flags, - * so there is a chance incompat flags are set on a rev 0 filesystem. - */ - features = EXT4_HAS_INCOMPAT_FEATURE(sb, ~EXT4_FEATURE_INCOMPAT_SUPP); - if (features) { - printk(KERN_ERR "EXT4-fs: %s: couldn't mount because of " - "unsupported optional features (%x).\n", - sb->s_id, le32_to_cpu(features)); - goto failed_mount; - } - features = EXT4_HAS_RO_COMPAT_FEATURE(sb, ~EXT4_FEATURE_RO_COMPAT_SUPP); - if (!(sb->s_flags & MS_RDONLY) && features) { - printk(KERN_ERR "EXT4-fs: %s: couldn't mount RDWR because of " - "unsupported optional features (%x).\n", - sb->s_id, le32_to_cpu(features)); - goto failed_mount; - } - blocksize = BLOCK_SIZE << le32_to_cpu(es->s_log_block_size); - - if (blocksize < EXT4_MIN_BLOCK_SIZE || - blocksize > EXT4_MAX_BLOCK_SIZE) { - printk(KERN_ERR - "EXT4-fs: Unsupported filesystem blocksize %d on %s.\n", - blocksize, sb->s_id); - goto failed_mount; - } - - hblock = bdev_hardsect_size(sb->s_bdev); - if (sb->s_blocksize != blocksize) { - /* - * Make sure the blocksize for the filesystem is larger - * than the hardware sectorsize for the machine. - */ - if (blocksize < hblock) { - printk(KERN_ERR "EXT4-fs: blocksize %d too small for " - "device blocksize %d.\n", blocksize, hblock); - goto failed_mount; - } - - brelse (bh); - sb_set_blocksize(sb, blocksize); - logical_sb_block = sb_block * EXT4_MIN_BLOCK_SIZE; - offset = do_div(logical_sb_block, blocksize); - bh = sb_bread(sb, logical_sb_block); - if (!bh) { - printk(KERN_ERR - "EXT4-fs: Can't read superblock on 2nd try.\n"); - goto failed_mount; - } - es = (struct ext4_super_block *)(((char *)bh->b_data) + offset); - sbi->s_es = es; - if (es->s_magic != cpu_to_le16(EXT4_SUPER_MAGIC)) { - printk (KERN_ERR - "EXT4-fs: Magic mismatch, very weird !\n"); - goto failed_mount; - } - } - - sb->s_maxbytes = ext4_max_size(sb->s_blocksize_bits); - - if (le32_to_cpu(es->s_rev_level) == EXT4_GOOD_OLD_REV) { - sbi->s_inode_size = EXT4_GOOD_OLD_INODE_SIZE; - sbi->s_first_ino = EXT4_GOOD_OLD_FIRST_INO; - } else { - sbi->s_inode_size = le16_to_cpu(es->s_inode_size); - sbi->s_first_ino = le32_to_cpu(es->s_first_ino); - if ((sbi->s_inode_size < EXT4_GOOD_OLD_INODE_SIZE) || - (sbi->s_inode_size & (sbi->s_inode_size - 1)) || - (sbi->s_inode_size > blocksize)) { - printk (KERN_ERR - "EXT4-fs: unsupported inode size: %d\n", - sbi->s_inode_size); - goto failed_mount; - } - } - sbi->s_frag_size = EXT4_MIN_FRAG_SIZE << - le32_to_cpu(es->s_log_frag_size); - if (blocksize != sbi->s_frag_size) { - printk(KERN_ERR - "EXT4-fs: fragsize %lu != blocksize %u (unsupported)\n", - sbi->s_frag_size, blocksize); - goto failed_mount; - } - sbi->s_desc_size = le16_to_cpu(es->s_desc_size); - if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_64BIT)) { - if (sbi->s_desc_size < EXT4_MIN_DESC_SIZE_64BIT || - sbi->s_desc_size > EXT4_MAX_DESC_SIZE || - sbi->s_desc_size & (sbi->s_desc_size - 1)) { - printk(KERN_ERR - "EXT4-fs: unsupported descriptor size %lu\n", - sbi->s_desc_size); - goto failed_mount; - } - } else - sbi->s_desc_size = EXT4_MIN_DESC_SIZE; - sbi->s_blocks_per_group = le32_to_cpu(es->s_blocks_per_group); - sbi->s_frags_per_group = le32_to_cpu(es->s_frags_per_group); - sbi->s_inodes_per_group = le32_to_cpu(es->s_inodes_per_group); - if (EXT4_INODE_SIZE(sb) == 0) - goto cantfind_ext4; - sbi->s_inodes_per_block = blocksize / EXT4_INODE_SIZE(sb); - if (sbi->s_inodes_per_block == 0) - goto cantfind_ext4; - sbi->s_itb_per_group = sbi->s_inodes_per_group / - sbi->s_inodes_per_block; - sbi->s_desc_per_block = blocksize / EXT4_DESC_SIZE(sb); - sbi->s_sbh = bh; - sbi->s_mount_state = le16_to_cpu(es->s_state); - sbi->s_addr_per_block_bits = log2(EXT4_ADDR_PER_BLOCK(sb)); - sbi->s_desc_per_block_bits = log2(EXT4_DESC_PER_BLOCK(sb)); - for (i=0; i < 4; i++) - sbi->s_hash_seed[i] = le32_to_cpu(es->s_hash_seed[i]); - sbi->s_def_hash_version = es->s_def_hash_version; - - if (sbi->s_blocks_per_group > blocksize * 8) { - printk (KERN_ERR - "EXT4-fs: #blocks per group too big: %lu\n", - sbi->s_blocks_per_group); - goto failed_mount; - } - if (sbi->s_frags_per_group > blocksize * 8) { - printk (KERN_ERR - "EXT4-fs: #fragments per group too big: %lu\n", - sbi->s_frags_per_group); - goto failed_mount; - } - if (sbi->s_inodes_per_group > blocksize * 8) { - printk (KERN_ERR - "EXT4-fs: #inodes per group too big: %lu\n", - sbi->s_inodes_per_group); - goto failed_mount; - } - - if (ext4_blocks_count(es) > - (sector_t)(~0ULL) >> (sb->s_blocksize_bits - 9)) { - printk(KERN_ERR "EXT4-fs: filesystem on %s:" - " too large to mount safely\n", sb->s_id); - if (sizeof(sector_t) < 8) - printk(KERN_WARNING "EXT4-fs: CONFIG_LBD not " - "enabled\n"); - goto failed_mount; - } - - if (EXT4_BLOCKS_PER_GROUP(sb) == 0) - goto cantfind_ext4; - blocks_count = (ext4_blocks_count(es) - - le32_to_cpu(es->s_first_data_block) + - EXT4_BLOCKS_PER_GROUP(sb) - 1); - do_div(blocks_count, EXT4_BLOCKS_PER_GROUP(sb)); - sbi->s_groups_count = blocks_count; - db_count = (sbi->s_groups_count + EXT4_DESC_PER_BLOCK(sb) - 1) / - EXT4_DESC_PER_BLOCK(sb); - sbi->s_group_desc = kmalloc(db_count * sizeof (struct buffer_head *), - GFP_KERNEL); - if (sbi->s_group_desc == NULL) { - printk (KERN_ERR "EXT4-fs: not enough memory\n"); - goto failed_mount; - } - - bgl_lock_init(&sbi->s_blockgroup_lock); - - for (i = 0; i < db_count; i++) { - block = descriptor_loc(sb, logical_sb_block, i); - sbi->s_group_desc[i] = sb_bread(sb, block); - if (!sbi->s_group_desc[i]) { - printk (KERN_ERR "EXT4-fs: " - "can't read group descriptor %d\n", i); - db_count = i; - goto failed_mount2; - } - } - if (!ext4_check_descriptors (sb)) { - printk(KERN_ERR "EXT4-fs: group descriptors corrupted!\n"); - goto failed_mount2; - } - sbi->s_gdb_count = db_count; - get_random_bytes(&sbi->s_next_generation, sizeof(u32)); - spin_lock_init(&sbi->s_next_gen_lock); - - percpu_counter_init(&sbi->s_freeblocks_counter, - ext4_count_free_blocks(sb)); - percpu_counter_init(&sbi->s_freeinodes_counter, - ext4_count_free_inodes(sb)); - percpu_counter_init(&sbi->s_dirs_counter, - ext4_count_dirs(sb)); - - /* per fileystem reservation list head & lock */ - spin_lock_init(&sbi->s_rsv_window_lock); - sbi->s_rsv_window_root = RB_ROOT; - /* Add a single, static dummy reservation to the start of the - * reservation window list --- it gives us a placeholder for - * append-at-start-of-list which makes the allocation logic - * _much_ simpler. */ - sbi->s_rsv_window_head.rsv_start = EXT4_RESERVE_WINDOW_NOT_ALLOCATED; - sbi->s_rsv_window_head.rsv_end = EXT4_RESERVE_WINDOW_NOT_ALLOCATED; - sbi->s_rsv_window_head.rsv_alloc_hit = 0; - sbi->s_rsv_window_head.rsv_goal_size = 0; - ext4_rsv_window_add(sb, &sbi->s_rsv_window_head); - - /* - * set up enough so that it can read an inode - */ - sb->s_op = &ext4_sops; - sb->s_export_op = &ext4_export_ops; - sb->s_xattr = ext4_xattr_handlers; -#ifdef CONFIG_QUOTA - sb->s_qcop = &ext4_qctl_operations; - sb->dq_op = &ext4_quota_operations; -#endif - INIT_LIST_HEAD(&sbi->s_orphan); /* unlinked but open files */ - - sb->s_root = NULL; - - needs_recovery = (es->s_last_orphan != 0 || - EXT4_HAS_INCOMPAT_FEATURE(sb, - EXT4_FEATURE_INCOMPAT_RECOVER)); - - /* - * The first inode we look at is the journal inode. Don't try - * root first: it may be modified in the journal! - */ - if (!test_opt(sb, NOLOAD) && - EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL)) { - if (ext4_load_journal(sb, es, journal_devnum)) - goto failed_mount3; - } else if (journal_inum) { - if (ext4_create_journal(sb, es, journal_inum)) - goto failed_mount3; - } else { - if (!silent) - printk (KERN_ERR - "ext4: No journal on filesystem on %s\n", - sb->s_id); - goto failed_mount3; - } - - /* We have now updated the journal if required, so we can - * validate the data journaling mode. */ - switch (test_opt(sb, DATA_FLAGS)) { - case 0: - /* No mode set, assume a default based on the journal - * capabilities: ORDERED_DATA if the journal can - * cope, else JOURNAL_DATA - */ - if (jbd2_journal_check_available_features - (sbi->s_journal, 0, 0, JBD2_FEATURE_INCOMPAT_REVOKE)) - set_opt(sbi->s_mount_opt, ORDERED_DATA); - else - set_opt(sbi->s_mount_opt, JOURNAL_DATA); - break; - - case EXT4_MOUNT_ORDERED_DATA: - case EXT4_MOUNT_WRITEBACK_DATA: - if (!jbd2_journal_check_available_features - (sbi->s_journal, 0, 0, JBD2_FEATURE_INCOMPAT_REVOKE)) { - printk(KERN_ERR "EXT4-fs: Journal does not support " - "requested data journaling mode\n"); - goto failed_mount4; - } - default: - break; - } - - if (test_opt(sb, NOBH)) { - if (!(test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA)) { - printk(KERN_WARNING "EXT4-fs: Ignoring nobh option - " - "its supported only with writeback mode\n"); - clear_opt(sbi->s_mount_opt, NOBH); - } - } - /* - * The jbd2_journal_load will have done any necessary log recovery, - * so we can safely mount the rest of the filesystem now. - */ - - root = iget(sb, EXT4_ROOT_INO); - sb->s_root = d_alloc_root(root); - if (!sb->s_root) { - printk(KERN_ERR "EXT4-fs: get root inode failed\n"); - iput(root); - goto failed_mount4; - } - if (!S_ISDIR(root->i_mode) || !root->i_blocks || !root->i_size) { - dput(sb->s_root); - sb->s_root = NULL; - printk(KERN_ERR "EXT4-fs: corrupt root inode, run e2fsck\n"); - goto failed_mount4; - } - - ext4_setup_super (sb, es, sb->s_flags & MS_RDONLY); - /* - * akpm: core read_super() calls in here with the superblock locked. - * That deadlocks, because orphan cleanup needs to lock the superblock - * in numerous places. Here we just pop the lock - it's relatively - * harmless, because we are now ready to accept write_super() requests, - * and aviro says that's the only reason for hanging onto the - * superblock lock. - */ - EXT4_SB(sb)->s_mount_state |= EXT4_ORPHAN_FS; - ext4_orphan_cleanup(sb, es); - EXT4_SB(sb)->s_mount_state &= ~EXT4_ORPHAN_FS; - if (needs_recovery) - printk (KERN_INFO "EXT4-fs: recovery complete.\n"); - ext4_mark_recovery_complete(sb, es); - printk (KERN_INFO "EXT4-fs: mounted filesystem with %s data mode.\n", - test_opt(sb,DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA ? "journal": - test_opt(sb,DATA_FLAGS) == EXT4_MOUNT_ORDERED_DATA ? "ordered": - "writeback"); - - ext4_ext_init(sb); - - lock_kernel(); - return 0; - -cantfind_ext4: - if (!silent) - printk(KERN_ERR "VFS: Can't find ext4 filesystem on dev %s.\n", - sb->s_id); - goto failed_mount; - -failed_mount4: - jbd2_journal_destroy(sbi->s_journal); -failed_mount3: - percpu_counter_destroy(&sbi->s_freeblocks_counter); - percpu_counter_destroy(&sbi->s_freeinodes_counter); - percpu_counter_destroy(&sbi->s_dirs_counter); -failed_mount2: - for (i = 0; i < db_count; i++) - brelse(sbi->s_group_desc[i]); - kfree(sbi->s_group_desc); -failed_mount: -#ifdef CONFIG_QUOTA - for (i = 0; i < MAXQUOTAS; i++) - kfree(sbi->s_qf_names[i]); -#endif - ext4_blkdev_remove(sbi); - brelse(bh); -out_fail: - sb->s_fs_info = NULL; - kfree(sbi); - lock_kernel(); - return -EINVAL; -} - -/* - * Setup any per-fs journal parameters now. We'll do this both on - * initial mount, once the journal has been initialised but before we've - * done any recovery; and again on any subsequent remount. - */ -static void ext4_init_journal_params(struct super_block *sb, journal_t *journal) -{ - struct ext4_sb_info *sbi = EXT4_SB(sb); - - if (sbi->s_commit_interval) - journal->j_commit_interval = sbi->s_commit_interval; - /* We could also set up an ext4-specific default for the commit - * interval here, but for now we'll just fall back to the jbd - * default. */ - - spin_lock(&journal->j_state_lock); - if (test_opt(sb, BARRIER)) - journal->j_flags |= JBD2_BARRIER; - else - journal->j_flags &= ~JBD2_BARRIER; - spin_unlock(&journal->j_state_lock); -} - -static journal_t *ext4_get_journal(struct super_block *sb, - unsigned int journal_inum) -{ - struct inode *journal_inode; - journal_t *journal; - - /* First, test for the existence of a valid inode on disk. Bad - * things happen if we iget() an unused inode, as the subsequent - * iput() will try to delete it. */ - - journal_inode = iget(sb, journal_inum); - if (!journal_inode) { - printk(KERN_ERR "EXT4-fs: no journal found.\n"); - return NULL; - } - if (!journal_inode->i_nlink) { - make_bad_inode(journal_inode); - iput(journal_inode); - printk(KERN_ERR "EXT4-fs: journal inode is deleted.\n"); - return NULL; - } - - jbd_debug(2, "Journal inode found at %p: %Ld bytes\n", - journal_inode, journal_inode->i_size); - if (is_bad_inode(journal_inode) || !S_ISREG(journal_inode->i_mode)) { - printk(KERN_ERR "EXT4-fs: invalid journal inode.\n"); - iput(journal_inode); - return NULL; - } - - journal = jbd2_journal_init_inode(journal_inode); - if (!journal) { - printk(KERN_ERR "EXT4-fs: Could not load journal inode\n"); - iput(journal_inode); - return NULL; - } - journal->j_private = sb; - ext4_init_journal_params(sb, journal); - return journal; -} - -static journal_t *ext4_get_dev_journal(struct super_block *sb, - dev_t j_dev) -{ - struct buffer_head * bh; - journal_t *journal; - ext4_fsblk_t start; - ext4_fsblk_t len; - int hblock, blocksize; - ext4_fsblk_t sb_block; - unsigned long offset; - struct ext4_super_block * es; - struct block_device *bdev; - - bdev = ext4_blkdev_get(j_dev); - if (bdev == NULL) - return NULL; - - if (bd_claim(bdev, sb)) { - printk(KERN_ERR - "EXT4: failed to claim external journal device.\n"); - blkdev_put(bdev); - return NULL; - } - - blocksize = sb->s_blocksize; - hblock = bdev_hardsect_size(bdev); - if (blocksize < hblock) { - printk(KERN_ERR - "EXT4-fs: blocksize too small for journal device.\n"); - goto out_bdev; - } - - sb_block = EXT4_MIN_BLOCK_SIZE / blocksize; - offset = EXT4_MIN_BLOCK_SIZE % blocksize; - set_blocksize(bdev, blocksize); - if (!(bh = __bread(bdev, sb_block, blocksize))) { - printk(KERN_ERR "EXT4-fs: couldn't read superblock of " - "external journal\n"); - goto out_bdev; - } - - es = (struct ext4_super_block *) (((char *)bh->b_data) + offset); - if ((le16_to_cpu(es->s_magic) != EXT4_SUPER_MAGIC) || - !(le32_to_cpu(es->s_feature_incompat) & - EXT4_FEATURE_INCOMPAT_JOURNAL_DEV)) { - printk(KERN_ERR "EXT4-fs: external journal has " - "bad superblock\n"); - brelse(bh); - goto out_bdev; - } - - if (memcmp(EXT4_SB(sb)->s_es->s_journal_uuid, es->s_uuid, 16)) { - printk(KERN_ERR "EXT4-fs: journal UUID does not match\n"); - brelse(bh); - goto out_bdev; - } - - len = ext4_blocks_count(es); - start = sb_block + 1; - brelse(bh); /* we're done with the superblock */ - - journal = jbd2_journal_init_dev(bdev, sb->s_bdev, - start, len, blocksize); - if (!journal) { - printk(KERN_ERR "EXT4-fs: failed to create device journal\n"); - goto out_bdev; - } - journal->j_private = sb; - ll_rw_block(READ, 1, &journal->j_sb_buffer); - wait_on_buffer(journal->j_sb_buffer); - if (!buffer_uptodate(journal->j_sb_buffer)) { - printk(KERN_ERR "EXT4-fs: I/O error on journal device\n"); - goto out_journal; - } - if (be32_to_cpu(journal->j_superblock->s_nr_users) != 1) { - printk(KERN_ERR "EXT4-fs: External journal has more than one " - "user (unsupported) - %d\n", - be32_to_cpu(journal->j_superblock->s_nr_users)); - goto out_journal; - } - EXT4_SB(sb)->journal_bdev = bdev; - ext4_init_journal_params(sb, journal); - return journal; -out_journal: - jbd2_journal_destroy(journal); -out_bdev: - ext4_blkdev_put(bdev); - return NULL; -} - -static int ext4_load_journal(struct super_block *sb, - struct ext4_super_block *es, - unsigned long journal_devnum) -{ - journal_t *journal; - unsigned int journal_inum = le32_to_cpu(es->s_journal_inum); - dev_t journal_dev; - int err = 0; - int really_read_only; - - if (journal_devnum && - journal_devnum != le32_to_cpu(es->s_journal_dev)) { - printk(KERN_INFO "EXT4-fs: external journal device major/minor " - "numbers have changed\n"); - journal_dev = new_decode_dev(journal_devnum); - } else - journal_dev = new_decode_dev(le32_to_cpu(es->s_journal_dev)); - - really_read_only = bdev_read_only(sb->s_bdev); - - /* - * Are we loading a blank journal or performing recovery after a - * crash? For recovery, we need to check in advance whether we - * can get read-write access to the device. - */ - - if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER)) { - if (sb->s_flags & MS_RDONLY) { - printk(KERN_INFO "EXT4-fs: INFO: recovery " - "required on readonly filesystem.\n"); - if (really_read_only) { - printk(KERN_ERR "EXT4-fs: write access " - "unavailable, cannot proceed.\n"); - return -EROFS; - } - printk (KERN_INFO "EXT4-fs: write access will " - "be enabled during recovery.\n"); - } - } - - if (journal_inum && journal_dev) { - printk(KERN_ERR "EXT4-fs: filesystem has both journal " - "and inode journals!\n"); - return -EINVAL; - } - - if (journal_inum) { - if (!(journal = ext4_get_journal(sb, journal_inum))) - return -EINVAL; - } else { - if (!(journal = ext4_get_dev_journal(sb, journal_dev))) - return -EINVAL; - } - - if (!really_read_only && test_opt(sb, UPDATE_JOURNAL)) { - err = jbd2_journal_update_format(journal); - if (err) { - printk(KERN_ERR "EXT4-fs: error updating journal.\n"); - jbd2_journal_destroy(journal); - return err; - } - } - - if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER)) - err = jbd2_journal_wipe(journal, !really_read_only); - if (!err) - err = jbd2_journal_load(journal); - - if (err) { - printk(KERN_ERR "EXT4-fs: error loading journal.\n"); - jbd2_journal_destroy(journal); - return err; - } - - EXT4_SB(sb)->s_journal = journal; - ext4_clear_journal_err(sb, es); - - if (journal_devnum && - journal_devnum != le32_to_cpu(es->s_journal_dev)) { - es->s_journal_dev = cpu_to_le32(journal_devnum); - sb->s_dirt = 1; - - /* Make sure we flush the recovery flag to disk. */ - ext4_commit_super(sb, es, 1); - } - - return 0; -} - -static int ext4_create_journal(struct super_block * sb, - struct ext4_super_block * es, - unsigned int journal_inum) -{ - journal_t *journal; - - if (sb->s_flags & MS_RDONLY) { - printk(KERN_ERR "EXT4-fs: readonly filesystem when trying to " - "create journal.\n"); - return -EROFS; - } - - if (!(journal = ext4_get_journal(sb, journal_inum))) - return -EINVAL; - - printk(KERN_INFO "EXT4-fs: creating new journal on inode %u\n", - journal_inum); - - if (jbd2_journal_create(journal)) { - printk(KERN_ERR "EXT4-fs: error creating journal.\n"); - jbd2_journal_destroy(journal); - return -EIO; - } - - EXT4_SB(sb)->s_journal = journal; - - ext4_update_dynamic_rev(sb); - EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); - EXT4_SET_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL); - - es->s_journal_inum = cpu_to_le32(journal_inum); - sb->s_dirt = 1; - - /* Make sure we flush the recovery flag to disk. */ - ext4_commit_super(sb, es, 1); - - return 0; -} - -static void ext4_commit_super (struct super_block * sb, - struct ext4_super_block * es, - int sync) -{ - struct buffer_head *sbh = EXT4_SB(sb)->s_sbh; - - if (!sbh) - return; - es->s_wtime = cpu_to_le32(get_seconds()); - ext4_free_blocks_count_set(es, ext4_count_free_blocks(sb)); - es->s_free_inodes_count = cpu_to_le32(ext4_count_free_inodes(sb)); - BUFFER_TRACE(sbh, "marking dirty"); - mark_buffer_dirty(sbh); - if (sync) - sync_dirty_buffer(sbh); -} - - -/* - * Have we just finished recovery? If so, and if we are mounting (or - * remounting) the filesystem readonly, then we will end up with a - * consistent fs on disk. Record that fact. - */ -static void ext4_mark_recovery_complete(struct super_block * sb, - struct ext4_super_block * es) -{ - journal_t *journal = EXT4_SB(sb)->s_journal; - - jbd2_journal_lock_updates(journal); - jbd2_journal_flush(journal); - if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER) && - sb->s_flags & MS_RDONLY) { - EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); - sb->s_dirt = 0; - ext4_commit_super(sb, es, 1); - } - jbd2_journal_unlock_updates(journal); -} - -/* - * If we are mounting (or read-write remounting) a filesystem whose journal - * has recorded an error from a previous lifetime, move that error to the - * main filesystem now. - */ -static void ext4_clear_journal_err(struct super_block * sb, - struct ext4_super_block * es) -{ - journal_t *journal; - int j_errno; - const char *errstr; - - journal = EXT4_SB(sb)->s_journal; - - /* - * Now check for any error status which may have been recorded in the - * journal by a prior ext4_error() or ext4_abort() - */ - - j_errno = jbd2_journal_errno(journal); - if (j_errno) { - char nbuf[16]; - - errstr = ext4_decode_error(sb, j_errno, nbuf); - ext4_warning(sb, __FUNCTION__, "Filesystem error recorded " - "from previous mount: %s", errstr); - ext4_warning(sb, __FUNCTION__, "Marking fs in need of " - "filesystem check."); - - EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; - es->s_state |= cpu_to_le16(EXT4_ERROR_FS); - ext4_commit_super (sb, es, 1); - - jbd2_journal_clear_err(journal); - } -} - -/* - * Force the running and committing transactions to commit, - * and wait on the commit. - */ -int ext4_force_commit(struct super_block *sb) -{ - journal_t *journal; - int ret; - - if (sb->s_flags & MS_RDONLY) - return 0; - - journal = EXT4_SB(sb)->s_journal; - sb->s_dirt = 0; - ret = ext4_journal_force_commit(journal); - return ret; -} - -/* - * Ext4 always journals updates to the superblock itself, so we don't - * have to propagate any other updates to the superblock on disk at this - * point. Just start an async writeback to get the buffers on their way - * to the disk. - * - * This implicitly triggers the writebehind on sync(). - */ - -static void ext4_write_super (struct super_block * sb) -{ - if (mutex_trylock(&sb->s_lock) != 0) - BUG(); - sb->s_dirt = 0; -} - -static int ext4_sync_fs(struct super_block *sb, int wait) -{ - tid_t target; - - sb->s_dirt = 0; - if (jbd2_journal_start_commit(EXT4_SB(sb)->s_journal, &target)) { - if (wait) - jbd2_log_wait_commit(EXT4_SB(sb)->s_journal, target); - } - return 0; -} - -/* - * LVM calls this function before a (read-only) snapshot is created. This - * gives us a chance to flush the journal completely and mark the fs clean. - */ -static void ext4_write_super_lockfs(struct super_block *sb) -{ - sb->s_dirt = 0; - - if (!(sb->s_flags & MS_RDONLY)) { - journal_t *journal = EXT4_SB(sb)->s_journal; - - /* Now we set up the journal barrier. */ - jbd2_journal_lock_updates(journal); - jbd2_journal_flush(journal); - - /* Journal blocked and flushed, clear needs_recovery flag. */ - EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); - ext4_commit_super(sb, EXT4_SB(sb)->s_es, 1); - } -} - -/* - * Called by LVM after the snapshot is done. We need to reset the RECOVER - * flag here, even though the filesystem is not technically dirty yet. - */ -static void ext4_unlockfs(struct super_block *sb) -{ - if (!(sb->s_flags & MS_RDONLY)) { - lock_super(sb); - /* Reser the needs_recovery flag before the fs is unlocked. */ - EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); - ext4_commit_super(sb, EXT4_SB(sb)->s_es, 1); - unlock_super(sb); - jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); - } -} - -static int ext4_remount (struct super_block * sb, int * flags, char * data) -{ - struct ext4_super_block * es; - struct ext4_sb_info *sbi = EXT4_SB(sb); - ext4_fsblk_t n_blocks_count = 0; - unsigned long old_sb_flags; - struct ext4_mount_options old_opts; - int err; -#ifdef CONFIG_QUOTA - int i; -#endif - - /* Store the original options */ - old_sb_flags = sb->s_flags; - old_opts.s_mount_opt = sbi->s_mount_opt; - old_opts.s_resuid = sbi->s_resuid; - old_opts.s_resgid = sbi->s_resgid; - old_opts.s_commit_interval = sbi->s_commit_interval; -#ifdef CONFIG_QUOTA - old_opts.s_jquota_fmt = sbi->s_jquota_fmt; - for (i = 0; i < MAXQUOTAS; i++) - old_opts.s_qf_names[i] = sbi->s_qf_names[i]; -#endif - - /* - * Allow the "check" option to be passed as a remount option. - */ - if (!parse_options(data, sb, NULL, NULL, &n_blocks_count, 1)) { - err = -EINVAL; - goto restore_opts; - } - - if (sbi->s_mount_opt & EXT4_MOUNT_ABORT) - ext4_abort(sb, __FUNCTION__, "Abort forced by user"); - - sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | - ((sbi->s_mount_opt & EXT4_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0); - - es = sbi->s_es; - - ext4_init_journal_params(sb, sbi->s_journal); - - if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY) || - n_blocks_count > ext4_blocks_count(es)) { - if (sbi->s_mount_opt & EXT4_MOUNT_ABORT) { - err = -EROFS; - goto restore_opts; - } - - if (*flags & MS_RDONLY) { - /* - * First of all, the unconditional stuff we have to do - * to disable replay of the journal when we next remount - */ - sb->s_flags |= MS_RDONLY; - - /* - * OK, test if we are remounting a valid rw partition - * readonly, and if so set the rdonly flag and then - * mark the partition as valid again. - */ - if (!(es->s_state & cpu_to_le16(EXT4_VALID_FS)) && - (sbi->s_mount_state & EXT4_VALID_FS)) - es->s_state = cpu_to_le16(sbi->s_mount_state); - - ext4_mark_recovery_complete(sb, es); - } else { - __le32 ret; - if ((ret = EXT4_HAS_RO_COMPAT_FEATURE(sb, - ~EXT4_FEATURE_RO_COMPAT_SUPP))) { - printk(KERN_WARNING "EXT4-fs: %s: couldn't " - "remount RDWR because of unsupported " - "optional features (%x).\n", - sb->s_id, le32_to_cpu(ret)); - err = -EROFS; - goto restore_opts; - } - /* - * Mounting a RDONLY partition read-write, so reread - * and store the current valid flag. (It may have - * been changed by e2fsck since we originally mounted - * the partition.) - */ - ext4_clear_journal_err(sb, es); - sbi->s_mount_state = le16_to_cpu(es->s_state); - if ((err = ext4_group_extend(sb, es, n_blocks_count))) - goto restore_opts; - if (!ext4_setup_super (sb, es, 0)) - sb->s_flags &= ~MS_RDONLY; - } - } -#ifdef CONFIG_QUOTA - /* Release old quota file names */ - for (i = 0; i < MAXQUOTAS; i++) - if (old_opts.s_qf_names[i] && - old_opts.s_qf_names[i] != sbi->s_qf_names[i]) - kfree(old_opts.s_qf_names[i]); -#endif - return 0; -restore_opts: - sb->s_flags = old_sb_flags; - sbi->s_mount_opt = old_opts.s_mount_opt; - sbi->s_resuid = old_opts.s_resuid; - sbi->s_resgid = old_opts.s_resgid; - sbi->s_commit_interval = old_opts.s_commit_interval; -#ifdef CONFIG_QUOTA - sbi->s_jquota_fmt = old_opts.s_jquota_fmt; - for (i = 0; i < MAXQUOTAS; i++) { - if (sbi->s_qf_names[i] && - old_opts.s_qf_names[i] != sbi->s_qf_names[i]) - kfree(sbi->s_qf_names[i]); - sbi->s_qf_names[i] = old_opts.s_qf_names[i]; - } -#endif - return err; -} - -static int ext4_statfs (struct dentry * dentry, struct kstatfs * buf) -{ - struct super_block *sb = dentry->d_sb; - struct ext4_sb_info *sbi = EXT4_SB(sb); - struct ext4_super_block *es = sbi->s_es; - ext4_fsblk_t overhead; - int i; - - if (test_opt (sb, MINIX_DF)) - overhead = 0; - else { - unsigned long ngroups; - ngroups = EXT4_SB(sb)->s_groups_count; - smp_rmb(); - - /* - * Compute the overhead (FS structures) - */ - - /* - * All of the blocks before first_data_block are - * overhead - */ - overhead = le32_to_cpu(es->s_first_data_block); - - /* - * Add the overhead attributed to the superblock and - * block group descriptors. If the sparse superblocks - * feature is turned on, then not all groups have this. - */ - for (i = 0; i < ngroups; i++) { - overhead += ext4_bg_has_super(sb, i) + - ext4_bg_num_gdb(sb, i); - cond_resched(); - } - - /* - * Every block group has an inode bitmap, a block - * bitmap, and an inode table. - */ - overhead += (ngroups * (2 + EXT4_SB(sb)->s_itb_per_group)); - } - - buf->f_type = EXT4_SUPER_MAGIC; - buf->f_bsize = sb->s_blocksize; - buf->f_blocks = ext4_blocks_count(es) - overhead; - buf->f_bfree = percpu_counter_sum(&sbi->s_freeblocks_counter); - buf->f_bavail = buf->f_bfree - ext4_r_blocks_count(es); - if (buf->f_bfree < ext4_r_blocks_count(es)) - buf->f_bavail = 0; - 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; - return 0; -} - -/* Helper function for writing quotas on sync - we need to start transaction before quota file - * is locked for write. Otherwise the are possible deadlocks: - * Process 1 Process 2 - * ext4_create() quota_sync() - * jbd2_journal_start() write_dquot() - * DQUOT_INIT() down(dqio_mutex) - * down(dqio_mutex) jbd2_journal_start() - * - */ - -#ifdef CONFIG_QUOTA - -static inline struct inode *dquot_to_inode(struct dquot *dquot) -{ - return sb_dqopt(dquot->dq_sb)->files[dquot->dq_type]; -} - -static int ext4_dquot_initialize(struct inode *inode, int type) -{ - handle_t *handle; - int ret, err; - - /* We may create quota structure so we need to reserve enough blocks */ - handle = ext4_journal_start(inode, 2*EXT4_QUOTA_INIT_BLOCKS(inode->i_sb)); - if (IS_ERR(handle)) - return PTR_ERR(handle); - ret = dquot_initialize(inode, type); - err = ext4_journal_stop(handle); - if (!ret) - ret = err; - return ret; -} - -static int ext4_dquot_drop(struct inode *inode) -{ - handle_t *handle; - int ret, err; - - /* We may delete quota structure so we need to reserve enough blocks */ - handle = ext4_journal_start(inode, 2*EXT4_QUOTA_DEL_BLOCKS(inode->i_sb)); - if (IS_ERR(handle)) - return PTR_ERR(handle); - ret = dquot_drop(inode); - err = ext4_journal_stop(handle); - if (!ret) - ret = err; - return ret; -} - -static int ext4_write_dquot(struct dquot *dquot) -{ - int ret, err; - handle_t *handle; - struct inode *inode; - - inode = dquot_to_inode(dquot); - handle = ext4_journal_start(inode, - EXT4_QUOTA_TRANS_BLOCKS(dquot->dq_sb)); - if (IS_ERR(handle)) - return PTR_ERR(handle); - ret = dquot_commit(dquot); - err = ext4_journal_stop(handle); - if (!ret) - ret = err; - return ret; -} - -static int ext4_acquire_dquot(struct dquot *dquot) -{ - int ret, err; - handle_t *handle; - - handle = ext4_journal_start(dquot_to_inode(dquot), - EXT4_QUOTA_INIT_BLOCKS(dquot->dq_sb)); - if (IS_ERR(handle)) - return PTR_ERR(handle); - ret = dquot_acquire(dquot); - err = ext4_journal_stop(handle); - if (!ret) - ret = err; - return ret; -} - -static int ext4_release_dquot(struct dquot *dquot) -{ - int ret, err; - handle_t *handle; - - handle = ext4_journal_start(dquot_to_inode(dquot), - EXT4_QUOTA_DEL_BLOCKS(dquot->dq_sb)); - if (IS_ERR(handle)) - return PTR_ERR(handle); - ret = dquot_release(dquot); - err = ext4_journal_stop(handle); - if (!ret) - ret = err; - return ret; -} - -static int ext4_mark_dquot_dirty(struct dquot *dquot) -{ - /* Are we journalling quotas? */ - if (EXT4_SB(dquot->dq_sb)->s_qf_names[USRQUOTA] || - EXT4_SB(dquot->dq_sb)->s_qf_names[GRPQUOTA]) { - dquot_mark_dquot_dirty(dquot); - return ext4_write_dquot(dquot); - } else { - return dquot_mark_dquot_dirty(dquot); - } -} - -static int ext4_write_info(struct super_block *sb, int type) -{ - int ret, err; - handle_t *handle; - - /* Data block + inode block */ - handle = ext4_journal_start(sb->s_root->d_inode, 2); - if (IS_ERR(handle)) - return PTR_ERR(handle); - ret = dquot_commit_info(sb, type); - err = ext4_journal_stop(handle); - if (!ret) - ret = err; - return ret; -} - -/* - * Turn on quotas during mount time - we need to find - * the quota file and such... - */ -static int ext4_quota_on_mount(struct super_block *sb, int type) -{ - return vfs_quota_on_mount(sb, EXT4_SB(sb)->s_qf_names[type], - EXT4_SB(sb)->s_jquota_fmt, type); -} - -/* - * Standard function to be called on quota_on - */ -static int ext4_quota_on(struct super_block *sb, int type, int format_id, - char *path) -{ - int err; - struct nameidata nd; - - if (!test_opt(sb, QUOTA)) - return -EINVAL; - /* Not journalling quota? */ - if (!EXT4_SB(sb)->s_qf_names[USRQUOTA] && - !EXT4_SB(sb)->s_qf_names[GRPQUOTA]) - return vfs_quota_on(sb, type, format_id, path); - err = path_lookup(path, LOOKUP_FOLLOW, &nd); - if (err) - return err; - /* Quotafile not on the same filesystem? */ - if (nd.mnt->mnt_sb != sb) { - path_release(&nd); - return -EXDEV; - } - /* Quotafile not of fs root? */ - if (nd.dentry->d_parent->d_inode != sb->s_root->d_inode) - printk(KERN_WARNING - "EXT4-fs: Quota file not on filesystem root. " - "Journalled quota will not work.\n"); - path_release(&nd); - return vfs_quota_on(sb, type, format_id, path); -} - -/* Read data from quotafile - avoid pagecache and such because we cannot afford - * acquiring the locks... As quota files are never truncated and quota code - * itself serializes the operations (and noone else should touch the files) - * we don't have to be afraid of races */ -static ssize_t ext4_quota_read(struct super_block *sb, int type, char *data, - size_t len, loff_t off) -{ - struct inode *inode = sb_dqopt(sb)->files[type]; - sector_t blk = off >> EXT4_BLOCK_SIZE_BITS(sb); - int err = 0; - int offset = off & (sb->s_blocksize - 1); - int tocopy; - size_t toread; - struct buffer_head *bh; - loff_t i_size = i_size_read(inode); - - if (off > i_size) - return 0; - if (off+len > i_size) - len = i_size-off; - toread = len; - while (toread > 0) { - tocopy = sb->s_blocksize - offset < toread ? - sb->s_blocksize - offset : toread; - bh = ext4_bread(NULL, inode, blk, 0, &err); - if (err) - return err; - if (!bh) /* A hole? */ - memset(data, 0, tocopy); - else - memcpy(data, bh->b_data+offset, tocopy); - brelse(bh); - offset = 0; - toread -= tocopy; - data += tocopy; - blk++; - } - return len; -} - -/* Write to quotafile (we know the transaction is already started and has - * enough credits) */ -static ssize_t ext4_quota_write(struct super_block *sb, int type, - const char *data, size_t len, loff_t off) -{ - struct inode *inode = sb_dqopt(sb)->files[type]; - sector_t blk = off >> EXT4_BLOCK_SIZE_BITS(sb); - int err = 0; - int offset = off & (sb->s_blocksize - 1); - int tocopy; - int journal_quota = EXT4_SB(sb)->s_qf_names[type] != NULL; - size_t towrite = len; - struct buffer_head *bh; - handle_t *handle = journal_current_handle(); - - mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA); - while (towrite > 0) { - tocopy = sb->s_blocksize - offset < towrite ? - sb->s_blocksize - offset : towrite; - bh = ext4_bread(handle, inode, blk, 1, &err); - if (!bh) - goto out; - if (journal_quota) { - err = ext4_journal_get_write_access(handle, bh); - if (err) { - brelse(bh); - goto out; - } - } - lock_buffer(bh); - memcpy(bh->b_data+offset, data, tocopy); - flush_dcache_page(bh->b_page); - unlock_buffer(bh); - if (journal_quota) - err = ext4_journal_dirty_metadata(handle, bh); - else { - /* Always do at least ordered writes for quotas */ - err = ext4_journal_dirty_data(handle, bh); - mark_buffer_dirty(bh); - } - brelse(bh); - if (err) - goto out; - offset = 0; - towrite -= tocopy; - data += tocopy; - blk++; - } -out: - if (len == towrite) - return err; - if (inode->i_size < off+len-towrite) { - i_size_write(inode, off+len-towrite); - EXT4_I(inode)->i_disksize = inode->i_size; - } - inode->i_version++; - inode->i_mtime = inode->i_ctime = CURRENT_TIME; - ext4_mark_inode_dirty(handle, inode); - mutex_unlock(&inode->i_mutex); - return len - towrite; -} - -#endif - -static int ext4_get_sb(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data, struct vfsmount *mnt) -{ - return get_sb_bdev(fs_type, flags, dev_name, data, ext4_fill_super, mnt); -} - -static struct file_system_type ext4dev_fs_type = { - .owner = THIS_MODULE, - .name = "ext4dev", - .get_sb = ext4_get_sb, - .kill_sb = kill_block_super, - .fs_flags = FS_REQUIRES_DEV, -}; - -static int __init init_ext4_fs(void) -{ - int err = init_ext4_xattr(); - if (err) - return err; - err = init_inodecache(); - if (err) - goto out1; - err = register_filesystem(&ext4dev_fs_type); - if (err) - goto out; - return 0; -out: - destroy_inodecache(); -out1: - exit_ext4_xattr(); - return err; -} - -static void __exit exit_ext4_fs(void) -{ - unregister_filesystem(&ext4dev_fs_type); - destroy_inodecache(); - exit_ext4_xattr(); -} - -MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others"); -MODULE_DESCRIPTION("Fourth Extended Filesystem with extents"); -MODULE_LICENSE("GPL"); -module_init(init_ext4_fs) -module_exit(exit_ext4_fs) diff --git a/trunk/fs/ext4/symlink.c b/trunk/fs/ext4/symlink.c deleted file mode 100644 index fcf527286d75..000000000000 --- a/trunk/fs/ext4/symlink.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * linux/fs/ext4/symlink.c - * - * Only fast symlinks left here - the rest is done by generic code. AV, 1999 - * - * Copyright (C) 1992, 1993, 1994, 1995 - * Remy Card (card@masi.ibp.fr) - * Laboratoire MASI - Institut Blaise Pascal - * Universite Pierre et Marie Curie (Paris VI) - * - * from - * - * linux/fs/minix/symlink.c - * - * Copyright (C) 1991, 1992 Linus Torvalds - * - * ext4 symlink handling code - */ - -#include -#include -#include -#include -#include "xattr.h" - -static void * ext4_follow_link(struct dentry *dentry, struct nameidata *nd) -{ - struct ext4_inode_info *ei = EXT4_I(dentry->d_inode); - nd_set_link(nd, (char*)ei->i_data); - return NULL; -} - -struct inode_operations ext4_symlink_inode_operations = { - .readlink = generic_readlink, - .follow_link = page_follow_link_light, - .put_link = page_put_link, -#ifdef CONFIG_EXT4DEV_FS_XATTR - .setxattr = generic_setxattr, - .getxattr = generic_getxattr, - .listxattr = ext4_listxattr, - .removexattr = generic_removexattr, -#endif -}; - -struct inode_operations ext4_fast_symlink_inode_operations = { - .readlink = generic_readlink, - .follow_link = ext4_follow_link, -#ifdef CONFIG_EXT4DEV_FS_XATTR - .setxattr = generic_setxattr, - .getxattr = generic_getxattr, - .listxattr = ext4_listxattr, - .removexattr = generic_removexattr, -#endif -}; diff --git a/trunk/fs/ext4/xattr.c b/trunk/fs/ext4/xattr.c deleted file mode 100644 index 63233cd946a7..000000000000 --- a/trunk/fs/ext4/xattr.c +++ /dev/null @@ -1,1317 +0,0 @@ -/* - * linux/fs/ext4/xattr.c - * - * Copyright (C) 2001-2003 Andreas Gruenbacher, - * - * Fix by Harrison Xing . - * Ext4 code with a lot of help from Eric Jarman . - * Extended attributes for symlinks and special files added per - * suggestion of Luka Renko . - * xattr consolidation Copyright (c) 2004 James Morris , - * Red Hat Inc. - * ea-in-inode support by Alex Tomas aka bzzz - * and Andreas Gruenbacher . - */ - -/* - * Extended attributes are stored directly in inodes (on file systems with - * inodes bigger than 128 bytes) and on additional disk blocks. The i_file_acl - * field contains the block number if an inode uses an additional block. All - * attributes must fit in the inode and one additional block. Blocks that - * contain the identical set of attributes may be shared among several inodes. - * Identical blocks are detected by keeping a cache of blocks that have - * recently been accessed. - * - * The attributes in inodes and on blocks have a different header; the entries - * are stored in the same format: - * - * +------------------+ - * | header | - * | entry 1 | | - * | entry 2 | | growing downwards - * | entry 3 | v - * | four null bytes | - * | . . . | - * | value 1 | ^ - * | value 3 | | growing upwards - * | value 2 | | - * +------------------+ - * - * The header is followed by multiple entry descriptors. In disk blocks, the - * entry descriptors are kept sorted. In inodes, they are unsorted. The - * attribute values are aligned to the end of the block in no specific order. - * - * Locking strategy - * ---------------- - * EXT4_I(inode)->i_file_acl is protected by EXT4_I(inode)->xattr_sem. - * EA blocks are only changed if they are exclusive to an inode, so - * holding xattr_sem also means that nothing but the EA block's reference - * count can change. Multiple writers to the same block are synchronized - * by the buffer lock. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "xattr.h" -#include "acl.h" - -#define BHDR(bh) ((struct ext4_xattr_header *)((bh)->b_data)) -#define ENTRY(ptr) ((struct ext4_xattr_entry *)(ptr)) -#define BFIRST(bh) ENTRY(BHDR(bh)+1) -#define IS_LAST_ENTRY(entry) (*(__u32 *)(entry) == 0) - -#define IHDR(inode, raw_inode) \ - ((struct ext4_xattr_ibody_header *) \ - ((void *)raw_inode + \ - EXT4_GOOD_OLD_INODE_SIZE + \ - EXT4_I(inode)->i_extra_isize)) -#define IFIRST(hdr) ((struct ext4_xattr_entry *)((hdr)+1)) - -#ifdef EXT4_XATTR_DEBUG -# define ea_idebug(inode, f...) do { \ - printk(KERN_DEBUG "inode %s:%lu: ", \ - inode->i_sb->s_id, inode->i_ino); \ - printk(f); \ - printk("\n"); \ - } while (0) -# define ea_bdebug(bh, f...) do { \ - char b[BDEVNAME_SIZE]; \ - printk(KERN_DEBUG "block %s:%lu: ", \ - bdevname(bh->b_bdev, b), \ - (unsigned long) bh->b_blocknr); \ - printk(f); \ - printk("\n"); \ - } while (0) -#else -# define ea_idebug(f...) -# define ea_bdebug(f...) -#endif - -static void ext4_xattr_cache_insert(struct buffer_head *); -static struct buffer_head *ext4_xattr_cache_find(struct inode *, - struct ext4_xattr_header *, - struct mb_cache_entry **); -static void ext4_xattr_rehash(struct ext4_xattr_header *, - struct ext4_xattr_entry *); - -static struct mb_cache *ext4_xattr_cache; - -static struct xattr_handler *ext4_xattr_handler_map[] = { - [EXT4_XATTR_INDEX_USER] = &ext4_xattr_user_handler, -#ifdef CONFIG_EXT4DEV_FS_POSIX_ACL - [EXT4_XATTR_INDEX_POSIX_ACL_ACCESS] = &ext4_xattr_acl_access_handler, - [EXT4_XATTR_INDEX_POSIX_ACL_DEFAULT] = &ext4_xattr_acl_default_handler, -#endif - [EXT4_XATTR_INDEX_TRUSTED] = &ext4_xattr_trusted_handler, -#ifdef CONFIG_EXT4DEV_FS_SECURITY - [EXT4_XATTR_INDEX_SECURITY] = &ext4_xattr_security_handler, -#endif -}; - -struct xattr_handler *ext4_xattr_handlers[] = { - &ext4_xattr_user_handler, - &ext4_xattr_trusted_handler, -#ifdef CONFIG_EXT4DEV_FS_POSIX_ACL - &ext4_xattr_acl_access_handler, - &ext4_xattr_acl_default_handler, -#endif -#ifdef CONFIG_EXT4DEV_FS_SECURITY - &ext4_xattr_security_handler, -#endif - NULL -}; - -static inline struct xattr_handler * -ext4_xattr_handler(int name_index) -{ - struct xattr_handler *handler = NULL; - - if (name_index > 0 && name_index < ARRAY_SIZE(ext4_xattr_handler_map)) - handler = ext4_xattr_handler_map[name_index]; - return handler; -} - -/* - * Inode operation listxattr() - * - * dentry->d_inode->i_mutex: don't care - */ -ssize_t -ext4_listxattr(struct dentry *dentry, char *buffer, size_t size) -{ - return ext4_xattr_list(dentry->d_inode, buffer, size); -} - -static int -ext4_xattr_check_names(struct ext4_xattr_entry *entry, void *end) -{ - while (!IS_LAST_ENTRY(entry)) { - struct ext4_xattr_entry *next = EXT4_XATTR_NEXT(entry); - if ((void *)next >= end) - return -EIO; - entry = next; - } - return 0; -} - -static inline int -ext4_xattr_check_block(struct buffer_head *bh) -{ - int error; - - if (BHDR(bh)->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC) || - BHDR(bh)->h_blocks != cpu_to_le32(1)) - return -EIO; - error = ext4_xattr_check_names(BFIRST(bh), bh->b_data + bh->b_size); - return error; -} - -static inline int -ext4_xattr_check_entry(struct ext4_xattr_entry *entry, size_t size) -{ - size_t value_size = le32_to_cpu(entry->e_value_size); - - if (entry->e_value_block != 0 || value_size > size || - le16_to_cpu(entry->e_value_offs) + value_size > size) - return -EIO; - return 0; -} - -static int -ext4_xattr_find_entry(struct ext4_xattr_entry **pentry, int name_index, - const char *name, size_t size, int sorted) -{ - struct ext4_xattr_entry *entry; - size_t name_len; - int cmp = 1; - - if (name == NULL) - return -EINVAL; - name_len = strlen(name); - entry = *pentry; - for (; !IS_LAST_ENTRY(entry); entry = EXT4_XATTR_NEXT(entry)) { - cmp = name_index - entry->e_name_index; - if (!cmp) - cmp = name_len - entry->e_name_len; - if (!cmp) - cmp = memcmp(name, entry->e_name, name_len); - if (cmp <= 0 && (sorted || cmp == 0)) - break; - } - *pentry = entry; - if (!cmp && ext4_xattr_check_entry(entry, size)) - return -EIO; - return cmp ? -ENODATA : 0; -} - -static int -ext4_xattr_block_get(struct inode *inode, int name_index, const char *name, - void *buffer, size_t buffer_size) -{ - struct buffer_head *bh = NULL; - struct ext4_xattr_entry *entry; - size_t size; - int error; - - ea_idebug(inode, "name=%d.%s, buffer=%p, buffer_size=%ld", - name_index, name, buffer, (long)buffer_size); - - error = -ENODATA; - if (!EXT4_I(inode)->i_file_acl) - goto cleanup; - ea_idebug(inode, "reading block %u", EXT4_I(inode)->i_file_acl); - bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl); - if (!bh) - goto cleanup; - ea_bdebug(bh, "b_count=%d, refcount=%d", - atomic_read(&(bh->b_count)), le32_to_cpu(BHDR(bh)->h_refcount)); - if (ext4_xattr_check_block(bh)) { -bad_block: ext4_error(inode->i_sb, __FUNCTION__, - "inode %lu: bad block %llu", inode->i_ino, - EXT4_I(inode)->i_file_acl); - error = -EIO; - goto cleanup; - } - ext4_xattr_cache_insert(bh); - entry = BFIRST(bh); - error = ext4_xattr_find_entry(&entry, name_index, name, bh->b_size, 1); - if (error == -EIO) - goto bad_block; - if (error) - goto cleanup; - size = le32_to_cpu(entry->e_value_size); - if (buffer) { - error = -ERANGE; - if (size > buffer_size) - goto cleanup; - memcpy(buffer, bh->b_data + le16_to_cpu(entry->e_value_offs), - size); - } - error = size; - -cleanup: - brelse(bh); - return error; -} - -static int -ext4_xattr_ibody_get(struct inode *inode, int name_index, const char *name, - void *buffer, size_t buffer_size) -{ - struct ext4_xattr_ibody_header *header; - struct ext4_xattr_entry *entry; - struct ext4_inode *raw_inode; - struct ext4_iloc iloc; - size_t size; - void *end; - int error; - - if (!(EXT4_I(inode)->i_state & EXT4_STATE_XATTR)) - return -ENODATA; - error = ext4_get_inode_loc(inode, &iloc); - if (error) - return error; - raw_inode = ext4_raw_inode(&iloc); - header = IHDR(inode, raw_inode); - entry = IFIRST(header); - end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size; - error = ext4_xattr_check_names(entry, end); - if (error) - goto cleanup; - error = ext4_xattr_find_entry(&entry, name_index, name, - end - (void *)entry, 0); - if (error) - goto cleanup; - size = le32_to_cpu(entry->e_value_size); - if (buffer) { - error = -ERANGE; - if (size > buffer_size) - goto cleanup; - memcpy(buffer, (void *)IFIRST(header) + - le16_to_cpu(entry->e_value_offs), size); - } - error = size; - -cleanup: - brelse(iloc.bh); - return error; -} - -/* - * ext4_xattr_get() - * - * Copy an extended attribute into the buffer - * provided, or compute the buffer size required. - * Buffer is NULL to compute the size of the buffer required. - * - * Returns a negative error number on failure, or the number of bytes - * used / required on success. - */ -int -ext4_xattr_get(struct inode *inode, int name_index, const char *name, - void *buffer, size_t buffer_size) -{ - int error; - - down_read(&EXT4_I(inode)->xattr_sem); - error = ext4_xattr_ibody_get(inode, name_index, name, buffer, - buffer_size); - if (error == -ENODATA) - error = ext4_xattr_block_get(inode, name_index, name, buffer, - buffer_size); - up_read(&EXT4_I(inode)->xattr_sem); - return error; -} - -static int -ext4_xattr_list_entries(struct inode *inode, struct ext4_xattr_entry *entry, - char *buffer, size_t buffer_size) -{ - size_t rest = buffer_size; - - for (; !IS_LAST_ENTRY(entry); entry = EXT4_XATTR_NEXT(entry)) { - struct xattr_handler *handler = - ext4_xattr_handler(entry->e_name_index); - - if (handler) { - size_t size = handler->list(inode, buffer, rest, - entry->e_name, - entry->e_name_len); - if (buffer) { - if (size > rest) - return -ERANGE; - buffer += size; - } - rest -= size; - } - } - return buffer_size - rest; -} - -static int -ext4_xattr_block_list(struct inode *inode, char *buffer, size_t buffer_size) -{ - struct buffer_head *bh = NULL; - int error; - - ea_idebug(inode, "buffer=%p, buffer_size=%ld", - buffer, (long)buffer_size); - - error = 0; - if (!EXT4_I(inode)->i_file_acl) - goto cleanup; - ea_idebug(inode, "reading block %u", EXT4_I(inode)->i_file_acl); - bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl); - error = -EIO; - if (!bh) - goto cleanup; - ea_bdebug(bh, "b_count=%d, refcount=%d", - atomic_read(&(bh->b_count)), le32_to_cpu(BHDR(bh)->h_refcount)); - if (ext4_xattr_check_block(bh)) { - ext4_error(inode->i_sb, __FUNCTION__, - "inode %lu: bad block %llu", inode->i_ino, - EXT4_I(inode)->i_file_acl); - error = -EIO; - goto cleanup; - } - ext4_xattr_cache_insert(bh); - error = ext4_xattr_list_entries(inode, BFIRST(bh), buffer, buffer_size); - -cleanup: - brelse(bh); - - return error; -} - -static int -ext4_xattr_ibody_list(struct inode *inode, char *buffer, size_t buffer_size) -{ - struct ext4_xattr_ibody_header *header; - struct ext4_inode *raw_inode; - struct ext4_iloc iloc; - void *end; - int error; - - if (!(EXT4_I(inode)->i_state & EXT4_STATE_XATTR)) - return 0; - error = ext4_get_inode_loc(inode, &iloc); - if (error) - return error; - raw_inode = ext4_raw_inode(&iloc); - header = IHDR(inode, raw_inode); - end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size; - error = ext4_xattr_check_names(IFIRST(header), end); - if (error) - goto cleanup; - error = ext4_xattr_list_entries(inode, IFIRST(header), - buffer, buffer_size); - -cleanup: - brelse(iloc.bh); - return error; -} - -/* - * ext4_xattr_list() - * - * Copy a list of attribute names into the buffer - * provided, or compute the buffer size required. - * Buffer is NULL to compute the size of the buffer required. - * - * Returns a negative error number on failure, or the number of bytes - * used / required on success. - */ -int -ext4_xattr_list(struct inode *inode, char *buffer, size_t buffer_size) -{ - int i_error, b_error; - - down_read(&EXT4_I(inode)->xattr_sem); - i_error = ext4_xattr_ibody_list(inode, buffer, buffer_size); - if (i_error < 0) { - b_error = 0; - } else { - if (buffer) { - buffer += i_error; - buffer_size -= i_error; - } - b_error = ext4_xattr_block_list(inode, buffer, buffer_size); - if (b_error < 0) - i_error = 0; - } - up_read(&EXT4_I(inode)->xattr_sem); - return i_error + b_error; -} - -/* - * If the EXT4_FEATURE_COMPAT_EXT_ATTR feature of this file system is - * not set, set it. - */ -static void ext4_xattr_update_super_block(handle_t *handle, - struct super_block *sb) -{ - 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_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); -} - -/* - * Release the xattr block BH: If the reference count is > 1, decrement - * it; otherwise free the block. - */ -static void -ext4_xattr_release_block(handle_t *handle, struct inode *inode, - struct buffer_head *bh) -{ - struct mb_cache_entry *ce = NULL; - - ce = mb_cache_entry_get(ext4_xattr_cache, bh->b_bdev, bh->b_blocknr); - if (BHDR(bh)->h_refcount == cpu_to_le32(1)) { - ea_bdebug(bh, "refcount now=0; freeing"); - if (ce) - mb_cache_entry_free(ce); - ext4_free_blocks(handle, inode, bh->b_blocknr, 1); - get_bh(bh); - ext4_forget(handle, 1, inode, bh, bh->b_blocknr); - } else { - if (ext4_journal_get_write_access(handle, bh) == 0) { - lock_buffer(bh); - BHDR(bh)->h_refcount = cpu_to_le32( - le32_to_cpu(BHDR(bh)->h_refcount) - 1); - ext4_journal_dirty_metadata(handle, bh); - if (IS_SYNC(inode)) - handle->h_sync = 1; - DQUOT_FREE_BLOCK(inode, 1); - unlock_buffer(bh); - ea_bdebug(bh, "refcount now=%d; releasing", - le32_to_cpu(BHDR(bh)->h_refcount)); - } - if (ce) - mb_cache_entry_release(ce); - } -} - -struct ext4_xattr_info { - int name_index; - const char *name; - const void *value; - size_t value_len; -}; - -struct ext4_xattr_search { - struct ext4_xattr_entry *first; - void *base; - void *end; - struct ext4_xattr_entry *here; - int not_found; -}; - -static int -ext4_xattr_set_entry(struct ext4_xattr_info *i, struct ext4_xattr_search *s) -{ - struct ext4_xattr_entry *last; - size_t free, min_offs = s->end - s->base, name_len = strlen(i->name); - - /* Compute min_offs and last. */ - last = s->first; - for (; !IS_LAST_ENTRY(last); last = EXT4_XATTR_NEXT(last)) { - if (!last->e_value_block && last->e_value_size) { - size_t offs = le16_to_cpu(last->e_value_offs); - if (offs < min_offs) - min_offs = offs; - } - } - free = min_offs - ((void *)last - s->base) - sizeof(__u32); - if (!s->not_found) { - if (!s->here->e_value_block && s->here->e_value_size) { - size_t size = le32_to_cpu(s->here->e_value_size); - free += EXT4_XATTR_SIZE(size); - } - free += EXT4_XATTR_LEN(name_len); - } - if (i->value) { - if (free < EXT4_XATTR_SIZE(i->value_len) || - free < EXT4_XATTR_LEN(name_len) + - EXT4_XATTR_SIZE(i->value_len)) - return -ENOSPC; - } - - if (i->value && s->not_found) { - /* Insert the new name. */ - size_t size = EXT4_XATTR_LEN(name_len); - size_t rest = (void *)last - (void *)s->here + sizeof(__u32); - memmove((void *)s->here + size, s->here, rest); - memset(s->here, 0, size); - s->here->e_name_index = i->name_index; - s->here->e_name_len = name_len; - memcpy(s->here->e_name, i->name, name_len); - } else { - if (!s->here->e_value_block && s->here->e_value_size) { - void *first_val = s->base + min_offs; - size_t offs = le16_to_cpu(s->here->e_value_offs); - void *val = s->base + offs; - size_t size = EXT4_XATTR_SIZE( - le32_to_cpu(s->here->e_value_size)); - - if (i->value && size == EXT4_XATTR_SIZE(i->value_len)) { - /* The old and the new value have the same - size. Just replace. */ - s->here->e_value_size = - cpu_to_le32(i->value_len); - memset(val + size - EXT4_XATTR_PAD, 0, - EXT4_XATTR_PAD); /* Clear pad bytes. */ - memcpy(val, i->value, i->value_len); - return 0; - } - - /* Remove the old value. */ - memmove(first_val + size, first_val, val - first_val); - memset(first_val, 0, size); - s->here->e_value_size = 0; - s->here->e_value_offs = 0; - min_offs += size; - - /* Adjust all value offsets. */ - last = s->first; - while (!IS_LAST_ENTRY(last)) { - size_t o = le16_to_cpu(last->e_value_offs); - if (!last->e_value_block && - last->e_value_size && o < offs) - last->e_value_offs = - cpu_to_le16(o + size); - last = EXT4_XATTR_NEXT(last); - } - } - if (!i->value) { - /* Remove the old name. */ - size_t size = EXT4_XATTR_LEN(name_len); - last = ENTRY((void *)last - size); - memmove(s->here, (void *)s->here + size, - (void *)last - (void *)s->here + sizeof(__u32)); - memset(last, 0, size); - } - } - - if (i->value) { - /* Insert the new value. */ - s->here->e_value_size = cpu_to_le32(i->value_len); - if (i->value_len) { - size_t size = EXT4_XATTR_SIZE(i->value_len); - void *val = s->base + min_offs - size; - s->here->e_value_offs = cpu_to_le16(min_offs - size); - memset(val + size - EXT4_XATTR_PAD, 0, - EXT4_XATTR_PAD); /* Clear the pad bytes. */ - memcpy(val, i->value, i->value_len); - } - } - return 0; -} - -struct ext4_xattr_block_find { - struct ext4_xattr_search s; - struct buffer_head *bh; -}; - -static int -ext4_xattr_block_find(struct inode *inode, struct ext4_xattr_info *i, - struct ext4_xattr_block_find *bs) -{ - struct super_block *sb = inode->i_sb; - int error; - - ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld", - i->name_index, i->name, i->value, (long)i->value_len); - - if (EXT4_I(inode)->i_file_acl) { - /* The inode already has an extended attribute block. */ - bs->bh = sb_bread(sb, EXT4_I(inode)->i_file_acl); - error = -EIO; - if (!bs->bh) - goto cleanup; - ea_bdebug(bs->bh, "b_count=%d, refcount=%d", - atomic_read(&(bs->bh->b_count)), - le32_to_cpu(BHDR(bs->bh)->h_refcount)); - if (ext4_xattr_check_block(bs->bh)) { - ext4_error(sb, __FUNCTION__, - "inode %lu: bad block %llu", inode->i_ino, - EXT4_I(inode)->i_file_acl); - error = -EIO; - goto cleanup; - } - /* Find the named attribute. */ - bs->s.base = BHDR(bs->bh); - bs->s.first = BFIRST(bs->bh); - bs->s.end = bs->bh->b_data + bs->bh->b_size; - bs->s.here = bs->s.first; - error = ext4_xattr_find_entry(&bs->s.here, i->name_index, - i->name, bs->bh->b_size, 1); - if (error && error != -ENODATA) - goto cleanup; - bs->s.not_found = error; - } - error = 0; - -cleanup: - return error; -} - -static int -ext4_xattr_block_set(handle_t *handle, struct inode *inode, - struct ext4_xattr_info *i, - struct ext4_xattr_block_find *bs) -{ - struct super_block *sb = inode->i_sb; - struct buffer_head *new_bh = NULL; - struct ext4_xattr_search *s = &bs->s; - struct mb_cache_entry *ce = NULL; - int error; - -#define header(x) ((struct ext4_xattr_header *)(x)) - - if (i->value && i->value_len > sb->s_blocksize) - return -ENOSPC; - if (s->base) { - ce = mb_cache_entry_get(ext4_xattr_cache, bs->bh->b_bdev, - bs->bh->b_blocknr); - if (header(s->base)->h_refcount == cpu_to_le32(1)) { - if (ce) { - mb_cache_entry_free(ce); - ce = NULL; - } - ea_bdebug(bs->bh, "modifying in-place"); - error = ext4_journal_get_write_access(handle, bs->bh); - if (error) - goto cleanup; - lock_buffer(bs->bh); - error = ext4_xattr_set_entry(i, s); - if (!error) { - if (!IS_LAST_ENTRY(s->first)) - ext4_xattr_rehash(header(s->base), - s->here); - ext4_xattr_cache_insert(bs->bh); - } - unlock_buffer(bs->bh); - if (error == -EIO) - goto bad_block; - if (!error) - error = ext4_journal_dirty_metadata(handle, - bs->bh); - if (error) - goto cleanup; - goto inserted; - } else { - int offset = (char *)s->here - bs->bh->b_data; - - if (ce) { - mb_cache_entry_release(ce); - ce = NULL; - } - ea_bdebug(bs->bh, "cloning"); - s->base = kmalloc(bs->bh->b_size, GFP_KERNEL); - error = -ENOMEM; - if (s->base == NULL) - goto cleanup; - memcpy(s->base, BHDR(bs->bh), bs->bh->b_size); - s->first = ENTRY(header(s->base)+1); - header(s->base)->h_refcount = cpu_to_le32(1); - s->here = ENTRY(s->base + offset); - s->end = s->base + bs->bh->b_size; - } - } else { - /* Allocate a buffer where we construct the new block. */ - s->base = kmalloc(sb->s_blocksize, GFP_KERNEL); - /* assert(header == s->base) */ - error = -ENOMEM; - if (s->base == NULL) - goto cleanup; - memset(s->base, 0, sb->s_blocksize); - header(s->base)->h_magic = cpu_to_le32(EXT4_XATTR_MAGIC); - header(s->base)->h_blocks = cpu_to_le32(1); - header(s->base)->h_refcount = cpu_to_le32(1); - s->first = ENTRY(header(s->base)+1); - s->here = ENTRY(header(s->base)+1); - s->end = s->base + sb->s_blocksize; - } - - error = ext4_xattr_set_entry(i, s); - if (error == -EIO) - goto bad_block; - if (error) - goto cleanup; - if (!IS_LAST_ENTRY(s->first)) - ext4_xattr_rehash(header(s->base), s->here); - -inserted: - if (!IS_LAST_ENTRY(s->first)) { - new_bh = ext4_xattr_cache_find(inode, header(s->base), &ce); - if (new_bh) { - /* We found an identical block in the cache. */ - if (new_bh == bs->bh) - ea_bdebug(new_bh, "keeping"); - else { - /* The old block is released after updating - the inode. */ - error = -EDQUOT; - if (DQUOT_ALLOC_BLOCK(inode, 1)) - goto cleanup; - error = ext4_journal_get_write_access(handle, - new_bh); - if (error) - goto cleanup_dquot; - lock_buffer(new_bh); - BHDR(new_bh)->h_refcount = cpu_to_le32(1 + - le32_to_cpu(BHDR(new_bh)->h_refcount)); - ea_bdebug(new_bh, "reusing; refcount now=%d", - le32_to_cpu(BHDR(new_bh)->h_refcount)); - unlock_buffer(new_bh); - error = ext4_journal_dirty_metadata(handle, - new_bh); - if (error) - goto cleanup_dquot; - } - mb_cache_entry_release(ce); - ce = NULL; - } else if (bs->bh && s->base == bs->bh->b_data) { - /* We were modifying this block in-place. */ - ea_bdebug(bs->bh, "keeping this block"); - new_bh = bs->bh; - get_bh(new_bh); - } else { - /* We need to allocate a new block */ - ext4_fsblk_t goal = le32_to_cpu( - EXT4_SB(sb)->s_es->s_first_data_block) + - (ext4_fsblk_t)EXT4_I(inode)->i_block_group * - EXT4_BLOCKS_PER_GROUP(sb); - ext4_fsblk_t block = ext4_new_block(handle, inode, - goal, &error); - if (error) - goto cleanup; - ea_idebug(inode, "creating block %d", block); - - new_bh = sb_getblk(sb, block); - if (!new_bh) { -getblk_failed: - ext4_free_blocks(handle, inode, block, 1); - error = -EIO; - goto cleanup; - } - lock_buffer(new_bh); - error = ext4_journal_get_create_access(handle, new_bh); - if (error) { - unlock_buffer(new_bh); - goto getblk_failed; - } - memcpy(new_bh->b_data, s->base, new_bh->b_size); - set_buffer_uptodate(new_bh); - unlock_buffer(new_bh); - ext4_xattr_cache_insert(new_bh); - error = ext4_journal_dirty_metadata(handle, new_bh); - if (error) - goto cleanup; - } - } - - /* Update the inode. */ - EXT4_I(inode)->i_file_acl = new_bh ? new_bh->b_blocknr : 0; - - /* Drop the previous xattr block. */ - if (bs->bh && bs->bh != new_bh) - ext4_xattr_release_block(handle, inode, bs->bh); - error = 0; - -cleanup: - if (ce) - mb_cache_entry_release(ce); - brelse(new_bh); - if (!(bs->bh && s->base == bs->bh->b_data)) - kfree(s->base); - - return error; - -cleanup_dquot: - DQUOT_FREE_BLOCK(inode, 1); - goto cleanup; - -bad_block: - ext4_error(inode->i_sb, __FUNCTION__, - "inode %lu: bad block %llu", inode->i_ino, - EXT4_I(inode)->i_file_acl); - goto cleanup; - -#undef header -} - -struct ext4_xattr_ibody_find { - struct ext4_xattr_search s; - struct ext4_iloc iloc; -}; - -static int -ext4_xattr_ibody_find(struct inode *inode, struct ext4_xattr_info *i, - struct ext4_xattr_ibody_find *is) -{ - struct ext4_xattr_ibody_header *header; - struct ext4_inode *raw_inode; - int error; - - if (EXT4_I(inode)->i_extra_isize == 0) - return 0; - raw_inode = ext4_raw_inode(&is->iloc); - header = IHDR(inode, raw_inode); - is->s.base = is->s.first = IFIRST(header); - is->s.here = is->s.first; - is->s.end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size; - if (EXT4_I(inode)->i_state & EXT4_STATE_XATTR) { - error = ext4_xattr_check_names(IFIRST(header), is->s.end); - if (error) - return error; - /* Find the named attribute. */ - error = ext4_xattr_find_entry(&is->s.here, i->name_index, - i->name, is->s.end - - (void *)is->s.base, 0); - if (error && error != -ENODATA) - return error; - is->s.not_found = error; - } - return 0; -} - -static int -ext4_xattr_ibody_set(handle_t *handle, struct inode *inode, - struct ext4_xattr_info *i, - struct ext4_xattr_ibody_find *is) -{ - struct ext4_xattr_ibody_header *header; - struct ext4_xattr_search *s = &is->s; - int error; - - if (EXT4_I(inode)->i_extra_isize == 0) - return -ENOSPC; - error = ext4_xattr_set_entry(i, s); - if (error) - return error; - header = IHDR(inode, ext4_raw_inode(&is->iloc)); - if (!IS_LAST_ENTRY(s->first)) { - header->h_magic = cpu_to_le32(EXT4_XATTR_MAGIC); - EXT4_I(inode)->i_state |= EXT4_STATE_XATTR; - } else { - header->h_magic = cpu_to_le32(0); - EXT4_I(inode)->i_state &= ~EXT4_STATE_XATTR; - } - return 0; -} - -/* - * ext4_xattr_set_handle() - * - * Create, replace or remove an extended attribute for this inode. Buffer - * is NULL to remove an existing extended attribute, and non-NULL to - * either replace an existing extended attribute, or create a new extended - * attribute. The flags XATTR_REPLACE and XATTR_CREATE - * specify that an extended attribute must exist and must not exist - * previous to the call, respectively. - * - * Returns 0, or a negative error number on failure. - */ -int -ext4_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index, - const char *name, const void *value, size_t value_len, - int flags) -{ - struct ext4_xattr_info i = { - .name_index = name_index, - .name = name, - .value = value, - .value_len = value_len, - - }; - struct ext4_xattr_ibody_find is = { - .s = { .not_found = -ENODATA, }, - }; - struct ext4_xattr_block_find bs = { - .s = { .not_found = -ENODATA, }, - }; - int error; - - if (!name) - return -EINVAL; - if (strlen(name) > 255) - return -ERANGE; - down_write(&EXT4_I(inode)->xattr_sem); - error = ext4_get_inode_loc(inode, &is.iloc); - if (error) - goto cleanup; - - if (EXT4_I(inode)->i_state & EXT4_STATE_NEW) { - struct ext4_inode *raw_inode = ext4_raw_inode(&is.iloc); - memset(raw_inode, 0, EXT4_SB(inode->i_sb)->s_inode_size); - EXT4_I(inode)->i_state &= ~EXT4_STATE_NEW; - } - - error = ext4_xattr_ibody_find(inode, &i, &is); - if (error) - goto cleanup; - if (is.s.not_found) - error = ext4_xattr_block_find(inode, &i, &bs); - if (error) - goto cleanup; - if (is.s.not_found && bs.s.not_found) { - error = -ENODATA; - if (flags & XATTR_REPLACE) - goto cleanup; - error = 0; - if (!value) - goto cleanup; - } else { - error = -EEXIST; - if (flags & XATTR_CREATE) - goto cleanup; - } - error = ext4_journal_get_write_access(handle, is.iloc.bh); - if (error) - goto cleanup; - if (!value) { - if (!is.s.not_found) - error = ext4_xattr_ibody_set(handle, inode, &i, &is); - else if (!bs.s.not_found) - error = ext4_xattr_block_set(handle, inode, &i, &bs); - } else { - error = ext4_xattr_ibody_set(handle, inode, &i, &is); - if (!error && !bs.s.not_found) { - i.value = NULL; - error = ext4_xattr_block_set(handle, inode, &i, &bs); - } else if (error == -ENOSPC) { - error = ext4_xattr_block_set(handle, inode, &i, &bs); - if (error) - goto cleanup; - if (!is.s.not_found) { - i.value = NULL; - error = ext4_xattr_ibody_set(handle, inode, &i, - &is); - } - } - } - if (!error) { - ext4_xattr_update_super_block(handle, inode->i_sb); - inode->i_ctime = CURRENT_TIME_SEC; - error = ext4_mark_iloc_dirty(handle, inode, &is.iloc); - /* - * The bh is consumed by ext4_mark_iloc_dirty, even with - * error != 0. - */ - is.iloc.bh = NULL; - if (IS_SYNC(inode)) - handle->h_sync = 1; - } - -cleanup: - brelse(is.iloc.bh); - brelse(bs.bh); - up_write(&EXT4_I(inode)->xattr_sem); - return error; -} - -/* - * ext4_xattr_set() - * - * Like ext4_xattr_set_handle, but start from an inode. This extended - * attribute modification is a filesystem transaction by itself. - * - * Returns 0, or a negative error number on failure. - */ -int -ext4_xattr_set(struct inode *inode, int name_index, const char *name, - const void *value, size_t value_len, int flags) -{ - handle_t *handle; - int error, retries = 0; - -retry: - handle = ext4_journal_start(inode, EXT4_DATA_TRANS_BLOCKS(inode->i_sb)); - if (IS_ERR(handle)) { - error = PTR_ERR(handle); - } else { - int error2; - - error = ext4_xattr_set_handle(handle, inode, name_index, name, - value, value_len, flags); - error2 = ext4_journal_stop(handle); - if (error == -ENOSPC && - ext4_should_retry_alloc(inode->i_sb, &retries)) - goto retry; - if (error == 0) - error = error2; - } - - return error; -} - -/* - * ext4_xattr_delete_inode() - * - * Free extended attribute resources associated with this inode. This - * is called immediately before an inode is freed. We have exclusive - * access to the inode. - */ -void -ext4_xattr_delete_inode(handle_t *handle, struct inode *inode) -{ - struct buffer_head *bh = NULL; - - if (!EXT4_I(inode)->i_file_acl) - goto cleanup; - bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl); - if (!bh) { - ext4_error(inode->i_sb, __FUNCTION__, - "inode %lu: block %llu read error", inode->i_ino, - EXT4_I(inode)->i_file_acl); - goto cleanup; - } - if (BHDR(bh)->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC) || - BHDR(bh)->h_blocks != cpu_to_le32(1)) { - ext4_error(inode->i_sb, __FUNCTION__, - "inode %lu: bad block %llu", inode->i_ino, - EXT4_I(inode)->i_file_acl); - goto cleanup; - } - ext4_xattr_release_block(handle, inode, bh); - EXT4_I(inode)->i_file_acl = 0; - -cleanup: - brelse(bh); -} - -/* - * ext4_xattr_put_super() - * - * This is called when a file system is unmounted. - */ -void -ext4_xattr_put_super(struct super_block *sb) -{ - mb_cache_shrink(sb->s_bdev); -} - -/* - * ext4_xattr_cache_insert() - * - * Create a new entry in the extended attribute cache, and insert - * it unless such an entry is already in the cache. - * - * Returns 0, or a negative error number on failure. - */ -static void -ext4_xattr_cache_insert(struct buffer_head *bh) -{ - __u32 hash = le32_to_cpu(BHDR(bh)->h_hash); - struct mb_cache_entry *ce; - int error; - - ce = mb_cache_entry_alloc(ext4_xattr_cache); - if (!ce) { - ea_bdebug(bh, "out of memory"); - return; - } - error = mb_cache_entry_insert(ce, bh->b_bdev, bh->b_blocknr, &hash); - if (error) { - mb_cache_entry_free(ce); - if (error == -EBUSY) { - ea_bdebug(bh, "already in cache"); - error = 0; - } - } else { - ea_bdebug(bh, "inserting [%x]", (int)hash); - mb_cache_entry_release(ce); - } -} - -/* - * ext4_xattr_cmp() - * - * Compare two extended attribute blocks for equality. - * - * Returns 0 if the blocks are equal, 1 if they differ, and - * a negative error number on errors. - */ -static int -ext4_xattr_cmp(struct ext4_xattr_header *header1, - struct ext4_xattr_header *header2) -{ - struct ext4_xattr_entry *entry1, *entry2; - - entry1 = ENTRY(header1+1); - entry2 = ENTRY(header2+1); - while (!IS_LAST_ENTRY(entry1)) { - if (IS_LAST_ENTRY(entry2)) - return 1; - if (entry1->e_hash != entry2->e_hash || - entry1->e_name_index != entry2->e_name_index || - entry1->e_name_len != entry2->e_name_len || - entry1->e_value_size != entry2->e_value_size || - memcmp(entry1->e_name, entry2->e_name, entry1->e_name_len)) - return 1; - if (entry1->e_value_block != 0 || entry2->e_value_block != 0) - return -EIO; - if (memcmp((char *)header1 + le16_to_cpu(entry1->e_value_offs), - (char *)header2 + le16_to_cpu(entry2->e_value_offs), - le32_to_cpu(entry1->e_value_size))) - return 1; - - entry1 = EXT4_XATTR_NEXT(entry1); - entry2 = EXT4_XATTR_NEXT(entry2); - } - if (!IS_LAST_ENTRY(entry2)) - return 1; - return 0; -} - -/* - * ext4_xattr_cache_find() - * - * Find an identical extended attribute block. - * - * Returns a pointer to the block found, or NULL if such a block was - * not found or an error occurred. - */ -static struct buffer_head * -ext4_xattr_cache_find(struct inode *inode, struct ext4_xattr_header *header, - struct mb_cache_entry **pce) -{ - __u32 hash = le32_to_cpu(header->h_hash); - struct mb_cache_entry *ce; - - if (!header->h_hash) - return NULL; /* never share */ - ea_idebug(inode, "looking for cached blocks [%x]", (int)hash); -again: - ce = mb_cache_entry_find_first(ext4_xattr_cache, 0, - inode->i_sb->s_bdev, hash); - while (ce) { - struct buffer_head *bh; - - if (IS_ERR(ce)) { - if (PTR_ERR(ce) == -EAGAIN) - goto again; - break; - } - bh = sb_bread(inode->i_sb, ce->e_block); - if (!bh) { - ext4_error(inode->i_sb, __FUNCTION__, - "inode %lu: block %lu read error", - inode->i_ino, (unsigned long) ce->e_block); - } else if (le32_to_cpu(BHDR(bh)->h_refcount) >= - EXT4_XATTR_REFCOUNT_MAX) { - ea_idebug(inode, "block %lu refcount %d>=%d", - (unsigned long) ce->e_block, - le32_to_cpu(BHDR(bh)->h_refcount), - EXT4_XATTR_REFCOUNT_MAX); - } else if (ext4_xattr_cmp(header, BHDR(bh)) == 0) { - *pce = ce; - return bh; - } - brelse(bh); - ce = mb_cache_entry_find_next(ce, 0, inode->i_sb->s_bdev, hash); - } - return NULL; -} - -#define NAME_HASH_SHIFT 5 -#define VALUE_HASH_SHIFT 16 - -/* - * ext4_xattr_hash_entry() - * - * Compute the hash of an extended attribute. - */ -static inline void ext4_xattr_hash_entry(struct ext4_xattr_header *header, - struct ext4_xattr_entry *entry) -{ - __u32 hash = 0; - char *name = entry->e_name; - int n; - - for (n=0; n < entry->e_name_len; n++) { - hash = (hash << NAME_HASH_SHIFT) ^ - (hash >> (8*sizeof(hash) - NAME_HASH_SHIFT)) ^ - *name++; - } - - if (entry->e_value_block == 0 && entry->e_value_size != 0) { - __le32 *value = (__le32 *)((char *)header + - le16_to_cpu(entry->e_value_offs)); - for (n = (le32_to_cpu(entry->e_value_size) + - EXT4_XATTR_ROUND) >> EXT4_XATTR_PAD_BITS; n; n--) { - hash = (hash << VALUE_HASH_SHIFT) ^ - (hash >> (8*sizeof(hash) - VALUE_HASH_SHIFT)) ^ - le32_to_cpu(*value++); - } - } - entry->e_hash = cpu_to_le32(hash); -} - -#undef NAME_HASH_SHIFT -#undef VALUE_HASH_SHIFT - -#define BLOCK_HASH_SHIFT 16 - -/* - * ext4_xattr_rehash() - * - * Re-compute the extended attribute hash value after an entry has changed. - */ -static void ext4_xattr_rehash(struct ext4_xattr_header *header, - struct ext4_xattr_entry *entry) -{ - struct ext4_xattr_entry *here; - __u32 hash = 0; - - ext4_xattr_hash_entry(header, entry); - here = ENTRY(header+1); - while (!IS_LAST_ENTRY(here)) { - if (!here->e_hash) { - /* Block is not shared if an entry's hash value == 0 */ - hash = 0; - break; - } - hash = (hash << BLOCK_HASH_SHIFT) ^ - (hash >> (8*sizeof(hash) - BLOCK_HASH_SHIFT)) ^ - le32_to_cpu(here->e_hash); - here = EXT4_XATTR_NEXT(here); - } - header->h_hash = cpu_to_le32(hash); -} - -#undef BLOCK_HASH_SHIFT - -int __init -init_ext4_xattr(void) -{ - ext4_xattr_cache = mb_cache_create("ext4_xattr", NULL, - sizeof(struct mb_cache_entry) + - sizeof(((struct mb_cache_entry *) 0)->e_indexes[0]), 1, 6); - if (!ext4_xattr_cache) - return -ENOMEM; - return 0; -} - -void -exit_ext4_xattr(void) -{ - if (ext4_xattr_cache) - mb_cache_destroy(ext4_xattr_cache); - ext4_xattr_cache = NULL; -} diff --git a/trunk/fs/ext4/xattr.h b/trunk/fs/ext4/xattr.h deleted file mode 100644 index 79432b35398f..000000000000 --- a/trunk/fs/ext4/xattr.h +++ /dev/null @@ -1,145 +0,0 @@ -/* - File: fs/ext4/xattr.h - - On-disk format of extended attributes for the ext4 filesystem. - - (C) 2001 Andreas Gruenbacher, -*/ - -#include - -/* Magic value in attribute blocks */ -#define EXT4_XATTR_MAGIC 0xEA020000 - -/* Maximum number of references to one attribute block */ -#define EXT4_XATTR_REFCOUNT_MAX 1024 - -/* Name indexes */ -#define EXT4_XATTR_INDEX_USER 1 -#define EXT4_XATTR_INDEX_POSIX_ACL_ACCESS 2 -#define EXT4_XATTR_INDEX_POSIX_ACL_DEFAULT 3 -#define EXT4_XATTR_INDEX_TRUSTED 4 -#define EXT4_XATTR_INDEX_LUSTRE 5 -#define EXT4_XATTR_INDEX_SECURITY 6 - -struct ext4_xattr_header { - __le32 h_magic; /* magic number for identification */ - __le32 h_refcount; /* reference count */ - __le32 h_blocks; /* number of disk blocks used */ - __le32 h_hash; /* hash value of all attributes */ - __u32 h_reserved[4]; /* zero right now */ -}; - -struct ext4_xattr_ibody_header { - __le32 h_magic; /* magic number for identification */ -}; - -struct ext4_xattr_entry { - __u8 e_name_len; /* length of name */ - __u8 e_name_index; /* attribute name index */ - __le16 e_value_offs; /* offset in disk block of value */ - __le32 e_value_block; /* disk block attribute is stored on (n/i) */ - __le32 e_value_size; /* size of attribute value */ - __le32 e_hash; /* hash value of name and value */ - char e_name[0]; /* attribute name */ -}; - -#define EXT4_XATTR_PAD_BITS 2 -#define EXT4_XATTR_PAD (1<e_name_len)) ) -#define EXT4_XATTR_SIZE(size) \ - (((size) + EXT4_XATTR_ROUND) & ~EXT4_XATTR_ROUND) - -# ifdef CONFIG_EXT4DEV_FS_XATTR - -extern struct xattr_handler ext4_xattr_user_handler; -extern struct xattr_handler ext4_xattr_trusted_handler; -extern struct xattr_handler ext4_xattr_acl_access_handler; -extern struct xattr_handler ext4_xattr_acl_default_handler; -extern struct xattr_handler ext4_xattr_security_handler; - -extern ssize_t ext4_listxattr(struct dentry *, char *, size_t); - -extern int ext4_xattr_get(struct inode *, int, const char *, void *, size_t); -extern int ext4_xattr_list(struct inode *, char *, size_t); -extern int ext4_xattr_set(struct inode *, int, const char *, const void *, size_t, int); -extern int ext4_xattr_set_handle(handle_t *, struct inode *, int, const char *, const void *, size_t, int); - -extern void ext4_xattr_delete_inode(handle_t *, struct inode *); -extern void ext4_xattr_put_super(struct super_block *); - -extern int init_ext4_xattr(void); -extern void exit_ext4_xattr(void); - -extern struct xattr_handler *ext4_xattr_handlers[]; - -# else /* CONFIG_EXT4DEV_FS_XATTR */ - -static inline int -ext4_xattr_get(struct inode *inode, int name_index, const char *name, - void *buffer, size_t size, int flags) -{ - return -EOPNOTSUPP; -} - -static inline int -ext4_xattr_list(struct inode *inode, void *buffer, size_t size) -{ - return -EOPNOTSUPP; -} - -static inline int -ext4_xattr_set(struct inode *inode, int name_index, const char *name, - const void *value, size_t size, int flags) -{ - return -EOPNOTSUPP; -} - -static inline int -ext4_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index, - const char *name, const void *value, size_t size, int flags) -{ - return -EOPNOTSUPP; -} - -static inline void -ext4_xattr_delete_inode(handle_t *handle, struct inode *inode) -{ -} - -static inline void -ext4_xattr_put_super(struct super_block *sb) -{ -} - -static inline int -init_ext4_xattr(void) -{ - return 0; -} - -static inline void -exit_ext4_xattr(void) -{ -} - -#define ext4_xattr_handlers NULL - -# endif /* CONFIG_EXT4DEV_FS_XATTR */ - -#ifdef CONFIG_EXT4DEV_FS_SECURITY -extern int ext4_init_security(handle_t *handle, struct inode *inode, - struct inode *dir); -#else -static inline int ext4_init_security(handle_t *handle, struct inode *inode, - struct inode *dir) -{ - return 0; -} -#endif diff --git a/trunk/fs/ext4/xattr_security.c b/trunk/fs/ext4/xattr_security.c deleted file mode 100644 index b6a6861951f9..000000000000 --- a/trunk/fs/ext4/xattr_security.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * linux/fs/ext4/xattr_security.c - * Handler for storing security labels as extended attributes. - */ - -#include -#include -#include -#include -#include -#include -#include -#include "xattr.h" - -static size_t -ext4_xattr_security_list(struct inode *inode, char *list, size_t list_size, - const char *name, size_t name_len) -{ - const size_t prefix_len = sizeof(XATTR_SECURITY_PREFIX)-1; - const size_t total_len = prefix_len + name_len + 1; - - - if (list && total_len <= list_size) { - memcpy(list, XATTR_SECURITY_PREFIX, prefix_len); - memcpy(list+prefix_len, name, name_len); - list[prefix_len + name_len] = '\0'; - } - return total_len; -} - -static int -ext4_xattr_security_get(struct inode *inode, const char *name, - void *buffer, size_t size) -{ - if (strcmp(name, "") == 0) - return -EINVAL; - return ext4_xattr_get(inode, EXT4_XATTR_INDEX_SECURITY, name, - buffer, size); -} - -static int -ext4_xattr_security_set(struct inode *inode, const char *name, - const void *value, size_t size, int flags) -{ - if (strcmp(name, "") == 0) - return -EINVAL; - return ext4_xattr_set(inode, EXT4_XATTR_INDEX_SECURITY, name, - value, size, flags); -} - -int -ext4_init_security(handle_t *handle, struct inode *inode, struct inode *dir) -{ - int err; - size_t len; - void *value; - char *name; - - err = security_inode_init_security(inode, dir, &name, &value, &len); - if (err) { - if (err == -EOPNOTSUPP) - return 0; - return err; - } - err = ext4_xattr_set_handle(handle, inode, EXT4_XATTR_INDEX_SECURITY, - name, value, len, 0); - kfree(name); - kfree(value); - return err; -} - -struct xattr_handler ext4_xattr_security_handler = { - .prefix = XATTR_SECURITY_PREFIX, - .list = ext4_xattr_security_list, - .get = ext4_xattr_security_get, - .set = ext4_xattr_security_set, -}; diff --git a/trunk/fs/ext4/xattr_trusted.c b/trunk/fs/ext4/xattr_trusted.c deleted file mode 100644 index b76f2dbc82da..000000000000 --- a/trunk/fs/ext4/xattr_trusted.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * linux/fs/ext4/xattr_trusted.c - * Handler for trusted extended attributes. - * - * Copyright (C) 2003 by Andreas Gruenbacher, - */ - -#include -#include -#include -#include -#include -#include -#include -#include "xattr.h" - -#define XATTR_TRUSTED_PREFIX "trusted." - -static size_t -ext4_xattr_trusted_list(struct inode *inode, char *list, size_t list_size, - const char *name, size_t name_len) -{ - const size_t prefix_len = sizeof(XATTR_TRUSTED_PREFIX)-1; - const size_t total_len = prefix_len + name_len + 1; - - if (!capable(CAP_SYS_ADMIN)) - return 0; - - if (list && total_len <= list_size) { - memcpy(list, XATTR_TRUSTED_PREFIX, prefix_len); - memcpy(list+prefix_len, name, name_len); - list[prefix_len + name_len] = '\0'; - } - return total_len; -} - -static int -ext4_xattr_trusted_get(struct inode *inode, const char *name, - void *buffer, size_t size) -{ - if (strcmp(name, "") == 0) - return -EINVAL; - return ext4_xattr_get(inode, EXT4_XATTR_INDEX_TRUSTED, name, - buffer, size); -} - -static int -ext4_xattr_trusted_set(struct inode *inode, const char *name, - const void *value, size_t size, int flags) -{ - if (strcmp(name, "") == 0) - return -EINVAL; - return ext4_xattr_set(inode, EXT4_XATTR_INDEX_TRUSTED, name, - value, size, flags); -} - -struct xattr_handler ext4_xattr_trusted_handler = { - .prefix = XATTR_TRUSTED_PREFIX, - .list = ext4_xattr_trusted_list, - .get = ext4_xattr_trusted_get, - .set = ext4_xattr_trusted_set, -}; diff --git a/trunk/fs/ext4/xattr_user.c b/trunk/fs/ext4/xattr_user.c deleted file mode 100644 index c53cded0761a..000000000000 --- a/trunk/fs/ext4/xattr_user.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * linux/fs/ext4/xattr_user.c - * Handler for extended user attributes. - * - * Copyright (C) 2001 by Andreas Gruenbacher, - */ - -#include -#include -#include -#include -#include -#include -#include "xattr.h" - -#define XATTR_USER_PREFIX "user." - -static size_t -ext4_xattr_user_list(struct inode *inode, char *list, size_t list_size, - const char *name, size_t name_len) -{ - const size_t prefix_len = sizeof(XATTR_USER_PREFIX)-1; - const size_t total_len = prefix_len + name_len + 1; - - if (!test_opt(inode->i_sb, XATTR_USER)) - return 0; - - if (list && total_len <= list_size) { - memcpy(list, XATTR_USER_PREFIX, prefix_len); - memcpy(list+prefix_len, name, name_len); - list[prefix_len + name_len] = '\0'; - } - return total_len; -} - -static int -ext4_xattr_user_get(struct inode *inode, const char *name, - void *buffer, size_t size) -{ - if (strcmp(name, "") == 0) - return -EINVAL; - if (!test_opt(inode->i_sb, XATTR_USER)) - return -EOPNOTSUPP; - return ext4_xattr_get(inode, EXT4_XATTR_INDEX_USER, name, buffer, size); -} - -static int -ext4_xattr_user_set(struct inode *inode, const char *name, - const void *value, size_t size, int flags) -{ - if (strcmp(name, "") == 0) - return -EINVAL; - if (!test_opt(inode->i_sb, XATTR_USER)) - return -EOPNOTSUPP; - return ext4_xattr_set(inode, EXT4_XATTR_INDEX_USER, name, - value, size, flags); -} - -struct xattr_handler ext4_xattr_user_handler = { - .prefix = XATTR_USER_PREFIX, - .list = ext4_xattr_user_list, - .get = ext4_xattr_user_get, - .set = ext4_xattr_user_set, -}; diff --git a/trunk/fs/fat/file.c b/trunk/fs/fat/file.c index 0aa813d944a6..f4b8f8b3fbdd 100644 --- a/trunk/fs/fat/file.c +++ b/trunk/fs/fat/file.c @@ -13,7 +13,6 @@ #include #include #include -#include #include int fat_generic_ioctl(struct inode *inode, struct file *filp, @@ -119,7 +118,7 @@ static int fat_file_release(struct inode *inode, struct file *filp) if ((filp->f_mode & FMODE_WRITE) && MSDOS_SB(inode->i_sb)->options.flush) { fat_flush_inodes(inode->i_sb, inode, NULL); - congestion_wait(WRITE, HZ/10); + blk_congestion_wait(WRITE, HZ/10); } return 0; } @@ -303,17 +302,7 @@ void fat_truncate(struct inode *inode) fat_flush_inodes(inode->i_sb, inode, NULL); } -int fat_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) -{ - struct inode *inode = dentry->d_inode; - generic_fillattr(inode, stat); - stat->blksize = MSDOS_SB(inode->i_sb)->cluster_size; - return 0; -} -EXPORT_SYMBOL_GPL(fat_getattr); - struct inode_operations fat_file_inode_operations = { .truncate = fat_truncate, .setattr = fat_notify_change, - .getattr = fat_getattr, }; diff --git a/trunk/fs/fat/inode.c b/trunk/fs/fat/inode.c index 78945b53b0f8..045738032a83 100644 --- a/trunk/fs/fat/inode.c +++ b/trunk/fs/fat/inode.c @@ -384,7 +384,7 @@ static int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de) le16_to_cpu(de->cdate)) + secs; inode->i_ctime.tv_nsec = csecs * 10000000; inode->i_atime.tv_sec = - date_dos2unix(0, le16_to_cpu(de->adate)); + date_dos2unix(le16_to_cpu(0), le16_to_cpu(de->adate)); inode->i_atime.tv_nsec = 0; } else inode->i_ctime = inode->i_atime = inode->i_mtime; @@ -1472,7 +1472,7 @@ int fat_flush_inodes(struct super_block *sb, struct inode *i1, struct inode *i2) ret = writeback_inode(i1); if (!ret && i2) ret = writeback_inode(i2); - if (!ret) { + if (!ret && sb) { struct address_space *mapping = sb->s_bdev->bd_inode->i_mapping; ret = filemap_flush(mapping); } diff --git a/trunk/fs/fuse/dir.c b/trunk/fs/fuse/dir.c index c71a6c092ad9..8605155db171 100644 --- a/trunk/fs/fuse/dir.c +++ b/trunk/fs/fuse/dir.c @@ -138,8 +138,6 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd) struct fuse_entry_out outarg; struct fuse_conn *fc; struct fuse_req *req; - struct fuse_req *forget_req; - struct dentry *parent; /* Doesn't hurt to "reset" the validity timeout */ fuse_invalidate_entry_cache(entry); @@ -153,33 +151,21 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd) if (IS_ERR(req)) return 0; - forget_req = fuse_get_req(fc); - if (IS_ERR(forget_req)) { - fuse_put_request(fc, req); - return 0; - } - - parent = dget_parent(entry); - fuse_lookup_init(req, parent->d_inode, entry, &outarg); + fuse_lookup_init(req, entry->d_parent->d_inode, entry, &outarg); request_send(fc, req); - dput(parent); err = req->out.h.error; - fuse_put_request(fc, req); /* Zero nodeid is same as -ENOENT */ if (!err && !outarg.nodeid) err = -ENOENT; if (!err) { struct fuse_inode *fi = get_fuse_inode(inode); if (outarg.nodeid != get_node_id(inode)) { - fuse_send_forget(fc, forget_req, - outarg.nodeid, 1); + fuse_send_forget(fc, req, outarg.nodeid, 1); return 0; } - spin_lock(&fc->lock); fi->nlookup ++; - spin_unlock(&fc->lock); } - fuse_put_request(fc, forget_req); + fuse_put_request(fc, req); if (err || (outarg.attr.mode ^ inode->i_mode) & S_IFMT) return 0; @@ -189,6 +175,22 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd) return 1; } +/* + * Check if there's already a hashed alias of this directory inode. + * If yes, then lookup and mkdir must not create a new alias. + */ +static int dir_alias(struct inode *inode) +{ + if (S_ISDIR(inode->i_mode)) { + struct dentry *alias = d_find_alias(inode); + if (alias) { + dput(alias); + return 1; + } + } + return 0; +} + static int invalid_nodeid(u64 nodeid) { return !nodeid || nodeid == FUSE_ROOT_ID; @@ -204,24 +206,6 @@ static int valid_mode(int m) S_ISBLK(m) || S_ISFIFO(m) || S_ISSOCK(m); } -/* - * Add a directory inode to a dentry, ensuring that no other dentry - * refers to this inode. Called with fc->inst_mutex. - */ -static int fuse_d_add_directory(struct dentry *entry, struct inode *inode) -{ - struct dentry *alias = d_find_alias(inode); - if (alias) { - /* This tries to shrink the subtree below alias */ - fuse_invalidate_entry(alias); - dput(alias); - if (!list_empty(&inode->i_dentry)) - return -EBUSY; - } - d_add(entry, inode); - return 0; -} - static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry, struct nameidata *nd) { @@ -230,7 +214,6 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry, struct inode *inode = NULL; struct fuse_conn *fc = get_fuse_conn(dir); struct fuse_req *req; - struct fuse_req *forget_req; if (entry->d_name.len > FUSE_NAME_MAX) return ERR_PTR(-ENAMETOOLONG); @@ -239,16 +222,9 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry, if (IS_ERR(req)) return ERR_PTR(PTR_ERR(req)); - forget_req = fuse_get_req(fc); - if (IS_ERR(forget_req)) { - fuse_put_request(fc, req); - return ERR_PTR(PTR_ERR(forget_req)); - } - fuse_lookup_init(req, dir, entry, &outarg); request_send(fc, req); err = req->out.h.error; - fuse_put_request(fc, req); /* Zero nodeid is same as -ENOENT, but with valid timeout */ if (!err && outarg.nodeid && (invalid_nodeid(outarg.nodeid) || !valid_mode(outarg.attr.mode))) @@ -257,25 +233,19 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry, inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation, &outarg.attr); if (!inode) { - fuse_send_forget(fc, forget_req, outarg.nodeid, 1); + fuse_send_forget(fc, req, outarg.nodeid, 1); return ERR_PTR(-ENOMEM); } } - fuse_put_request(fc, forget_req); + fuse_put_request(fc, req); if (err && err != -ENOENT) return ERR_PTR(err); - if (inode && S_ISDIR(inode->i_mode)) { - mutex_lock(&fc->inst_mutex); - err = fuse_d_add_directory(entry, inode); - mutex_unlock(&fc->inst_mutex); - if (err) { - iput(inode); - return ERR_PTR(err); - } - } else - d_add(entry, inode); - + if (inode && dir_alias(inode)) { + iput(inode); + return ERR_PTR(-EIO); + } + d_add(entry, inode); entry->d_op = &fuse_dentry_operations; if (!err) fuse_change_timeout(entry, &outarg); @@ -405,13 +375,6 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req, struct fuse_entry_out outarg; struct inode *inode; int err; - struct fuse_req *forget_req; - - forget_req = fuse_get_req(fc); - if (IS_ERR(forget_req)) { - fuse_put_request(fc, req); - return PTR_ERR(forget_req); - } req->in.h.nodeid = get_node_id(dir); req->out.numargs = 1; @@ -419,47 +382,37 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req, req->out.args[0].value = &outarg; request_send(fc, req); err = req->out.h.error; - fuse_put_request(fc, req); - if (err) - goto out_put_forget_req; - + if (err) { + fuse_put_request(fc, req); + return err; + } err = -EIO; if (invalid_nodeid(outarg.nodeid)) - goto out_put_forget_req; + goto out_put_request; if ((outarg.attr.mode ^ mode) & S_IFMT) - goto out_put_forget_req; + goto out_put_request; inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation, &outarg.attr); if (!inode) { - fuse_send_forget(fc, forget_req, outarg.nodeid, 1); + fuse_send_forget(fc, req, outarg.nodeid, 1); return -ENOMEM; } - fuse_put_request(fc, forget_req); + fuse_put_request(fc, req); - if (S_ISDIR(inode->i_mode)) { - struct dentry *alias; - mutex_lock(&fc->inst_mutex); - alias = d_find_alias(inode); - if (alias) { - /* New directory must have moved since mkdir */ - mutex_unlock(&fc->inst_mutex); - dput(alias); - iput(inode); - return -EBUSY; - } - d_instantiate(entry, inode); - mutex_unlock(&fc->inst_mutex); - } else - d_instantiate(entry, inode); + if (dir_alias(inode)) { + iput(inode); + return -EIO; + } + d_instantiate(entry, inode); fuse_change_timeout(entry, &outarg); fuse_invalidate_attr(dir); return 0; - out_put_forget_req: - fuse_put_request(fc, forget_req); + out_put_request: + fuse_put_request(fc, req); return err; } @@ -982,30 +935,14 @@ static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg) } } -static void fuse_vmtruncate(struct inode *inode, loff_t offset) -{ - struct fuse_conn *fc = get_fuse_conn(inode); - int need_trunc; - - spin_lock(&fc->lock); - need_trunc = inode->i_size > offset; - i_size_write(inode, offset); - spin_unlock(&fc->lock); - - if (need_trunc) { - struct address_space *mapping = inode->i_mapping; - unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1); - truncate_inode_pages(mapping, offset); - } -} - /* * Set attributes, and at the same time refresh them. * * Truncation is slightly complicated, because the 'truncate' request * may fail, in which case we don't want to touch the mapping. - * vmtruncate() doesn't allow for this case, so do the rlimit checking - * and the actual truncation by hand. + * vmtruncate() doesn't allow for this case. So do the rlimit + * checking by hand and call vmtruncate() only after the file has + * actually been truncated. */ static int fuse_setattr(struct dentry *entry, struct iattr *attr) { @@ -1056,8 +993,12 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr) make_bad_inode(inode); err = -EIO; } else { - if (is_truncate) - fuse_vmtruncate(inode, outarg.attr.size); + if (is_truncate) { + loff_t origsize = i_size_read(inode); + i_size_write(inode, outarg.attr.size); + if (origsize > outarg.attr.size) + vmtruncate(inode, outarg.attr.size); + } fuse_change_attributes(inode, &outarg.attr); fi->i_time = time_to_jiffies(outarg.attr_valid, outarg.attr_valid_nsec); diff --git a/trunk/fs/fuse/file.c b/trunk/fs/fuse/file.c index 763a50daf1c0..183626868eea 100644 --- a/trunk/fs/fuse/file.c +++ b/trunk/fs/fuse/file.c @@ -397,14 +397,14 @@ static int fuse_readpages(struct file *file, struct address_space *mapping, err = -EIO; if (is_bad_inode(inode)) - goto out; + goto clean_pages_up; data.file = file; data.inode = inode; data.req = fuse_get_req(fc); err = PTR_ERR(data.req); if (IS_ERR(data.req)) - goto out; + goto clean_pages_up; err = read_cache_pages(mapping, pages, fuse_readpages_fill, &data); if (!err) { @@ -413,7 +413,10 @@ static int fuse_readpages(struct file *file, struct address_space *mapping, else fuse_put_request(fc, data.req); } -out: + return err; + +clean_pages_up: + put_pages_list(pages); return err; } @@ -478,10 +481,8 @@ static int fuse_commit_write(struct file *file, struct page *page, err = -EIO; if (!err) { pos += count; - spin_lock(&fc->lock); - if (pos > inode->i_size) + if (pos > i_size_read(inode)) i_size_write(inode, pos); - spin_unlock(&fc->lock); if (offset == 0 && to == PAGE_CACHE_SIZE) { clear_page_dirty(page); @@ -585,12 +586,8 @@ static ssize_t fuse_direct_io(struct file *file, const char __user *buf, } fuse_put_request(fc, req); if (res > 0) { - if (write) { - spin_lock(&fc->lock); - if (pos > inode->i_size) - i_size_write(inode, pos); - spin_unlock(&fc->lock); - } + if (write && pos > i_size_read(inode)) + i_size_write(inode, pos); *ppos = pos; } fuse_invalidate_attr(inode); diff --git a/trunk/fs/fuse/fuse_i.h b/trunk/fs/fuse/fuse_i.h index 91edb8932d90..69c7750d55b8 100644 --- a/trunk/fs/fuse/fuse_i.h +++ b/trunk/fs/fuse/fuse_i.h @@ -239,9 +239,6 @@ struct fuse_conn { /** Lock protecting accessess to members of this structure */ spinlock_t lock; - /** Mutex protecting against directory alias creation */ - struct mutex inst_mutex; - /** Refcount */ atomic_t count; diff --git a/trunk/fs/fuse/inode.c b/trunk/fs/fuse/inode.c index fc4203570370..7d0a9aee01f2 100644 --- a/trunk/fs/fuse/inode.c +++ b/trunk/fs/fuse/inode.c @@ -109,7 +109,6 @@ static int fuse_remount_fs(struct super_block *sb, int *flags, char *data) void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr) { - struct fuse_conn *fc = get_fuse_conn(inode); if (S_ISREG(inode->i_mode) && i_size_read(inode) != attr->size) invalidate_inode_pages(inode->i_mapping); @@ -118,9 +117,7 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr) inode->i_nlink = attr->nlink; inode->i_uid = attr->uid; inode->i_gid = attr->gid; - spin_lock(&fc->lock); i_size_write(inode, attr->size); - spin_unlock(&fc->lock); inode->i_blocks = attr->blocks; inode->i_atime.tv_sec = attr->atime; inode->i_atime.tv_nsec = attr->atimensec; @@ -133,7 +130,7 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr) static void fuse_init_inode(struct inode *inode, struct fuse_attr *attr) { inode->i_mode = attr->mode & S_IFMT; - inode->i_size = attr->size; + i_size_write(inode, attr->size); if (S_ISREG(inode->i_mode)) { fuse_init_common(inode); fuse_init_file_inode(inode); @@ -172,6 +169,7 @@ struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid, struct inode *inode; struct fuse_inode *fi; struct fuse_conn *fc = get_fuse_conn_super(sb); + int retried = 0; retry: inode = iget5_locked(sb, nodeid, fuse_inode_eq, fuse_inode_set, &nodeid); @@ -185,16 +183,16 @@ struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid, fuse_init_inode(inode, attr); unlock_new_inode(inode); } else if ((inode->i_mode ^ attr->mode) & S_IFMT) { + BUG_ON(retried); /* Inode has changed type, any I/O on the old should fail */ make_bad_inode(inode); iput(inode); + retried = 1; goto retry; } fi = get_fuse_inode(inode); - spin_lock(&fc->lock); fi->nlookup ++; - spin_unlock(&fc->lock); fuse_change_attributes(inode, attr); return inode; } @@ -379,7 +377,6 @@ static struct fuse_conn *new_conn(void) fc = kzalloc(sizeof(*fc), GFP_KERNEL); if (fc) { spin_lock_init(&fc->lock); - mutex_init(&fc->inst_mutex); atomic_set(&fc->count, 1); init_waitqueue_head(&fc->waitq); init_waitqueue_head(&fc->blocked_waitq); @@ -399,10 +396,8 @@ static struct fuse_conn *new_conn(void) void fuse_conn_put(struct fuse_conn *fc) { - if (atomic_dec_and_test(&fc->count)) { - mutex_destroy(&fc->inst_mutex); + if (atomic_dec_and_test(&fc->count)) kfree(fc); - } } struct fuse_conn *fuse_conn_get(struct fuse_conn *fc) diff --git a/trunk/fs/gfs2/bmap.c b/trunk/fs/gfs2/bmap.c index 06e9a8cb45e9..cc57f2ecd219 100644 --- a/trunk/fs/gfs2/bmap.c +++ b/trunk/fs/gfs2/bmap.c @@ -434,7 +434,8 @@ static int lookup_block(struct gfs2_inode *ip, struct buffer_head *bh, */ static int gfs2_block_pointers(struct inode *inode, u64 lblock, int create, - struct buffer_head *bh_map, struct metapath *mp) + struct buffer_head *bh_map, struct metapath *mp, + unsigned int maxlen) { struct gfs2_inode *ip = GFS2_I(inode); struct gfs2_sbd *sdp = GFS2_SB(inode); @@ -447,7 +448,6 @@ static int gfs2_block_pointers(struct inode *inode, u64 lblock, int create, int new = 0; u64 dblock = 0; int boundary; - unsigned int maxlen = bh_map->b_size >> inode->i_blkbits; BUG_ON(maxlen == 0); @@ -541,13 +541,13 @@ static inline void bmap_unlock(struct inode *inode, int create) } int gfs2_block_map(struct inode *inode, u64 lblock, int create, - struct buffer_head *bh) + struct buffer_head *bh, unsigned int maxlen) { struct metapath mp; int ret; bmap_lock(inode, create); - ret = gfs2_block_pointers(inode, lblock, create, bh, &mp); + ret = gfs2_block_pointers(inode, lblock, create, bh, &mp, maxlen); bmap_unlock(inode, create); return ret; } @@ -555,7 +555,7 @@ int gfs2_block_map(struct inode *inode, u64 lblock, int create, int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsigned *extlen) { struct metapath mp; - struct buffer_head bh = { .b_state = 0, .b_blocknr = 0 }; + struct buffer_head bh = { .b_state = 0, .b_blocknr = 0, .b_size = 0 }; int ret; int create = *new; @@ -563,9 +563,8 @@ int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsi BUG_ON(!dblock); BUG_ON(!new); - bh.b_size = 1 << (inode->i_blkbits + 5); bmap_lock(inode, create); - ret = gfs2_block_pointers(inode, lblock, create, &bh, &mp); + ret = gfs2_block_pointers(inode, lblock, create, &bh, &mp, 32); bmap_unlock(inode, create); *extlen = bh.b_size >> inode->i_blkbits; *dblock = bh.b_blocknr; diff --git a/trunk/fs/gfs2/bmap.h b/trunk/fs/gfs2/bmap.h index ac2fd04370dc..0fd379b4cd9e 100644 --- a/trunk/fs/gfs2/bmap.h +++ b/trunk/fs/gfs2/bmap.h @@ -15,7 +15,7 @@ struct gfs2_inode; struct page; int gfs2_unstuff_dinode(struct gfs2_inode *ip, struct page *page); -int gfs2_block_map(struct inode *inode, u64 lblock, int create, struct buffer_head *bh); +int gfs2_block_map(struct inode *inode, u64 lblock, int create, struct buffer_head *bh, unsigned int maxlen); int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsigned *extlen); int gfs2_truncatei(struct gfs2_inode *ip, u64 size); diff --git a/trunk/fs/gfs2/dir.c b/trunk/fs/gfs2/dir.c index e24af28b1a12..459498cac93b 100644 --- a/trunk/fs/gfs2/dir.c +++ b/trunk/fs/gfs2/dir.c @@ -184,7 +184,7 @@ static int gfs2_dir_write_data(struct gfs2_inode *ip, const char *buf, while (copied < size) { unsigned int amount; struct buffer_head *bh; - int new = 0; + int new; amount = size - copied; if (amount > sdp->sd_sb.sb_bsize - o) @@ -212,6 +212,8 @@ static int gfs2_dir_write_data(struct gfs2_inode *ip, const char *buf, gfs2_trans_add_bh(ip->i_gl, bh, 1); memcpy(bh->b_data + o, buf, amount); brelse(bh); + if (error) + goto fail; buf += amount; copied += amount; @@ -315,7 +317,8 @@ static int gfs2_dir_read_data(struct gfs2_inode *ip, char *buf, u64 offset, if (!ra) extlen = 1; bh = gfs2_meta_ra(ip->i_gl, dblock, extlen); - } else { + } + if (!bh) { error = gfs2_meta_read(ip->i_gl, dblock, DIO_WAIT, &bh); if (error) goto fail; @@ -329,6 +332,7 @@ static int gfs2_dir_read_data(struct gfs2_inode *ip, char *buf, u64 offset, extlen--; memcpy(buf, bh->b_data + o, amount); brelse(bh); + bh = NULL; buf += amount; copied += amount; lblock++; @@ -811,7 +815,7 @@ static struct gfs2_leaf *new_leaf(struct inode *inode, struct buffer_head **pbh, leaf = (struct gfs2_leaf *)bh->b_data; leaf->lf_depth = cpu_to_be16(depth); leaf->lf_entries = 0; - leaf->lf_dirent_format = cpu_to_be32(GFS2_FORMAT_DE); + leaf->lf_dirent_format = cpu_to_be16(GFS2_FORMAT_DE); leaf->lf_next = 0; memset(leaf->lf_reserved, 0, sizeof(leaf->lf_reserved)); dent = (struct gfs2_dirent *)(leaf+1); diff --git a/trunk/fs/gfs2/inode.c b/trunk/fs/gfs2/inode.c index d470e5286ecd..57c43ac47925 100644 --- a/trunk/fs/gfs2/inode.c +++ b/trunk/fs/gfs2/inode.c @@ -157,9 +157,6 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum *inum, struct gfs2_glock *io_gl; int error; - if (!inode) - return ERR_PTR(-ENOBUFS); - if (inode->i_state & I_NEW) { struct gfs2_sbd *sdp = GFS2_SB(inode); umode_t mode = DT2IF(type); diff --git a/trunk/fs/gfs2/locking/dlm/mount.c b/trunk/fs/gfs2/locking/dlm/mount.c index cdd1694e889b..1f94dd35a943 100644 --- a/trunk/fs/gfs2/locking/dlm/mount.c +++ b/trunk/fs/gfs2/locking/dlm/mount.c @@ -45,7 +45,7 @@ static struct gdlm_ls *init_gdlm(lm_callback_t cb, struct gfs2_sbd *sdp, strncpy(buf, table_name, 256); buf[255] = '\0'; - p = strchr(buf, ':'); + p = strstr(buf, ":"); if (!p) { log_info("invalid table_name \"%s\"", table_name); kfree(ls); diff --git a/trunk/fs/gfs2/log.c b/trunk/fs/gfs2/log.c index 0cace3da9dbb..554fe5bd1b72 100644 --- a/trunk/fs/gfs2/log.c +++ b/trunk/fs/gfs2/log.c @@ -312,12 +312,10 @@ void gfs2_log_release(struct gfs2_sbd *sdp, unsigned int blks) static u64 log_bmap(struct gfs2_sbd *sdp, unsigned int lbn) { - struct inode *inode = sdp->sd_jdesc->jd_inode; int error; - struct buffer_head bh_map = { .b_state = 0, .b_blocknr = 0 }; + struct buffer_head bh_map; - bh_map.b_size = 1 << inode->i_blkbits; - error = gfs2_block_map(inode, lbn, 0, &bh_map); + error = gfs2_block_map(sdp->sd_jdesc->jd_inode, lbn, 0, &bh_map, 1); if (error || !bh_map.b_blocknr) printk(KERN_INFO "error=%d, dbn=%llu lbn=%u", error, bh_map.b_blocknr, lbn); gfs2_assert_withdraw(sdp, !error && bh_map.b_blocknr); @@ -571,15 +569,16 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl) else if (sdp->sd_log_tail != current_tail(sdp) && !sdp->sd_log_idle) log_write_header(sdp, 0, PULL); lops_after_commit(sdp, ai); - - gfs2_log_lock(sdp); sdp->sd_log_head = sdp->sd_log_flush_head; + sdp->sd_log_blks_free -= sdp->sd_log_num_hdrs; + sdp->sd_log_blks_reserved = 0; sdp->sd_log_commited_buf = 0; sdp->sd_log_num_hdrs = 0; sdp->sd_log_commited_revoke = 0; + gfs2_log_lock(sdp); if (!list_empty(&ai->ai_ail1_list)) { list_add(&ai->ai_list, &sdp->sd_ail1_list); ai = NULL; diff --git a/trunk/fs/gfs2/lops.c b/trunk/fs/gfs2/lops.c index ab6d1115f95d..881e337b6a70 100644 --- a/trunk/fs/gfs2/lops.c +++ b/trunk/fs/gfs2/lops.c @@ -492,7 +492,7 @@ static int gfs2_check_magic(struct buffer_head *bh) ptr = kaddr + bh_offset(bh); if (*ptr == cpu_to_be32(GFS2_MAGIC)) rv = 1; - kunmap_atomic(kaddr, KM_USER0); + kunmap_atomic(page, KM_USER0); return rv; } @@ -626,7 +626,7 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp) memcpy(bh->b_data, kaddr + bh_offset(bd2->bd_bh), sdp->sd_sb.sb_bsize); - kunmap_atomic(kaddr, KM_USER0); + kunmap_atomic(page, KM_USER0); *(__be32 *)bh->b_data = 0; } else { bh = gfs2_log_fake_buf(sdp, bd2->bd_bh); diff --git a/trunk/fs/gfs2/main.c b/trunk/fs/gfs2/main.c index 9889c1eacec1..21508a13bb78 100644 --- a/trunk/fs/gfs2/main.c +++ b/trunk/fs/gfs2/main.c @@ -84,8 +84,8 @@ static int __init init_gfs2_fs(void) gfs2_inode_cachep = kmem_cache_create("gfs2_inode", sizeof(struct gfs2_inode), - 0, SLAB_RECLAIM_ACCOUNT| - SLAB_MEM_SPREAD, + 0, (SLAB_RECLAIM_ACCOUNT| + SLAB_PANIC|SLAB_MEM_SPREAD), gfs2_init_inode_once, NULL); if (!gfs2_inode_cachep) goto fail; diff --git a/trunk/fs/gfs2/ops_address.c b/trunk/fs/gfs2/ops_address.c index 015640b3f123..4fb743f4e4a4 100644 --- a/trunk/fs/gfs2/ops_address.c +++ b/trunk/fs/gfs2/ops_address.c @@ -65,7 +65,7 @@ static void gfs2_page_add_databufs(struct gfs2_inode *ip, struct page *page, int gfs2_get_block(struct inode *inode, sector_t lblock, struct buffer_head *bh_result, int create) { - return gfs2_block_map(inode, lblock, create, bh_result); + return gfs2_block_map(inode, lblock, create, bh_result, 32); } /** @@ -83,7 +83,7 @@ static int gfs2_get_block_noalloc(struct inode *inode, sector_t lblock, { int error; - error = gfs2_block_map(inode, lblock, 0, bh_result); + error = gfs2_block_map(inode, lblock, 0, bh_result, 1); if (error) return error; if (bh_result->b_blocknr == 0) @@ -94,7 +94,7 @@ static int gfs2_get_block_noalloc(struct inode *inode, sector_t lblock, static int gfs2_get_block_direct(struct inode *inode, sector_t lblock, struct buffer_head *bh_result, int create) { - return gfs2_block_map(inode, lblock, 0, bh_result); + return gfs2_block_map(inode, lblock, 0, bh_result, 32); } /** @@ -162,7 +162,7 @@ static int zero_readpage(struct page *page) kaddr = kmap_atomic(page, KM_USER0); memset(kaddr, 0, PAGE_CACHE_SIZE); - kunmap_atomic(kaddr, KM_USER0); + kunmap_atomic(page, KM_USER0); SetPageUptodate(page); @@ -195,7 +195,7 @@ static int stuffed_readpage(struct gfs2_inode *ip, struct page *page) memcpy(kaddr, dibh->b_data + sizeof(struct gfs2_dinode), ip->i_di.di_size); memset(kaddr + ip->i_di.di_size, 0, PAGE_CACHE_SIZE - ip->i_di.di_size); - kunmap_atomic(kaddr, KM_USER0); + kunmap_atomic(page, KM_USER0); brelse(dibh); @@ -337,6 +337,13 @@ static int gfs2_readpages(struct file *file, struct address_space *mapping, out_noerror: ret = 0; out_unlock: + /* unlock all pages, we can't do any I/O right now */ + for (page_idx = 0; page_idx < nr_pages; page_idx++) { + struct page *page = list_entry(pages->prev, struct page, lru); + list_del(&page->lru); + unlock_page(page); + page_cache_release(page); + } if (do_unlock) gfs2_holder_uninit(&gh); goto out; @@ -363,22 +370,19 @@ static int gfs2_prepare_write(struct file *file, struct page *page, loff_t pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + from; loff_t end = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to; struct gfs2_alloc *al; - unsigned int write_len = to - from; - gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_ATIME|GL_AOP, &ip->i_gh); error = gfs2_glock_nq_m_atime(1, &ip->i_gh); if (error) goto out_uninit; - gfs2_write_calc_reserv(ip, write_len, &data_blocks, &ind_blocks); + gfs2_write_calc_reserv(ip, to - from, &data_blocks, &ind_blocks); - error = gfs2_write_alloc_required(ip, pos, write_len, &alloc_required); + error = gfs2_write_alloc_required(ip, pos, from - to, &alloc_required); if (error) goto out_unlock; - ip->i_alloc.al_requested = 0; if (alloc_required) { al = gfs2_alloc_get(ip); @@ -478,7 +482,7 @@ static int gfs2_commit_write(struct file *file, struct page *page, kaddr = kmap_atomic(page, KM_USER0); memcpy(dibh->b_data + sizeof(struct gfs2_dinode) + from, kaddr + from, to - from); - kunmap_atomic(kaddr, KM_USER0); + kunmap_atomic(page, KM_USER0); SetPageUptodate(page); diff --git a/trunk/fs/gfs2/ops_fstype.c b/trunk/fs/gfs2/ops_fstype.c index 882873a6bd69..178b33911843 100644 --- a/trunk/fs/gfs2/ops_fstype.c +++ b/trunk/fs/gfs2/ops_fstype.c @@ -794,8 +794,8 @@ static int fill_super_meta(struct super_block *sb, struct super_block *new, fs_err(sdp, "can't get root dentry\n"); error = -ENOMEM; iput(inode); - } else - new->s_root->d_op = &gfs2_dops; + } + new->s_root->d_op = &gfs2_dops; return error; } @@ -854,6 +854,7 @@ static int gfs2_get_sb_meta(struct file_system_type *fs_type, int flags, int error = 0; struct super_block *sb = NULL, *new; struct gfs2_sbd *sdp; + char *gfs2mnt = NULL; sb = get_gfs2_sb(dev_name); if (!sb) { @@ -891,6 +892,8 @@ static int gfs2_get_sb_meta(struct file_system_type *fs_type, int flags, atomic_inc(&sdp->sd_gfs2mnt->mnt_count); return simple_set_mnt(mnt, new); error: + if (gfs2mnt) + kfree(gfs2mnt); return error; } diff --git a/trunk/fs/gfs2/ops_super.c b/trunk/fs/gfs2/ops_super.c index b47d9598c047..06f06f7773d0 100644 --- a/trunk/fs/gfs2/ops_super.c +++ b/trunk/fs/gfs2/ops_super.c @@ -138,27 +138,16 @@ static void gfs2_put_super(struct super_block *sb) } /** - * gfs2_write_super - * @sb: the superblock + * gfs2_write_super - disk commit all incore transactions + * @sb: the filesystem * + * This function is called every time sync(2) is called. + * After this exits, all dirty buffers are synced. */ static void gfs2_write_super(struct super_block *sb) { - sb->s_dirt = 0; -} - -/** - * gfs2_sync_fs - sync the filesystem - * @sb: the superblock - * - * Flushes the log to disk. - */ -static int gfs2_sync_fs(struct super_block *sb, int wait) -{ - sb->s_dirt = 0; gfs2_log_flush(sb->s_fs_info, NULL); - return 0; } /** @@ -463,18 +452,17 @@ static void gfs2_destroy_inode(struct inode *inode) } struct super_operations gfs2_super_ops = { - .alloc_inode = gfs2_alloc_inode, - .destroy_inode = gfs2_destroy_inode, - .write_inode = gfs2_write_inode, - .delete_inode = gfs2_delete_inode, - .put_super = gfs2_put_super, - .write_super = gfs2_write_super, - .sync_fs = gfs2_sync_fs, - .write_super_lockfs = gfs2_write_super_lockfs, - .unlockfs = gfs2_unlockfs, - .statfs = gfs2_statfs, - .remount_fs = gfs2_remount_fs, - .clear_inode = gfs2_clear_inode, - .show_options = gfs2_show_options, + .alloc_inode = gfs2_alloc_inode, + .destroy_inode = gfs2_destroy_inode, + .write_inode = gfs2_write_inode, + .delete_inode = gfs2_delete_inode, + .put_super = gfs2_put_super, + .write_super = gfs2_write_super, + .write_super_lockfs = gfs2_write_super_lockfs, + .unlockfs = gfs2_unlockfs, + .statfs = gfs2_statfs, + .remount_fs = gfs2_remount_fs, + .clear_inode = gfs2_clear_inode, + .show_options = gfs2_show_options, }; diff --git a/trunk/fs/gfs2/quota.c b/trunk/fs/gfs2/quota.c index a3deae7416c9..c69b94a55588 100644 --- a/trunk/fs/gfs2/quota.c +++ b/trunk/fs/gfs2/quota.c @@ -251,7 +251,7 @@ static int bh_get(struct gfs2_quota_data *qd) unsigned int block, offset; struct buffer_head *bh; int error; - struct buffer_head bh_map = { .b_state = 0, .b_blocknr = 0 }; + struct buffer_head bh_map; mutex_lock(&sdp->sd_quota_mutex); @@ -263,8 +263,7 @@ static int bh_get(struct gfs2_quota_data *qd) block = qd->qd_slot / sdp->sd_qc_per_block; offset = qd->qd_slot % sdp->sd_qc_per_block;; - bh_map.b_size = 1 << ip->i_inode.i_blkbits; - error = gfs2_block_map(&ip->i_inode, block, 0, &bh_map); + error = gfs2_block_map(&ip->i_inode, block, 0, &bh_map, 1); if (error) goto fail; error = gfs2_meta_read(ip->i_gl, bh_map.b_blocknr, DIO_WAIT, &bh); diff --git a/trunk/fs/gfs2/recovery.c b/trunk/fs/gfs2/recovery.c index 62cd223819b7..0a8a4b87dcc6 100644 --- a/trunk/fs/gfs2/recovery.c +++ b/trunk/fs/gfs2/recovery.c @@ -372,12 +372,11 @@ static int clean_journal(struct gfs2_jdesc *jd, struct gfs2_log_header *head) u32 hash; struct buffer_head *bh; int error; - struct buffer_head bh_map = { .b_state = 0, .b_blocknr = 0 }; + struct buffer_head bh_map; lblock = head->lh_blkno; gfs2_replay_incr_blk(sdp, &lblock); - bh_map.b_size = 1 << ip->i_inode.i_blkbits; - error = gfs2_block_map(&ip->i_inode, lblock, 0, &bh_map); + error = gfs2_block_map(&ip->i_inode, lblock, 0, &bh_map, 1); if (error) return error; if (!bh_map.b_blocknr) { diff --git a/trunk/fs/gfs2/rgrp.h b/trunk/fs/gfs2/rgrp.h index b01e0cfc99b5..9eedfd12bfff 100644 --- a/trunk/fs/gfs2/rgrp.h +++ b/trunk/fs/gfs2/rgrp.h @@ -32,7 +32,7 @@ void gfs2_rgrp_repolish_clones(struct gfs2_rgrpd *rgd); struct gfs2_alloc *gfs2_alloc_get(struct gfs2_inode *ip); static inline void gfs2_alloc_put(struct gfs2_inode *ip) { - return; /* So we can see where ip->i_alloc is used */ + return; /* Se we can see where ip->i_alloc is used */ } int gfs2_inplace_reserve_i(struct gfs2_inode *ip, diff --git a/trunk/fs/hfs/super.c b/trunk/fs/hfs/super.c index 85b17b3fa4a0..d43b4fcc8ad3 100644 --- a/trunk/fs/hfs/super.c +++ b/trunk/fs/hfs/super.c @@ -390,13 +390,11 @@ static int hfs_fill_super(struct super_block *sb, void *data, int silent) hfs_find_exit(&fd); goto bail_no_root; } - res = -EINVAL; root_inode = hfs_iget(sb, &fd.search_key->cat, &rec); hfs_find_exit(&fd); if (!root_inode) goto bail_no_root; - res = -ENOMEM; sb->s_root = d_alloc_root(root_inode); if (!sb->s_root) goto bail_iput; diff --git a/trunk/fs/hpfs/inode.c b/trunk/fs/hpfs/inode.c index 7faef8544f32..bcf6ee36e065 100644 --- a/trunk/fs/hpfs/inode.c +++ b/trunk/fs/hpfs/inode.c @@ -60,14 +60,14 @@ void hpfs_read_inode(struct inode *i) if (hpfs_sb(i->i_sb)->sb_eas) { if ((ea = hpfs_get_ea(i->i_sb, fnode, "UID", &ea_size))) { if (ea_size == 2) { - i->i_uid = le16_to_cpu(*(__le16*)ea); + i->i_uid = le16_to_cpu(*(u16*)ea); hpfs_inode->i_ea_uid = 1; } kfree(ea); } if ((ea = hpfs_get_ea(i->i_sb, fnode, "GID", &ea_size))) { if (ea_size == 2) { - i->i_gid = le16_to_cpu(*(__le16*)ea); + i->i_gid = le16_to_cpu(*(u16*)ea); hpfs_inode->i_ea_gid = 1; } kfree(ea); @@ -87,7 +87,7 @@ void hpfs_read_inode(struct inode *i) int rdev = 0; umode_t mode = hpfs_sb(sb)->sb_mode; if (ea_size == 2) { - mode = le16_to_cpu(*(__le16*)ea); + mode = le16_to_cpu(*(u16*)ea); hpfs_inode->i_ea_mode = 1; } kfree(ea); @@ -95,7 +95,7 @@ void hpfs_read_inode(struct inode *i) if (S_ISBLK(mode) || S_ISCHR(mode)) { if ((ea = hpfs_get_ea(i->i_sb, fnode, "DEV", &ea_size))) { if (ea_size == 4) - rdev = le32_to_cpu(*(__le32*)ea); + rdev = le32_to_cpu(*(u32*)ea); kfree(ea); } } @@ -148,7 +148,7 @@ static void hpfs_write_inode_ea(struct inode *i, struct fnode *fnode) we'd better not overwrite them hpfs_error(i->i_sb, "fnode %08x has some unknown HPFS386 stuctures", i->i_ino); } else*/ if (hpfs_sb(i->i_sb)->sb_eas >= 2) { - __le32 ea; + u32 ea; if ((i->i_uid != hpfs_sb(i->i_sb)->sb_uid) || hpfs_inode->i_ea_uid) { ea = cpu_to_le32(i->i_uid); hpfs_set_ea(i, fnode, "UID", (char*)&ea, 2); @@ -165,7 +165,6 @@ static void hpfs_write_inode_ea(struct inode *i, struct fnode *fnode) && i->i_mode != ((hpfs_sb(i->i_sb)->sb_mode & ~(S_ISDIR(i->i_mode) ? 0222 : 0333)) | (S_ISDIR(i->i_mode) ? S_IFDIR : S_IFREG))) || hpfs_inode->i_ea_mode) { ea = cpu_to_le32(i->i_mode); - /* sick, but legal */ hpfs_set_ea(i, fnode, "MODE", (char *)&ea, 2); hpfs_inode->i_ea_mode = 1; } diff --git a/trunk/fs/hppfs/hppfs_kern.c b/trunk/fs/hppfs/hppfs_kern.c index 642675fc394a..dcb6d2e988b8 100644 --- a/trunk/fs/hppfs/hppfs_kern.c +++ b/trunk/fs/hppfs/hppfs_kern.c @@ -572,7 +572,7 @@ struct hppfs_dirent { }; static int hppfs_filldir(void *d, const char *name, int size, - loff_t offset, u64 inode, unsigned int type) + loff_t offset, ino_t inode, unsigned int type) { struct hppfs_dirent *dirent = d; diff --git a/trunk/fs/hugetlbfs/inode.c b/trunk/fs/hugetlbfs/inode.c index 7f4756963d05..5e03b2f67b93 100644 --- a/trunk/fs/hugetlbfs/inode.c +++ b/trunk/fs/hugetlbfs/inode.c @@ -62,19 +62,24 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma) loff_t len, vma_len; int ret; - /* - * vma alignment has already been checked by prepare_hugepage_range. - * If you add any error returns here, do so after setting VM_HUGETLB, - * so is_vm_hugetlb_page tests below unmap_region go the right way - * when do_mmap_pgoff unwinds (may be important on powerpc and ia64). - */ - vma->vm_flags |= VM_HUGETLB | VM_RESERVED; - vma->vm_ops = &hugetlb_vm_ops; + if (vma->vm_pgoff & (HPAGE_SIZE / PAGE_SIZE - 1)) + return -EINVAL; + + if (vma->vm_start & ~HPAGE_MASK) + return -EINVAL; + + if (vma->vm_end & ~HPAGE_MASK) + return -EINVAL; + + if (vma->vm_end - vma->vm_start < HPAGE_SIZE) + return -EINVAL; vma_len = (loff_t)(vma->vm_end - vma->vm_start); mutex_lock(&inode->i_mutex); file_accessed(file); + vma->vm_flags |= VM_HUGETLB | VM_RESERVED; + vma->vm_ops = &hugetlb_vm_ops; ret = -ENOMEM; len = vma_len + ((loff_t)vma->vm_pgoff << PAGE_SHIFT); @@ -266,27 +271,29 @@ static void hugetlbfs_drop_inode(struct inode *inode) hugetlbfs_forget_inode(inode); } +/* + * h_pgoff is in HPAGE_SIZE units. + * vma->vm_pgoff is in PAGE_SIZE units. + */ static inline void -hugetlb_vmtruncate_list(struct prio_tree_root *root, pgoff_t pgoff) +hugetlb_vmtruncate_list(struct prio_tree_root *root, unsigned long h_pgoff) { struct vm_area_struct *vma; struct prio_tree_iter iter; - vma_prio_tree_foreach(vma, &iter, root, pgoff, ULONG_MAX) { + vma_prio_tree_foreach(vma, &iter, root, h_pgoff, ULONG_MAX) { + unsigned long h_vm_pgoff; unsigned long v_offset; + h_vm_pgoff = vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT); + v_offset = (h_pgoff - h_vm_pgoff) << HPAGE_SHIFT; /* - * Can the expression below overflow on 32-bit arches? - * No, because the prio_tree returns us only those vmas - * which overlap the truncated area starting at pgoff, - * and no vma on a 32-bit arch can span beyond the 4GB. + * Is this VMA fully outside the truncation point? */ - if (vma->vm_pgoff < pgoff) - v_offset = (pgoff - vma->vm_pgoff) << PAGE_SHIFT; - else + if (h_vm_pgoff >= h_pgoff) v_offset = 0; - __unmap_hugepage_range(vma, + unmap_hugepage_range(vma, vma->vm_start + v_offset, vma->vm_end); } } @@ -296,14 +303,14 @@ hugetlb_vmtruncate_list(struct prio_tree_root *root, pgoff_t pgoff) */ static int hugetlb_vmtruncate(struct inode *inode, loff_t offset) { - pgoff_t pgoff; + unsigned long pgoff; struct address_space *mapping = inode->i_mapping; if (offset > inode->i_size) return -EINVAL; BUG_ON(offset & ~HPAGE_MASK); - pgoff = offset >> PAGE_SHIFT; + pgoff = offset >> HPAGE_SHIFT; inode->i_size = offset; spin_lock(&mapping->i_mmap_lock); @@ -617,6 +624,7 @@ hugetlbfs_parse_options(char *options, struct hugetlbfs_config *pconfig) do_div(size, 100); rest++; } + size &= HPAGE_MASK; pconfig->nr_blocks = (size >> HPAGE_SHIFT); value = rest; } else if (!strcmp(opt,"nr_inodes")) { diff --git a/trunk/fs/inode.c b/trunk/fs/inode.c index 26cdb115ce67..bf6bec4e54ff 100644 --- a/trunk/fs/inode.c +++ b/trunk/fs/inode.c @@ -162,7 +162,7 @@ static struct inode *alloc_inode(struct super_block *sb) bdi = sb->s_bdev->bd_inode->i_mapping->backing_dev_info; mapping->backing_dev_info = bdi; } - inode->i_private = NULL; + inode->i_private = 0; inode->i_mapping = mapping; } return inode; @@ -1306,42 +1306,6 @@ void wake_up_inode(struct inode *inode) wake_up_bit(&inode->i_state, __I_LOCK); } -/* - * We rarely want to lock two inodes that do not have a parent/child - * relationship (such as directory, child inode) simultaneously. The - * vast majority of file systems should be able to get along fine - * without this. Do not use these functions except as a last resort. - */ -void inode_double_lock(struct inode *inode1, struct inode *inode2) -{ - if (inode1 == NULL || inode2 == NULL || inode1 == inode2) { - if (inode1) - mutex_lock(&inode1->i_mutex); - else if (inode2) - mutex_lock(&inode2->i_mutex); - return; - } - - if (inode1 < inode2) { - mutex_lock_nested(&inode1->i_mutex, I_MUTEX_PARENT); - mutex_lock_nested(&inode2->i_mutex, I_MUTEX_CHILD); - } else { - mutex_lock_nested(&inode2->i_mutex, I_MUTEX_PARENT); - mutex_lock_nested(&inode1->i_mutex, I_MUTEX_CHILD); - } -} -EXPORT_SYMBOL(inode_double_lock); - -void inode_double_unlock(struct inode *inode1, struct inode *inode2) -{ - if (inode1) - mutex_unlock(&inode1->i_mutex); - - if (inode2 && inode2 != inode1) - mutex_unlock(&inode2->i_mutex); -} -EXPORT_SYMBOL(inode_double_unlock); - static __initdata unsigned long ihash_entries; static int __init set_ihash_entries(char *str) { diff --git a/trunk/fs/ioprio.c b/trunk/fs/ioprio.c index 89e8da112a75..6dc6721d9e82 100644 --- a/trunk/fs/ioprio.c +++ b/trunk/fs/ioprio.c @@ -150,6 +150,11 @@ int ioprio_best(unsigned short aprio, unsigned short bprio) unsigned short aclass = IOPRIO_PRIO_CLASS(aprio); unsigned short bclass = IOPRIO_PRIO_CLASS(bprio); + if (!ioprio_valid(aprio)) + return bprio; + if (!ioprio_valid(bprio)) + return aprio; + if (aclass == IOPRIO_CLASS_NONE) aclass = IOPRIO_CLASS_BE; if (bclass == IOPRIO_CLASS_NONE) diff --git a/trunk/fs/isofs/joliet.c b/trunk/fs/isofs/joliet.c index fb8fe7a9ddc6..81a90e170ac3 100644 --- a/trunk/fs/isofs/joliet.c +++ b/trunk/fs/isofs/joliet.c @@ -14,9 +14,9 @@ * Convert Unicode 16 to UTF-8 or ASCII. */ static int -uni16_to_x8(unsigned char *ascii, __be16 *uni, int len, struct nls_table *nls) +uni16_to_x8(unsigned char *ascii, u16 *uni, int len, struct nls_table *nls) { - __be16 *ip, ch; + wchar_t *ip, ch; unsigned char *op; ip = uni; @@ -24,8 +24,8 @@ uni16_to_x8(unsigned char *ascii, __be16 *uni, int len, struct nls_table *nls) while ((ch = get_unaligned(ip)) && len) { int llen; - llen = nls->uni2char(be16_to_cpu(ch), op, NLS_MAX_CHARSET_SIZE); - if (llen > 0) + ch = be16_to_cpu(ch); + if ((llen = nls->uni2char(ch, op, NLS_MAX_CHARSET_SIZE)) > 0) op += llen; else *op++ = '?'; @@ -82,7 +82,7 @@ get_joliet_filename(struct iso_directory_record * de, unsigned char *outname, st len = wcsntombs_be(outname, de->name, de->name_len[0] >> 1, PAGE_SIZE); } else { - len = uni16_to_x8(outname, (__be16 *) de->name, + len = uni16_to_x8(outname, (u16 *) de->name, de->name_len[0] >> 1, nls); } if ((len > 2) && (outname[len-2] == ';') && (outname[len-1] == '1')) { diff --git a/trunk/fs/jbd/journal.c b/trunk/fs/jbd/journal.c index b85c686b60db..c518dd8fe60a 100644 --- a/trunk/fs/jbd/journal.c +++ b/trunk/fs/jbd/journal.c @@ -725,7 +725,6 @@ journal_t * journal_init_dev(struct block_device *bdev, __FUNCTION__); kfree(journal); journal = NULL; - goto out; } journal->j_dev = bdev; journal->j_fs_dev = fs_dev; @@ -736,7 +735,7 @@ journal_t * journal_init_dev(struct block_device *bdev, J_ASSERT(bh != NULL); journal->j_sb_buffer = bh; journal->j_superblock = (journal_superblock_t *)bh->b_data; -out: + return journal; } diff --git a/trunk/fs/jbd/transaction.c b/trunk/fs/jbd/transaction.c index 4f82bcd63e48..e1b3c8af4d17 100644 --- a/trunk/fs/jbd/transaction.c +++ b/trunk/fs/jbd/transaction.c @@ -967,13 +967,6 @@ int journal_dirty_data(handle_t *handle, struct buffer_head *bh) */ jbd_lock_bh_state(bh); spin_lock(&journal->j_list_lock); - - /* Now that we have bh_state locked, are we really still mapped? */ - if (!buffer_mapped(bh)) { - JBUFFER_TRACE(jh, "unmapped buffer, bailing out"); - goto no_journal; - } - if (jh->b_transaction) { JBUFFER_TRACE(jh, "has transaction"); if (jh->b_transaction != handle->h_transaction) { @@ -1035,11 +1028,6 @@ int journal_dirty_data(handle_t *handle, struct buffer_head *bh) sync_dirty_buffer(bh); jbd_lock_bh_state(bh); spin_lock(&journal->j_list_lock); - /* Since we dropped the lock... */ - if (!buffer_mapped(bh)) { - JBUFFER_TRACE(jh, "buffer got unmapped"); - goto no_journal; - } /* The buffer may become locked again at any time if it is redirtied */ } @@ -1326,14 +1314,13 @@ int journal_stop(handle_t *handle) int old_handle_count, err; pid_t pid; + J_ASSERT(transaction->t_updates > 0); J_ASSERT(journal_current_handle() == handle); if (is_handle_aborted(handle)) err = -EIO; - else { - J_ASSERT(transaction->t_updates > 0); + else err = 0; - } if (--handle->h_ref > 0) { jbd_debug(4, "h_ref %d -> %d\n", handle->h_ref + 1, @@ -1836,7 +1823,6 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh) } } } else if (transaction == journal->j_committing_transaction) { - JBUFFER_TRACE(jh, "on committing transaction"); if (jh->b_jlist == BJ_Locked) { /* * The buffer is on the committing transaction's locked @@ -1851,6 +1837,7 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh) * can remove it's next_transaction pointer from the * running transaction if that is set, but nothing * else. */ + JBUFFER_TRACE(jh, "on committing transaction"); set_buffer_freed(bh); if (jh->b_next_transaction) { J_ASSERT(jh->b_next_transaction == @@ -1870,7 +1857,6 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh) * i_size already for this truncate so recovery will not * expose the disk blocks we are discarding here.) */ J_ASSERT_JH(jh, transaction == journal->j_running_transaction); - JBUFFER_TRACE(jh, "on running transaction"); may_free = __dispose_buffer(jh, transaction); } diff --git a/trunk/fs/jbd2/Makefile b/trunk/fs/jbd2/Makefile deleted file mode 100644 index 802a3413872a..000000000000 --- a/trunk/fs/jbd2/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# -# Makefile for the linux journaling routines. -# - -obj-$(CONFIG_JBD2) += jbd2.o - -jbd2-objs := transaction.o commit.o recovery.o checkpoint.o revoke.o journal.o diff --git a/trunk/fs/jbd2/checkpoint.c b/trunk/fs/jbd2/checkpoint.c deleted file mode 100644 index 68039fa9a566..000000000000 --- a/trunk/fs/jbd2/checkpoint.c +++ /dev/null @@ -1,697 +0,0 @@ -/* - * linux/fs/checkpoint.c - * - * Written by Stephen C. Tweedie , 1999 - * - * Copyright 1999 Red Hat Software --- All Rights Reserved - * - * This file is part of the Linux kernel and is made available under - * the terms of the GNU General Public License, version 2, or at your - * option, any later version, incorporated herein by reference. - * - * Checkpoint routines for the generic filesystem journaling code. - * Part of the ext2fs journaling system. - * - * Checkpointing is the process of ensuring that a section of the log is - * committed fully to disk, so that that portion of the log can be - * reused. - */ - -#include -#include -#include -#include -#include - -/* - * Unlink a buffer from a transaction checkpoint list. - * - * Called with j_list_lock held. - */ -static inline void __buffer_unlink_first(struct journal_head *jh) -{ - transaction_t *transaction = jh->b_cp_transaction; - - jh->b_cpnext->b_cpprev = jh->b_cpprev; - jh->b_cpprev->b_cpnext = jh->b_cpnext; - if (transaction->t_checkpoint_list == jh) { - transaction->t_checkpoint_list = jh->b_cpnext; - if (transaction->t_checkpoint_list == jh) - transaction->t_checkpoint_list = NULL; - } -} - -/* - * Unlink a buffer from a transaction checkpoint(io) list. - * - * Called with j_list_lock held. - */ -static inline void __buffer_unlink(struct journal_head *jh) -{ - transaction_t *transaction = jh->b_cp_transaction; - - __buffer_unlink_first(jh); - if (transaction->t_checkpoint_io_list == jh) { - transaction->t_checkpoint_io_list = jh->b_cpnext; - if (transaction->t_checkpoint_io_list == jh) - transaction->t_checkpoint_io_list = NULL; - } -} - -/* - * Move a buffer from the checkpoint list to the checkpoint io list - * - * Called with j_list_lock held - */ -static inline void __buffer_relink_io(struct journal_head *jh) -{ - transaction_t *transaction = jh->b_cp_transaction; - - __buffer_unlink_first(jh); - - if (!transaction->t_checkpoint_io_list) { - jh->b_cpnext = jh->b_cpprev = jh; - } else { - jh->b_cpnext = transaction->t_checkpoint_io_list; - jh->b_cpprev = transaction->t_checkpoint_io_list->b_cpprev; - jh->b_cpprev->b_cpnext = jh; - jh->b_cpnext->b_cpprev = jh; - } - transaction->t_checkpoint_io_list = jh; -} - -/* - * Try to release a checkpointed buffer from its transaction. - * Returns 1 if we released it and 2 if we also released the - * whole transaction. - * - * Requires j_list_lock - * Called under jbd_lock_bh_state(jh2bh(jh)), and drops it - */ -static int __try_to_free_cp_buf(struct journal_head *jh) -{ - int ret = 0; - struct buffer_head *bh = jh2bh(jh); - - if (jh->b_jlist == BJ_None && !buffer_locked(bh) && !buffer_dirty(bh)) { - JBUFFER_TRACE(jh, "remove from checkpoint list"); - ret = __jbd2_journal_remove_checkpoint(jh) + 1; - jbd_unlock_bh_state(bh); - jbd2_journal_remove_journal_head(bh); - BUFFER_TRACE(bh, "release"); - __brelse(bh); - } else { - jbd_unlock_bh_state(bh); - } - return ret; -} - -/* - * __jbd2_log_wait_for_space: wait until there is space in the journal. - * - * Called under j-state_lock *only*. It will be unlocked if we have to wait - * for a checkpoint to free up some space in the log. - */ -void __jbd2_log_wait_for_space(journal_t *journal) -{ - int nblocks; - assert_spin_locked(&journal->j_state_lock); - - nblocks = jbd_space_needed(journal); - while (__jbd2_log_space_left(journal) < nblocks) { - if (journal->j_flags & JBD2_ABORT) - return; - spin_unlock(&journal->j_state_lock); - mutex_lock(&journal->j_checkpoint_mutex); - - /* - * Test again, another process may have checkpointed while we - * were waiting for the checkpoint lock - */ - spin_lock(&journal->j_state_lock); - nblocks = jbd_space_needed(journal); - if (__jbd2_log_space_left(journal) < nblocks) { - spin_unlock(&journal->j_state_lock); - jbd2_log_do_checkpoint(journal); - spin_lock(&journal->j_state_lock); - } - mutex_unlock(&journal->j_checkpoint_mutex); - } -} - -/* - * We were unable to perform jbd_trylock_bh_state() inside j_list_lock. - * The caller must restart a list walk. Wait for someone else to run - * jbd_unlock_bh_state(). - */ -static void jbd_sync_bh(journal_t *journal, struct buffer_head *bh) - __releases(journal->j_list_lock) -{ - get_bh(bh); - spin_unlock(&journal->j_list_lock); - jbd_lock_bh_state(bh); - jbd_unlock_bh_state(bh); - put_bh(bh); -} - -/* - * Clean up transaction's list of buffers submitted for io. - * We wait for any pending IO to complete and remove any clean - * buffers. Note that we take the buffers in the opposite ordering - * from the one in which they were submitted for IO. - * - * Called with j_list_lock held. - */ -static void __wait_cp_io(journal_t *journal, transaction_t *transaction) -{ - struct journal_head *jh; - struct buffer_head *bh; - tid_t this_tid; - int released = 0; - - this_tid = transaction->t_tid; -restart: - /* Did somebody clean up the transaction in the meanwhile? */ - if (journal->j_checkpoint_transactions != transaction || - transaction->t_tid != this_tid) - return; - while (!released && transaction->t_checkpoint_io_list) { - jh = transaction->t_checkpoint_io_list; - bh = jh2bh(jh); - if (!jbd_trylock_bh_state(bh)) { - jbd_sync_bh(journal, bh); - spin_lock(&journal->j_list_lock); - goto restart; - } - if (buffer_locked(bh)) { - atomic_inc(&bh->b_count); - spin_unlock(&journal->j_list_lock); - jbd_unlock_bh_state(bh); - wait_on_buffer(bh); - /* the journal_head may have gone by now */ - BUFFER_TRACE(bh, "brelse"); - __brelse(bh); - spin_lock(&journal->j_list_lock); - goto restart; - } - /* - * Now in whatever state the buffer currently is, we know that - * it has been written out and so we can drop it from the list - */ - released = __jbd2_journal_remove_checkpoint(jh); - jbd_unlock_bh_state(bh); - jbd2_journal_remove_journal_head(bh); - __brelse(bh); - } -} - -#define NR_BATCH 64 - -static void -__flush_batch(journal_t *journal, struct buffer_head **bhs, int *batch_count) -{ - int i; - - ll_rw_block(SWRITE, *batch_count, bhs); - for (i = 0; i < *batch_count; i++) { - struct buffer_head *bh = bhs[i]; - clear_buffer_jwrite(bh); - BUFFER_TRACE(bh, "brelse"); - __brelse(bh); - } - *batch_count = 0; -} - -/* - * Try to flush one buffer from the checkpoint list to disk. - * - * Return 1 if something happened which requires us to abort the current - * scan of the checkpoint list. - * - * Called with j_list_lock held and drops it if 1 is returned - * Called under jbd_lock_bh_state(jh2bh(jh)), and drops it - */ -static int __process_buffer(journal_t *journal, struct journal_head *jh, - struct buffer_head **bhs, int *batch_count) -{ - struct buffer_head *bh = jh2bh(jh); - int ret = 0; - - if (buffer_locked(bh)) { - atomic_inc(&bh->b_count); - spin_unlock(&journal->j_list_lock); - jbd_unlock_bh_state(bh); - wait_on_buffer(bh); - /* the journal_head may have gone by now */ - BUFFER_TRACE(bh, "brelse"); - __brelse(bh); - ret = 1; - } else if (jh->b_transaction != NULL) { - transaction_t *t = jh->b_transaction; - tid_t tid = t->t_tid; - - spin_unlock(&journal->j_list_lock); - jbd_unlock_bh_state(bh); - jbd2_log_start_commit(journal, tid); - jbd2_log_wait_commit(journal, tid); - ret = 1; - } else if (!buffer_dirty(bh)) { - J_ASSERT_JH(jh, !buffer_jbddirty(bh)); - BUFFER_TRACE(bh, "remove from checkpoint"); - __jbd2_journal_remove_checkpoint(jh); - spin_unlock(&journal->j_list_lock); - jbd_unlock_bh_state(bh); - jbd2_journal_remove_journal_head(bh); - __brelse(bh); - ret = 1; - } else { - /* - * Important: we are about to write the buffer, and - * possibly block, while still holding the journal lock. - * We cannot afford to let the transaction logic start - * messing around with this buffer before we write it to - * disk, as that would break recoverability. - */ - BUFFER_TRACE(bh, "queue"); - get_bh(bh); - J_ASSERT_BH(bh, !buffer_jwrite(bh)); - set_buffer_jwrite(bh); - bhs[*batch_count] = bh; - __buffer_relink_io(jh); - jbd_unlock_bh_state(bh); - (*batch_count)++; - if (*batch_count == NR_BATCH) { - spin_unlock(&journal->j_list_lock); - __flush_batch(journal, bhs, batch_count); - ret = 1; - } - } - return ret; -} - -/* - * Perform an actual checkpoint. We take the first transaction on the - * list of transactions to be checkpointed and send all its buffers - * to disk. We submit larger chunks of data at once. - * - * The journal should be locked before calling this function. - */ -int jbd2_log_do_checkpoint(journal_t *journal) -{ - transaction_t *transaction; - tid_t this_tid; - int result; - - jbd_debug(1, "Start checkpoint\n"); - - /* - * First thing: if there are any transactions in the log which - * don't need checkpointing, just eliminate them from the - * journal straight away. - */ - result = jbd2_cleanup_journal_tail(journal); - jbd_debug(1, "cleanup_journal_tail returned %d\n", result); - if (result <= 0) - return result; - - /* - * OK, we need to start writing disk blocks. Take one transaction - * and write it. - */ - spin_lock(&journal->j_list_lock); - if (!journal->j_checkpoint_transactions) - goto out; - transaction = journal->j_checkpoint_transactions; - this_tid = transaction->t_tid; -restart: - /* - * If someone cleaned up this transaction while we slept, we're - * done (maybe it's a new transaction, but it fell at the same - * address). - */ - if (journal->j_checkpoint_transactions == transaction && - transaction->t_tid == this_tid) { - int batch_count = 0; - struct buffer_head *bhs[NR_BATCH]; - struct journal_head *jh; - int retry = 0; - - while (!retry && transaction->t_checkpoint_list) { - struct buffer_head *bh; - - jh = transaction->t_checkpoint_list; - bh = jh2bh(jh); - if (!jbd_trylock_bh_state(bh)) { - jbd_sync_bh(journal, bh); - retry = 1; - break; - } - retry = __process_buffer(journal, jh, bhs,&batch_count); - if (!retry && lock_need_resched(&journal->j_list_lock)){ - spin_unlock(&journal->j_list_lock); - retry = 1; - break; - } - } - - if (batch_count) { - if (!retry) { - spin_unlock(&journal->j_list_lock); - retry = 1; - } - __flush_batch(journal, bhs, &batch_count); - } - - if (retry) { - spin_lock(&journal->j_list_lock); - goto restart; - } - /* - * Now we have cleaned up the first transaction's checkpoint - * list. Let's clean up the second one - */ - __wait_cp_io(journal, transaction); - } -out: - spin_unlock(&journal->j_list_lock); - result = jbd2_cleanup_journal_tail(journal); - if (result < 0) - return result; - return 0; -} - -/* - * Check the list of checkpoint transactions for the journal to see if - * we have already got rid of any since the last update of the log tail - * in the journal superblock. If so, we can instantly roll the - * superblock forward to remove those transactions from the log. - * - * Return <0 on error, 0 on success, 1 if there was nothing to clean up. - * - * Called with the journal lock held. - * - * This is the only part of the journaling code which really needs to be - * aware of transaction aborts. Checkpointing involves writing to the - * main filesystem area rather than to the journal, so it can proceed - * even in abort state, but we must not update the journal superblock if - * we have an abort error outstanding. - */ - -int jbd2_cleanup_journal_tail(journal_t *journal) -{ - transaction_t * transaction; - tid_t first_tid; - unsigned long blocknr, freed; - - /* OK, work out the oldest transaction remaining in the log, and - * the log block it starts at. - * - * If the log is now empty, we need to work out which is the - * next transaction ID we will write, and where it will - * start. */ - - spin_lock(&journal->j_state_lock); - spin_lock(&journal->j_list_lock); - transaction = journal->j_checkpoint_transactions; - if (transaction) { - first_tid = transaction->t_tid; - blocknr = transaction->t_log_start; - } else if ((transaction = journal->j_committing_transaction) != NULL) { - first_tid = transaction->t_tid; - blocknr = transaction->t_log_start; - } else if ((transaction = journal->j_running_transaction) != NULL) { - first_tid = transaction->t_tid; - blocknr = journal->j_head; - } else { - first_tid = journal->j_transaction_sequence; - blocknr = journal->j_head; - } - spin_unlock(&journal->j_list_lock); - J_ASSERT(blocknr != 0); - - /* If the oldest pinned transaction is at the tail of the log - already then there's not much we can do right now. */ - if (journal->j_tail_sequence == first_tid) { - spin_unlock(&journal->j_state_lock); - return 1; - } - - /* OK, update the superblock to recover the freed space. - * Physical blocks come first: have we wrapped beyond the end of - * the log? */ - freed = blocknr - journal->j_tail; - if (blocknr < journal->j_tail) - freed = freed + journal->j_last - journal->j_first; - - jbd_debug(1, - "Cleaning journal tail from %d to %d (offset %lu), " - "freeing %lu\n", - journal->j_tail_sequence, first_tid, blocknr, freed); - - journal->j_free += freed; - journal->j_tail_sequence = first_tid; - journal->j_tail = blocknr; - spin_unlock(&journal->j_state_lock); - if (!(journal->j_flags & JBD2_ABORT)) - jbd2_journal_update_superblock(journal, 1); - return 0; -} - - -/* Checkpoint list management */ - -/* - * journal_clean_one_cp_list - * - * Find all the written-back checkpoint buffers in the given list and release them. - * - * Called with the journal locked. - * Called with j_list_lock held. - * Returns number of bufers reaped (for debug) - */ - -static int journal_clean_one_cp_list(struct journal_head *jh, int *released) -{ - struct journal_head *last_jh; - struct journal_head *next_jh = jh; - int ret, freed = 0; - - *released = 0; - if (!jh) - return 0; - - last_jh = jh->b_cpprev; - do { - jh = next_jh; - next_jh = jh->b_cpnext; - /* Use trylock because of the ranking */ - if (jbd_trylock_bh_state(jh2bh(jh))) { - ret = __try_to_free_cp_buf(jh); - if (ret) { - freed++; - if (ret == 2) { - *released = 1; - return freed; - } - } - } - /* - * This function only frees up some memory - * if possible so we dont have an obligation - * to finish processing. Bail out if preemption - * requested: - */ - if (need_resched()) - return freed; - } while (jh != last_jh); - - return freed; -} - -/* - * journal_clean_checkpoint_list - * - * Find all the written-back checkpoint buffers in the journal and release them. - * - * Called with the journal locked. - * Called with j_list_lock held. - * Returns number of buffers reaped (for debug) - */ - -int __jbd2_journal_clean_checkpoint_list(journal_t *journal) -{ - transaction_t *transaction, *last_transaction, *next_transaction; - int ret = 0; - int released; - - transaction = journal->j_checkpoint_transactions; - if (!transaction) - goto out; - - last_transaction = transaction->t_cpprev; - next_transaction = transaction; - do { - transaction = next_transaction; - next_transaction = transaction->t_cpnext; - ret += journal_clean_one_cp_list(transaction-> - t_checkpoint_list, &released); - /* - * This function only frees up some memory if possible so we - * dont have an obligation to finish processing. Bail out if - * preemption requested: - */ - if (need_resched()) - goto out; - if (released) - continue; - /* - * It is essential that we are as careful as in the case of - * t_checkpoint_list with removing the buffer from the list as - * we can possibly see not yet submitted buffers on io_list - */ - ret += journal_clean_one_cp_list(transaction-> - t_checkpoint_io_list, &released); - if (need_resched()) - goto out; - } while (transaction != last_transaction); -out: - return ret; -} - -/* - * journal_remove_checkpoint: called after a buffer has been committed - * to disk (either by being write-back flushed to disk, or being - * committed to the log). - * - * We cannot safely clean a transaction out of the log until all of the - * buffer updates committed in that transaction have safely been stored - * elsewhere on disk. To achieve this, all of the buffers in a - * transaction need to be maintained on the transaction's checkpoint - * lists until they have been rewritten, at which point this function is - * called to remove the buffer from the existing transaction's - * checkpoint lists. - * - * The function returns 1 if it frees the transaction, 0 otherwise. - * - * This function is called with the journal locked. - * This function is called with j_list_lock held. - * This function is called with jbd_lock_bh_state(jh2bh(jh)) - */ - -int __jbd2_journal_remove_checkpoint(struct journal_head *jh) -{ - transaction_t *transaction; - journal_t *journal; - int ret = 0; - - JBUFFER_TRACE(jh, "entry"); - - if ((transaction = jh->b_cp_transaction) == NULL) { - JBUFFER_TRACE(jh, "not on transaction"); - goto out; - } - journal = transaction->t_journal; - - __buffer_unlink(jh); - jh->b_cp_transaction = NULL; - - if (transaction->t_checkpoint_list != NULL || - transaction->t_checkpoint_io_list != NULL) - goto out; - JBUFFER_TRACE(jh, "transaction has no more buffers"); - - /* - * There is one special case to worry about: if we have just pulled the - * buffer off a committing transaction's forget list, then even if the - * checkpoint list is empty, the transaction obviously cannot be - * dropped! - * - * The locking here around j_committing_transaction is a bit sleazy. - * See the comment at the end of jbd2_journal_commit_transaction(). - */ - if (transaction == journal->j_committing_transaction) { - JBUFFER_TRACE(jh, "belongs to committing transaction"); - goto out; - } - - /* OK, that was the last buffer for the transaction: we can now - safely remove this transaction from the log */ - - __jbd2_journal_drop_transaction(journal, transaction); - - /* Just in case anybody was waiting for more transactions to be - checkpointed... */ - wake_up(&journal->j_wait_logspace); - ret = 1; -out: - JBUFFER_TRACE(jh, "exit"); - return ret; -} - -/* - * journal_insert_checkpoint: put a committed buffer onto a checkpoint - * list so that we know when it is safe to clean the transaction out of - * the log. - * - * Called with the journal locked. - * Called with j_list_lock held. - */ -void __jbd2_journal_insert_checkpoint(struct journal_head *jh, - transaction_t *transaction) -{ - JBUFFER_TRACE(jh, "entry"); - J_ASSERT_JH(jh, buffer_dirty(jh2bh(jh)) || buffer_jbddirty(jh2bh(jh))); - J_ASSERT_JH(jh, jh->b_cp_transaction == NULL); - - jh->b_cp_transaction = transaction; - - if (!transaction->t_checkpoint_list) { - jh->b_cpnext = jh->b_cpprev = jh; - } else { - jh->b_cpnext = transaction->t_checkpoint_list; - jh->b_cpprev = transaction->t_checkpoint_list->b_cpprev; - jh->b_cpprev->b_cpnext = jh; - jh->b_cpnext->b_cpprev = jh; - } - transaction->t_checkpoint_list = jh; -} - -/* - * We've finished with this transaction structure: adios... - * - * The transaction must have no links except for the checkpoint by this - * point. - * - * Called with the journal locked. - * Called with j_list_lock held. - */ - -void __jbd2_journal_drop_transaction(journal_t *journal, transaction_t *transaction) -{ - assert_spin_locked(&journal->j_list_lock); - if (transaction->t_cpnext) { - transaction->t_cpnext->t_cpprev = transaction->t_cpprev; - transaction->t_cpprev->t_cpnext = transaction->t_cpnext; - if (journal->j_checkpoint_transactions == transaction) - journal->j_checkpoint_transactions = - transaction->t_cpnext; - if (journal->j_checkpoint_transactions == transaction) - journal->j_checkpoint_transactions = NULL; - } - - J_ASSERT(transaction->t_state == T_FINISHED); - J_ASSERT(transaction->t_buffers == NULL); - J_ASSERT(transaction->t_sync_datalist == NULL); - J_ASSERT(transaction->t_forget == NULL); - J_ASSERT(transaction->t_iobuf_list == NULL); - J_ASSERT(transaction->t_shadow_list == NULL); - J_ASSERT(transaction->t_log_list == NULL); - J_ASSERT(transaction->t_checkpoint_list == NULL); - J_ASSERT(transaction->t_checkpoint_io_list == NULL); - J_ASSERT(transaction->t_updates == 0); - J_ASSERT(journal->j_committing_transaction != transaction); - J_ASSERT(journal->j_running_transaction != transaction); - - jbd_debug(1, "Dropping transaction %d, all done\n", transaction->t_tid); - kfree(transaction); -} diff --git a/trunk/fs/jbd2/commit.c b/trunk/fs/jbd2/commit.c deleted file mode 100644 index 70b2ae1ef281..000000000000 --- a/trunk/fs/jbd2/commit.c +++ /dev/null @@ -1,920 +0,0 @@ -/* - * linux/fs/jbd2/commit.c - * - * Written by Stephen C. Tweedie , 1998 - * - * Copyright 1998 Red Hat corp --- All Rights Reserved - * - * This file is part of the Linux kernel and is made available under - * the terms of the GNU General Public License, version 2, or at your - * option, any later version, incorporated herein by reference. - * - * Journal commit routines for the generic filesystem journaling code; - * part of the ext2fs journaling system. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Default IO end handler for temporary BJ_IO buffer_heads. - */ -static void journal_end_buffer_io_sync(struct buffer_head *bh, int uptodate) -{ - BUFFER_TRACE(bh, ""); - if (uptodate) - set_buffer_uptodate(bh); - else - clear_buffer_uptodate(bh); - unlock_buffer(bh); -} - -/* - * When an ext3-ordered file is truncated, it is possible that many pages are - * not sucessfully freed, because they are attached to a committing transaction. - * After the transaction commits, these pages are left on the LRU, with no - * ->mapping, and with attached buffers. These pages are trivially reclaimable - * by the VM, but their apparent absence upsets the VM accounting, and it makes - * the numbers in /proc/meminfo look odd. - * - * So here, we have a buffer which has just come off the forget list. Look to - * see if we can strip all buffers from the backing page. - * - * Called under lock_journal(), and possibly under journal_datalist_lock. The - * caller provided us with a ref against the buffer, and we drop that here. - */ -static void release_buffer_page(struct buffer_head *bh) -{ - struct page *page; - - if (buffer_dirty(bh)) - goto nope; - if (atomic_read(&bh->b_count) != 1) - goto nope; - page = bh->b_page; - if (!page) - goto nope; - if (page->mapping) - goto nope; - - /* OK, it's a truncated page */ - if (TestSetPageLocked(page)) - goto nope; - - page_cache_get(page); - __brelse(bh); - try_to_free_buffers(page); - unlock_page(page); - page_cache_release(page); - return; - -nope: - __brelse(bh); -} - -/* - * Try to acquire jbd_lock_bh_state() against the buffer, when j_list_lock is - * held. For ranking reasons we must trylock. If we lose, schedule away and - * return 0. j_list_lock is dropped in this case. - */ -static int inverted_lock(journal_t *journal, struct buffer_head *bh) -{ - if (!jbd_trylock_bh_state(bh)) { - spin_unlock(&journal->j_list_lock); - schedule(); - return 0; - } - return 1; -} - -/* Done it all: now write the commit record. We should have - * cleaned up our previous buffers by now, so if we are in abort - * mode we can now just skip the rest of the journal write - * entirely. - * - * Returns 1 if the journal needs to be aborted or 0 on success - */ -static int journal_write_commit_record(journal_t *journal, - transaction_t *commit_transaction) -{ - struct journal_head *descriptor; - struct buffer_head *bh; - int i, ret; - int barrier_done = 0; - - if (is_journal_aborted(journal)) - return 0; - - descriptor = jbd2_journal_get_descriptor_buffer(journal); - if (!descriptor) - return 1; - - bh = jh2bh(descriptor); - - /* AKPM: buglet - add `i' to tmp! */ - for (i = 0; i < bh->b_size; i += 512) { - journal_header_t *tmp = (journal_header_t*)bh->b_data; - tmp->h_magic = cpu_to_be32(JBD2_MAGIC_NUMBER); - tmp->h_blocktype = cpu_to_be32(JBD2_COMMIT_BLOCK); - tmp->h_sequence = cpu_to_be32(commit_transaction->t_tid); - } - - JBUFFER_TRACE(descriptor, "write commit block"); - set_buffer_dirty(bh); - if (journal->j_flags & JBD2_BARRIER) { - set_buffer_ordered(bh); - barrier_done = 1; - } - ret = sync_dirty_buffer(bh); - /* is it possible for another commit to fail at roughly - * the same time as this one? If so, we don't want to - * trust the barrier flag in the super, but instead want - * to remember if we sent a barrier request - */ - if (ret == -EOPNOTSUPP && barrier_done) { - char b[BDEVNAME_SIZE]; - - printk(KERN_WARNING - "JBD: barrier-based sync failed on %s - " - "disabling barriers\n", - bdevname(journal->j_dev, b)); - spin_lock(&journal->j_state_lock); - journal->j_flags &= ~JBD2_BARRIER; - spin_unlock(&journal->j_state_lock); - - /* And try again, without the barrier */ - clear_buffer_ordered(bh); - set_buffer_uptodate(bh); - set_buffer_dirty(bh); - ret = sync_dirty_buffer(bh); - } - put_bh(bh); /* One for getblk() */ - jbd2_journal_put_journal_head(descriptor); - - return (ret == -EIO); -} - -static void journal_do_submit_data(struct buffer_head **wbuf, int bufs) -{ - int i; - - for (i = 0; i < bufs; i++) { - wbuf[i]->b_end_io = end_buffer_write_sync; - /* We use-up our safety reference in submit_bh() */ - submit_bh(WRITE, wbuf[i]); - } -} - -/* - * Submit all the data buffers to disk - */ -static void journal_submit_data_buffers(journal_t *journal, - transaction_t *commit_transaction) -{ - struct journal_head *jh; - struct buffer_head *bh; - int locked; - int bufs = 0; - struct buffer_head **wbuf = journal->j_wbuf; - - /* - * Whenever we unlock the journal and sleep, things can get added - * onto ->t_sync_datalist, so we have to keep looping back to - * write_out_data until we *know* that the list is empty. - * - * Cleanup any flushed data buffers from the data list. Even in - * abort mode, we want to flush this out as soon as possible. - */ -write_out_data: - cond_resched(); - spin_lock(&journal->j_list_lock); - - while (commit_transaction->t_sync_datalist) { - jh = commit_transaction->t_sync_datalist; - bh = jh2bh(jh); - locked = 0; - - /* Get reference just to make sure buffer does not disappear - * when we are forced to drop various locks */ - get_bh(bh); - /* If the buffer is dirty, we need to submit IO and hence - * we need the buffer lock. We try to lock the buffer without - * blocking. If we fail, we need to drop j_list_lock and do - * blocking lock_buffer(). - */ - if (buffer_dirty(bh)) { - if (test_set_buffer_locked(bh)) { - BUFFER_TRACE(bh, "needs blocking lock"); - spin_unlock(&journal->j_list_lock); - /* Write out all data to prevent deadlocks */ - journal_do_submit_data(wbuf, bufs); - bufs = 0; - lock_buffer(bh); - spin_lock(&journal->j_list_lock); - } - locked = 1; - } - /* We have to get bh_state lock. Again out of order, sigh. */ - if (!inverted_lock(journal, bh)) { - jbd_lock_bh_state(bh); - spin_lock(&journal->j_list_lock); - } - /* Someone already cleaned up the buffer? */ - if (!buffer_jbd(bh) - || jh->b_transaction != commit_transaction - || jh->b_jlist != BJ_SyncData) { - jbd_unlock_bh_state(bh); - if (locked) - unlock_buffer(bh); - BUFFER_TRACE(bh, "already cleaned up"); - put_bh(bh); - continue; - } - if (locked && test_clear_buffer_dirty(bh)) { - BUFFER_TRACE(bh, "needs writeout, adding to array"); - wbuf[bufs++] = bh; - __jbd2_journal_file_buffer(jh, commit_transaction, - BJ_Locked); - jbd_unlock_bh_state(bh); - if (bufs == journal->j_wbufsize) { - spin_unlock(&journal->j_list_lock); - journal_do_submit_data(wbuf, bufs); - bufs = 0; - goto write_out_data; - } - } - else { - BUFFER_TRACE(bh, "writeout complete: unfile"); - __jbd2_journal_unfile_buffer(jh); - jbd_unlock_bh_state(bh); - if (locked) - unlock_buffer(bh); - jbd2_journal_remove_journal_head(bh); - /* Once for our safety reference, once for - * jbd2_journal_remove_journal_head() */ - put_bh(bh); - put_bh(bh); - } - - if (lock_need_resched(&journal->j_list_lock)) { - spin_unlock(&journal->j_list_lock); - goto write_out_data; - } - } - spin_unlock(&journal->j_list_lock); - journal_do_submit_data(wbuf, bufs); -} - -static inline void write_tag_block(int tag_bytes, journal_block_tag_t *tag, - unsigned long long block) -{ - tag->t_blocknr = cpu_to_be32(block & (u32)~0); - if (tag_bytes > JBD_TAG_SIZE32) - tag->t_blocknr_high = cpu_to_be32((block >> 31) >> 1); -} - -/* - * jbd2_journal_commit_transaction - * - * The primary function for committing a transaction to the log. This - * function is called by the journal thread to begin a complete commit. - */ -void jbd2_journal_commit_transaction(journal_t *journal) -{ - transaction_t *commit_transaction; - struct journal_head *jh, *new_jh, *descriptor; - struct buffer_head **wbuf = journal->j_wbuf; - int bufs; - int flags; - int err; - unsigned long long blocknr; - char *tagp = NULL; - journal_header_t *header; - journal_block_tag_t *tag = NULL; - int space_left = 0; - int first_tag = 0; - int tag_flag; - int i; - int tag_bytes = journal_tag_bytes(journal); - - /* - * First job: lock down the current transaction and wait for - * all outstanding updates to complete. - */ - -#ifdef COMMIT_STATS - spin_lock(&journal->j_list_lock); - summarise_journal_usage(journal); - spin_unlock(&journal->j_list_lock); -#endif - - /* Do we need to erase the effects of a prior jbd2_journal_flush? */ - if (journal->j_flags & JBD2_FLUSHED) { - jbd_debug(3, "super block updated\n"); - jbd2_journal_update_superblock(journal, 1); - } else { - jbd_debug(3, "superblock not updated\n"); - } - - J_ASSERT(journal->j_running_transaction != NULL); - J_ASSERT(journal->j_committing_transaction == NULL); - - commit_transaction = journal->j_running_transaction; - J_ASSERT(commit_transaction->t_state == T_RUNNING); - - jbd_debug(1, "JBD: starting commit of transaction %d\n", - commit_transaction->t_tid); - - spin_lock(&journal->j_state_lock); - commit_transaction->t_state = T_LOCKED; - - spin_lock(&commit_transaction->t_handle_lock); - while (commit_transaction->t_updates) { - DEFINE_WAIT(wait); - - prepare_to_wait(&journal->j_wait_updates, &wait, - TASK_UNINTERRUPTIBLE); - if (commit_transaction->t_updates) { - spin_unlock(&commit_transaction->t_handle_lock); - spin_unlock(&journal->j_state_lock); - schedule(); - spin_lock(&journal->j_state_lock); - spin_lock(&commit_transaction->t_handle_lock); - } - finish_wait(&journal->j_wait_updates, &wait); - } - spin_unlock(&commit_transaction->t_handle_lock); - - J_ASSERT (commit_transaction->t_outstanding_credits <= - journal->j_max_transaction_buffers); - - /* - * First thing we are allowed to do is to discard any remaining - * BJ_Reserved buffers. Note, it is _not_ permissible to assume - * that there are no such buffers: if a large filesystem - * operation like a truncate needs to split itself over multiple - * transactions, then it may try to do a jbd2_journal_restart() while - * there are still BJ_Reserved buffers outstanding. These must - * be released cleanly from the current transaction. - * - * In this case, the filesystem must still reserve write access - * again before modifying the buffer in the new transaction, but - * we do not require it to remember exactly which old buffers it - * has reserved. This is consistent with the existing behaviour - * that multiple jbd2_journal_get_write_access() calls to the same - * buffer are perfectly permissable. - */ - while (commit_transaction->t_reserved_list) { - jh = commit_transaction->t_reserved_list; - JBUFFER_TRACE(jh, "reserved, unused: refile"); - /* - * A jbd2_journal_get_undo_access()+jbd2_journal_release_buffer() may - * leave undo-committed data. - */ - if (jh->b_committed_data) { - struct buffer_head *bh = jh2bh(jh); - - jbd_lock_bh_state(bh); - jbd2_slab_free(jh->b_committed_data, bh->b_size); - jh->b_committed_data = NULL; - jbd_unlock_bh_state(bh); - } - jbd2_journal_refile_buffer(journal, jh); - } - - /* - * Now try to drop any written-back buffers from the journal's - * checkpoint lists. We do this *before* commit because it potentially - * frees some memory - */ - spin_lock(&journal->j_list_lock); - __jbd2_journal_clean_checkpoint_list(journal); - spin_unlock(&journal->j_list_lock); - - jbd_debug (3, "JBD: commit phase 1\n"); - - /* - * Switch to a new revoke table. - */ - jbd2_journal_switch_revoke_table(journal); - - commit_transaction->t_state = T_FLUSH; - journal->j_committing_transaction = commit_transaction; - journal->j_running_transaction = NULL; - commit_transaction->t_log_start = journal->j_head; - wake_up(&journal->j_wait_transaction_locked); - spin_unlock(&journal->j_state_lock); - - jbd_debug (3, "JBD: commit phase 2\n"); - - /* - * First, drop modified flag: all accesses to the buffers - * will be tracked for a new trasaction only -bzzz - */ - spin_lock(&journal->j_list_lock); - if (commit_transaction->t_buffers) { - new_jh = jh = commit_transaction->t_buffers->b_tnext; - do { - J_ASSERT_JH(new_jh, new_jh->b_modified == 1 || - new_jh->b_modified == 0); - new_jh->b_modified = 0; - new_jh = new_jh->b_tnext; - } while (new_jh != jh); - } - spin_unlock(&journal->j_list_lock); - - /* - * Now start flushing things to disk, in the order they appear - * on the transaction lists. Data blocks go first. - */ - err = 0; - journal_submit_data_buffers(journal, commit_transaction); - - /* - * Wait for all previously submitted IO to complete. - */ - spin_lock(&journal->j_list_lock); - while (commit_transaction->t_locked_list) { - struct buffer_head *bh; - - jh = commit_transaction->t_locked_list->b_tprev; - bh = jh2bh(jh); - get_bh(bh); - if (buffer_locked(bh)) { - spin_unlock(&journal->j_list_lock); - wait_on_buffer(bh); - if (unlikely(!buffer_uptodate(bh))) - err = -EIO; - spin_lock(&journal->j_list_lock); - } - if (!inverted_lock(journal, bh)) { - put_bh(bh); - spin_lock(&journal->j_list_lock); - continue; - } - if (buffer_jbd(bh) && jh->b_jlist == BJ_Locked) { - __jbd2_journal_unfile_buffer(jh); - jbd_unlock_bh_state(bh); - jbd2_journal_remove_journal_head(bh); - put_bh(bh); - } else { - jbd_unlock_bh_state(bh); - } - put_bh(bh); - cond_resched_lock(&journal->j_list_lock); - } - spin_unlock(&journal->j_list_lock); - - if (err) - __jbd2_journal_abort_hard(journal); - - jbd2_journal_write_revoke_records(journal, commit_transaction); - - jbd_debug(3, "JBD: commit phase 2\n"); - - /* - * If we found any dirty or locked buffers, then we should have - * looped back up to the write_out_data label. If there weren't - * any then journal_clean_data_list should have wiped the list - * clean by now, so check that it is in fact empty. - */ - J_ASSERT (commit_transaction->t_sync_datalist == NULL); - - jbd_debug (3, "JBD: commit phase 3\n"); - - /* - * Way to go: we have now written out all of the data for a - * transaction! Now comes the tricky part: we need to write out - * metadata. Loop over the transaction's entire buffer list: - */ - commit_transaction->t_state = T_COMMIT; - - descriptor = NULL; - bufs = 0; - while (commit_transaction->t_buffers) { - - /* Find the next buffer to be journaled... */ - - jh = commit_transaction->t_buffers; - - /* If we're in abort mode, we just un-journal the buffer and - release it for background writing. */ - - if (is_journal_aborted(journal)) { - JBUFFER_TRACE(jh, "journal is aborting: refile"); - jbd2_journal_refile_buffer(journal, jh); - /* If that was the last one, we need to clean up - * any descriptor buffers which may have been - * already allocated, even if we are now - * aborting. */ - if (!commit_transaction->t_buffers) - goto start_journal_io; - continue; - } - - /* Make sure we have a descriptor block in which to - record the metadata buffer. */ - - if (!descriptor) { - struct buffer_head *bh; - - J_ASSERT (bufs == 0); - - jbd_debug(4, "JBD: get descriptor\n"); - - descriptor = jbd2_journal_get_descriptor_buffer(journal); - if (!descriptor) { - __jbd2_journal_abort_hard(journal); - continue; - } - - bh = jh2bh(descriptor); - jbd_debug(4, "JBD: got buffer %llu (%p)\n", - (unsigned long long)bh->b_blocknr, bh->b_data); - header = (journal_header_t *)&bh->b_data[0]; - header->h_magic = cpu_to_be32(JBD2_MAGIC_NUMBER); - header->h_blocktype = cpu_to_be32(JBD2_DESCRIPTOR_BLOCK); - header->h_sequence = cpu_to_be32(commit_transaction->t_tid); - - tagp = &bh->b_data[sizeof(journal_header_t)]; - space_left = bh->b_size - sizeof(journal_header_t); - first_tag = 1; - set_buffer_jwrite(bh); - set_buffer_dirty(bh); - wbuf[bufs++] = bh; - - /* Record it so that we can wait for IO - completion later */ - BUFFER_TRACE(bh, "ph3: file as descriptor"); - jbd2_journal_file_buffer(descriptor, commit_transaction, - BJ_LogCtl); - } - - /* Where is the buffer to be written? */ - - err = jbd2_journal_next_log_block(journal, &blocknr); - /* If the block mapping failed, just abandon the buffer - and repeat this loop: we'll fall into the - refile-on-abort condition above. */ - if (err) { - __jbd2_journal_abort_hard(journal); - continue; - } - - /* - * start_this_handle() uses t_outstanding_credits to determine - * the free space in the log, but this counter is changed - * by jbd2_journal_next_log_block() also. - */ - commit_transaction->t_outstanding_credits--; - - /* Bump b_count to prevent truncate from stumbling over - the shadowed buffer! @@@ This can go if we ever get - rid of the BJ_IO/BJ_Shadow pairing of buffers. */ - atomic_inc(&jh2bh(jh)->b_count); - - /* Make a temporary IO buffer with which to write it out - (this will requeue both the metadata buffer and the - temporary IO buffer). new_bh goes on BJ_IO*/ - - set_bit(BH_JWrite, &jh2bh(jh)->b_state); - /* - * akpm: jbd2_journal_write_metadata_buffer() sets - * new_bh->b_transaction to commit_transaction. - * We need to clean this up before we release new_bh - * (which is of type BJ_IO) - */ - JBUFFER_TRACE(jh, "ph3: write metadata"); - flags = jbd2_journal_write_metadata_buffer(commit_transaction, - jh, &new_jh, blocknr); - set_bit(BH_JWrite, &jh2bh(new_jh)->b_state); - wbuf[bufs++] = jh2bh(new_jh); - - /* Record the new block's tag in the current descriptor - buffer */ - - tag_flag = 0; - if (flags & 1) - tag_flag |= JBD2_FLAG_ESCAPE; - if (!first_tag) - tag_flag |= JBD2_FLAG_SAME_UUID; - - tag = (journal_block_tag_t *) tagp; - write_tag_block(tag_bytes, tag, jh2bh(jh)->b_blocknr); - tag->t_flags = cpu_to_be32(tag_flag); - tagp += tag_bytes; - space_left -= tag_bytes; - - if (first_tag) { - memcpy (tagp, journal->j_uuid, 16); - tagp += 16; - space_left -= 16; - first_tag = 0; - } - - /* If there's no more to do, or if the descriptor is full, - let the IO rip! */ - - if (bufs == journal->j_wbufsize || - commit_transaction->t_buffers == NULL || - space_left < tag_bytes + 16) { - - jbd_debug(4, "JBD: Submit %d IOs\n", bufs); - - /* Write an end-of-descriptor marker before - submitting the IOs. "tag" still points to - the last tag we set up. */ - - tag->t_flags |= cpu_to_be32(JBD2_FLAG_LAST_TAG); - -start_journal_io: - for (i = 0; i < bufs; i++) { - struct buffer_head *bh = wbuf[i]; - lock_buffer(bh); - clear_buffer_dirty(bh); - set_buffer_uptodate(bh); - bh->b_end_io = journal_end_buffer_io_sync; - submit_bh(WRITE, bh); - } - cond_resched(); - - /* Force a new descriptor to be generated next - time round the loop. */ - descriptor = NULL; - bufs = 0; - } - } - - /* Lo and behold: we have just managed to send a transaction to - the log. Before we can commit it, wait for the IO so far to - complete. Control buffers being written are on the - transaction's t_log_list queue, and metadata buffers are on - the t_iobuf_list queue. - - Wait for the buffers in reverse order. That way we are - less likely to be woken up until all IOs have completed, and - so we incur less scheduling load. - */ - - jbd_debug(3, "JBD: commit phase 4\n"); - - /* - * akpm: these are BJ_IO, and j_list_lock is not needed. - * See __journal_try_to_free_buffer. - */ -wait_for_iobuf: - while (commit_transaction->t_iobuf_list != NULL) { - struct buffer_head *bh; - - jh = commit_transaction->t_iobuf_list->b_tprev; - bh = jh2bh(jh); - if (buffer_locked(bh)) { - wait_on_buffer(bh); - goto wait_for_iobuf; - } - if (cond_resched()) - goto wait_for_iobuf; - - if (unlikely(!buffer_uptodate(bh))) - err = -EIO; - - clear_buffer_jwrite(bh); - - JBUFFER_TRACE(jh, "ph4: unfile after journal write"); - jbd2_journal_unfile_buffer(journal, jh); - - /* - * ->t_iobuf_list should contain only dummy buffer_heads - * which were created by jbd2_journal_write_metadata_buffer(). - */ - BUFFER_TRACE(bh, "dumping temporary bh"); - jbd2_journal_put_journal_head(jh); - __brelse(bh); - J_ASSERT_BH(bh, atomic_read(&bh->b_count) == 0); - free_buffer_head(bh); - - /* We also have to unlock and free the corresponding - shadowed buffer */ - jh = commit_transaction->t_shadow_list->b_tprev; - bh = jh2bh(jh); - clear_bit(BH_JWrite, &bh->b_state); - J_ASSERT_BH(bh, buffer_jbddirty(bh)); - - /* The metadata is now released for reuse, but we need - to remember it against this transaction so that when - we finally commit, we can do any checkpointing - required. */ - JBUFFER_TRACE(jh, "file as BJ_Forget"); - jbd2_journal_file_buffer(jh, commit_transaction, BJ_Forget); - /* Wake up any transactions which were waiting for this - IO to complete */ - wake_up_bit(&bh->b_state, BH_Unshadow); - JBUFFER_TRACE(jh, "brelse shadowed buffer"); - __brelse(bh); - } - - J_ASSERT (commit_transaction->t_shadow_list == NULL); - - jbd_debug(3, "JBD: commit phase 5\n"); - - /* Here we wait for the revoke record and descriptor record buffers */ - wait_for_ctlbuf: - while (commit_transaction->t_log_list != NULL) { - struct buffer_head *bh; - - jh = commit_transaction->t_log_list->b_tprev; - bh = jh2bh(jh); - if (buffer_locked(bh)) { - wait_on_buffer(bh); - goto wait_for_ctlbuf; - } - if (cond_resched()) - goto wait_for_ctlbuf; - - if (unlikely(!buffer_uptodate(bh))) - err = -EIO; - - BUFFER_TRACE(bh, "ph5: control buffer writeout done: unfile"); - clear_buffer_jwrite(bh); - jbd2_journal_unfile_buffer(journal, jh); - jbd2_journal_put_journal_head(jh); - __brelse(bh); /* One for getblk */ - /* AKPM: bforget here */ - } - - jbd_debug(3, "JBD: commit phase 6\n"); - - if (journal_write_commit_record(journal, commit_transaction)) - err = -EIO; - - if (err) - __jbd2_journal_abort_hard(journal); - - /* End of a transaction! Finally, we can do checkpoint - processing: any buffers committed as a result of this - transaction can be removed from any checkpoint list it was on - before. */ - - jbd_debug(3, "JBD: commit phase 7\n"); - - J_ASSERT(commit_transaction->t_sync_datalist == NULL); - J_ASSERT(commit_transaction->t_buffers == NULL); - J_ASSERT(commit_transaction->t_checkpoint_list == NULL); - J_ASSERT(commit_transaction->t_iobuf_list == NULL); - J_ASSERT(commit_transaction->t_shadow_list == NULL); - J_ASSERT(commit_transaction->t_log_list == NULL); - -restart_loop: - /* - * As there are other places (journal_unmap_buffer()) adding buffers - * to this list we have to be careful and hold the j_list_lock. - */ - spin_lock(&journal->j_list_lock); - while (commit_transaction->t_forget) { - transaction_t *cp_transaction; - struct buffer_head *bh; - - jh = commit_transaction->t_forget; - spin_unlock(&journal->j_list_lock); - bh = jh2bh(jh); - jbd_lock_bh_state(bh); - J_ASSERT_JH(jh, jh->b_transaction == commit_transaction || - jh->b_transaction == journal->j_running_transaction); - - /* - * If there is undo-protected committed data against - * this buffer, then we can remove it now. If it is a - * buffer needing such protection, the old frozen_data - * field now points to a committed version of the - * buffer, so rotate that field to the new committed - * data. - * - * Otherwise, we can just throw away the frozen data now. - */ - if (jh->b_committed_data) { - jbd2_slab_free(jh->b_committed_data, bh->b_size); - jh->b_committed_data = NULL; - if (jh->b_frozen_data) { - jh->b_committed_data = jh->b_frozen_data; - jh->b_frozen_data = NULL; - } - } else if (jh->b_frozen_data) { - jbd2_slab_free(jh->b_frozen_data, bh->b_size); - jh->b_frozen_data = NULL; - } - - spin_lock(&journal->j_list_lock); - cp_transaction = jh->b_cp_transaction; - if (cp_transaction) { - JBUFFER_TRACE(jh, "remove from old cp transaction"); - __jbd2_journal_remove_checkpoint(jh); - } - - /* Only re-checkpoint the buffer_head if it is marked - * dirty. If the buffer was added to the BJ_Forget list - * by jbd2_journal_forget, it may no longer be dirty and - * there's no point in keeping a checkpoint record for - * it. */ - - /* A buffer which has been freed while still being - * journaled by a previous transaction may end up still - * being dirty here, but we want to avoid writing back - * that buffer in the future now that the last use has - * been committed. That's not only a performance gain, - * it also stops aliasing problems if the buffer is left - * behind for writeback and gets reallocated for another - * use in a different page. */ - if (buffer_freed(bh)) { - clear_buffer_freed(bh); - clear_buffer_jbddirty(bh); - } - - if (buffer_jbddirty(bh)) { - JBUFFER_TRACE(jh, "add to new checkpointing trans"); - __jbd2_journal_insert_checkpoint(jh, commit_transaction); - JBUFFER_TRACE(jh, "refile for checkpoint writeback"); - __jbd2_journal_refile_buffer(jh); - jbd_unlock_bh_state(bh); - } else { - J_ASSERT_BH(bh, !buffer_dirty(bh)); - /* The buffer on BJ_Forget list and not jbddirty means - * it has been freed by this transaction and hence it - * could not have been reallocated until this - * transaction has committed. *BUT* it could be - * reallocated once we have written all the data to - * disk and before we process the buffer on BJ_Forget - * list. */ - JBUFFER_TRACE(jh, "refile or unfile freed buffer"); - __jbd2_journal_refile_buffer(jh); - if (!jh->b_transaction) { - jbd_unlock_bh_state(bh); - /* needs a brelse */ - jbd2_journal_remove_journal_head(bh); - release_buffer_page(bh); - } else - jbd_unlock_bh_state(bh); - } - cond_resched_lock(&journal->j_list_lock); - } - spin_unlock(&journal->j_list_lock); - /* - * This is a bit sleazy. We borrow j_list_lock to protect - * journal->j_committing_transaction in __jbd2_journal_remove_checkpoint. - * Really, __jbd2_journal_remove_checkpoint should be using j_state_lock but - * it's a bit hassle to hold that across __jbd2_journal_remove_checkpoint - */ - spin_lock(&journal->j_state_lock); - spin_lock(&journal->j_list_lock); - /* - * Now recheck if some buffers did not get attached to the transaction - * while the lock was dropped... - */ - if (commit_transaction->t_forget) { - spin_unlock(&journal->j_list_lock); - spin_unlock(&journal->j_state_lock); - goto restart_loop; - } - - /* Done with this transaction! */ - - jbd_debug(3, "JBD: commit phase 8\n"); - - J_ASSERT(commit_transaction->t_state == T_COMMIT); - - commit_transaction->t_state = T_FINISHED; - J_ASSERT(commit_transaction == journal->j_committing_transaction); - journal->j_commit_sequence = commit_transaction->t_tid; - journal->j_committing_transaction = NULL; - spin_unlock(&journal->j_state_lock); - - if (commit_transaction->t_checkpoint_list == NULL) { - __jbd2_journal_drop_transaction(journal, commit_transaction); - } else { - if (journal->j_checkpoint_transactions == NULL) { - journal->j_checkpoint_transactions = commit_transaction; - commit_transaction->t_cpnext = commit_transaction; - commit_transaction->t_cpprev = commit_transaction; - } else { - commit_transaction->t_cpnext = - journal->j_checkpoint_transactions; - commit_transaction->t_cpprev = - commit_transaction->t_cpnext->t_cpprev; - commit_transaction->t_cpnext->t_cpprev = - commit_transaction; - commit_transaction->t_cpprev->t_cpnext = - commit_transaction; - } - } - spin_unlock(&journal->j_list_lock); - - jbd_debug(1, "JBD: commit %d complete, head %d\n", - journal->j_commit_sequence, journal->j_tail_sequence); - - wake_up(&journal->j_wait_done_commit); -} diff --git a/trunk/fs/jbd2/journal.c b/trunk/fs/jbd2/journal.c deleted file mode 100644 index c60f378b0f76..000000000000 --- a/trunk/fs/jbd2/journal.c +++ /dev/null @@ -1,2084 +0,0 @@ -/* - * linux/fs/jbd2/journal.c - * - * Written by Stephen C. Tweedie , 1998 - * - * Copyright 1998 Red Hat corp --- All Rights Reserved - * - * This file is part of the Linux kernel and is made available under - * the terms of the GNU General Public License, version 2, or at your - * option, any later version, incorporated herein by reference. - * - * Generic filesystem journal-writing code; part of the ext2fs - * journaling system. - * - * This file manages journals: areas of disk reserved for logging - * transactional updates. This includes the kernel journaling thread - * which is responsible for scheduling updates to the log. - * - * We do not actually manage the physical storage of the journal in this - * file: that is left to a per-journal policy function, which allows us - * to store the journal within a filesystem-specified area for ext2 - * journaling (ext2 can use a reserved inode for storing the log). - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -EXPORT_SYMBOL(jbd2_journal_start); -EXPORT_SYMBOL(jbd2_journal_restart); -EXPORT_SYMBOL(jbd2_journal_extend); -EXPORT_SYMBOL(jbd2_journal_stop); -EXPORT_SYMBOL(jbd2_journal_lock_updates); -EXPORT_SYMBOL(jbd2_journal_unlock_updates); -EXPORT_SYMBOL(jbd2_journal_get_write_access); -EXPORT_SYMBOL(jbd2_journal_get_create_access); -EXPORT_SYMBOL(jbd2_journal_get_undo_access); -EXPORT_SYMBOL(jbd2_journal_dirty_data); -EXPORT_SYMBOL(jbd2_journal_dirty_metadata); -EXPORT_SYMBOL(jbd2_journal_release_buffer); -EXPORT_SYMBOL(jbd2_journal_forget); -#if 0 -EXPORT_SYMBOL(journal_sync_buffer); -#endif -EXPORT_SYMBOL(jbd2_journal_flush); -EXPORT_SYMBOL(jbd2_journal_revoke); - -EXPORT_SYMBOL(jbd2_journal_init_dev); -EXPORT_SYMBOL(jbd2_journal_init_inode); -EXPORT_SYMBOL(jbd2_journal_update_format); -EXPORT_SYMBOL(jbd2_journal_check_used_features); -EXPORT_SYMBOL(jbd2_journal_check_available_features); -EXPORT_SYMBOL(jbd2_journal_set_features); -EXPORT_SYMBOL(jbd2_journal_create); -EXPORT_SYMBOL(jbd2_journal_load); -EXPORT_SYMBOL(jbd2_journal_destroy); -EXPORT_SYMBOL(jbd2_journal_update_superblock); -EXPORT_SYMBOL(jbd2_journal_abort); -EXPORT_SYMBOL(jbd2_journal_errno); -EXPORT_SYMBOL(jbd2_journal_ack_err); -EXPORT_SYMBOL(jbd2_journal_clear_err); -EXPORT_SYMBOL(jbd2_log_wait_commit); -EXPORT_SYMBOL(jbd2_journal_start_commit); -EXPORT_SYMBOL(jbd2_journal_force_commit_nested); -EXPORT_SYMBOL(jbd2_journal_wipe); -EXPORT_SYMBOL(jbd2_journal_blocks_per_page); -EXPORT_SYMBOL(jbd2_journal_invalidatepage); -EXPORT_SYMBOL(jbd2_journal_try_to_free_buffers); -EXPORT_SYMBOL(jbd2_journal_force_commit); - -static int journal_convert_superblock_v1(journal_t *, journal_superblock_t *); -static void __journal_abort_soft (journal_t *journal, int errno); -static int jbd2_journal_create_jbd_slab(size_t slab_size); - -/* - * Helper function used to manage commit timeouts - */ - -static void commit_timeout(unsigned long __data) -{ - struct task_struct * p = (struct task_struct *) __data; - - wake_up_process(p); -} - -/* - * kjournald2: The main thread function used to manage a logging device - * journal. - * - * This kernel thread is responsible for two things: - * - * 1) COMMIT: Every so often we need to commit the current state of the - * filesystem to disk. The journal thread is responsible for writing - * all of the metadata buffers to disk. - * - * 2) CHECKPOINT: We cannot reuse a used section of the log file until all - * of the data in that part of the log has been rewritten elsewhere on - * the disk. Flushing these old buffers to reclaim space in the log is - * known as checkpointing, and this thread is responsible for that job. - */ - -static int kjournald2(void *arg) -{ - journal_t *journal = arg; - transaction_t *transaction; - - /* - * Set up an interval timer which can be used to trigger a commit wakeup - * after the commit interval expires - */ - setup_timer(&journal->j_commit_timer, commit_timeout, - (unsigned long)current); - - /* Record that the journal thread is running */ - journal->j_task = current; - wake_up(&journal->j_wait_done_commit); - - printk(KERN_INFO "kjournald2 starting. Commit interval %ld seconds\n", - journal->j_commit_interval / HZ); - - /* - * And now, wait forever for commit wakeup events. - */ - spin_lock(&journal->j_state_lock); - -loop: - if (journal->j_flags & JBD2_UNMOUNT) - goto end_loop; - - jbd_debug(1, "commit_sequence=%d, commit_request=%d\n", - journal->j_commit_sequence, journal->j_commit_request); - - if (journal->j_commit_sequence != journal->j_commit_request) { - jbd_debug(1, "OK, requests differ\n"); - spin_unlock(&journal->j_state_lock); - del_timer_sync(&journal->j_commit_timer); - jbd2_journal_commit_transaction(journal); - spin_lock(&journal->j_state_lock); - goto loop; - } - - wake_up(&journal->j_wait_done_commit); - if (freezing(current)) { - /* - * The simpler the better. Flushing journal isn't a - * good idea, because that depends on threads that may - * be already stopped. - */ - jbd_debug(1, "Now suspending kjournald2\n"); - spin_unlock(&journal->j_state_lock); - refrigerator(); - spin_lock(&journal->j_state_lock); - } else { - /* - * We assume on resume that commits are already there, - * so we don't sleep - */ - DEFINE_WAIT(wait); - int should_sleep = 1; - - prepare_to_wait(&journal->j_wait_commit, &wait, - TASK_INTERRUPTIBLE); - if (journal->j_commit_sequence != journal->j_commit_request) - should_sleep = 0; - transaction = journal->j_running_transaction; - if (transaction && time_after_eq(jiffies, - transaction->t_expires)) - should_sleep = 0; - if (journal->j_flags & JBD2_UNMOUNT) - should_sleep = 0; - if (should_sleep) { - spin_unlock(&journal->j_state_lock); - schedule(); - spin_lock(&journal->j_state_lock); - } - finish_wait(&journal->j_wait_commit, &wait); - } - - jbd_debug(1, "kjournald2 wakes\n"); - - /* - * Were we woken up by a commit wakeup event? - */ - transaction = journal->j_running_transaction; - if (transaction && time_after_eq(jiffies, transaction->t_expires)) { - journal->j_commit_request = transaction->t_tid; - jbd_debug(1, "woke because of timeout\n"); - } - goto loop; - -end_loop: - spin_unlock(&journal->j_state_lock); - del_timer_sync(&journal->j_commit_timer); - journal->j_task = NULL; - wake_up(&journal->j_wait_done_commit); - jbd_debug(1, "Journal thread exiting.\n"); - return 0; -} - -static void jbd2_journal_start_thread(journal_t *journal) -{ - kthread_run(kjournald2, journal, "kjournald2"); - wait_event(journal->j_wait_done_commit, journal->j_task != 0); -} - -static void journal_kill_thread(journal_t *journal) -{ - spin_lock(&journal->j_state_lock); - journal->j_flags |= JBD2_UNMOUNT; - - while (journal->j_task) { - wake_up(&journal->j_wait_commit); - spin_unlock(&journal->j_state_lock); - wait_event(journal->j_wait_done_commit, journal->j_task == 0); - spin_lock(&journal->j_state_lock); - } - spin_unlock(&journal->j_state_lock); -} - -/* - * jbd2_journal_write_metadata_buffer: write a metadata buffer to the journal. - * - * Writes a metadata buffer to a given disk block. The actual IO is not - * performed but a new buffer_head is constructed which labels the data - * to be written with the correct destination disk block. - * - * Any magic-number escaping which needs to be done will cause a - * copy-out here. If the buffer happens to start with the - * JBD2_MAGIC_NUMBER, then we can't write it to the log directly: the - * magic number is only written to the log for descripter blocks. In - * this case, we copy the data and replace the first word with 0, and we - * return a result code which indicates that this buffer needs to be - * marked as an escaped buffer in the corresponding log descriptor - * block. The missing word can then be restored when the block is read - * during recovery. - * - * If the source buffer has already been modified by a new transaction - * since we took the last commit snapshot, we use the frozen copy of - * that data for IO. If we end up using the existing buffer_head's data - * for the write, then we *have* to lock the buffer to prevent anyone - * else from using and possibly modifying it while the IO is in - * progress. - * - * The function returns a pointer to the buffer_heads to be used for IO. - * - * We assume that the journal has already been locked in this function. - * - * Return value: - * <0: Error - * >=0: Finished OK - * - * On success: - * Bit 0 set == escape performed on the data - * Bit 1 set == buffer copy-out performed (kfree the data after IO) - */ - -int jbd2_journal_write_metadata_buffer(transaction_t *transaction, - struct journal_head *jh_in, - struct journal_head **jh_out, - unsigned long long blocknr) -{ - int need_copy_out = 0; - int done_copy_out = 0; - int do_escape = 0; - char *mapped_data; - struct buffer_head *new_bh; - struct journal_head *new_jh; - struct page *new_page; - unsigned int new_offset; - struct buffer_head *bh_in = jh2bh(jh_in); - - /* - * The buffer really shouldn't be locked: only the current committing - * transaction is allowed to write it, so nobody else is allowed - * to do any IO. - * - * akpm: except if we're journalling data, and write() output is - * also part of a shared mapping, and another thread has - * decided to launch a writepage() against this buffer. - */ - J_ASSERT_BH(bh_in, buffer_jbddirty(bh_in)); - - new_bh = alloc_buffer_head(GFP_NOFS|__GFP_NOFAIL); - - /* - * If a new transaction has already done a buffer copy-out, then - * we use that version of the data for the commit. - */ - jbd_lock_bh_state(bh_in); -repeat: - if (jh_in->b_frozen_data) { - done_copy_out = 1; - new_page = virt_to_page(jh_in->b_frozen_data); - new_offset = offset_in_page(jh_in->b_frozen_data); - } else { - new_page = jh2bh(jh_in)->b_page; - new_offset = offset_in_page(jh2bh(jh_in)->b_data); - } - - mapped_data = kmap_atomic(new_page, KM_USER0); - /* - * Check for escaping - */ - if (*((__be32 *)(mapped_data + new_offset)) == - cpu_to_be32(JBD2_MAGIC_NUMBER)) { - need_copy_out = 1; - do_escape = 1; - } - kunmap_atomic(mapped_data, KM_USER0); - - /* - * Do we need to do a data copy? - */ - if (need_copy_out && !done_copy_out) { - char *tmp; - - jbd_unlock_bh_state(bh_in); - tmp = jbd2_slab_alloc(bh_in->b_size, GFP_NOFS); - jbd_lock_bh_state(bh_in); - if (jh_in->b_frozen_data) { - jbd2_slab_free(tmp, bh_in->b_size); - goto repeat; - } - - jh_in->b_frozen_data = tmp; - mapped_data = kmap_atomic(new_page, KM_USER0); - memcpy(tmp, mapped_data + new_offset, jh2bh(jh_in)->b_size); - kunmap_atomic(mapped_data, KM_USER0); - - new_page = virt_to_page(tmp); - new_offset = offset_in_page(tmp); - done_copy_out = 1; - } - - /* - * Did we need to do an escaping? Now we've done all the - * copying, we can finally do so. - */ - if (do_escape) { - mapped_data = kmap_atomic(new_page, KM_USER0); - *((unsigned int *)(mapped_data + new_offset)) = 0; - kunmap_atomic(mapped_data, KM_USER0); - } - - /* keep subsequent assertions sane */ - new_bh->b_state = 0; - init_buffer(new_bh, NULL, NULL); - atomic_set(&new_bh->b_count, 1); - jbd_unlock_bh_state(bh_in); - - new_jh = jbd2_journal_add_journal_head(new_bh); /* This sleeps */ - - set_bh_page(new_bh, new_page, new_offset); - new_jh->b_transaction = NULL; - new_bh->b_size = jh2bh(jh_in)->b_size; - new_bh->b_bdev = transaction->t_journal->j_dev; - new_bh->b_blocknr = blocknr; - set_buffer_mapped(new_bh); - set_buffer_dirty(new_bh); - - *jh_out = new_jh; - - /* - * The to-be-written buffer needs to get moved to the io queue, - * and the original buffer whose contents we are shadowing or - * copying is moved to the transaction's shadow queue. - */ - JBUFFER_TRACE(jh_in, "file as BJ_Shadow"); - jbd2_journal_file_buffer(jh_in, transaction, BJ_Shadow); - JBUFFER_TRACE(new_jh, "file as BJ_IO"); - jbd2_journal_file_buffer(new_jh, transaction, BJ_IO); - - return do_escape | (done_copy_out << 1); -} - -/* - * Allocation code for the journal file. Manage the space left in the - * journal, so that we can begin checkpointing when appropriate. - */ - -/* - * __jbd2_log_space_left: Return the number of free blocks left in the journal. - * - * Called with the journal already locked. - * - * Called under j_state_lock - */ - -int __jbd2_log_space_left(journal_t *journal) -{ - int left = journal->j_free; - - assert_spin_locked(&journal->j_state_lock); - - /* - * Be pessimistic here about the number of those free blocks which - * might be required for log descriptor control blocks. - */ - -#define MIN_LOG_RESERVED_BLOCKS 32 /* Allow for rounding errors */ - - left -= MIN_LOG_RESERVED_BLOCKS; - - if (left <= 0) - return 0; - left -= (left >> 3); - return left; -} - -/* - * Called under j_state_lock. Returns true if a transaction was started. - */ -int __jbd2_log_start_commit(journal_t *journal, tid_t target) -{ - /* - * Are we already doing a recent enough commit? - */ - if (!tid_geq(journal->j_commit_request, target)) { - /* - * We want a new commit: OK, mark the request and wakup the - * commit thread. We do _not_ do the commit ourselves. - */ - - journal->j_commit_request = target; - jbd_debug(1, "JBD: requesting commit %d/%d\n", - journal->j_commit_request, - journal->j_commit_sequence); - wake_up(&journal->j_wait_commit); - return 1; - } - return 0; -} - -int jbd2_log_start_commit(journal_t *journal, tid_t tid) -{ - int ret; - - spin_lock(&journal->j_state_lock); - ret = __jbd2_log_start_commit(journal, tid); - spin_unlock(&journal->j_state_lock); - return ret; -} - -/* - * Force and wait upon a commit if the calling process is not within - * transaction. This is used for forcing out undo-protected data which contains - * bitmaps, when the fs is running out of space. - * - * We can only force the running transaction if we don't have an active handle; - * otherwise, we will deadlock. - * - * Returns true if a transaction was started. - */ -int jbd2_journal_force_commit_nested(journal_t *journal) -{ - transaction_t *transaction = NULL; - tid_t tid; - - spin_lock(&journal->j_state_lock); - if (journal->j_running_transaction && !current->journal_info) { - transaction = journal->j_running_transaction; - __jbd2_log_start_commit(journal, transaction->t_tid); - } else if (journal->j_committing_transaction) - transaction = journal->j_committing_transaction; - - if (!transaction) { - spin_unlock(&journal->j_state_lock); - return 0; /* Nothing to retry */ - } - - tid = transaction->t_tid; - spin_unlock(&journal->j_state_lock); - jbd2_log_wait_commit(journal, tid); - return 1; -} - -/* - * Start a commit of the current running transaction (if any). Returns true - * if a transaction was started, and fills its tid in at *ptid - */ -int jbd2_journal_start_commit(journal_t *journal, tid_t *ptid) -{ - int ret = 0; - - spin_lock(&journal->j_state_lock); - if (journal->j_running_transaction) { - tid_t tid = journal->j_running_transaction->t_tid; - - ret = __jbd2_log_start_commit(journal, tid); - if (ret && ptid) - *ptid = tid; - } else if (journal->j_committing_transaction && ptid) { - /* - * If ext3_write_super() recently started a commit, then we - * have to wait for completion of that transaction - */ - *ptid = journal->j_committing_transaction->t_tid; - ret = 1; - } - spin_unlock(&journal->j_state_lock); - return ret; -} - -/* - * Wait for a specified commit to complete. - * The caller may not hold the journal lock. - */ -int jbd2_log_wait_commit(journal_t *journal, tid_t tid) -{ - int err = 0; - -#ifdef CONFIG_JBD_DEBUG - spin_lock(&journal->j_state_lock); - if (!tid_geq(journal->j_commit_request, tid)) { - printk(KERN_EMERG - "%s: error: j_commit_request=%d, tid=%d\n", - __FUNCTION__, journal->j_commit_request, tid); - } - spin_unlock(&journal->j_state_lock); -#endif - spin_lock(&journal->j_state_lock); - while (tid_gt(tid, journal->j_commit_sequence)) { - jbd_debug(1, "JBD: want %d, j_commit_sequence=%d\n", - tid, journal->j_commit_sequence); - wake_up(&journal->j_wait_commit); - spin_unlock(&journal->j_state_lock); - wait_event(journal->j_wait_done_commit, - !tid_gt(tid, journal->j_commit_sequence)); - spin_lock(&journal->j_state_lock); - } - spin_unlock(&journal->j_state_lock); - - if (unlikely(is_journal_aborted(journal))) { - printk(KERN_EMERG "journal commit I/O error\n"); - err = -EIO; - } - return err; -} - -/* - * Log buffer allocation routines: - */ - -int jbd2_journal_next_log_block(journal_t *journal, unsigned long long *retp) -{ - unsigned long blocknr; - - spin_lock(&journal->j_state_lock); - J_ASSERT(journal->j_free > 1); - - blocknr = journal->j_head; - journal->j_head++; - journal->j_free--; - if (journal->j_head == journal->j_last) - journal->j_head = journal->j_first; - spin_unlock(&journal->j_state_lock); - return jbd2_journal_bmap(journal, blocknr, retp); -} - -/* - * Conversion of logical to physical block numbers for the journal - * - * On external journals the journal blocks are identity-mapped, so - * this is a no-op. If needed, we can use j_blk_offset - everything is - * ready. - */ -int jbd2_journal_bmap(journal_t *journal, unsigned long blocknr, - unsigned long long *retp) -{ - int err = 0; - unsigned long long ret; - - if (journal->j_inode) { - ret = bmap(journal->j_inode, blocknr); - if (ret) - *retp = ret; - else { - char b[BDEVNAME_SIZE]; - - printk(KERN_ALERT "%s: journal block not found " - "at offset %lu on %s\n", - __FUNCTION__, - blocknr, - bdevname(journal->j_dev, b)); - err = -EIO; - __journal_abort_soft(journal, err); - } - } else { - *retp = blocknr; /* +journal->j_blk_offset */ - } - return err; -} - -/* - * We play buffer_head aliasing tricks to write data/metadata blocks to - * the journal without copying their contents, but for journal - * descriptor blocks we do need to generate bona fide buffers. - * - * After the caller of jbd2_journal_get_descriptor_buffer() has finished modifying - * the buffer's contents they really should run flush_dcache_page(bh->b_page). - * But we don't bother doing that, so there will be coherency problems with - * mmaps of blockdevs which hold live JBD-controlled filesystems. - */ -struct journal_head *jbd2_journal_get_descriptor_buffer(journal_t *journal) -{ - struct buffer_head *bh; - unsigned long long blocknr; - int err; - - err = jbd2_journal_next_log_block(journal, &blocknr); - - if (err) - return NULL; - - bh = __getblk(journal->j_dev, blocknr, journal->j_blocksize); - lock_buffer(bh); - memset(bh->b_data, 0, journal->j_blocksize); - set_buffer_uptodate(bh); - unlock_buffer(bh); - BUFFER_TRACE(bh, "return this buffer"); - return jbd2_journal_add_journal_head(bh); -} - -/* - * Management for journal control blocks: functions to create and - * destroy journal_t structures, and to initialise and read existing - * journal blocks from disk. */ - -/* First: create and setup a journal_t object in memory. We initialise - * very few fields yet: that has to wait until we have created the - * journal structures from from scratch, or loaded them from disk. */ - -static journal_t * journal_init_common (void) -{ - journal_t *journal; - int err; - - journal = jbd_kmalloc(sizeof(*journal), GFP_KERNEL); - if (!journal) - goto fail; - memset(journal, 0, sizeof(*journal)); - - init_waitqueue_head(&journal->j_wait_transaction_locked); - init_waitqueue_head(&journal->j_wait_logspace); - init_waitqueue_head(&journal->j_wait_done_commit); - init_waitqueue_head(&journal->j_wait_checkpoint); - init_waitqueue_head(&journal->j_wait_commit); - init_waitqueue_head(&journal->j_wait_updates); - mutex_init(&journal->j_barrier); - mutex_init(&journal->j_checkpoint_mutex); - spin_lock_init(&journal->j_revoke_lock); - spin_lock_init(&journal->j_list_lock); - spin_lock_init(&journal->j_state_lock); - - journal->j_commit_interval = (HZ * JBD_DEFAULT_MAX_COMMIT_AGE); - - /* The journal is marked for error until we succeed with recovery! */ - journal->j_flags = JBD2_ABORT; - - /* Set up a default-sized revoke table for the new mount. */ - err = jbd2_journal_init_revoke(journal, JOURNAL_REVOKE_DEFAULT_HASH); - if (err) { - kfree(journal); - goto fail; - } - return journal; -fail: - return NULL; -} - -/* jbd2_journal_init_dev and jbd2_journal_init_inode: - * - * Create a journal structure assigned some fixed set of disk blocks to - * the journal. We don't actually touch those disk blocks yet, but we - * need to set up all of the mapping information to tell the journaling - * system where the journal blocks are. - * - */ - -/** - * journal_t * jbd2_journal_init_dev() - creates an initialises a journal structure - * @bdev: Block device on which to create the journal - * @fs_dev: Device which hold journalled filesystem for this journal. - * @start: Block nr Start of journal. - * @len: Length of the journal in blocks. - * @blocksize: blocksize of journalling device - * @returns: a newly created journal_t * - * - * jbd2_journal_init_dev creates a journal which maps a fixed contiguous - * range of blocks on an arbitrary block device. - * - */ -journal_t * jbd2_journal_init_dev(struct block_device *bdev, - struct block_device *fs_dev, - unsigned long long start, int len, int blocksize) -{ - journal_t *journal = journal_init_common(); - struct buffer_head *bh; - int n; - - if (!journal) - return NULL; - - /* journal descriptor can store up to n blocks -bzzz */ - journal->j_blocksize = blocksize; - n = journal->j_blocksize / sizeof(journal_block_tag_t); - journal->j_wbufsize = n; - journal->j_wbuf = kmalloc(n * sizeof(struct buffer_head*), GFP_KERNEL); - if (!journal->j_wbuf) { - printk(KERN_ERR "%s: Cant allocate bhs for commit thread\n", - __FUNCTION__); - kfree(journal); - journal = NULL; - goto out; - } - journal->j_dev = bdev; - journal->j_fs_dev = fs_dev; - journal->j_blk_offset = start; - journal->j_maxlen = len; - - bh = __getblk(journal->j_dev, start, journal->j_blocksize); - J_ASSERT(bh != NULL); - journal->j_sb_buffer = bh; - journal->j_superblock = (journal_superblock_t *)bh->b_data; -out: - return journal; -} - -/** - * journal_t * jbd2_journal_init_inode () - creates a journal which maps to a inode. - * @inode: An inode to create the journal in - * - * jbd2_journal_init_inode creates a journal which maps an on-disk inode as - * the journal. The inode must exist already, must support bmap() and - * must have all data blocks preallocated. - */ -journal_t * jbd2_journal_init_inode (struct inode *inode) -{ - struct buffer_head *bh; - journal_t *journal = journal_init_common(); - int err; - int n; - unsigned long long blocknr; - - if (!journal) - return NULL; - - journal->j_dev = journal->j_fs_dev = inode->i_sb->s_bdev; - journal->j_inode = inode; - jbd_debug(1, - "journal %p: inode %s/%ld, size %Ld, bits %d, blksize %ld\n", - journal, inode->i_sb->s_id, inode->i_ino, - (long long) inode->i_size, - inode->i_sb->s_blocksize_bits, inode->i_sb->s_blocksize); - - journal->j_maxlen = inode->i_size >> inode->i_sb->s_blocksize_bits; - journal->j_blocksize = inode->i_sb->s_blocksize; - - /* journal descriptor can store up to n blocks -bzzz */ - n = journal->j_blocksize / sizeof(journal_block_tag_t); - journal->j_wbufsize = n; - journal->j_wbuf = kmalloc(n * sizeof(struct buffer_head*), GFP_KERNEL); - if (!journal->j_wbuf) { - printk(KERN_ERR "%s: Cant allocate bhs for commit thread\n", - __FUNCTION__); - kfree(journal); - return NULL; - } - - err = jbd2_journal_bmap(journal, 0, &blocknr); - /* If that failed, give up */ - if (err) { - printk(KERN_ERR "%s: Cannnot locate journal superblock\n", - __FUNCTION__); - kfree(journal); - return NULL; - } - - bh = __getblk(journal->j_dev, blocknr, journal->j_blocksize); - J_ASSERT(bh != NULL); - journal->j_sb_buffer = bh; - journal->j_superblock = (journal_superblock_t *)bh->b_data; - - return journal; -} - -/* - * If the journal init or create aborts, we need to mark the journal - * superblock as being NULL to prevent the journal destroy from writing - * back a bogus superblock. - */ -static void journal_fail_superblock (journal_t *journal) -{ - struct buffer_head *bh = journal->j_sb_buffer; - brelse(bh); - journal->j_sb_buffer = NULL; -} - -/* - * Given a journal_t structure, initialise the various fields for - * startup of a new journaling session. We use this both when creating - * a journal, and after recovering an old journal to reset it for - * subsequent use. - */ - -static int journal_reset(journal_t *journal) -{ - journal_superblock_t *sb = journal->j_superblock; - unsigned long long first, last; - - first = be32_to_cpu(sb->s_first); - last = be32_to_cpu(sb->s_maxlen); - - journal->j_first = first; - journal->j_last = last; - - journal->j_head = first; - journal->j_tail = first; - journal->j_free = last - first; - - journal->j_tail_sequence = journal->j_transaction_sequence; - journal->j_commit_sequence = journal->j_transaction_sequence - 1; - journal->j_commit_request = journal->j_commit_sequence; - - journal->j_max_transaction_buffers = journal->j_maxlen / 4; - - /* Add the dynamic fields and write it to disk. */ - jbd2_journal_update_superblock(journal, 1); - jbd2_journal_start_thread(journal); - return 0; -} - -/** - * int jbd2_journal_create() - Initialise the new journal file - * @journal: Journal to create. This structure must have been initialised - * - * Given a journal_t structure which tells us which disk blocks we can - * use, create a new journal superblock and initialise all of the - * journal fields from scratch. - **/ -int jbd2_journal_create(journal_t *journal) -{ - unsigned long long blocknr; - struct buffer_head *bh; - journal_superblock_t *sb; - int i, err; - - if (journal->j_maxlen < JBD2_MIN_JOURNAL_BLOCKS) { - printk (KERN_ERR "Journal length (%d blocks) too short.\n", - journal->j_maxlen); - journal_fail_superblock(journal); - return -EINVAL; - } - - if (journal->j_inode == NULL) { - /* - * We don't know what block to start at! - */ - printk(KERN_EMERG - "%s: creation of journal on external device!\n", - __FUNCTION__); - BUG(); - } - - /* Zero out the entire journal on disk. We cannot afford to - have any blocks on disk beginning with JBD2_MAGIC_NUMBER. */ - jbd_debug(1, "JBD: Zeroing out journal blocks...\n"); - for (i = 0; i < journal->j_maxlen; i++) { - err = jbd2_journal_bmap(journal, i, &blocknr); - if (err) - return err; - bh = __getblk(journal->j_dev, blocknr, journal->j_blocksize); - lock_buffer(bh); - memset (bh->b_data, 0, journal->j_blocksize); - BUFFER_TRACE(bh, "marking dirty"); - mark_buffer_dirty(bh); - BUFFER_TRACE(bh, "marking uptodate"); - set_buffer_uptodate(bh); - unlock_buffer(bh); - __brelse(bh); - } - - sync_blockdev(journal->j_dev); - jbd_debug(1, "JBD: journal cleared.\n"); - - /* OK, fill in the initial static fields in the new superblock */ - sb = journal->j_superblock; - - sb->s_header.h_magic = cpu_to_be32(JBD2_MAGIC_NUMBER); - sb->s_header.h_blocktype = cpu_to_be32(JBD2_SUPERBLOCK_V2); - - sb->s_blocksize = cpu_to_be32(journal->j_blocksize); - sb->s_maxlen = cpu_to_be32(journal->j_maxlen); - sb->s_first = cpu_to_be32(1); - - journal->j_transaction_sequence = 1; - - journal->j_flags &= ~JBD2_ABORT; - journal->j_format_version = 2; - - return journal_reset(journal); -} - -/** - * void jbd2_journal_update_superblock() - Update journal sb on disk. - * @journal: The journal to update. - * @wait: Set to '0' if you don't want to wait for IO completion. - * - * Update a journal's dynamic superblock fields and write it to disk, - * optionally waiting for the IO to complete. - */ -void jbd2_journal_update_superblock(journal_t *journal, int wait) -{ - journal_superblock_t *sb = journal->j_superblock; - struct buffer_head *bh = journal->j_sb_buffer; - - /* - * As a special case, if the on-disk copy is already marked as needing - * no recovery (s_start == 0) and there are no outstanding transactions - * in the filesystem, then we can safely defer the superblock update - * until the next commit by setting JBD2_FLUSHED. This avoids - * attempting a write to a potential-readonly device. - */ - if (sb->s_start == 0 && journal->j_tail_sequence == - journal->j_transaction_sequence) { - jbd_debug(1,"JBD: Skipping superblock update on recovered sb " - "(start %ld, seq %d, errno %d)\n", - journal->j_tail, journal->j_tail_sequence, - journal->j_errno); - goto out; - } - - spin_lock(&journal->j_state_lock); - jbd_debug(1,"JBD: updating superblock (start %ld, seq %d, errno %d)\n", - journal->j_tail, journal->j_tail_sequence, journal->j_errno); - - sb->s_sequence = cpu_to_be32(journal->j_tail_sequence); - sb->s_start = cpu_to_be32(journal->j_tail); - sb->s_errno = cpu_to_be32(journal->j_errno); - spin_unlock(&journal->j_state_lock); - - BUFFER_TRACE(bh, "marking dirty"); - mark_buffer_dirty(bh); - if (wait) - sync_dirty_buffer(bh); - else - ll_rw_block(SWRITE, 1, &bh); - -out: - /* If we have just flushed the log (by marking s_start==0), then - * any future commit will have to be careful to update the - * superblock again to re-record the true start of the log. */ - - spin_lock(&journal->j_state_lock); - if (sb->s_start) - journal->j_flags &= ~JBD2_FLUSHED; - else - journal->j_flags |= JBD2_FLUSHED; - spin_unlock(&journal->j_state_lock); -} - -/* - * Read the superblock for a given journal, performing initial - * validation of the format. - */ - -static int journal_get_superblock(journal_t *journal) -{ - struct buffer_head *bh; - journal_superblock_t *sb; - int err = -EIO; - - bh = journal->j_sb_buffer; - - J_ASSERT(bh != NULL); - if (!buffer_uptodate(bh)) { - ll_rw_block(READ, 1, &bh); - wait_on_buffer(bh); - if (!buffer_uptodate(bh)) { - printk (KERN_ERR - "JBD: IO error reading journal superblock\n"); - goto out; - } - } - - sb = journal->j_superblock; - - err = -EINVAL; - - if (sb->s_header.h_magic != cpu_to_be32(JBD2_MAGIC_NUMBER) || - sb->s_blocksize != cpu_to_be32(journal->j_blocksize)) { - printk(KERN_WARNING "JBD: no valid journal superblock found\n"); - goto out; - } - - switch(be32_to_cpu(sb->s_header.h_blocktype)) { - case JBD2_SUPERBLOCK_V1: - journal->j_format_version = 1; - break; - case JBD2_SUPERBLOCK_V2: - journal->j_format_version = 2; - break; - default: - printk(KERN_WARNING "JBD: unrecognised superblock format ID\n"); - goto out; - } - - if (be32_to_cpu(sb->s_maxlen) < journal->j_maxlen) - journal->j_maxlen = be32_to_cpu(sb->s_maxlen); - else if (be32_to_cpu(sb->s_maxlen) > journal->j_maxlen) { - printk (KERN_WARNING "JBD: journal file too short\n"); - goto out; - } - - return 0; - -out: - journal_fail_superblock(journal); - return err; -} - -/* - * Load the on-disk journal superblock and read the key fields into the - * journal_t. - */ - -static int load_superblock(journal_t *journal) -{ - int err; - journal_superblock_t *sb; - - err = journal_get_superblock(journal); - if (err) - return err; - - sb = journal->j_superblock; - - journal->j_tail_sequence = be32_to_cpu(sb->s_sequence); - journal->j_tail = be32_to_cpu(sb->s_start); - journal->j_first = be32_to_cpu(sb->s_first); - journal->j_last = be32_to_cpu(sb->s_maxlen); - journal->j_errno = be32_to_cpu(sb->s_errno); - - return 0; -} - - -/** - * int jbd2_journal_load() - Read journal from disk. - * @journal: Journal to act on. - * - * Given a journal_t structure which tells us which disk blocks contain - * a journal, read the journal from disk to initialise the in-memory - * structures. - */ -int jbd2_journal_load(journal_t *journal) -{ - int err; - journal_superblock_t *sb; - - err = load_superblock(journal); - if (err) - return err; - - sb = journal->j_superblock; - /* If this is a V2 superblock, then we have to check the - * features flags on it. */ - - if (journal->j_format_version >= 2) { - if ((sb->s_feature_ro_compat & - ~cpu_to_be32(JBD2_KNOWN_ROCOMPAT_FEATURES)) || - (sb->s_feature_incompat & - ~cpu_to_be32(JBD2_KNOWN_INCOMPAT_FEATURES))) { - printk (KERN_WARNING - "JBD: Unrecognised features on journal\n"); - return -EINVAL; - } - } - - /* - * Create a slab for this blocksize - */ - err = jbd2_journal_create_jbd_slab(be32_to_cpu(sb->s_blocksize)); - if (err) - return err; - - /* Let the recovery code check whether it needs to recover any - * data from the journal. */ - if (jbd2_journal_recover(journal)) - goto recovery_error; - - /* OK, we've finished with the dynamic journal bits: - * reinitialise the dynamic contents of the superblock in memory - * and reset them on disk. */ - if (journal_reset(journal)) - goto recovery_error; - - journal->j_flags &= ~JBD2_ABORT; - journal->j_flags |= JBD2_LOADED; - return 0; - -recovery_error: - printk (KERN_WARNING "JBD: recovery failed\n"); - return -EIO; -} - -/** - * void jbd2_journal_destroy() - Release a journal_t structure. - * @journal: Journal to act on. - * - * Release a journal_t structure once it is no longer in use by the - * journaled object. - */ -void jbd2_journal_destroy(journal_t *journal) -{ - /* Wait for the commit thread to wake up and die. */ - journal_kill_thread(journal); - - /* Force a final log commit */ - if (journal->j_running_transaction) - jbd2_journal_commit_transaction(journal); - - /* Force any old transactions to disk */ - - /* Totally anal locking here... */ - spin_lock(&journal->j_list_lock); - while (journal->j_checkpoint_transactions != NULL) { - spin_unlock(&journal->j_list_lock); - jbd2_log_do_checkpoint(journal); - spin_lock(&journal->j_list_lock); - } - - J_ASSERT(journal->j_running_transaction == NULL); - J_ASSERT(journal->j_committing_transaction == NULL); - J_ASSERT(journal->j_checkpoint_transactions == NULL); - spin_unlock(&journal->j_list_lock); - - /* We can now mark the journal as empty. */ - journal->j_tail = 0; - journal->j_tail_sequence = ++journal->j_transaction_sequence; - if (journal->j_sb_buffer) { - jbd2_journal_update_superblock(journal, 1); - brelse(journal->j_sb_buffer); - } - - if (journal->j_inode) - iput(journal->j_inode); - if (journal->j_revoke) - jbd2_journal_destroy_revoke(journal); - kfree(journal->j_wbuf); - kfree(journal); -} - - -/** - *int jbd2_journal_check_used_features () - Check if features specified are used. - * @journal: Journal to check. - * @compat: bitmask of compatible features - * @ro: bitmask of features that force read-only mount - * @incompat: bitmask of incompatible features - * - * Check whether the journal uses all of a given set of - * features. Return true (non-zero) if it does. - **/ - -int jbd2_journal_check_used_features (journal_t *journal, unsigned long compat, - unsigned long ro, unsigned long incompat) -{ - journal_superblock_t *sb; - - if (!compat && !ro && !incompat) - return 1; - if (journal->j_format_version == 1) - return 0; - - sb = journal->j_superblock; - - if (((be32_to_cpu(sb->s_feature_compat) & compat) == compat) && - ((be32_to_cpu(sb->s_feature_ro_compat) & ro) == ro) && - ((be32_to_cpu(sb->s_feature_incompat) & incompat) == incompat)) - return 1; - - return 0; -} - -/** - * int jbd2_journal_check_available_features() - Check feature set in journalling layer - * @journal: Journal to check. - * @compat: bitmask of compatible features - * @ro: bitmask of features that force read-only mount - * @incompat: bitmask of incompatible features - * - * Check whether the journaling code supports the use of - * all of a given set of features on this journal. Return true - * (non-zero) if it can. */ - -int jbd2_journal_check_available_features (journal_t *journal, unsigned long compat, - unsigned long ro, unsigned long incompat) -{ - journal_superblock_t *sb; - - if (!compat && !ro && !incompat) - return 1; - - sb = journal->j_superblock; - - /* We can support any known requested features iff the - * superblock is in version 2. Otherwise we fail to support any - * extended sb features. */ - - if (journal->j_format_version != 2) - return 0; - - if ((compat & JBD2_KNOWN_COMPAT_FEATURES) == compat && - (ro & JBD2_KNOWN_ROCOMPAT_FEATURES) == ro && - (incompat & JBD2_KNOWN_INCOMPAT_FEATURES) == incompat) - return 1; - - return 0; -} - -/** - * int jbd2_journal_set_features () - Mark a given journal feature in the superblock - * @journal: Journal to act on. - * @compat: bitmask of compatible features - * @ro: bitmask of features that force read-only mount - * @incompat: bitmask of incompatible features - * - * Mark a given journal feature as present on the - * superblock. Returns true if the requested features could be set. - * - */ - -int jbd2_journal_set_features (journal_t *journal, unsigned long compat, - unsigned long ro, unsigned long incompat) -{ - journal_superblock_t *sb; - - if (jbd2_journal_check_used_features(journal, compat, ro, incompat)) - return 1; - - if (!jbd2_journal_check_available_features(journal, compat, ro, incompat)) - return 0; - - jbd_debug(1, "Setting new features 0x%lx/0x%lx/0x%lx\n", - compat, ro, incompat); - - sb = journal->j_superblock; - - sb->s_feature_compat |= cpu_to_be32(compat); - sb->s_feature_ro_compat |= cpu_to_be32(ro); - sb->s_feature_incompat |= cpu_to_be32(incompat); - - return 1; -} - - -/** - * int jbd2_journal_update_format () - Update on-disk journal structure. - * @journal: Journal to act on. - * - * Given an initialised but unloaded journal struct, poke about in the - * on-disk structure to update it to the most recent supported version. - */ -int jbd2_journal_update_format (journal_t *journal) -{ - journal_superblock_t *sb; - int err; - - err = journal_get_superblock(journal); - if (err) - return err; - - sb = journal->j_superblock; - - switch (be32_to_cpu(sb->s_header.h_blocktype)) { - case JBD2_SUPERBLOCK_V2: - return 0; - case JBD2_SUPERBLOCK_V1: - return journal_convert_superblock_v1(journal, sb); - default: - break; - } - return -EINVAL; -} - -static int journal_convert_superblock_v1(journal_t *journal, - journal_superblock_t *sb) -{ - int offset, blocksize; - struct buffer_head *bh; - - printk(KERN_WARNING - "JBD: Converting superblock from version 1 to 2.\n"); - - /* Pre-initialise new fields to zero */ - offset = ((char *) &(sb->s_feature_compat)) - ((char *) sb); - blocksize = be32_to_cpu(sb->s_blocksize); - memset(&sb->s_feature_compat, 0, blocksize-offset); - - sb->s_nr_users = cpu_to_be32(1); - sb->s_header.h_blocktype = cpu_to_be32(JBD2_SUPERBLOCK_V2); - journal->j_format_version = 2; - - bh = journal->j_sb_buffer; - BUFFER_TRACE(bh, "marking dirty"); - mark_buffer_dirty(bh); - sync_dirty_buffer(bh); - return 0; -} - - -/** - * int jbd2_journal_flush () - Flush journal - * @journal: Journal to act on. - * - * Flush all data for a given journal to disk and empty the journal. - * Filesystems can use this when remounting readonly to ensure that - * recovery does not need to happen on remount. - */ - -int jbd2_journal_flush(journal_t *journal) -{ - int err = 0; - transaction_t *transaction = NULL; - unsigned long old_tail; - - spin_lock(&journal->j_state_lock); - - /* Force everything buffered to the log... */ - if (journal->j_running_transaction) { - transaction = journal->j_running_transaction; - __jbd2_log_start_commit(journal, transaction->t_tid); - } else if (journal->j_committing_transaction) - transaction = journal->j_committing_transaction; - - /* Wait for the log commit to complete... */ - if (transaction) { - tid_t tid = transaction->t_tid; - - spin_unlock(&journal->j_state_lock); - jbd2_log_wait_commit(journal, tid); - } else { - spin_unlock(&journal->j_state_lock); - } - - /* ...and flush everything in the log out to disk. */ - spin_lock(&journal->j_list_lock); - while (!err && journal->j_checkpoint_transactions != NULL) { - spin_unlock(&journal->j_list_lock); - err = jbd2_log_do_checkpoint(journal); - spin_lock(&journal->j_list_lock); - } - spin_unlock(&journal->j_list_lock); - jbd2_cleanup_journal_tail(journal); - - /* Finally, mark the journal as really needing no recovery. - * This sets s_start==0 in the underlying superblock, which is - * the magic code for a fully-recovered superblock. Any future - * commits of data to the journal will restore the current - * s_start value. */ - spin_lock(&journal->j_state_lock); - old_tail = journal->j_tail; - journal->j_tail = 0; - spin_unlock(&journal->j_state_lock); - jbd2_journal_update_superblock(journal, 1); - spin_lock(&journal->j_state_lock); - journal->j_tail = old_tail; - - J_ASSERT(!journal->j_running_transaction); - J_ASSERT(!journal->j_committing_transaction); - J_ASSERT(!journal->j_checkpoint_transactions); - J_ASSERT(journal->j_head == journal->j_tail); - J_ASSERT(journal->j_tail_sequence == journal->j_transaction_sequence); - spin_unlock(&journal->j_state_lock); - return err; -} - -/** - * int jbd2_journal_wipe() - Wipe journal contents - * @journal: Journal to act on. - * @write: flag (see below) - * - * Wipe out all of the contents of a journal, safely. This will produce - * a warning if the journal contains any valid recovery information. - * Must be called between journal_init_*() and jbd2_journal_load(). - * - * If 'write' is non-zero, then we wipe out the journal on disk; otherwise - * we merely suppress recovery. - */ - -int jbd2_journal_wipe(journal_t *journal, int write) -{ - journal_superblock_t *sb; - int err = 0; - - J_ASSERT (!(journal->j_flags & JBD2_LOADED)); - - err = load_superblock(journal); - if (err) - return err; - - sb = journal->j_superblock; - - if (!journal->j_tail) - goto no_recovery; - - printk (KERN_WARNING "JBD: %s recovery information on journal\n", - write ? "Clearing" : "Ignoring"); - - err = jbd2_journal_skip_recovery(journal); - if (write) - jbd2_journal_update_superblock(journal, 1); - - no_recovery: - return err; -} - -/* - * journal_dev_name: format a character string to describe on what - * device this journal is present. - */ - -static const char *journal_dev_name(journal_t *journal, char *buffer) -{ - struct block_device *bdev; - - if (journal->j_inode) - bdev = journal->j_inode->i_sb->s_bdev; - else - bdev = journal->j_dev; - - return bdevname(bdev, buffer); -} - -/* - * Journal abort has very specific semantics, which we describe - * for journal abort. - * - * Two internal function, which provide abort to te jbd layer - * itself are here. - */ - -/* - * Quick version for internal journal use (doesn't lock the journal). - * Aborts hard --- we mark the abort as occurred, but do _nothing_ else, - * and don't attempt to make any other journal updates. - */ -void __jbd2_journal_abort_hard(journal_t *journal) -{ - transaction_t *transaction; - char b[BDEVNAME_SIZE]; - - if (journal->j_flags & JBD2_ABORT) - return; - - printk(KERN_ERR "Aborting journal on device %s.\n", - journal_dev_name(journal, b)); - - spin_lock(&journal->j_state_lock); - journal->j_flags |= JBD2_ABORT; - transaction = journal->j_running_transaction; - if (transaction) - __jbd2_log_start_commit(journal, transaction->t_tid); - spin_unlock(&journal->j_state_lock); -} - -/* Soft abort: record the abort error status in the journal superblock, - * but don't do any other IO. */ -static void __journal_abort_soft (journal_t *journal, int errno) -{ - if (journal->j_flags & JBD2_ABORT) - return; - - if (!journal->j_errno) - journal->j_errno = errno; - - __jbd2_journal_abort_hard(journal); - - if (errno) - jbd2_journal_update_superblock(journal, 1); -} - -/** - * void jbd2_journal_abort () - Shutdown the journal immediately. - * @journal: the journal to shutdown. - * @errno: an error number to record in the journal indicating - * the reason for the shutdown. - * - * Perform a complete, immediate shutdown of the ENTIRE - * journal (not of a single transaction). This operation cannot be - * undone without closing and reopening the journal. - * - * The jbd2_journal_abort function is intended to support higher level error - * recovery mechanisms such as the ext2/ext3 remount-readonly error - * mode. - * - * Journal abort has very specific semantics. Any existing dirty, - * unjournaled buffers in the main filesystem will still be written to - * disk by bdflush, but the journaling mechanism will be suspended - * immediately and no further transaction commits will be honoured. - * - * Any dirty, journaled buffers will be written back to disk without - * hitting the journal. Atomicity cannot be guaranteed on an aborted - * filesystem, but we _do_ attempt to leave as much data as possible - * behind for fsck to use for cleanup. - * - * Any attempt to get a new transaction handle on a journal which is in - * ABORT state will just result in an -EROFS error return. A - * jbd2_journal_stop on an existing handle will return -EIO if we have - * entered abort state during the update. - * - * Recursive transactions are not disturbed by journal abort until the - * final jbd2_journal_stop, which will receive the -EIO error. - * - * Finally, the jbd2_journal_abort call allows the caller to supply an errno - * which will be recorded (if possible) in the journal superblock. This - * allows a client to record failure conditions in the middle of a - * transaction without having to complete the transaction to record the - * failure to disk. ext3_error, for example, now uses this - * functionality. - * - * Errors which originate from within the journaling layer will NOT - * supply an errno; a null errno implies that absolutely no further - * writes are done to the journal (unless there are any already in - * progress). - * - */ - -void jbd2_journal_abort(journal_t *journal, int errno) -{ - __journal_abort_soft(journal, errno); -} - -/** - * int jbd2_journal_errno () - returns the journal's error state. - * @journal: journal to examine. - * - * This is the errno numbet set with jbd2_journal_abort(), the last - * time the journal was mounted - if the journal was stopped - * without calling abort this will be 0. - * - * If the journal has been aborted on this mount time -EROFS will - * be returned. - */ -int jbd2_journal_errno(journal_t *journal) -{ - int err; - - spin_lock(&journal->j_state_lock); - if (journal->j_flags & JBD2_ABORT) - err = -EROFS; - else - err = journal->j_errno; - spin_unlock(&journal->j_state_lock); - return err; -} - -/** - * int jbd2_journal_clear_err () - clears the journal's error state - * @journal: journal to act on. - * - * An error must be cleared or Acked to take a FS out of readonly - * mode. - */ -int jbd2_journal_clear_err(journal_t *journal) -{ - int err = 0; - - spin_lock(&journal->j_state_lock); - if (journal->j_flags & JBD2_ABORT) - err = -EROFS; - else - journal->j_errno = 0; - spin_unlock(&journal->j_state_lock); - return err; -} - -/** - * void jbd2_journal_ack_err() - Ack journal err. - * @journal: journal to act on. - * - * An error must be cleared or Acked to take a FS out of readonly - * mode. - */ -void jbd2_journal_ack_err(journal_t *journal) -{ - spin_lock(&journal->j_state_lock); - if (journal->j_errno) - journal->j_flags |= JBD2_ACK_ERR; - spin_unlock(&journal->j_state_lock); -} - -int jbd2_journal_blocks_per_page(struct inode *inode) -{ - return 1 << (PAGE_CACHE_SHIFT - inode->i_sb->s_blocksize_bits); -} - -/* - * helper functions to deal with 32 or 64bit block numbers. - */ -size_t journal_tag_bytes(journal_t *journal) -{ - if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_64BIT)) - return JBD_TAG_SIZE64; - else - return JBD_TAG_SIZE32; -} - -/* - * Simple support for retrying memory allocations. Introduced to help to - * debug different VM deadlock avoidance strategies. - */ -void * __jbd2_kmalloc (const char *where, size_t size, gfp_t flags, int retry) -{ - return kmalloc(size, flags | (retry ? __GFP_NOFAIL : 0)); -} - -/* - * jbd slab management: create 1k, 2k, 4k, 8k slabs as needed - * and allocate frozen and commit buffers from these slabs. - * - * Reason for doing this is to avoid, SLAB_DEBUG - since it could - * cause bh to cross page boundary. - */ - -#define JBD_MAX_SLABS 5 -#define JBD_SLAB_INDEX(size) (size >> 11) - -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" -}; - -static void jbd2_journal_destroy_jbd_slabs(void) -{ - int i; - - for (i = 0; i < JBD_MAX_SLABS; i++) { - if (jbd_slab[i]) - kmem_cache_destroy(jbd_slab[i]); - jbd_slab[i] = NULL; - } -} - -static int jbd2_journal_create_jbd_slab(size_t slab_size) -{ - int i = JBD_SLAB_INDEX(slab_size); - - BUG_ON(i >= JBD_MAX_SLABS); - - /* - * Check if we already have a slab created for this size - */ - if (jbd_slab[i]) - return 0; - - /* - * Create a slab and force alignment to be same as slabsize - - * this will make sure that allocations won't cross the page - * boundary. - */ - jbd_slab[i] = kmem_cache_create(jbd_slab_names[i], - slab_size, slab_size, 0, NULL, NULL); - if (!jbd_slab[i]) { - printk(KERN_EMERG "JBD: no memory for jbd_slab cache\n"); - return -ENOMEM; - } - return 0; -} - -void * jbd2_slab_alloc(size_t size, gfp_t flags) -{ - int idx; - - idx = JBD_SLAB_INDEX(size); - BUG_ON(jbd_slab[idx] == NULL); - return kmem_cache_alloc(jbd_slab[idx], flags | __GFP_NOFAIL); -} - -void jbd2_slab_free(void *ptr, size_t size) -{ - int idx; - - idx = JBD_SLAB_INDEX(size); - BUG_ON(jbd_slab[idx] == NULL); - kmem_cache_free(jbd_slab[idx], ptr); -} - -/* - * Journal_head storage management - */ -static kmem_cache_t *jbd2_journal_head_cache; -#ifdef CONFIG_JBD_DEBUG -static atomic_t nr_journal_heads = ATOMIC_INIT(0); -#endif - -static int journal_init_jbd2_journal_head_cache(void) -{ - int retval; - - J_ASSERT(jbd2_journal_head_cache == 0); - jbd2_journal_head_cache = kmem_cache_create("jbd2_journal_head", - sizeof(struct journal_head), - 0, /* offset */ - 0, /* flags */ - NULL, /* ctor */ - NULL); /* dtor */ - retval = 0; - if (jbd2_journal_head_cache == 0) { - retval = -ENOMEM; - printk(KERN_EMERG "JBD: no memory for journal_head cache\n"); - } - return retval; -} - -static void jbd2_journal_destroy_jbd2_journal_head_cache(void) -{ - J_ASSERT(jbd2_journal_head_cache != NULL); - kmem_cache_destroy(jbd2_journal_head_cache); - jbd2_journal_head_cache = NULL; -} - -/* - * journal_head splicing and dicing - */ -static struct journal_head *journal_alloc_journal_head(void) -{ - struct journal_head *ret; - static unsigned long last_warning; - -#ifdef CONFIG_JBD_DEBUG - atomic_inc(&nr_journal_heads); -#endif - ret = kmem_cache_alloc(jbd2_journal_head_cache, GFP_NOFS); - if (ret == 0) { - jbd_debug(1, "out of memory for journal_head\n"); - if (time_after(jiffies, last_warning + 5*HZ)) { - printk(KERN_NOTICE "ENOMEM in %s, retrying.\n", - __FUNCTION__); - last_warning = jiffies; - } - while (ret == 0) { - yield(); - ret = kmem_cache_alloc(jbd2_journal_head_cache, GFP_NOFS); - } - } - return ret; -} - -static void journal_free_journal_head(struct journal_head *jh) -{ -#ifdef CONFIG_JBD_DEBUG - atomic_dec(&nr_journal_heads); - memset(jh, JBD_POISON_FREE, sizeof(*jh)); -#endif - kmem_cache_free(jbd2_journal_head_cache, jh); -} - -/* - * A journal_head is attached to a buffer_head whenever JBD has an - * interest in the buffer. - * - * Whenever a buffer has an attached journal_head, its ->b_state:BH_JBD bit - * is set. This bit is tested in core kernel code where we need to take - * JBD-specific actions. Testing the zeroness of ->b_private is not reliable - * there. - * - * When a buffer has its BH_JBD bit set, its ->b_count is elevated by one. - * - * When a buffer has its BH_JBD bit set it is immune from being released by - * core kernel code, mainly via ->b_count. - * - * A journal_head may be detached from its buffer_head when the journal_head's - * b_transaction, b_cp_transaction and b_next_transaction pointers are NULL. - * Various places in JBD call jbd2_journal_remove_journal_head() to indicate that the - * journal_head can be dropped if needed. - * - * Various places in the kernel want to attach a journal_head to a buffer_head - * _before_ attaching the journal_head to a transaction. To protect the - * journal_head in this situation, jbd2_journal_add_journal_head elevates the - * journal_head's b_jcount refcount by one. The caller must call - * jbd2_journal_put_journal_head() to undo this. - * - * So the typical usage would be: - * - * (Attach a journal_head if needed. Increments b_jcount) - * struct journal_head *jh = jbd2_journal_add_journal_head(bh); - * ... - * jh->b_transaction = xxx; - * jbd2_journal_put_journal_head(jh); - * - * Now, the journal_head's b_jcount is zero, but it is safe from being released - * because it has a non-zero b_transaction. - */ - -/* - * Give a buffer_head a journal_head. - * - * Doesn't need the journal lock. - * May sleep. - */ -struct journal_head *jbd2_journal_add_journal_head(struct buffer_head *bh) -{ - struct journal_head *jh; - struct journal_head *new_jh = NULL; - -repeat: - if (!buffer_jbd(bh)) { - new_jh = journal_alloc_journal_head(); - memset(new_jh, 0, sizeof(*new_jh)); - } - - jbd_lock_bh_journal_head(bh); - if (buffer_jbd(bh)) { - jh = bh2jh(bh); - } else { - J_ASSERT_BH(bh, - (atomic_read(&bh->b_count) > 0) || - (bh->b_page && bh->b_page->mapping)); - - if (!new_jh) { - jbd_unlock_bh_journal_head(bh); - goto repeat; - } - - jh = new_jh; - new_jh = NULL; /* We consumed it */ - set_buffer_jbd(bh); - bh->b_private = jh; - jh->b_bh = bh; - get_bh(bh); - BUFFER_TRACE(bh, "added journal_head"); - } - jh->b_jcount++; - jbd_unlock_bh_journal_head(bh); - if (new_jh) - journal_free_journal_head(new_jh); - return bh->b_private; -} - -/* - * Grab a ref against this buffer_head's journal_head. If it ended up not - * having a journal_head, return NULL - */ -struct journal_head *jbd2_journal_grab_journal_head(struct buffer_head *bh) -{ - struct journal_head *jh = NULL; - - jbd_lock_bh_journal_head(bh); - if (buffer_jbd(bh)) { - jh = bh2jh(bh); - jh->b_jcount++; - } - jbd_unlock_bh_journal_head(bh); - return jh; -} - -static void __journal_remove_journal_head(struct buffer_head *bh) -{ - struct journal_head *jh = bh2jh(bh); - - J_ASSERT_JH(jh, jh->b_jcount >= 0); - - get_bh(bh); - if (jh->b_jcount == 0) { - if (jh->b_transaction == NULL && - jh->b_next_transaction == NULL && - jh->b_cp_transaction == NULL) { - J_ASSERT_JH(jh, jh->b_jlist == BJ_None); - J_ASSERT_BH(bh, buffer_jbd(bh)); - J_ASSERT_BH(bh, jh2bh(jh) == bh); - BUFFER_TRACE(bh, "remove journal_head"); - if (jh->b_frozen_data) { - printk(KERN_WARNING "%s: freeing " - "b_frozen_data\n", - __FUNCTION__); - jbd2_slab_free(jh->b_frozen_data, bh->b_size); - } - if (jh->b_committed_data) { - printk(KERN_WARNING "%s: freeing " - "b_committed_data\n", - __FUNCTION__); - jbd2_slab_free(jh->b_committed_data, bh->b_size); - } - bh->b_private = NULL; - jh->b_bh = NULL; /* debug, really */ - clear_buffer_jbd(bh); - __brelse(bh); - journal_free_journal_head(jh); - } else { - BUFFER_TRACE(bh, "journal_head was locked"); - } - } -} - -/* - * jbd2_journal_remove_journal_head(): if the buffer isn't attached to a transaction - * and has a zero b_jcount then remove and release its journal_head. If we did - * see that the buffer is not used by any transaction we also "logically" - * decrement ->b_count. - * - * We in fact take an additional increment on ->b_count as a convenience, - * because the caller usually wants to do additional things with the bh - * after calling here. - * The caller of jbd2_journal_remove_journal_head() *must* run __brelse(bh) at some - * time. Once the caller has run __brelse(), the buffer is eligible for - * reaping by try_to_free_buffers(). - */ -void jbd2_journal_remove_journal_head(struct buffer_head *bh) -{ - jbd_lock_bh_journal_head(bh); - __journal_remove_journal_head(bh); - jbd_unlock_bh_journal_head(bh); -} - -/* - * Drop a reference on the passed journal_head. If it fell to zero then try to - * release the journal_head from the buffer_head. - */ -void jbd2_journal_put_journal_head(struct journal_head *jh) -{ - struct buffer_head *bh = jh2bh(jh); - - jbd_lock_bh_journal_head(bh); - J_ASSERT_JH(jh, jh->b_jcount > 0); - --jh->b_jcount; - if (!jh->b_jcount && !jh->b_transaction) { - __journal_remove_journal_head(bh); - __brelse(bh); - } - jbd_unlock_bh_journal_head(bh); -} - -/* - * /proc tunables - */ -#if defined(CONFIG_JBD_DEBUG) -int jbd2_journal_enable_debug; -EXPORT_SYMBOL(jbd2_journal_enable_debug); -#endif - -#if defined(CONFIG_JBD_DEBUG) && defined(CONFIG_PROC_FS) - -static struct proc_dir_entry *proc_jbd_debug; - -static int read_jbd_debug(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - int ret; - - ret = sprintf(page + off, "%d\n", jbd2_journal_enable_debug); - *eof = 1; - return ret; -} - -static int write_jbd_debug(struct file *file, const char __user *buffer, - unsigned long count, void *data) -{ - char buf[32]; - - if (count > ARRAY_SIZE(buf) - 1) - count = ARRAY_SIZE(buf) - 1; - if (copy_from_user(buf, buffer, count)) - return -EFAULT; - buf[ARRAY_SIZE(buf) - 1] = '\0'; - jbd2_journal_enable_debug = simple_strtoul(buf, NULL, 10); - return count; -} - -#define JBD_PROC_NAME "sys/fs/jbd2-debug" - -static void __init create_jbd_proc_entry(void) -{ - proc_jbd_debug = create_proc_entry(JBD_PROC_NAME, 0644, NULL); - if (proc_jbd_debug) { - /* Why is this so hard? */ - proc_jbd_debug->read_proc = read_jbd_debug; - proc_jbd_debug->write_proc = write_jbd_debug; - } -} - -static void __exit jbd2_remove_jbd_proc_entry(void) -{ - if (proc_jbd_debug) - remove_proc_entry(JBD_PROC_NAME, NULL); -} - -#else - -#define create_jbd_proc_entry() do {} while (0) -#define jbd2_remove_jbd_proc_entry() do {} while (0) - -#endif - -kmem_cache_t *jbd2_handle_cache; - -static int __init journal_init_handle_cache(void) -{ - jbd2_handle_cache = kmem_cache_create("jbd2_journal_handle", - sizeof(handle_t), - 0, /* offset */ - 0, /* flags */ - NULL, /* ctor */ - NULL); /* dtor */ - if (jbd2_handle_cache == NULL) { - printk(KERN_EMERG "JBD: failed to create handle cache\n"); - return -ENOMEM; - } - return 0; -} - -static void jbd2_journal_destroy_handle_cache(void) -{ - if (jbd2_handle_cache) - kmem_cache_destroy(jbd2_handle_cache); -} - -/* - * Module startup and shutdown - */ - -static int __init journal_init_caches(void) -{ - int ret; - - ret = jbd2_journal_init_revoke_caches(); - if (ret == 0) - ret = journal_init_jbd2_journal_head_cache(); - if (ret == 0) - ret = journal_init_handle_cache(); - return ret; -} - -static void jbd2_journal_destroy_caches(void) -{ - jbd2_journal_destroy_revoke_caches(); - jbd2_journal_destroy_jbd2_journal_head_cache(); - jbd2_journal_destroy_handle_cache(); - jbd2_journal_destroy_jbd_slabs(); -} - -static int __init journal_init(void) -{ - int ret; - - BUILD_BUG_ON(sizeof(struct journal_superblock_s) != 1024); - - ret = journal_init_caches(); - if (ret != 0) - jbd2_journal_destroy_caches(); - create_jbd_proc_entry(); - return ret; -} - -static void __exit journal_exit(void) -{ -#ifdef CONFIG_JBD_DEBUG - int n = atomic_read(&nr_journal_heads); - if (n) - printk(KERN_EMERG "JBD: leaked %d journal_heads!\n", n); -#endif - jbd2_remove_jbd_proc_entry(); - jbd2_journal_destroy_caches(); -} - -MODULE_LICENSE("GPL"); -module_init(journal_init); -module_exit(journal_exit); - diff --git a/trunk/fs/jbd2/recovery.c b/trunk/fs/jbd2/recovery.c deleted file mode 100644 index 9f10acafaf70..000000000000 --- a/trunk/fs/jbd2/recovery.c +++ /dev/null @@ -1,609 +0,0 @@ -/* - * linux/fs/recovery.c - * - * Written by Stephen C. Tweedie , 1999 - * - * Copyright 1999-2000 Red Hat Software --- All Rights Reserved - * - * This file is part of the Linux kernel and is made available under - * the terms of the GNU General Public License, version 2, or at your - * option, any later version, incorporated herein by reference. - * - * Journal recovery routines for the generic filesystem journaling code; - * part of the ext2fs journaling system. - */ - -#ifndef __KERNEL__ -#include "jfs_user.h" -#else -#include -#include -#include -#include -#include -#endif - -/* - * Maintain information about the progress of the recovery job, so that - * the different passes can carry information between them. - */ -struct recovery_info -{ - tid_t start_transaction; - tid_t end_transaction; - - int nr_replays; - int nr_revokes; - int nr_revoke_hits; -}; - -enum passtype {PASS_SCAN, PASS_REVOKE, PASS_REPLAY}; -static int do_one_pass(journal_t *journal, - struct recovery_info *info, enum passtype pass); -static int scan_revoke_records(journal_t *, struct buffer_head *, - tid_t, struct recovery_info *); - -#ifdef __KERNEL__ - -/* Release readahead buffers after use */ -static void journal_brelse_array(struct buffer_head *b[], int n) -{ - while (--n >= 0) - brelse (b[n]); -} - - -/* - * When reading from the journal, we are going through the block device - * layer directly and so there is no readahead being done for us. We - * need to implement any readahead ourselves if we want it to happen at - * all. Recovery is basically one long sequential read, so make sure we - * do the IO in reasonably large chunks. - * - * This is not so critical that we need to be enormously clever about - * the readahead size, though. 128K is a purely arbitrary, good-enough - * fixed value. - */ - -#define MAXBUF 8 -static int do_readahead(journal_t *journal, unsigned int start) -{ - int err; - unsigned int max, nbufs, next; - unsigned long long blocknr; - struct buffer_head *bh; - - struct buffer_head * bufs[MAXBUF]; - - /* Do up to 128K of readahead */ - max = start + (128 * 1024 / journal->j_blocksize); - if (max > journal->j_maxlen) - max = journal->j_maxlen; - - /* Do the readahead itself. We'll submit MAXBUF buffer_heads at - * a time to the block device IO layer. */ - - nbufs = 0; - - for (next = start; next < max; next++) { - err = jbd2_journal_bmap(journal, next, &blocknr); - - if (err) { - printk (KERN_ERR "JBD: bad block at offset %u\n", - next); - goto failed; - } - - bh = __getblk(journal->j_dev, blocknr, journal->j_blocksize); - if (!bh) { - err = -ENOMEM; - goto failed; - } - - if (!buffer_uptodate(bh) && !buffer_locked(bh)) { - bufs[nbufs++] = bh; - if (nbufs == MAXBUF) { - ll_rw_block(READ, nbufs, bufs); - journal_brelse_array(bufs, nbufs); - nbufs = 0; - } - } else - brelse(bh); - } - - if (nbufs) - ll_rw_block(READ, nbufs, bufs); - err = 0; - -failed: - if (nbufs) - journal_brelse_array(bufs, nbufs); - return err; -} - -#endif /* __KERNEL__ */ - - -/* - * Read a block from the journal - */ - -static int jread(struct buffer_head **bhp, journal_t *journal, - unsigned int offset) -{ - int err; - unsigned long long blocknr; - struct buffer_head *bh; - - *bhp = NULL; - - if (offset >= journal->j_maxlen) { - printk(KERN_ERR "JBD: corrupted journal superblock\n"); - return -EIO; - } - - err = jbd2_journal_bmap(journal, offset, &blocknr); - - if (err) { - printk (KERN_ERR "JBD: bad block at offset %u\n", - offset); - return err; - } - - bh = __getblk(journal->j_dev, blocknr, journal->j_blocksize); - if (!bh) - return -ENOMEM; - - if (!buffer_uptodate(bh)) { - /* If this is a brand new buffer, start readahead. - Otherwise, we assume we are already reading it. */ - if (!buffer_req(bh)) - do_readahead(journal, offset); - wait_on_buffer(bh); - } - - if (!buffer_uptodate(bh)) { - printk (KERN_ERR "JBD: Failed to read block at offset %u\n", - offset); - brelse(bh); - return -EIO; - } - - *bhp = bh; - return 0; -} - - -/* - * Count the number of in-use tags in a journal descriptor block. - */ - -static int count_tags(journal_t *journal, struct buffer_head *bh) -{ - char * tagp; - journal_block_tag_t * tag; - int nr = 0, size = journal->j_blocksize; - int tag_bytes = journal_tag_bytes(journal); - - tagp = &bh->b_data[sizeof(journal_header_t)]; - - while ((tagp - bh->b_data + tag_bytes) <= size) { - tag = (journal_block_tag_t *) tagp; - - nr++; - tagp += tag_bytes; - if (!(tag->t_flags & cpu_to_be32(JBD2_FLAG_SAME_UUID))) - tagp += 16; - - if (tag->t_flags & cpu_to_be32(JBD2_FLAG_LAST_TAG)) - break; - } - - return nr; -} - - -/* Make sure we wrap around the log correctly! */ -#define wrap(journal, var) \ -do { \ - if (var >= (journal)->j_last) \ - var -= ((journal)->j_last - (journal)->j_first); \ -} while (0) - -/** - * jbd2_journal_recover - recovers a on-disk journal - * @journal: the journal to recover - * - * The primary function for recovering the log contents when mounting a - * journaled device. - * - * Recovery is done in three passes. In the first pass, we look for the - * end of the log. In the second, we assemble the list of revoke - * blocks. In the third and final pass, we replay any un-revoked blocks - * in the log. - */ -int jbd2_journal_recover(journal_t *journal) -{ - int err; - journal_superblock_t * sb; - - struct recovery_info info; - - memset(&info, 0, sizeof(info)); - sb = journal->j_superblock; - - /* - * The journal superblock's s_start field (the current log head) - * is always zero if, and only if, the journal was cleanly - * unmounted. - */ - - if (!sb->s_start) { - jbd_debug(1, "No recovery required, last transaction %d\n", - be32_to_cpu(sb->s_sequence)); - journal->j_transaction_sequence = be32_to_cpu(sb->s_sequence) + 1; - return 0; - } - - err = do_one_pass(journal, &info, PASS_SCAN); - if (!err) - err = do_one_pass(journal, &info, PASS_REVOKE); - if (!err) - err = do_one_pass(journal, &info, PASS_REPLAY); - - jbd_debug(0, "JBD: recovery, exit status %d, " - "recovered transactions %u to %u\n", - err, info.start_transaction, info.end_transaction); - jbd_debug(0, "JBD: Replayed %d and revoked %d/%d blocks\n", - info.nr_replays, info.nr_revoke_hits, info.nr_revokes); - - /* Restart the log at the next transaction ID, thus invalidating - * any existing commit records in the log. */ - journal->j_transaction_sequence = ++info.end_transaction; - - jbd2_journal_clear_revoke(journal); - sync_blockdev(journal->j_fs_dev); - return err; -} - -/** - * jbd2_journal_skip_recovery - Start journal and wipe exiting records - * @journal: journal to startup - * - * Locate any valid recovery information from the journal and set up the - * journal structures in memory to ignore it (presumably because the - * caller has evidence that it is out of date). - * This function does'nt appear to be exorted.. - * - * We perform one pass over the journal to allow us to tell the user how - * much recovery information is being erased, and to let us initialise - * the journal transaction sequence numbers to the next unused ID. - */ -int jbd2_journal_skip_recovery(journal_t *journal) -{ - int err; - journal_superblock_t * sb; - - struct recovery_info info; - - memset (&info, 0, sizeof(info)); - sb = journal->j_superblock; - - err = do_one_pass(journal, &info, PASS_SCAN); - - if (err) { - printk(KERN_ERR "JBD: error %d scanning journal\n", err); - ++journal->j_transaction_sequence; - } else { -#ifdef CONFIG_JBD_DEBUG - int dropped = info.end_transaction - be32_to_cpu(sb->s_sequence); -#endif - jbd_debug(0, - "JBD: ignoring %d transaction%s from the journal.\n", - dropped, (dropped == 1) ? "" : "s"); - journal->j_transaction_sequence = ++info.end_transaction; - } - - journal->j_tail = 0; - return err; -} - -static inline unsigned long long read_tag_block(int tag_bytes, journal_block_tag_t *tag) -{ - unsigned long long block = be32_to_cpu(tag->t_blocknr); - if (tag_bytes > JBD_TAG_SIZE32) - block |= (u64)be32_to_cpu(tag->t_blocknr_high) << 32; - return block; -} - -static int do_one_pass(journal_t *journal, - struct recovery_info *info, enum passtype pass) -{ - unsigned int first_commit_ID, next_commit_ID; - unsigned long next_log_block; - int err, success = 0; - journal_superblock_t * sb; - journal_header_t * tmp; - struct buffer_head * bh; - unsigned int sequence; - int blocktype; - int tag_bytes = journal_tag_bytes(journal); - - /* Precompute the maximum metadata descriptors in a descriptor block */ - int MAX_BLOCKS_PER_DESC; - MAX_BLOCKS_PER_DESC = ((journal->j_blocksize-sizeof(journal_header_t)) - / tag_bytes); - - /* - * First thing is to establish what we expect to find in the log - * (in terms of transaction IDs), and where (in terms of log - * block offsets): query the superblock. - */ - - sb = journal->j_superblock; - next_commit_ID = be32_to_cpu(sb->s_sequence); - next_log_block = be32_to_cpu(sb->s_start); - - first_commit_ID = next_commit_ID; - if (pass == PASS_SCAN) - info->start_transaction = first_commit_ID; - - jbd_debug(1, "Starting recovery pass %d\n", pass); - - /* - * Now we walk through the log, transaction by transaction, - * making sure that each transaction has a commit block in the - * expected place. Each complete transaction gets replayed back - * into the main filesystem. - */ - - while (1) { - int flags; - char * tagp; - journal_block_tag_t * tag; - struct buffer_head * obh; - struct buffer_head * nbh; - - cond_resched(); /* We're under lock_kernel() */ - - /* If we already know where to stop the log traversal, - * check right now that we haven't gone past the end of - * the log. */ - - if (pass != PASS_SCAN) - if (tid_geq(next_commit_ID, info->end_transaction)) - break; - - jbd_debug(2, "Scanning for sequence ID %u at %lu/%lu\n", - next_commit_ID, next_log_block, journal->j_last); - - /* Skip over each chunk of the transaction looking - * either the next descriptor block or the final commit - * record. */ - - jbd_debug(3, "JBD: checking block %ld\n", next_log_block); - err = jread(&bh, journal, next_log_block); - if (err) - goto failed; - - next_log_block++; - wrap(journal, next_log_block); - - /* What kind of buffer is it? - * - * If it is a descriptor block, check that it has the - * expected sequence number. Otherwise, we're all done - * here. */ - - tmp = (journal_header_t *)bh->b_data; - - if (tmp->h_magic != cpu_to_be32(JBD2_MAGIC_NUMBER)) { - brelse(bh); - break; - } - - blocktype = be32_to_cpu(tmp->h_blocktype); - sequence = be32_to_cpu(tmp->h_sequence); - jbd_debug(3, "Found magic %d, sequence %d\n", - blocktype, sequence); - - if (sequence != next_commit_ID) { - brelse(bh); - break; - } - - /* OK, we have a valid descriptor block which matches - * all of the sequence number checks. What are we going - * to do with it? That depends on the pass... */ - - switch(blocktype) { - case JBD2_DESCRIPTOR_BLOCK: - /* If it is a valid descriptor block, replay it - * in pass REPLAY; otherwise, just skip over the - * blocks it describes. */ - if (pass != PASS_REPLAY) { - next_log_block += count_tags(journal, bh); - wrap(journal, next_log_block); - brelse(bh); - continue; - } - - /* A descriptor block: we can now write all of - * the data blocks. Yay, useful work is finally - * getting done here! */ - - tagp = &bh->b_data[sizeof(journal_header_t)]; - while ((tagp - bh->b_data + tag_bytes) - <= journal->j_blocksize) { - unsigned long io_block; - - tag = (journal_block_tag_t *) tagp; - flags = be32_to_cpu(tag->t_flags); - - io_block = next_log_block++; - wrap(journal, next_log_block); - err = jread(&obh, journal, io_block); - if (err) { - /* Recover what we can, but - * report failure at the end. */ - success = err; - printk (KERN_ERR - "JBD: IO error %d recovering " - "block %ld in log\n", - err, io_block); - } else { - unsigned long long blocknr; - - J_ASSERT(obh != NULL); - blocknr = read_tag_block(tag_bytes, - tag); - - /* If the block has been - * revoked, then we're all done - * here. */ - if (jbd2_journal_test_revoke - (journal, blocknr, - next_commit_ID)) { - brelse(obh); - ++info->nr_revoke_hits; - goto skip_write; - } - - /* Find a buffer for the new - * data being restored */ - nbh = __getblk(journal->j_fs_dev, - blocknr, - journal->j_blocksize); - if (nbh == NULL) { - printk(KERN_ERR - "JBD: Out of memory " - "during recovery.\n"); - err = -ENOMEM; - brelse(bh); - brelse(obh); - goto failed; - } - - lock_buffer(nbh); - memcpy(nbh->b_data, obh->b_data, - journal->j_blocksize); - if (flags & JBD2_FLAG_ESCAPE) { - *((__be32 *)bh->b_data) = - cpu_to_be32(JBD2_MAGIC_NUMBER); - } - - BUFFER_TRACE(nbh, "marking dirty"); - set_buffer_uptodate(nbh); - mark_buffer_dirty(nbh); - BUFFER_TRACE(nbh, "marking uptodate"); - ++info->nr_replays; - /* ll_rw_block(WRITE, 1, &nbh); */ - unlock_buffer(nbh); - brelse(obh); - brelse(nbh); - } - - skip_write: - tagp += tag_bytes; - if (!(flags & JBD2_FLAG_SAME_UUID)) - tagp += 16; - - if (flags & JBD2_FLAG_LAST_TAG) - break; - } - - brelse(bh); - continue; - - case JBD2_COMMIT_BLOCK: - /* Found an expected commit block: not much to - * do other than move on to the next sequence - * number. */ - brelse(bh); - next_commit_ID++; - continue; - - case JBD2_REVOKE_BLOCK: - /* If we aren't in the REVOKE pass, then we can - * just skip over this block. */ - if (pass != PASS_REVOKE) { - brelse(bh); - continue; - } - - err = scan_revoke_records(journal, bh, - next_commit_ID, info); - brelse(bh); - if (err) - goto failed; - continue; - - default: - jbd_debug(3, "Unrecognised magic %d, end of scan.\n", - blocktype); - brelse(bh); - goto done; - } - } - - done: - /* - * We broke out of the log scan loop: either we came to the - * known end of the log or we found an unexpected block in the - * log. If the latter happened, then we know that the "current" - * transaction marks the end of the valid log. - */ - - if (pass == PASS_SCAN) - info->end_transaction = next_commit_ID; - else { - /* It's really bad news if different passes end up at - * different places (but possible due to IO errors). */ - if (info->end_transaction != next_commit_ID) { - printk (KERN_ERR "JBD: recovery pass %d ended at " - "transaction %u, expected %u\n", - pass, next_commit_ID, info->end_transaction); - if (!success) - success = -EIO; - } - } - - return success; - - failed: - return err; -} - - -/* Scan a revoke record, marking all blocks mentioned as revoked. */ - -static int scan_revoke_records(journal_t *journal, struct buffer_head *bh, - tid_t sequence, struct recovery_info *info) -{ - jbd2_journal_revoke_header_t *header; - int offset, max; - int record_len = 4; - - header = (jbd2_journal_revoke_header_t *) bh->b_data; - offset = sizeof(jbd2_journal_revoke_header_t); - max = be32_to_cpu(header->r_count); - - if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_64BIT)) - record_len = 8; - - while (offset + record_len <= max) { - unsigned long long blocknr; - int err; - - if (record_len == 4) - blocknr = be32_to_cpu(* ((__be32 *) (bh->b_data+offset))); - else - blocknr = be64_to_cpu(* ((__be64 *) (bh->b_data+offset))); - offset += record_len; - err = jbd2_journal_set_revoke(journal, blocknr, sequence); - if (err) - return err; - ++info->nr_revokes; - } - return 0; -} diff --git a/trunk/fs/jbd2/revoke.c b/trunk/fs/jbd2/revoke.c deleted file mode 100644 index 380d19917f37..000000000000 --- a/trunk/fs/jbd2/revoke.c +++ /dev/null @@ -1,712 +0,0 @@ -/* - * linux/fs/revoke.c - * - * Written by Stephen C. Tweedie , 2000 - * - * Copyright 2000 Red Hat corp --- All Rights Reserved - * - * This file is part of the Linux kernel and is made available under - * the terms of the GNU General Public License, version 2, or at your - * option, any later version, incorporated herein by reference. - * - * Journal revoke routines for the generic filesystem journaling code; - * part of the ext2fs journaling system. - * - * Revoke is the mechanism used to prevent old log records for deleted - * metadata from being replayed on top of newer data using the same - * blocks. The revoke mechanism is used in two separate places: - * - * + Commit: during commit we write the entire list of the current - * transaction's revoked blocks to the journal - * - * + Recovery: during recovery we record the transaction ID of all - * revoked blocks. If there are multiple revoke records in the log - * for a single block, only the last one counts, and if there is a log - * entry for a block beyond the last revoke, then that log entry still - * gets replayed. - * - * We can get interactions between revokes and new log data within a - * single transaction: - * - * Block is revoked and then journaled: - * The desired end result is the journaling of the new block, so we - * cancel the revoke before the transaction commits. - * - * Block is journaled and then revoked: - * The revoke must take precedence over the write of the block, so we - * need either to cancel the journal entry or to write the revoke - * later in the log than the log block. In this case, we choose the - * latter: journaling a block cancels any revoke record for that block - * in the current transaction, so any revoke for that block in the - * transaction must have happened after the block was journaled and so - * the revoke must take precedence. - * - * Block is revoked and then written as data: - * The data write is allowed to succeed, but the revoke is _not_ - * cancelled. We still need to prevent old log records from - * overwriting the new data. We don't even need to clear the revoke - * bit here. - * - * Revoke information on buffers is a tri-state value: - * - * RevokeValid clear: no cached revoke status, need to look it up - * RevokeValid set, Revoked clear: - * buffer has not been revoked, and cancel_revoke - * need do nothing. - * RevokeValid set, Revoked set: - * buffer has been revoked. - */ - -#ifndef __KERNEL__ -#include "jfs_user.h" -#else -#include -#include -#include -#include -#include -#include -#include -#include -#endif - -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 - last transaction to revoke this block. */ - -struct jbd2_revoke_record_s -{ - struct list_head hash; - tid_t sequence; /* Used for recovery only */ - unsigned long long blocknr; -}; - - -/* The revoke table is just a simple hash table of revoke records. */ -struct jbd2_revoke_table_s -{ - /* It is conceivable that we might want a larger hash table - * for recovery. Must be a power of two. */ - int hash_size; - int hash_shift; - struct list_head *hash_table; -}; - - -#ifdef __KERNEL__ -static void write_one_revoke_record(journal_t *, transaction_t *, - struct journal_head **, int *, - struct jbd2_revoke_record_s *); -static void flush_descriptor(journal_t *, struct journal_head *, int); -#endif - -/* Utility functions to maintain the revoke table */ - -/* Borrowed from buffer.c: this is a tried and tested block hash function */ -static inline int hash(journal_t *journal, unsigned long long block) -{ - struct jbd2_revoke_table_s *table = journal->j_revoke; - int hash_shift = table->hash_shift; - int hash = (int)block ^ (int)((block >> 31) >> 1); - - return ((hash << (hash_shift - 6)) ^ - (hash >> 13) ^ - (hash << (hash_shift - 12))) & (table->hash_size - 1); -} - -static int insert_revoke_hash(journal_t *journal, unsigned long long blocknr, - tid_t seq) -{ - struct list_head *hash_list; - struct jbd2_revoke_record_s *record; - -repeat: - record = kmem_cache_alloc(jbd2_revoke_record_cache, GFP_NOFS); - if (!record) - goto oom; - - record->sequence = seq; - record->blocknr = blocknr; - hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)]; - spin_lock(&journal->j_revoke_lock); - list_add(&record->hash, hash_list); - spin_unlock(&journal->j_revoke_lock); - return 0; - -oom: - if (!journal_oom_retry) - return -ENOMEM; - jbd_debug(1, "ENOMEM in %s, retrying\n", __FUNCTION__); - yield(); - goto repeat; -} - -/* Find a revoke record in the journal's hash table. */ - -static struct jbd2_revoke_record_s *find_revoke_record(journal_t *journal, - unsigned long long blocknr) -{ - struct list_head *hash_list; - struct jbd2_revoke_record_s *record; - - hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)]; - - spin_lock(&journal->j_revoke_lock); - record = (struct jbd2_revoke_record_s *) hash_list->next; - while (&(record->hash) != hash_list) { - if (record->blocknr == blocknr) { - spin_unlock(&journal->j_revoke_lock); - return record; - } - record = (struct jbd2_revoke_record_s *) record->hash.next; - } - spin_unlock(&journal->j_revoke_lock); - return NULL; -} - -int __init jbd2_journal_init_revoke_caches(void) -{ - jbd2_revoke_record_cache = kmem_cache_create("jbd2_revoke_record", - sizeof(struct jbd2_revoke_record_s), - 0, SLAB_HWCACHE_ALIGN, NULL, NULL); - if (jbd2_revoke_record_cache == 0) - return -ENOMEM; - - jbd2_revoke_table_cache = kmem_cache_create("jbd2_revoke_table", - sizeof(struct jbd2_revoke_table_s), - 0, 0, NULL, NULL); - if (jbd2_revoke_table_cache == 0) { - kmem_cache_destroy(jbd2_revoke_record_cache); - jbd2_revoke_record_cache = NULL; - return -ENOMEM; - } - return 0; -} - -void jbd2_journal_destroy_revoke_caches(void) -{ - kmem_cache_destroy(jbd2_revoke_record_cache); - jbd2_revoke_record_cache = NULL; - kmem_cache_destroy(jbd2_revoke_table_cache); - jbd2_revoke_table_cache = NULL; -} - -/* Initialise the revoke table for a given journal to a given size. */ - -int jbd2_journal_init_revoke(journal_t *journal, int hash_size) -{ - int shift, tmp; - - J_ASSERT (journal->j_revoke_table[0] == NULL); - - shift = 0; - tmp = hash_size; - while((tmp >>= 1UL) != 0UL) - shift++; - - journal->j_revoke_table[0] = kmem_cache_alloc(jbd2_revoke_table_cache, GFP_KERNEL); - if (!journal->j_revoke_table[0]) - return -ENOMEM; - journal->j_revoke = journal->j_revoke_table[0]; - - /* Check that the hash_size is a power of two */ - J_ASSERT ((hash_size & (hash_size-1)) == 0); - - journal->j_revoke->hash_size = hash_size; - - journal->j_revoke->hash_shift = shift; - - journal->j_revoke->hash_table = - kmalloc(hash_size * sizeof(struct list_head), GFP_KERNEL); - if (!journal->j_revoke->hash_table) { - kmem_cache_free(jbd2_revoke_table_cache, journal->j_revoke_table[0]); - journal->j_revoke = NULL; - return -ENOMEM; - } - - for (tmp = 0; tmp < hash_size; tmp++) - INIT_LIST_HEAD(&journal->j_revoke->hash_table[tmp]); - - journal->j_revoke_table[1] = kmem_cache_alloc(jbd2_revoke_table_cache, GFP_KERNEL); - if (!journal->j_revoke_table[1]) { - kfree(journal->j_revoke_table[0]->hash_table); - kmem_cache_free(jbd2_revoke_table_cache, journal->j_revoke_table[0]); - return -ENOMEM; - } - - journal->j_revoke = journal->j_revoke_table[1]; - - /* Check that the hash_size is a power of two */ - J_ASSERT ((hash_size & (hash_size-1)) == 0); - - journal->j_revoke->hash_size = hash_size; - - journal->j_revoke->hash_shift = shift; - - journal->j_revoke->hash_table = - kmalloc(hash_size * sizeof(struct list_head), GFP_KERNEL); - if (!journal->j_revoke->hash_table) { - kfree(journal->j_revoke_table[0]->hash_table); - kmem_cache_free(jbd2_revoke_table_cache, journal->j_revoke_table[0]); - kmem_cache_free(jbd2_revoke_table_cache, journal->j_revoke_table[1]); - journal->j_revoke = NULL; - return -ENOMEM; - } - - for (tmp = 0; tmp < hash_size; tmp++) - INIT_LIST_HEAD(&journal->j_revoke->hash_table[tmp]); - - spin_lock_init(&journal->j_revoke_lock); - - return 0; -} - -/* Destoy a journal's revoke table. The table must already be empty! */ - -void jbd2_journal_destroy_revoke(journal_t *journal) -{ - struct jbd2_revoke_table_s *table; - struct list_head *hash_list; - int i; - - table = journal->j_revoke_table[0]; - if (!table) - return; - - for (i=0; ihash_size; i++) { - hash_list = &table->hash_table[i]; - J_ASSERT (list_empty(hash_list)); - } - - kfree(table->hash_table); - kmem_cache_free(jbd2_revoke_table_cache, table); - journal->j_revoke = NULL; - - table = journal->j_revoke_table[1]; - if (!table) - return; - - for (i=0; ihash_size; i++) { - hash_list = &table->hash_table[i]; - J_ASSERT (list_empty(hash_list)); - } - - kfree(table->hash_table); - kmem_cache_free(jbd2_revoke_table_cache, table); - journal->j_revoke = NULL; -} - - -#ifdef __KERNEL__ - -/* - * jbd2_journal_revoke: revoke a given buffer_head from the journal. This - * prevents the block from being replayed during recovery if we take a - * crash after this current transaction commits. Any subsequent - * metadata writes of the buffer in this transaction cancel the - * revoke. - * - * Note that this call may block --- it is up to the caller to make - * sure that there are no further calls to journal_write_metadata - * before the revoke is complete. In ext3, this implies calling the - * revoke before clearing the block bitmap when we are deleting - * metadata. - * - * Revoke performs a jbd2_journal_forget on any buffer_head passed in as a - * parameter, but does _not_ forget the buffer_head if the bh was only - * found implicitly. - * - * bh_in may not be a journalled buffer - it may have come off - * the hash tables without an attached journal_head. - * - * If bh_in is non-zero, jbd2_journal_revoke() will decrement its b_count - * by one. - */ - -int jbd2_journal_revoke(handle_t *handle, unsigned long long blocknr, - struct buffer_head *bh_in) -{ - struct buffer_head *bh = NULL; - journal_t *journal; - struct block_device *bdev; - int err; - - might_sleep(); - if (bh_in) - BUFFER_TRACE(bh_in, "enter"); - - journal = handle->h_transaction->t_journal; - if (!jbd2_journal_set_features(journal, 0, 0, JBD2_FEATURE_INCOMPAT_REVOKE)){ - J_ASSERT (!"Cannot set revoke feature!"); - return -EINVAL; - } - - bdev = journal->j_fs_dev; - bh = bh_in; - - if (!bh) { - bh = __find_get_block(bdev, blocknr, journal->j_blocksize); - if (bh) - BUFFER_TRACE(bh, "found on hash"); - } -#ifdef JBD_EXPENSIVE_CHECKING - else { - struct buffer_head *bh2; - - /* If there is a different buffer_head lying around in - * memory anywhere... */ - bh2 = __find_get_block(bdev, blocknr, journal->j_blocksize); - if (bh2) { - /* ... and it has RevokeValid status... */ - if (bh2 != bh && buffer_revokevalid(bh2)) - /* ...then it better be revoked too, - * since it's illegal to create a revoke - * record against a buffer_head which is - * not marked revoked --- that would - * risk missing a subsequent revoke - * cancel. */ - J_ASSERT_BH(bh2, buffer_revoked(bh2)); - put_bh(bh2); - } - } -#endif - - /* We really ought not ever to revoke twice in a row without - first having the revoke cancelled: it's illegal to free a - block twice without allocating it in between! */ - if (bh) { - if (!J_EXPECT_BH(bh, !buffer_revoked(bh), - "inconsistent data on disk")) { - if (!bh_in) - brelse(bh); - return -EIO; - } - set_buffer_revoked(bh); - set_buffer_revokevalid(bh); - if (bh_in) { - BUFFER_TRACE(bh_in, "call jbd2_journal_forget"); - jbd2_journal_forget(handle, bh_in); - } else { - BUFFER_TRACE(bh, "call brelse"); - __brelse(bh); - } - } - - jbd_debug(2, "insert revoke for block %llu, bh_in=%p\n",blocknr, bh_in); - err = insert_revoke_hash(journal, blocknr, - handle->h_transaction->t_tid); - BUFFER_TRACE(bh_in, "exit"); - return err; -} - -/* - * Cancel an outstanding revoke. For use only internally by the - * journaling code (called from jbd2_journal_get_write_access). - * - * We trust buffer_revoked() on the buffer if the buffer is already - * being journaled: if there is no revoke pending on the buffer, then we - * don't do anything here. - * - * This would break if it were possible for a buffer to be revoked and - * discarded, and then reallocated within the same transaction. In such - * a case we would have lost the revoked bit, but when we arrived here - * the second time we would still have a pending revoke to cancel. So, - * do not trust the Revoked bit on buffers unless RevokeValid is also - * set. - * - * The caller must have the journal locked. - */ -int jbd2_journal_cancel_revoke(handle_t *handle, struct journal_head *jh) -{ - struct jbd2_revoke_record_s *record; - journal_t *journal = handle->h_transaction->t_journal; - int need_cancel; - int did_revoke = 0; /* akpm: debug */ - struct buffer_head *bh = jh2bh(jh); - - jbd_debug(4, "journal_head %p, cancelling revoke\n", jh); - - /* Is the existing Revoke bit valid? If so, we trust it, and - * only perform the full cancel if the revoke bit is set. If - * not, we can't trust the revoke bit, and we need to do the - * full search for a revoke record. */ - if (test_set_buffer_revokevalid(bh)) { - need_cancel = test_clear_buffer_revoked(bh); - } else { - need_cancel = 1; - clear_buffer_revoked(bh); - } - - if (need_cancel) { - record = find_revoke_record(journal, bh->b_blocknr); - if (record) { - jbd_debug(4, "cancelled existing revoke on " - "blocknr %llu\n", (unsigned long long)bh->b_blocknr); - spin_lock(&journal->j_revoke_lock); - list_del(&record->hash); - spin_unlock(&journal->j_revoke_lock); - kmem_cache_free(jbd2_revoke_record_cache, record); - did_revoke = 1; - } - } - -#ifdef JBD_EXPENSIVE_CHECKING - /* There better not be one left behind by now! */ - record = find_revoke_record(journal, bh->b_blocknr); - J_ASSERT_JH(jh, record == NULL); -#endif - - /* Finally, have we just cleared revoke on an unhashed - * buffer_head? If so, we'd better make sure we clear the - * revoked status on any hashed alias too, otherwise the revoke - * state machine will get very upset later on. */ - if (need_cancel) { - struct buffer_head *bh2; - bh2 = __find_get_block(bh->b_bdev, bh->b_blocknr, bh->b_size); - if (bh2) { - if (bh2 != bh) - clear_buffer_revoked(bh2); - __brelse(bh2); - } - } - return did_revoke; -} - -/* journal_switch_revoke table select j_revoke for next transaction - * we do not want to suspend any processing until all revokes are - * written -bzzz - */ -void jbd2_journal_switch_revoke_table(journal_t *journal) -{ - int i; - - if (journal->j_revoke == journal->j_revoke_table[0]) - journal->j_revoke = journal->j_revoke_table[1]; - else - journal->j_revoke = journal->j_revoke_table[0]; - - for (i = 0; i < journal->j_revoke->hash_size; i++) - INIT_LIST_HEAD(&journal->j_revoke->hash_table[i]); -} - -/* - * Write revoke records to the journal for all entries in the current - * revoke hash, deleting the entries as we go. - * - * Called with the journal lock held. - */ - -void jbd2_journal_write_revoke_records(journal_t *journal, - transaction_t *transaction) -{ - struct journal_head *descriptor; - struct jbd2_revoke_record_s *record; - struct jbd2_revoke_table_s *revoke; - struct list_head *hash_list; - int i, offset, count; - - descriptor = NULL; - offset = 0; - count = 0; - - /* select revoke table for committing transaction */ - revoke = journal->j_revoke == journal->j_revoke_table[0] ? - journal->j_revoke_table[1] : journal->j_revoke_table[0]; - - for (i = 0; i < revoke->hash_size; i++) { - hash_list = &revoke->hash_table[i]; - - while (!list_empty(hash_list)) { - record = (struct jbd2_revoke_record_s *) - hash_list->next; - write_one_revoke_record(journal, transaction, - &descriptor, &offset, - record); - count++; - list_del(&record->hash); - kmem_cache_free(jbd2_revoke_record_cache, record); - } - } - if (descriptor) - flush_descriptor(journal, descriptor, offset); - jbd_debug(1, "Wrote %d revoke records\n", count); -} - -/* - * Write out one revoke record. We need to create a new descriptor - * block if the old one is full or if we have not already created one. - */ - -static void write_one_revoke_record(journal_t *journal, - transaction_t *transaction, - struct journal_head **descriptorp, - int *offsetp, - struct jbd2_revoke_record_s *record) -{ - struct journal_head *descriptor; - int offset; - journal_header_t *header; - - /* If we are already aborting, this all becomes a noop. We - still need to go round the loop in - jbd2_journal_write_revoke_records in order to free all of the - revoke records: only the IO to the journal is omitted. */ - if (is_journal_aborted(journal)) - return; - - descriptor = *descriptorp; - offset = *offsetp; - - /* Make sure we have a descriptor with space left for the record */ - if (descriptor) { - if (offset == journal->j_blocksize) { - flush_descriptor(journal, descriptor, offset); - descriptor = NULL; - } - } - - if (!descriptor) { - descriptor = jbd2_journal_get_descriptor_buffer(journal); - if (!descriptor) - return; - header = (journal_header_t *) &jh2bh(descriptor)->b_data[0]; - header->h_magic = cpu_to_be32(JBD2_MAGIC_NUMBER); - header->h_blocktype = cpu_to_be32(JBD2_REVOKE_BLOCK); - header->h_sequence = cpu_to_be32(transaction->t_tid); - - /* Record it so that we can wait for IO completion later */ - JBUFFER_TRACE(descriptor, "file as BJ_LogCtl"); - jbd2_journal_file_buffer(descriptor, transaction, BJ_LogCtl); - - offset = sizeof(jbd2_journal_revoke_header_t); - *descriptorp = descriptor; - } - - if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_64BIT)) { - * ((__be64 *)(&jh2bh(descriptor)->b_data[offset])) = - cpu_to_be64(record->blocknr); - offset += 8; - - } else { - * ((__be32 *)(&jh2bh(descriptor)->b_data[offset])) = - cpu_to_be32(record->blocknr); - offset += 4; - } - - *offsetp = offset; -} - -/* - * Flush a revoke descriptor out to the journal. If we are aborting, - * this is a noop; otherwise we are generating a buffer which needs to - * be waited for during commit, so it has to go onto the appropriate - * journal buffer list. - */ - -static void flush_descriptor(journal_t *journal, - struct journal_head *descriptor, - int offset) -{ - jbd2_journal_revoke_header_t *header; - struct buffer_head *bh = jh2bh(descriptor); - - if (is_journal_aborted(journal)) { - put_bh(bh); - return; - } - - header = (jbd2_journal_revoke_header_t *) jh2bh(descriptor)->b_data; - header->r_count = cpu_to_be32(offset); - set_buffer_jwrite(bh); - BUFFER_TRACE(bh, "write"); - set_buffer_dirty(bh); - ll_rw_block(SWRITE, 1, &bh); -} -#endif - -/* - * Revoke support for recovery. - * - * Recovery needs to be able to: - * - * record all revoke records, including the tid of the latest instance - * of each revoke in the journal - * - * check whether a given block in a given transaction should be replayed - * (ie. has not been revoked by a revoke record in that or a subsequent - * transaction) - * - * empty the revoke table after recovery. - */ - -/* - * First, setting revoke records. We create a new revoke record for - * every block ever revoked in the log as we scan it for recovery, and - * we update the existing records if we find multiple revokes for a - * single block. - */ - -int jbd2_journal_set_revoke(journal_t *journal, - unsigned long long blocknr, - tid_t sequence) -{ - struct jbd2_revoke_record_s *record; - - record = find_revoke_record(journal, blocknr); - if (record) { - /* If we have multiple occurrences, only record the - * latest sequence number in the hashed record */ - if (tid_gt(sequence, record->sequence)) - record->sequence = sequence; - return 0; - } - return insert_revoke_hash(journal, blocknr, sequence); -} - -/* - * Test revoke records. For a given block referenced in the log, has - * that block been revoked? A revoke record with a given transaction - * sequence number revokes all blocks in that transaction and earlier - * ones, but later transactions still need replayed. - */ - -int jbd2_journal_test_revoke(journal_t *journal, - unsigned long long blocknr, - tid_t sequence) -{ - struct jbd2_revoke_record_s *record; - - record = find_revoke_record(journal, blocknr); - if (!record) - return 0; - if (tid_gt(sequence, record->sequence)) - return 0; - return 1; -} - -/* - * Finally, once recovery is over, we need to clear the revoke table so - * that it can be reused by the running filesystem. - */ - -void jbd2_journal_clear_revoke(journal_t *journal) -{ - int i; - struct list_head *hash_list; - struct jbd2_revoke_record_s *record; - struct jbd2_revoke_table_s *revoke; - - revoke = journal->j_revoke; - - for (i = 0; i < revoke->hash_size; i++) { - hash_list = &revoke->hash_table[i]; - while (!list_empty(hash_list)) { - record = (struct jbd2_revoke_record_s*) hash_list->next; - list_del(&record->hash); - kmem_cache_free(jbd2_revoke_record_cache, record); - } - } -} diff --git a/trunk/fs/jbd2/transaction.c b/trunk/fs/jbd2/transaction.c deleted file mode 100644 index c051a94c8a97..000000000000 --- a/trunk/fs/jbd2/transaction.c +++ /dev/null @@ -1,2094 +0,0 @@ -/* - * linux/fs/transaction.c - * - * Written by Stephen C. Tweedie , 1998 - * - * Copyright 1998 Red Hat corp --- All Rights Reserved - * - * This file is part of the Linux kernel and is made available under - * the terms of the GNU General Public License, version 2, or at your - * option, any later version, incorporated herein by reference. - * - * Generic filesystem transaction handling code; part of the ext2fs - * journaling system. - * - * This file manages transactions (compound commits managed by the - * journaling code) and handles (individual atomic operations by the - * filesystem). - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * jbd2_get_transaction: obtain a new transaction_t object. - * - * Simply allocate and initialise a new transaction. Create it in - * RUNNING state and add it to the current journal (which should not - * have an existing running transaction: we only make a new transaction - * once we have started to commit the old one). - * - * Preconditions: - * The journal MUST be locked. We don't perform atomic mallocs on the - * new transaction and we can't block without protecting against other - * processes trying to touch the journal while it is in transition. - * - * Called under j_state_lock - */ - -static transaction_t * -jbd2_get_transaction(journal_t *journal, transaction_t *transaction) -{ - transaction->t_journal = journal; - transaction->t_state = T_RUNNING; - transaction->t_tid = journal->j_transaction_sequence++; - transaction->t_expires = jiffies + journal->j_commit_interval; - spin_lock_init(&transaction->t_handle_lock); - - /* Set up the commit timer for the new transaction. */ - journal->j_commit_timer.expires = transaction->t_expires; - add_timer(&journal->j_commit_timer); - - J_ASSERT(journal->j_running_transaction == NULL); - journal->j_running_transaction = transaction; - - return transaction; -} - -/* - * Handle management. - * - * A handle_t is an object which represents a single atomic update to a - * filesystem, and which tracks all of the modifications which form part - * of that one update. - */ - -/* - * start_this_handle: Given a handle, deal with any locking or stalling - * needed to make sure that there is enough journal space for the handle - * to begin. Attach the handle to a transaction and set up the - * transaction's buffer credits. - */ - -static int start_this_handle(journal_t *journal, handle_t *handle) -{ - transaction_t *transaction; - int needed; - int nblocks = handle->h_buffer_credits; - transaction_t *new_transaction = NULL; - int ret = 0; - - if (nblocks > journal->j_max_transaction_buffers) { - printk(KERN_ERR "JBD: %s wants too many credits (%d > %d)\n", - current->comm, nblocks, - journal->j_max_transaction_buffers); - ret = -ENOSPC; - goto out; - } - -alloc_transaction: - if (!journal->j_running_transaction) { - new_transaction = jbd_kmalloc(sizeof(*new_transaction), - GFP_NOFS); - if (!new_transaction) { - ret = -ENOMEM; - goto out; - } - memset(new_transaction, 0, sizeof(*new_transaction)); - } - - jbd_debug(3, "New handle %p going live.\n", handle); - -repeat: - - /* - * We need to hold j_state_lock until t_updates has been incremented, - * for proper journal barrier handling - */ - spin_lock(&journal->j_state_lock); -repeat_locked: - if (is_journal_aborted(journal) || - (journal->j_errno != 0 && !(journal->j_flags & JBD2_ACK_ERR))) { - spin_unlock(&journal->j_state_lock); - ret = -EROFS; - goto out; - } - - /* Wait on the journal's transaction barrier if necessary */ - if (journal->j_barrier_count) { - spin_unlock(&journal->j_state_lock); - wait_event(journal->j_wait_transaction_locked, - journal->j_barrier_count == 0); - goto repeat; - } - - if (!journal->j_running_transaction) { - if (!new_transaction) { - spin_unlock(&journal->j_state_lock); - goto alloc_transaction; - } - jbd2_get_transaction(journal, new_transaction); - new_transaction = NULL; - } - - transaction = journal->j_running_transaction; - - /* - * If the current transaction is locked down for commit, wait for the - * lock to be released. - */ - if (transaction->t_state == T_LOCKED) { - DEFINE_WAIT(wait); - - prepare_to_wait(&journal->j_wait_transaction_locked, - &wait, TASK_UNINTERRUPTIBLE); - spin_unlock(&journal->j_state_lock); - schedule(); - finish_wait(&journal->j_wait_transaction_locked, &wait); - goto repeat; - } - - /* - * If there is not enough space left in the log to write all potential - * buffers requested by this operation, we need to stall pending a log - * checkpoint to free some more log space. - */ - spin_lock(&transaction->t_handle_lock); - needed = transaction->t_outstanding_credits + nblocks; - - if (needed > journal->j_max_transaction_buffers) { - /* - * If the current transaction is already too large, then start - * to commit it: we can then go back and attach this handle to - * a new transaction. - */ - DEFINE_WAIT(wait); - - jbd_debug(2, "Handle %p starting new commit...\n", handle); - spin_unlock(&transaction->t_handle_lock); - prepare_to_wait(&journal->j_wait_transaction_locked, &wait, - TASK_UNINTERRUPTIBLE); - __jbd2_log_start_commit(journal, transaction->t_tid); - spin_unlock(&journal->j_state_lock); - schedule(); - finish_wait(&journal->j_wait_transaction_locked, &wait); - goto repeat; - } - - /* - * The commit code assumes that it can get enough log space - * without forcing a checkpoint. This is *critical* for - * correctness: a checkpoint of a buffer which is also - * associated with a committing transaction creates a deadlock, - * so commit simply cannot force through checkpoints. - * - * We must therefore ensure the necessary space in the journal - * *before* starting to dirty potentially checkpointed buffers - * in the new transaction. - * - * The worst part is, any transaction currently committing can - * reduce the free space arbitrarily. Be careful to account for - * those buffers when checkpointing. - */ - - /* - * @@@ AKPM: This seems rather over-defensive. We're giving commit - * a _lot_ of headroom: 1/4 of the journal plus the size of - * the committing transaction. Really, we only need to give it - * committing_transaction->t_outstanding_credits plus "enough" for - * the log control blocks. - * Also, this test is inconsitent with the matching one in - * jbd2_journal_extend(). - */ - if (__jbd2_log_space_left(journal) < jbd_space_needed(journal)) { - jbd_debug(2, "Handle %p waiting for checkpoint...\n", handle); - spin_unlock(&transaction->t_handle_lock); - __jbd2_log_wait_for_space(journal); - goto repeat_locked; - } - - /* OK, account for the buffers that this operation expects to - * use and add the handle to the running transaction. */ - - handle->h_transaction = transaction; - transaction->t_outstanding_credits += nblocks; - transaction->t_updates++; - transaction->t_handle_count++; - jbd_debug(4, "Handle %p given %d credits (total %d, free %d)\n", - handle, nblocks, transaction->t_outstanding_credits, - __jbd2_log_space_left(journal)); - spin_unlock(&transaction->t_handle_lock); - spin_unlock(&journal->j_state_lock); -out: - if (unlikely(new_transaction)) /* It's usually NULL */ - kfree(new_transaction); - return ret; -} - -/* Allocate a new handle. This should probably be in a slab... */ -static handle_t *new_handle(int nblocks) -{ - handle_t *handle = jbd_alloc_handle(GFP_NOFS); - if (!handle) - return NULL; - memset(handle, 0, sizeof(*handle)); - handle->h_buffer_credits = nblocks; - handle->h_ref = 1; - - return handle; -} - -/** - * handle_t *jbd2_journal_start() - Obtain a new handle. - * @journal: Journal to start transaction on. - * @nblocks: number of block buffer we might modify - * - * We make sure that the transaction can guarantee at least nblocks of - * modified buffers in the log. We block until the log can guarantee - * that much space. - * - * This function is visible to journal users (like ext3fs), so is not - * called with the journal already locked. - * - * Return a pointer to a newly allocated handle, or NULL on failure - */ -handle_t *jbd2_journal_start(journal_t *journal, int nblocks) -{ - handle_t *handle = journal_current_handle(); - int err; - - if (!journal) - return ERR_PTR(-EROFS); - - if (handle) { - J_ASSERT(handle->h_transaction->t_journal == journal); - handle->h_ref++; - return handle; - } - - handle = new_handle(nblocks); - if (!handle) - return ERR_PTR(-ENOMEM); - - current->journal_info = handle; - - err = start_this_handle(journal, handle); - if (err < 0) { - jbd_free_handle(handle); - current->journal_info = NULL; - handle = ERR_PTR(err); - } - return handle; -} - -/** - * int jbd2_journal_extend() - extend buffer credits. - * @handle: handle to 'extend' - * @nblocks: nr blocks to try to extend by. - * - * Some transactions, such as large extends and truncates, can be done - * atomically all at once or in several stages. The operation requests - * a credit for a number of buffer modications in advance, but can - * extend its credit if it needs more. - * - * jbd2_journal_extend tries to give the running handle more buffer credits. - * It does not guarantee that allocation - this is a best-effort only. - * The calling process MUST be able to deal cleanly with a failure to - * extend here. - * - * Return 0 on success, non-zero on failure. - * - * return code < 0 implies an error - * return code > 0 implies normal transaction-full status. - */ -int jbd2_journal_extend(handle_t *handle, int nblocks) -{ - transaction_t *transaction = handle->h_transaction; - journal_t *journal = transaction->t_journal; - int result; - int wanted; - - result = -EIO; - if (is_handle_aborted(handle)) - goto out; - - result = 1; - - spin_lock(&journal->j_state_lock); - - /* Don't extend a locked-down transaction! */ - if (handle->h_transaction->t_state != T_RUNNING) { - jbd_debug(3, "denied handle %p %d blocks: " - "transaction not running\n", handle, nblocks); - goto error_out; - } - - spin_lock(&transaction->t_handle_lock); - wanted = transaction->t_outstanding_credits + nblocks; - - if (wanted > journal->j_max_transaction_buffers) { - jbd_debug(3, "denied handle %p %d blocks: " - "transaction too large\n", handle, nblocks); - goto unlock; - } - - if (wanted > __jbd2_log_space_left(journal)) { - jbd_debug(3, "denied handle %p %d blocks: " - "insufficient log space\n", handle, nblocks); - goto unlock; - } - - handle->h_buffer_credits += nblocks; - transaction->t_outstanding_credits += nblocks; - result = 0; - - jbd_debug(3, "extended handle %p by %d\n", handle, nblocks); -unlock: - spin_unlock(&transaction->t_handle_lock); -error_out: - spin_unlock(&journal->j_state_lock); -out: - return result; -} - - -/** - * int jbd2_journal_restart() - restart a handle . - * @handle: handle to restart - * @nblocks: nr credits requested - * - * Restart a handle for a multi-transaction filesystem - * operation. - * - * If the jbd2_journal_extend() call above fails to grant new buffer credits - * to a running handle, a call to jbd2_journal_restart will commit the - * handle's transaction so far and reattach the handle to a new - * transaction capabable of guaranteeing the requested number of - * credits. - */ - -int jbd2_journal_restart(handle_t *handle, int nblocks) -{ - transaction_t *transaction = handle->h_transaction; - journal_t *journal = transaction->t_journal; - int ret; - - /* If we've had an abort of any type, don't even think about - * actually doing the restart! */ - if (is_handle_aborted(handle)) - return 0; - - /* - * First unlink the handle from its current transaction, and start the - * commit on that. - */ - J_ASSERT(transaction->t_updates > 0); - J_ASSERT(journal_current_handle() == handle); - - spin_lock(&journal->j_state_lock); - spin_lock(&transaction->t_handle_lock); - transaction->t_outstanding_credits -= handle->h_buffer_credits; - transaction->t_updates--; - - if (!transaction->t_updates) - wake_up(&journal->j_wait_updates); - spin_unlock(&transaction->t_handle_lock); - - jbd_debug(2, "restarting handle %p\n", handle); - __jbd2_log_start_commit(journal, transaction->t_tid); - spin_unlock(&journal->j_state_lock); - - handle->h_buffer_credits = nblocks; - ret = start_this_handle(journal, handle); - return ret; -} - - -/** - * void jbd2_journal_lock_updates () - establish a transaction barrier. - * @journal: Journal to establish a barrier on. - * - * This locks out any further updates from being started, and blocks - * until all existing updates have completed, returning only once the - * journal is in a quiescent state with no updates running. - * - * The journal lock should not be held on entry. - */ -void jbd2_journal_lock_updates(journal_t *journal) -{ - DEFINE_WAIT(wait); - - spin_lock(&journal->j_state_lock); - ++journal->j_barrier_count; - - /* Wait until there are no running updates */ - while (1) { - transaction_t *transaction = journal->j_running_transaction; - - if (!transaction) - break; - - spin_lock(&transaction->t_handle_lock); - if (!transaction->t_updates) { - spin_unlock(&transaction->t_handle_lock); - break; - } - prepare_to_wait(&journal->j_wait_updates, &wait, - TASK_UNINTERRUPTIBLE); - spin_unlock(&transaction->t_handle_lock); - spin_unlock(&journal->j_state_lock); - schedule(); - finish_wait(&journal->j_wait_updates, &wait); - spin_lock(&journal->j_state_lock); - } - spin_unlock(&journal->j_state_lock); - - /* - * We have now established a barrier against other normal updates, but - * we also need to barrier against other jbd2_journal_lock_updates() calls - * to make sure that we serialise special journal-locked operations - * too. - */ - mutex_lock(&journal->j_barrier); -} - -/** - * void jbd2_journal_unlock_updates (journal_t* journal) - release barrier - * @journal: Journal to release the barrier on. - * - * Release a transaction barrier obtained with jbd2_journal_lock_updates(). - * - * Should be called without the journal lock held. - */ -void jbd2_journal_unlock_updates (journal_t *journal) -{ - J_ASSERT(journal->j_barrier_count != 0); - - mutex_unlock(&journal->j_barrier); - spin_lock(&journal->j_state_lock); - --journal->j_barrier_count; - spin_unlock(&journal->j_state_lock); - wake_up(&journal->j_wait_transaction_locked); -} - -/* - * Report any unexpected dirty buffers which turn up. Normally those - * indicate an error, but they can occur if the user is running (say) - * tune2fs to modify the live filesystem, so we need the option of - * continuing as gracefully as possible. # - * - * The caller should already hold the journal lock and - * j_list_lock spinlock: most callers will need those anyway - * in order to probe the buffer's journaling state safely. - */ -static void jbd_unexpected_dirty_buffer(struct journal_head *jh) -{ - int jlist; - - /* If this buffer is one which might reasonably be dirty - * --- ie. data, or not part of this journal --- then - * we're OK to leave it alone, but otherwise we need to - * move the dirty bit to the journal's own internal - * JBDDirty bit. */ - jlist = jh->b_jlist; - - if (jlist == BJ_Metadata || jlist == BJ_Reserved || - jlist == BJ_Shadow || jlist == BJ_Forget) { - struct buffer_head *bh = jh2bh(jh); - - if (test_clear_buffer_dirty(bh)) - set_buffer_jbddirty(bh); - } -} - -/* - * If the buffer is already part of the current transaction, then there - * is nothing we need to do. If it is already part of a prior - * transaction which we are still committing to disk, then we need to - * make sure that we do not overwrite the old copy: we do copy-out to - * preserve the copy going to disk. We also account the buffer against - * the handle's metadata buffer credits (unless the buffer is already - * part of the transaction, that is). - * - */ -static int -do_get_write_access(handle_t *handle, struct journal_head *jh, - int force_copy) -{ - struct buffer_head *bh; - transaction_t *transaction; - journal_t *journal; - int error; - char *frozen_buffer = NULL; - int need_copy = 0; - - if (is_handle_aborted(handle)) - return -EROFS; - - transaction = handle->h_transaction; - journal = transaction->t_journal; - - jbd_debug(5, "buffer_head %p, force_copy %d\n", jh, force_copy); - - JBUFFER_TRACE(jh, "entry"); -repeat: - bh = jh2bh(jh); - - /* @@@ Need to check for errors here at some point. */ - - lock_buffer(bh); - jbd_lock_bh_state(bh); - - /* We now hold the buffer lock so it is safe to query the buffer - * state. Is the buffer dirty? - * - * If so, there are two possibilities. The buffer may be - * non-journaled, and undergoing a quite legitimate writeback. - * Otherwise, it is journaled, and we don't expect dirty buffers - * in that state (the buffers should be marked JBD_Dirty - * instead.) So either the IO is being done under our own - * control and this is a bug, or it's a third party IO such as - * dump(8) (which may leave the buffer scheduled for read --- - * ie. locked but not dirty) or tune2fs (which may actually have - * the buffer dirtied, ugh.) */ - - if (buffer_dirty(bh)) { - /* - * First question: is this buffer already part of the current - * transaction or the existing committing transaction? - */ - if (jh->b_transaction) { - J_ASSERT_JH(jh, - jh->b_transaction == transaction || - jh->b_transaction == - journal->j_committing_transaction); - if (jh->b_next_transaction) - J_ASSERT_JH(jh, jh->b_next_transaction == - transaction); - } - /* - * In any case we need to clean the dirty flag and we must - * do it under the buffer lock to be sure we don't race - * with running write-out. - */ - JBUFFER_TRACE(jh, "Unexpected dirty buffer"); - jbd_unexpected_dirty_buffer(jh); - } - - unlock_buffer(bh); - - error = -EROFS; - if (is_handle_aborted(handle)) { - jbd_unlock_bh_state(bh); - goto out; - } - error = 0; - - /* - * The buffer is already part of this transaction if b_transaction or - * b_next_transaction points to it - */ - if (jh->b_transaction == transaction || - jh->b_next_transaction == transaction) - goto done; - - /* - * If there is already a copy-out version of this buffer, then we don't - * need to make another one - */ - if (jh->b_frozen_data) { - JBUFFER_TRACE(jh, "has frozen data"); - J_ASSERT_JH(jh, jh->b_next_transaction == NULL); - jh->b_next_transaction = transaction; - goto done; - } - - /* Is there data here we need to preserve? */ - - if (jh->b_transaction && jh->b_transaction != transaction) { - JBUFFER_TRACE(jh, "owned by older transaction"); - J_ASSERT_JH(jh, jh->b_next_transaction == NULL); - J_ASSERT_JH(jh, jh->b_transaction == - journal->j_committing_transaction); - - /* There is one case we have to be very careful about. - * If the committing transaction is currently writing - * this buffer out to disk and has NOT made a copy-out, - * then we cannot modify the buffer contents at all - * right now. The essence of copy-out is that it is the - * extra copy, not the primary copy, which gets - * journaled. If the primary copy is already going to - * disk then we cannot do copy-out here. */ - - if (jh->b_jlist == BJ_Shadow) { - DEFINE_WAIT_BIT(wait, &bh->b_state, BH_Unshadow); - wait_queue_head_t *wqh; - - wqh = bit_waitqueue(&bh->b_state, BH_Unshadow); - - JBUFFER_TRACE(jh, "on shadow: sleep"); - jbd_unlock_bh_state(bh); - /* commit wakes up all shadow buffers after IO */ - for ( ; ; ) { - prepare_to_wait(wqh, &wait.wait, - TASK_UNINTERRUPTIBLE); - if (jh->b_jlist != BJ_Shadow) - break; - schedule(); - } - finish_wait(wqh, &wait.wait); - goto repeat; - } - - /* Only do the copy if the currently-owning transaction - * still needs it. If it is on the Forget list, the - * committing transaction is past that stage. The - * buffer had better remain locked during the kmalloc, - * but that should be true --- we hold the journal lock - * still and the buffer is already on the BUF_JOURNAL - * list so won't be flushed. - * - * Subtle point, though: if this is a get_undo_access, - * then we will be relying on the frozen_data to contain - * the new value of the committed_data record after the - * transaction, so we HAVE to force the frozen_data copy - * in that case. */ - - if (jh->b_jlist != BJ_Forget || force_copy) { - JBUFFER_TRACE(jh, "generate frozen data"); - if (!frozen_buffer) { - JBUFFER_TRACE(jh, "allocate memory for buffer"); - jbd_unlock_bh_state(bh); - frozen_buffer = - jbd2_slab_alloc(jh2bh(jh)->b_size, - GFP_NOFS); - if (!frozen_buffer) { - printk(KERN_EMERG - "%s: OOM for frozen_buffer\n", - __FUNCTION__); - JBUFFER_TRACE(jh, "oom!"); - error = -ENOMEM; - jbd_lock_bh_state(bh); - goto done; - } - goto repeat; - } - jh->b_frozen_data = frozen_buffer; - frozen_buffer = NULL; - need_copy = 1; - } - jh->b_next_transaction = transaction; - } - - - /* - * Finally, if the buffer is not journaled right now, we need to make - * sure it doesn't get written to disk before the caller actually - * commits the new data - */ - if (!jh->b_transaction) { - JBUFFER_TRACE(jh, "no transaction"); - J_ASSERT_JH(jh, !jh->b_next_transaction); - jh->b_transaction = transaction; - JBUFFER_TRACE(jh, "file as BJ_Reserved"); - spin_lock(&journal->j_list_lock); - __jbd2_journal_file_buffer(jh, transaction, BJ_Reserved); - spin_unlock(&journal->j_list_lock); - } - -done: - if (need_copy) { - struct page *page; - int offset; - char *source; - - J_EXPECT_JH(jh, buffer_uptodate(jh2bh(jh)), - "Possible IO failure.\n"); - page = jh2bh(jh)->b_page; - offset = ((unsigned long) jh2bh(jh)->b_data) & ~PAGE_MASK; - source = kmap_atomic(page, KM_USER0); - memcpy(jh->b_frozen_data, source+offset, jh2bh(jh)->b_size); - kunmap_atomic(source, KM_USER0); - } - jbd_unlock_bh_state(bh); - - /* - * If we are about to journal a buffer, then any revoke pending on it is - * no longer valid - */ - jbd2_journal_cancel_revoke(handle, jh); - -out: - if (unlikely(frozen_buffer)) /* It's usually NULL */ - jbd2_slab_free(frozen_buffer, bh->b_size); - - JBUFFER_TRACE(jh, "exit"); - return error; -} - -/** - * int jbd2_journal_get_write_access() - notify intent to modify a buffer for metadata (not data) update. - * @handle: transaction to add buffer modifications to - * @bh: bh to be used for metadata writes - * @credits: variable that will receive credits for the buffer - * - * Returns an error code or 0 on success. - * - * In full data journalling mode the buffer may be of type BJ_AsyncData, - * because we're write()ing a buffer which is also part of a shared mapping. - */ - -int jbd2_journal_get_write_access(handle_t *handle, struct buffer_head *bh) -{ - struct journal_head *jh = jbd2_journal_add_journal_head(bh); - int rc; - - /* We do not want to get caught playing with fields which the - * log thread also manipulates. Make sure that the buffer - * completes any outstanding IO before proceeding. */ - rc = do_get_write_access(handle, jh, 0); - jbd2_journal_put_journal_head(jh); - return rc; -} - - -/* - * When the user wants to journal a newly created buffer_head - * (ie. getblk() returned a new buffer and we are going to populate it - * manually rather than reading off disk), then we need to keep the - * buffer_head locked until it has been completely filled with new - * data. In this case, we should be able to make the assertion that - * the bh is not already part of an existing transaction. - * - * The buffer should already be locked by the caller by this point. - * There is no lock ranking violation: it was a newly created, - * unlocked buffer beforehand. */ - -/** - * int jbd2_journal_get_create_access () - notify intent to use newly created bh - * @handle: transaction to new buffer to - * @bh: new buffer. - * - * Call this if you create a new bh. - */ -int jbd2_journal_get_create_access(handle_t *handle, struct buffer_head *bh) -{ - transaction_t *transaction = handle->h_transaction; - journal_t *journal = transaction->t_journal; - struct journal_head *jh = jbd2_journal_add_journal_head(bh); - int err; - - jbd_debug(5, "journal_head %p\n", jh); - err = -EROFS; - if (is_handle_aborted(handle)) - goto out; - err = 0; - - JBUFFER_TRACE(jh, "entry"); - /* - * The buffer may already belong to this transaction due to pre-zeroing - * in the filesystem's new_block code. It may also be on the previous, - * committing transaction's lists, but it HAS to be in Forget state in - * that case: the transaction must have deleted the buffer for it to be - * reused here. - */ - jbd_lock_bh_state(bh); - spin_lock(&journal->j_list_lock); - J_ASSERT_JH(jh, (jh->b_transaction == transaction || - jh->b_transaction == NULL || - (jh->b_transaction == journal->j_committing_transaction && - jh->b_jlist == BJ_Forget))); - - J_ASSERT_JH(jh, jh->b_next_transaction == NULL); - J_ASSERT_JH(jh, buffer_locked(jh2bh(jh))); - - if (jh->b_transaction == NULL) { - jh->b_transaction = transaction; - JBUFFER_TRACE(jh, "file as BJ_Reserved"); - __jbd2_journal_file_buffer(jh, transaction, BJ_Reserved); - } else if (jh->b_transaction == journal->j_committing_transaction) { - JBUFFER_TRACE(jh, "set next transaction"); - jh->b_next_transaction = transaction; - } - spin_unlock(&journal->j_list_lock); - jbd_unlock_bh_state(bh); - - /* - * akpm: I added this. ext3_alloc_branch can pick up new indirect - * blocks which contain freed but then revoked metadata. We need - * to cancel the revoke in case we end up freeing it yet again - * and the reallocating as data - this would cause a second revoke, - * which hits an assertion error. - */ - JBUFFER_TRACE(jh, "cancelling revoke"); - jbd2_journal_cancel_revoke(handle, jh); - jbd2_journal_put_journal_head(jh); -out: - return err; -} - -/** - * int jbd2_journal_get_undo_access() - Notify intent to modify metadata with - * non-rewindable consequences - * @handle: transaction - * @bh: buffer to undo - * @credits: store the number of taken credits here (if not NULL) - * - * Sometimes there is a need to distinguish between metadata which has - * been committed to disk and that which has not. The ext3fs code uses - * this for freeing and allocating space, we have to make sure that we - * do not reuse freed space until the deallocation has been committed, - * since if we overwrote that space we would make the delete - * un-rewindable in case of a crash. - * - * To deal with that, jbd2_journal_get_undo_access requests write access to a - * buffer for parts of non-rewindable operations such as delete - * operations on the bitmaps. The journaling code must keep a copy of - * the buffer's contents prior to the undo_access call until such time - * as we know that the buffer has definitely been committed to disk. - * - * We never need to know which transaction the committed data is part - * of, buffers touched here are guaranteed to be dirtied later and so - * will be committed to a new transaction in due course, at which point - * we can discard the old committed data pointer. - * - * Returns error number or 0 on success. - */ -int jbd2_journal_get_undo_access(handle_t *handle, struct buffer_head *bh) -{ - int err; - struct journal_head *jh = jbd2_journal_add_journal_head(bh); - char *committed_data = NULL; - - JBUFFER_TRACE(jh, "entry"); - - /* - * Do this first --- it can drop the journal lock, so we want to - * make sure that obtaining the committed_data is done - * atomically wrt. completion of any outstanding commits. - */ - err = do_get_write_access(handle, jh, 1); - if (err) - goto out; - -repeat: - if (!jh->b_committed_data) { - committed_data = jbd2_slab_alloc(jh2bh(jh)->b_size, GFP_NOFS); - if (!committed_data) { - printk(KERN_EMERG "%s: No memory for committed data\n", - __FUNCTION__); - err = -ENOMEM; - goto out; - } - } - - jbd_lock_bh_state(bh); - if (!jh->b_committed_data) { - /* Copy out the current buffer contents into the - * preserved, committed copy. */ - JBUFFER_TRACE(jh, "generate b_committed data"); - if (!committed_data) { - jbd_unlock_bh_state(bh); - goto repeat; - } - - jh->b_committed_data = committed_data; - committed_data = NULL; - memcpy(jh->b_committed_data, bh->b_data, bh->b_size); - } - jbd_unlock_bh_state(bh); -out: - jbd2_journal_put_journal_head(jh); - if (unlikely(committed_data)) - jbd2_slab_free(committed_data, bh->b_size); - return err; -} - -/** - * int jbd2_journal_dirty_data() - mark a buffer as containing dirty data which - * needs to be flushed before we can commit the - * current transaction. - * @handle: transaction - * @bh: bufferhead to mark - * - * The buffer is placed on the transaction's data list and is marked as - * belonging to the transaction. - * - * Returns error number or 0 on success. - * - * jbd2_journal_dirty_data() can be called via page_launder->ext3_writepage - * by kswapd. - */ -int jbd2_journal_dirty_data(handle_t *handle, struct buffer_head *bh) -{ - journal_t *journal = handle->h_transaction->t_journal; - int need_brelse = 0; - struct journal_head *jh; - - if (is_handle_aborted(handle)) - return 0; - - jh = jbd2_journal_add_journal_head(bh); - JBUFFER_TRACE(jh, "entry"); - - /* - * The buffer could *already* be dirty. Writeout can start - * at any time. - */ - jbd_debug(4, "jh: %p, tid:%d\n", jh, handle->h_transaction->t_tid); - - /* - * What if the buffer is already part of a running transaction? - * - * There are two cases: - * 1) It is part of the current running transaction. Refile it, - * just in case we have allocated it as metadata, deallocated - * it, then reallocated it as data. - * 2) It is part of the previous, still-committing transaction. - * If all we want to do is to guarantee that the buffer will be - * written to disk before this new transaction commits, then - * being sure that the *previous* transaction has this same - * property is sufficient for us! Just leave it on its old - * transaction. - * - * In case (2), the buffer must not already exist as metadata - * --- that would violate write ordering (a transaction is free - * to write its data at any point, even before the previous - * committing transaction has committed). The caller must - * never, ever allow this to happen: there's nothing we can do - * about it in this layer. - */ - jbd_lock_bh_state(bh); - spin_lock(&journal->j_list_lock); - - /* Now that we have bh_state locked, are we really still mapped? */ - if (!buffer_mapped(bh)) { - JBUFFER_TRACE(jh, "unmapped buffer, bailing out"); - goto no_journal; - } - - if (jh->b_transaction) { - JBUFFER_TRACE(jh, "has transaction"); - if (jh->b_transaction != handle->h_transaction) { - JBUFFER_TRACE(jh, "belongs to older transaction"); - J_ASSERT_JH(jh, jh->b_transaction == - journal->j_committing_transaction); - - /* @@@ IS THIS TRUE ? */ - /* - * Not any more. Scenario: someone does a write() - * in data=journal mode. The buffer's transaction has - * moved into commit. Then someone does another - * write() to the file. We do the frozen data copyout - * and set b_next_transaction to point to j_running_t. - * And while we're in that state, someone does a - * writepage() in an attempt to pageout the same area - * of the file via a shared mapping. At present that - * calls jbd2_journal_dirty_data(), and we get right here. - * It may be too late to journal the data. Simply - * falling through to the next test will suffice: the - * data will be dirty and wil be checkpointed. The - * ordering comments in the next comment block still - * apply. - */ - //J_ASSERT_JH(jh, jh->b_next_transaction == NULL); - - /* - * If we're journalling data, and this buffer was - * subject to a write(), it could be metadata, forget - * or shadow against the committing transaction. Now, - * someone has dirtied the same darn page via a mapping - * and it is being writepage()'d. - * We *could* just steal the page from commit, with some - * fancy locking there. Instead, we just skip it - - * don't tie the page's buffers to the new transaction - * at all. - * Implication: if we crash before the writepage() data - * is written into the filesystem, recovery will replay - * the write() data. - */ - if (jh->b_jlist != BJ_None && - jh->b_jlist != BJ_SyncData && - jh->b_jlist != BJ_Locked) { - JBUFFER_TRACE(jh, "Not stealing"); - goto no_journal; - } - - /* - * This buffer may be undergoing writeout in commit. We - * can't return from here and let the caller dirty it - * again because that can cause the write-out loop in - * commit to never terminate. - */ - if (buffer_dirty(bh)) { - get_bh(bh); - spin_unlock(&journal->j_list_lock); - jbd_unlock_bh_state(bh); - need_brelse = 1; - sync_dirty_buffer(bh); - jbd_lock_bh_state(bh); - spin_lock(&journal->j_list_lock); - /* Since we dropped the lock... */ - if (!buffer_mapped(bh)) { - JBUFFER_TRACE(jh, "buffer got unmapped"); - goto no_journal; - } - /* The buffer may become locked again at any - time if it is redirtied */ - } - - /* journal_clean_data_list() may have got there first */ - if (jh->b_transaction != NULL) { - JBUFFER_TRACE(jh, "unfile from commit"); - __jbd2_journal_temp_unlink_buffer(jh); - /* It still points to the committing - * transaction; move it to this one so - * that the refile assert checks are - * happy. */ - jh->b_transaction = handle->h_transaction; - } - /* The buffer will be refiled below */ - - } - /* - * Special case --- the buffer might actually have been - * allocated and then immediately deallocated in the previous, - * committing transaction, so might still be left on that - * transaction's metadata lists. - */ - if (jh->b_jlist != BJ_SyncData && jh->b_jlist != BJ_Locked) { - JBUFFER_TRACE(jh, "not on correct data list: unfile"); - J_ASSERT_JH(jh, jh->b_jlist != BJ_Shadow); - __jbd2_journal_temp_unlink_buffer(jh); - jh->b_transaction = handle->h_transaction; - JBUFFER_TRACE(jh, "file as data"); - __jbd2_journal_file_buffer(jh, handle->h_transaction, - BJ_SyncData); - } - } else { - JBUFFER_TRACE(jh, "not on a transaction"); - __jbd2_journal_file_buffer(jh, handle->h_transaction, BJ_SyncData); - } -no_journal: - spin_unlock(&journal->j_list_lock); - jbd_unlock_bh_state(bh); - if (need_brelse) { - BUFFER_TRACE(bh, "brelse"); - __brelse(bh); - } - JBUFFER_TRACE(jh, "exit"); - jbd2_journal_put_journal_head(jh); - return 0; -} - -/** - * int jbd2_journal_dirty_metadata() - mark a buffer as containing dirty metadata - * @handle: transaction to add buffer to. - * @bh: buffer to mark - * - * mark dirty metadata which needs to be journaled as part of the current - * transaction. - * - * The buffer is placed on the transaction's metadata list and is marked - * as belonging to the transaction. - * - * Returns error number or 0 on success. - * - * Special care needs to be taken if the buffer already belongs to the - * current committing transaction (in which case we should have frozen - * data present for that commit). In that case, we don't relink the - * buffer: that only gets done when the old transaction finally - * completes its commit. - */ -int jbd2_journal_dirty_metadata(handle_t *handle, struct buffer_head *bh) -{ - transaction_t *transaction = handle->h_transaction; - journal_t *journal = transaction->t_journal; - struct journal_head *jh = bh2jh(bh); - - jbd_debug(5, "journal_head %p\n", jh); - JBUFFER_TRACE(jh, "entry"); - if (is_handle_aborted(handle)) - goto out; - - jbd_lock_bh_state(bh); - - if (jh->b_modified == 0) { - /* - * This buffer's got modified and becoming part - * of the transaction. This needs to be done - * once a transaction -bzzz - */ - jh->b_modified = 1; - J_ASSERT_JH(jh, handle->h_buffer_credits > 0); - handle->h_buffer_credits--; - } - - /* - * fastpath, to avoid expensive locking. If this buffer is already - * on the running transaction's metadata list there is nothing to do. - * Nobody can take it off again because there is a handle open. - * I _think_ we're OK here with SMP barriers - a mistaken decision will - * result in this test being false, so we go in and take the locks. - */ - if (jh->b_transaction == transaction && jh->b_jlist == BJ_Metadata) { - JBUFFER_TRACE(jh, "fastpath"); - J_ASSERT_JH(jh, jh->b_transaction == - journal->j_running_transaction); - goto out_unlock_bh; - } - - set_buffer_jbddirty(bh); - - /* - * Metadata already on the current transaction list doesn't - * need to be filed. Metadata on another transaction's list must - * be committing, and will be refiled once the commit completes: - * leave it alone for now. - */ - if (jh->b_transaction != transaction) { - JBUFFER_TRACE(jh, "already on other transaction"); - J_ASSERT_JH(jh, jh->b_transaction == - journal->j_committing_transaction); - J_ASSERT_JH(jh, jh->b_next_transaction == transaction); - /* And this case is illegal: we can't reuse another - * transaction's data buffer, ever. */ - goto out_unlock_bh; - } - - /* That test should have eliminated the following case: */ - J_ASSERT_JH(jh, jh->b_frozen_data == 0); - - JBUFFER_TRACE(jh, "file as BJ_Metadata"); - spin_lock(&journal->j_list_lock); - __jbd2_journal_file_buffer(jh, handle->h_transaction, BJ_Metadata); - spin_unlock(&journal->j_list_lock); -out_unlock_bh: - jbd_unlock_bh_state(bh); -out: - JBUFFER_TRACE(jh, "exit"); - return 0; -} - -/* - * jbd2_journal_release_buffer: undo a get_write_access without any buffer - * updates, if the update decided in the end that it didn't need access. - * - */ -void -jbd2_journal_release_buffer(handle_t *handle, struct buffer_head *bh) -{ - BUFFER_TRACE(bh, "entry"); -} - -/** - * void jbd2_journal_forget() - bforget() for potentially-journaled buffers. - * @handle: transaction handle - * @bh: bh to 'forget' - * - * We can only do the bforget if there are no commits pending against the - * buffer. If the buffer is dirty in the current running transaction we - * can safely unlink it. - * - * bh may not be a journalled buffer at all - it may be a non-JBD - * buffer which came off the hashtable. Check for this. - * - * Decrements bh->b_count by one. - * - * Allow this call even if the handle has aborted --- it may be part of - * the caller's cleanup after an abort. - */ -int jbd2_journal_forget (handle_t *handle, struct buffer_head *bh) -{ - transaction_t *transaction = handle->h_transaction; - journal_t *journal = transaction->t_journal; - struct journal_head *jh; - int drop_reserve = 0; - int err = 0; - - BUFFER_TRACE(bh, "entry"); - - jbd_lock_bh_state(bh); - spin_lock(&journal->j_list_lock); - - if (!buffer_jbd(bh)) - goto not_jbd; - jh = bh2jh(bh); - - /* Critical error: attempting to delete a bitmap buffer, maybe? - * Don't do any jbd operations, and return an error. */ - if (!J_EXPECT_JH(jh, !jh->b_committed_data, - "inconsistent data on disk")) { - err = -EIO; - goto not_jbd; - } - - /* - * The buffer's going from the transaction, we must drop - * all references -bzzz - */ - jh->b_modified = 0; - - if (jh->b_transaction == handle->h_transaction) { - J_ASSERT_JH(jh, !jh->b_frozen_data); - - /* If we are forgetting a buffer which is already part - * of this transaction, then we can just drop it from - * the transaction immediately. */ - clear_buffer_dirty(bh); - clear_buffer_jbddirty(bh); - - JBUFFER_TRACE(jh, "belongs to current transaction: unfile"); - - drop_reserve = 1; - - /* - * We are no longer going to journal this buffer. - * However, the commit of this transaction is still - * important to the buffer: the delete that we are now - * processing might obsolete an old log entry, so by - * committing, we can satisfy the buffer's checkpoint. - * - * So, if we have a checkpoint on the buffer, we should - * now refile the buffer on our BJ_Forget list so that - * we know to remove the checkpoint after we commit. - */ - - if (jh->b_cp_transaction) { - __jbd2_journal_temp_unlink_buffer(jh); - __jbd2_journal_file_buffer(jh, transaction, BJ_Forget); - } else { - __jbd2_journal_unfile_buffer(jh); - jbd2_journal_remove_journal_head(bh); - __brelse(bh); - if (!buffer_jbd(bh)) { - spin_unlock(&journal->j_list_lock); - jbd_unlock_bh_state(bh); - __bforget(bh); - goto drop; - } - } - } else if (jh->b_transaction) { - J_ASSERT_JH(jh, (jh->b_transaction == - journal->j_committing_transaction)); - /* However, if the buffer is still owned by a prior - * (committing) transaction, we can't drop it yet... */ - JBUFFER_TRACE(jh, "belongs to older transaction"); - /* ... but we CAN drop it from the new transaction if we - * have also modified it since the original commit. */ - - if (jh->b_next_transaction) { - J_ASSERT(jh->b_next_transaction == transaction); - jh->b_next_transaction = NULL; - drop_reserve = 1; - } - } - -not_jbd: - spin_unlock(&journal->j_list_lock); - jbd_unlock_bh_state(bh); - __brelse(bh); -drop: - if (drop_reserve) { - /* no need to reserve log space for this block -bzzz */ - handle->h_buffer_credits++; - } - return err; -} - -/** - * int jbd2_journal_stop() - complete a transaction - * @handle: tranaction to complete. - * - * All done for a particular handle. - * - * There is not much action needed here. We just return any remaining - * buffer credits to the transaction and remove the handle. The only - * complication is that we need to start a commit operation if the - * filesystem is marked for synchronous update. - * - * jbd2_journal_stop itself will not usually return an error, but it may - * do so in unusual circumstances. In particular, expect it to - * return -EIO if a jbd2_journal_abort has been executed since the - * transaction began. - */ -int jbd2_journal_stop(handle_t *handle) -{ - transaction_t *transaction = handle->h_transaction; - journal_t *journal = transaction->t_journal; - int old_handle_count, err; - pid_t pid; - - J_ASSERT(journal_current_handle() == handle); - - if (is_handle_aborted(handle)) - err = -EIO; - else { - J_ASSERT(transaction->t_updates > 0); - err = 0; - } - - if (--handle->h_ref > 0) { - jbd_debug(4, "h_ref %d -> %d\n", handle->h_ref + 1, - handle->h_ref); - return err; - } - - jbd_debug(4, "Handle %p going down\n", handle); - - /* - * Implement synchronous transaction batching. If the handle - * was synchronous, don't force a commit immediately. Let's - * yield and let another thread piggyback onto this transaction. - * Keep doing that while new threads continue to arrive. - * It doesn't cost much - we're about to run a commit and sleep - * on IO anyway. Speeds up many-threaded, many-dir operations - * by 30x or more... - * - * But don't do this if this process was the most recent one to - * perform a synchronous write. We do this to detect the case where a - * single process is doing a stream of sync writes. No point in waiting - * for joiners in that case. - */ - pid = current->pid; - if (handle->h_sync && journal->j_last_sync_writer != pid) { - journal->j_last_sync_writer = pid; - do { - old_handle_count = transaction->t_handle_count; - schedule_timeout_uninterruptible(1); - } while (old_handle_count != transaction->t_handle_count); - } - - current->journal_info = NULL; - spin_lock(&journal->j_state_lock); - spin_lock(&transaction->t_handle_lock); - transaction->t_outstanding_credits -= handle->h_buffer_credits; - transaction->t_updates--; - if (!transaction->t_updates) { - wake_up(&journal->j_wait_updates); - if (journal->j_barrier_count) - wake_up(&journal->j_wait_transaction_locked); - } - - /* - * If the handle is marked SYNC, we need to set another commit - * going! We also want to force a commit if the current - * transaction is occupying too much of the log, or if the - * transaction is too old now. - */ - if (handle->h_sync || - transaction->t_outstanding_credits > - journal->j_max_transaction_buffers || - time_after_eq(jiffies, transaction->t_expires)) { - /* Do this even for aborted journals: an abort still - * completes the commit thread, it just doesn't write - * anything to disk. */ - tid_t tid = transaction->t_tid; - - spin_unlock(&transaction->t_handle_lock); - jbd_debug(2, "transaction too old, requesting commit for " - "handle %p\n", handle); - /* This is non-blocking */ - __jbd2_log_start_commit(journal, transaction->t_tid); - spin_unlock(&journal->j_state_lock); - - /* - * Special case: JBD2_SYNC synchronous updates require us - * to wait for the commit to complete. - */ - if (handle->h_sync && !(current->flags & PF_MEMALLOC)) - err = jbd2_log_wait_commit(journal, tid); - } else { - spin_unlock(&transaction->t_handle_lock); - spin_unlock(&journal->j_state_lock); - } - - jbd_free_handle(handle); - return err; -} - -/**int jbd2_journal_force_commit() - force any uncommitted transactions - * @journal: journal to force - * - * For synchronous operations: force any uncommitted transactions - * to disk. May seem kludgy, but it reuses all the handle batching - * code in a very simple manner. - */ -int jbd2_journal_force_commit(journal_t *journal) -{ - handle_t *handle; - int ret; - - handle = jbd2_journal_start(journal, 1); - if (IS_ERR(handle)) { - ret = PTR_ERR(handle); - } else { - handle->h_sync = 1; - ret = jbd2_journal_stop(handle); - } - return ret; -} - -/* - * - * List management code snippets: various functions for manipulating the - * transaction buffer lists. - * - */ - -/* - * Append a buffer to a transaction list, given the transaction's list head - * pointer. - * - * j_list_lock is held. - * - * jbd_lock_bh_state(jh2bh(jh)) is held. - */ - -static inline void -__blist_add_buffer(struct journal_head **list, struct journal_head *jh) -{ - if (!*list) { - jh->b_tnext = jh->b_tprev = jh; - *list = jh; - } else { - /* Insert at the tail of the list to preserve order */ - struct journal_head *first = *list, *last = first->b_tprev; - jh->b_tprev = last; - jh->b_tnext = first; - last->b_tnext = first->b_tprev = jh; - } -} - -/* - * Remove a buffer from a transaction list, given the transaction's list - * head pointer. - * - * Called with j_list_lock held, and the journal may not be locked. - * - * jbd_lock_bh_state(jh2bh(jh)) is held. - */ - -static inline void -__blist_del_buffer(struct journal_head **list, struct journal_head *jh) -{ - if (*list == jh) { - *list = jh->b_tnext; - if (*list == jh) - *list = NULL; - } - jh->b_tprev->b_tnext = jh->b_tnext; - jh->b_tnext->b_tprev = jh->b_tprev; -} - -/* - * Remove a buffer from the appropriate transaction list. - * - * Note that this function can *change* the value of - * bh->b_transaction->t_sync_datalist, t_buffers, t_forget, - * t_iobuf_list, t_shadow_list, t_log_list or t_reserved_list. If the caller - * is holding onto a copy of one of thee pointers, it could go bad. - * Generally the caller needs to re-read the pointer from the transaction_t. - * - * Called under j_list_lock. The journal may not be locked. - */ -void __jbd2_journal_temp_unlink_buffer(struct journal_head *jh) -{ - struct journal_head **list = NULL; - transaction_t *transaction; - struct buffer_head *bh = jh2bh(jh); - - J_ASSERT_JH(jh, jbd_is_locked_bh_state(bh)); - transaction = jh->b_transaction; - if (transaction) - assert_spin_locked(&transaction->t_journal->j_list_lock); - - J_ASSERT_JH(jh, jh->b_jlist < BJ_Types); - if (jh->b_jlist != BJ_None) - J_ASSERT_JH(jh, transaction != 0); - - switch (jh->b_jlist) { - case BJ_None: - return; - case BJ_SyncData: - list = &transaction->t_sync_datalist; - break; - case BJ_Metadata: - transaction->t_nr_buffers--; - J_ASSERT_JH(jh, transaction->t_nr_buffers >= 0); - list = &transaction->t_buffers; - break; - case BJ_Forget: - list = &transaction->t_forget; - break; - case BJ_IO: - list = &transaction->t_iobuf_list; - break; - case BJ_Shadow: - list = &transaction->t_shadow_list; - break; - case BJ_LogCtl: - list = &transaction->t_log_list; - break; - case BJ_Reserved: - list = &transaction->t_reserved_list; - break; - case BJ_Locked: - list = &transaction->t_locked_list; - break; - } - - __blist_del_buffer(list, jh); - jh->b_jlist = BJ_None; - if (test_clear_buffer_jbddirty(bh)) - mark_buffer_dirty(bh); /* Expose it to the VM */ -} - -void __jbd2_journal_unfile_buffer(struct journal_head *jh) -{ - __jbd2_journal_temp_unlink_buffer(jh); - jh->b_transaction = NULL; -} - -void jbd2_journal_unfile_buffer(journal_t *journal, struct journal_head *jh) -{ - jbd_lock_bh_state(jh2bh(jh)); - spin_lock(&journal->j_list_lock); - __jbd2_journal_unfile_buffer(jh); - spin_unlock(&journal->j_list_lock); - jbd_unlock_bh_state(jh2bh(jh)); -} - -/* - * Called from jbd2_journal_try_to_free_buffers(). - * - * Called under jbd_lock_bh_state(bh) - */ -static void -__journal_try_to_free_buffer(journal_t *journal, struct buffer_head *bh) -{ - struct journal_head *jh; - - jh = bh2jh(bh); - - if (buffer_locked(bh) || buffer_dirty(bh)) - goto out; - - if (jh->b_next_transaction != 0) - goto out; - - spin_lock(&journal->j_list_lock); - if (jh->b_transaction != 0 && jh->b_cp_transaction == 0) { - if (jh->b_jlist == BJ_SyncData || jh->b_jlist == BJ_Locked) { - /* A written-back ordered data buffer */ - JBUFFER_TRACE(jh, "release data"); - __jbd2_journal_unfile_buffer(jh); - jbd2_journal_remove_journal_head(bh); - __brelse(bh); - } - } else if (jh->b_cp_transaction != 0 && jh->b_transaction == 0) { - /* written-back checkpointed metadata buffer */ - if (jh->b_jlist == BJ_None) { - JBUFFER_TRACE(jh, "remove from checkpoint list"); - __jbd2_journal_remove_checkpoint(jh); - jbd2_journal_remove_journal_head(bh); - __brelse(bh); - } - } - spin_unlock(&journal->j_list_lock); -out: - return; -} - - -/** - * int jbd2_journal_try_to_free_buffers() - try to free page buffers. - * @journal: journal for operation - * @page: to try and free - * @unused_gfp_mask: unused - * - * - * For all the buffers on this page, - * if they are fully written out ordered data, move them onto BUF_CLEAN - * so try_to_free_buffers() can reap them. - * - * This function returns non-zero if we wish try_to_free_buffers() - * to be called. We do this if the page is releasable by try_to_free_buffers(). - * We also do it if the page has locked or dirty buffers and the caller wants - * us to perform sync or async writeout. - * - * This complicates JBD locking somewhat. We aren't protected by the - * BKL here. We wish to remove the buffer from its committing or - * running transaction's ->t_datalist via __jbd2_journal_unfile_buffer. - * - * This may *change* the value of transaction_t->t_datalist, so anyone - * who looks at t_datalist needs to lock against this function. - * - * Even worse, someone may be doing a jbd2_journal_dirty_data on this - * buffer. So we need to lock against that. jbd2_journal_dirty_data() - * will come out of the lock with the buffer dirty, which makes it - * ineligible for release here. - * - * Who else is affected by this? hmm... Really the only contender - * is do_get_write_access() - it could be looking at the buffer while - * journal_try_to_free_buffer() is changing its state. But that - * cannot happen because we never reallocate freed data as metadata - * while the data is part of a transaction. Yes? - */ -int jbd2_journal_try_to_free_buffers(journal_t *journal, - struct page *page, gfp_t unused_gfp_mask) -{ - struct buffer_head *head; - struct buffer_head *bh; - int ret = 0; - - J_ASSERT(PageLocked(page)); - - head = page_buffers(page); - bh = head; - do { - struct journal_head *jh; - - /* - * We take our own ref against the journal_head here to avoid - * having to add tons of locking around each instance of - * jbd2_journal_remove_journal_head() and jbd2_journal_put_journal_head(). - */ - jh = jbd2_journal_grab_journal_head(bh); - if (!jh) - continue; - - jbd_lock_bh_state(bh); - __journal_try_to_free_buffer(journal, bh); - jbd2_journal_put_journal_head(jh); - jbd_unlock_bh_state(bh); - if (buffer_jbd(bh)) - goto busy; - } while ((bh = bh->b_this_page) != head); - ret = try_to_free_buffers(page); -busy: - return ret; -} - -/* - * This buffer is no longer needed. If it is on an older transaction's - * checkpoint list we need to record it on this transaction's forget list - * to pin this buffer (and hence its checkpointing transaction) down until - * this transaction commits. If the buffer isn't on a checkpoint list, we - * release it. - * Returns non-zero if JBD no longer has an interest in the buffer. - * - * Called under j_list_lock. - * - * Called under jbd_lock_bh_state(bh). - */ -static int __dispose_buffer(struct journal_head *jh, transaction_t *transaction) -{ - int may_free = 1; - struct buffer_head *bh = jh2bh(jh); - - __jbd2_journal_unfile_buffer(jh); - - if (jh->b_cp_transaction) { - JBUFFER_TRACE(jh, "on running+cp transaction"); - __jbd2_journal_file_buffer(jh, transaction, BJ_Forget); - clear_buffer_jbddirty(bh); - may_free = 0; - } else { - JBUFFER_TRACE(jh, "on running transaction"); - jbd2_journal_remove_journal_head(bh); - __brelse(bh); - } - return may_free; -} - -/* - * jbd2_journal_invalidatepage - * - * This code is tricky. It has a number of cases to deal with. - * - * There are two invariants which this code relies on: - * - * i_size must be updated on disk before we start calling invalidatepage on the - * data. - * - * This is done in ext3 by defining an ext3_setattr method which - * updates i_size before truncate gets going. By maintaining this - * invariant, we can be sure that it is safe to throw away any buffers - * attached to the current transaction: once the transaction commits, - * we know that the data will not be needed. - * - * Note however that we can *not* throw away data belonging to the - * previous, committing transaction! - * - * Any disk blocks which *are* part of the previous, committing - * transaction (and which therefore cannot be discarded immediately) are - * not going to be reused in the new running transaction - * - * The bitmap committed_data images guarantee this: any block which is - * allocated in one transaction and removed in the next will be marked - * as in-use in the committed_data bitmap, so cannot be reused until - * the next transaction to delete the block commits. This means that - * leaving committing buffers dirty is quite safe: the disk blocks - * cannot be reallocated to a different file and so buffer aliasing is - * not possible. - * - * - * The above applies mainly to ordered data mode. In writeback mode we - * don't make guarantees about the order in which data hits disk --- in - * particular we don't guarantee that new dirty data is flushed before - * transaction commit --- so it is always safe just to discard data - * immediately in that mode. --sct - */ - -/* - * The journal_unmap_buffer helper function returns zero if the buffer - * concerned remains pinned as an anonymous buffer belonging to an older - * transaction. - * - * We're outside-transaction here. Either or both of j_running_transaction - * and j_committing_transaction may be NULL. - */ -static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh) -{ - transaction_t *transaction; - struct journal_head *jh; - int may_free = 1; - int ret; - - BUFFER_TRACE(bh, "entry"); - - /* - * It is safe to proceed here without the j_list_lock because the - * buffers cannot be stolen by try_to_free_buffers as long as we are - * holding the page lock. --sct - */ - - if (!buffer_jbd(bh)) - goto zap_buffer_unlocked; - - spin_lock(&journal->j_state_lock); - jbd_lock_bh_state(bh); - spin_lock(&journal->j_list_lock); - - jh = jbd2_journal_grab_journal_head(bh); - if (!jh) - goto zap_buffer_no_jh; - - transaction = jh->b_transaction; - if (transaction == NULL) { - /* First case: not on any transaction. If it - * has no checkpoint link, then we can zap it: - * it's a writeback-mode buffer so we don't care - * if it hits disk safely. */ - if (!jh->b_cp_transaction) { - JBUFFER_TRACE(jh, "not on any transaction: zap"); - goto zap_buffer; - } - - if (!buffer_dirty(bh)) { - /* bdflush has written it. We can drop it now */ - goto zap_buffer; - } - - /* OK, it must be in the journal but still not - * written fully to disk: it's metadata or - * journaled data... */ - - if (journal->j_running_transaction) { - /* ... and once the current transaction has - * committed, the buffer won't be needed any - * longer. */ - JBUFFER_TRACE(jh, "checkpointed: add to BJ_Forget"); - ret = __dispose_buffer(jh, - journal->j_running_transaction); - jbd2_journal_put_journal_head(jh); - spin_unlock(&journal->j_list_lock); - jbd_unlock_bh_state(bh); - spin_unlock(&journal->j_state_lock); - return ret; - } else { - /* There is no currently-running transaction. So the - * orphan record which we wrote for this file must have - * passed into commit. We must attach this buffer to - * the committing transaction, if it exists. */ - if (journal->j_committing_transaction) { - JBUFFER_TRACE(jh, "give to committing trans"); - ret = __dispose_buffer(jh, - journal->j_committing_transaction); - jbd2_journal_put_journal_head(jh); - spin_unlock(&journal->j_list_lock); - jbd_unlock_bh_state(bh); - spin_unlock(&journal->j_state_lock); - return ret; - } else { - /* The orphan record's transaction has - * committed. We can cleanse this buffer */ - clear_buffer_jbddirty(bh); - goto zap_buffer; - } - } - } else if (transaction == journal->j_committing_transaction) { - JBUFFER_TRACE(jh, "on committing transaction"); - if (jh->b_jlist == BJ_Locked) { - /* - * The buffer is on the committing transaction's locked - * list. We have the buffer locked, so I/O has - * completed. So we can nail the buffer now. - */ - may_free = __dispose_buffer(jh, transaction); - goto zap_buffer; - } - /* - * If it is committing, we simply cannot touch it. We - * can remove it's next_transaction pointer from the - * running transaction if that is set, but nothing - * else. */ - set_buffer_freed(bh); - if (jh->b_next_transaction) { - J_ASSERT(jh->b_next_transaction == - journal->j_running_transaction); - jh->b_next_transaction = NULL; - } - jbd2_journal_put_journal_head(jh); - spin_unlock(&journal->j_list_lock); - jbd_unlock_bh_state(bh); - spin_unlock(&journal->j_state_lock); - return 0; - } else { - /* Good, the buffer belongs to the running transaction. - * We are writing our own transaction's data, not any - * previous one's, so it is safe to throw it away - * (remember that we expect the filesystem to have set - * i_size already for this truncate so recovery will not - * expose the disk blocks we are discarding here.) */ - J_ASSERT_JH(jh, transaction == journal->j_running_transaction); - JBUFFER_TRACE(jh, "on running transaction"); - may_free = __dispose_buffer(jh, transaction); - } - -zap_buffer: - jbd2_journal_put_journal_head(jh); -zap_buffer_no_jh: - spin_unlock(&journal->j_list_lock); - jbd_unlock_bh_state(bh); - spin_unlock(&journal->j_state_lock); -zap_buffer_unlocked: - clear_buffer_dirty(bh); - J_ASSERT_BH(bh, !buffer_jbddirty(bh)); - clear_buffer_mapped(bh); - clear_buffer_req(bh); - clear_buffer_new(bh); - bh->b_bdev = NULL; - return may_free; -} - -/** - * void jbd2_journal_invalidatepage() - * @journal: journal to use for flush... - * @page: page to flush - * @offset: length of page to invalidate. - * - * Reap page buffers containing data after offset in page. - * - */ -void jbd2_journal_invalidatepage(journal_t *journal, - struct page *page, - unsigned long offset) -{ - struct buffer_head *head, *bh, *next; - unsigned int curr_off = 0; - int may_free = 1; - - if (!PageLocked(page)) - BUG(); - if (!page_has_buffers(page)) - return; - - /* We will potentially be playing with lists other than just the - * data lists (especially for journaled data mode), so be - * cautious in our locking. */ - - head = bh = page_buffers(page); - do { - unsigned int next_off = curr_off + bh->b_size; - next = bh->b_this_page; - - if (offset <= curr_off) { - /* This block is wholly outside the truncation point */ - lock_buffer(bh); - may_free &= journal_unmap_buffer(journal, bh); - unlock_buffer(bh); - } - curr_off = next_off; - bh = next; - - } while (bh != head); - - if (!offset) { - if (may_free && try_to_free_buffers(page)) - J_ASSERT(!page_has_buffers(page)); - } -} - -/* - * File a buffer on the given transaction list. - */ -void __jbd2_journal_file_buffer(struct journal_head *jh, - transaction_t *transaction, int jlist) -{ - struct journal_head **list = NULL; - int was_dirty = 0; - struct buffer_head *bh = jh2bh(jh); - - J_ASSERT_JH(jh, jbd_is_locked_bh_state(bh)); - assert_spin_locked(&transaction->t_journal->j_list_lock); - - J_ASSERT_JH(jh, jh->b_jlist < BJ_Types); - J_ASSERT_JH(jh, jh->b_transaction == transaction || - jh->b_transaction == 0); - - if (jh->b_transaction && jh->b_jlist == jlist) - return; - - /* The following list of buffer states needs to be consistent - * with __jbd_unexpected_dirty_buffer()'s handling of dirty - * state. */ - - if (jlist == BJ_Metadata || jlist == BJ_Reserved || - jlist == BJ_Shadow || jlist == BJ_Forget) { - if (test_clear_buffer_dirty(bh) || - test_clear_buffer_jbddirty(bh)) - was_dirty = 1; - } - - if (jh->b_transaction) - __jbd2_journal_temp_unlink_buffer(jh); - jh->b_transaction = transaction; - - switch (jlist) { - case BJ_None: - J_ASSERT_JH(jh, !jh->b_committed_data); - J_ASSERT_JH(jh, !jh->b_frozen_data); - return; - case BJ_SyncData: - list = &transaction->t_sync_datalist; - break; - case BJ_Metadata: - transaction->t_nr_buffers++; - list = &transaction->t_buffers; - break; - case BJ_Forget: - list = &transaction->t_forget; - break; - case BJ_IO: - list = &transaction->t_iobuf_list; - break; - case BJ_Shadow: - list = &transaction->t_shadow_list; - break; - case BJ_LogCtl: - list = &transaction->t_log_list; - break; - case BJ_Reserved: - list = &transaction->t_reserved_list; - break; - case BJ_Locked: - list = &transaction->t_locked_list; - break; - } - - __blist_add_buffer(list, jh); - jh->b_jlist = jlist; - - if (was_dirty) - set_buffer_jbddirty(bh); -} - -void jbd2_journal_file_buffer(struct journal_head *jh, - transaction_t *transaction, int jlist) -{ - jbd_lock_bh_state(jh2bh(jh)); - spin_lock(&transaction->t_journal->j_list_lock); - __jbd2_journal_file_buffer(jh, transaction, jlist); - spin_unlock(&transaction->t_journal->j_list_lock); - jbd_unlock_bh_state(jh2bh(jh)); -} - -/* - * Remove a buffer from its current buffer list in preparation for - * dropping it from its current transaction entirely. If the buffer has - * already started to be used by a subsequent transaction, refile the - * buffer on that transaction's metadata list. - * - * Called under journal->j_list_lock - * - * Called under jbd_lock_bh_state(jh2bh(jh)) - */ -void __jbd2_journal_refile_buffer(struct journal_head *jh) -{ - int was_dirty; - struct buffer_head *bh = jh2bh(jh); - - J_ASSERT_JH(jh, jbd_is_locked_bh_state(bh)); - if (jh->b_transaction) - assert_spin_locked(&jh->b_transaction->t_journal->j_list_lock); - - /* If the buffer is now unused, just drop it. */ - if (jh->b_next_transaction == NULL) { - __jbd2_journal_unfile_buffer(jh); - return; - } - - /* - * It has been modified by a later transaction: add it to the new - * transaction's metadata list. - */ - - was_dirty = test_clear_buffer_jbddirty(bh); - __jbd2_journal_temp_unlink_buffer(jh); - jh->b_transaction = jh->b_next_transaction; - jh->b_next_transaction = NULL; - __jbd2_journal_file_buffer(jh, jh->b_transaction, - was_dirty ? BJ_Metadata : BJ_Reserved); - J_ASSERT_JH(jh, jh->b_transaction->t_state == T_RUNNING); - - if (was_dirty) - set_buffer_jbddirty(bh); -} - -/* - * For the unlocked version of this call, also make sure that any - * hanging journal_head is cleaned up if necessary. - * - * __jbd2_journal_refile_buffer is usually called as part of a single locked - * operation on a buffer_head, in which the caller is probably going to - * be hooking the journal_head onto other lists. In that case it is up - * to the caller to remove the journal_head if necessary. For the - * unlocked jbd2_journal_refile_buffer call, the caller isn't going to be - * doing anything else to the buffer so we need to do the cleanup - * ourselves to avoid a jh leak. - * - * *** The journal_head may be freed by this call! *** - */ -void jbd2_journal_refile_buffer(journal_t *journal, struct journal_head *jh) -{ - struct buffer_head *bh = jh2bh(jh); - - jbd_lock_bh_state(bh); - spin_lock(&journal->j_list_lock); - - __jbd2_journal_refile_buffer(jh); - jbd_unlock_bh_state(bh); - jbd2_journal_remove_journal_head(bh); - - spin_unlock(&journal->j_list_lock); - __brelse(bh); -} diff --git a/trunk/fs/jffs2/super.c b/trunk/fs/jffs2/super.c index bc4b8106a490..6de374513c01 100644 --- a/trunk/fs/jffs2/super.c +++ b/trunk/fs/jffs2/super.c @@ -334,10 +334,10 @@ static int __init init_jffs2_fs(void) which means just 'no padding', without the alignment thing. But GCC doesn't have that -- we have to just hope the structs are the right sizes, instead. */ - BUILD_BUG_ON(sizeof(struct jffs2_unknown_node) != 12); - BUILD_BUG_ON(sizeof(struct jffs2_raw_dirent) != 40); - BUILD_BUG_ON(sizeof(struct jffs2_raw_inode) != 68); - BUILD_BUG_ON(sizeof(struct jffs2_raw_summary) != 32); + BUG_ON(sizeof(struct jffs2_unknown_node) != 12); + BUG_ON(sizeof(struct jffs2_raw_dirent) != 40); + BUG_ON(sizeof(struct jffs2_raw_inode) != 68); + BUG_ON(sizeof(struct jffs2_raw_summary) != 32); printk(KERN_INFO "JFFS2 version 2.2." #ifdef CONFIG_JFFS2_FS_WRITEBUFFER diff --git a/trunk/fs/jfs/file.c b/trunk/fs/jfs/file.c index aa9132d04920..34181b8f5a0a 100644 --- a/trunk/fs/jfs/file.c +++ b/trunk/fs/jfs/file.c @@ -109,8 +109,6 @@ const struct file_operations jfs_file_operations = { .aio_write = generic_file_aio_write, .mmap = generic_file_mmap, .sendfile = generic_file_sendfile, - .splice_read = generic_file_splice_read, - .splice_write = generic_file_splice_write, .fsync = jfs_fsync, .release = jfs_release, .ioctl = jfs_ioctl, diff --git a/trunk/fs/jfs/jfs_filsys.h b/trunk/fs/jfs/jfs_filsys.h index eb550b339bb8..9901928668cf 100644 --- a/trunk/fs/jfs/jfs_filsys.h +++ b/trunk/fs/jfs/jfs_filsys.h @@ -81,7 +81,7 @@ #define JFS_SWAP_BYTES 0x00100000 /* running on big endian computer */ /* Directory index */ -#define JFS_DIR_INDEX 0x00200000 /* Persistent index for */ +#define JFS_DIR_INDEX 0x00200000 /* Persistant index for */ /* directory entries */ diff --git a/trunk/fs/jfs/jfs_imap.c b/trunk/fs/jfs/jfs_imap.c index ee9b473b7b80..489a3d63002d 100644 --- a/trunk/fs/jfs/jfs_imap.c +++ b/trunk/fs/jfs/jfs_imap.c @@ -318,7 +318,7 @@ int diRead(struct inode *ip) struct inomap *imap; int block_offset; int inodes_left; - unsigned long pageno; + uint pageno; int rel_inode; jfs_info("diRead: ino = %ld", ip->i_ino); @@ -606,7 +606,7 @@ int diWrite(tid_t tid, struct inode *ip) int block_offset; int inodes_left; struct metapage *mp; - unsigned long pageno; + uint pageno; int rel_inode; int dioffset; struct inode *ipimap; diff --git a/trunk/fs/jfs/xattr.c b/trunk/fs/jfs/xattr.c index b753ba216450..4c7985ebca92 100644 --- a/trunk/fs/jfs/xattr.c +++ b/trunk/fs/jfs/xattr.c @@ -756,11 +756,6 @@ static int can_set_system_xattr(struct inode *inode, const char *name, return -EOPNOTSUPP; } -/* - * Most of the permission checking is done by xattr_permission in the vfs. - * The local file system is responsible for handling the system.* namespace. - * We also need to verify that this is a namespace that we recognize. - */ static int can_set_xattr(struct inode *inode, const char *name, const void *value, size_t value_len) { @@ -776,6 +771,10 @@ static int can_set_xattr(struct inode *inode, const char *name, strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN)) return -EOPNOTSUPP; + if (!S_ISREG(inode->i_mode) && + (!S_ISDIR(inode->i_mode) || inode->i_mode &S_ISVTX)) + return -EPERM; + return 0; } diff --git a/trunk/fs/lockd/clntlock.c b/trunk/fs/lockd/clntlock.c index b85a0ad2cfb6..e8c7765419e8 100644 --- a/trunk/fs/lockd/clntlock.c +++ b/trunk/fs/lockd/clntlock.c @@ -100,12 +100,12 @@ int nlmclnt_block(struct nlm_wait *block, struct nlm_rqst *req, long timeout) /* * The server lockd has called us back to tell us the lock was granted */ -__be32 nlmclnt_grant(const struct sockaddr_in *addr, const struct nlm_lock *lock) +u32 nlmclnt_grant(const struct sockaddr_in *addr, const struct nlm_lock *lock) { const struct file_lock *fl = &lock->fl; const struct nfs_fh *fh = &lock->fh; struct nlm_wait *block; - __be32 res = nlm_lck_denied; + u32 res = nlm_lck_denied; /* * Look up blocked request based on arguments. diff --git a/trunk/fs/lockd/mon.c b/trunk/fs/lockd/mon.c index eb243edf8932..e0179f8c327f 100644 --- a/trunk/fs/lockd/mon.c +++ b/trunk/fs/lockd/mon.c @@ -148,8 +148,8 @@ nsm_create(void) * XDR functions for NSM. */ -static __be32 * -xdr_encode_common(struct rpc_rqst *rqstp, __be32 *p, struct nsm_args *argp) +static u32 * +xdr_encode_common(struct rpc_rqst *rqstp, u32 *p, struct nsm_args *argp) { char buffer[20], *name; @@ -176,7 +176,7 @@ xdr_encode_common(struct rpc_rqst *rqstp, __be32 *p, struct nsm_args *argp) } static int -xdr_encode_mon(struct rpc_rqst *rqstp, __be32 *p, struct nsm_args *argp) +xdr_encode_mon(struct rpc_rqst *rqstp, u32 *p, struct nsm_args *argp) { p = xdr_encode_common(rqstp, p, argp); if (IS_ERR(p)) @@ -192,7 +192,7 @@ xdr_encode_mon(struct rpc_rqst *rqstp, __be32 *p, struct nsm_args *argp) } static int -xdr_encode_unmon(struct rpc_rqst *rqstp, __be32 *p, struct nsm_args *argp) +xdr_encode_unmon(struct rpc_rqst *rqstp, u32 *p, struct nsm_args *argp) { p = xdr_encode_common(rqstp, p, argp); if (IS_ERR(p)) @@ -202,7 +202,7 @@ xdr_encode_unmon(struct rpc_rqst *rqstp, __be32 *p, struct nsm_args *argp) } static int -xdr_decode_stat_res(struct rpc_rqst *rqstp, __be32 *p, struct nsm_res *resp) +xdr_decode_stat_res(struct rpc_rqst *rqstp, u32 *p, struct nsm_res *resp) { resp->status = ntohl(*p++); resp->state = ntohl(*p++); @@ -212,7 +212,7 @@ xdr_decode_stat_res(struct rpc_rqst *rqstp, __be32 *p, struct nsm_res *resp) } static int -xdr_decode_stat(struct rpc_rqst *rqstp, __be32 *p, struct nsm_res *resp) +xdr_decode_stat(struct rpc_rqst *rqstp, u32 *p, struct nsm_res *resp) { resp->state = ntohl(*p++); return 0; diff --git a/trunk/fs/lockd/svc.c b/trunk/fs/lockd/svc.c index 8ca18085e68d..634139232aaf 100644 --- a/trunk/fs/lockd/svc.c +++ b/trunk/fs/lockd/svc.c @@ -353,6 +353,9 @@ EXPORT_SYMBOL(lockd_down); * Sysctl parameters (same as module parameters, different interface). */ +/* Something that isn't CTL_ANY, CTL_NONE or a value that may clash. */ +#define CTL_UNNUMBERED -2 + static ctl_table nlm_sysctls[] = { { .ctl_name = CTL_UNNUMBERED, diff --git a/trunk/fs/lockd/svc4proc.c b/trunk/fs/lockd/svc4proc.c index 0ce5c81ff507..fa370f6eb07b 100644 --- a/trunk/fs/lockd/svc4proc.c +++ b/trunk/fs/lockd/svc4proc.c @@ -24,14 +24,14 @@ /* * Obtain client and file from arguments */ -static __be32 +static u32 nlm4svc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp, struct nlm_host **hostp, struct nlm_file **filp) { struct nlm_host *host = NULL; struct nlm_file *file = NULL; struct nlm_lock *lock = &argp->lock; - __be32 error = 0; + u32 error = 0; /* nfsd callbacks must have been installed for this procedure */ if (!nlmsvc_ops) @@ -68,7 +68,7 @@ nlm4svc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp, /* * NULL: Test for presence of service */ -static __be32 +static int nlm4svc_proc_null(struct svc_rqst *rqstp, void *argp, void *resp) { dprintk("lockd: NULL called\n"); @@ -78,7 +78,7 @@ nlm4svc_proc_null(struct svc_rqst *rqstp, void *argp, void *resp) /* * TEST: Check for conflicting lock */ -static __be32 +static int nlm4svc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp, struct nlm_res *resp) { @@ -96,7 +96,7 @@ nlm4svc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp, /* Obtain client and file */ if ((resp->status = nlm4svc_retrieve_args(rqstp, argp, &host, &file))) - return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; + return rpc_success; /* Now check for conflicting locks */ resp->status = nlmsvc_testlock(file, &argp->lock, &resp->lock); @@ -107,7 +107,7 @@ nlm4svc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp, return rpc_success; } -static __be32 +static int nlm4svc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp, struct nlm_res *resp) { @@ -126,7 +126,7 @@ nlm4svc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp, /* Obtain client and file */ if ((resp->status = nlm4svc_retrieve_args(rqstp, argp, &host, &file))) - return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; + return rpc_success; #if 0 /* If supplied state doesn't match current state, we assume it's @@ -150,7 +150,7 @@ nlm4svc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp, return rpc_success; } -static __be32 +static int nlm4svc_proc_cancel(struct svc_rqst *rqstp, struct nlm_args *argp, struct nlm_res *resp) { @@ -169,7 +169,7 @@ nlm4svc_proc_cancel(struct svc_rqst *rqstp, struct nlm_args *argp, /* Obtain client and file */ if ((resp->status = nlm4svc_retrieve_args(rqstp, argp, &host, &file))) - return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; + return rpc_success; /* Try to cancel request. */ resp->status = nlmsvc_cancel_blocked(file, &argp->lock); @@ -183,7 +183,7 @@ nlm4svc_proc_cancel(struct svc_rqst *rqstp, struct nlm_args *argp, /* * UNLOCK: release a lock */ -static __be32 +static int nlm4svc_proc_unlock(struct svc_rqst *rqstp, struct nlm_args *argp, struct nlm_res *resp) { @@ -202,7 +202,7 @@ nlm4svc_proc_unlock(struct svc_rqst *rqstp, struct nlm_args *argp, /* Obtain client and file */ if ((resp->status = nlm4svc_retrieve_args(rqstp, argp, &host, &file))) - return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; + return rpc_success; /* Now try to remove the lock */ resp->status = nlmsvc_unlock(file, &argp->lock); @@ -217,7 +217,7 @@ nlm4svc_proc_unlock(struct svc_rqst *rqstp, struct nlm_args *argp, * GRANTED: A server calls us to tell that a process' lock request * was granted */ -static __be32 +static int nlm4svc_proc_granted(struct svc_rqst *rqstp, struct nlm_args *argp, struct nlm_res *resp) { @@ -253,12 +253,12 @@ static const struct rpc_call_ops nlm4svc_callback_ops = { * because we send the callback before the reply proper. I hope this * doesn't break any clients. */ -static __be32 nlm4svc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_args *argp, - __be32 (*func)(struct svc_rqst *, struct nlm_args *, struct nlm_res *)) +static int nlm4svc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_args *argp, + int (*func)(struct svc_rqst *, struct nlm_args *, struct nlm_res *)) { struct nlm_host *host; struct nlm_rqst *call; - __be32 stat; + int stat; host = nlmsvc_lookup_host(rqstp, argp->lock.caller, @@ -282,35 +282,35 @@ static __be32 nlm4svc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_args return rpc_success; } -static __be32 nlm4svc_proc_test_msg(struct svc_rqst *rqstp, struct nlm_args *argp, +static int nlm4svc_proc_test_msg(struct svc_rqst *rqstp, struct nlm_args *argp, void *resp) { dprintk("lockd: TEST_MSG called\n"); return nlm4svc_callback(rqstp, NLMPROC_TEST_RES, argp, nlm4svc_proc_test); } -static __be32 nlm4svc_proc_lock_msg(struct svc_rqst *rqstp, struct nlm_args *argp, +static int nlm4svc_proc_lock_msg(struct svc_rqst *rqstp, struct nlm_args *argp, void *resp) { dprintk("lockd: LOCK_MSG called\n"); return nlm4svc_callback(rqstp, NLMPROC_LOCK_RES, argp, nlm4svc_proc_lock); } -static __be32 nlm4svc_proc_cancel_msg(struct svc_rqst *rqstp, struct nlm_args *argp, +static int nlm4svc_proc_cancel_msg(struct svc_rqst *rqstp, struct nlm_args *argp, void *resp) { dprintk("lockd: CANCEL_MSG called\n"); return nlm4svc_callback(rqstp, NLMPROC_CANCEL_RES, argp, nlm4svc_proc_cancel); } -static __be32 nlm4svc_proc_unlock_msg(struct svc_rqst *rqstp, struct nlm_args *argp, +static int nlm4svc_proc_unlock_msg(struct svc_rqst *rqstp, struct nlm_args *argp, void *resp) { dprintk("lockd: UNLOCK_MSG called\n"); return nlm4svc_callback(rqstp, NLMPROC_UNLOCK_RES, argp, nlm4svc_proc_unlock); } -static __be32 nlm4svc_proc_granted_msg(struct svc_rqst *rqstp, struct nlm_args *argp, +static int nlm4svc_proc_granted_msg(struct svc_rqst *rqstp, struct nlm_args *argp, void *resp) { dprintk("lockd: GRANTED_MSG called\n"); @@ -320,7 +320,7 @@ static __be32 nlm4svc_proc_granted_msg(struct svc_rqst *rqstp, struct nlm_args * /* * SHARE: create a DOS share or alter existing share. */ -static __be32 +static int nlm4svc_proc_share(struct svc_rqst *rqstp, struct nlm_args *argp, struct nlm_res *resp) { @@ -339,7 +339,7 @@ nlm4svc_proc_share(struct svc_rqst *rqstp, struct nlm_args *argp, /* Obtain client and file */ if ((resp->status = nlm4svc_retrieve_args(rqstp, argp, &host, &file))) - return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; + return rpc_success; /* Now try to create the share */ resp->status = nlmsvc_share_file(host, file, argp); @@ -353,7 +353,7 @@ nlm4svc_proc_share(struct svc_rqst *rqstp, struct nlm_args *argp, /* * UNSHARE: Release a DOS share. */ -static __be32 +static int nlm4svc_proc_unshare(struct svc_rqst *rqstp, struct nlm_args *argp, struct nlm_res *resp) { @@ -372,7 +372,7 @@ nlm4svc_proc_unshare(struct svc_rqst *rqstp, struct nlm_args *argp, /* Obtain client and file */ if ((resp->status = nlm4svc_retrieve_args(rqstp, argp, &host, &file))) - return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; + return rpc_success; /* Now try to lock the file */ resp->status = nlmsvc_unshare_file(host, file, argp); @@ -386,7 +386,7 @@ nlm4svc_proc_unshare(struct svc_rqst *rqstp, struct nlm_args *argp, /* * NM_LOCK: Create an unmonitored lock */ -static __be32 +static int nlm4svc_proc_nm_lock(struct svc_rqst *rqstp, struct nlm_args *argp, struct nlm_res *resp) { @@ -399,7 +399,7 @@ nlm4svc_proc_nm_lock(struct svc_rqst *rqstp, struct nlm_args *argp, /* * FREE_ALL: Release all locks and shares held by client */ -static __be32 +static int nlm4svc_proc_free_all(struct svc_rqst *rqstp, struct nlm_args *argp, void *resp) { @@ -417,7 +417,7 @@ nlm4svc_proc_free_all(struct svc_rqst *rqstp, struct nlm_args *argp, /* * SM_NOTIFY: private callback from statd (not part of official NLM proto) */ -static __be32 +static int nlm4svc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp, void *resp) { @@ -446,7 +446,7 @@ nlm4svc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp, /* * client sent a GRANTED_RES, let's remove the associated block */ -static __be32 +static int nlm4svc_proc_granted_res(struct svc_rqst *rqstp, struct nlm_res *argp, void *resp) { diff --git a/trunk/fs/lockd/svclock.c b/trunk/fs/lockd/svclock.c index 7e219b938552..814c6064c9e0 100644 --- a/trunk/fs/lockd/svclock.c +++ b/trunk/fs/lockd/svclock.c @@ -334,13 +334,13 @@ static void nlmsvc_freegrantargs(struct nlm_rqst *call) * Attempt to establish a lock, and if it can't be granted, block it * if required. */ -__be32 +u32 nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file, struct nlm_lock *lock, int wait, struct nlm_cookie *cookie) { struct nlm_block *block, *newblock = NULL; int error; - __be32 ret; + u32 ret; dprintk("lockd: nlmsvc_lock(%s/%ld, ty=%d, pi=%d, %Ld-%Ld, bl=%d)\n", file->f_file->f_dentry->d_inode->i_sb->s_id, @@ -415,7 +415,7 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file, /* * Test for presence of a conflicting lock. */ -__be32 +u32 nlmsvc_testlock(struct nlm_file *file, struct nlm_lock *lock, struct nlm_lock *conflock) { @@ -448,7 +448,7 @@ nlmsvc_testlock(struct nlm_file *file, struct nlm_lock *lock, * afterwards. In this case the block will still be there, and hence * must be removed. */ -__be32 +u32 nlmsvc_unlock(struct nlm_file *file, struct nlm_lock *lock) { int error; @@ -476,7 +476,7 @@ nlmsvc_unlock(struct nlm_file *file, struct nlm_lock *lock) * be in progress. * The calling procedure must check whether the file can be closed. */ -__be32 +u32 nlmsvc_cancel_blocked(struct nlm_file *file, struct nlm_lock *lock) { struct nlm_block *block; diff --git a/trunk/fs/lockd/svcproc.c b/trunk/fs/lockd/svcproc.c index 32e99a6e8dca..75b2c81bcb93 100644 --- a/trunk/fs/lockd/svcproc.c +++ b/trunk/fs/lockd/svcproc.c @@ -22,8 +22,8 @@ #define NLMDBG_FACILITY NLMDBG_CLIENT #ifdef CONFIG_LOCKD_V4 -static __be32 -cast_to_nlm(__be32 status, u32 vers) +static u32 +cast_to_nlm(u32 status, u32 vers) { /* Note: status is assumed to be in network byte order !!! */ if (vers != 4){ @@ -52,14 +52,14 @@ cast_to_nlm(__be32 status, u32 vers) /* * Obtain client and file from arguments */ -static __be32 +static u32 nlmsvc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp, struct nlm_host **hostp, struct nlm_file **filp) { struct nlm_host *host = NULL; struct nlm_file *file = NULL; struct nlm_lock *lock = &argp->lock; - __be32 error = 0; + u32 error; /* nfsd callbacks must have been installed for this procedure */ if (!nlmsvc_ops) @@ -88,15 +88,13 @@ nlmsvc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp, no_locks: if (host) nlm_release_host(host); - if (error) - return error; return nlm_lck_denied_nolocks; } /* * NULL: Test for presence of service */ -static __be32 +static int nlmsvc_proc_null(struct svc_rqst *rqstp, void *argp, void *resp) { dprintk("lockd: NULL called\n"); @@ -106,7 +104,7 @@ nlmsvc_proc_null(struct svc_rqst *rqstp, void *argp, void *resp) /* * TEST: Check for conflicting lock */ -static __be32 +static int nlmsvc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp, struct nlm_res *resp) { @@ -124,7 +122,7 @@ nlmsvc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp, /* Obtain client and file */ if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file))) - return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; + return rpc_success; /* Now check for conflicting locks */ resp->status = cast_status(nlmsvc_testlock(file, &argp->lock, &resp->lock)); @@ -136,7 +134,7 @@ nlmsvc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp, return rpc_success; } -static __be32 +static int nlmsvc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp, struct nlm_res *resp) { @@ -155,7 +153,7 @@ nlmsvc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp, /* Obtain client and file */ if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file))) - return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; + return rpc_success; #if 0 /* If supplied state doesn't match current state, we assume it's @@ -179,7 +177,7 @@ nlmsvc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp, return rpc_success; } -static __be32 +static int nlmsvc_proc_cancel(struct svc_rqst *rqstp, struct nlm_args *argp, struct nlm_res *resp) { @@ -198,7 +196,7 @@ nlmsvc_proc_cancel(struct svc_rqst *rqstp, struct nlm_args *argp, /* Obtain client and file */ if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file))) - return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; + return rpc_success; /* Try to cancel request. */ resp->status = cast_status(nlmsvc_cancel_blocked(file, &argp->lock)); @@ -212,7 +210,7 @@ nlmsvc_proc_cancel(struct svc_rqst *rqstp, struct nlm_args *argp, /* * UNLOCK: release a lock */ -static __be32 +static int nlmsvc_proc_unlock(struct svc_rqst *rqstp, struct nlm_args *argp, struct nlm_res *resp) { @@ -231,7 +229,7 @@ nlmsvc_proc_unlock(struct svc_rqst *rqstp, struct nlm_args *argp, /* Obtain client and file */ if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file))) - return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; + return rpc_success; /* Now try to remove the lock */ resp->status = cast_status(nlmsvc_unlock(file, &argp->lock)); @@ -246,7 +244,7 @@ nlmsvc_proc_unlock(struct svc_rqst *rqstp, struct nlm_args *argp, * GRANTED: A server calls us to tell that a process' lock request * was granted */ -static __be32 +static int nlmsvc_proc_granted(struct svc_rqst *rqstp, struct nlm_args *argp, struct nlm_res *resp) { @@ -282,12 +280,12 @@ static const struct rpc_call_ops nlmsvc_callback_ops = { * because we send the callback before the reply proper. I hope this * doesn't break any clients. */ -static __be32 nlmsvc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_args *argp, - __be32 (*func)(struct svc_rqst *, struct nlm_args *, struct nlm_res *)) +static int nlmsvc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_args *argp, + int (*func)(struct svc_rqst *, struct nlm_args *, struct nlm_res *)) { struct nlm_host *host; struct nlm_rqst *call; - __be32 stat; + int stat; host = nlmsvc_lookup_host(rqstp, argp->lock.caller, @@ -311,28 +309,28 @@ static __be32 nlmsvc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_args return rpc_success; } -static __be32 nlmsvc_proc_test_msg(struct svc_rqst *rqstp, struct nlm_args *argp, +static int nlmsvc_proc_test_msg(struct svc_rqst *rqstp, struct nlm_args *argp, void *resp) { dprintk("lockd: TEST_MSG called\n"); return nlmsvc_callback(rqstp, NLMPROC_TEST_RES, argp, nlmsvc_proc_test); } -static __be32 nlmsvc_proc_lock_msg(struct svc_rqst *rqstp, struct nlm_args *argp, +static int nlmsvc_proc_lock_msg(struct svc_rqst *rqstp, struct nlm_args *argp, void *resp) { dprintk("lockd: LOCK_MSG called\n"); return nlmsvc_callback(rqstp, NLMPROC_LOCK_RES, argp, nlmsvc_proc_lock); } -static __be32 nlmsvc_proc_cancel_msg(struct svc_rqst *rqstp, struct nlm_args *argp, +static int nlmsvc_proc_cancel_msg(struct svc_rqst *rqstp, struct nlm_args *argp, void *resp) { dprintk("lockd: CANCEL_MSG called\n"); return nlmsvc_callback(rqstp, NLMPROC_CANCEL_RES, argp, nlmsvc_proc_cancel); } -static __be32 +static int nlmsvc_proc_unlock_msg(struct svc_rqst *rqstp, struct nlm_args *argp, void *resp) { @@ -340,7 +338,7 @@ nlmsvc_proc_unlock_msg(struct svc_rqst *rqstp, struct nlm_args *argp, return nlmsvc_callback(rqstp, NLMPROC_UNLOCK_RES, argp, nlmsvc_proc_unlock); } -static __be32 +static int nlmsvc_proc_granted_msg(struct svc_rqst *rqstp, struct nlm_args *argp, void *resp) { @@ -351,7 +349,7 @@ nlmsvc_proc_granted_msg(struct svc_rqst *rqstp, struct nlm_args *argp, /* * SHARE: create a DOS share or alter existing share. */ -static __be32 +static int nlmsvc_proc_share(struct svc_rqst *rqstp, struct nlm_args *argp, struct nlm_res *resp) { @@ -370,7 +368,7 @@ nlmsvc_proc_share(struct svc_rqst *rqstp, struct nlm_args *argp, /* Obtain client and file */ if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file))) - return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; + return rpc_success; /* Now try to create the share */ resp->status = cast_status(nlmsvc_share_file(host, file, argp)); @@ -384,7 +382,7 @@ nlmsvc_proc_share(struct svc_rqst *rqstp, struct nlm_args *argp, /* * UNSHARE: Release a DOS share. */ -static __be32 +static int nlmsvc_proc_unshare(struct svc_rqst *rqstp, struct nlm_args *argp, struct nlm_res *resp) { @@ -403,7 +401,7 @@ nlmsvc_proc_unshare(struct svc_rqst *rqstp, struct nlm_args *argp, /* Obtain client and file */ if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file))) - return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; + return rpc_success; /* Now try to unshare the file */ resp->status = cast_status(nlmsvc_unshare_file(host, file, argp)); @@ -417,7 +415,7 @@ nlmsvc_proc_unshare(struct svc_rqst *rqstp, struct nlm_args *argp, /* * NM_LOCK: Create an unmonitored lock */ -static __be32 +static int nlmsvc_proc_nm_lock(struct svc_rqst *rqstp, struct nlm_args *argp, struct nlm_res *resp) { @@ -430,7 +428,7 @@ nlmsvc_proc_nm_lock(struct svc_rqst *rqstp, struct nlm_args *argp, /* * FREE_ALL: Release all locks and shares held by client */ -static __be32 +static int nlmsvc_proc_free_all(struct svc_rqst *rqstp, struct nlm_args *argp, void *resp) { @@ -448,7 +446,7 @@ nlmsvc_proc_free_all(struct svc_rqst *rqstp, struct nlm_args *argp, /* * SM_NOTIFY: private callback from statd (not part of official NLM proto) */ -static __be32 +static int nlmsvc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp, void *resp) { @@ -477,7 +475,7 @@ nlmsvc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp, /* * client sent a GRANTED_RES, let's remove the associated block */ -static __be32 +static int nlmsvc_proc_granted_res(struct svc_rqst *rqstp, struct nlm_res *argp, void *resp) { diff --git a/trunk/fs/lockd/svcshare.c b/trunk/fs/lockd/svcshare.c index 6220dc2a3f2c..b9926ce8782e 100644 --- a/trunk/fs/lockd/svcshare.c +++ b/trunk/fs/lockd/svcshare.c @@ -23,7 +23,7 @@ nlm_cmp_owner(struct nlm_share *share, struct xdr_netobj *oh) && !memcmp(share->s_owner.data, oh->data, oh->len); } -__be32 +u32 nlmsvc_share_file(struct nlm_host *host, struct nlm_file *file, struct nlm_args *argp) { @@ -64,7 +64,7 @@ nlmsvc_share_file(struct nlm_host *host, struct nlm_file *file, /* * Delete a share. */ -__be32 +u32 nlmsvc_unshare_file(struct nlm_host *host, struct nlm_file *file, struct nlm_args *argp) { diff --git a/trunk/fs/lockd/svcsubs.c b/trunk/fs/lockd/svcsubs.c index e83024e16042..514f5f20701e 100644 --- a/trunk/fs/lockd/svcsubs.c +++ b/trunk/fs/lockd/svcsubs.c @@ -78,14 +78,14 @@ static inline unsigned int file_hash(struct nfs_fh *f) * This is not quite right, but for now, we assume the client performs * the proper R/W checking. */ -__be32 +u32 nlm_lookup_file(struct svc_rqst *rqstp, struct nlm_file **result, struct nfs_fh *f) { struct hlist_node *pos; struct nlm_file *file; unsigned int hash; - __be32 nfserr; + u32 nfserr; nlm_debug_print_fh("nlm_file_lookup", f); @@ -135,6 +135,12 @@ nlm_lookup_file(struct svc_rqst *rqstp, struct nlm_file **result, out_free: kfree(file); +#ifdef CONFIG_LOCKD_V4 + if (nfserr == 1) + nfserr = nlm4_stale_fh; + else +#endif + nfserr = nlm_lck_denied; goto out_unlock; } @@ -318,16 +324,7 @@ nlmsvc_same_host(struct nlm_host *host, struct nlm_host *other) static int nlmsvc_is_client(struct nlm_host *host, struct nlm_host *dummy) { - if (host->h_server) { - /* we are destroying locks even though the client - * hasn't asked us too, so don't unmonitor the - * client - */ - if (host->h_nsmhandle) - host->h_nsmhandle->sm_sticky = 1; - return 1; - } else - return 0; + return host->h_server; } /* diff --git a/trunk/fs/lockd/xdr.c b/trunk/fs/lockd/xdr.c index b7c949256e5a..61c46facf257 100644 --- a/trunk/fs/lockd/xdr.c +++ b/trunk/fs/lockd/xdr.c @@ -43,7 +43,7 @@ loff_t_to_s32(loff_t offset) /* * XDR functions for basic NLM types */ -static __be32 *nlm_decode_cookie(__be32 *p, struct nlm_cookie *c) +static u32 *nlm_decode_cookie(u32 *p, struct nlm_cookie *c) { unsigned int len; @@ -69,8 +69,8 @@ static __be32 *nlm_decode_cookie(__be32 *p, struct nlm_cookie *c) return p; } -static inline __be32 * -nlm_encode_cookie(__be32 *p, struct nlm_cookie *c) +static inline u32 * +nlm_encode_cookie(u32 *p, struct nlm_cookie *c) { *p++ = htonl(c->len); memcpy(p, c->data, c->len); @@ -78,8 +78,8 @@ nlm_encode_cookie(__be32 *p, struct nlm_cookie *c) return p; } -static __be32 * -nlm_decode_fh(__be32 *p, struct nfs_fh *f) +static u32 * +nlm_decode_fh(u32 *p, struct nfs_fh *f) { unsigned int len; @@ -95,8 +95,8 @@ nlm_decode_fh(__be32 *p, struct nfs_fh *f) return p + XDR_QUADLEN(NFS2_FHSIZE); } -static inline __be32 * -nlm_encode_fh(__be32 *p, struct nfs_fh *f) +static inline u32 * +nlm_encode_fh(u32 *p, struct nfs_fh *f) { *p++ = htonl(NFS2_FHSIZE); memcpy(p, f->data, NFS2_FHSIZE); @@ -106,20 +106,20 @@ nlm_encode_fh(__be32 *p, struct nfs_fh *f) /* * Encode and decode owner handle */ -static inline __be32 * -nlm_decode_oh(__be32 *p, struct xdr_netobj *oh) +static inline u32 * +nlm_decode_oh(u32 *p, struct xdr_netobj *oh) { return xdr_decode_netobj(p, oh); } -static inline __be32 * -nlm_encode_oh(__be32 *p, struct xdr_netobj *oh) +static inline u32 * +nlm_encode_oh(u32 *p, struct xdr_netobj *oh) { return xdr_encode_netobj(p, oh); } -static __be32 * -nlm_decode_lock(__be32 *p, struct nlm_lock *lock) +static u32 * +nlm_decode_lock(u32 *p, struct nlm_lock *lock) { struct file_lock *fl = &lock->fl; s32 start, len, end; @@ -153,8 +153,8 @@ nlm_decode_lock(__be32 *p, struct nlm_lock *lock) /* * Encode a lock as part of an NLM call */ -static __be32 * -nlm_encode_lock(__be32 *p, struct nlm_lock *lock) +static u32 * +nlm_encode_lock(u32 *p, struct nlm_lock *lock) { struct file_lock *fl = &lock->fl; __s32 start, len; @@ -184,8 +184,8 @@ nlm_encode_lock(__be32 *p, struct nlm_lock *lock) /* * Encode result of a TEST/TEST_MSG call */ -static __be32 * -nlm_encode_testres(__be32 *p, struct nlm_res *resp) +static u32 * +nlm_encode_testres(u32 *p, struct nlm_res *resp) { s32 start, len; @@ -221,7 +221,7 @@ nlm_encode_testres(__be32 *p, struct nlm_res *resp) * First, the server side XDR functions */ int -nlmsvc_decode_testargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp) +nlmsvc_decode_testargs(struct svc_rqst *rqstp, u32 *p, nlm_args *argp) { u32 exclusive; @@ -238,7 +238,7 @@ nlmsvc_decode_testargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp) } int -nlmsvc_encode_testres(struct svc_rqst *rqstp, __be32 *p, struct nlm_res *resp) +nlmsvc_encode_testres(struct svc_rqst *rqstp, u32 *p, struct nlm_res *resp) { if (!(p = nlm_encode_testres(p, resp))) return 0; @@ -246,7 +246,7 @@ nlmsvc_encode_testres(struct svc_rqst *rqstp, __be32 *p, struct nlm_res *resp) } int -nlmsvc_decode_lockargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp) +nlmsvc_decode_lockargs(struct svc_rqst *rqstp, u32 *p, nlm_args *argp) { u32 exclusive; @@ -266,7 +266,7 @@ nlmsvc_decode_lockargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp) } int -nlmsvc_decode_cancargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp) +nlmsvc_decode_cancargs(struct svc_rqst *rqstp, u32 *p, nlm_args *argp) { u32 exclusive; @@ -282,7 +282,7 @@ nlmsvc_decode_cancargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp) } int -nlmsvc_decode_unlockargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp) +nlmsvc_decode_unlockargs(struct svc_rqst *rqstp, u32 *p, nlm_args *argp) { if (!(p = nlm_decode_cookie(p, &argp->cookie)) || !(p = nlm_decode_lock(p, &argp->lock))) @@ -292,7 +292,7 @@ nlmsvc_decode_unlockargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp) } int -nlmsvc_decode_shareargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp) +nlmsvc_decode_shareargs(struct svc_rqst *rqstp, u32 *p, nlm_args *argp) { struct nlm_lock *lock = &argp->lock; @@ -313,7 +313,7 @@ nlmsvc_decode_shareargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp) } int -nlmsvc_encode_shareres(struct svc_rqst *rqstp, __be32 *p, struct nlm_res *resp) +nlmsvc_encode_shareres(struct svc_rqst *rqstp, u32 *p, struct nlm_res *resp) { if (!(p = nlm_encode_cookie(p, &resp->cookie))) return 0; @@ -323,7 +323,7 @@ nlmsvc_encode_shareres(struct svc_rqst *rqstp, __be32 *p, struct nlm_res *resp) } int -nlmsvc_encode_res(struct svc_rqst *rqstp, __be32 *p, struct nlm_res *resp) +nlmsvc_encode_res(struct svc_rqst *rqstp, u32 *p, struct nlm_res *resp) { if (!(p = nlm_encode_cookie(p, &resp->cookie))) return 0; @@ -332,7 +332,7 @@ nlmsvc_encode_res(struct svc_rqst *rqstp, __be32 *p, struct nlm_res *resp) } int -nlmsvc_decode_notify(struct svc_rqst *rqstp, __be32 *p, struct nlm_args *argp) +nlmsvc_decode_notify(struct svc_rqst *rqstp, u32 *p, struct nlm_args *argp) { struct nlm_lock *lock = &argp->lock; @@ -344,7 +344,7 @@ nlmsvc_decode_notify(struct svc_rqst *rqstp, __be32 *p, struct nlm_args *argp) } int -nlmsvc_decode_reboot(struct svc_rqst *rqstp, __be32 *p, struct nlm_reboot *argp) +nlmsvc_decode_reboot(struct svc_rqst *rqstp, u32 *p, struct nlm_reboot *argp) { if (!(p = xdr_decode_string_inplace(p, &argp->mon, &argp->len, SM_MAXSTRLEN))) return 0; @@ -357,7 +357,7 @@ nlmsvc_decode_reboot(struct svc_rqst *rqstp, __be32 *p, struct nlm_reboot *argp) } int -nlmsvc_decode_res(struct svc_rqst *rqstp, __be32 *p, struct nlm_res *resp) +nlmsvc_decode_res(struct svc_rqst *rqstp, u32 *p, struct nlm_res *resp) { if (!(p = nlm_decode_cookie(p, &resp->cookie))) return 0; @@ -366,13 +366,13 @@ nlmsvc_decode_res(struct svc_rqst *rqstp, __be32 *p, struct nlm_res *resp) } int -nlmsvc_decode_void(struct svc_rqst *rqstp, __be32 *p, void *dummy) +nlmsvc_decode_void(struct svc_rqst *rqstp, u32 *p, void *dummy) { return xdr_argsize_check(rqstp, p); } int -nlmsvc_encode_void(struct svc_rqst *rqstp, __be32 *p, void *dummy) +nlmsvc_encode_void(struct svc_rqst *rqstp, u32 *p, void *dummy) { return xdr_ressize_check(rqstp, p); } @@ -389,7 +389,7 @@ nlmclt_decode_void(struct rpc_rqst *req, u32 *p, void *ptr) #endif static int -nlmclt_encode_testargs(struct rpc_rqst *req, __be32 *p, nlm_args *argp) +nlmclt_encode_testargs(struct rpc_rqst *req, u32 *p, nlm_args *argp) { struct nlm_lock *lock = &argp->lock; @@ -403,7 +403,7 @@ nlmclt_encode_testargs(struct rpc_rqst *req, __be32 *p, nlm_args *argp) } static int -nlmclt_decode_testres(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp) +nlmclt_decode_testres(struct rpc_rqst *req, u32 *p, struct nlm_res *resp) { if (!(p = nlm_decode_cookie(p, &resp->cookie))) return -EIO; @@ -438,7 +438,7 @@ nlmclt_decode_testres(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp) static int -nlmclt_encode_lockargs(struct rpc_rqst *req, __be32 *p, nlm_args *argp) +nlmclt_encode_lockargs(struct rpc_rqst *req, u32 *p, nlm_args *argp) { struct nlm_lock *lock = &argp->lock; @@ -455,7 +455,7 @@ nlmclt_encode_lockargs(struct rpc_rqst *req, __be32 *p, nlm_args *argp) } static int -nlmclt_encode_cancargs(struct rpc_rqst *req, __be32 *p, nlm_args *argp) +nlmclt_encode_cancargs(struct rpc_rqst *req, u32 *p, nlm_args *argp) { struct nlm_lock *lock = &argp->lock; @@ -470,7 +470,7 @@ nlmclt_encode_cancargs(struct rpc_rqst *req, __be32 *p, nlm_args *argp) } static int -nlmclt_encode_unlockargs(struct rpc_rqst *req, __be32 *p, nlm_args *argp) +nlmclt_encode_unlockargs(struct rpc_rqst *req, u32 *p, nlm_args *argp) { struct nlm_lock *lock = &argp->lock; @@ -483,7 +483,7 @@ nlmclt_encode_unlockargs(struct rpc_rqst *req, __be32 *p, nlm_args *argp) } static int -nlmclt_encode_res(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp) +nlmclt_encode_res(struct rpc_rqst *req, u32 *p, struct nlm_res *resp) { if (!(p = nlm_encode_cookie(p, &resp->cookie))) return -EIO; @@ -493,7 +493,7 @@ nlmclt_encode_res(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp) } static int -nlmclt_encode_testres(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp) +nlmclt_encode_testres(struct rpc_rqst *req, u32 *p, struct nlm_res *resp) { if (!(p = nlm_encode_testres(p, resp))) return -EIO; @@ -502,7 +502,7 @@ nlmclt_encode_testres(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp) } static int -nlmclt_decode_res(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp) +nlmclt_decode_res(struct rpc_rqst *req, u32 *p, struct nlm_res *resp) { if (!(p = nlm_decode_cookie(p, &resp->cookie))) return -EIO; diff --git a/trunk/fs/lockd/xdr4.c b/trunk/fs/lockd/xdr4.c index f4c0b2b9f75a..36eb175ec335 100644 --- a/trunk/fs/lockd/xdr4.c +++ b/trunk/fs/lockd/xdr4.c @@ -44,8 +44,8 @@ loff_t_to_s64(loff_t offset) /* * XDR functions for basic NLM types */ -static __be32 * -nlm4_decode_cookie(__be32 *p, struct nlm_cookie *c) +static u32 * +nlm4_decode_cookie(u32 *p, struct nlm_cookie *c) { unsigned int len; @@ -71,8 +71,8 @@ nlm4_decode_cookie(__be32 *p, struct nlm_cookie *c) return p; } -static __be32 * -nlm4_encode_cookie(__be32 *p, struct nlm_cookie *c) +static u32 * +nlm4_encode_cookie(u32 *p, struct nlm_cookie *c) { *p++ = htonl(c->len); memcpy(p, c->data, c->len); @@ -80,8 +80,8 @@ nlm4_encode_cookie(__be32 *p, struct nlm_cookie *c) return p; } -static __be32 * -nlm4_decode_fh(__be32 *p, struct nfs_fh *f) +static u32 * +nlm4_decode_fh(u32 *p, struct nfs_fh *f) { memset(f->data, 0, sizeof(f->data)); f->size = ntohl(*p++); @@ -95,8 +95,8 @@ nlm4_decode_fh(__be32 *p, struct nfs_fh *f) return p + XDR_QUADLEN(f->size); } -static __be32 * -nlm4_encode_fh(__be32 *p, struct nfs_fh *f) +static u32 * +nlm4_encode_fh(u32 *p, struct nfs_fh *f) { *p++ = htonl(f->size); if (f->size) p[XDR_QUADLEN(f->size)-1] = 0; /* don't leak anything */ @@ -107,20 +107,20 @@ nlm4_encode_fh(__be32 *p, struct nfs_fh *f) /* * Encode and decode owner handle */ -static __be32 * -nlm4_decode_oh(__be32 *p, struct xdr_netobj *oh) +static u32 * +nlm4_decode_oh(u32 *p, struct xdr_netobj *oh) { return xdr_decode_netobj(p, oh); } -static __be32 * -nlm4_encode_oh(__be32 *p, struct xdr_netobj *oh) +static u32 * +nlm4_encode_oh(u32 *p, struct xdr_netobj *oh) { return xdr_encode_netobj(p, oh); } -static __be32 * -nlm4_decode_lock(__be32 *p, struct nlm_lock *lock) +static u32 * +nlm4_decode_lock(u32 *p, struct nlm_lock *lock) { struct file_lock *fl = &lock->fl; __s64 len, start, end; @@ -153,8 +153,8 @@ nlm4_decode_lock(__be32 *p, struct nlm_lock *lock) /* * Encode a lock as part of an NLM call */ -static __be32 * -nlm4_encode_lock(__be32 *p, struct nlm_lock *lock) +static u32 * +nlm4_encode_lock(u32 *p, struct nlm_lock *lock) { struct file_lock *fl = &lock->fl; __s64 start, len; @@ -185,8 +185,8 @@ nlm4_encode_lock(__be32 *p, struct nlm_lock *lock) /* * Encode result of a TEST/TEST_MSG call */ -static __be32 * -nlm4_encode_testres(__be32 *p, struct nlm_res *resp) +static u32 * +nlm4_encode_testres(u32 *p, struct nlm_res *resp) { s64 start, len; @@ -227,7 +227,7 @@ nlm4_encode_testres(__be32 *p, struct nlm_res *resp) * First, the server side XDR functions */ int -nlm4svc_decode_testargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp) +nlm4svc_decode_testargs(struct svc_rqst *rqstp, u32 *p, nlm_args *argp) { u32 exclusive; @@ -244,7 +244,7 @@ nlm4svc_decode_testargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp) } int -nlm4svc_encode_testres(struct svc_rqst *rqstp, __be32 *p, struct nlm_res *resp) +nlm4svc_encode_testres(struct svc_rqst *rqstp, u32 *p, struct nlm_res *resp) { if (!(p = nlm4_encode_testres(p, resp))) return 0; @@ -252,7 +252,7 @@ nlm4svc_encode_testres(struct svc_rqst *rqstp, __be32 *p, struct nlm_res *resp) } int -nlm4svc_decode_lockargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp) +nlm4svc_decode_lockargs(struct svc_rqst *rqstp, u32 *p, nlm_args *argp) { u32 exclusive; @@ -272,7 +272,7 @@ nlm4svc_decode_lockargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp) } int -nlm4svc_decode_cancargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp) +nlm4svc_decode_cancargs(struct svc_rqst *rqstp, u32 *p, nlm_args *argp) { u32 exclusive; @@ -288,7 +288,7 @@ nlm4svc_decode_cancargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp) } int -nlm4svc_decode_unlockargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp) +nlm4svc_decode_unlockargs(struct svc_rqst *rqstp, u32 *p, nlm_args *argp) { if (!(p = nlm4_decode_cookie(p, &argp->cookie)) || !(p = nlm4_decode_lock(p, &argp->lock))) @@ -298,7 +298,7 @@ nlm4svc_decode_unlockargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp) } int -nlm4svc_decode_shareargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp) +nlm4svc_decode_shareargs(struct svc_rqst *rqstp, u32 *p, nlm_args *argp) { struct nlm_lock *lock = &argp->lock; @@ -319,7 +319,7 @@ nlm4svc_decode_shareargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp) } int -nlm4svc_encode_shareres(struct svc_rqst *rqstp, __be32 *p, struct nlm_res *resp) +nlm4svc_encode_shareres(struct svc_rqst *rqstp, u32 *p, struct nlm_res *resp) { if (!(p = nlm4_encode_cookie(p, &resp->cookie))) return 0; @@ -329,7 +329,7 @@ nlm4svc_encode_shareres(struct svc_rqst *rqstp, __be32 *p, struct nlm_res *resp) } int -nlm4svc_encode_res(struct svc_rqst *rqstp, __be32 *p, struct nlm_res *resp) +nlm4svc_encode_res(struct svc_rqst *rqstp, u32 *p, struct nlm_res *resp) { if (!(p = nlm4_encode_cookie(p, &resp->cookie))) return 0; @@ -338,7 +338,7 @@ nlm4svc_encode_res(struct svc_rqst *rqstp, __be32 *p, struct nlm_res *resp) } int -nlm4svc_decode_notify(struct svc_rqst *rqstp, __be32 *p, struct nlm_args *argp) +nlm4svc_decode_notify(struct svc_rqst *rqstp, u32 *p, struct nlm_args *argp) { struct nlm_lock *lock = &argp->lock; @@ -350,7 +350,7 @@ nlm4svc_decode_notify(struct svc_rqst *rqstp, __be32 *p, struct nlm_args *argp) } int -nlm4svc_decode_reboot(struct svc_rqst *rqstp, __be32 *p, struct nlm_reboot *argp) +nlm4svc_decode_reboot(struct svc_rqst *rqstp, u32 *p, struct nlm_reboot *argp) { if (!(p = xdr_decode_string_inplace(p, &argp->mon, &argp->len, SM_MAXSTRLEN))) return 0; @@ -363,7 +363,7 @@ nlm4svc_decode_reboot(struct svc_rqst *rqstp, __be32 *p, struct nlm_reboot *argp } int -nlm4svc_decode_res(struct svc_rqst *rqstp, __be32 *p, struct nlm_res *resp) +nlm4svc_decode_res(struct svc_rqst *rqstp, u32 *p, struct nlm_res *resp) { if (!(p = nlm4_decode_cookie(p, &resp->cookie))) return 0; @@ -372,13 +372,13 @@ nlm4svc_decode_res(struct svc_rqst *rqstp, __be32 *p, struct nlm_res *resp) } int -nlm4svc_decode_void(struct svc_rqst *rqstp, __be32 *p, void *dummy) +nlm4svc_decode_void(struct svc_rqst *rqstp, u32 *p, void *dummy) { return xdr_argsize_check(rqstp, p); } int -nlm4svc_encode_void(struct svc_rqst *rqstp, __be32 *p, void *dummy) +nlm4svc_encode_void(struct svc_rqst *rqstp, u32 *p, void *dummy) { return xdr_ressize_check(rqstp, p); } @@ -388,14 +388,14 @@ nlm4svc_encode_void(struct svc_rqst *rqstp, __be32 *p, void *dummy) */ #ifdef NLMCLNT_SUPPORT_SHARES static int -nlm4clt_decode_void(struct rpc_rqst *req, __be32 *p, void *ptr) +nlm4clt_decode_void(struct rpc_rqst *req, u32 *p, void *ptr) { return 0; } #endif static int -nlm4clt_encode_testargs(struct rpc_rqst *req, __be32 *p, nlm_args *argp) +nlm4clt_encode_testargs(struct rpc_rqst *req, u32 *p, nlm_args *argp) { struct nlm_lock *lock = &argp->lock; @@ -409,7 +409,7 @@ nlm4clt_encode_testargs(struct rpc_rqst *req, __be32 *p, nlm_args *argp) } static int -nlm4clt_decode_testres(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp) +nlm4clt_decode_testres(struct rpc_rqst *req, u32 *p, struct nlm_res *resp) { if (!(p = nlm4_decode_cookie(p, &resp->cookie))) return -EIO; @@ -444,7 +444,7 @@ nlm4clt_decode_testres(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp) static int -nlm4clt_encode_lockargs(struct rpc_rqst *req, __be32 *p, nlm_args *argp) +nlm4clt_encode_lockargs(struct rpc_rqst *req, u32 *p, nlm_args *argp) { struct nlm_lock *lock = &argp->lock; @@ -461,7 +461,7 @@ nlm4clt_encode_lockargs(struct rpc_rqst *req, __be32 *p, nlm_args *argp) } static int -nlm4clt_encode_cancargs(struct rpc_rqst *req, __be32 *p, nlm_args *argp) +nlm4clt_encode_cancargs(struct rpc_rqst *req, u32 *p, nlm_args *argp) { struct nlm_lock *lock = &argp->lock; @@ -476,7 +476,7 @@ nlm4clt_encode_cancargs(struct rpc_rqst *req, __be32 *p, nlm_args *argp) } static int -nlm4clt_encode_unlockargs(struct rpc_rqst *req, __be32 *p, nlm_args *argp) +nlm4clt_encode_unlockargs(struct rpc_rqst *req, u32 *p, nlm_args *argp) { struct nlm_lock *lock = &argp->lock; @@ -489,7 +489,7 @@ nlm4clt_encode_unlockargs(struct rpc_rqst *req, __be32 *p, nlm_args *argp) } static int -nlm4clt_encode_res(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp) +nlm4clt_encode_res(struct rpc_rqst *req, u32 *p, struct nlm_res *resp) { if (!(p = nlm4_encode_cookie(p, &resp->cookie))) return -EIO; @@ -499,7 +499,7 @@ nlm4clt_encode_res(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp) } static int -nlm4clt_encode_testres(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp) +nlm4clt_encode_testres(struct rpc_rqst *req, u32 *p, struct nlm_res *resp) { if (!(p = nlm4_encode_testres(p, resp))) return -EIO; @@ -508,7 +508,7 @@ nlm4clt_encode_testres(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp) } static int -nlm4clt_decode_res(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp) +nlm4clt_decode_res(struct rpc_rqst *req, u32 *p, struct nlm_res *resp) { if (!(p = nlm4_decode_cookie(p, &resp->cookie))) return -EIO; diff --git a/trunk/fs/minix/inode.c b/trunk/fs/minix/inode.c index 1e36bae4d0eb..c11a4b9fb863 100644 --- a/trunk/fs/minix/inode.c +++ b/trunk/fs/minix/inode.c @@ -149,8 +149,12 @@ static int minix_fill_super(struct super_block *s, void *data, int silent) return -ENOMEM; s->s_fs_info = sbi; - BUILD_BUG_ON(32 != sizeof (struct minix_inode)); - BUILD_BUG_ON(64 != sizeof(struct minix2_inode)); + /* N.B. These should be compile-time tests. + Unfortunately that is impossible. */ + if (32 != sizeof (struct minix_inode)) + panic("bad V1 i-node size"); + if (64 != sizeof(struct minix2_inode)) + panic("bad V2 i-node size"); if (!sb_set_blocksize(s, BLOCK_SIZE)) goto out_bad_hblock; diff --git a/trunk/fs/msdos/namei.c b/trunk/fs/msdos/namei.c index 452461955cbd..b0f01b3b0536 100644 --- a/trunk/fs/msdos/namei.c +++ b/trunk/fs/msdos/namei.c @@ -654,7 +654,6 @@ static struct inode_operations msdos_dir_inode_operations = { .rmdir = msdos_rmdir, .rename = msdos_rename, .setattr = fat_notify_change, - .getattr = fat_getattr, }; static int msdos_fill_super(struct super_block *sb, void *data, int silent) diff --git a/trunk/fs/ncpfs/ioctl.c b/trunk/fs/ncpfs/ioctl.c index 589d1eac55c1..a89ac84a8241 100644 --- a/trunk/fs/ncpfs/ioctl.c +++ b/trunk/fs/ncpfs/ioctl.c @@ -726,7 +726,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp, struct compat_ncp_privatedata_ioctl user32; user32.len = user.len; user32.data = (unsigned long) user.data; - if (copy_to_user(argp, &user32, sizeof(user32))) + if (copy_to_user(&user32, argp, sizeof(user32))) return -EFAULT; } else #endif diff --git a/trunk/fs/nfs/callback.h b/trunk/fs/nfs/callback.h index db3d7919c601..5676163d26e8 100644 --- a/trunk/fs/nfs/callback.h +++ b/trunk/fs/nfs/callback.h @@ -31,10 +31,10 @@ struct cb_compound_hdr_arg { }; struct cb_compound_hdr_res { - __be32 *status; + uint32_t *status; int taglen; const char *tag; - __be32 *nops; + uint32_t *nops; }; struct cb_getattrargs { @@ -44,7 +44,7 @@ struct cb_getattrargs { }; struct cb_getattrres { - __be32 status; + uint32_t status; uint32_t bitmap[2]; uint64_t size; uint64_t change_attr; @@ -59,8 +59,8 @@ struct cb_recallargs { uint32_t truncate; }; -extern __be32 nfs4_callback_getattr(struct cb_getattrargs *args, struct cb_getattrres *res); -extern __be32 nfs4_callback_recall(struct cb_recallargs *args, void *dummy); +extern unsigned nfs4_callback_getattr(struct cb_getattrargs *args, struct cb_getattrres *res); +extern unsigned nfs4_callback_recall(struct cb_recallargs *args, void *dummy); #ifdef CONFIG_NFS_V4 extern int nfs_callback_up(void); diff --git a/trunk/fs/nfs/callback_proc.c b/trunk/fs/nfs/callback_proc.c index 72e55d83756d..97cf8f71451f 100644 --- a/trunk/fs/nfs/callback_proc.c +++ b/trunk/fs/nfs/callback_proc.c @@ -14,7 +14,7 @@ #define NFSDBG_FACILITY NFSDBG_CALLBACK -__be32 nfs4_callback_getattr(struct cb_getattrargs *args, struct cb_getattrres *res) +unsigned nfs4_callback_getattr(struct cb_getattrargs *args, struct cb_getattrres *res) { struct nfs_client *clp; struct nfs_delegation *delegation; @@ -55,11 +55,11 @@ __be32 nfs4_callback_getattr(struct cb_getattrargs *args, struct cb_getattrres * return res->status; } -__be32 nfs4_callback_recall(struct cb_recallargs *args, void *dummy) +unsigned nfs4_callback_recall(struct cb_recallargs *args, void *dummy) { struct nfs_client *clp; struct inode *inode; - __be32 res; + unsigned res; res = htonl(NFS4ERR_BADHANDLE); clp = nfs_find_client(args->addr, 4); diff --git a/trunk/fs/nfs/callback_xdr.c b/trunk/fs/nfs/callback_xdr.c index f8ea1f51f590..29f932192054 100644 --- a/trunk/fs/nfs/callback_xdr.c +++ b/trunk/fs/nfs/callback_xdr.c @@ -22,9 +22,9 @@ #define NFSDBG_FACILITY NFSDBG_CALLBACK -typedef __be32 (*callback_process_op_t)(void *, void *); -typedef __be32 (*callback_decode_arg_t)(struct svc_rqst *, struct xdr_stream *, void *); -typedef __be32 (*callback_encode_res_t)(struct svc_rqst *, struct xdr_stream *, void *); +typedef unsigned (*callback_process_op_t)(void *, void *); +typedef unsigned (*callback_decode_arg_t)(struct svc_rqst *, struct xdr_stream *, void *); +typedef unsigned (*callback_encode_res_t)(struct svc_rqst *, struct xdr_stream *, void *); struct callback_op { @@ -36,24 +36,24 @@ struct callback_op { static struct callback_op callback_ops[]; -static __be32 nfs4_callback_null(struct svc_rqst *rqstp, void *argp, void *resp) +static int nfs4_callback_null(struct svc_rqst *rqstp, void *argp, void *resp) { return htonl(NFS4_OK); } -static int nfs4_decode_void(struct svc_rqst *rqstp, __be32 *p, void *dummy) +static int nfs4_decode_void(struct svc_rqst *rqstp, uint32_t *p, void *dummy) { return xdr_argsize_check(rqstp, p); } -static int nfs4_encode_void(struct svc_rqst *rqstp, __be32 *p, void *dummy) +static int nfs4_encode_void(struct svc_rqst *rqstp, uint32_t *p, void *dummy) { return xdr_ressize_check(rqstp, p); } -static __be32 *read_buf(struct xdr_stream *xdr, int nbytes) +static uint32_t *read_buf(struct xdr_stream *xdr, int nbytes) { - __be32 *p; + uint32_t *p; p = xdr_inline_decode(xdr, nbytes); if (unlikely(p == NULL)) @@ -61,9 +61,9 @@ static __be32 *read_buf(struct xdr_stream *xdr, int nbytes) return p; } -static __be32 decode_string(struct xdr_stream *xdr, unsigned int *len, const char **str) +static unsigned decode_string(struct xdr_stream *xdr, unsigned int *len, const char **str) { - __be32 *p; + uint32_t *p; p = read_buf(xdr, 4); if (unlikely(p == NULL)) @@ -81,9 +81,9 @@ static __be32 decode_string(struct xdr_stream *xdr, unsigned int *len, const cha return 0; } -static __be32 decode_fh(struct xdr_stream *xdr, struct nfs_fh *fh) +static unsigned decode_fh(struct xdr_stream *xdr, struct nfs_fh *fh) { - __be32 *p; + uint32_t *p; p = read_buf(xdr, 4); if (unlikely(p == NULL)) @@ -99,9 +99,9 @@ static __be32 decode_fh(struct xdr_stream *xdr, struct nfs_fh *fh) return 0; } -static __be32 decode_bitmap(struct xdr_stream *xdr, uint32_t *bitmap) +static unsigned decode_bitmap(struct xdr_stream *xdr, uint32_t *bitmap) { - __be32 *p; + uint32_t *p; unsigned int attrlen; p = read_buf(xdr, 4); @@ -118,9 +118,9 @@ static __be32 decode_bitmap(struct xdr_stream *xdr, uint32_t *bitmap) return 0; } -static __be32 decode_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid) +static unsigned decode_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid) { - __be32 *p; + uint32_t *p; p = read_buf(xdr, 16); if (unlikely(p == NULL)) @@ -129,11 +129,11 @@ static __be32 decode_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid) return 0; } -static __be32 decode_compound_hdr_arg(struct xdr_stream *xdr, struct cb_compound_hdr_arg *hdr) +static unsigned decode_compound_hdr_arg(struct xdr_stream *xdr, struct cb_compound_hdr_arg *hdr) { - __be32 *p; + uint32_t *p; unsigned int minor_version; - __be32 status; + unsigned status; status = decode_string(xdr, &hdr->taglen, &hdr->tag); if (unlikely(status != 0)) @@ -159,9 +159,9 @@ static __be32 decode_compound_hdr_arg(struct xdr_stream *xdr, struct cb_compound return 0; } -static __be32 decode_op_hdr(struct xdr_stream *xdr, unsigned int *op) +static unsigned decode_op_hdr(struct xdr_stream *xdr, unsigned int *op) { - __be32 *p; + uint32_t *p; p = read_buf(xdr, 4); if (unlikely(p == NULL)) return htonl(NFS4ERR_RESOURCE); @@ -169,9 +169,9 @@ static __be32 decode_op_hdr(struct xdr_stream *xdr, unsigned int *op) return 0; } -static __be32 decode_getattr_args(struct svc_rqst *rqstp, struct xdr_stream *xdr, struct cb_getattrargs *args) +static unsigned decode_getattr_args(struct svc_rqst *rqstp, struct xdr_stream *xdr, struct cb_getattrargs *args) { - __be32 status; + unsigned status; status = decode_fh(xdr, &args->fh); if (unlikely(status != 0)) @@ -183,10 +183,10 @@ static __be32 decode_getattr_args(struct svc_rqst *rqstp, struct xdr_stream *xdr return status; } -static __be32 decode_recall_args(struct svc_rqst *rqstp, struct xdr_stream *xdr, struct cb_recallargs *args) +static unsigned decode_recall_args(struct svc_rqst *rqstp, struct xdr_stream *xdr, struct cb_recallargs *args) { - __be32 *p; - __be32 status; + uint32_t *p; + unsigned status; args->addr = &rqstp->rq_addr; status = decode_stateid(xdr, &args->stateid); @@ -204,9 +204,9 @@ static __be32 decode_recall_args(struct svc_rqst *rqstp, struct xdr_stream *xdr, return status; } -static __be32 encode_string(struct xdr_stream *xdr, unsigned int len, const char *str) +static unsigned encode_string(struct xdr_stream *xdr, unsigned int len, const char *str) { - __be32 *p; + uint32_t *p; p = xdr_reserve_space(xdr, 4 + len); if (unlikely(p == NULL)) @@ -217,10 +217,10 @@ static __be32 encode_string(struct xdr_stream *xdr, unsigned int len, const char #define CB_SUPPORTED_ATTR0 (FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE) #define CB_SUPPORTED_ATTR1 (FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY) -static __be32 encode_attr_bitmap(struct xdr_stream *xdr, const uint32_t *bitmap, __be32 **savep) +static unsigned encode_attr_bitmap(struct xdr_stream *xdr, const uint32_t *bitmap, uint32_t **savep) { - __be32 bm[2]; - __be32 *p; + uint32_t bm[2]; + uint32_t *p; bm[0] = htonl(bitmap[0] & CB_SUPPORTED_ATTR0); bm[1] = htonl(bitmap[1] & CB_SUPPORTED_ATTR1); @@ -247,9 +247,9 @@ static __be32 encode_attr_bitmap(struct xdr_stream *xdr, const uint32_t *bitmap, return 0; } -static __be32 encode_attr_change(struct xdr_stream *xdr, const uint32_t *bitmap, uint64_t change) +static unsigned encode_attr_change(struct xdr_stream *xdr, const uint32_t *bitmap, uint64_t change) { - __be32 *p; + uint32_t *p; if (!(bitmap[0] & FATTR4_WORD0_CHANGE)) return 0; @@ -260,9 +260,9 @@ static __be32 encode_attr_change(struct xdr_stream *xdr, const uint32_t *bitmap, return 0; } -static __be32 encode_attr_size(struct xdr_stream *xdr, const uint32_t *bitmap, uint64_t size) +static unsigned encode_attr_size(struct xdr_stream *xdr, const uint32_t *bitmap, uint64_t size) { - __be32 *p; + uint32_t *p; if (!(bitmap[0] & FATTR4_WORD0_SIZE)) return 0; @@ -273,9 +273,9 @@ static __be32 encode_attr_size(struct xdr_stream *xdr, const uint32_t *bitmap, u return 0; } -static __be32 encode_attr_time(struct xdr_stream *xdr, const struct timespec *time) +static unsigned encode_attr_time(struct xdr_stream *xdr, const struct timespec *time) { - __be32 *p; + uint32_t *p; p = xdr_reserve_space(xdr, 12); if (unlikely(p == 0)) @@ -285,23 +285,23 @@ static __be32 encode_attr_time(struct xdr_stream *xdr, const struct timespec *ti return 0; } -static __be32 encode_attr_ctime(struct xdr_stream *xdr, const uint32_t *bitmap, const struct timespec *time) +static unsigned encode_attr_ctime(struct xdr_stream *xdr, const uint32_t *bitmap, const struct timespec *time) { if (!(bitmap[1] & FATTR4_WORD1_TIME_METADATA)) return 0; return encode_attr_time(xdr,time); } -static __be32 encode_attr_mtime(struct xdr_stream *xdr, const uint32_t *bitmap, const struct timespec *time) +static unsigned encode_attr_mtime(struct xdr_stream *xdr, const uint32_t *bitmap, const struct timespec *time) { if (!(bitmap[1] & FATTR4_WORD1_TIME_MODIFY)) return 0; return encode_attr_time(xdr,time); } -static __be32 encode_compound_hdr_res(struct xdr_stream *xdr, struct cb_compound_hdr_res *hdr) +static unsigned encode_compound_hdr_res(struct xdr_stream *xdr, struct cb_compound_hdr_res *hdr) { - __be32 status; + unsigned status; hdr->status = xdr_reserve_space(xdr, 4); if (unlikely(hdr->status == NULL)) @@ -315,9 +315,9 @@ static __be32 encode_compound_hdr_res(struct xdr_stream *xdr, struct cb_compound return 0; } -static __be32 encode_op_hdr(struct xdr_stream *xdr, uint32_t op, __be32 res) +static unsigned encode_op_hdr(struct xdr_stream *xdr, uint32_t op, uint32_t res) { - __be32 *p; + uint32_t *p; p = xdr_reserve_space(xdr, 8); if (unlikely(p == NULL)) @@ -327,10 +327,10 @@ static __be32 encode_op_hdr(struct xdr_stream *xdr, uint32_t op, __be32 res) return 0; } -static __be32 encode_getattr_res(struct svc_rqst *rqstp, struct xdr_stream *xdr, const struct cb_getattrres *res) +static unsigned encode_getattr_res(struct svc_rqst *rqstp, struct xdr_stream *xdr, const struct cb_getattrres *res) { - __be32 *savep = NULL; - __be32 status = res->status; + uint32_t *savep = NULL; + unsigned status = res->status; if (unlikely(status != 0)) goto out; @@ -353,15 +353,15 @@ static __be32 encode_getattr_res(struct svc_rqst *rqstp, struct xdr_stream *xdr, return status; } -static __be32 process_op(struct svc_rqst *rqstp, +static unsigned process_op(struct svc_rqst *rqstp, struct xdr_stream *xdr_in, void *argp, struct xdr_stream *xdr_out, void *resp) { struct callback_op *op = &callback_ops[0]; unsigned int op_nr = OP_CB_ILLEGAL; - __be32 status = 0; + unsigned int status = 0; long maxlen; - __be32 res; + unsigned res; dprintk("%s: start\n", __FUNCTION__); status = decode_op_hdr(xdr_in, &op_nr); @@ -399,20 +399,20 @@ static __be32 process_op(struct svc_rqst *rqstp, /* * Decode, process and encode a COMPOUND */ -static __be32 nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *resp) +static int nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *resp) { struct cb_compound_hdr_arg hdr_arg; struct cb_compound_hdr_res hdr_res; struct xdr_stream xdr_in, xdr_out; - __be32 *p; - __be32 status; + uint32_t *p; + unsigned int status; unsigned int nops = 1; dprintk("%s: start\n", __FUNCTION__); xdr_init_decode(&xdr_in, &rqstp->rq_arg, rqstp->rq_arg.head[0].iov_base); - p = (__be32*)((char *)rqstp->rq_res.head[0].iov_base + rqstp->rq_res.head[0].iov_len); + p = (uint32_t*)((char *)rqstp->rq_res.head[0].iov_base + rqstp->rq_res.head[0].iov_len); xdr_init_encode(&xdr_out, &rqstp->rq_res, p); decode_compound_hdr_arg(&xdr_in, &hdr_arg); diff --git a/trunk/fs/nfs/client.c b/trunk/fs/nfs/client.c index 5fea638743e4..6e4e48c5092a 100644 --- a/trunk/fs/nfs/client.c +++ b/trunk/fs/nfs/client.c @@ -232,15 +232,11 @@ void nfs_put_client(struct nfs_client *clp) * Find a client by address * - caller must hold nfs_client_lock */ -static struct nfs_client *__nfs_find_client(const struct sockaddr_in *addr, int nfsversion, int match_port) +static struct nfs_client *__nfs_find_client(const struct sockaddr_in *addr, int nfsversion) { struct nfs_client *clp; list_for_each_entry(clp, &nfs_client_list, cl_share_link) { - /* Don't match clients that failed to initialise properly */ - if (clp->cl_cons_state < 0) - continue; - /* Different NFS versions cannot share the same nfs_client */ if (clp->cl_nfsversion != nfsversion) continue; @@ -249,7 +245,7 @@ static struct nfs_client *__nfs_find_client(const struct sockaddr_in *addr, int sizeof(clp->cl_addr.sin_addr)) != 0) continue; - if (!match_port || clp->cl_addr.sin_port == addr->sin_port) + if (clp->cl_addr.sin_port == addr->sin_port) goto found; } @@ -269,12 +265,11 @@ struct nfs_client *nfs_find_client(const struct sockaddr_in *addr, int nfsversio struct nfs_client *clp; spin_lock(&nfs_client_lock); - clp = __nfs_find_client(addr, nfsversion, 0); + clp = __nfs_find_client(addr, nfsversion); spin_unlock(&nfs_client_lock); - if (clp != NULL && clp->cl_cons_state != NFS_CS_READY) { - nfs_put_client(clp); - clp = NULL; - } + + BUG_ON(clp && clp->cl_cons_state == 0); + return clp; } @@ -297,7 +292,7 @@ static struct nfs_client *nfs_get_client(const char *hostname, do { spin_lock(&nfs_client_lock); - clp = __nfs_find_client(addr, nfsversion, 1); + clp = __nfs_find_client(addr, nfsversion); if (clp) goto found_client; if (new) @@ -327,11 +322,25 @@ static struct nfs_client *nfs_get_client(const char *hostname, if (new) nfs_free_client(new); - error = wait_event_interruptible(nfs_client_active_wq, - clp->cl_cons_state != NFS_CS_INITING); - if (error < 0) { - nfs_put_client(clp); - return ERR_PTR(-ERESTARTSYS); + if (clp->cl_cons_state == NFS_CS_INITING) { + DECLARE_WAITQUEUE(myself, current); + + add_wait_queue(&nfs_client_active_wq, &myself); + + for (;;) { + set_current_state(TASK_INTERRUPTIBLE); + if (signal_pending(current) || + clp->cl_cons_state > NFS_CS_READY) + break; + schedule(); + } + + remove_wait_queue(&nfs_client_active_wq, &myself); + + if (signal_pending(current)) { + nfs_put_client(clp); + return ERR_PTR(-ERESTARTSYS); + } } if (clp->cl_cons_state < NFS_CS_READY) { @@ -854,7 +863,6 @@ struct nfs_server *nfs_create_server(const struct nfs_mount_data *data, */ static int nfs4_init_client(struct nfs_client *clp, int proto, int timeo, int retrans, - const char *ip_addr, rpc_authflavor_t authflavour) { int error; @@ -871,7 +879,6 @@ static int nfs4_init_client(struct nfs_client *clp, error = nfs_create_rpc_client(clp, proto, timeo, retrans, authflavour); if (error < 0) goto error; - memcpy(clp->cl_ipaddr, ip_addr, sizeof(clp->cl_ipaddr)); error = nfs_idmap_new(clp); if (error < 0) { @@ -895,7 +902,6 @@ static int nfs4_init_client(struct nfs_client *clp, */ static int nfs4_set_client(struct nfs_server *server, const char *hostname, const struct sockaddr_in *addr, - const char *ip_addr, rpc_authflavor_t authflavour, int proto, int timeo, int retrans) { @@ -910,7 +916,7 @@ static int nfs4_set_client(struct nfs_server *server, error = PTR_ERR(clp); goto error; } - error = nfs4_init_client(clp, proto, timeo, retrans, ip_addr, authflavour); + error = nfs4_init_client(clp, proto, timeo, retrans, authflavour); if (error < 0) goto error_put; @@ -979,7 +985,7 @@ struct nfs_server *nfs4_create_server(const struct nfs4_mount_data *data, return ERR_PTR(-ENOMEM); /* Get a client record */ - error = nfs4_set_client(server, hostname, addr, ip_addr, authflavour, + error = nfs4_set_client(server, hostname, addr, authflavour, data->proto, data->timeo, data->retrans); if (error < 0) goto error; @@ -1049,7 +1055,6 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data, /* Get a client representation. * Note: NFSv4 always uses TCP, */ error = nfs4_set_client(server, data->hostname, data->addr, - parent_client->cl_ipaddr, data->authflavor, parent_server->client->cl_xprt->prot, parent_client->retrans_timeo, diff --git a/trunk/fs/nfs/dir.c b/trunk/fs/nfs/dir.c index b34cd16f472f..481f8892a919 100644 --- a/trunk/fs/nfs/dir.c +++ b/trunk/fs/nfs/dir.c @@ -142,12 +142,12 @@ nfs_opendir(struct inode *inode, struct file *filp) return res; } -typedef __be32 * (*decode_dirent_t)(__be32 *, struct nfs_entry *, int); +typedef u32 * (*decode_dirent_t)(u32 *, struct nfs_entry *, int); typedef struct { struct file *file; struct page *page; unsigned long page_index; - __be32 *ptr; + u32 *ptr; u64 *dir_cookie; loff_t current_index; struct nfs_entry *entry; @@ -203,10 +203,8 @@ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page *page) * Note: assumes we have exclusive access to this mapping either * through inode->i_mutex or some other mechanism. */ - if (page->index == 0 && invalidate_inode_pages2_range(inode->i_mapping, PAGE_CACHE_SIZE, -1) < 0) { - /* Should never happen */ - nfs_zap_mapping(inode, inode->i_mapping); - } + if (page->index == 0) + invalidate_inode_pages2_range(inode->i_mapping, PAGE_CACHE_SIZE, -1); unlock_page(page); return 0; error: @@ -220,7 +218,7 @@ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page *page) static inline int dir_decode(nfs_readdir_descriptor_t *desc) { - __be32 *p = desc->ptr; + u32 *p = desc->ptr; p = desc->decode(p, desc->entry, desc->plus); if (IS_ERR(p)) return PTR_ERR(p); @@ -935,17 +933,8 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru no_entry: res = d_materialise_unique(dentry, inode); - if (res != NULL) { - struct dentry *parent; - if (IS_ERR(res)) - goto out_unlock; - /* Was a directory renamed! */ - parent = dget_parent(res); - if (!IS_ROOT(parent)) - nfs_mark_for_revalidate(parent->d_inode); - dput(parent); + if (res != NULL) dentry = res; - } nfs_renew_times(dentry); nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); out_unlock: @@ -1141,8 +1130,6 @@ static struct dentry *nfs_readdir_lookup(nfs_readdir_descriptor_t *desc) alias = d_materialise_unique(dentry, inode); if (alias != NULL) { dput(dentry); - if (IS_ERR(alias)) - return NULL; dentry = alias; } @@ -1530,8 +1517,8 @@ static int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *sym pagevec_init(&lru_pvec, 0); if (!add_to_page_cache(page, dentry->d_inode->i_mapping, 0, GFP_KERNEL)) { - pagevec_add(&lru_pvec, page); - pagevec_lru_add(&lru_pvec); + if (!pagevec_add(&lru_pvec, page)) + __pagevec_lru_add(&lru_pvec); SetPageUptodate(page); unlock_page(page); } else diff --git a/trunk/fs/nfs/direct.c b/trunk/fs/nfs/direct.c index bdfabf854a51..9f7f8b9ea1e2 100644 --- a/trunk/fs/nfs/direct.c +++ b/trunk/fs/nfs/direct.c @@ -497,7 +497,6 @@ static void nfs_direct_write_complete(struct nfs_direct_req *dreq, struct inode if (dreq->commit_data != NULL) nfs_commit_free(dreq->commit_data); nfs_direct_free_writedata(dreq); - nfs_zap_mapping(inode, inode->i_mapping); nfs_direct_complete(dreq); } } @@ -518,7 +517,6 @@ static void nfs_direct_write_complete(struct nfs_direct_req *dreq, struct inode { nfs_end_data_update(inode); nfs_direct_free_writedata(dreq); - nfs_zap_mapping(inode, inode->i_mapping); nfs_direct_complete(dreq); } #endif @@ -534,12 +532,10 @@ static void nfs_direct_write_result(struct rpc_task *task, void *calldata) spin_lock(&dreq->lock); - if (unlikely(status < 0)) { - dreq->error = status; - goto out_unlock; - } - - dreq->count += data->res.count; + if (likely(status >= 0)) + dreq->count += data->res.count; + else + dreq->error = task->tk_status; if (data->res.verf->committed != NFS_FILE_SYNC) { switch (dreq->flags) { @@ -554,7 +550,7 @@ static void nfs_direct_write_result(struct rpc_task *task, void *calldata) } } } -out_unlock: + spin_unlock(&dreq->lock); } @@ -832,6 +828,17 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, const struct iovec *iov, retval = nfs_direct_write(iocb, (unsigned long) buf, count, pos); + /* + * XXX: nfs_end_data_update() already ensures this file's + * cached data is subsequently invalidated. Do we really + * need to call invalidate_inode_pages2() again here? + * + * For aio writes, this invalidation will almost certainly + * occur before the writes complete. Kind of racey. + */ + if (mapping->nrpages) + invalidate_inode_pages2(mapping); + if (retval > 0) iocb->ki_pos = pos + retval; diff --git a/trunk/fs/nfs/inode.c b/trunk/fs/nfs/inode.c index 08cc4c5919ab..bc9376ca86cd 100644 --- a/trunk/fs/nfs/inode.c +++ b/trunk/fs/nfs/inode.c @@ -131,15 +131,6 @@ void nfs_zap_caches(struct inode *inode) spin_unlock(&inode->i_lock); } -void nfs_zap_mapping(struct inode *inode, struct address_space *mapping) -{ - if (mapping->nrpages != 0) { - spin_lock(&inode->i_lock); - NFS_I(inode)->cache_validity |= NFS_INO_INVALID_DATA; - spin_unlock(&inode->i_lock); - } -} - static void nfs_zap_acl_cache(struct inode *inode) { void (*clear_acl_cache)(struct inode *); @@ -583,7 +574,7 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) nfs_inc_stats(inode, NFSIOS_INODEREVALIDATE); lock_kernel(); - if (is_bad_inode(inode)) + if (!inode || is_bad_inode(inode)) goto out_nowait; if (NFS_STALE(inode)) goto out_nowait; @@ -680,20 +671,13 @@ int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping) if ((nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE) || nfs_attribute_timeout(inode)) ret = __nfs_revalidate_inode(NFS_SERVER(inode), inode); - if (ret < 0) - goto out; if (nfsi->cache_validity & NFS_INO_INVALID_DATA) { - if (mapping->nrpages != 0) { - if (S_ISREG(inode->i_mode)) { - ret = nfs_sync_mapping(mapping); - if (ret < 0) - goto out; - } - ret = invalidate_inode_pages2(mapping); - if (ret < 0) - goto out; - } + nfs_inc_stats(inode, NFSIOS_DATAINVALIDATE); + if (S_ISREG(inode->i_mode)) + nfs_sync_mapping(mapping); + invalidate_inode_pages2(mapping); + spin_lock(&inode->i_lock); nfsi->cache_validity &= ~NFS_INO_INVALID_DATA; if (S_ISDIR(inode->i_mode)) { @@ -703,12 +687,10 @@ int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping) } spin_unlock(&inode->i_lock); - nfs_inc_stats(inode, NFSIOS_DATAINVALIDATE); dfprintk(PAGECACHE, "NFS: (%s/%Ld) data cache invalidated\n", inode->i_sb->s_id, (long long)NFS_FILEID(inode)); } -out: return ret; } diff --git a/trunk/fs/nfs/internal.h b/trunk/fs/nfs/internal.h index d205466233f6..bea0b016bd70 100644 --- a/trunk/fs/nfs/internal.h +++ b/trunk/fs/nfs/internal.h @@ -93,15 +93,15 @@ extern void nfs_destroy_directcache(void); /* nfs2xdr.c */ extern int nfs_stat_to_errno(int); extern struct rpc_procinfo nfs_procedures[]; -extern __be32 * nfs_decode_dirent(__be32 *, struct nfs_entry *, int); +extern u32 * nfs_decode_dirent(u32 *, struct nfs_entry *, int); /* nfs3xdr.c */ extern struct rpc_procinfo nfs3_procedures[]; -extern __be32 *nfs3_decode_dirent(__be32 *, struct nfs_entry *, int); +extern u32 *nfs3_decode_dirent(u32 *, struct nfs_entry *, int); /* nfs4xdr.c */ #ifdef CONFIG_NFS_V4 -extern __be32 *nfs4_decode_dirent(__be32 *p, struct nfs_entry *entry, int plus); +extern u32 *nfs4_decode_dirent(u32 *p, struct nfs_entry *entry, int plus); #endif /* nfs4proc.c */ diff --git a/trunk/fs/nfs/mount_clnt.c b/trunk/fs/nfs/mount_clnt.c index f75fe72b4160..d507b021207f 100644 --- a/trunk/fs/nfs/mount_clnt.c +++ b/trunk/fs/nfs/mount_clnt.c @@ -95,7 +95,7 @@ mnt_create(char *hostname, struct sockaddr_in *srvaddr, int version, * XDR encode/decode functions for MOUNT */ static int -xdr_encode_dirpath(struct rpc_rqst *req, __be32 *p, const char *path) +xdr_encode_dirpath(struct rpc_rqst *req, u32 *p, const char *path) { p = xdr_encode_string(p, path); @@ -104,7 +104,7 @@ xdr_encode_dirpath(struct rpc_rqst *req, __be32 *p, const char *path) } static int -xdr_decode_fhstatus(struct rpc_rqst *req, __be32 *p, struct mnt_fhstatus *res) +xdr_decode_fhstatus(struct rpc_rqst *req, u32 *p, struct mnt_fhstatus *res) { struct nfs_fh *fh = res->fh; @@ -116,7 +116,7 @@ xdr_decode_fhstatus(struct rpc_rqst *req, __be32 *p, struct mnt_fhstatus *res) } static int -xdr_decode_fhstatus3(struct rpc_rqst *req, __be32 *p, struct mnt_fhstatus *res) +xdr_decode_fhstatus3(struct rpc_rqst *req, u32 *p, struct mnt_fhstatus *res) { struct nfs_fh *fh = res->fh; diff --git a/trunk/fs/nfs/nfs2xdr.c b/trunk/fs/nfs/nfs2xdr.c index 3be4e72a0227..b49501fc0a79 100644 --- a/trunk/fs/nfs/nfs2xdr.c +++ b/trunk/fs/nfs/nfs2xdr.c @@ -66,15 +66,15 @@ /* * Common NFS XDR functions as inlines */ -static inline __be32 * -xdr_encode_fhandle(__be32 *p, struct nfs_fh *fhandle) +static inline u32 * +xdr_encode_fhandle(u32 *p, struct nfs_fh *fhandle) { memcpy(p, fhandle->data, NFS2_FHSIZE); return p + XDR_QUADLEN(NFS2_FHSIZE); } -static inline __be32 * -xdr_decode_fhandle(__be32 *p, struct nfs_fh *fhandle) +static inline u32 * +xdr_decode_fhandle(u32 *p, struct nfs_fh *fhandle) { /* NFSv2 handles have a fixed length */ fhandle->size = NFS2_FHSIZE; @@ -82,8 +82,8 @@ xdr_decode_fhandle(__be32 *p, struct nfs_fh *fhandle) return p + XDR_QUADLEN(NFS2_FHSIZE); } -static inline __be32* -xdr_encode_time(__be32 *p, struct timespec *timep) +static inline u32* +xdr_encode_time(u32 *p, struct timespec *timep) { *p++ = htonl(timep->tv_sec); /* Convert nanoseconds into microseconds */ @@ -91,8 +91,8 @@ xdr_encode_time(__be32 *p, struct timespec *timep) return p; } -static inline __be32* -xdr_encode_current_server_time(__be32 *p, struct timespec *timep) +static inline u32* +xdr_encode_current_server_time(u32 *p, struct timespec *timep) { /* * Passing the invalid value useconds=1000000 is a @@ -108,8 +108,8 @@ xdr_encode_current_server_time(__be32 *p, struct timespec *timep) return p; } -static inline __be32* -xdr_decode_time(__be32 *p, struct timespec *timep) +static inline u32* +xdr_decode_time(u32 *p, struct timespec *timep) { timep->tv_sec = ntohl(*p++); /* Convert microseconds into nanoseconds */ @@ -117,8 +117,8 @@ xdr_decode_time(__be32 *p, struct timespec *timep) return p; } -static __be32 * -xdr_decode_fattr(__be32 *p, struct nfs_fattr *fattr) +static u32 * +xdr_decode_fattr(u32 *p, struct nfs_fattr *fattr) { u32 rdev; fattr->type = (enum nfs_ftype) ntohl(*p++); @@ -146,10 +146,10 @@ xdr_decode_fattr(__be32 *p, struct nfs_fattr *fattr) return p; } -static inline __be32 * -xdr_encode_sattr(__be32 *p, struct iattr *attr) +static inline u32 * +xdr_encode_sattr(u32 *p, struct iattr *attr) { - const __be32 not_set = __constant_htonl(0xFFFFFFFF); + const u32 not_set = __constant_htonl(0xFFFFFFFF); *p++ = (attr->ia_valid & ATTR_MODE) ? htonl(attr->ia_mode) : not_set; *p++ = (attr->ia_valid & ATTR_UID) ? htonl(attr->ia_uid) : not_set; @@ -184,7 +184,7 @@ xdr_encode_sattr(__be32 *p, struct iattr *attr) * GETATTR, READLINK, STATFS */ static int -nfs_xdr_fhandle(struct rpc_rqst *req, __be32 *p, struct nfs_fh *fh) +nfs_xdr_fhandle(struct rpc_rqst *req, u32 *p, struct nfs_fh *fh) { p = xdr_encode_fhandle(p, fh); req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); @@ -195,7 +195,7 @@ nfs_xdr_fhandle(struct rpc_rqst *req, __be32 *p, struct nfs_fh *fh) * Encode SETATTR arguments */ static int -nfs_xdr_sattrargs(struct rpc_rqst *req, __be32 *p, struct nfs_sattrargs *args) +nfs_xdr_sattrargs(struct rpc_rqst *req, u32 *p, struct nfs_sattrargs *args) { p = xdr_encode_fhandle(p, args->fh); p = xdr_encode_sattr(p, args->sattr); @@ -208,7 +208,7 @@ nfs_xdr_sattrargs(struct rpc_rqst *req, __be32 *p, struct nfs_sattrargs *args) * LOOKUP, REMOVE, RMDIR */ static int -nfs_xdr_diropargs(struct rpc_rqst *req, __be32 *p, struct nfs_diropargs *args) +nfs_xdr_diropargs(struct rpc_rqst *req, u32 *p, struct nfs_diropargs *args) { p = xdr_encode_fhandle(p, args->fh); p = xdr_encode_array(p, args->name, args->len); @@ -222,7 +222,7 @@ nfs_xdr_diropargs(struct rpc_rqst *req, __be32 *p, struct nfs_diropargs *args) * exactly to the page we want to fetch. */ static int -nfs_xdr_readargs(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args) +nfs_xdr_readargs(struct rpc_rqst *req, u32 *p, struct nfs_readargs *args) { struct rpc_auth *auth = req->rq_task->tk_auth; unsigned int replen; @@ -246,7 +246,7 @@ nfs_xdr_readargs(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args) * Decode READ reply */ static int -nfs_xdr_readres(struct rpc_rqst *req, __be32 *p, struct nfs_readres *res) +nfs_xdr_readres(struct rpc_rqst *req, u32 *p, struct nfs_readres *res) { struct kvec *iov = req->rq_rcv_buf.head; int status, count, recvd, hdrlen; @@ -286,7 +286,7 @@ nfs_xdr_readres(struct rpc_rqst *req, __be32 *p, struct nfs_readres *res) * Write arguments. Splice the buffer to be written into the iovec. */ static int -nfs_xdr_writeargs(struct rpc_rqst *req, __be32 *p, struct nfs_writeargs *args) +nfs_xdr_writeargs(struct rpc_rqst *req, u32 *p, struct nfs_writeargs *args) { struct xdr_buf *sndbuf = &req->rq_snd_buf; u32 offset = (u32)args->offset; @@ -309,7 +309,7 @@ nfs_xdr_writeargs(struct rpc_rqst *req, __be32 *p, struct nfs_writeargs *args) * CREATE, MKDIR */ static int -nfs_xdr_createargs(struct rpc_rqst *req, __be32 *p, struct nfs_createargs *args) +nfs_xdr_createargs(struct rpc_rqst *req, u32 *p, struct nfs_createargs *args) { p = xdr_encode_fhandle(p, args->fh); p = xdr_encode_array(p, args->name, args->len); @@ -322,7 +322,7 @@ nfs_xdr_createargs(struct rpc_rqst *req, __be32 *p, struct nfs_createargs *args) * Encode RENAME arguments */ static int -nfs_xdr_renameargs(struct rpc_rqst *req, __be32 *p, struct nfs_renameargs *args) +nfs_xdr_renameargs(struct rpc_rqst *req, u32 *p, struct nfs_renameargs *args) { p = xdr_encode_fhandle(p, args->fromfh); p = xdr_encode_array(p, args->fromname, args->fromlen); @@ -336,7 +336,7 @@ nfs_xdr_renameargs(struct rpc_rqst *req, __be32 *p, struct nfs_renameargs *args) * Encode LINK arguments */ static int -nfs_xdr_linkargs(struct rpc_rqst *req, __be32 *p, struct nfs_linkargs *args) +nfs_xdr_linkargs(struct rpc_rqst *req, u32 *p, struct nfs_linkargs *args) { p = xdr_encode_fhandle(p, args->fromfh); p = xdr_encode_fhandle(p, args->tofh); @@ -349,7 +349,7 @@ nfs_xdr_linkargs(struct rpc_rqst *req, __be32 *p, struct nfs_linkargs *args) * Encode SYMLINK arguments */ static int -nfs_xdr_symlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs_symlinkargs *args) +nfs_xdr_symlinkargs(struct rpc_rqst *req, u32 *p, struct nfs_symlinkargs *args) { struct xdr_buf *sndbuf = &req->rq_snd_buf; size_t pad; @@ -378,7 +378,7 @@ nfs_xdr_symlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs_symlinkargs *arg * Encode arguments to readdir call */ static int -nfs_xdr_readdirargs(struct rpc_rqst *req, __be32 *p, struct nfs_readdirargs *args) +nfs_xdr_readdirargs(struct rpc_rqst *req, u32 *p, struct nfs_readdirargs *args) { struct rpc_task *task = req->rq_task; struct rpc_auth *auth = task->tk_auth; @@ -404,7 +404,7 @@ nfs_xdr_readdirargs(struct rpc_rqst *req, __be32 *p, struct nfs_readdirargs *arg * from nfs_readdir for each entry. */ static int -nfs_xdr_readdirres(struct rpc_rqst *req, __be32 *p, void *dummy) +nfs_xdr_readdirres(struct rpc_rqst *req, u32 *p, void *dummy) { struct xdr_buf *rcvbuf = &req->rq_rcv_buf; struct kvec *iov = rcvbuf->head; @@ -412,7 +412,7 @@ nfs_xdr_readdirres(struct rpc_rqst *req, __be32 *p, void *dummy) int hdrlen, recvd; int status, nr; unsigned int len, pglen; - __be32 *end, *entry, *kaddr; + u32 *end, *entry, *kaddr; if ((status = ntohl(*p++))) return -nfs_stat_to_errno(status); @@ -432,8 +432,8 @@ nfs_xdr_readdirres(struct rpc_rqst *req, __be32 *p, void *dummy) if (pglen > recvd) pglen = recvd; page = rcvbuf->pages; - kaddr = p = kmap_atomic(*page, KM_USER0); - end = (__be32 *)((char *)p + pglen); + kaddr = p = (u32 *)kmap_atomic(*page, KM_USER0); + end = (u32 *)((char *)p + pglen); entry = p; for (nr = 0; *p++; nr++) { if (p + 2 > end) @@ -468,8 +468,8 @@ nfs_xdr_readdirres(struct rpc_rqst *req, __be32 *p, void *dummy) goto out; } -__be32 * -nfs_decode_dirent(__be32 *p, struct nfs_entry *entry, int plus) +u32 * +nfs_decode_dirent(u32 *p, struct nfs_entry *entry, int plus) { if (!*p++) { if (!*p) @@ -496,7 +496,7 @@ nfs_decode_dirent(__be32 *p, struct nfs_entry *entry, int plus) * Decode simple status reply */ static int -nfs_xdr_stat(struct rpc_rqst *req, __be32 *p, void *dummy) +nfs_xdr_stat(struct rpc_rqst *req, u32 *p, void *dummy) { int status; @@ -510,7 +510,7 @@ nfs_xdr_stat(struct rpc_rqst *req, __be32 *p, void *dummy) * GETATTR, SETATTR, WRITE */ static int -nfs_xdr_attrstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr) +nfs_xdr_attrstat(struct rpc_rqst *req, u32 *p, struct nfs_fattr *fattr) { int status; @@ -525,7 +525,7 @@ nfs_xdr_attrstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr) * LOOKUP, CREATE, MKDIR */ static int -nfs_xdr_diropres(struct rpc_rqst *req, __be32 *p, struct nfs_diropok *res) +nfs_xdr_diropres(struct rpc_rqst *req, u32 *p, struct nfs_diropok *res) { int status; @@ -540,7 +540,7 @@ nfs_xdr_diropres(struct rpc_rqst *req, __be32 *p, struct nfs_diropok *res) * Encode READLINK args */ static int -nfs_xdr_readlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs_readlinkargs *args) +nfs_xdr_readlinkargs(struct rpc_rqst *req, u32 *p, struct nfs_readlinkargs *args) { struct rpc_auth *auth = req->rq_task->tk_auth; unsigned int replen; @@ -558,7 +558,7 @@ nfs_xdr_readlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs_readlinkargs *a * Decode READLINK reply */ static int -nfs_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, void *dummy) +nfs_xdr_readlinkres(struct rpc_rqst *req, u32 *p, void *dummy) { struct xdr_buf *rcvbuf = &req->rq_rcv_buf; struct kvec *iov = rcvbuf->head; @@ -601,7 +601,7 @@ nfs_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, void *dummy) * Decode WRITE reply */ static int -nfs_xdr_writeres(struct rpc_rqst *req, __be32 *p, struct nfs_writeres *res) +nfs_xdr_writeres(struct rpc_rqst *req, u32 *p, struct nfs_writeres *res) { res->verf->committed = NFS_FILE_SYNC; return nfs_xdr_attrstat(req, p, res->fattr); @@ -611,7 +611,7 @@ nfs_xdr_writeres(struct rpc_rqst *req, __be32 *p, struct nfs_writeres *res) * Decode STATFS reply */ static int -nfs_xdr_statfsres(struct rpc_rqst *req, __be32 *p, struct nfs2_fsstat *res) +nfs_xdr_statfsres(struct rpc_rqst *req, u32 *p, struct nfs2_fsstat *res) { int status; diff --git a/trunk/fs/nfs/nfs3proc.c b/trunk/fs/nfs/nfs3proc.c index e5f128ffc32d..3b234d4601e7 100644 --- a/trunk/fs/nfs/nfs3proc.c +++ b/trunk/fs/nfs/nfs3proc.c @@ -668,7 +668,7 @@ nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, { struct inode *dir = dentry->d_inode; struct nfs_fattr dir_attr; - __be32 *verf = NFS_COOKIEVERF(dir); + u32 *verf = NFS_COOKIEVERF(dir); struct nfs3_readdirargs arg = { .fh = NFS_FH(dir), .cookie = cookie, diff --git a/trunk/fs/nfs/nfs3xdr.c b/trunk/fs/nfs/nfs3xdr.c index 0ace092d126f..16556fa4effb 100644 --- a/trunk/fs/nfs/nfs3xdr.c +++ b/trunk/fs/nfs/nfs3xdr.c @@ -105,14 +105,14 @@ static struct { /* * Common NFS XDR functions as inlines */ -static inline __be32 * -xdr_encode_fhandle(__be32 *p, struct nfs_fh *fh) +static inline u32 * +xdr_encode_fhandle(u32 *p, struct nfs_fh *fh) { return xdr_encode_array(p, fh->data, fh->size); } -static inline __be32 * -xdr_decode_fhandle(__be32 *p, struct nfs_fh *fh) +static inline u32 * +xdr_decode_fhandle(u32 *p, struct nfs_fh *fh) { if ((fh->size = ntohl(*p++)) <= NFS3_FHSIZE) { memcpy(fh->data, p, fh->size); @@ -124,24 +124,24 @@ xdr_decode_fhandle(__be32 *p, struct nfs_fh *fh) /* * Encode/decode time. */ -static inline __be32 * -xdr_encode_time3(__be32 *p, struct timespec *timep) +static inline u32 * +xdr_encode_time3(u32 *p, struct timespec *timep) { *p++ = htonl(timep->tv_sec); *p++ = htonl(timep->tv_nsec); return p; } -static inline __be32 * -xdr_decode_time3(__be32 *p, struct timespec *timep) +static inline u32 * +xdr_decode_time3(u32 *p, struct timespec *timep) { timep->tv_sec = ntohl(*p++); timep->tv_nsec = ntohl(*p++); return p; } -static __be32 * -xdr_decode_fattr(__be32 *p, struct nfs_fattr *fattr) +static u32 * +xdr_decode_fattr(u32 *p, struct nfs_fattr *fattr) { unsigned int type, major, minor; int fmode; @@ -177,8 +177,8 @@ xdr_decode_fattr(__be32 *p, struct nfs_fattr *fattr) return p; } -static inline __be32 * -xdr_encode_sattr(__be32 *p, struct iattr *attr) +static inline u32 * +xdr_encode_sattr(u32 *p, struct iattr *attr) { if (attr->ia_valid & ATTR_MODE) { *p++ = xdr_one; @@ -223,8 +223,8 @@ xdr_encode_sattr(__be32 *p, struct iattr *attr) return p; } -static inline __be32 * -xdr_decode_wcc_attr(__be32 *p, struct nfs_fattr *fattr) +static inline u32 * +xdr_decode_wcc_attr(u32 *p, struct nfs_fattr *fattr) { p = xdr_decode_hyper(p, &fattr->pre_size); p = xdr_decode_time3(p, &fattr->pre_mtime); @@ -233,16 +233,16 @@ xdr_decode_wcc_attr(__be32 *p, struct nfs_fattr *fattr) return p; } -static inline __be32 * -xdr_decode_post_op_attr(__be32 *p, struct nfs_fattr *fattr) +static inline u32 * +xdr_decode_post_op_attr(u32 *p, struct nfs_fattr *fattr) { if (*p++) p = xdr_decode_fattr(p, fattr); return p; } -static inline __be32 * -xdr_decode_pre_op_attr(__be32 *p, struct nfs_fattr *fattr) +static inline u32 * +xdr_decode_pre_op_attr(u32 *p, struct nfs_fattr *fattr) { if (*p++) return xdr_decode_wcc_attr(p, fattr); @@ -250,8 +250,8 @@ xdr_decode_pre_op_attr(__be32 *p, struct nfs_fattr *fattr) } -static inline __be32 * -xdr_decode_wcc_data(__be32 *p, struct nfs_fattr *fattr) +static inline u32 * +xdr_decode_wcc_data(u32 *p, struct nfs_fattr *fattr) { p = xdr_decode_pre_op_attr(p, fattr); return xdr_decode_post_op_attr(p, fattr); @@ -265,7 +265,7 @@ xdr_decode_wcc_data(__be32 *p, struct nfs_fattr *fattr) * Encode file handle argument */ static int -nfs3_xdr_fhandle(struct rpc_rqst *req, __be32 *p, struct nfs_fh *fh) +nfs3_xdr_fhandle(struct rpc_rqst *req, u32 *p, struct nfs_fh *fh) { p = xdr_encode_fhandle(p, fh); req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); @@ -276,7 +276,7 @@ nfs3_xdr_fhandle(struct rpc_rqst *req, __be32 *p, struct nfs_fh *fh) * Encode SETATTR arguments */ static int -nfs3_xdr_sattrargs(struct rpc_rqst *req, __be32 *p, struct nfs3_sattrargs *args) +nfs3_xdr_sattrargs(struct rpc_rqst *req, u32 *p, struct nfs3_sattrargs *args) { p = xdr_encode_fhandle(p, args->fh); p = xdr_encode_sattr(p, args->sattr); @@ -291,7 +291,7 @@ nfs3_xdr_sattrargs(struct rpc_rqst *req, __be32 *p, struct nfs3_sattrargs *args) * Encode directory ops argument */ static int -nfs3_xdr_diropargs(struct rpc_rqst *req, __be32 *p, struct nfs3_diropargs *args) +nfs3_xdr_diropargs(struct rpc_rqst *req, u32 *p, struct nfs3_diropargs *args) { p = xdr_encode_fhandle(p, args->fh); p = xdr_encode_array(p, args->name, args->len); @@ -303,7 +303,7 @@ nfs3_xdr_diropargs(struct rpc_rqst *req, __be32 *p, struct nfs3_diropargs *args) * Encode access() argument */ static int -nfs3_xdr_accessargs(struct rpc_rqst *req, __be32 *p, struct nfs3_accessargs *args) +nfs3_xdr_accessargs(struct rpc_rqst *req, u32 *p, struct nfs3_accessargs *args) { p = xdr_encode_fhandle(p, args->fh); *p++ = htonl(args->access); @@ -317,7 +317,7 @@ nfs3_xdr_accessargs(struct rpc_rqst *req, __be32 *p, struct nfs3_accessargs *arg * exactly to the page we want to fetch. */ static int -nfs3_xdr_readargs(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args) +nfs3_xdr_readargs(struct rpc_rqst *req, u32 *p, struct nfs_readargs *args) { struct rpc_auth *auth = req->rq_task->tk_auth; unsigned int replen; @@ -339,7 +339,7 @@ nfs3_xdr_readargs(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args) * Write arguments. Splice the buffer to be written into the iovec. */ static int -nfs3_xdr_writeargs(struct rpc_rqst *req, __be32 *p, struct nfs_writeargs *args) +nfs3_xdr_writeargs(struct rpc_rqst *req, u32 *p, struct nfs_writeargs *args) { struct xdr_buf *sndbuf = &req->rq_snd_buf; u32 count = args->count; @@ -360,7 +360,7 @@ nfs3_xdr_writeargs(struct rpc_rqst *req, __be32 *p, struct nfs_writeargs *args) * Encode CREATE arguments */ static int -nfs3_xdr_createargs(struct rpc_rqst *req, __be32 *p, struct nfs3_createargs *args) +nfs3_xdr_createargs(struct rpc_rqst *req, u32 *p, struct nfs3_createargs *args) { p = xdr_encode_fhandle(p, args->fh); p = xdr_encode_array(p, args->name, args->len); @@ -380,7 +380,7 @@ nfs3_xdr_createargs(struct rpc_rqst *req, __be32 *p, struct nfs3_createargs *arg * Encode MKDIR arguments */ static int -nfs3_xdr_mkdirargs(struct rpc_rqst *req, __be32 *p, struct nfs3_mkdirargs *args) +nfs3_xdr_mkdirargs(struct rpc_rqst *req, u32 *p, struct nfs3_mkdirargs *args) { p = xdr_encode_fhandle(p, args->fh); p = xdr_encode_array(p, args->name, args->len); @@ -393,7 +393,7 @@ nfs3_xdr_mkdirargs(struct rpc_rqst *req, __be32 *p, struct nfs3_mkdirargs *args) * Encode SYMLINK arguments */ static int -nfs3_xdr_symlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs3_symlinkargs *args) +nfs3_xdr_symlinkargs(struct rpc_rqst *req, u32 *p, struct nfs3_symlinkargs *args) { p = xdr_encode_fhandle(p, args->fromfh); p = xdr_encode_array(p, args->fromname, args->fromlen); @@ -410,7 +410,7 @@ nfs3_xdr_symlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs3_symlinkargs *a * Encode MKNOD arguments */ static int -nfs3_xdr_mknodargs(struct rpc_rqst *req, __be32 *p, struct nfs3_mknodargs *args) +nfs3_xdr_mknodargs(struct rpc_rqst *req, u32 *p, struct nfs3_mknodargs *args) { p = xdr_encode_fhandle(p, args->fh); p = xdr_encode_array(p, args->name, args->len); @@ -429,7 +429,7 @@ nfs3_xdr_mknodargs(struct rpc_rqst *req, __be32 *p, struct nfs3_mknodargs *args) * Encode RENAME arguments */ static int -nfs3_xdr_renameargs(struct rpc_rqst *req, __be32 *p, struct nfs3_renameargs *args) +nfs3_xdr_renameargs(struct rpc_rqst *req, u32 *p, struct nfs3_renameargs *args) { p = xdr_encode_fhandle(p, args->fromfh); p = xdr_encode_array(p, args->fromname, args->fromlen); @@ -443,7 +443,7 @@ nfs3_xdr_renameargs(struct rpc_rqst *req, __be32 *p, struct nfs3_renameargs *arg * Encode LINK arguments */ static int -nfs3_xdr_linkargs(struct rpc_rqst *req, __be32 *p, struct nfs3_linkargs *args) +nfs3_xdr_linkargs(struct rpc_rqst *req, u32 *p, struct nfs3_linkargs *args) { p = xdr_encode_fhandle(p, args->fromfh); p = xdr_encode_fhandle(p, args->tofh); @@ -456,7 +456,7 @@ nfs3_xdr_linkargs(struct rpc_rqst *req, __be32 *p, struct nfs3_linkargs *args) * Encode arguments to readdir call */ static int -nfs3_xdr_readdirargs(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirargs *args) +nfs3_xdr_readdirargs(struct rpc_rqst *req, u32 *p, struct nfs3_readdirargs *args) { struct rpc_auth *auth = req->rq_task->tk_auth; unsigned int replen; @@ -485,7 +485,7 @@ nfs3_xdr_readdirargs(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirargs *a * We just check for syntactical correctness. */ static int -nfs3_xdr_readdirres(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirres *res) +nfs3_xdr_readdirres(struct rpc_rqst *req, u32 *p, struct nfs3_readdirres *res) { struct xdr_buf *rcvbuf = &req->rq_rcv_buf; struct kvec *iov = rcvbuf->head; @@ -493,7 +493,7 @@ nfs3_xdr_readdirres(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirres *res int hdrlen, recvd; int status, nr; unsigned int len, pglen; - __be32 *entry, *end, *kaddr; + u32 *entry, *end, *kaddr; status = ntohl(*p++); /* Decode post_op_attrs */ @@ -523,8 +523,8 @@ nfs3_xdr_readdirres(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirres *res if (pglen > recvd) pglen = recvd; page = rcvbuf->pages; - kaddr = p = kmap_atomic(*page, KM_USER0); - end = (__be32 *)((char *)p + pglen); + kaddr = p = (u32 *)kmap_atomic(*page, KM_USER0); + end = (u32 *)((char *)p + pglen); entry = p; for (nr = 0; *p++; nr++) { if (p + 3 > end) @@ -583,8 +583,8 @@ nfs3_xdr_readdirres(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirres *res goto out; } -__be32 * -nfs3_decode_dirent(__be32 *p, struct nfs_entry *entry, int plus) +u32 * +nfs3_decode_dirent(u32 *p, struct nfs_entry *entry, int plus) { struct nfs_entry old = *entry; @@ -626,7 +626,7 @@ nfs3_decode_dirent(__be32 *p, struct nfs_entry *entry, int plus) * Encode COMMIT arguments */ static int -nfs3_xdr_commitargs(struct rpc_rqst *req, __be32 *p, struct nfs_writeargs *args) +nfs3_xdr_commitargs(struct rpc_rqst *req, u32 *p, struct nfs_writeargs *args) { p = xdr_encode_fhandle(p, args->fh); p = xdr_encode_hyper(p, args->offset); @@ -640,7 +640,7 @@ nfs3_xdr_commitargs(struct rpc_rqst *req, __be32 *p, struct nfs_writeargs *args) * Encode GETACL arguments */ static int -nfs3_xdr_getaclargs(struct rpc_rqst *req, __be32 *p, +nfs3_xdr_getaclargs(struct rpc_rqst *req, u32 *p, struct nfs3_getaclargs *args) { struct rpc_auth *auth = req->rq_task->tk_auth; @@ -664,7 +664,7 @@ nfs3_xdr_getaclargs(struct rpc_rqst *req, __be32 *p, * Encode SETACL arguments */ static int -nfs3_xdr_setaclargs(struct rpc_rqst *req, __be32 *p, +nfs3_xdr_setaclargs(struct rpc_rqst *req, u32 *p, struct nfs3_setaclargs *args) { struct xdr_buf *buf = &req->rq_snd_buf; @@ -711,7 +711,7 @@ nfs3_xdr_setaclargs(struct rpc_rqst *req, __be32 *p, * Decode attrstat reply. */ static int -nfs3_xdr_attrstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr) +nfs3_xdr_attrstat(struct rpc_rqst *req, u32 *p, struct nfs_fattr *fattr) { int status; @@ -726,7 +726,7 @@ nfs3_xdr_attrstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr) * SATTR, REMOVE, RMDIR */ static int -nfs3_xdr_wccstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr) +nfs3_xdr_wccstat(struct rpc_rqst *req, u32 *p, struct nfs_fattr *fattr) { int status; @@ -740,7 +740,7 @@ nfs3_xdr_wccstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr) * Decode LOOKUP reply */ static int -nfs3_xdr_lookupres(struct rpc_rqst *req, __be32 *p, struct nfs3_diropres *res) +nfs3_xdr_lookupres(struct rpc_rqst *req, u32 *p, struct nfs3_diropres *res) { int status; @@ -759,7 +759,7 @@ nfs3_xdr_lookupres(struct rpc_rqst *req, __be32 *p, struct nfs3_diropres *res) * Decode ACCESS reply */ static int -nfs3_xdr_accessres(struct rpc_rqst *req, __be32 *p, struct nfs3_accessres *res) +nfs3_xdr_accessres(struct rpc_rqst *req, u32 *p, struct nfs3_accessres *res) { int status = ntohl(*p++); @@ -771,7 +771,7 @@ nfs3_xdr_accessres(struct rpc_rqst *req, __be32 *p, struct nfs3_accessres *res) } static int -nfs3_xdr_readlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs3_readlinkargs *args) +nfs3_xdr_readlinkargs(struct rpc_rqst *req, u32 *p, struct nfs3_readlinkargs *args) { struct rpc_auth *auth = req->rq_task->tk_auth; unsigned int replen; @@ -789,7 +789,7 @@ nfs3_xdr_readlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs3_readlinkargs * Decode READLINK reply */ static int -nfs3_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr) +nfs3_xdr_readlinkres(struct rpc_rqst *req, u32 *p, struct nfs_fattr *fattr) { struct xdr_buf *rcvbuf = &req->rq_rcv_buf; struct kvec *iov = rcvbuf->head; @@ -837,7 +837,7 @@ nfs3_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr) * Decode READ reply */ static int -nfs3_xdr_readres(struct rpc_rqst *req, __be32 *p, struct nfs_readres *res) +nfs3_xdr_readres(struct rpc_rqst *req, u32 *p, struct nfs_readres *res) { struct kvec *iov = req->rq_rcv_buf.head; int status, count, ocount, recvd, hdrlen; @@ -888,7 +888,7 @@ nfs3_xdr_readres(struct rpc_rqst *req, __be32 *p, struct nfs_readres *res) * Decode WRITE response */ static int -nfs3_xdr_writeres(struct rpc_rqst *req, __be32 *p, struct nfs_writeres *res) +nfs3_xdr_writeres(struct rpc_rqst *req, u32 *p, struct nfs_writeres *res) { int status; @@ -910,7 +910,7 @@ nfs3_xdr_writeres(struct rpc_rqst *req, __be32 *p, struct nfs_writeres *res) * Decode a CREATE response */ static int -nfs3_xdr_createres(struct rpc_rqst *req, __be32 *p, struct nfs3_diropres *res) +nfs3_xdr_createres(struct rpc_rqst *req, u32 *p, struct nfs3_diropres *res) { int status; @@ -937,7 +937,7 @@ nfs3_xdr_createres(struct rpc_rqst *req, __be32 *p, struct nfs3_diropres *res) * Decode RENAME reply */ static int -nfs3_xdr_renameres(struct rpc_rqst *req, __be32 *p, struct nfs3_renameres *res) +nfs3_xdr_renameres(struct rpc_rqst *req, u32 *p, struct nfs3_renameres *res) { int status; @@ -952,7 +952,7 @@ nfs3_xdr_renameres(struct rpc_rqst *req, __be32 *p, struct nfs3_renameres *res) * Decode LINK reply */ static int -nfs3_xdr_linkres(struct rpc_rqst *req, __be32 *p, struct nfs3_linkres *res) +nfs3_xdr_linkres(struct rpc_rqst *req, u32 *p, struct nfs3_linkres *res) { int status; @@ -967,7 +967,7 @@ nfs3_xdr_linkres(struct rpc_rqst *req, __be32 *p, struct nfs3_linkres *res) * Decode FSSTAT reply */ static int -nfs3_xdr_fsstatres(struct rpc_rqst *req, __be32 *p, struct nfs_fsstat *res) +nfs3_xdr_fsstatres(struct rpc_rqst *req, u32 *p, struct nfs_fsstat *res) { int status; @@ -992,7 +992,7 @@ nfs3_xdr_fsstatres(struct rpc_rqst *req, __be32 *p, struct nfs_fsstat *res) * Decode FSINFO reply */ static int -nfs3_xdr_fsinfores(struct rpc_rqst *req, __be32 *p, struct nfs_fsinfo *res) +nfs3_xdr_fsinfores(struct rpc_rqst *req, u32 *p, struct nfs_fsinfo *res) { int status; @@ -1020,7 +1020,7 @@ nfs3_xdr_fsinfores(struct rpc_rqst *req, __be32 *p, struct nfs_fsinfo *res) * Decode PATHCONF reply */ static int -nfs3_xdr_pathconfres(struct rpc_rqst *req, __be32 *p, struct nfs_pathconf *res) +nfs3_xdr_pathconfres(struct rpc_rqst *req, u32 *p, struct nfs_pathconf *res) { int status; @@ -1040,7 +1040,7 @@ nfs3_xdr_pathconfres(struct rpc_rqst *req, __be32 *p, struct nfs_pathconf *res) * Decode COMMIT reply */ static int -nfs3_xdr_commitres(struct rpc_rqst *req, __be32 *p, struct nfs_writeres *res) +nfs3_xdr_commitres(struct rpc_rqst *req, u32 *p, struct nfs_writeres *res) { int status; @@ -1059,7 +1059,7 @@ nfs3_xdr_commitres(struct rpc_rqst *req, __be32 *p, struct nfs_writeres *res) * Decode GETACL reply */ static int -nfs3_xdr_getaclres(struct rpc_rqst *req, __be32 *p, +nfs3_xdr_getaclres(struct rpc_rqst *req, u32 *p, struct nfs3_getaclres *res) { struct xdr_buf *buf = &req->rq_rcv_buf; @@ -1091,7 +1091,7 @@ nfs3_xdr_getaclres(struct rpc_rqst *req, __be32 *p, * Decode setacl reply. */ static int -nfs3_xdr_setaclres(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr) +nfs3_xdr_setaclres(struct rpc_rqst *req, u32 *p, struct nfs_fattr *fattr) { int status = ntohl(*p++); diff --git a/trunk/fs/nfs/nfs4_fs.h b/trunk/fs/nfs/nfs4_fs.h index 6f346677332d..61095fe4b5ca 100644 --- a/trunk/fs/nfs/nfs4_fs.h +++ b/trunk/fs/nfs/nfs4_fs.h @@ -212,7 +212,7 @@ extern void nfs_free_seqid(struct nfs_seqid *seqid); extern const nfs4_stateid zero_stateid; /* nfs4xdr.c */ -extern __be32 *nfs4_decode_dirent(__be32 *p, struct nfs_entry *entry, int plus); +extern uint32_t *nfs4_decode_dirent(uint32_t *p, struct nfs_entry *entry, int plus); extern struct rpc_procinfo nfs4_procedures[]; struct nfs4_mount_data; diff --git a/trunk/fs/nfs/nfs4proc.c b/trunk/fs/nfs/nfs4proc.c index 8118036cc449..47c7e6e3910d 100644 --- a/trunk/fs/nfs/nfs4proc.c +++ b/trunk/fs/nfs/nfs4proc.c @@ -138,10 +138,10 @@ const u32 nfs4_fs_locations_bitmap[2] = { | FATTR4_WORD1_MOUNTED_ON_FILEID }; -static void nfs4_setup_readdir(u64 cookie, __be32 *verifier, struct dentry *dentry, +static void nfs4_setup_readdir(u64 cookie, u32 *verifier, struct dentry *dentry, struct nfs4_readdir_arg *readdir) { - __be32 *start, *p; + u32 *start, *p; BUG_ON(readdir->count < 80); if (cookie > 2) { @@ -162,7 +162,7 @@ static void nfs4_setup_readdir(u64 cookie, __be32 *verifier, struct dentry *dent * when talking to the server, we always send cookie 0 * instead of 1 or 2. */ - start = p = kmap_atomic(*readdir->pages, KM_USER0); + start = p = (u32 *)kmap_atomic(*readdir->pages, KM_USER0); if (cookie == 0) { *p++ = xdr_one; /* next */ @@ -1314,9 +1314,11 @@ nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, st case -EROFS: lookup_instantiate_filp(nd, (struct dentry *)state, NULL); return 1; - default: - goto out_drop; + case -ENOENT: + if (dentry->d_inode == NULL) + return 1; } + goto out_drop; } if (state->inode == dentry->d_inode) { nfs4_intent_set_file(nd, dentry, state); @@ -2915,11 +2917,11 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, unsigned short po .rpc_resp = clp, .rpc_cred = cred, }; - __be32 *p; + u32 *p; int loop = 0; int status; - p = (__be32*)sc_verifier.data; + p = (u32*)sc_verifier.data; *p++ = htonl((u32)clp->cl_boot_time.tv_sec); *p = htonl((u32)clp->cl_boot_time.tv_nsec); diff --git a/trunk/fs/nfs/nfs4xdr.c b/trunk/fs/nfs/nfs4xdr.c index 0cf3fa312a33..3dd413f52da1 100644 --- a/trunk/fs/nfs/nfs4xdr.c +++ b/trunk/fs/nfs/nfs4xdr.c @@ -471,7 +471,7 @@ struct compound_hdr { static void encode_string(struct xdr_stream *xdr, unsigned int len, const char *str) { - __be32 *p; + uint32_t *p; p = xdr_reserve_space(xdr, 4 + len); BUG_ON(p == NULL); @@ -480,7 +480,7 @@ static void encode_string(struct xdr_stream *xdr, unsigned int len, const char * static int encode_compound_hdr(struct xdr_stream *xdr, struct compound_hdr *hdr) { - __be32 *p; + uint32_t *p; dprintk("encode_compound: tag=%.*s\n", (int)hdr->taglen, hdr->tag); BUG_ON(hdr->taglen > NFS4_MAXTAGLEN); @@ -494,7 +494,7 @@ static int encode_compound_hdr(struct xdr_stream *xdr, struct compound_hdr *hdr) static void encode_nfs4_verifier(struct xdr_stream *xdr, const nfs4_verifier *verf) { - __be32 *p; + uint32_t *p; p = xdr_reserve_space(xdr, NFS4_VERIFIER_SIZE); BUG_ON(p == NULL); @@ -507,8 +507,8 @@ static int encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const s char owner_group[IDMAP_NAMESZ]; int owner_namelen = 0; int owner_grouplen = 0; - __be32 *p; - __be32 *q; + uint32_t *p; + uint32_t *q; int len; uint32_t bmval0 = 0; uint32_t bmval1 = 0; @@ -630,7 +630,7 @@ static int encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const s static int encode_access(struct xdr_stream *xdr, u32 access) { - __be32 *p; + uint32_t *p; RESERVE_SPACE(8); WRITE32(OP_ACCESS); @@ -641,7 +641,7 @@ static int encode_access(struct xdr_stream *xdr, u32 access) static int encode_close(struct xdr_stream *xdr, const struct nfs_closeargs *arg) { - __be32 *p; + uint32_t *p; RESERVE_SPACE(8+sizeof(arg->stateid->data)); WRITE32(OP_CLOSE); @@ -653,7 +653,7 @@ static int encode_close(struct xdr_stream *xdr, const struct nfs_closeargs *arg) static int encode_commit(struct xdr_stream *xdr, const struct nfs_writeargs *args) { - __be32 *p; + uint32_t *p; RESERVE_SPACE(16); WRITE32(OP_COMMIT); @@ -665,7 +665,7 @@ static int encode_commit(struct xdr_stream *xdr, const struct nfs_writeargs *arg static int encode_create(struct xdr_stream *xdr, const struct nfs4_create_arg *create) { - __be32 *p; + uint32_t *p; RESERVE_SPACE(8); WRITE32(OP_CREATE); @@ -697,7 +697,7 @@ static int encode_create(struct xdr_stream *xdr, const struct nfs4_create_arg *c static int encode_getattr_one(struct xdr_stream *xdr, uint32_t bitmap) { - __be32 *p; + uint32_t *p; RESERVE_SPACE(12); WRITE32(OP_GETATTR); @@ -708,7 +708,7 @@ static int encode_getattr_one(struct xdr_stream *xdr, uint32_t bitmap) static int encode_getattr_two(struct xdr_stream *xdr, uint32_t bm0, uint32_t bm1) { - __be32 *p; + uint32_t *p; RESERVE_SPACE(16); WRITE32(OP_GETATTR); @@ -740,7 +740,7 @@ static int encode_fs_locations(struct xdr_stream *xdr, const u32* bitmask) static int encode_getfh(struct xdr_stream *xdr) { - __be32 *p; + uint32_t *p; RESERVE_SPACE(4); WRITE32(OP_GETFH); @@ -750,7 +750,7 @@ static int encode_getfh(struct xdr_stream *xdr) static int encode_link(struct xdr_stream *xdr, const struct qstr *name) { - __be32 *p; + uint32_t *p; RESERVE_SPACE(8 + name->len); WRITE32(OP_LINK); @@ -780,7 +780,7 @@ static inline uint64_t nfs4_lock_length(struct file_lock *fl) */ static int encode_lock(struct xdr_stream *xdr, const struct nfs_lock_args *args) { - __be32 *p; + uint32_t *p; RESERVE_SPACE(32); WRITE32(OP_LOCK); @@ -809,7 +809,7 @@ static int encode_lock(struct xdr_stream *xdr, const struct nfs_lock_args *args) static int encode_lockt(struct xdr_stream *xdr, const struct nfs_lockt_args *args) { - __be32 *p; + uint32_t *p; RESERVE_SPACE(40); WRITE32(OP_LOCKT); @@ -825,7 +825,7 @@ static int encode_lockt(struct xdr_stream *xdr, const struct nfs_lockt_args *arg static int encode_locku(struct xdr_stream *xdr, const struct nfs_locku_args *args) { - __be32 *p; + uint32_t *p; RESERVE_SPACE(44); WRITE32(OP_LOCKU); @@ -841,7 +841,7 @@ static int encode_locku(struct xdr_stream *xdr, const struct nfs_locku_args *arg static int encode_lookup(struct xdr_stream *xdr, const struct qstr *name) { int len = name->len; - __be32 *p; + uint32_t *p; RESERVE_SPACE(8 + len); WRITE32(OP_LOOKUP); @@ -853,7 +853,7 @@ static int encode_lookup(struct xdr_stream *xdr, const struct qstr *name) static void encode_share_access(struct xdr_stream *xdr, int open_flags) { - __be32 *p; + uint32_t *p; RESERVE_SPACE(8); switch (open_flags & (FMODE_READ|FMODE_WRITE)) { @@ -874,7 +874,7 @@ static void encode_share_access(struct xdr_stream *xdr, int open_flags) static inline void encode_openhdr(struct xdr_stream *xdr, const struct nfs_openargs *arg) { - __be32 *p; + uint32_t *p; /* * opcode 4, seqid 4, share_access 4, share_deny 4, clientid 8, ownerlen 4, * owner 4 = 32 @@ -891,7 +891,7 @@ static inline void encode_openhdr(struct xdr_stream *xdr, const struct nfs_opena static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_openargs *arg) { - __be32 *p; + uint32_t *p; RESERVE_SPACE(4); switch(arg->open_flags & O_EXCL) { @@ -907,7 +907,7 @@ static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_op static void encode_opentype(struct xdr_stream *xdr, const struct nfs_openargs *arg) { - __be32 *p; + uint32_t *p; RESERVE_SPACE(4); switch (arg->open_flags & O_CREAT) { @@ -923,7 +923,7 @@ static void encode_opentype(struct xdr_stream *xdr, const struct nfs_openargs *a static inline void encode_delegation_type(struct xdr_stream *xdr, int delegation_type) { - __be32 *p; + uint32_t *p; RESERVE_SPACE(4); switch (delegation_type) { @@ -943,7 +943,7 @@ static inline void encode_delegation_type(struct xdr_stream *xdr, int delegation static inline void encode_claim_null(struct xdr_stream *xdr, const struct qstr *name) { - __be32 *p; + uint32_t *p; RESERVE_SPACE(4); WRITE32(NFS4_OPEN_CLAIM_NULL); @@ -952,7 +952,7 @@ static inline void encode_claim_null(struct xdr_stream *xdr, const struct qstr * static inline void encode_claim_previous(struct xdr_stream *xdr, int type) { - __be32 *p; + uint32_t *p; RESERVE_SPACE(4); WRITE32(NFS4_OPEN_CLAIM_PREVIOUS); @@ -961,7 +961,7 @@ static inline void encode_claim_previous(struct xdr_stream *xdr, int type) static inline void encode_claim_delegate_cur(struct xdr_stream *xdr, const struct qstr *name, const nfs4_stateid *stateid) { - __be32 *p; + uint32_t *p; RESERVE_SPACE(4+sizeof(stateid->data)); WRITE32(NFS4_OPEN_CLAIM_DELEGATE_CUR); @@ -991,7 +991,7 @@ static int encode_open(struct xdr_stream *xdr, const struct nfs_openargs *arg) static int encode_open_confirm(struct xdr_stream *xdr, const struct nfs_open_confirmargs *arg) { - __be32 *p; + uint32_t *p; RESERVE_SPACE(8+sizeof(arg->stateid->data)); WRITE32(OP_OPEN_CONFIRM); @@ -1003,7 +1003,7 @@ static int encode_open_confirm(struct xdr_stream *xdr, const struct nfs_open_con static int encode_open_downgrade(struct xdr_stream *xdr, const struct nfs_closeargs *arg) { - __be32 *p; + uint32_t *p; RESERVE_SPACE(8+sizeof(arg->stateid->data)); WRITE32(OP_OPEN_DOWNGRADE); @@ -1017,7 +1017,7 @@ static int encode_putfh(struct xdr_stream *xdr, const struct nfs_fh *fh) { int len = fh->size; - __be32 *p; + uint32_t *p; RESERVE_SPACE(8 + len); WRITE32(OP_PUTFH); @@ -1029,7 +1029,7 @@ encode_putfh(struct xdr_stream *xdr, const struct nfs_fh *fh) static int encode_putrootfh(struct xdr_stream *xdr) { - __be32 *p; + uint32_t *p; RESERVE_SPACE(4); WRITE32(OP_PUTROOTFH); @@ -1040,7 +1040,7 @@ static int encode_putrootfh(struct xdr_stream *xdr) static void encode_stateid(struct xdr_stream *xdr, const struct nfs_open_context *ctx) { nfs4_stateid stateid; - __be32 *p; + uint32_t *p; RESERVE_SPACE(16); if (ctx->state != NULL) { @@ -1052,7 +1052,7 @@ static void encode_stateid(struct xdr_stream *xdr, const struct nfs_open_context static int encode_read(struct xdr_stream *xdr, const struct nfs_readargs *args) { - __be32 *p; + uint32_t *p; RESERVE_SPACE(4); WRITE32(OP_READ); @@ -1074,7 +1074,7 @@ static int encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg FATTR4_WORD1_MOUNTED_ON_FILEID, }; int replen; - __be32 *p; + uint32_t *p; RESERVE_SPACE(32+sizeof(nfs4_verifier)); WRITE32(OP_READDIR); @@ -1116,7 +1116,7 @@ static int encode_readlink(struct xdr_stream *xdr, const struct nfs4_readlink *r { struct rpc_auth *auth = req->rq_task->tk_auth; unsigned int replen; - __be32 *p; + uint32_t *p; RESERVE_SPACE(4); WRITE32(OP_READLINK); @@ -1134,7 +1134,7 @@ static int encode_readlink(struct xdr_stream *xdr, const struct nfs4_readlink *r static int encode_remove(struct xdr_stream *xdr, const struct qstr *name) { - __be32 *p; + uint32_t *p; RESERVE_SPACE(8 + name->len); WRITE32(OP_REMOVE); @@ -1146,7 +1146,7 @@ static int encode_remove(struct xdr_stream *xdr, const struct qstr *name) static int encode_rename(struct xdr_stream *xdr, const struct qstr *oldname, const struct qstr *newname) { - __be32 *p; + uint32_t *p; RESERVE_SPACE(8 + oldname->len); WRITE32(OP_RENAME); @@ -1162,7 +1162,7 @@ static int encode_rename(struct xdr_stream *xdr, const struct qstr *oldname, con static int encode_renew(struct xdr_stream *xdr, const struct nfs_client *client_stateid) { - __be32 *p; + uint32_t *p; RESERVE_SPACE(12); WRITE32(OP_RENEW); @@ -1174,7 +1174,7 @@ static int encode_renew(struct xdr_stream *xdr, const struct nfs_client *client_ static int encode_restorefh(struct xdr_stream *xdr) { - __be32 *p; + uint32_t *p; RESERVE_SPACE(4); WRITE32(OP_RESTOREFH); @@ -1185,7 +1185,7 @@ encode_restorefh(struct xdr_stream *xdr) static int encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg) { - __be32 *p; + uint32_t *p; RESERVE_SPACE(4+sizeof(zero_stateid.data)); WRITE32(OP_SETATTR); @@ -1204,7 +1204,7 @@ encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg) static int encode_savefh(struct xdr_stream *xdr) { - __be32 *p; + uint32_t *p; RESERVE_SPACE(4); WRITE32(OP_SAVEFH); @@ -1215,7 +1215,7 @@ encode_savefh(struct xdr_stream *xdr) static int encode_setattr(struct xdr_stream *xdr, const struct nfs_setattrargs *arg, const struct nfs_server *server) { int status; - __be32 *p; + uint32_t *p; RESERVE_SPACE(4+sizeof(arg->stateid.data)); WRITE32(OP_SETATTR); @@ -1229,7 +1229,7 @@ static int encode_setattr(struct xdr_stream *xdr, const struct nfs_setattrargs * static int encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclientid *setclientid) { - __be32 *p; + uint32_t *p; RESERVE_SPACE(4 + sizeof(setclientid->sc_verifier->data)); WRITE32(OP_SETCLIENTID); @@ -1248,7 +1248,7 @@ static int encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclien static int encode_setclientid_confirm(struct xdr_stream *xdr, const struct nfs_client *client_state) { - __be32 *p; + uint32_t *p; RESERVE_SPACE(12 + sizeof(client_state->cl_confirm.data)); WRITE32(OP_SETCLIENTID_CONFIRM); @@ -1260,7 +1260,7 @@ static int encode_setclientid_confirm(struct xdr_stream *xdr, const struct nfs_c static int encode_write(struct xdr_stream *xdr, const struct nfs_writeargs *args) { - __be32 *p; + uint32_t *p; RESERVE_SPACE(4); WRITE32(OP_WRITE); @@ -1279,7 +1279,7 @@ static int encode_write(struct xdr_stream *xdr, const struct nfs_writeargs *args static int encode_delegreturn(struct xdr_stream *xdr, const nfs4_stateid *stateid) { - __be32 *p; + uint32_t *p; RESERVE_SPACE(20); @@ -1295,7 +1295,7 @@ static int encode_delegreturn(struct xdr_stream *xdr, const nfs4_stateid *statei /* * Encode an ACCESS request */ -static int nfs4_xdr_enc_access(struct rpc_rqst *req, __be32 *p, const struct nfs4_accessargs *args) +static int nfs4_xdr_enc_access(struct rpc_rqst *req, uint32_t *p, const struct nfs4_accessargs *args) { struct xdr_stream xdr; struct compound_hdr hdr = { @@ -1313,7 +1313,7 @@ static int nfs4_xdr_enc_access(struct rpc_rqst *req, __be32 *p, const struct nfs /* * Encode LOOKUP request */ -static int nfs4_xdr_enc_lookup(struct rpc_rqst *req, __be32 *p, const struct nfs4_lookup_arg *args) +static int nfs4_xdr_enc_lookup(struct rpc_rqst *req, uint32_t *p, const struct nfs4_lookup_arg *args) { struct xdr_stream xdr; struct compound_hdr hdr = { @@ -1337,7 +1337,7 @@ static int nfs4_xdr_enc_lookup(struct rpc_rqst *req, __be32 *p, const struct nfs /* * Encode LOOKUP_ROOT request */ -static int nfs4_xdr_enc_lookup_root(struct rpc_rqst *req, __be32 *p, const struct nfs4_lookup_root_arg *args) +static int nfs4_xdr_enc_lookup_root(struct rpc_rqst *req, uint32_t *p, const struct nfs4_lookup_root_arg *args) { struct xdr_stream xdr; struct compound_hdr hdr = { @@ -1358,7 +1358,7 @@ static int nfs4_xdr_enc_lookup_root(struct rpc_rqst *req, __be32 *p, const struc /* * Encode REMOVE request */ -static int nfs4_xdr_enc_remove(struct rpc_rqst *req, __be32 *p, const struct nfs4_remove_arg *args) +static int nfs4_xdr_enc_remove(struct rpc_rqst *req, uint32_t *p, const struct nfs4_remove_arg *args) { struct xdr_stream xdr; struct compound_hdr hdr = { @@ -1380,7 +1380,7 @@ static int nfs4_xdr_enc_remove(struct rpc_rqst *req, __be32 *p, const struct nfs /* * Encode RENAME request */ -static int nfs4_xdr_enc_rename(struct rpc_rqst *req, __be32 *p, const struct nfs4_rename_arg *args) +static int nfs4_xdr_enc_rename(struct rpc_rqst *req, uint32_t *p, const struct nfs4_rename_arg *args) { struct xdr_stream xdr; struct compound_hdr hdr = { @@ -1410,7 +1410,7 @@ static int nfs4_xdr_enc_rename(struct rpc_rqst *req, __be32 *p, const struct nfs /* * Encode LINK request */ -static int nfs4_xdr_enc_link(struct rpc_rqst *req, __be32 *p, const struct nfs4_link_arg *args) +static int nfs4_xdr_enc_link(struct rpc_rqst *req, uint32_t *p, const struct nfs4_link_arg *args) { struct xdr_stream xdr; struct compound_hdr hdr = { @@ -1440,7 +1440,7 @@ static int nfs4_xdr_enc_link(struct rpc_rqst *req, __be32 *p, const struct nfs4_ /* * Encode CREATE request */ -static int nfs4_xdr_enc_create(struct rpc_rqst *req, __be32 *p, const struct nfs4_create_arg *args) +static int nfs4_xdr_enc_create(struct rpc_rqst *req, uint32_t *p, const struct nfs4_create_arg *args) { struct xdr_stream xdr; struct compound_hdr hdr = { @@ -1470,7 +1470,7 @@ static int nfs4_xdr_enc_create(struct rpc_rqst *req, __be32 *p, const struct nfs /* * Encode SYMLINK request */ -static int nfs4_xdr_enc_symlink(struct rpc_rqst *req, __be32 *p, const struct nfs4_create_arg *args) +static int nfs4_xdr_enc_symlink(struct rpc_rqst *req, uint32_t *p, const struct nfs4_create_arg *args) { return nfs4_xdr_enc_create(req, p, args); } @@ -1478,7 +1478,7 @@ static int nfs4_xdr_enc_symlink(struct rpc_rqst *req, __be32 *p, const struct nf /* * Encode GETATTR request */ -static int nfs4_xdr_enc_getattr(struct rpc_rqst *req, __be32 *p, const struct nfs4_getattr_arg *args) +static int nfs4_xdr_enc_getattr(struct rpc_rqst *req, uint32_t *p, const struct nfs4_getattr_arg *args) { struct xdr_stream xdr; struct compound_hdr hdr = { @@ -1496,7 +1496,7 @@ static int nfs4_xdr_enc_getattr(struct rpc_rqst *req, __be32 *p, const struct nf /* * Encode a CLOSE request */ -static int nfs4_xdr_enc_close(struct rpc_rqst *req, __be32 *p, struct nfs_closeargs *args) +static int nfs4_xdr_enc_close(struct rpc_rqst *req, uint32_t *p, struct nfs_closeargs *args) { struct xdr_stream xdr; struct compound_hdr hdr = { @@ -1520,7 +1520,7 @@ static int nfs4_xdr_enc_close(struct rpc_rqst *req, __be32 *p, struct nfs_closea /* * Encode an OPEN request */ -static int nfs4_xdr_enc_open(struct rpc_rqst *req, __be32 *p, struct nfs_openargs *args) +static int nfs4_xdr_enc_open(struct rpc_rqst *req, uint32_t *p, struct nfs_openargs *args) { struct xdr_stream xdr; struct compound_hdr hdr = { @@ -1556,7 +1556,7 @@ static int nfs4_xdr_enc_open(struct rpc_rqst *req, __be32 *p, struct nfs_openarg /* * Encode an OPEN_CONFIRM request */ -static int nfs4_xdr_enc_open_confirm(struct rpc_rqst *req, __be32 *p, struct nfs_open_confirmargs *args) +static int nfs4_xdr_enc_open_confirm(struct rpc_rqst *req, uint32_t *p, struct nfs_open_confirmargs *args) { struct xdr_stream xdr; struct compound_hdr hdr = { @@ -1577,7 +1577,7 @@ static int nfs4_xdr_enc_open_confirm(struct rpc_rqst *req, __be32 *p, struct nfs /* * Encode an OPEN request with no attributes. */ -static int nfs4_xdr_enc_open_noattr(struct rpc_rqst *req, __be32 *p, struct nfs_openargs *args) +static int nfs4_xdr_enc_open_noattr(struct rpc_rqst *req, uint32_t *p, struct nfs_openargs *args) { struct xdr_stream xdr; struct compound_hdr hdr = { @@ -1601,7 +1601,7 @@ static int nfs4_xdr_enc_open_noattr(struct rpc_rqst *req, __be32 *p, struct nfs_ /* * Encode an OPEN_DOWNGRADE request */ -static int nfs4_xdr_enc_open_downgrade(struct rpc_rqst *req, __be32 *p, struct nfs_closeargs *args) +static int nfs4_xdr_enc_open_downgrade(struct rpc_rqst *req, uint32_t *p, struct nfs_closeargs *args) { struct xdr_stream xdr; struct compound_hdr hdr = { @@ -1625,7 +1625,7 @@ static int nfs4_xdr_enc_open_downgrade(struct rpc_rqst *req, __be32 *p, struct n /* * Encode a LOCK request */ -static int nfs4_xdr_enc_lock(struct rpc_rqst *req, __be32 *p, struct nfs_lock_args *args) +static int nfs4_xdr_enc_lock(struct rpc_rqst *req, uint32_t *p, struct nfs_lock_args *args) { struct xdr_stream xdr; struct compound_hdr hdr = { @@ -1646,7 +1646,7 @@ static int nfs4_xdr_enc_lock(struct rpc_rqst *req, __be32 *p, struct nfs_lock_ar /* * Encode a LOCKT request */ -static int nfs4_xdr_enc_lockt(struct rpc_rqst *req, __be32 *p, struct nfs_lockt_args *args) +static int nfs4_xdr_enc_lockt(struct rpc_rqst *req, uint32_t *p, struct nfs_lockt_args *args) { struct xdr_stream xdr; struct compound_hdr hdr = { @@ -1667,7 +1667,7 @@ static int nfs4_xdr_enc_lockt(struct rpc_rqst *req, __be32 *p, struct nfs_lockt_ /* * Encode a LOCKU request */ -static int nfs4_xdr_enc_locku(struct rpc_rqst *req, __be32 *p, struct nfs_locku_args *args) +static int nfs4_xdr_enc_locku(struct rpc_rqst *req, uint32_t *p, struct nfs_locku_args *args) { struct xdr_stream xdr; struct compound_hdr hdr = { @@ -1688,7 +1688,7 @@ static int nfs4_xdr_enc_locku(struct rpc_rqst *req, __be32 *p, struct nfs_locku_ /* * Encode a READLINK request */ -static int nfs4_xdr_enc_readlink(struct rpc_rqst *req, __be32 *p, const struct nfs4_readlink *args) +static int nfs4_xdr_enc_readlink(struct rpc_rqst *req, uint32_t *p, const struct nfs4_readlink *args) { struct xdr_stream xdr; struct compound_hdr hdr = { @@ -1709,7 +1709,7 @@ static int nfs4_xdr_enc_readlink(struct rpc_rqst *req, __be32 *p, const struct n /* * Encode a READDIR request */ -static int nfs4_xdr_enc_readdir(struct rpc_rqst *req, __be32 *p, const struct nfs4_readdir_arg *args) +static int nfs4_xdr_enc_readdir(struct rpc_rqst *req, uint32_t *p, const struct nfs4_readdir_arg *args) { struct xdr_stream xdr; struct compound_hdr hdr = { @@ -1730,7 +1730,7 @@ static int nfs4_xdr_enc_readdir(struct rpc_rqst *req, __be32 *p, const struct nf /* * Encode a READ request */ -static int nfs4_xdr_enc_read(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args) +static int nfs4_xdr_enc_read(struct rpc_rqst *req, uint32_t *p, struct nfs_readargs *args) { struct rpc_auth *auth = req->rq_task->tk_auth; struct xdr_stream xdr; @@ -1762,7 +1762,7 @@ static int nfs4_xdr_enc_read(struct rpc_rqst *req, __be32 *p, struct nfs_readarg /* * Encode an SETATTR request */ -static int nfs4_xdr_enc_setattr(struct rpc_rqst *req, __be32 *p, struct nfs_setattrargs *args) +static int nfs4_xdr_enc_setattr(struct rpc_rqst *req, uint32_t *p, struct nfs_setattrargs *args) { struct xdr_stream xdr; @@ -1788,7 +1788,7 @@ static int nfs4_xdr_enc_setattr(struct rpc_rqst *req, __be32 *p, struct nfs_seta * Encode a GETACL request */ static int -nfs4_xdr_enc_getacl(struct rpc_rqst *req, __be32 *p, +nfs4_xdr_enc_getacl(struct rpc_rqst *req, uint32_t *p, struct nfs_getaclargs *args) { struct xdr_stream xdr; @@ -1815,7 +1815,7 @@ nfs4_xdr_enc_getacl(struct rpc_rqst *req, __be32 *p, /* * Encode a WRITE request */ -static int nfs4_xdr_enc_write(struct rpc_rqst *req, __be32 *p, struct nfs_writeargs *args) +static int nfs4_xdr_enc_write(struct rpc_rqst *req, uint32_t *p, struct nfs_writeargs *args) { struct xdr_stream xdr; struct compound_hdr hdr = { @@ -1839,7 +1839,7 @@ static int nfs4_xdr_enc_write(struct rpc_rqst *req, __be32 *p, struct nfs_writea /* * a COMMIT request */ -static int nfs4_xdr_enc_commit(struct rpc_rqst *req, __be32 *p, struct nfs_writeargs *args) +static int nfs4_xdr_enc_commit(struct rpc_rqst *req, uint32_t *p, struct nfs_writeargs *args) { struct xdr_stream xdr; struct compound_hdr hdr = { @@ -1863,7 +1863,7 @@ static int nfs4_xdr_enc_commit(struct rpc_rqst *req, __be32 *p, struct nfs_write /* * FSINFO request */ -static int nfs4_xdr_enc_fsinfo(struct rpc_rqst *req, __be32 *p, struct nfs4_fsinfo_arg *args) +static int nfs4_xdr_enc_fsinfo(struct rpc_rqst *req, uint32_t *p, struct nfs4_fsinfo_arg *args) { struct xdr_stream xdr; struct compound_hdr hdr = { @@ -1882,7 +1882,7 @@ static int nfs4_xdr_enc_fsinfo(struct rpc_rqst *req, __be32 *p, struct nfs4_fsin /* * a PATHCONF request */ -static int nfs4_xdr_enc_pathconf(struct rpc_rqst *req, __be32 *p, const struct nfs4_pathconf_arg *args) +static int nfs4_xdr_enc_pathconf(struct rpc_rqst *req, uint32_t *p, const struct nfs4_pathconf_arg *args) { struct xdr_stream xdr; struct compound_hdr hdr = { @@ -1902,7 +1902,7 @@ static int nfs4_xdr_enc_pathconf(struct rpc_rqst *req, __be32 *p, const struct n /* * a STATFS request */ -static int nfs4_xdr_enc_statfs(struct rpc_rqst *req, __be32 *p, const struct nfs4_statfs_arg *args) +static int nfs4_xdr_enc_statfs(struct rpc_rqst *req, uint32_t *p, const struct nfs4_statfs_arg *args) { struct xdr_stream xdr; struct compound_hdr hdr = { @@ -1923,7 +1923,7 @@ static int nfs4_xdr_enc_statfs(struct rpc_rqst *req, __be32 *p, const struct nfs /* * GETATTR_BITMAP request */ -static int nfs4_xdr_enc_server_caps(struct rpc_rqst *req, __be32 *p, const struct nfs_fh *fhandle) +static int nfs4_xdr_enc_server_caps(struct rpc_rqst *req, uint32_t *p, const struct nfs_fh *fhandle) { struct xdr_stream xdr; struct compound_hdr hdr = { @@ -1945,7 +1945,7 @@ static int nfs4_xdr_enc_server_caps(struct rpc_rqst *req, __be32 *p, const struc /* * a RENEW request */ -static int nfs4_xdr_enc_renew(struct rpc_rqst *req, __be32 *p, struct nfs_client *clp) +static int nfs4_xdr_enc_renew(struct rpc_rqst *req, uint32_t *p, struct nfs_client *clp) { struct xdr_stream xdr; struct compound_hdr hdr = { @@ -1960,7 +1960,7 @@ static int nfs4_xdr_enc_renew(struct rpc_rqst *req, __be32 *p, struct nfs_client /* * a SETCLIENTID request */ -static int nfs4_xdr_enc_setclientid(struct rpc_rqst *req, __be32 *p, struct nfs4_setclientid *sc) +static int nfs4_xdr_enc_setclientid(struct rpc_rqst *req, uint32_t *p, struct nfs4_setclientid *sc) { struct xdr_stream xdr; struct compound_hdr hdr = { @@ -1975,7 +1975,7 @@ static int nfs4_xdr_enc_setclientid(struct rpc_rqst *req, __be32 *p, struct nfs4 /* * a SETCLIENTID_CONFIRM request */ -static int nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, __be32 *p, struct nfs_client *clp) +static int nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, uint32_t *p, struct nfs_client *clp) { struct xdr_stream xdr; struct compound_hdr hdr = { @@ -1997,7 +1997,7 @@ static int nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, __be32 *p, str /* * DELEGRETURN request */ -static int nfs4_xdr_enc_delegreturn(struct rpc_rqst *req, __be32 *p, const struct nfs4_delegreturnargs *args) +static int nfs4_xdr_enc_delegreturn(struct rpc_rqst *req, uint32_t *p, const struct nfs4_delegreturnargs *args) { struct xdr_stream xdr; struct compound_hdr hdr = { @@ -2021,7 +2021,7 @@ static int nfs4_xdr_enc_delegreturn(struct rpc_rqst *req, __be32 *p, const struc /* * Encode FS_LOCATIONS request */ -static int nfs4_xdr_enc_fs_locations(struct rpc_rqst *req, __be32 *p, struct nfs4_fs_locations_arg *args) +static int nfs4_xdr_enc_fs_locations(struct rpc_rqst *req, uint32_t *p, struct nfs4_fs_locations_arg *args) { struct xdr_stream xdr; struct compound_hdr hdr = { @@ -2086,7 +2086,7 @@ static int nfs4_xdr_enc_fs_locations(struct rpc_rqst *req, __be32 *p, struct nfs static int decode_opaque_inline(struct xdr_stream *xdr, unsigned int *len, char **string) { - __be32 *p; + uint32_t *p; READ_BUF(4); READ32(*len); @@ -2097,7 +2097,7 @@ static int decode_opaque_inline(struct xdr_stream *xdr, unsigned int *len, char static int decode_compound_hdr(struct xdr_stream *xdr, struct compound_hdr *hdr) { - __be32 *p; + uint32_t *p; READ_BUF(8); READ32(hdr->status); @@ -2112,7 +2112,7 @@ static int decode_compound_hdr(struct xdr_stream *xdr, struct compound_hdr *hdr) static int decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected) { - __be32 *p; + uint32_t *p; uint32_t opnum; int32_t nfserr; @@ -2134,7 +2134,7 @@ static int decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected) /* Dummy routine */ static int decode_ace(struct xdr_stream *xdr, void *ace, struct nfs_client *clp) { - __be32 *p; + uint32_t *p; unsigned int strlen; char *str; @@ -2144,8 +2144,7 @@ static int decode_ace(struct xdr_stream *xdr, void *ace, struct nfs_client *clp) static int decode_attr_bitmap(struct xdr_stream *xdr, uint32_t *bitmap) { - uint32_t bmlen; - __be32 *p; + uint32_t bmlen, *p; READ_BUF(4); READ32(bmlen); @@ -2160,9 +2159,9 @@ static int decode_attr_bitmap(struct xdr_stream *xdr, uint32_t *bitmap) return 0; } -static inline int decode_attr_length(struct xdr_stream *xdr, uint32_t *attrlen, __be32 **savep) +static inline int decode_attr_length(struct xdr_stream *xdr, uint32_t *attrlen, uint32_t **savep) { - __be32 *p; + uint32_t *p; READ_BUF(4); READ32(*attrlen); @@ -2183,7 +2182,7 @@ static int decode_attr_supported(struct xdr_stream *xdr, uint32_t *bitmap, uint3 static int decode_attr_type(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *type) { - __be32 *p; + uint32_t *p; *type = 0; if (unlikely(bitmap[0] & (FATTR4_WORD0_TYPE - 1U))) @@ -2203,7 +2202,7 @@ static int decode_attr_type(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t * static int decode_attr_change(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *change) { - __be32 *p; + uint32_t *p; *change = 0; if (unlikely(bitmap[0] & (FATTR4_WORD0_CHANGE - 1U))) @@ -2220,7 +2219,7 @@ static int decode_attr_change(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t static int decode_attr_size(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *size) { - __be32 *p; + uint32_t *p; *size = 0; if (unlikely(bitmap[0] & (FATTR4_WORD0_SIZE - 1U))) @@ -2236,7 +2235,7 @@ static int decode_attr_size(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t * static int decode_attr_link_support(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) { - __be32 *p; + uint32_t *p; *res = 0; if (unlikely(bitmap[0] & (FATTR4_WORD0_LINK_SUPPORT - 1U))) @@ -2252,7 +2251,7 @@ static int decode_attr_link_support(struct xdr_stream *xdr, uint32_t *bitmap, ui static int decode_attr_symlink_support(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) { - __be32 *p; + uint32_t *p; *res = 0; if (unlikely(bitmap[0] & (FATTR4_WORD0_SYMLINK_SUPPORT - 1U))) @@ -2268,7 +2267,7 @@ static int decode_attr_symlink_support(struct xdr_stream *xdr, uint32_t *bitmap, static int decode_attr_fsid(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_fsid *fsid) { - __be32 *p; + uint32_t *p; fsid->major = 0; fsid->minor = 0; @@ -2288,7 +2287,7 @@ static int decode_attr_fsid(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs static int decode_attr_lease_time(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) { - __be32 *p; + uint32_t *p; *res = 60; if (unlikely(bitmap[0] & (FATTR4_WORD0_LEASE_TIME - 1U))) @@ -2304,7 +2303,7 @@ static int decode_attr_lease_time(struct xdr_stream *xdr, uint32_t *bitmap, uint static int decode_attr_aclsupport(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) { - __be32 *p; + uint32_t *p; *res = ACL4_SUPPORT_ALLOW_ACL|ACL4_SUPPORT_DENY_ACL; if (unlikely(bitmap[0] & (FATTR4_WORD0_ACLSUPPORT - 1U))) @@ -2320,7 +2319,7 @@ static int decode_attr_aclsupport(struct xdr_stream *xdr, uint32_t *bitmap, uint static int decode_attr_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *fileid) { - __be32 *p; + uint32_t *p; *fileid = 0; if (unlikely(bitmap[0] & (FATTR4_WORD0_FILEID - 1U))) @@ -2336,7 +2335,7 @@ static int decode_attr_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t static int decode_attr_mounted_on_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *fileid) { - __be32 *p; + uint32_t *p; *fileid = 0; if (unlikely(bitmap[1] & (FATTR4_WORD1_MOUNTED_ON_FILEID - 1U))) @@ -2352,7 +2351,7 @@ static int decode_attr_mounted_on_fileid(struct xdr_stream *xdr, uint32_t *bitma static int decode_attr_files_avail(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) { - __be32 *p; + uint32_t *p; int status = 0; *res = 0; @@ -2369,7 +2368,7 @@ static int decode_attr_files_avail(struct xdr_stream *xdr, uint32_t *bitmap, uin static int decode_attr_files_free(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) { - __be32 *p; + uint32_t *p; int status = 0; *res = 0; @@ -2386,7 +2385,7 @@ static int decode_attr_files_free(struct xdr_stream *xdr, uint32_t *bitmap, uint static int decode_attr_files_total(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) { - __be32 *p; + uint32_t *p; int status = 0; *res = 0; @@ -2404,7 +2403,7 @@ static int decode_attr_files_total(struct xdr_stream *xdr, uint32_t *bitmap, uin static int decode_pathname(struct xdr_stream *xdr, struct nfs4_pathname *path) { int n; - __be32 *p; + uint32_t *p; int status = 0; READ_BUF(4); @@ -2449,7 +2448,7 @@ static int decode_pathname(struct xdr_stream *xdr, struct nfs4_pathname *path) static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs4_fs_locations *res) { int n; - __be32 *p; + uint32_t *p; int status = -EIO; if (unlikely(bitmap[0] & (FATTR4_WORD0_FS_LOCATIONS -1U))) @@ -2513,7 +2512,7 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st static int decode_attr_maxfilesize(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) { - __be32 *p; + uint32_t *p; int status = 0; *res = 0; @@ -2530,7 +2529,7 @@ static int decode_attr_maxfilesize(struct xdr_stream *xdr, uint32_t *bitmap, uin static int decode_attr_maxlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *maxlink) { - __be32 *p; + uint32_t *p; int status = 0; *maxlink = 1; @@ -2547,7 +2546,7 @@ static int decode_attr_maxlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_ static int decode_attr_maxname(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *maxname) { - __be32 *p; + uint32_t *p; int status = 0; *maxname = 1024; @@ -2564,7 +2563,7 @@ static int decode_attr_maxname(struct xdr_stream *xdr, uint32_t *bitmap, uint32_ static int decode_attr_maxread(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) { - __be32 *p; + uint32_t *p; int status = 0; *res = 1024; @@ -2585,7 +2584,7 @@ static int decode_attr_maxread(struct xdr_stream *xdr, uint32_t *bitmap, uint32_ static int decode_attr_maxwrite(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) { - __be32 *p; + uint32_t *p; int status = 0; *res = 1024; @@ -2606,7 +2605,7 @@ static int decode_attr_maxwrite(struct xdr_stream *xdr, uint32_t *bitmap, uint32 static int decode_attr_mode(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *mode) { - __be32 *p; + uint32_t *p; *mode = 0; if (unlikely(bitmap[1] & (FATTR4_WORD1_MODE - 1U))) @@ -2623,7 +2622,7 @@ static int decode_attr_mode(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t * static int decode_attr_nlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *nlink) { - __be32 *p; + uint32_t *p; *nlink = 1; if (unlikely(bitmap[1] & (FATTR4_WORD1_NUMLINKS - 1U))) @@ -2639,8 +2638,7 @@ static int decode_attr_nlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_client *clp, int32_t *uid) { - uint32_t len; - __be32 *p; + uint32_t len, *p; *uid = -2; if (unlikely(bitmap[1] & (FATTR4_WORD1_OWNER - 1U))) @@ -2664,8 +2662,7 @@ static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, struct nf static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_client *clp, int32_t *gid) { - uint32_t len; - __be32 *p; + uint32_t len, *p; *gid = -2; if (unlikely(bitmap[1] & (FATTR4_WORD1_OWNER_GROUP - 1U))) @@ -2689,8 +2686,7 @@ static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, struct nf static int decode_attr_rdev(struct xdr_stream *xdr, uint32_t *bitmap, dev_t *rdev) { - uint32_t major = 0, minor = 0; - __be32 *p; + uint32_t major = 0, minor = 0, *p; *rdev = MKDEV(0,0); if (unlikely(bitmap[1] & (FATTR4_WORD1_RAWDEV - 1U))) @@ -2712,7 +2708,7 @@ static int decode_attr_rdev(struct xdr_stream *xdr, uint32_t *bitmap, dev_t *rde static int decode_attr_space_avail(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) { - __be32 *p; + uint32_t *p; int status = 0; *res = 0; @@ -2729,7 +2725,7 @@ static int decode_attr_space_avail(struct xdr_stream *xdr, uint32_t *bitmap, uin static int decode_attr_space_free(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) { - __be32 *p; + uint32_t *p; int status = 0; *res = 0; @@ -2746,7 +2742,7 @@ static int decode_attr_space_free(struct xdr_stream *xdr, uint32_t *bitmap, uint static int decode_attr_space_total(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) { - __be32 *p; + uint32_t *p; int status = 0; *res = 0; @@ -2763,7 +2759,7 @@ static int decode_attr_space_total(struct xdr_stream *xdr, uint32_t *bitmap, uin static int decode_attr_space_used(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *used) { - __be32 *p; + uint32_t *p; *used = 0; if (unlikely(bitmap[1] & (FATTR4_WORD1_SPACE_USED - 1U))) @@ -2780,7 +2776,7 @@ static int decode_attr_space_used(struct xdr_stream *xdr, uint32_t *bitmap, uint static int decode_attr_time(struct xdr_stream *xdr, struct timespec *time) { - __be32 *p; + uint32_t *p; uint64_t sec; uint32_t nsec; @@ -2840,7 +2836,7 @@ static int decode_attr_time_modify(struct xdr_stream *xdr, uint32_t *bitmap, str return status; } -static int verify_attr_len(struct xdr_stream *xdr, __be32 *savep, uint32_t attrlen) +static int verify_attr_len(struct xdr_stream *xdr, uint32_t *savep, uint32_t attrlen) { unsigned int attrwords = XDR_QUADLEN(attrlen); unsigned int nwords = xdr->p - savep; @@ -2858,7 +2854,7 @@ static int verify_attr_len(struct xdr_stream *xdr, __be32 *savep, uint32_t attrl static int decode_change_info(struct xdr_stream *xdr, struct nfs4_change_info *cinfo) { - __be32 *p; + uint32_t *p; READ_BUF(20); READ32(cinfo->atomic); @@ -2869,7 +2865,7 @@ static int decode_change_info(struct xdr_stream *xdr, struct nfs4_change_info *c static int decode_access(struct xdr_stream *xdr, struct nfs4_accessres *access) { - __be32 *p; + uint32_t *p; uint32_t supp, acc; int status; @@ -2886,7 +2882,7 @@ static int decode_access(struct xdr_stream *xdr, struct nfs4_accessres *access) static int decode_close(struct xdr_stream *xdr, struct nfs_closeres *res) { - __be32 *p; + uint32_t *p; int status; status = decode_op_hdr(xdr, OP_CLOSE); @@ -2899,7 +2895,7 @@ static int decode_close(struct xdr_stream *xdr, struct nfs_closeres *res) static int decode_commit(struct xdr_stream *xdr, struct nfs_writeres *res) { - __be32 *p; + uint32_t *p; int status; status = decode_op_hdr(xdr, OP_COMMIT); @@ -2912,7 +2908,7 @@ static int decode_commit(struct xdr_stream *xdr, struct nfs_writeres *res) static int decode_create(struct xdr_stream *xdr, struct nfs4_change_info *cinfo) { - __be32 *p; + uint32_t *p; uint32_t bmlen; int status; @@ -2929,7 +2925,7 @@ static int decode_create(struct xdr_stream *xdr, struct nfs4_change_info *cinfo) static int decode_server_caps(struct xdr_stream *xdr, struct nfs4_server_caps_res *res) { - __be32 *savep; + uint32_t *savep; uint32_t attrlen, bitmap[2] = {0}; int status; @@ -2956,7 +2952,7 @@ static int decode_server_caps(struct xdr_stream *xdr, struct nfs4_server_caps_re static int decode_statfs(struct xdr_stream *xdr, struct nfs_fsstat *fsstat) { - __be32 *savep; + uint32_t *savep; uint32_t attrlen, bitmap[2] = {0}; int status; @@ -2989,7 +2985,7 @@ static int decode_statfs(struct xdr_stream *xdr, struct nfs_fsstat *fsstat) static int decode_pathconf(struct xdr_stream *xdr, struct nfs_pathconf *pathconf) { - __be32 *savep; + uint32_t *savep; uint32_t attrlen, bitmap[2] = {0}; int status; @@ -3014,7 +3010,7 @@ static int decode_pathconf(struct xdr_stream *xdr, struct nfs_pathconf *pathconf static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr, const struct nfs_server *server) { - __be32 *savep; + uint32_t *savep; uint32_t attrlen, bitmap[2] = {0}, type; @@ -3083,7 +3079,7 @@ static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr, cons static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo) { - __be32 *savep; + uint32_t *savep; uint32_t attrlen, bitmap[2]; int status; @@ -3115,7 +3111,7 @@ static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo) static int decode_getfh(struct xdr_stream *xdr, struct nfs_fh *fh) { - __be32 *p; + uint32_t *p; uint32_t len; int status; @@ -3151,7 +3147,7 @@ static int decode_link(struct xdr_stream *xdr, struct nfs4_change_info *cinfo) static int decode_lock_denied (struct xdr_stream *xdr, struct file_lock *fl) { uint64_t offset, length, clientid; - __be32 *p; + uint32_t *p; uint32_t namelen, type; READ_BUF(32); @@ -3176,7 +3172,7 @@ static int decode_lock_denied (struct xdr_stream *xdr, struct file_lock *fl) static int decode_lock(struct xdr_stream *xdr, struct nfs_lock_res *res) { - __be32 *p; + uint32_t *p; int status; status = decode_op_hdr(xdr, OP_LOCK); @@ -3199,7 +3195,7 @@ static int decode_lockt(struct xdr_stream *xdr, struct nfs_lockt_res *res) static int decode_locku(struct xdr_stream *xdr, struct nfs_locku_res *res) { - __be32 *p; + uint32_t *p; int status; status = decode_op_hdr(xdr, OP_LOCKU); @@ -3218,7 +3214,7 @@ static int decode_lookup(struct xdr_stream *xdr) /* This is too sick! */ static int decode_space_limit(struct xdr_stream *xdr, u64 *maxsize) { - __be32 *p; + uint32_t *p; uint32_t limit_type, nblocks, blocksize; READ_BUF(12); @@ -3237,7 +3233,7 @@ static int decode_space_limit(struct xdr_stream *xdr, u64 *maxsize) static int decode_delegation(struct xdr_stream *xdr, struct nfs_openres *res) { - __be32 *p; + uint32_t *p; uint32_t delegation_type; READ_BUF(4); @@ -3263,7 +3259,7 @@ static int decode_delegation(struct xdr_stream *xdr, struct nfs_openres *res) static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res) { - __be32 *p; + uint32_t *p; uint32_t bmlen; int status; @@ -3291,7 +3287,7 @@ static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res) static int decode_open_confirm(struct xdr_stream *xdr, struct nfs_open_confirmres *res) { - __be32 *p; + uint32_t *p; int status; status = decode_op_hdr(xdr, OP_OPEN_CONFIRM); @@ -3304,7 +3300,7 @@ static int decode_open_confirm(struct xdr_stream *xdr, struct nfs_open_confirmre static int decode_open_downgrade(struct xdr_stream *xdr, struct nfs_closeres *res) { - __be32 *p; + uint32_t *p; int status; status = decode_op_hdr(xdr, OP_OPEN_DOWNGRADE); @@ -3328,7 +3324,7 @@ static int decode_putrootfh(struct xdr_stream *xdr) static int decode_read(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs_readres *res) { struct kvec *iov = req->rq_rcv_buf.head; - __be32 *p; + uint32_t *p; uint32_t count, eof, recvd, hdrlen; int status; @@ -3358,7 +3354,7 @@ static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct n struct page *page = *rcvbuf->pages; struct kvec *iov = rcvbuf->head; unsigned int nr, pglen = rcvbuf->page_len; - __be32 *end, *entry, *p, *kaddr; + uint32_t *end, *entry, *p, *kaddr; uint32_t len, attrlen, xlen; int hdrlen, recvd, status; @@ -3380,7 +3376,7 @@ static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct n xdr_read_pages(xdr, pglen); BUG_ON(pglen + readdir->pgbase > PAGE_CACHE_SIZE); - kaddr = p = kmap_atomic(page, KM_USER0); + kaddr = p = (uint32_t *) kmap_atomic(page, KM_USER0); end = p + ((pglen + readdir->pgbase) >> 2); entry = p; for (nr = 0; *p++; nr++) { @@ -3432,7 +3428,7 @@ static int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req) struct xdr_buf *rcvbuf = &req->rq_rcv_buf; struct kvec *iov = rcvbuf->head; int hdrlen, len, recvd; - __be32 *p; + uint32_t *p; char *kaddr; int status; @@ -3509,7 +3505,7 @@ decode_restorefh(struct xdr_stream *xdr) static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req, size_t *acl_len) { - __be32 *savep; + uint32_t *savep; uint32_t attrlen, bitmap[2] = {0}; struct kvec *iov = req->rq_rcv_buf.head; @@ -3555,7 +3551,7 @@ decode_savefh(struct xdr_stream *xdr) static int decode_setattr(struct xdr_stream *xdr, struct nfs_setattrres *res) { - __be32 *p; + uint32_t *p; uint32_t bmlen; int status; @@ -3571,7 +3567,7 @@ static int decode_setattr(struct xdr_stream *xdr, struct nfs_setattrres *res) static int decode_setclientid(struct xdr_stream *xdr, struct nfs_client *clp) { - __be32 *p; + uint32_t *p; uint32_t opnum; int32_t nfserr; @@ -3614,7 +3610,7 @@ static int decode_setclientid_confirm(struct xdr_stream *xdr) static int decode_write(struct xdr_stream *xdr, struct nfs_writeres *res) { - __be32 *p; + uint32_t *p; int status; status = decode_op_hdr(xdr, OP_WRITE); @@ -3636,7 +3632,7 @@ static int decode_delegreturn(struct xdr_stream *xdr) /* * Decode OPEN_DOWNGRADE response */ -static int nfs4_xdr_dec_open_downgrade(struct rpc_rqst *rqstp, __be32 *p, struct nfs_closeres *res) +static int nfs4_xdr_dec_open_downgrade(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_closeres *res) { struct xdr_stream xdr; struct compound_hdr hdr; @@ -3664,7 +3660,7 @@ static int nfs4_xdr_dec_open_downgrade(struct rpc_rqst *rqstp, __be32 *p, struct /* * Decode ACCESS response */ -static int nfs4_xdr_dec_access(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_accessres *res) +static int nfs4_xdr_dec_access(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_accessres *res) { struct xdr_stream xdr; struct compound_hdr hdr; @@ -3682,7 +3678,7 @@ static int nfs4_xdr_dec_access(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_ac /* * Decode LOOKUP response */ -static int nfs4_xdr_dec_lookup(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_lookup_res *res) +static int nfs4_xdr_dec_lookup(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_lookup_res *res) { struct xdr_stream xdr; struct compound_hdr hdr; @@ -3705,7 +3701,7 @@ static int nfs4_xdr_dec_lookup(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_lo /* * Decode LOOKUP_ROOT response */ -static int nfs4_xdr_dec_lookup_root(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_lookup_res *res) +static int nfs4_xdr_dec_lookup_root(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_lookup_res *res) { struct xdr_stream xdr; struct compound_hdr hdr; @@ -3725,7 +3721,7 @@ static int nfs4_xdr_dec_lookup_root(struct rpc_rqst *rqstp, __be32 *p, struct nf /* * Decode REMOVE response */ -static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_remove_res *res) +static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_remove_res *res) { struct xdr_stream xdr; struct compound_hdr hdr; @@ -3746,7 +3742,7 @@ static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_re /* * Decode RENAME response */ -static int nfs4_xdr_dec_rename(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_rename_res *res) +static int nfs4_xdr_dec_rename(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_rename_res *res) { struct xdr_stream xdr; struct compound_hdr hdr; @@ -3776,7 +3772,7 @@ static int nfs4_xdr_dec_rename(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_re /* * Decode LINK response */ -static int nfs4_xdr_dec_link(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_link_res *res) +static int nfs4_xdr_dec_link(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_link_res *res) { struct xdr_stream xdr; struct compound_hdr hdr; @@ -3809,7 +3805,7 @@ static int nfs4_xdr_dec_link(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_link /* * Decode CREATE response */ -static int nfs4_xdr_dec_create(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_create_res *res) +static int nfs4_xdr_dec_create(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_create_res *res) { struct xdr_stream xdr; struct compound_hdr hdr; @@ -3838,7 +3834,7 @@ static int nfs4_xdr_dec_create(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_cr /* * Decode SYMLINK response */ -static int nfs4_xdr_dec_symlink(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_create_res *res) +static int nfs4_xdr_dec_symlink(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_create_res *res) { return nfs4_xdr_dec_create(rqstp, p, res); } @@ -3846,7 +3842,7 @@ static int nfs4_xdr_dec_symlink(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_c /* * Decode GETATTR response */ -static int nfs4_xdr_dec_getattr(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_getattr_res *res) +static int nfs4_xdr_dec_getattr(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_getattr_res *res) { struct xdr_stream xdr; struct compound_hdr hdr; @@ -3869,7 +3865,7 @@ static int nfs4_xdr_dec_getattr(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_g * Encode an SETACL request */ static int -nfs4_xdr_enc_setacl(struct rpc_rqst *req, __be32 *p, struct nfs_setaclargs *args) +nfs4_xdr_enc_setacl(struct rpc_rqst *req, uint32_t *p, struct nfs_setaclargs *args) { struct xdr_stream xdr; struct compound_hdr hdr = { @@ -3890,7 +3886,7 @@ nfs4_xdr_enc_setacl(struct rpc_rqst *req, __be32 *p, struct nfs_setaclargs *args * Decode SETACL response */ static int -nfs4_xdr_dec_setacl(struct rpc_rqst *rqstp, __be32 *p, void *res) +nfs4_xdr_dec_setacl(struct rpc_rqst *rqstp, uint32_t *p, void *res) { struct xdr_stream xdr; struct compound_hdr hdr; @@ -3912,7 +3908,7 @@ nfs4_xdr_dec_setacl(struct rpc_rqst *rqstp, __be32 *p, void *res) * Decode GETACL response */ static int -nfs4_xdr_dec_getacl(struct rpc_rqst *rqstp, __be32 *p, size_t *acl_len) +nfs4_xdr_dec_getacl(struct rpc_rqst *rqstp, uint32_t *p, size_t *acl_len) { struct xdr_stream xdr; struct compound_hdr hdr; @@ -3934,7 +3930,7 @@ nfs4_xdr_dec_getacl(struct rpc_rqst *rqstp, __be32 *p, size_t *acl_len) /* * Decode CLOSE response */ -static int nfs4_xdr_dec_close(struct rpc_rqst *rqstp, __be32 *p, struct nfs_closeres *res) +static int nfs4_xdr_dec_close(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_closeres *res) { struct xdr_stream xdr; struct compound_hdr hdr; @@ -3964,7 +3960,7 @@ static int nfs4_xdr_dec_close(struct rpc_rqst *rqstp, __be32 *p, struct nfs_clos /* * Decode OPEN response */ -static int nfs4_xdr_dec_open(struct rpc_rqst *rqstp, __be32 *p, struct nfs_openres *res) +static int nfs4_xdr_dec_open(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_openres *res) { struct xdr_stream xdr; struct compound_hdr hdr; @@ -3998,7 +3994,7 @@ static int nfs4_xdr_dec_open(struct rpc_rqst *rqstp, __be32 *p, struct nfs_openr /* * Decode OPEN_CONFIRM response */ -static int nfs4_xdr_dec_open_confirm(struct rpc_rqst *rqstp, __be32 *p, struct nfs_open_confirmres *res) +static int nfs4_xdr_dec_open_confirm(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_open_confirmres *res) { struct xdr_stream xdr; struct compound_hdr hdr; @@ -4019,7 +4015,7 @@ static int nfs4_xdr_dec_open_confirm(struct rpc_rqst *rqstp, __be32 *p, struct n /* * Decode OPEN response */ -static int nfs4_xdr_dec_open_noattr(struct rpc_rqst *rqstp, __be32 *p, struct nfs_openres *res) +static int nfs4_xdr_dec_open_noattr(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_openres *res) { struct xdr_stream xdr; struct compound_hdr hdr; @@ -4043,7 +4039,7 @@ static int nfs4_xdr_dec_open_noattr(struct rpc_rqst *rqstp, __be32 *p, struct nf /* * Decode SETATTR response */ -static int nfs4_xdr_dec_setattr(struct rpc_rqst *rqstp, __be32 *p, struct nfs_setattrres *res) +static int nfs4_xdr_dec_setattr(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_setattrres *res) { struct xdr_stream xdr; struct compound_hdr hdr; @@ -4069,7 +4065,7 @@ static int nfs4_xdr_dec_setattr(struct rpc_rqst *rqstp, __be32 *p, struct nfs_se /* * Decode LOCK response */ -static int nfs4_xdr_dec_lock(struct rpc_rqst *rqstp, __be32 *p, struct nfs_lock_res *res) +static int nfs4_xdr_dec_lock(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_lock_res *res) { struct xdr_stream xdr; struct compound_hdr hdr; @@ -4090,7 +4086,7 @@ static int nfs4_xdr_dec_lock(struct rpc_rqst *rqstp, __be32 *p, struct nfs_lock_ /* * Decode LOCKT response */ -static int nfs4_xdr_dec_lockt(struct rpc_rqst *rqstp, __be32 *p, struct nfs_lockt_res *res) +static int nfs4_xdr_dec_lockt(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_lockt_res *res) { struct xdr_stream xdr; struct compound_hdr hdr; @@ -4111,7 +4107,7 @@ static int nfs4_xdr_dec_lockt(struct rpc_rqst *rqstp, __be32 *p, struct nfs_lock /* * Decode LOCKU response */ -static int nfs4_xdr_dec_locku(struct rpc_rqst *rqstp, __be32 *p, struct nfs_locku_res *res) +static int nfs4_xdr_dec_locku(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_locku_res *res) { struct xdr_stream xdr; struct compound_hdr hdr; @@ -4132,7 +4128,7 @@ static int nfs4_xdr_dec_locku(struct rpc_rqst *rqstp, __be32 *p, struct nfs_lock /* * Decode READLINK response */ -static int nfs4_xdr_dec_readlink(struct rpc_rqst *rqstp, __be32 *p, void *res) +static int nfs4_xdr_dec_readlink(struct rpc_rqst *rqstp, uint32_t *p, void *res) { struct xdr_stream xdr; struct compound_hdr hdr; @@ -4153,7 +4149,7 @@ static int nfs4_xdr_dec_readlink(struct rpc_rqst *rqstp, __be32 *p, void *res) /* * Decode READDIR response */ -static int nfs4_xdr_dec_readdir(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_readdir_res *res) +static int nfs4_xdr_dec_readdir(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_readdir_res *res) { struct xdr_stream xdr; struct compound_hdr hdr; @@ -4174,7 +4170,7 @@ static int nfs4_xdr_dec_readdir(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_r /* * Decode Read response */ -static int nfs4_xdr_dec_read(struct rpc_rqst *rqstp, __be32 *p, struct nfs_readres *res) +static int nfs4_xdr_dec_read(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_readres *res) { struct xdr_stream xdr; struct compound_hdr hdr; @@ -4197,7 +4193,7 @@ static int nfs4_xdr_dec_read(struct rpc_rqst *rqstp, __be32 *p, struct nfs_readr /* * Decode WRITE response */ -static int nfs4_xdr_dec_write(struct rpc_rqst *rqstp, __be32 *p, struct nfs_writeres *res) +static int nfs4_xdr_dec_write(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_writeres *res) { struct xdr_stream xdr; struct compound_hdr hdr; @@ -4223,7 +4219,7 @@ static int nfs4_xdr_dec_write(struct rpc_rqst *rqstp, __be32 *p, struct nfs_writ /* * Decode COMMIT response */ -static int nfs4_xdr_dec_commit(struct rpc_rqst *rqstp, __be32 *p, struct nfs_writeres *res) +static int nfs4_xdr_dec_commit(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_writeres *res) { struct xdr_stream xdr; struct compound_hdr hdr; @@ -4247,7 +4243,7 @@ static int nfs4_xdr_dec_commit(struct rpc_rqst *rqstp, __be32 *p, struct nfs_wri /* * FSINFO request */ -static int nfs4_xdr_dec_fsinfo(struct rpc_rqst *req, __be32 *p, struct nfs_fsinfo *fsinfo) +static int nfs4_xdr_dec_fsinfo(struct rpc_rqst *req, uint32_t *p, struct nfs_fsinfo *fsinfo) { struct xdr_stream xdr; struct compound_hdr hdr; @@ -4267,7 +4263,7 @@ static int nfs4_xdr_dec_fsinfo(struct rpc_rqst *req, __be32 *p, struct nfs_fsinf /* * PATHCONF request */ -static int nfs4_xdr_dec_pathconf(struct rpc_rqst *req, __be32 *p, struct nfs_pathconf *pathconf) +static int nfs4_xdr_dec_pathconf(struct rpc_rqst *req, uint32_t *p, struct nfs_pathconf *pathconf) { struct xdr_stream xdr; struct compound_hdr hdr; @@ -4285,7 +4281,7 @@ static int nfs4_xdr_dec_pathconf(struct rpc_rqst *req, __be32 *p, struct nfs_pat /* * STATFS request */ -static int nfs4_xdr_dec_statfs(struct rpc_rqst *req, __be32 *p, struct nfs_fsstat *fsstat) +static int nfs4_xdr_dec_statfs(struct rpc_rqst *req, uint32_t *p, struct nfs_fsstat *fsstat) { struct xdr_stream xdr; struct compound_hdr hdr; @@ -4303,7 +4299,7 @@ static int nfs4_xdr_dec_statfs(struct rpc_rqst *req, __be32 *p, struct nfs_fssta /* * GETATTR_BITMAP request */ -static int nfs4_xdr_dec_server_caps(struct rpc_rqst *req, __be32 *p, struct nfs4_server_caps_res *res) +static int nfs4_xdr_dec_server_caps(struct rpc_rqst *req, uint32_t *p, struct nfs4_server_caps_res *res) { struct xdr_stream xdr; struct compound_hdr hdr; @@ -4322,7 +4318,7 @@ static int nfs4_xdr_dec_server_caps(struct rpc_rqst *req, __be32 *p, struct nfs4 /* * Decode RENEW response */ -static int nfs4_xdr_dec_renew(struct rpc_rqst *rqstp, __be32 *p, void *dummy) +static int nfs4_xdr_dec_renew(struct rpc_rqst *rqstp, uint32_t *p, void *dummy) { struct xdr_stream xdr; struct compound_hdr hdr; @@ -4338,7 +4334,7 @@ static int nfs4_xdr_dec_renew(struct rpc_rqst *rqstp, __be32 *p, void *dummy) /* * a SETCLIENTID request */ -static int nfs4_xdr_dec_setclientid(struct rpc_rqst *req, __be32 *p, +static int nfs4_xdr_dec_setclientid(struct rpc_rqst *req, uint32_t *p, struct nfs_client *clp) { struct xdr_stream xdr; @@ -4357,7 +4353,7 @@ static int nfs4_xdr_dec_setclientid(struct rpc_rqst *req, __be32 *p, /* * a SETCLIENTID_CONFIRM request */ -static int nfs4_xdr_dec_setclientid_confirm(struct rpc_rqst *req, __be32 *p, struct nfs_fsinfo *fsinfo) +static int nfs4_xdr_dec_setclientid_confirm(struct rpc_rqst *req, uint32_t *p, struct nfs_fsinfo *fsinfo) { struct xdr_stream xdr; struct compound_hdr hdr; @@ -4379,7 +4375,7 @@ static int nfs4_xdr_dec_setclientid_confirm(struct rpc_rqst *req, __be32 *p, str /* * DELEGRETURN request */ -static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_delegreturnres *res) +static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_delegreturnres *res) { struct xdr_stream xdr; struct compound_hdr hdr; @@ -4401,7 +4397,7 @@ static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp, __be32 *p, struct nf /* * FS_LOCATIONS request */ -static int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req, __be32 *p, struct nfs4_fs_locations *res) +static int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req, uint32_t *p, struct nfs4_fs_locations *res) { struct xdr_stream xdr; struct compound_hdr hdr; @@ -4421,7 +4417,7 @@ static int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req, __be32 *p, struct nfs return status; } -__be32 *nfs4_decode_dirent(__be32 *p, struct nfs_entry *entry, int plus) +uint32_t *nfs4_decode_dirent(uint32_t *p, struct nfs_entry *entry, int plus) { uint32_t bitmap[2] = {0}; uint32_t len; diff --git a/trunk/fs/nfs/super.c b/trunk/fs/nfs/super.c index 28108c82b887..28659a919d6e 100644 --- a/trunk/fs/nfs/super.c +++ b/trunk/fs/nfs/super.c @@ -834,7 +834,7 @@ static int nfs4_get_sb(struct file_system_type *fs_type, } /* RFC3530: The default port for NFS is 2049 */ if (addr.sin_port == 0) - addr.sin_port = htons(NFS_PORT); + addr.sin_port = NFS_PORT; /* Grab the authentication type */ authflavour = RPC_AUTH_UNIX; diff --git a/trunk/fs/nfs/sysctl.c b/trunk/fs/nfs/sysctl.c index 3ea50ac64820..2fe3403c2409 100644 --- a/trunk/fs/nfs/sysctl.c +++ b/trunk/fs/nfs/sysctl.c @@ -18,6 +18,11 @@ static const int nfs_set_port_min = 0; static const int nfs_set_port_max = 65535; static struct ctl_table_header *nfs_callback_sysctl_table; +/* + * Something that isn't CTL_ANY, CTL_NONE or a value that may clash. + * Use the same values as fs/lockd/svc.c + */ +#define CTL_UNNUMBERED -2 static ctl_table nfs_cb_sysctls[] = { #ifdef CONFIG_NFS_V4 diff --git a/trunk/fs/nfs/write.c b/trunk/fs/nfs/write.c index 883dd4a1c157..f6675d2c386c 100644 --- a/trunk/fs/nfs/write.c +++ b/trunk/fs/nfs/write.c @@ -57,8 +57,6 @@ #include #include #include -#include - #include #include @@ -397,7 +395,7 @@ int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc) out: clear_bit(BDI_write_congested, &bdi->state); wake_up_all(&nfs_write_congestion); - congestion_end(WRITE); + writeback_congestion_end(); return err; } @@ -590,10 +588,10 @@ static void nfs_cancel_commit_list(struct list_head *head) while(!list_empty(head)) { req = nfs_list_entry(head->next); - dec_zone_page_state(req->wb_page, NR_UNSTABLE_NFS); nfs_list_remove_request(req); nfs_inode_remove_request(req); - nfs_unlock_request(req); + dec_zone_page_state(req->wb_page, NR_UNSTABLE_NFS); + nfs_clear_page_writeback(req); } } diff --git a/trunk/fs/nfs_common/nfsacl.c b/trunk/fs/nfs_common/nfsacl.c index c11f5375d7c1..0c2be8c0307d 100644 --- a/trunk/fs/nfs_common/nfsacl.c +++ b/trunk/fs/nfs_common/nfsacl.c @@ -46,7 +46,7 @@ xdr_nfsace_encode(struct xdr_array2_desc *desc, void *elem) { struct nfsacl_encode_desc *nfsacl_desc = (struct nfsacl_encode_desc *) desc; - __be32 *p = elem; + u32 *p = (u32 *) elem; struct posix_acl_entry *entry = &nfsacl_desc->acl->a_entries[nfsacl_desc->count++]; @@ -127,7 +127,7 @@ xdr_nfsace_decode(struct xdr_array2_desc *desc, void *elem) { struct nfsacl_decode_desc *nfsacl_desc = (struct nfsacl_decode_desc *) desc; - __be32 *p = elem; + u32 *p = (u32 *) elem; struct posix_acl_entry *entry; if (!nfsacl_desc->acl) { diff --git a/trunk/fs/nfsd/export.c b/trunk/fs/nfsd/export.c index f37df46d2eaa..e13fa23bd108 100644 --- a/trunk/fs/nfsd/export.c +++ b/trunk/fs/nfsd/export.c @@ -1148,12 +1148,12 @@ exp_find(struct auth_domain *clp, int fsid_type, u32 *fsidv, * for a given NFSv4 client. The root is defined to be the * export point with fsid==0 */ -__be32 +int exp_pseudoroot(struct auth_domain *clp, struct svc_fh *fhp, struct cache_req *creq) { struct svc_export *exp; - __be32 rv; + int rv; u32 fsidv[2]; mk_fsid_v1(fsidv, 0); diff --git a/trunk/fs/nfsd/lockd.c b/trunk/fs/nfsd/lockd.c index 11fdaf7721b4..7b889ff15ae6 100644 --- a/trunk/fs/nfsd/lockd.c +++ b/trunk/fs/nfsd/lockd.c @@ -25,7 +25,7 @@ static u32 nlm_fopen(struct svc_rqst *rqstp, struct nfs_fh *f, struct file **filp) { - __be32 nfserr; + u32 nfserr; struct svc_fh fh; /* must initialize before using! but maxsize doesn't matter */ @@ -39,20 +39,18 @@ nlm_fopen(struct svc_rqst *rqstp, struct nfs_fh *f, struct file **filp) fh_put(&fh); rqstp->rq_client = NULL; exp_readunlock(); - /* We return nlm error codes as nlm doesn't know - * about nfsd, but nfsd does know about nlm.. + /* nlm and nfsd don't share error codes. + * we invent: 0 = no error + * 1 = stale file handle + * 2 = other error */ switch (nfserr) { case nfs_ok: return 0; - case nfserr_dropit: - return nlm_drop_reply; -#ifdef CONFIG_LOCKD_V4 case nfserr_stale: - return nlm4_stale_fh; -#endif + return 1; default: - return nlm_lck_denied; + return 2; } } diff --git a/trunk/fs/nfsd/nfs2acl.c b/trunk/fs/nfsd/nfs2acl.c index e3eca0816986..9187755661df 100644 --- a/trunk/fs/nfsd/nfs2acl.c +++ b/trunk/fs/nfsd/nfs2acl.c @@ -21,7 +21,7 @@ /* * NULL call. */ -static __be32 +static int nfsacld_proc_null(struct svc_rqst *rqstp, void *argp, void *resp) { return nfs_ok; @@ -30,12 +30,12 @@ nfsacld_proc_null(struct svc_rqst *rqstp, void *argp, void *resp) /* * Get the Access and/or Default ACL of a file. */ -static __be32 nfsacld_proc_getacl(struct svc_rqst * rqstp, +static int nfsacld_proc_getacl(struct svc_rqst * rqstp, struct nfsd3_getaclargs *argp, struct nfsd3_getaclres *resp) { svc_fh *fh; struct posix_acl *acl; - __be32 nfserr = 0; + int nfserr = 0; dprintk("nfsd: GETACL(2acl) %s\n", SVCFH_fmt(&argp->fh)); @@ -97,12 +97,12 @@ static __be32 nfsacld_proc_getacl(struct svc_rqst * rqstp, /* * Set the Access and/or Default ACL of a file. */ -static __be32 nfsacld_proc_setacl(struct svc_rqst * rqstp, +static int nfsacld_proc_setacl(struct svc_rqst * rqstp, struct nfsd3_setaclargs *argp, struct nfsd_attrstat *resp) { svc_fh *fh; - __be32 nfserr = 0; + int nfserr = 0; dprintk("nfsd: SETACL(2acl) %s\n", SVCFH_fmt(&argp->fh)); @@ -128,7 +128,7 @@ static __be32 nfsacld_proc_setacl(struct svc_rqst * rqstp, /* * Check file attributes */ -static __be32 nfsacld_proc_getattr(struct svc_rqst * rqstp, +static int nfsacld_proc_getattr(struct svc_rqst * rqstp, struct nfsd_fhandle *argp, struct nfsd_attrstat *resp) { dprintk("nfsd: GETATTR %s\n", SVCFH_fmt(&argp->fh)); @@ -140,10 +140,10 @@ static __be32 nfsacld_proc_getattr(struct svc_rqst * rqstp, /* * Check file access */ -static __be32 nfsacld_proc_access(struct svc_rqst *rqstp, struct nfsd3_accessargs *argp, +static int nfsacld_proc_access(struct svc_rqst *rqstp, struct nfsd3_accessargs *argp, struct nfsd3_accessres *resp) { - __be32 nfserr; + int nfserr; dprintk("nfsd: ACCESS(2acl) %s 0x%x\n", SVCFH_fmt(&argp->fh), @@ -158,7 +158,7 @@ static __be32 nfsacld_proc_access(struct svc_rqst *rqstp, struct nfsd3_accessarg /* * XDR decode functions */ -static int nfsaclsvc_decode_getaclargs(struct svc_rqst *rqstp, __be32 *p, +static int nfsaclsvc_decode_getaclargs(struct svc_rqst *rqstp, u32 *p, struct nfsd3_getaclargs *argp) { if (!(p = nfs2svc_decode_fh(p, &argp->fh))) @@ -169,7 +169,7 @@ static int nfsaclsvc_decode_getaclargs(struct svc_rqst *rqstp, __be32 *p, } -static int nfsaclsvc_decode_setaclargs(struct svc_rqst *rqstp, __be32 *p, +static int nfsaclsvc_decode_setaclargs(struct svc_rqst *rqstp, u32 *p, struct nfsd3_setaclargs *argp) { struct kvec *head = rqstp->rq_arg.head; @@ -194,7 +194,7 @@ static int nfsaclsvc_decode_setaclargs(struct svc_rqst *rqstp, __be32 *p, return (n > 0); } -static int nfsaclsvc_decode_fhandleargs(struct svc_rqst *rqstp, __be32 *p, +static int nfsaclsvc_decode_fhandleargs(struct svc_rqst *rqstp, u32 *p, struct nfsd_fhandle *argp) { if (!(p = nfs2svc_decode_fh(p, &argp->fh))) @@ -202,7 +202,7 @@ static int nfsaclsvc_decode_fhandleargs(struct svc_rqst *rqstp, __be32 *p, return xdr_argsize_check(rqstp, p); } -static int nfsaclsvc_decode_accessargs(struct svc_rqst *rqstp, __be32 *p, +static int nfsaclsvc_decode_accessargs(struct svc_rqst *rqstp, u32 *p, struct nfsd3_accessargs *argp) { if (!(p = nfs2svc_decode_fh(p, &argp->fh))) @@ -217,7 +217,7 @@ static int nfsaclsvc_decode_accessargs(struct svc_rqst *rqstp, __be32 *p, */ /* GETACL */ -static int nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, __be32 *p, +static int nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, u32 *p, struct nfsd3_getaclres *resp) { struct dentry *dentry = resp->fh.fh_dentry; @@ -259,7 +259,7 @@ static int nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, __be32 *p, return 1; } -static int nfsaclsvc_encode_attrstatres(struct svc_rqst *rqstp, __be32 *p, +static int nfsaclsvc_encode_attrstatres(struct svc_rqst *rqstp, u32 *p, struct nfsd_attrstat *resp) { p = nfs2svc_encode_fattr(rqstp, p, &resp->fh); @@ -267,7 +267,7 @@ static int nfsaclsvc_encode_attrstatres(struct svc_rqst *rqstp, __be32 *p, } /* ACCESS */ -static int nfsaclsvc_encode_accessres(struct svc_rqst *rqstp, __be32 *p, +static int nfsaclsvc_encode_accessres(struct svc_rqst *rqstp, u32 *p, struct nfsd3_accessres *resp) { p = nfs2svc_encode_fattr(rqstp, p, &resp->fh); @@ -278,7 +278,7 @@ static int nfsaclsvc_encode_accessres(struct svc_rqst *rqstp, __be32 *p, /* * XDR release functions */ -static int nfsaclsvc_release_getacl(struct svc_rqst *rqstp, __be32 *p, +static int nfsaclsvc_release_getacl(struct svc_rqst *rqstp, u32 *p, struct nfsd3_getaclres *resp) { fh_put(&resp->fh); @@ -287,7 +287,7 @@ static int nfsaclsvc_release_getacl(struct svc_rqst *rqstp, __be32 *p, return 1; } -static int nfsaclsvc_release_fhandle(struct svc_rqst *rqstp, __be32 *p, +static int nfsaclsvc_release_fhandle(struct svc_rqst *rqstp, u32 *p, struct nfsd_fhandle *resp) { fh_put(&resp->fh); diff --git a/trunk/fs/nfsd/nfs3acl.c b/trunk/fs/nfsd/nfs3acl.c index fcad2895ddb0..d4bdc00c1169 100644 --- a/trunk/fs/nfsd/nfs3acl.c +++ b/trunk/fs/nfsd/nfs3acl.c @@ -19,7 +19,7 @@ /* * NULL call. */ -static __be32 +static int nfsd3_proc_null(struct svc_rqst *rqstp, void *argp, void *resp) { return nfs_ok; @@ -28,12 +28,12 @@ nfsd3_proc_null(struct svc_rqst *rqstp, void *argp, void *resp) /* * Get the Access and/or Default ACL of a file. */ -static __be32 nfsd3_proc_getacl(struct svc_rqst * rqstp, +static int nfsd3_proc_getacl(struct svc_rqst * rqstp, struct nfsd3_getaclargs *argp, struct nfsd3_getaclres *resp) { svc_fh *fh; struct posix_acl *acl; - __be32 nfserr = 0; + int nfserr = 0; fh = fh_copy(&resp->fh, &argp->fh); if ((nfserr = fh_verify(rqstp, &resp->fh, 0, MAY_NOP))) @@ -93,12 +93,12 @@ static __be32 nfsd3_proc_getacl(struct svc_rqst * rqstp, /* * Set the Access and/or Default ACL of a file. */ -static __be32 nfsd3_proc_setacl(struct svc_rqst * rqstp, +static int nfsd3_proc_setacl(struct svc_rqst * rqstp, struct nfsd3_setaclargs *argp, struct nfsd3_attrstat *resp) { svc_fh *fh; - __be32 nfserr = 0; + int nfserr = 0; fh = fh_copy(&resp->fh, &argp->fh); nfserr = fh_verify(rqstp, &resp->fh, 0, MAY_SATTR); @@ -122,7 +122,7 @@ static __be32 nfsd3_proc_setacl(struct svc_rqst * rqstp, /* * XDR decode functions */ -static int nfs3svc_decode_getaclargs(struct svc_rqst *rqstp, __be32 *p, +static int nfs3svc_decode_getaclargs(struct svc_rqst *rqstp, u32 *p, struct nfsd3_getaclargs *args) { if (!(p = nfs3svc_decode_fh(p, &args->fh))) @@ -133,7 +133,7 @@ static int nfs3svc_decode_getaclargs(struct svc_rqst *rqstp, __be32 *p, } -static int nfs3svc_decode_setaclargs(struct svc_rqst *rqstp, __be32 *p, +static int nfs3svc_decode_setaclargs(struct svc_rqst *rqstp, u32 *p, struct nfsd3_setaclargs *args) { struct kvec *head = rqstp->rq_arg.head; @@ -163,7 +163,7 @@ static int nfs3svc_decode_setaclargs(struct svc_rqst *rqstp, __be32 *p, */ /* GETACL */ -static int nfs3svc_encode_getaclres(struct svc_rqst *rqstp, __be32 *p, +static int nfs3svc_encode_getaclres(struct svc_rqst *rqstp, u32 *p, struct nfsd3_getaclres *resp) { struct dentry *dentry = resp->fh.fh_dentry; @@ -208,7 +208,7 @@ static int nfs3svc_encode_getaclres(struct svc_rqst *rqstp, __be32 *p, } /* SETACL */ -static int nfs3svc_encode_setaclres(struct svc_rqst *rqstp, __be32 *p, +static int nfs3svc_encode_setaclres(struct svc_rqst *rqstp, u32 *p, struct nfsd3_attrstat *resp) { p = nfs3svc_encode_post_op_attr(rqstp, p, &resp->fh); @@ -219,7 +219,7 @@ static int nfs3svc_encode_setaclres(struct svc_rqst *rqstp, __be32 *p, /* * XDR release functions */ -static int nfs3svc_release_getacl(struct svc_rqst *rqstp, __be32 *p, +static int nfs3svc_release_getacl(struct svc_rqst *rqstp, u32 *p, struct nfsd3_getaclres *resp) { fh_put(&resp->fh); diff --git a/trunk/fs/nfsd/nfs3proc.c b/trunk/fs/nfsd/nfs3proc.c index 7f5bad0393b1..a5ebc7dbb384 100644 --- a/trunk/fs/nfsd/nfs3proc.c +++ b/trunk/fs/nfsd/nfs3proc.c @@ -43,7 +43,7 @@ static int nfs3_ftypes[] = { /* * NULL call. */ -static __be32 +static int nfsd3_proc_null(struct svc_rqst *rqstp, void *argp, void *resp) { return nfs_ok; @@ -52,12 +52,11 @@ nfsd3_proc_null(struct svc_rqst *rqstp, void *argp, void *resp) /* * Get a file's attributes */ -static __be32 +static int nfsd3_proc_getattr(struct svc_rqst *rqstp, struct nfsd_fhandle *argp, struct nfsd3_attrstat *resp) { - int err; - __be32 nfserr; + int err, nfserr; dprintk("nfsd: GETATTR(3) %s\n", SVCFH_fmt(&argp->fh)); @@ -77,11 +76,11 @@ nfsd3_proc_getattr(struct svc_rqst *rqstp, struct nfsd_fhandle *argp, /* * Set a file's attributes */ -static __be32 +static int nfsd3_proc_setattr(struct svc_rqst *rqstp, struct nfsd3_sattrargs *argp, struct nfsd3_attrstat *resp) { - __be32 nfserr; + int nfserr; dprintk("nfsd: SETATTR(3) %s\n", SVCFH_fmt(&argp->fh)); @@ -95,11 +94,11 @@ nfsd3_proc_setattr(struct svc_rqst *rqstp, struct nfsd3_sattrargs *argp, /* * Look up a path name component */ -static __be32 +static int nfsd3_proc_lookup(struct svc_rqst *rqstp, struct nfsd3_diropargs *argp, struct nfsd3_diropres *resp) { - __be32 nfserr; + int nfserr; dprintk("nfsd: LOOKUP(3) %s %.*s\n", SVCFH_fmt(&argp->fh), @@ -119,11 +118,11 @@ nfsd3_proc_lookup(struct svc_rqst *rqstp, struct nfsd3_diropargs *argp, /* * Check file access */ -static __be32 +static int nfsd3_proc_access(struct svc_rqst *rqstp, struct nfsd3_accessargs *argp, struct nfsd3_accessres *resp) { - __be32 nfserr; + int nfserr; dprintk("nfsd: ACCESS(3) %s 0x%x\n", SVCFH_fmt(&argp->fh), @@ -138,11 +137,11 @@ nfsd3_proc_access(struct svc_rqst *rqstp, struct nfsd3_accessargs *argp, /* * Read a symlink. */ -static __be32 +static int nfsd3_proc_readlink(struct svc_rqst *rqstp, struct nfsd3_readlinkargs *argp, struct nfsd3_readlinkres *resp) { - __be32 nfserr; + int nfserr; dprintk("nfsd: READLINK(3) %s\n", SVCFH_fmt(&argp->fh)); @@ -156,11 +155,11 @@ nfsd3_proc_readlink(struct svc_rqst *rqstp, struct nfsd3_readlinkargs *argp, /* * Read a portion of a file. */ -static __be32 +static int nfsd3_proc_read(struct svc_rqst *rqstp, struct nfsd3_readargs *argp, struct nfsd3_readres *resp) { - __be32 nfserr; + int nfserr; u32 max_blocksize = svc_max_payload(rqstp); dprintk("nfsd: READ(3) %s %lu bytes at %lu\n", @@ -196,11 +195,11 @@ nfsd3_proc_read(struct svc_rqst *rqstp, struct nfsd3_readargs *argp, /* * Write data to a file */ -static __be32 +static int nfsd3_proc_write(struct svc_rqst *rqstp, struct nfsd3_writeargs *argp, struct nfsd3_writeres *resp) { - __be32 nfserr; + int nfserr; dprintk("nfsd: WRITE(3) %s %d bytes at %ld%s\n", SVCFH_fmt(&argp->fh), @@ -224,13 +223,13 @@ nfsd3_proc_write(struct svc_rqst *rqstp, struct nfsd3_writeargs *argp, * At least in theory; we'll see how it fares in practice when the * first reports about SunOS compatibility problems start to pour in... */ -static __be32 +static int nfsd3_proc_create(struct svc_rqst *rqstp, struct nfsd3_createargs *argp, struct nfsd3_diropres *resp) { svc_fh *dirfhp, *newfhp = NULL; struct iattr *attr; - __be32 nfserr; + u32 nfserr; dprintk("nfsd: CREATE(3) %s %.*s\n", SVCFH_fmt(&argp->fh), @@ -258,7 +257,7 @@ nfsd3_proc_create(struct svc_rqst *rqstp, struct nfsd3_createargs *argp, /* Now create the file and set attributes */ nfserr = nfsd_create_v3(rqstp, dirfhp, argp->name, argp->len, attr, newfhp, - argp->createmode, argp->verf, NULL, NULL); + argp->createmode, argp->verf, NULL); RETURN_STATUS(nfserr); } @@ -266,11 +265,11 @@ nfsd3_proc_create(struct svc_rqst *rqstp, struct nfsd3_createargs *argp, /* * Make directory. This operation is not idempotent. */ -static __be32 +static int nfsd3_proc_mkdir(struct svc_rqst *rqstp, struct nfsd3_createargs *argp, struct nfsd3_diropres *resp) { - __be32 nfserr; + int nfserr; dprintk("nfsd: MKDIR(3) %s %.*s\n", SVCFH_fmt(&argp->fh), @@ -286,11 +285,11 @@ nfsd3_proc_mkdir(struct svc_rqst *rqstp, struct nfsd3_createargs *argp, RETURN_STATUS(nfserr); } -static __be32 +static int nfsd3_proc_symlink(struct svc_rqst *rqstp, struct nfsd3_symlinkargs *argp, struct nfsd3_diropres *resp) { - __be32 nfserr; + int nfserr; dprintk("nfsd: SYMLINK(3) %s %.*s -> %.*s\n", SVCFH_fmt(&argp->ffh), @@ -308,12 +307,11 @@ nfsd3_proc_symlink(struct svc_rqst *rqstp, struct nfsd3_symlinkargs *argp, /* * Make socket/fifo/device. */ -static __be32 +static int nfsd3_proc_mknod(struct svc_rqst *rqstp, struct nfsd3_mknodargs *argp, struct nfsd3_diropres *resp) { - __be32 nfserr; - int type; + int nfserr, type; dev_t rdev = 0; dprintk("nfsd: MKNOD(3) %s %.*s\n", @@ -345,11 +343,11 @@ nfsd3_proc_mknod(struct svc_rqst *rqstp, struct nfsd3_mknodargs *argp, /* * Remove file/fifo/socket etc. */ -static __be32 +static int nfsd3_proc_remove(struct svc_rqst *rqstp, struct nfsd3_diropargs *argp, struct nfsd3_attrstat *resp) { - __be32 nfserr; + int nfserr; dprintk("nfsd: REMOVE(3) %s %.*s\n", SVCFH_fmt(&argp->fh), @@ -365,11 +363,11 @@ nfsd3_proc_remove(struct svc_rqst *rqstp, struct nfsd3_diropargs *argp, /* * Remove a directory */ -static __be32 +static int nfsd3_proc_rmdir(struct svc_rqst *rqstp, struct nfsd3_diropargs *argp, struct nfsd3_attrstat *resp) { - __be32 nfserr; + int nfserr; dprintk("nfsd: RMDIR(3) %s %.*s\n", SVCFH_fmt(&argp->fh), @@ -381,11 +379,11 @@ nfsd3_proc_rmdir(struct svc_rqst *rqstp, struct nfsd3_diropargs *argp, RETURN_STATUS(nfserr); } -static __be32 +static int nfsd3_proc_rename(struct svc_rqst *rqstp, struct nfsd3_renameargs *argp, struct nfsd3_renameres *resp) { - __be32 nfserr; + int nfserr; dprintk("nfsd: RENAME(3) %s %.*s ->\n", SVCFH_fmt(&argp->ffh), @@ -403,11 +401,11 @@ nfsd3_proc_rename(struct svc_rqst *rqstp, struct nfsd3_renameargs *argp, RETURN_STATUS(nfserr); } -static __be32 +static int nfsd3_proc_link(struct svc_rqst *rqstp, struct nfsd3_linkargs *argp, struct nfsd3_linkres *resp) { - __be32 nfserr; + int nfserr; dprintk("nfsd: LINK(3) %s ->\n", SVCFH_fmt(&argp->ffh)); @@ -426,12 +424,11 @@ nfsd3_proc_link(struct svc_rqst *rqstp, struct nfsd3_linkargs *argp, /* * Read a portion of a directory. */ -static __be32 +static int nfsd3_proc_readdir(struct svc_rqst *rqstp, struct nfsd3_readdirargs *argp, struct nfsd3_readdirres *resp) { - __be32 nfserr; - int count; + int nfserr, count; dprintk("nfsd: READDIR(3) %s %d bytes at %d\n", SVCFH_fmt(&argp->fh), @@ -462,12 +459,11 @@ nfsd3_proc_readdir(struct svc_rqst *rqstp, struct nfsd3_readdirargs *argp, * Read a portion of a directory, including file handles and attrs. * For now, we choose to ignore the dircount parameter. */ -static __be32 +static int nfsd3_proc_readdirplus(struct svc_rqst *rqstp, struct nfsd3_readdirargs *argp, struct nfsd3_readdirres *resp) { - __be32 nfserr; - int count = 0; + int nfserr, count = 0; loff_t offset; int i; caddr_t page_addr = NULL; @@ -521,11 +517,11 @@ nfsd3_proc_readdirplus(struct svc_rqst *rqstp, struct nfsd3_readdirargs *argp, /* * Get file system stats */ -static __be32 +static int nfsd3_proc_fsstat(struct svc_rqst * rqstp, struct nfsd_fhandle *argp, struct nfsd3_fsstatres *resp) { - __be32 nfserr; + int nfserr; dprintk("nfsd: FSSTAT(3) %s\n", SVCFH_fmt(&argp->fh)); @@ -538,11 +534,11 @@ nfsd3_proc_fsstat(struct svc_rqst * rqstp, struct nfsd_fhandle *argp, /* * Get file system info */ -static __be32 +static int nfsd3_proc_fsinfo(struct svc_rqst * rqstp, struct nfsd_fhandle *argp, struct nfsd3_fsinfores *resp) { - __be32 nfserr; + int nfserr; u32 max_blocksize = svc_max_payload(rqstp); dprintk("nfsd: FSINFO(3) %s\n", @@ -580,11 +576,11 @@ nfsd3_proc_fsinfo(struct svc_rqst * rqstp, struct nfsd_fhandle *argp, /* * Get pathconf info for the specified file */ -static __be32 +static int nfsd3_proc_pathconf(struct svc_rqst * rqstp, struct nfsd_fhandle *argp, struct nfsd3_pathconfres *resp) { - __be32 nfserr; + int nfserr; dprintk("nfsd: PATHCONF(3) %s\n", SVCFH_fmt(&argp->fh)); @@ -623,11 +619,11 @@ nfsd3_proc_pathconf(struct svc_rqst * rqstp, struct nfsd_fhandle *argp, /* * Commit a file (range) to stable storage. */ -static __be32 +static int nfsd3_proc_commit(struct svc_rqst * rqstp, struct nfsd3_commitargs *argp, struct nfsd3_commitres *resp) { - __be32 nfserr; + int nfserr; dprintk("nfsd: COMMIT(3) %s %u@%Lu\n", SVCFH_fmt(&argp->fh), diff --git a/trunk/fs/nfsd/nfs3xdr.c b/trunk/fs/nfsd/nfs3xdr.c index b4baca3053c3..247d518248bf 100644 --- a/trunk/fs/nfsd/nfs3xdr.c +++ b/trunk/fs/nfsd/nfs3xdr.c @@ -42,23 +42,23 @@ static u32 nfs3_ftypes[] = { /* * XDR functions for basic NFS types */ -static inline __be32 * -encode_time3(__be32 *p, struct timespec *time) +static inline u32 * +encode_time3(u32 *p, struct timespec *time) { *p++ = htonl((u32) time->tv_sec); *p++ = htonl(time->tv_nsec); return p; } -static inline __be32 * -decode_time3(__be32 *p, struct timespec *time) +static inline u32 * +decode_time3(u32 *p, struct timespec *time) { time->tv_sec = ntohl(*p++); time->tv_nsec = ntohl(*p++); return p; } -static inline __be32 * -decode_fh(__be32 *p, struct svc_fh *fhp) +static inline u32 * +decode_fh(u32 *p, struct svc_fh *fhp) { unsigned int size; fh_init(fhp, NFS3_FHSIZE); @@ -72,13 +72,13 @@ decode_fh(__be32 *p, struct svc_fh *fhp) } /* Helper function for NFSv3 ACL code */ -__be32 *nfs3svc_decode_fh(__be32 *p, struct svc_fh *fhp) +u32 *nfs3svc_decode_fh(u32 *p, struct svc_fh *fhp) { return decode_fh(p, fhp); } -static inline __be32 * -encode_fh(__be32 *p, struct svc_fh *fhp) +static inline u32 * +encode_fh(u32 *p, struct svc_fh *fhp) { unsigned int size = fhp->fh_handle.fh_size; *p++ = htonl(size); @@ -91,8 +91,8 @@ 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 inline __be32 * -decode_filename(__be32 *p, char **namp, int *lenp) +static inline u32 * +decode_filename(u32 *p, char **namp, int *lenp) { char *name; int i; @@ -107,8 +107,8 @@ decode_filename(__be32 *p, char **namp, int *lenp) return p; } -static inline __be32 * -decode_sattr3(__be32 *p, struct iattr *iap) +static inline u32 * +decode_sattr3(u32 *p, struct iattr *iap) { u32 tmp; @@ -153,8 +153,8 @@ decode_sattr3(__be32 *p, struct iattr *iap) return p; } -static inline __be32 * -encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp, +static inline u32 * +encode_fattr3(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp, struct kstat *stat) { struct dentry *dentry = fhp->fh_dentry; @@ -186,8 +186,8 @@ encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp, return p; } -static inline __be32 * -encode_saved_post_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp) +static inline u32 * +encode_saved_post_attr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp) { struct inode *inode = fhp->fh_dentry->d_inode; @@ -224,8 +224,8 @@ encode_saved_post_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp) * The inode may be NULL if the call failed because of a stale file * handle. In this case, no attributes are returned. */ -static __be32 * -encode_post_op_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp) +static u32 * +encode_post_op_attr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp) { struct dentry *dentry = fhp->fh_dentry; if (dentry && dentry->d_inode != NULL) { @@ -243,8 +243,8 @@ encode_post_op_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp) } /* Helper for NFSv3 ACLs */ -__be32 * -nfs3svc_encode_post_op_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp) +u32 * +nfs3svc_encode_post_op_attr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp) { return encode_post_op_attr(rqstp, p, fhp); } @@ -252,8 +252,8 @@ nfs3svc_encode_post_op_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fh /* * Enocde weak cache consistency data */ -static __be32 * -encode_wcc_data(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp) +static u32 * +encode_wcc_data(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp) { struct dentry *dentry = fhp->fh_dentry; @@ -278,7 +278,7 @@ encode_wcc_data(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp) * XDR decode functions */ int -nfs3svc_decode_fhandle(struct svc_rqst *rqstp, __be32 *p, struct nfsd_fhandle *args) +nfs3svc_decode_fhandle(struct svc_rqst *rqstp, u32 *p, struct nfsd_fhandle *args) { if (!(p = decode_fh(p, &args->fh))) return 0; @@ -286,7 +286,7 @@ nfs3svc_decode_fhandle(struct svc_rqst *rqstp, __be32 *p, struct nfsd_fhandle *a } int -nfs3svc_decode_sattrargs(struct svc_rqst *rqstp, __be32 *p, +nfs3svc_decode_sattrargs(struct svc_rqst *rqstp, u32 *p, struct nfsd3_sattrargs *args) { if (!(p = decode_fh(p, &args->fh)) @@ -303,7 +303,7 @@ nfs3svc_decode_sattrargs(struct svc_rqst *rqstp, __be32 *p, } int -nfs3svc_decode_diropargs(struct svc_rqst *rqstp, __be32 *p, +nfs3svc_decode_diropargs(struct svc_rqst *rqstp, u32 *p, struct nfsd3_diropargs *args) { if (!(p = decode_fh(p, &args->fh)) @@ -314,7 +314,7 @@ nfs3svc_decode_diropargs(struct svc_rqst *rqstp, __be32 *p, } int -nfs3svc_decode_accessargs(struct svc_rqst *rqstp, __be32 *p, +nfs3svc_decode_accessargs(struct svc_rqst *rqstp, u32 *p, struct nfsd3_accessargs *args) { if (!(p = decode_fh(p, &args->fh))) @@ -325,7 +325,7 @@ nfs3svc_decode_accessargs(struct svc_rqst *rqstp, __be32 *p, } int -nfs3svc_decode_readargs(struct svc_rqst *rqstp, __be32 *p, +nfs3svc_decode_readargs(struct svc_rqst *rqstp, u32 *p, struct nfsd3_readargs *args) { unsigned int len; @@ -355,7 +355,7 @@ nfs3svc_decode_readargs(struct svc_rqst *rqstp, __be32 *p, } int -nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p, +nfs3svc_decode_writeargs(struct svc_rqst *rqstp, u32 *p, struct nfsd3_writeargs *args) { unsigned int len, v, hdr; @@ -393,7 +393,7 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p, } int -nfs3svc_decode_createargs(struct svc_rqst *rqstp, __be32 *p, +nfs3svc_decode_createargs(struct svc_rqst *rqstp, u32 *p, struct nfsd3_createargs *args) { if (!(p = decode_fh(p, &args->fh)) @@ -417,7 +417,7 @@ nfs3svc_decode_createargs(struct svc_rqst *rqstp, __be32 *p, return xdr_argsize_check(rqstp, p); } int -nfs3svc_decode_mkdirargs(struct svc_rqst *rqstp, __be32 *p, +nfs3svc_decode_mkdirargs(struct svc_rqst *rqstp, u32 *p, struct nfsd3_createargs *args) { if (!(p = decode_fh(p, &args->fh)) @@ -429,7 +429,7 @@ nfs3svc_decode_mkdirargs(struct svc_rqst *rqstp, __be32 *p, } int -nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p, +nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, u32 *p, struct nfsd3_symlinkargs *args) { unsigned int len; @@ -481,7 +481,7 @@ nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p, } int -nfs3svc_decode_mknodargs(struct svc_rqst *rqstp, __be32 *p, +nfs3svc_decode_mknodargs(struct svc_rqst *rqstp, u32 *p, struct nfsd3_mknodargs *args) { if (!(p = decode_fh(p, &args->fh)) @@ -505,7 +505,7 @@ nfs3svc_decode_mknodargs(struct svc_rqst *rqstp, __be32 *p, } int -nfs3svc_decode_renameargs(struct svc_rqst *rqstp, __be32 *p, +nfs3svc_decode_renameargs(struct svc_rqst *rqstp, u32 *p, struct nfsd3_renameargs *args) { if (!(p = decode_fh(p, &args->ffh)) @@ -518,7 +518,7 @@ nfs3svc_decode_renameargs(struct svc_rqst *rqstp, __be32 *p, } int -nfs3svc_decode_readlinkargs(struct svc_rqst *rqstp, __be32 *p, +nfs3svc_decode_readlinkargs(struct svc_rqst *rqstp, u32 *p, struct nfsd3_readlinkargs *args) { if (!(p = decode_fh(p, &args->fh))) @@ -530,7 +530,7 @@ nfs3svc_decode_readlinkargs(struct svc_rqst *rqstp, __be32 *p, } int -nfs3svc_decode_linkargs(struct svc_rqst *rqstp, __be32 *p, +nfs3svc_decode_linkargs(struct svc_rqst *rqstp, u32 *p, struct nfsd3_linkargs *args) { if (!(p = decode_fh(p, &args->ffh)) @@ -542,7 +542,7 @@ nfs3svc_decode_linkargs(struct svc_rqst *rqstp, __be32 *p, } int -nfs3svc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p, +nfs3svc_decode_readdirargs(struct svc_rqst *rqstp, u32 *p, struct nfsd3_readdirargs *args) { if (!(p = decode_fh(p, &args->fh))) @@ -562,7 +562,7 @@ nfs3svc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p, } int -nfs3svc_decode_readdirplusargs(struct svc_rqst *rqstp, __be32 *p, +nfs3svc_decode_readdirplusargs(struct svc_rqst *rqstp, u32 *p, struct nfsd3_readdirargs *args) { int len, pn; @@ -590,7 +590,7 @@ nfs3svc_decode_readdirplusargs(struct svc_rqst *rqstp, __be32 *p, } int -nfs3svc_decode_commitargs(struct svc_rqst *rqstp, __be32 *p, +nfs3svc_decode_commitargs(struct svc_rqst *rqstp, u32 *p, struct nfsd3_commitargs *args) { if (!(p = decode_fh(p, &args->fh))) @@ -609,14 +609,14 @@ nfs3svc_decode_commitargs(struct svc_rqst *rqstp, __be32 *p, * will work properly. */ int -nfs3svc_encode_voidres(struct svc_rqst *rqstp, __be32 *p, void *dummy) +nfs3svc_encode_voidres(struct svc_rqst *rqstp, u32 *p, void *dummy) { return xdr_ressize_check(rqstp, p); } /* GETATTR */ int -nfs3svc_encode_attrstat(struct svc_rqst *rqstp, __be32 *p, +nfs3svc_encode_attrstat(struct svc_rqst *rqstp, u32 *p, struct nfsd3_attrstat *resp) { if (resp->status == 0) @@ -626,7 +626,7 @@ nfs3svc_encode_attrstat(struct svc_rqst *rqstp, __be32 *p, /* SETATTR, REMOVE, RMDIR */ int -nfs3svc_encode_wccstat(struct svc_rqst *rqstp, __be32 *p, +nfs3svc_encode_wccstat(struct svc_rqst *rqstp, u32 *p, struct nfsd3_attrstat *resp) { p = encode_wcc_data(rqstp, p, &resp->fh); @@ -635,7 +635,7 @@ nfs3svc_encode_wccstat(struct svc_rqst *rqstp, __be32 *p, /* LOOKUP */ int -nfs3svc_encode_diropres(struct svc_rqst *rqstp, __be32 *p, +nfs3svc_encode_diropres(struct svc_rqst *rqstp, u32 *p, struct nfsd3_diropres *resp) { if (resp->status == 0) { @@ -648,7 +648,7 @@ nfs3svc_encode_diropres(struct svc_rqst *rqstp, __be32 *p, /* ACCESS */ int -nfs3svc_encode_accessres(struct svc_rqst *rqstp, __be32 *p, +nfs3svc_encode_accessres(struct svc_rqst *rqstp, u32 *p, struct nfsd3_accessres *resp) { p = encode_post_op_attr(rqstp, p, &resp->fh); @@ -659,7 +659,7 @@ nfs3svc_encode_accessres(struct svc_rqst *rqstp, __be32 *p, /* READLINK */ int -nfs3svc_encode_readlinkres(struct svc_rqst *rqstp, __be32 *p, +nfs3svc_encode_readlinkres(struct svc_rqst *rqstp, u32 *p, struct nfsd3_readlinkres *resp) { p = encode_post_op_attr(rqstp, p, &resp->fh); @@ -680,7 +680,7 @@ nfs3svc_encode_readlinkres(struct svc_rqst *rqstp, __be32 *p, /* READ */ int -nfs3svc_encode_readres(struct svc_rqst *rqstp, __be32 *p, +nfs3svc_encode_readres(struct svc_rqst *rqstp, u32 *p, struct nfsd3_readres *resp) { p = encode_post_op_attr(rqstp, p, &resp->fh); @@ -704,7 +704,7 @@ nfs3svc_encode_readres(struct svc_rqst *rqstp, __be32 *p, /* WRITE */ int -nfs3svc_encode_writeres(struct svc_rqst *rqstp, __be32 *p, +nfs3svc_encode_writeres(struct svc_rqst *rqstp, u32 *p, struct nfsd3_writeres *resp) { p = encode_wcc_data(rqstp, p, &resp->fh); @@ -719,7 +719,7 @@ nfs3svc_encode_writeres(struct svc_rqst *rqstp, __be32 *p, /* CREATE, MKDIR, SYMLINK, MKNOD */ int -nfs3svc_encode_createres(struct svc_rqst *rqstp, __be32 *p, +nfs3svc_encode_createres(struct svc_rqst *rqstp, u32 *p, struct nfsd3_diropres *resp) { if (resp->status == 0) { @@ -733,7 +733,7 @@ nfs3svc_encode_createres(struct svc_rqst *rqstp, __be32 *p, /* RENAME */ int -nfs3svc_encode_renameres(struct svc_rqst *rqstp, __be32 *p, +nfs3svc_encode_renameres(struct svc_rqst *rqstp, u32 *p, struct nfsd3_renameres *resp) { p = encode_wcc_data(rqstp, p, &resp->ffh); @@ -743,7 +743,7 @@ nfs3svc_encode_renameres(struct svc_rqst *rqstp, __be32 *p, /* LINK */ int -nfs3svc_encode_linkres(struct svc_rqst *rqstp, __be32 *p, +nfs3svc_encode_linkres(struct svc_rqst *rqstp, u32 *p, struct nfsd3_linkres *resp) { p = encode_post_op_attr(rqstp, p, &resp->fh); @@ -753,7 +753,7 @@ nfs3svc_encode_linkres(struct svc_rqst *rqstp, __be32 *p, /* READDIR */ int -nfs3svc_encode_readdirres(struct svc_rqst *rqstp, __be32 *p, +nfs3svc_encode_readdirres(struct svc_rqst *rqstp, u32 *p, struct nfsd3_readdirres *resp) { p = encode_post_op_attr(rqstp, p, &resp->fh); @@ -776,8 +776,8 @@ nfs3svc_encode_readdirres(struct svc_rqst *rqstp, __be32 *p, return xdr_ressize_check(rqstp, p); } -static inline __be32 * -encode_entry_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name, +static inline u32 * +encode_entry_baggage(struct nfsd3_readdirres *cd, u32 *p, const char *name, int namlen, ino_t ino) { *p++ = xdr_one; /* mark entry present */ @@ -790,8 +790,8 @@ encode_entry_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name, return p; } -static inline __be32 * -encode_entryplus_baggage(struct nfsd3_readdirres *cd, __be32 *p, +static inline u32 * +encode_entryplus_baggage(struct nfsd3_readdirres *cd, u32 *p, struct svc_fh *fhp) { p = encode_post_op_attr(cd->rqstp, p, fhp); @@ -853,7 +853,7 @@ encode_entry(struct readdir_cd *ccd, const char *name, { struct nfsd3_readdirres *cd = container_of(ccd, struct nfsd3_readdirres, common); - __be32 *p = cd->buffer; + u32 *p = cd->buffer; caddr_t curr_page_addr = NULL; int pn; /* current page number */ int slen; /* string (name) length */ @@ -919,7 +919,7 @@ encode_entry(struct readdir_cd *ccd, const char *name, } else if (cd->rqstp->rq_respages[pn+1] != NULL) { /* temporarily encode entry into next page, then move back to * current and next page in rq_respages[] */ - __be32 *p1, *tmp; + u32 *p1, *tmp; int len1, len2; /* grab next page for temporary storage of entry */ @@ -1009,7 +1009,7 @@ nfs3svc_encode_entry_plus(struct readdir_cd *cd, const char *name, /* FSSTAT */ int -nfs3svc_encode_fsstatres(struct svc_rqst *rqstp, __be32 *p, +nfs3svc_encode_fsstatres(struct svc_rqst *rqstp, u32 *p, struct nfsd3_fsstatres *resp) { struct kstatfs *s = &resp->stats; @@ -1031,7 +1031,7 @@ nfs3svc_encode_fsstatres(struct svc_rqst *rqstp, __be32 *p, /* FSINFO */ int -nfs3svc_encode_fsinfores(struct svc_rqst *rqstp, __be32 *p, +nfs3svc_encode_fsinfores(struct svc_rqst *rqstp, u32 *p, struct nfsd3_fsinfores *resp) { *p++ = xdr_zero; /* no post_op_attr */ @@ -1055,7 +1055,7 @@ nfs3svc_encode_fsinfores(struct svc_rqst *rqstp, __be32 *p, /* PATHCONF */ int -nfs3svc_encode_pathconfres(struct svc_rqst *rqstp, __be32 *p, +nfs3svc_encode_pathconfres(struct svc_rqst *rqstp, u32 *p, struct nfsd3_pathconfres *resp) { *p++ = xdr_zero; /* no post_op_attr */ @@ -1074,7 +1074,7 @@ nfs3svc_encode_pathconfres(struct svc_rqst *rqstp, __be32 *p, /* COMMIT */ int -nfs3svc_encode_commitres(struct svc_rqst *rqstp, __be32 *p, +nfs3svc_encode_commitres(struct svc_rqst *rqstp, u32 *p, struct nfsd3_commitres *resp) { p = encode_wcc_data(rqstp, p, &resp->fh); @@ -1090,7 +1090,7 @@ nfs3svc_encode_commitres(struct svc_rqst *rqstp, __be32 *p, * XDR release functions */ int -nfs3svc_release_fhandle(struct svc_rqst *rqstp, __be32 *p, +nfs3svc_release_fhandle(struct svc_rqst *rqstp, u32 *p, struct nfsd3_attrstat *resp) { fh_put(&resp->fh); @@ -1098,7 +1098,7 @@ nfs3svc_release_fhandle(struct svc_rqst *rqstp, __be32 *p, } int -nfs3svc_release_fhandle2(struct svc_rqst *rqstp, __be32 *p, +nfs3svc_release_fhandle2(struct svc_rqst *rqstp, u32 *p, struct nfsd3_fhandle_pair *resp) { fh_put(&resp->fh1); diff --git a/trunk/fs/nfsd/nfs4callback.c b/trunk/fs/nfsd/nfs4callback.c index f57655a7a2b6..f6ca9fb3fc63 100644 --- a/trunk/fs/nfsd/nfs4callback.c +++ b/trunk/fs/nfsd/nfs4callback.c @@ -85,8 +85,8 @@ enum nfs_cb_opnum4 { /* * Generic encode routines from fs/nfs/nfs4xdr.c */ -static inline __be32 * -xdr_writemem(__be32 *p, const void *ptr, int nbytes) +static inline u32 * +xdr_writemem(u32 *p, const void *ptr, int nbytes) { int tmp = XDR_QUADLEN(nbytes); if (!tmp) @@ -205,7 +205,7 @@ nfs_cb_stat_to_errno(int stat) static int encode_cb_compound_hdr(struct xdr_stream *xdr, struct nfs4_cb_compound_hdr *hdr) { - __be32 * p; + u32 * p; RESERVE_SPACE(16); WRITE32(0); /* tag length is always 0 */ @@ -218,7 +218,7 @@ encode_cb_compound_hdr(struct xdr_stream *xdr, struct nfs4_cb_compound_hdr *hdr) static int encode_cb_recall(struct xdr_stream *xdr, struct nfs4_cb_recall *cb_rec) { - __be32 *p; + u32 *p; int len = cb_rec->cbr_fhlen; RESERVE_SPACE(12+sizeof(cb_rec->cbr_stateid) + len); @@ -231,7 +231,7 @@ encode_cb_recall(struct xdr_stream *xdr, struct nfs4_cb_recall *cb_rec) } static int -nfs4_xdr_enc_cb_null(struct rpc_rqst *req, __be32 *p) +nfs4_xdr_enc_cb_null(struct rpc_rqst *req, u32 *p) { struct xdr_stream xdrs, *xdr = &xdrs; @@ -241,7 +241,7 @@ nfs4_xdr_enc_cb_null(struct rpc_rqst *req, __be32 *p) } static int -nfs4_xdr_enc_cb_recall(struct rpc_rqst *req, __be32 *p, struct nfs4_cb_recall *args) +nfs4_xdr_enc_cb_recall(struct rpc_rqst *req, u32 *p, struct nfs4_cb_recall *args) { struct xdr_stream xdr; struct nfs4_cb_compound_hdr hdr = { @@ -257,7 +257,7 @@ nfs4_xdr_enc_cb_recall(struct rpc_rqst *req, __be32 *p, struct nfs4_cb_recall *a static int decode_cb_compound_hdr(struct xdr_stream *xdr, struct nfs4_cb_compound_hdr *hdr){ - __be32 *p; + u32 *p; READ_BUF(8); READ32(hdr->status); @@ -272,7 +272,7 @@ decode_cb_compound_hdr(struct xdr_stream *xdr, struct nfs4_cb_compound_hdr *hdr) static int decode_cb_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected) { - __be32 *p; + u32 *p; u32 op; int32_t nfserr; @@ -291,13 +291,13 @@ decode_cb_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected) } static int -nfs4_xdr_dec_cb_null(struct rpc_rqst *req, __be32 *p) +nfs4_xdr_dec_cb_null(struct rpc_rqst *req, u32 *p) { return 0; } static int -nfs4_xdr_dec_cb_recall(struct rpc_rqst *rqstp, __be32 *p) +nfs4_xdr_dec_cb_recall(struct rpc_rqst *rqstp, u32 *p) { struct xdr_stream xdr; struct nfs4_cb_compound_hdr hdr; @@ -421,7 +421,7 @@ nfsd4_probe_callback(struct nfs4_client *clp) /* Create RPC client */ cb->cb_client = rpc_create(&args); - if (IS_ERR(cb->cb_client)) { + if (!cb->cb_client) { dprintk("NFSD: couldn't create callback client\n"); goto out_err; } @@ -448,10 +448,10 @@ nfsd4_probe_callback(struct nfs4_client *clp) out_rpciod: atomic_dec(&clp->cl_count); rpciod_down(); + cb->cb_client = NULL; out_clnt: rpc_shutdown_client(cb->cb_client); out_err: - cb->cb_client = NULL; dprintk("NFSD: warning: no callback path to client %.*s\n", (int)clp->cl_name.len, clp->cl_name.data); } @@ -461,7 +461,7 @@ nfs4_cb_null(struct rpc_task *task, void *dummy) { struct nfs4_client *clp = (struct nfs4_client *)task->tk_msg.rpc_argp; struct nfs4_callback *cb = &clp->cl_callback; - __be32 addr = htonl(cb->cb_addr); + u32 addr = htonl(cb->cb_addr); dprintk("NFSD: nfs4_cb_null task->tk_status %d\n", task->tk_status); diff --git a/trunk/fs/nfsd/nfs4proc.c b/trunk/fs/nfsd/nfs4proc.c index 50bc94243ca1..8333db12caca 100644 --- a/trunk/fs/nfsd/nfs4proc.c +++ b/trunk/fs/nfsd/nfs4proc.c @@ -67,33 +67,32 @@ fh_dup2(struct svc_fh *dst, struct svc_fh *src) *dst = *src; } -static __be32 -do_open_permission(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open, int accmode) +static int +do_open_permission(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open) { - __be32 status; + int accmode, status; if (open->op_truncate && !(open->op_share_access & NFS4_SHARE_ACCESS_WRITE)) return nfserr_inval; + accmode = MAY_NOP; if (open->op_share_access & NFS4_SHARE_ACCESS_READ) - accmode |= MAY_READ; - if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE) + accmode = MAY_READ; + if (open->op_share_deny & NFS4_SHARE_ACCESS_WRITE) accmode |= (MAY_WRITE | MAY_TRUNC); - if (open->op_share_deny & NFS4_SHARE_DENY_WRITE) - accmode |= MAY_WRITE; + accmode |= MAY_OWNER_OVERRIDE; status = fh_verify(rqstp, current_fh, S_IFREG, accmode); return status; } -static __be32 +static int do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open) { struct svc_fh resfh; - __be32 status; - int created = 0; + int status; fh_init(&resfh, NFS4_FHSIZE); open->op_truncate = 0; @@ -106,35 +105,36 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o status = nfsd_create_v3(rqstp, current_fh, open->op_fname.data, open->op_fname.len, &open->op_iattr, &resfh, open->op_createmode, - (u32 *)open->op_verf.data, &open->op_truncate, &created); - } else { + (u32 *)open->op_verf.data, &open->op_truncate); + } + else { status = nfsd_lookup(rqstp, current_fh, open->op_fname.data, open->op_fname.len, &resfh); fh_unlock(current_fh); } - if (status) - goto out; - set_change_info(&open->op_cinfo, current_fh); + if (!status) { + set_change_info(&open->op_cinfo, current_fh); - /* set reply cache */ - fh_dup2(current_fh, &resfh); - open->op_stateowner->so_replay.rp_openfh_len = resfh.fh_handle.fh_size; - memcpy(open->op_stateowner->so_replay.rp_openfh, - &resfh.fh_handle.fh_base, resfh.fh_handle.fh_size); + /* set reply cache */ + fh_dup2(current_fh, &resfh); + open->op_stateowner->so_replay.rp_openfh_len = + resfh.fh_handle.fh_size; + memcpy(open->op_stateowner->so_replay.rp_openfh, + &resfh.fh_handle.fh_base, + resfh.fh_handle.fh_size); - if (!created) - status = do_open_permission(rqstp, current_fh, open, MAY_NOP); + status = do_open_permission(rqstp, current_fh, open); + } -out: fh_put(&resfh); return status; } -static __be32 +static int do_open_fhandle(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open) { - __be32 status; + int status; /* Only reclaims from previously confirmed clients are valid */ if ((status = nfs4_check_open_reclaim(&open->op_clientid))) @@ -155,16 +155,16 @@ do_open_fhandle(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_ open->op_truncate = (open->op_iattr.ia_valid & ATTR_SIZE) && (open->op_iattr.ia_size == 0); - status = do_open_permission(rqstp, current_fh, open, MAY_OWNER_OVERRIDE); + status = do_open_permission(rqstp, current_fh, open); return status; } -static inline __be32 +static inline int nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open, struct nfs4_stateowner **replay_owner) { - __be32 status; + int status; dprintk("NFSD: nfsd4_open filename %.*s op_stateowner %p\n", (int)open->op_fname.len, open->op_fname.data, open->op_stateowner); @@ -177,7 +177,7 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open /* check seqid for replay. set nfs4_owner */ status = nfsd4_process_open1(open); - if (status == nfserr_replay_me) { + if (status == NFSERR_REPLAY_ME) { struct nfs4_replay *rp = &open->op_stateowner->so_replay; fh_put(current_fh); current_fh->fh_handle.fh_size = rp->rp_openfh_len; @@ -188,7 +188,7 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open dprintk("nfsd4_open: replay failed" " restoring previous filehandle\n"); else - status = nfserr_replay_me; + status = NFSERR_REPLAY_ME; } if (status) goto out; @@ -261,7 +261,7 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open /* * filehandle-manipulating ops. */ -static inline __be32 +static inline int nfsd4_getfh(struct svc_fh *current_fh, struct svc_fh **getfh) { if (!current_fh->fh_dentry) @@ -271,7 +271,7 @@ nfsd4_getfh(struct svc_fh *current_fh, struct svc_fh **getfh) return nfs_ok; } -static inline __be32 +static inline int nfsd4_putfh(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_putfh *putfh) { fh_put(current_fh); @@ -280,10 +280,10 @@ nfsd4_putfh(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_putf return fh_verify(rqstp, current_fh, 0, MAY_NOP); } -static inline __be32 +static inline int nfsd4_putrootfh(struct svc_rqst *rqstp, struct svc_fh *current_fh) { - __be32 status; + int status; fh_put(current_fh); status = exp_pseudoroot(rqstp->rq_client, current_fh, @@ -291,7 +291,7 @@ nfsd4_putrootfh(struct svc_rqst *rqstp, struct svc_fh *current_fh) return status; } -static inline __be32 +static inline int nfsd4_restorefh(struct svc_fh *current_fh, struct svc_fh *save_fh) { if (!save_fh->fh_dentry) @@ -301,7 +301,7 @@ nfsd4_restorefh(struct svc_fh *current_fh, struct svc_fh *save_fh) return nfs_ok; } -static inline __be32 +static inline int nfsd4_savefh(struct svc_fh *current_fh, struct svc_fh *save_fh) { if (!current_fh->fh_dentry) @@ -314,7 +314,7 @@ nfsd4_savefh(struct svc_fh *current_fh, struct svc_fh *save_fh) /* * misc nfsv4 ops */ -static inline __be32 +static inline int nfsd4_access(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_access *access) { if (access->ac_req_access & ~NFS3_ACCESS_FULL) @@ -324,10 +324,10 @@ nfsd4_access(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_acc return nfsd_access(rqstp, current_fh, &access->ac_resp_access, &access->ac_supported); } -static inline __be32 +static inline int nfsd4_commit(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_commit *commit) { - __be32 status; + int status; u32 *p = (u32 *)commit->co_verf.data; *p++ = nfssvc_boot.tv_sec; @@ -339,11 +339,11 @@ nfsd4_commit(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_com return status; } -static __be32 +static int nfsd4_create(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_create *create) { struct svc_fh resfh; - __be32 status; + int status; dev_t rdev; fh_init(&resfh, NFS4_FHSIZE); @@ -423,10 +423,10 @@ nfsd4_create(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_cre return status; } -static inline __be32 +static inline int nfsd4_getattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_getattr *getattr) { - __be32 status; + int status; status = fh_verify(rqstp, current_fh, 0, MAY_NOP); if (status) @@ -442,11 +442,11 @@ nfsd4_getattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_ge return nfs_ok; } -static inline __be32 +static inline int nfsd4_link(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct svc_fh *save_fh, struct nfsd4_link *link) { - __be32 status = nfserr_nofilehandle; + int status = nfserr_nofilehandle; if (!save_fh->fh_dentry) return status; @@ -456,11 +456,11 @@ nfsd4_link(struct svc_rqst *rqstp, struct svc_fh *current_fh, return status; } -static __be32 +static int nfsd4_lookupp(struct svc_rqst *rqstp, struct svc_fh *current_fh) { struct svc_fh tmp_fh; - __be32 ret; + int ret; fh_init(&tmp_fh, NFS4_FHSIZE); if((ret = exp_pseudoroot(rqstp->rq_client, &tmp_fh, @@ -474,16 +474,16 @@ nfsd4_lookupp(struct svc_rqst *rqstp, struct svc_fh *current_fh) return nfsd_lookup(rqstp, current_fh, "..", 2, current_fh); } -static inline __be32 +static inline int nfsd4_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lookup *lookup) { return nfsd_lookup(rqstp, current_fh, lookup->lo_name, lookup->lo_len, current_fh); } -static inline __be32 +static inline int nfsd4_read(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_read *read) { - __be32 status; + int status; /* no need to check permission - this will be done in nfsd_read() */ @@ -508,7 +508,7 @@ nfsd4_read(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_read return status; } -static inline __be32 +static inline int nfsd4_readdir(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_readdir *readdir) { u64 cookie = readdir->rd_cookie; @@ -531,7 +531,7 @@ nfsd4_readdir(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_re return nfs_ok; } -static inline __be32 +static inline int nfsd4_readlink(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_readlink *readlink) { readlink->rl_rqstp = rqstp; @@ -539,10 +539,10 @@ nfsd4_readlink(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_r return nfs_ok; } -static inline __be32 +static inline int nfsd4_remove(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_remove *remove) { - __be32 status; + int status; if (nfs4_in_grace()) return nfserr_grace; @@ -556,11 +556,11 @@ nfsd4_remove(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_rem return status; } -static inline __be32 +static inline int nfsd4_rename(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct svc_fh *save_fh, struct nfsd4_rename *rename) { - __be32 status = nfserr_nofilehandle; + int status = nfserr_nofilehandle; if (!save_fh->fh_dentry) return status; @@ -589,10 +589,10 @@ nfsd4_rename(struct svc_rqst *rqstp, struct svc_fh *current_fh, return status; } -static inline __be32 +static inline int nfsd4_setattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_setattr *setattr) { - __be32 status = nfs_ok; + int status = nfs_ok; if (setattr->sa_iattr.ia_valid & ATTR_SIZE) { nfs4_lock_state(); @@ -614,13 +614,13 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_se return status; } -static inline __be32 +static inline int nfsd4_write(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_write *write) { stateid_t *stateid = &write->wr_stateid; struct file *filp = NULL; u32 *p; - __be32 status = nfs_ok; + int status = nfs_ok; /* no need to check permission - this will be done in nfsd_write() */ @@ -661,12 +661,12 @@ nfsd4_write(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_writ * attributes matched. VERIFY is implemented by mapping NFSERR_SAME * to NFS_OK after the call; NVERIFY by mapping NFSERR_NOT_SAME to NFS_OK. */ -static __be32 +static int nfsd4_verify(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_verify *verify) { - __be32 *buf, *p; + u32 *buf, *p; int count; - __be32 status; + int status; status = fh_verify(rqstp, current_fh, 0, MAY_NOP); if (status) @@ -715,7 +715,7 @@ nfsd4_verify(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_ver /* * NULL call. */ -static __be32 +static int nfsd4_proc_null(struct svc_rqst *rqstp, void *argp, void *resp) { return nfs_ok; @@ -731,7 +731,7 @@ static inline void nfsd4_increment_op_stats(u32 opnum) /* * COMPOUND call. */ -static __be32 +static int nfsd4_proc_compound(struct svc_rqst *rqstp, struct nfsd4_compoundargs *args, struct nfsd4_compoundres *resp) @@ -741,7 +741,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp, struct svc_fh *save_fh = NULL; struct nfs4_stateowner *replay_owner = NULL; int slack_space; /* in words, not bytes! */ - __be32 status; + int status; status = nfserr_resource; current_fh = kmalloc(sizeof(*current_fh), GFP_KERNEL); @@ -937,7 +937,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp, } encode_op: - if (op->status == nfserr_replay_me) { + if (op->status == NFSERR_REPLAY_ME) { op->replay = &replay_owner->so_replay; nfsd4_encode_replay(resp, op); status = op->status = op->replay->rp_status; diff --git a/trunk/fs/nfsd/nfs4recover.c b/trunk/fs/nfsd/nfs4recover.c index 81b8565d3837..1cbd2e4ee122 100644 --- a/trunk/fs/nfsd/nfs4recover.c +++ b/trunk/fs/nfsd/nfs4recover.c @@ -83,13 +83,13 @@ md5_to_hex(char *out, char *md5) *out = '\0'; } -__be32 +int nfs4_make_rec_clidname(char *dname, struct xdr_netobj *clname) { struct xdr_netobj cksum; struct hash_desc desc; struct scatterlist sg[1]; - __be32 status = nfserr_resource; + int status = nfserr_resource; dprintk("NFSD: nfs4_make_rec_clidname for %.*s\n", clname->len, clname->data); @@ -193,7 +193,7 @@ nfsd4_build_dentrylist(void *arg, const char *name, int namlen, struct dentry_list *child; if (name && isdotent(name, namlen)) - return 0; + return nfs_ok; dentry = lookup_one_len(name, parent, namlen); if (IS_ERR(dentry)) return PTR_ERR(dentry); @@ -274,7 +274,7 @@ nfsd4_clear_clid_dir(struct dentry *dir, struct dentry *dentry) * any regular files anyway, just in case the directory was created by * a kernel from the future.... */ nfsd4_list_rec_dir(dentry, nfsd4_remove_clid_file); - mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT); + mutex_lock(&dir->d_inode->i_mutex); status = vfs_rmdir(dir->d_inode, dentry); mutex_unlock(&dir->d_inode->i_mutex); return status; @@ -333,14 +333,14 @@ purge_old(struct dentry *parent, struct dentry *child) int status; if (nfs4_has_reclaimed_state(child->d_name.name)) - return 0; + return nfs_ok; status = nfsd4_clear_clid_dir(parent, child); if (status) printk("failed to remove client recovery directory %s\n", child->d_name.name); /* Keep trying, success or failure: */ - return 0; + return nfs_ok; } void @@ -365,10 +365,10 @@ load_recdir(struct dentry *parent, struct dentry *child) printk("nfsd4: illegal name %s in recovery directory\n", child->d_name.name); /* Keep trying; maybe the others are OK: */ - return 0; + return nfs_ok; } nfs4_client_to_reclaim(child->d_name.name); - return 0; + return nfs_ok; } int diff --git a/trunk/fs/nfsd/nfs4state.c b/trunk/fs/nfsd/nfs4state.c index 293b6495829f..ebcf226a9e4a 100644 --- a/trunk/fs/nfsd/nfs4state.c +++ b/trunk/fs/nfsd/nfs4state.c @@ -710,10 +710,10 @@ gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se) * as described above. * */ -__be32 +int nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_setclientid *setclid) { - __be32 ip_addr = rqstp->rq_addr.sin_addr.s_addr; + u32 ip_addr = rqstp->rq_addr.sin_addr.s_addr; struct xdr_netobj clname = { .len = setclid->se_namelen, .data = setclid->se_name, @@ -721,7 +721,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_setclientid *setclid) nfs4_verifier clverifier = setclid->se_verf; unsigned int strhashval; struct nfs4_client *conf, *unconf, *new; - __be32 status; + int status; char dname[HEXDIR_LEN]; if (!check_name(clname)) @@ -875,14 +875,14 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_setclientid *setclid) * * NOTE: callback information will be processed here in a future patch */ -__be32 +int nfsd4_setclientid_confirm(struct svc_rqst *rqstp, struct nfsd4_setclientid_confirm *setclientid_confirm) { - __be32 ip_addr = rqstp->rq_addr.sin_addr.s_addr; + u32 ip_addr = rqstp->rq_addr.sin_addr.s_addr; struct nfs4_client *conf, *unconf; nfs4_verifier confirm = setclientid_confirm->sc_confirm; clientid_t * clid = &setclientid_confirm->sc_clientid; - __be32 status; + int status; if (STALE_CLIENTID(clid)) return nfserr_stale_clientid; @@ -1280,13 +1280,13 @@ test_share(struct nfs4_stateid *stp, struct nfsd4_open *open) { * Called to check deny when READ with all zero stateid or * WRITE with all zero or all one stateid */ -static __be32 +static int nfs4_share_conflict(struct svc_fh *current_fh, unsigned int deny_type) { struct inode *ino = current_fh->fh_dentry->d_inode; struct nfs4_file *fp; struct nfs4_stateid *stp; - __be32 ret; + int ret; dprintk("NFSD: nfs4_share_conflict\n"); @@ -1444,7 +1444,7 @@ static struct lock_manager_operations nfsd_lease_mng_ops = { }; -__be32 +int nfsd4_process_open1(struct nfsd4_open *open) { clientid_t *clientid = &open->op_clientid; @@ -1477,7 +1477,7 @@ nfsd4_process_open1(struct nfsd4_open *open) } if (open->op_seqid == sop->so_seqid - 1) { if (sop->so_replay.rp_buflen) - return nfserr_replay_me; + return NFSERR_REPLAY_ME; /* The original OPEN failed so spectacularly * that we don't even have replay data saved! * Therefore, we have no choice but to continue @@ -1501,7 +1501,7 @@ nfsd4_process_open1(struct nfsd4_open *open) return nfs_ok; } -static inline __be32 +static inline int nfs4_check_delegmode(struct nfs4_delegation *dp, int flags) { if ((flags & WR_STATE) && (dp->dl_type == NFS4_OPEN_DELEGATE_READ)) @@ -1522,12 +1522,12 @@ find_delegation_file(struct nfs4_file *fp, stateid_t *stid) return NULL; } -static __be32 +static int nfs4_check_deleg(struct nfs4_file *fp, struct nfsd4_open *open, struct nfs4_delegation **dp) { int flags; - __be32 status = nfserr_bad_stateid; + int status = nfserr_bad_stateid; *dp = find_delegation_file(fp, &open->op_delegate_stateid); if (*dp == NULL) @@ -1546,11 +1546,11 @@ nfs4_check_deleg(struct nfs4_file *fp, struct nfsd4_open *open, return nfs_ok; } -static __be32 +static int nfs4_check_open(struct nfs4_file *fp, struct nfsd4_open *open, struct nfs4_stateid **stpp) { struct nfs4_stateid *local; - __be32 status = nfserr_share_denied; + int status = nfserr_share_denied; struct nfs4_stateowner *sop = open->op_stateowner; list_for_each_entry(local, &fp->fi_stateids, st_perfile) { @@ -1575,7 +1575,7 @@ nfs4_alloc_stateid(void) return kmem_cache_alloc(stateid_slab, GFP_KERNEL); } -static __be32 +static int nfs4_new_open(struct svc_rqst *rqstp, struct nfs4_stateid **stpp, struct nfs4_delegation *dp, struct svc_fh *cur_fh, int flags) @@ -1590,7 +1590,7 @@ nfs4_new_open(struct svc_rqst *rqstp, struct nfs4_stateid **stpp, get_file(dp->dl_vfs_file); stp->st_vfs_file = dp->dl_vfs_file; } else { - __be32 status; + int status; status = nfsd_open(rqstp, cur_fh, S_IFREG, flags, &stp->st_vfs_file); if (status) { @@ -1604,7 +1604,7 @@ nfs4_new_open(struct svc_rqst *rqstp, struct nfs4_stateid **stpp, return 0; } -static inline __be32 +static inline int nfsd4_truncate(struct svc_rqst *rqstp, struct svc_fh *fh, struct nfsd4_open *open) { @@ -1619,22 +1619,22 @@ nfsd4_truncate(struct svc_rqst *rqstp, struct svc_fh *fh, return nfsd_setattr(rqstp, fh, &iattr, 0, (time_t)0); } -static __be32 +static int nfs4_upgrade_open(struct svc_rqst *rqstp, struct svc_fh *cur_fh, struct nfs4_stateid *stp, struct nfsd4_open *open) { struct file *filp = stp->st_vfs_file; struct inode *inode = filp->f_dentry->d_inode; unsigned int share_access, new_writer; - __be32 status; + int status; set_access(&share_access, stp->st_access_bmap); new_writer = (~share_access) & open->op_share_access & NFS4_SHARE_ACCESS_WRITE; if (new_writer) { - int err = get_write_access(inode); - if (err) - return nfserrno(err); + status = get_write_access(inode); + if (status) + return nfserrno(status); } status = nfsd4_truncate(rqstp, cur_fh, open); if (status) { @@ -1738,14 +1738,14 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta /* * called with nfs4_lock_state() held. */ -__be32 +int nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open) { struct nfs4_file *fp = NULL; struct inode *ino = current_fh->fh_dentry->d_inode; struct nfs4_stateid *stp = NULL; struct nfs4_delegation *dp = NULL; - __be32 status; + int status; status = nfserr_inval; if (!access_valid(open->op_share_access) @@ -1833,11 +1833,11 @@ static struct work_struct laundromat_work; static void laundromat_main(void *); static DECLARE_WORK(laundromat_work, laundromat_main, NULL); -__be32 +int nfsd4_renew(clientid_t *clid) { struct nfs4_client *clp; - __be32 status; + int status; nfs4_lock_state(); dprintk("process_renew(%08x/%08x): starting\n", @@ -1996,9 +1996,9 @@ access_permit_write(unsigned long access_bmap) } static -__be32 nfs4_check_openmode(struct nfs4_stateid *stp, int flags) +int nfs4_check_openmode(struct nfs4_stateid *stp, int flags) { - __be32 status = nfserr_openmode; + int status = nfserr_openmode; if ((flags & WR_STATE) && (!access_permit_write(stp->st_access_bmap))) goto out; @@ -2009,7 +2009,7 @@ __be32 nfs4_check_openmode(struct nfs4_stateid *stp, int flags) return status; } -static inline __be32 +static inline int check_special_stateids(svc_fh *current_fh, stateid_t *stateid, int flags) { /* Trying to call delegreturn with a special stateid? Yuch: */ @@ -2043,14 +2043,14 @@ io_during_grace_disallowed(struct inode *inode, int flags) /* * Checks for stateid operations */ -__be32 +int nfs4_preprocess_stateid_op(struct svc_fh *current_fh, stateid_t *stateid, int flags, struct file **filpp) { struct nfs4_stateid *stp = NULL; struct nfs4_delegation *dp = NULL; stateid_t *stidp; struct inode *ino = current_fh->fh_dentry->d_inode; - __be32 status; + int status; dprintk("NFSD: preprocess_stateid_op: stateid = (%08x/%08x/%08x/%08x)\n", stateid->si_boot, stateid->si_stateownerid, @@ -2125,7 +2125,7 @@ setlkflg (int type) /* * Checks for sequence id mutating operations. */ -static __be32 +static int nfs4_preprocess_seqid_op(struct svc_fh *current_fh, u32 seqid, stateid_t *stateid, int flags, struct nfs4_stateowner **sopp, struct nfs4_stateid **stpp, struct nfsd4_lock *lock) { struct nfs4_stateid *stp; @@ -2169,7 +2169,7 @@ nfs4_preprocess_seqid_op(struct svc_fh *current_fh, u32 seqid, stateid_t *statei clientid_t *lockclid = &lock->v.new.clientid; struct nfs4_client *clp = sop->so_client; int lkflg = 0; - __be32 status; + int status; lkflg = setlkflg(lock->lk_type); @@ -2233,7 +2233,7 @@ nfs4_preprocess_seqid_op(struct svc_fh *current_fh, u32 seqid, stateid_t *statei if (seqid == sop->so_seqid - 1) { dprintk("NFSD: preprocess_seqid_op: retransmission?\n"); /* indicate replay to calling function */ - return nfserr_replay_me; + return NFSERR_REPLAY_ME; } printk("NFSD: preprocess_seqid_op: bad seqid (expected %d, got %d)\n", sop->so_seqid, seqid); @@ -2241,10 +2241,10 @@ nfs4_preprocess_seqid_op(struct svc_fh *current_fh, u32 seqid, stateid_t *statei return nfserr_bad_seqid; } -__be32 +int nfsd4_open_confirm(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open_confirm *oc, struct nfs4_stateowner **replay_owner) { - __be32 status; + int status; struct nfs4_stateowner *sop; struct nfs4_stateid *stp; @@ -2310,10 +2310,10 @@ reset_union_bmap_deny(unsigned long deny, unsigned long *bmap) } } -__be32 +int nfsd4_open_downgrade(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open_downgrade *od, struct nfs4_stateowner **replay_owner) { - __be32 status; + int status; struct nfs4_stateid *stp; unsigned int share_access; @@ -2365,10 +2365,10 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct n /* * nfs4_unlock_state() called after encode */ -__be32 +int nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_close *close, struct nfs4_stateowner **replay_owner) { - __be32 status; + int status; struct nfs4_stateid *stp; dprintk("NFSD: nfsd4_close on file %.*s\n", @@ -2404,10 +2404,10 @@ nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_clos return status; } -__be32 +int nfsd4_delegreturn(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_delegreturn *dr) { - __be32 status; + int status; if ((status = fh_verify(rqstp, current_fh, S_IFREG, 0))) goto out; @@ -2635,7 +2635,7 @@ check_lock_length(u64 offset, u64 length) /* * LOCK operation */ -__be32 +int nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock *lock, struct nfs4_stateowner **replay_owner) { struct nfs4_stateowner *open_sop = NULL; @@ -2644,9 +2644,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock struct file *filp; struct file_lock file_lock; struct file_lock conflock; - __be32 status = 0; + int status = 0; unsigned int strhashval; - int err; dprintk("NFSD: nfsd4_lock: start=%Ld length=%Ld\n", (long long) lock->lk_offset, @@ -2759,14 +2758,13 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock * locks_copy_lock: */ conflock.fl_ops = NULL; conflock.fl_lmops = NULL; - err = posix_lock_file_conf(filp, &file_lock, &conflock); + status = posix_lock_file_conf(filp, &file_lock, &conflock); dprintk("NFSD: nfsd4_lock: posix_lock_file_conf status %d\n",status); - switch (-err) { + switch (-status) { case 0: /* success! */ update_stateid(&lock_stp->st_stateid); memcpy(&lock->lk_resp_stateid, &lock_stp->st_stateid, sizeof(stateid_t)); - status = 0; break; case (EAGAIN): /* conflock holds conflicting lock */ status = nfserr_denied; @@ -2777,7 +2775,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock status = nfserr_deadlock; break; default: - dprintk("NFSD: nfsd4_lock: posix_lock_file_conf() failed! status %d\n",err); + dprintk("NFSD: nfsd4_lock: posix_lock_file_conf() failed! status %d\n",status); status = nfserr_resource; break; } @@ -2795,14 +2793,14 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock /* * LOCKT operation */ -__be32 +int nfsd4_lockt(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lockt *lockt) { struct inode *inode; struct file file; struct file_lock file_lock; struct file_lock conflock; - __be32 status; + int status; if (nfs4_in_grace()) return nfserr_grace; @@ -2875,14 +2873,13 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock return status; } -__be32 +int nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_locku *locku, struct nfs4_stateowner **replay_owner) { struct nfs4_stateid *stp; struct file *filp = NULL; struct file_lock file_lock; - __be32 status; - int err; + int status; dprintk("NFSD: nfsd4_locku: start=%Ld length=%Ld\n", (long long) locku->lu_offset, @@ -2920,8 +2917,8 @@ nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock /* * Try to unlock the file in the VFS. */ - err = posix_lock_file(filp, &file_lock); - if (err) { + status = posix_lock_file(filp, &file_lock); + if (status) { dprintk("NFSD: nfs4_locku: posix_lock_file failed!\n"); goto out_nfserr; } @@ -2940,7 +2937,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock return status; out_nfserr: - status = nfserrno(err); + status = nfserrno(status); goto out; } @@ -2968,7 +2965,7 @@ check_for_locks(struct file *filp, struct nfs4_stateowner *lowner) return status; } -__be32 +int nfsd4_release_lockowner(struct svc_rqst *rqstp, struct nfsd4_release_lockowner *rlockowner) { clientid_t *clid = &rlockowner->rl_clientid; @@ -2977,7 +2974,7 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp, struct nfsd4_release_lockowner * struct xdr_netobj *owner = &rlockowner->rl_owner; struct list_head matches; int i; - __be32 status; + int status; dprintk("nfsd4_release_lockowner clientid: (%08x/%08x):\n", clid->cl_boot, clid->cl_id); @@ -3114,7 +3111,7 @@ nfs4_find_reclaim_client(clientid_t *clid) /* * Called from OPEN. Look for clientid in reclaim list. */ -__be32 +int nfs4_check_open_reclaim(clientid_t *clid) { return nfs4_find_reclaim_client(clid) ? nfs_ok : nfserr_reclaim_bad; diff --git a/trunk/fs/nfsd/nfs4xdr.c b/trunk/fs/nfsd/nfs4xdr.c index f3f239db04bb..41fc241b729a 100644 --- a/trunk/fs/nfsd/nfs4xdr.c +++ b/trunk/fs/nfsd/nfs4xdr.c @@ -68,8 +68,8 @@ #define NFS4_REFERRAL_FSID_MAJOR 0x8000000ULL #define NFS4_REFERRAL_FSID_MINOR 0x8000000ULL -static __be32 -check_filename(char *str, int len, __be32 err) +static int +check_filename(char *str, int len, int err) { int i; @@ -94,8 +94,8 @@ check_filename(char *str, int len, __be32 err) * consistent with the style used in NFSv2/v3... */ #define DECODE_HEAD \ - __be32 *p; \ - __be32 status + u32 *p; \ + int status #define DECODE_TAIL \ status = 0; \ out: \ @@ -144,13 +144,13 @@ xdr_error: \ } \ } while (0) -static __be32 *read_buf(struct nfsd4_compoundargs *argp, int nbytes) +static u32 *read_buf(struct nfsd4_compoundargs *argp, int nbytes) { /* We want more bytes than seem to be available. * Maybe we need a new page, maybe we have just run out */ int avail = (char*)argp->end - (char*)argp->p; - __be32 *p; + u32 *p; if (avail + argp->pagelen < nbytes) return NULL; if (avail + PAGE_SIZE < nbytes) /* need more than a page !! */ @@ -197,7 +197,7 @@ defer_free(struct nfsd4_compoundargs *argp, return 0; } -static char *savemem(struct nfsd4_compoundargs *argp, __be32 *p, int nbytes) +static char *savemem(struct nfsd4_compoundargs *argp, u32 *p, int nbytes) { void *new = NULL; if (p == argp->tmp) { @@ -217,7 +217,7 @@ static char *savemem(struct nfsd4_compoundargs *argp, __be32 *p, int nbytes) } -static __be32 +static int nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval) { u32 bmlen; @@ -240,14 +240,13 @@ nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval) DECODE_TAIL; } -static __be32 +static int nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, struct iattr *iattr, struct nfs4_acl **acl) { int expected_len, len = 0; u32 dummy32; char *buf; - int host_err; DECODE_HEAD; iattr->ia_valid = 0; @@ -281,7 +280,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, struct iattr *ia *acl = nfs4_acl_new(); if (*acl == NULL) { - host_err = -ENOMEM; + status = -ENOMEM; goto out_nfserr; } defer_free(argp, (void (*)(const void *))nfs4_acl_free, *acl); @@ -296,20 +295,20 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, struct iattr *ia len += XDR_QUADLEN(dummy32) << 2; READMEM(buf, dummy32); ace.whotype = nfs4_acl_get_whotype(buf, dummy32); - host_err = 0; + status = 0; if (ace.whotype != NFS4_ACL_WHO_NAMED) ace.who = 0; else if (ace.flag & NFS4_ACE_IDENTIFIER_GROUP) - host_err = nfsd_map_name_to_gid(argp->rqstp, + status = nfsd_map_name_to_gid(argp->rqstp, buf, dummy32, &ace.who); else - host_err = nfsd_map_name_to_uid(argp->rqstp, + status = nfsd_map_name_to_uid(argp->rqstp, buf, dummy32, &ace.who); - if (host_err) + if (status) goto out_nfserr; - host_err = nfs4_acl_add_ace(*acl, ace.type, ace.flag, + status = nfs4_acl_add_ace(*acl, ace.type, ace.flag, ace.access_mask, ace.whotype, ace.who); - if (host_err) + if (status) goto out_nfserr; } } else @@ -328,7 +327,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, struct iattr *ia READ_BUF(dummy32); len += (XDR_QUADLEN(dummy32) << 2); READMEM(buf, dummy32); - if ((host_err = nfsd_map_name_to_uid(argp->rqstp, buf, dummy32, &iattr->ia_uid))) + if ((status = nfsd_map_name_to_uid(argp->rqstp, buf, dummy32, &iattr->ia_uid))) goto out_nfserr; iattr->ia_valid |= ATTR_UID; } @@ -339,7 +338,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, struct iattr *ia READ_BUF(dummy32); len += (XDR_QUADLEN(dummy32) << 2); READMEM(buf, dummy32); - if ((host_err = nfsd_map_name_to_gid(argp->rqstp, buf, dummy32, &iattr->ia_gid))) + if ((status = nfsd_map_name_to_gid(argp->rqstp, buf, dummy32, &iattr->ia_gid))) goto out_nfserr; iattr->ia_valid |= ATTR_GID; } @@ -415,11 +414,11 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, struct iattr *ia DECODE_TAIL; out_nfserr: - status = nfserrno(host_err); + status = nfserrno(status); goto out; } -static __be32 +static int nfsd4_decode_access(struct nfsd4_compoundargs *argp, struct nfsd4_access *access) { DECODE_HEAD; @@ -430,7 +429,7 @@ nfsd4_decode_access(struct nfsd4_compoundargs *argp, struct nfsd4_access *access DECODE_TAIL; } -static __be32 +static int nfsd4_decode_close(struct nfsd4_compoundargs *argp, struct nfsd4_close *close) { DECODE_HEAD; @@ -445,7 +444,7 @@ nfsd4_decode_close(struct nfsd4_compoundargs *argp, struct nfsd4_close *close) } -static __be32 +static int nfsd4_decode_commit(struct nfsd4_compoundargs *argp, struct nfsd4_commit *commit) { DECODE_HEAD; @@ -457,7 +456,7 @@ nfsd4_decode_commit(struct nfsd4_compoundargs *argp, struct nfsd4_commit *commit DECODE_TAIL; } -static __be32 +static int nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create) { DECODE_HEAD; @@ -497,7 +496,7 @@ nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create DECODE_TAIL; } -static inline __be32 +static inline int nfsd4_decode_delegreturn(struct nfsd4_compoundargs *argp, struct nfsd4_delegreturn *dr) { DECODE_HEAD; @@ -509,13 +508,13 @@ nfsd4_decode_delegreturn(struct nfsd4_compoundargs *argp, struct nfsd4_delegretu DECODE_TAIL; } -static inline __be32 +static inline int nfsd4_decode_getattr(struct nfsd4_compoundargs *argp, struct nfsd4_getattr *getattr) { return nfsd4_decode_bitmap(argp, getattr->ga_bmval); } -static __be32 +static int nfsd4_decode_link(struct nfsd4_compoundargs *argp, struct nfsd4_link *link) { DECODE_HEAD; @@ -530,7 +529,7 @@ nfsd4_decode_link(struct nfsd4_compoundargs *argp, struct nfsd4_link *link) DECODE_TAIL; } -static __be32 +static int nfsd4_decode_lock(struct nfsd4_compoundargs *argp, struct nfsd4_lock *lock) { DECODE_HEAD; @@ -569,7 +568,7 @@ nfsd4_decode_lock(struct nfsd4_compoundargs *argp, struct nfsd4_lock *lock) DECODE_TAIL; } -static __be32 +static int nfsd4_decode_lockt(struct nfsd4_compoundargs *argp, struct nfsd4_lockt *lockt) { DECODE_HEAD; @@ -588,7 +587,7 @@ nfsd4_decode_lockt(struct nfsd4_compoundargs *argp, struct nfsd4_lockt *lockt) DECODE_TAIL; } -static __be32 +static int nfsd4_decode_locku(struct nfsd4_compoundargs *argp, struct nfsd4_locku *locku) { DECODE_HEAD; @@ -607,7 +606,7 @@ nfsd4_decode_locku(struct nfsd4_compoundargs *argp, struct nfsd4_locku *locku) DECODE_TAIL; } -static __be32 +static int nfsd4_decode_lookup(struct nfsd4_compoundargs *argp, struct nfsd4_lookup *lookup) { DECODE_HEAD; @@ -622,7 +621,7 @@ nfsd4_decode_lookup(struct nfsd4_compoundargs *argp, struct nfsd4_lookup *lookup DECODE_TAIL; } -static __be32 +static int nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open) { DECODE_HEAD; @@ -700,7 +699,7 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open) DECODE_TAIL; } -static __be32 +static int nfsd4_decode_open_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_open_confirm *open_conf) { DECODE_HEAD; @@ -714,7 +713,7 @@ nfsd4_decode_open_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_open_con DECODE_TAIL; } -static __be32 +static int nfsd4_decode_open_downgrade(struct nfsd4_compoundargs *argp, struct nfsd4_open_downgrade *open_down) { DECODE_HEAD; @@ -730,7 +729,7 @@ nfsd4_decode_open_downgrade(struct nfsd4_compoundargs *argp, struct nfsd4_open_d DECODE_TAIL; } -static __be32 +static int nfsd4_decode_putfh(struct nfsd4_compoundargs *argp, struct nfsd4_putfh *putfh) { DECODE_HEAD; @@ -745,7 +744,7 @@ nfsd4_decode_putfh(struct nfsd4_compoundargs *argp, struct nfsd4_putfh *putfh) DECODE_TAIL; } -static __be32 +static int nfsd4_decode_read(struct nfsd4_compoundargs *argp, struct nfsd4_read *read) { DECODE_HEAD; @@ -759,7 +758,7 @@ nfsd4_decode_read(struct nfsd4_compoundargs *argp, struct nfsd4_read *read) DECODE_TAIL; } -static __be32 +static int nfsd4_decode_readdir(struct nfsd4_compoundargs *argp, struct nfsd4_readdir *readdir) { DECODE_HEAD; @@ -775,7 +774,7 @@ nfsd4_decode_readdir(struct nfsd4_compoundargs *argp, struct nfsd4_readdir *read DECODE_TAIL; } -static __be32 +static int nfsd4_decode_remove(struct nfsd4_compoundargs *argp, struct nfsd4_remove *remove) { DECODE_HEAD; @@ -790,7 +789,7 @@ nfsd4_decode_remove(struct nfsd4_compoundargs *argp, struct nfsd4_remove *remove DECODE_TAIL; } -static __be32 +static int nfsd4_decode_rename(struct nfsd4_compoundargs *argp, struct nfsd4_rename *rename) { DECODE_HEAD; @@ -810,7 +809,7 @@ nfsd4_decode_rename(struct nfsd4_compoundargs *argp, struct nfsd4_rename *rename DECODE_TAIL; } -static __be32 +static int nfsd4_decode_renew(struct nfsd4_compoundargs *argp, clientid_t *clientid) { DECODE_HEAD; @@ -821,7 +820,7 @@ nfsd4_decode_renew(struct nfsd4_compoundargs *argp, clientid_t *clientid) DECODE_TAIL; } -static __be32 +static int nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *setattr) { DECODE_HEAD; @@ -835,7 +834,7 @@ nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *seta DECODE_TAIL; } -static __be32 +static int nfsd4_decode_setclientid(struct nfsd4_compoundargs *argp, struct nfsd4_setclientid *setclientid) { DECODE_HEAD; @@ -860,7 +859,7 @@ nfsd4_decode_setclientid(struct nfsd4_compoundargs *argp, struct nfsd4_setclient DECODE_TAIL; } -static __be32 +static int nfsd4_decode_setclientid_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_setclientid_confirm *scd_c) { DECODE_HEAD; @@ -873,7 +872,7 @@ nfsd4_decode_setclientid_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_s } /* Also used for NVERIFY */ -static __be32 +static int nfsd4_decode_verify(struct nfsd4_compoundargs *argp, struct nfsd4_verify *verify) { #if 0 @@ -909,7 +908,7 @@ nfsd4_decode_verify(struct nfsd4_compoundargs *argp, struct nfsd4_verify *verify DECODE_TAIL; } -static __be32 +static int nfsd4_decode_write(struct nfsd4_compoundargs *argp, struct nfsd4_write *write) { int avail; @@ -952,15 +951,15 @@ nfsd4_decode_write(struct nfsd4_compoundargs *argp, struct nfsd4_write *write) argp->pagelen -= len; } } - argp->end = (__be32*) (argp->rqstp->rq_vec[v].iov_base + argp->rqstp->rq_vec[v].iov_len); - argp->p = (__be32*) (argp->rqstp->rq_vec[v].iov_base + (XDR_QUADLEN(len) << 2)); + argp->end = (u32*) (argp->rqstp->rq_vec[v].iov_base + argp->rqstp->rq_vec[v].iov_len); + argp->p = (u32*) (argp->rqstp->rq_vec[v].iov_base + (XDR_QUADLEN(len) << 2)); argp->rqstp->rq_vec[v].iov_len = len; write->wr_vlen = v+1; DECODE_TAIL; } -static __be32 +static int nfsd4_decode_release_lockowner(struct nfsd4_compoundargs *argp, struct nfsd4_release_lockowner *rlockowner) { DECODE_HEAD; @@ -974,7 +973,7 @@ nfsd4_decode_release_lockowner(struct nfsd4_compoundargs *argp, struct nfsd4_rel DECODE_TAIL; } -static __be32 +static int nfsd4_decode_compound(struct nfsd4_compoundargs *argp) { DECODE_HEAD; @@ -1180,7 +1179,7 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp) * task to translate them into Linux-specific versions which are more * consistent with the style used in NFSv2/v3... */ -#define ENCODE_HEAD __be32 *p +#define ENCODE_HEAD u32 *p #define WRITE32(n) *p++ = htonl(n) #define WRITE64(n) do { \ @@ -1210,8 +1209,8 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp) * Header routine to setup seqid operation replay cache */ #define ENCODE_SEQID_OP_HEAD \ - __be32 *p; \ - __be32 *save; \ + u32 *p; \ + u32 *save; \ \ save = resp->p; @@ -1235,11 +1234,11 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp) /* Encode as an array of strings the string given with components * seperated @sep. */ -static __be32 nfsd4_encode_components(char sep, char *components, - __be32 **pp, int *buflen) +static int nfsd4_encode_components(char sep, char *components, + u32 **pp, int *buflen) { - __be32 *p = *pp; - __be32 *countp = p; + u32 *p = *pp; + u32 *countp = p; int strlen, count=0; char *str, *end; @@ -1272,11 +1271,11 @@ static __be32 nfsd4_encode_components(char sep, char *components, /* * encode a location element of a fs_locations structure */ -static __be32 nfsd4_encode_fs_location4(struct nfsd4_fs_location *location, - __be32 **pp, int *buflen) +static int nfsd4_encode_fs_location4(struct nfsd4_fs_location *location, + u32 **pp, int *buflen) { - __be32 status; - __be32 *p = *pp; + int status; + u32 *p = *pp; status = nfsd4_encode_components(':', location->hosts, &p, buflen); if (status) @@ -1293,15 +1292,16 @@ static __be32 nfsd4_encode_fs_location4(struct nfsd4_fs_location *location, * Returned string is safe to use as long as the caller holds a reference * to @exp. */ -static char *nfsd4_path(struct svc_rqst *rqstp, struct svc_export *exp, __be32 *stat) +static char *nfsd4_path(struct svc_rqst *rqstp, struct svc_export *exp) { struct svc_fh tmp_fh; char *path, *rootpath; + int stat; fh_init(&tmp_fh, NFS4_FHSIZE); - *stat = exp_pseudoroot(rqstp->rq_client, &tmp_fh, &rqstp->rq_chandle); - if (*stat) - return NULL; + stat = exp_pseudoroot(rqstp->rq_client, &tmp_fh, &rqstp->rq_chandle); + if (stat) + return ERR_PTR(stat); rootpath = tmp_fh.fh_export->ex_path; path = exp->ex_path; @@ -1309,8 +1309,7 @@ static char *nfsd4_path(struct svc_rqst *rqstp, struct svc_export *exp, __be32 * if (strncmp(path, rootpath, strlen(rootpath))) { printk("nfsd: fs_locations failed;" "%s is not contained in %s\n", path, rootpath); - *stat = nfserr_notsupp; - return NULL; + return ERR_PTR(-EOPNOTSUPP); } return path + strlen(rootpath); @@ -1319,18 +1318,17 @@ static char *nfsd4_path(struct svc_rqst *rqstp, struct svc_export *exp, __be32 * /* * encode a fs_locations structure */ -static __be32 nfsd4_encode_fs_locations(struct svc_rqst *rqstp, +static int nfsd4_encode_fs_locations(struct svc_rqst *rqstp, struct svc_export *exp, - __be32 **pp, int *buflen) + u32 **pp, int *buflen) { - __be32 status; - int i; - __be32 *p = *pp; + int status, i; + u32 *p = *pp; struct nfsd4_fs_locations *fslocs = &exp->ex_fslocs; - char *root = nfsd4_path(rqstp, exp, &status); + char *root = nfsd4_path(rqstp, exp); - if (status) - return status; + if (IS_ERR(root)) + return PTR_ERR(root); status = nfsd4_encode_components('/', root, &p, buflen); if (status) return status; @@ -1354,9 +1352,9 @@ static u32 nfs4_ftypes[16] = { NF4SOCK, NF4BAD, NF4LNK, NF4BAD, }; -static __be32 +static int nfsd4_encode_name(struct svc_rqst *rqstp, int whotype, uid_t id, int group, - __be32 **p, int *buflen) + u32 **p, int *buflen) { int status; @@ -1376,21 +1374,21 @@ nfsd4_encode_name(struct svc_rqst *rqstp, int whotype, uid_t id, int group, return 0; } -static inline __be32 -nfsd4_encode_user(struct svc_rqst *rqstp, uid_t uid, __be32 **p, int *buflen) +static inline int +nfsd4_encode_user(struct svc_rqst *rqstp, uid_t uid, u32 **p, int *buflen) { return nfsd4_encode_name(rqstp, NFS4_ACL_WHO_NAMED, uid, 0, p, buflen); } -static inline __be32 -nfsd4_encode_group(struct svc_rqst *rqstp, uid_t gid, __be32 **p, int *buflen) +static inline int +nfsd4_encode_group(struct svc_rqst *rqstp, uid_t gid, u32 **p, int *buflen) { return nfsd4_encode_name(rqstp, NFS4_ACL_WHO_NAMED, gid, 1, p, buflen); } -static inline __be32 +static inline int nfsd4_encode_aclname(struct svc_rqst *rqstp, int whotype, uid_t id, int group, - __be32 **p, int *buflen) + u32 **p, int *buflen) { return nfsd4_encode_name(rqstp, whotype, id, group, p, buflen); } @@ -1399,7 +1397,7 @@ nfsd4_encode_aclname(struct svc_rqst *rqstp, int whotype, uid_t id, int group, FATTR4_WORD0_RDATTR_ERROR) #define WORD1_ABSENT_FS_ATTRS FATTR4_WORD1_MOUNTED_ON_FILEID -static __be32 fattr_handle_absent_fs(u32 *bmval0, u32 *bmval1, u32 *rdattr_err) +static int fattr_handle_absent_fs(u32 *bmval0, u32 *bmval1, u32 *rdattr_err) { /* As per referral draft: */ if (*bmval0 & ~WORD0_ABSENT_FS_ATTRS || @@ -1422,9 +1420,9 @@ static __be32 fattr_handle_absent_fs(u32 *bmval0, u32 *bmval1, u32 *rdattr_err) * @countp is the buffer size in _words_; upon successful return this becomes * replaced with the number of words written. */ -__be32 +int nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, - struct dentry *dentry, __be32 *buffer, int *countp, u32 *bmval, + struct dentry *dentry, u32 *buffer, int *countp, u32 *bmval, struct svc_rqst *rqstp) { u32 bmval0 = bmval[0]; @@ -1433,13 +1431,12 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, struct svc_fh tempfh; struct kstatfs statfs; int buflen = *countp << 2; - __be32 *attrlenp; + u32 *attrlenp; u32 dummy; u64 dummy64; u32 rdattr_err = 0; - __be32 *p = buffer; - __be32 status; - int err; + u32 *p = buffer; + int status; int aclsupport = 0; struct nfs4_acl *acl = NULL; @@ -1453,14 +1450,14 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, goto out; } - err = vfs_getattr(exp->ex_mnt, dentry, &stat); - if (err) + status = vfs_getattr(exp->ex_mnt, dentry, &stat); + if (status) goto out_nfserr; if ((bmval0 & (FATTR4_WORD0_FILES_FREE | FATTR4_WORD0_FILES_TOTAL)) || (bmval1 & (FATTR4_WORD1_SPACE_AVAIL | FATTR4_WORD1_SPACE_FREE | FATTR4_WORD1_SPACE_TOTAL))) { - err = vfs_statfs(dentry, &statfs); - if (err) + status = vfs_statfs(dentry, &statfs); + if (status) goto out_nfserr; } if ((bmval0 & (FATTR4_WORD0_FILEHANDLE | FATTR4_WORD0_FSID)) && !fhp) { @@ -1472,15 +1469,15 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, } if (bmval0 & (FATTR4_WORD0_ACL | FATTR4_WORD0_ACLSUPPORT | FATTR4_WORD0_SUPPORTED_ATTRS)) { - err = nfsd4_get_nfs4_acl(rqstp, dentry, &acl); - aclsupport = (err == 0); + status = nfsd4_get_nfs4_acl(rqstp, dentry, &acl); + aclsupport = (status == 0); if (bmval0 & FATTR4_WORD0_ACL) { - if (err == -EOPNOTSUPP) + if (status == -EOPNOTSUPP) bmval0 &= ~FATTR4_WORD0_ACL; - else if (err == -EINVAL) { + else if (status == -EINVAL) { status = nfserr_attrnotsupp; goto out; - } else if (err != 0) + } else if (status != 0) goto out_nfserr; } } @@ -1820,7 +1817,7 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, fh_put(&tempfh); return status; out_nfserr: - status = nfserrno(err); + status = nfserrno(status); goto out; out_resource: *countp = 0; @@ -1831,13 +1828,13 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, goto out; } -static __be32 +static int nfsd4_encode_dirent_fattr(struct nfsd4_readdir *cd, - const char *name, int namlen, __be32 *p, int *buflen) + const char *name, int namlen, u32 *p, int *buflen) { struct svc_export *exp = cd->rd_fhp->fh_export; struct dentry *dentry; - __be32 nfserr; + int nfserr; dentry = lookup_one_len(name, cd->rd_fhp->fh_dentry, namlen); if (IS_ERR(dentry)) @@ -1866,10 +1863,10 @@ nfsd4_encode_dirent_fattr(struct nfsd4_readdir *cd, return nfserr; } -static __be32 * -nfsd4_encode_rdattr_error(__be32 *p, int buflen, __be32 nfserr) +static u32 * +nfsd4_encode_rdattr_error(u32 *p, int buflen, int nfserr) { - __be32 *attrlenp; + u32 *attrlenp; if (buflen < 6) return NULL; @@ -1889,8 +1886,8 @@ nfsd4_encode_dirent(struct readdir_cd *ccd, const char *name, int namlen, { struct nfsd4_readdir *cd = container_of(ccd, struct nfsd4_readdir, common); int buflen; - __be32 *p = cd->buffer; - __be32 nfserr = nfserr_toosmall; + u32 *p = cd->buffer; + int nfserr = nfserr_toosmall; /* In nfsv4, "." and ".." never make it onto the wire.. */ if (name && isdotent(name, namlen)) { @@ -1946,7 +1943,7 @@ nfsd4_encode_dirent(struct readdir_cd *ccd, const char *name, int namlen, } static void -nfsd4_encode_access(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_access *access) +nfsd4_encode_access(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_access *access) { ENCODE_HEAD; @@ -1959,7 +1956,7 @@ nfsd4_encode_access(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_ } static void -nfsd4_encode_close(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_close *close) +nfsd4_encode_close(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_close *close) { ENCODE_SEQID_OP_HEAD; @@ -1974,7 +1971,7 @@ nfsd4_encode_close(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_c static void -nfsd4_encode_commit(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_commit *commit) +nfsd4_encode_commit(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_commit *commit) { ENCODE_HEAD; @@ -1986,7 +1983,7 @@ nfsd4_encode_commit(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_ } static void -nfsd4_encode_create(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_create *create) +nfsd4_encode_create(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_create *create) { ENCODE_HEAD; @@ -2000,8 +1997,8 @@ nfsd4_encode_create(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_ } } -static __be32 -nfsd4_encode_getattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_getattr *getattr) +static int +nfsd4_encode_getattr(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_getattr *getattr) { struct svc_fh *fhp = getattr->ga_fhp; int buflen; @@ -2019,7 +2016,7 @@ nfsd4_encode_getattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4 } static void -nfsd4_encode_getfh(struct nfsd4_compoundres *resp, __be32 nfserr, struct svc_fh *fhp) +nfsd4_encode_getfh(struct nfsd4_compoundres *resp, int nfserr, struct svc_fh *fhp) { unsigned int len; ENCODE_HEAD; @@ -2059,7 +2056,7 @@ nfsd4_encode_lock_denied(struct nfsd4_compoundres *resp, struct nfsd4_lock_denie } static void -nfsd4_encode_lock(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lock *lock) +nfsd4_encode_lock(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_lock *lock) { ENCODE_SEQID_OP_HEAD; @@ -2075,14 +2072,14 @@ nfsd4_encode_lock(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lo } static void -nfsd4_encode_lockt(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lockt *lockt) +nfsd4_encode_lockt(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_lockt *lockt) { if (nfserr == nfserr_denied) nfsd4_encode_lock_denied(resp, &lockt->lt_denied); } static void -nfsd4_encode_locku(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_locku *locku) +nfsd4_encode_locku(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_locku *locku) { ENCODE_SEQID_OP_HEAD; @@ -2098,7 +2095,7 @@ nfsd4_encode_locku(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_l static void -nfsd4_encode_link(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_link *link) +nfsd4_encode_link(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_link *link) { ENCODE_HEAD; @@ -2111,7 +2108,7 @@ nfsd4_encode_link(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_li static void -nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open *open) +nfsd4_encode_open(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_open *open) { ENCODE_SEQID_OP_HEAD; @@ -2176,7 +2173,7 @@ nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_op } static void -nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_confirm *oc) +nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_open_confirm *oc) { ENCODE_SEQID_OP_HEAD; @@ -2191,7 +2188,7 @@ nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, __be32 nfserr, struct } static void -nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_downgrade *od) +nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_open_downgrade *od) { ENCODE_SEQID_OP_HEAD; @@ -2205,8 +2202,8 @@ nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, __be32 nfserr, struc ENCODE_SEQID_OP_TAIL(od->od_stateowner); } -static __be32 -nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr, +static int +nfsd4_encode_read(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_read *read) { u32 eof; @@ -2270,8 +2267,8 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr, return 0; } -static __be32 -nfsd4_encode_readlink(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_readlink *readlink) +static int +nfsd4_encode_readlink(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_readlink *readlink) { int maxcount; char *page; @@ -2318,12 +2315,12 @@ nfsd4_encode_readlink(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd return 0; } -static __be32 -nfsd4_encode_readdir(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_readdir *readdir) +static int +nfsd4_encode_readdir(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_readdir *readdir) { int maxcount; loff_t offset; - __be32 *page, *savep, *tailbase; + u32 *page, *savep, *tailbase; ENCODE_HEAD; if (nfserr) @@ -2398,7 +2395,7 @@ nfsd4_encode_readdir(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4 } static void -nfsd4_encode_remove(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_remove *remove) +nfsd4_encode_remove(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_remove *remove) { ENCODE_HEAD; @@ -2410,7 +2407,7 @@ nfsd4_encode_remove(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_ } static void -nfsd4_encode_rename(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_rename *rename) +nfsd4_encode_rename(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_rename *rename) { ENCODE_HEAD; @@ -2427,7 +2424,7 @@ nfsd4_encode_rename(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_ * regardless of the error status. */ static void -nfsd4_encode_setattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setattr *setattr) +nfsd4_encode_setattr(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_setattr *setattr) { ENCODE_HEAD; @@ -2446,7 +2443,7 @@ nfsd4_encode_setattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4 } static void -nfsd4_encode_setclientid(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setclientid *scd) +nfsd4_encode_setclientid(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_setclientid *scd) { ENCODE_HEAD; @@ -2465,7 +2462,7 @@ nfsd4_encode_setclientid(struct nfsd4_compoundres *resp, __be32 nfserr, struct n } static void -nfsd4_encode_write(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_write *write) +nfsd4_encode_write(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_write *write) { ENCODE_HEAD; @@ -2481,7 +2478,7 @@ nfsd4_encode_write(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_w void nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op) { - __be32 *statp; + u32 *statp; ENCODE_HEAD; RESERVE_SPACE(8); @@ -2619,7 +2616,7 @@ nfsd4_encode_replay(struct nfsd4_compoundres *resp, struct nfsd4_op *op) */ int -nfs4svc_encode_voidres(struct svc_rqst *rqstp, __be32 *p, void *dummy) +nfs4svc_encode_voidres(struct svc_rqst *rqstp, u32 *p, void *dummy) { return xdr_ressize_check(rqstp, p); } @@ -2641,9 +2638,9 @@ void nfsd4_release_compoundargs(struct nfsd4_compoundargs *args) } int -nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_compoundargs *args) +nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, u32 *p, struct nfsd4_compoundargs *args) { - __be32 status; + int status; args->p = p; args->end = rqstp->rq_arg.head[0].iov_base + rqstp->rq_arg.head[0].iov_len; @@ -2662,7 +2659,7 @@ nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_comp } int -nfs4svc_encode_compoundres(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_compoundres *resp) +nfs4svc_encode_compoundres(struct svc_rqst *rqstp, u32 *p, struct nfsd4_compoundres *resp) { /* * All that remains is to write the tag and operation count... diff --git a/trunk/fs/nfsd/nfscache.c b/trunk/fs/nfsd/nfscache.c index 6100bbe27432..fdf7cf3dfadc 100644 --- a/trunk/fs/nfsd/nfscache.c +++ b/trunk/fs/nfsd/nfscache.c @@ -29,7 +29,7 @@ */ #define CACHESIZE 1024 #define HASHSIZE 64 -#define REQHASH(xid) (((((__force __u32)xid) >> 24) ^ ((__force __u32)xid)) & (HASHSIZE-1)) +#define REQHASH(xid) ((((xid) >> 24) ^ (xid)) & (HASHSIZE-1)) static struct hlist_head * hash_list; static struct list_head lru_head; @@ -127,8 +127,8 @@ nfsd_cache_lookup(struct svc_rqst *rqstp, int type) struct hlist_node *hn; struct hlist_head *rh; struct svc_cacherep *rp; - __be32 xid = rqstp->rq_xid; - u32 proto = rqstp->rq_prot, + u32 xid = rqstp->rq_xid, + proto = rqstp->rq_prot, vers = rqstp->rq_vers, proc = rqstp->rq_proc; unsigned long age; @@ -258,7 +258,7 @@ nfsd_cache_lookup(struct svc_rqst *rqstp, int type) * In this case, nfsd_cache_update is called with statp == NULL. */ void -nfsd_cache_update(struct svc_rqst *rqstp, int cachetype, __be32 *statp) +nfsd_cache_update(struct svc_rqst *rqstp, int cachetype, u32 *statp) { struct svc_cacherep *rp; struct kvec *resv = &rqstp->rq_res.head[0], *cachv; diff --git a/trunk/fs/nfsd/nfsfh.c b/trunk/fs/nfsd/nfsfh.c index 727ab3bd450d..501d83884530 100644 --- a/trunk/fs/nfsd/nfsfh.c +++ b/trunk/fs/nfsd/nfsfh.c @@ -76,7 +76,7 @@ static int nfsd_acceptable(void *expv, struct dentry *dentry) * comment in the NFSv3 spec says this is incorrect (implementation notes for * the write call). */ -static inline __be32 +static inline int nfsd_mode_check(struct svc_rqst *rqstp, umode_t mode, int type) { /* Type can be negative when creating hardlinks - not to a dir */ @@ -110,13 +110,13 @@ nfsd_mode_check(struct svc_rqst *rqstp, umode_t mode, int type) * This is only called at the start of an nfsproc call, so fhp points to * a svc_fh which is all 0 except for the over-the-wire file handle. */ -__be32 +u32 fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access) { struct knfsd_fh *fh = &fhp->fh_handle; struct svc_export *exp = NULL; struct dentry *dentry; - __be32 error = 0; + u32 error = 0; dprintk("nfsd: fh_verify(%s)\n", SVCFH_fmt(fhp)); @@ -315,7 +315,7 @@ static inline void _fh_update_old(struct dentry *dentry, fh->ofh_dirino = 0; } -__be32 +int fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, struct svc_fh *ref_fh) { /* ref_fh is a reference file handle. @@ -451,7 +451,7 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, st * Update file handle information after changing a dentry. * This is only called by nfsd_create, nfsd_create_v3 and nfsd_proc_create */ -__be32 +int fh_update(struct svc_fh *fhp) { struct dentry *dentry; diff --git a/trunk/fs/nfsd/nfsproc.c b/trunk/fs/nfsd/nfsproc.c index ec983b777680..9ee1dab5d44a 100644 --- a/trunk/fs/nfsd/nfsproc.c +++ b/trunk/fs/nfsd/nfsproc.c @@ -30,22 +30,22 @@ typedef struct svc_buf svc_buf; #define NFSDDBG_FACILITY NFSDDBG_PROC -static __be32 +static int nfsd_proc_null(struct svc_rqst *rqstp, void *argp, void *resp) { return nfs_ok; } -static __be32 -nfsd_return_attrs(__be32 err, struct nfsd_attrstat *resp) +static int +nfsd_return_attrs(int err, struct nfsd_attrstat *resp) { if (err) return err; return nfserrno(vfs_getattr(resp->fh.fh_export->ex_mnt, resp->fh.fh_dentry, &resp->stat)); } -static __be32 -nfsd_return_dirop(__be32 err, struct nfsd_diropres *resp) +static int +nfsd_return_dirop(int err, struct nfsd_diropres *resp) { if (err) return err; return nfserrno(vfs_getattr(resp->fh.fh_export->ex_mnt, @@ -56,11 +56,11 @@ nfsd_return_dirop(__be32 err, struct nfsd_diropres *resp) * Get a file's attributes * N.B. After this call resp->fh needs an fh_put */ -static __be32 +static int nfsd_proc_getattr(struct svc_rqst *rqstp, struct nfsd_fhandle *argp, struct nfsd_attrstat *resp) { - __be32 nfserr; + int nfserr; dprintk("nfsd: GETATTR %s\n", SVCFH_fmt(&argp->fh)); fh_copy(&resp->fh, &argp->fh); @@ -72,11 +72,11 @@ nfsd_proc_getattr(struct svc_rqst *rqstp, struct nfsd_fhandle *argp, * Set a file's attributes * N.B. After this call resp->fh needs an fh_put */ -static __be32 +static int nfsd_proc_setattr(struct svc_rqst *rqstp, struct nfsd_sattrargs *argp, struct nfsd_attrstat *resp) { - __be32 nfserr; + int nfserr; dprintk("nfsd: SETATTR %s, valid=%x, size=%ld\n", SVCFH_fmt(&argp->fh), argp->attrs.ia_valid, (long) argp->attrs.ia_size); @@ -92,11 +92,11 @@ nfsd_proc_setattr(struct svc_rqst *rqstp, struct nfsd_sattrargs *argp, * doesn't exist yet. * N.B. After this call resp->fh needs an fh_put */ -static __be32 +static int nfsd_proc_lookup(struct svc_rqst *rqstp, struct nfsd_diropargs *argp, struct nfsd_diropres *resp) { - __be32 nfserr; + int nfserr; dprintk("nfsd: LOOKUP %s %.*s\n", SVCFH_fmt(&argp->fh), argp->len, argp->name); @@ -112,11 +112,11 @@ nfsd_proc_lookup(struct svc_rqst *rqstp, struct nfsd_diropargs *argp, /* * Read a symlink. */ -static __be32 +static int nfsd_proc_readlink(struct svc_rqst *rqstp, struct nfsd_readlinkargs *argp, struct nfsd_readlinkres *resp) { - __be32 nfserr; + int nfserr; dprintk("nfsd: READLINK %s\n", SVCFH_fmt(&argp->fh)); @@ -132,11 +132,11 @@ nfsd_proc_readlink(struct svc_rqst *rqstp, struct nfsd_readlinkargs *argp, * Read a portion of a file. * N.B. After this call resp->fh needs an fh_put */ -static __be32 +static int nfsd_proc_read(struct svc_rqst *rqstp, struct nfsd_readargs *argp, struct nfsd_readres *resp) { - __be32 nfserr; + int nfserr; dprintk("nfsd: READ %s %d bytes at %d\n", SVCFH_fmt(&argp->fh), @@ -172,11 +172,11 @@ nfsd_proc_read(struct svc_rqst *rqstp, struct nfsd_readargs *argp, * Write data to a file * N.B. After this call resp->fh needs an fh_put */ -static __be32 +static int nfsd_proc_write(struct svc_rqst *rqstp, struct nfsd_writeargs *argp, struct nfsd_attrstat *resp) { - __be32 nfserr; + int nfserr; int stable = 1; dprintk("nfsd: WRITE %s %d bytes at %d\n", @@ -197,7 +197,7 @@ nfsd_proc_write(struct svc_rqst *rqstp, struct nfsd_writeargs *argp, * and the actual create() call in compliance with VFS protocols. * N.B. After this call _both_ argp->fh and resp->fh need an fh_put */ -static __be32 +static int nfsd_proc_create(struct svc_rqst *rqstp, struct nfsd_createargs *argp, struct nfsd_diropres *resp) { @@ -206,8 +206,7 @@ nfsd_proc_create(struct svc_rqst *rqstp, struct nfsd_createargs *argp, struct iattr *attr = &argp->attrs; struct inode *inode; struct dentry *dchild; - int type, mode; - __be32 nfserr; + int nfserr, type, mode; dev_t rdev = 0, wanted = new_decode_dev(attr->ia_size); dprintk("nfsd: CREATE %s %.*s\n", @@ -349,11 +348,11 @@ nfsd_proc_create(struct svc_rqst *rqstp, struct nfsd_createargs *argp, return nfsd_return_dirop(nfserr, resp); } -static __be32 +static int nfsd_proc_remove(struct svc_rqst *rqstp, struct nfsd_diropargs *argp, void *resp) { - __be32 nfserr; + int nfserr; dprintk("nfsd: REMOVE %s %.*s\n", SVCFH_fmt(&argp->fh), argp->len, argp->name); @@ -364,11 +363,11 @@ nfsd_proc_remove(struct svc_rqst *rqstp, struct nfsd_diropargs *argp, return nfserr; } -static __be32 +static int nfsd_proc_rename(struct svc_rqst *rqstp, struct nfsd_renameargs *argp, void *resp) { - __be32 nfserr; + int nfserr; dprintk("nfsd: RENAME %s %.*s -> \n", SVCFH_fmt(&argp->ffh), argp->flen, argp->fname); @@ -382,11 +381,11 @@ nfsd_proc_rename(struct svc_rqst *rqstp, struct nfsd_renameargs *argp, return nfserr; } -static __be32 +static int nfsd_proc_link(struct svc_rqst *rqstp, struct nfsd_linkargs *argp, void *resp) { - __be32 nfserr; + int nfserr; dprintk("nfsd: LINK %s ->\n", SVCFH_fmt(&argp->ffh)); @@ -402,12 +401,12 @@ nfsd_proc_link(struct svc_rqst *rqstp, struct nfsd_linkargs *argp, return nfserr; } -static __be32 +static int nfsd_proc_symlink(struct svc_rqst *rqstp, struct nfsd_symlinkargs *argp, void *resp) { struct svc_fh newfh; - __be32 nfserr; + int nfserr; dprintk("nfsd: SYMLINK %s %.*s -> %.*s\n", SVCFH_fmt(&argp->ffh), argp->flen, argp->fname, @@ -431,11 +430,11 @@ nfsd_proc_symlink(struct svc_rqst *rqstp, struct nfsd_symlinkargs *argp, * Make directory. This operation is not idempotent. * N.B. After this call resp->fh needs an fh_put */ -static __be32 +static int nfsd_proc_mkdir(struct svc_rqst *rqstp, struct nfsd_createargs *argp, struct nfsd_diropres *resp) { - __be32 nfserr; + int nfserr; dprintk("nfsd: MKDIR %s %.*s\n", SVCFH_fmt(&argp->fh), argp->len, argp->name); @@ -455,11 +454,11 @@ nfsd_proc_mkdir(struct svc_rqst *rqstp, struct nfsd_createargs *argp, /* * Remove a directory */ -static __be32 +static int nfsd_proc_rmdir(struct svc_rqst *rqstp, struct nfsd_diropargs *argp, void *resp) { - __be32 nfserr; + int nfserr; dprintk("nfsd: RMDIR %s %.*s\n", SVCFH_fmt(&argp->fh), argp->len, argp->name); @@ -471,12 +470,11 @@ nfsd_proc_rmdir(struct svc_rqst *rqstp, struct nfsd_diropargs *argp, /* * Read a portion of a directory. */ -static __be32 +static int nfsd_proc_readdir(struct svc_rqst *rqstp, struct nfsd_readdirargs *argp, struct nfsd_readdirres *resp) { - int count; - __be32 nfserr; + int nfserr, count; loff_t offset; dprintk("nfsd: READDIR %s %d bytes at %d\n", @@ -511,11 +509,11 @@ nfsd_proc_readdir(struct svc_rqst *rqstp, struct nfsd_readdirargs *argp, /* * Get file system info */ -static __be32 +static int nfsd_proc_statfs(struct svc_rqst * rqstp, struct nfsd_fhandle *argp, struct nfsd_statfsres *resp) { - __be32 nfserr; + int nfserr; dprintk("nfsd: STATFS %s\n", SVCFH_fmt(&argp->fh)); @@ -581,11 +579,11 @@ struct svc_version nfsd_version2 = { /* * Map errnos to NFS errnos. */ -__be32 +int nfserrno (int errno) { static struct { - __be32 nfserr; + int nfserr; int syserr; } nfs_errtbl[] = { { nfs_ok, 0 }, @@ -617,10 +615,11 @@ nfserrno (int errno) { nfserr_badname, -ESRCH }, { nfserr_io, -ETXTBSY }, { nfserr_notsupp, -EOPNOTSUPP }, + { -1, -EIO } }; int i; - for (i = 0; i < ARRAY_SIZE(nfs_errtbl); i++) { + for (i = 0; nfs_errtbl[i].nfserr != -1; i++) { if (nfs_errtbl[i].syserr == errno) return nfs_errtbl[i].nfserr; } diff --git a/trunk/fs/nfsd/nfssvc.c b/trunk/fs/nfsd/nfssvc.c index 0aaccb03bf76..6fa6340a5fb8 100644 --- a/trunk/fs/nfsd/nfssvc.c +++ b/trunk/fs/nfsd/nfssvc.c @@ -217,7 +217,7 @@ int nfsd_create_serv(void) atomic_set(&nfsd_busy, 0); nfsd_serv = svc_create_pooled(&nfsd_program, - nfsd_max_blksize, + NFSD_BUFSIZE - NFSSVC_MAXBLKSIZE + nfsd_max_blksize, nfsd_last_thread, nfsd, SIG_NOCLEAN, THIS_MODULE); if (nfsd_serv == NULL) @@ -491,12 +491,12 @@ nfsd(struct svc_rqst *rqstp) } int -nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp) +nfsd_dispatch(struct svc_rqst *rqstp, u32 *statp) { struct svc_procedure *proc; kxdrproc_t xdr; - __be32 nfserr; - __be32 *nfserrp; + u32 nfserr; + u32 *nfserrp; dprintk("nfsd_dispatch: vers %d proc %d\n", rqstp->rq_vers, rqstp->rq_proc); @@ -515,7 +515,7 @@ nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp) /* Decode arguments */ xdr = proc->pc_decode; - if (xdr && !xdr(rqstp, (__be32*)rqstp->rq_arg.head[0].iov_base, + if (xdr && !xdr(rqstp, (u32*)rqstp->rq_arg.head[0].iov_base, rqstp->rq_argp)) { dprintk("nfsd: failed to decode arguments!\n"); nfsd_cache_update(rqstp, RC_NOCACHE, NULL); @@ -528,7 +528,7 @@ nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp) */ nfserrp = rqstp->rq_res.head[0].iov_base + rqstp->rq_res.head[0].iov_len; - rqstp->rq_res.head[0].iov_len += sizeof(__be32); + rqstp->rq_res.head[0].iov_len += sizeof(u32); /* Now call the procedure handler, and encode NFS status. */ nfserr = proc->pc_func(rqstp, rqstp->rq_argp, rqstp->rq_resp); diff --git a/trunk/fs/nfsd/nfsxdr.c b/trunk/fs/nfsd/nfsxdr.c index 56ebb1443e0e..1135c0d14557 100644 --- a/trunk/fs/nfsd/nfsxdr.c +++ b/trunk/fs/nfsd/nfsxdr.c @@ -37,8 +37,8 @@ static u32 nfs_ftypes[] = { /* * XDR functions for basic NFS types */ -static __be32 * -decode_fh(__be32 *p, struct svc_fh *fhp) +static u32 * +decode_fh(u32 *p, struct svc_fh *fhp) { fh_init(fhp, NFS_FHSIZE); memcpy(&fhp->fh_handle.fh_base, p, NFS_FHSIZE); @@ -50,13 +50,13 @@ decode_fh(__be32 *p, struct svc_fh *fhp) } /* Helper function for NFSv2 ACL code */ -__be32 *nfs2svc_decode_fh(__be32 *p, struct svc_fh *fhp) +u32 *nfs2svc_decode_fh(u32 *p, struct svc_fh *fhp) { return decode_fh(p, fhp); } -static inline __be32 * -encode_fh(__be32 *p, struct svc_fh *fhp) +static inline u32 * +encode_fh(u32 *p, struct svc_fh *fhp) { memcpy(p, &fhp->fh_handle.fh_base, NFS_FHSIZE); return p + (NFS_FHSIZE>> 2); @@ -66,8 +66,8 @@ 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 inline __be32 * -decode_filename(__be32 *p, char **namp, int *lenp) +static inline u32 * +decode_filename(u32 *p, char **namp, int *lenp) { char *name; int i; @@ -82,8 +82,8 @@ decode_filename(__be32 *p, char **namp, int *lenp) return p; } -static inline __be32 * -decode_pathname(__be32 *p, char **namp, int *lenp) +static inline u32 * +decode_pathname(u32 *p, char **namp, int *lenp) { char *name; int i; @@ -98,8 +98,8 @@ decode_pathname(__be32 *p, char **namp, int *lenp) return p; } -static inline __be32 * -decode_sattr(__be32 *p, struct iattr *iap) +static inline u32 * +decode_sattr(u32 *p, struct iattr *iap) { u32 tmp, tmp1; @@ -151,8 +151,8 @@ decode_sattr(__be32 *p, struct iattr *iap) return p; } -static __be32 * -encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp, +static u32 * +encode_fattr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp, struct kstat *stat) { struct dentry *dentry = fhp->fh_dentry; @@ -195,7 +195,7 @@ encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp, } /* Helper function for NFSv2 ACL code */ -__be32 *nfs2svc_encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp) +u32 *nfs2svc_encode_fattr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp) { struct kstat stat; vfs_getattr(fhp->fh_export->ex_mnt, fhp->fh_dentry, &stat); @@ -206,13 +206,13 @@ __be32 *nfs2svc_encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *f * XDR decode functions */ int -nfssvc_decode_void(struct svc_rqst *rqstp, __be32 *p, void *dummy) +nfssvc_decode_void(struct svc_rqst *rqstp, u32 *p, void *dummy) { return xdr_argsize_check(rqstp, p); } int -nfssvc_decode_fhandle(struct svc_rqst *rqstp, __be32 *p, struct nfsd_fhandle *args) +nfssvc_decode_fhandle(struct svc_rqst *rqstp, u32 *p, struct nfsd_fhandle *args) { if (!(p = decode_fh(p, &args->fh))) return 0; @@ -220,7 +220,7 @@ nfssvc_decode_fhandle(struct svc_rqst *rqstp, __be32 *p, struct nfsd_fhandle *ar } int -nfssvc_decode_sattrargs(struct svc_rqst *rqstp, __be32 *p, +nfssvc_decode_sattrargs(struct svc_rqst *rqstp, u32 *p, struct nfsd_sattrargs *args) { if (!(p = decode_fh(p, &args->fh)) @@ -231,7 +231,7 @@ nfssvc_decode_sattrargs(struct svc_rqst *rqstp, __be32 *p, } int -nfssvc_decode_diropargs(struct svc_rqst *rqstp, __be32 *p, +nfssvc_decode_diropargs(struct svc_rqst *rqstp, u32 *p, struct nfsd_diropargs *args) { if (!(p = decode_fh(p, &args->fh)) @@ -242,7 +242,7 @@ nfssvc_decode_diropargs(struct svc_rqst *rqstp, __be32 *p, } int -nfssvc_decode_readargs(struct svc_rqst *rqstp, __be32 *p, +nfssvc_decode_readargs(struct svc_rqst *rqstp, u32 *p, struct nfsd_readargs *args) { unsigned int len; @@ -273,7 +273,7 @@ nfssvc_decode_readargs(struct svc_rqst *rqstp, __be32 *p, } int -nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p, +nfssvc_decode_writeargs(struct svc_rqst *rqstp, u32 *p, struct nfsd_writeargs *args) { unsigned int len; @@ -303,7 +303,7 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p, } int -nfssvc_decode_createargs(struct svc_rqst *rqstp, __be32 *p, +nfssvc_decode_createargs(struct svc_rqst *rqstp, u32 *p, struct nfsd_createargs *args) { if (!(p = decode_fh(p, &args->fh)) @@ -315,7 +315,7 @@ nfssvc_decode_createargs(struct svc_rqst *rqstp, __be32 *p, } int -nfssvc_decode_renameargs(struct svc_rqst *rqstp, __be32 *p, +nfssvc_decode_renameargs(struct svc_rqst *rqstp, u32 *p, struct nfsd_renameargs *args) { if (!(p = decode_fh(p, &args->ffh)) @@ -328,7 +328,7 @@ nfssvc_decode_renameargs(struct svc_rqst *rqstp, __be32 *p, } int -nfssvc_decode_readlinkargs(struct svc_rqst *rqstp, __be32 *p, struct nfsd_readlinkargs *args) +nfssvc_decode_readlinkargs(struct svc_rqst *rqstp, u32 *p, struct nfsd_readlinkargs *args) { if (!(p = decode_fh(p, &args->fh))) return 0; @@ -338,7 +338,7 @@ nfssvc_decode_readlinkargs(struct svc_rqst *rqstp, __be32 *p, struct nfsd_readli } int -nfssvc_decode_linkargs(struct svc_rqst *rqstp, __be32 *p, +nfssvc_decode_linkargs(struct svc_rqst *rqstp, u32 *p, struct nfsd_linkargs *args) { if (!(p = decode_fh(p, &args->ffh)) @@ -350,7 +350,7 @@ nfssvc_decode_linkargs(struct svc_rqst *rqstp, __be32 *p, } int -nfssvc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p, +nfssvc_decode_symlinkargs(struct svc_rqst *rqstp, u32 *p, struct nfsd_symlinkargs *args) { if (!(p = decode_fh(p, &args->ffh)) @@ -363,7 +363,7 @@ nfssvc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p, } int -nfssvc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p, +nfssvc_decode_readdirargs(struct svc_rqst *rqstp, u32 *p, struct nfsd_readdirargs *args) { if (!(p = decode_fh(p, &args->fh))) @@ -382,13 +382,13 @@ nfssvc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p, * XDR encode functions */ int -nfssvc_encode_void(struct svc_rqst *rqstp, __be32 *p, void *dummy) +nfssvc_encode_void(struct svc_rqst *rqstp, u32 *p, void *dummy) { return xdr_ressize_check(rqstp, p); } int -nfssvc_encode_attrstat(struct svc_rqst *rqstp, __be32 *p, +nfssvc_encode_attrstat(struct svc_rqst *rqstp, u32 *p, struct nfsd_attrstat *resp) { p = encode_fattr(rqstp, p, &resp->fh, &resp->stat); @@ -396,7 +396,7 @@ nfssvc_encode_attrstat(struct svc_rqst *rqstp, __be32 *p, } int -nfssvc_encode_diropres(struct svc_rqst *rqstp, __be32 *p, +nfssvc_encode_diropres(struct svc_rqst *rqstp, u32 *p, struct nfsd_diropres *resp) { p = encode_fh(p, &resp->fh); @@ -405,7 +405,7 @@ nfssvc_encode_diropres(struct svc_rqst *rqstp, __be32 *p, } int -nfssvc_encode_readlinkres(struct svc_rqst *rqstp, __be32 *p, +nfssvc_encode_readlinkres(struct svc_rqst *rqstp, u32 *p, struct nfsd_readlinkres *resp) { *p++ = htonl(resp->len); @@ -421,7 +421,7 @@ nfssvc_encode_readlinkres(struct svc_rqst *rqstp, __be32 *p, } int -nfssvc_encode_readres(struct svc_rqst *rqstp, __be32 *p, +nfssvc_encode_readres(struct svc_rqst *rqstp, u32 *p, struct nfsd_readres *resp) { p = encode_fattr(rqstp, p, &resp->fh, &resp->stat); @@ -440,7 +440,7 @@ nfssvc_encode_readres(struct svc_rqst *rqstp, __be32 *p, } int -nfssvc_encode_readdirres(struct svc_rqst *rqstp, __be32 *p, +nfssvc_encode_readdirres(struct svc_rqst *rqstp, u32 *p, struct nfsd_readdirres *resp) { xdr_ressize_check(rqstp, p); @@ -453,7 +453,7 @@ nfssvc_encode_readdirres(struct svc_rqst *rqstp, __be32 *p, } int -nfssvc_encode_statfsres(struct svc_rqst *rqstp, __be32 *p, +nfssvc_encode_statfsres(struct svc_rqst *rqstp, u32 *p, struct nfsd_statfsres *resp) { struct kstatfs *stat = &resp->stats; @@ -471,7 +471,7 @@ nfssvc_encode_entry(struct readdir_cd *ccd, const char *name, int namlen, loff_t offset, ino_t ino, unsigned int d_type) { struct nfsd_readdirres *cd = container_of(ccd, struct nfsd_readdirres, common); - __be32 *p = cd->buffer; + u32 *p = cd->buffer; int buflen, slen; /* @@ -497,7 +497,7 @@ nfssvc_encode_entry(struct readdir_cd *ccd, const char *name, *p++ = htonl((u32) ino); /* file id */ p = xdr_encode_array(p, name, namlen);/* name length & name */ cd->offset = p; /* remember pointer */ - *p++ = htonl(~0U); /* offset of next entry */ + *p++ = ~(u32) 0; /* offset of next entry */ cd->buflen = buflen; cd->buffer = p; @@ -509,7 +509,7 @@ nfssvc_encode_entry(struct readdir_cd *ccd, const char *name, * XDR release functions */ int -nfssvc_release_fhandle(struct svc_rqst *rqstp, __be32 *p, +nfssvc_release_fhandle(struct svc_rqst *rqstp, u32 *p, struct nfsd_fhandle *resp) { fh_put(&resp->fh); diff --git a/trunk/fs/nfsd/vfs.c b/trunk/fs/nfsd/vfs.c index bb4d926e4487..1141bd29e4e3 100644 --- a/trunk/fs/nfsd/vfs.c +++ b/trunk/fs/nfsd/vfs.c @@ -110,7 +110,7 @@ nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp, struct dentry *dentry = *dpp; struct vfsmount *mnt = mntget(exp->ex_mnt); struct dentry *mounts = dget(dentry); - int err = 0; + int err = nfs_ok; while (follow_down(&mnt,&mounts)&&d_mountpoint(mounts)); @@ -148,15 +148,14 @@ nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp, * clients and is explicitly disallowed for NFSv3 * NeilBrown */ -__be32 +int nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name, int len, struct svc_fh *resfh) { struct svc_export *exp; struct dentry *dparent; struct dentry *dentry; - __be32 err; - int host_err; + int err; dprintk("nfsd: nfsd_lookup(fh %s, %.*s)\n", SVCFH_fmt(fhp), len,name); @@ -194,7 +193,7 @@ nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name, exp2 = exp_parent(exp->ex_client, mnt, dentry, &rqstp->rq_chandle); if (IS_ERR(exp2)) { - host_err = PTR_ERR(exp2); + err = PTR_ERR(exp2); dput(dentry); mntput(mnt); goto out_nfserr; @@ -211,14 +210,14 @@ nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name, } else { fh_lock(fhp); dentry = lookup_one_len(name, dparent, len); - host_err = PTR_ERR(dentry); + err = PTR_ERR(dentry); if (IS_ERR(dentry)) goto out_nfserr; /* * check if we have crossed a mount point ... */ if (d_mountpoint(dentry)) { - if ((host_err = nfsd_cross_mnt(rqstp, &dentry, &exp))) { + if ((err = nfsd_cross_mnt(rqstp, &dentry, &exp))) { dput(dentry); goto out_nfserr; } @@ -237,7 +236,7 @@ nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name, return err; out_nfserr: - err = nfserrno(host_err); + err = nfserrno(err); goto out; } @@ -245,7 +244,7 @@ nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name, * Set various file attributes. * N.B. After this call fhp needs an fh_put */ -__be32 +int nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap, int check_guard, time_t guardtime) { @@ -254,8 +253,7 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap, int accmode = MAY_SATTR; int ftype = 0; int imode; - __be32 err; - int host_err; + int err; int size_change = 0; if (iap->ia_valid & (ATTR_ATIME | ATTR_MTIME | ATTR_SIZE)) @@ -321,19 +319,19 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap, * If we are changing the size of the file, then * we need to break all leases. */ - host_err = break_lease(inode, FMODE_WRITE | O_NONBLOCK); - if (host_err == -EWOULDBLOCK) - host_err = -ETIMEDOUT; - if (host_err) /* ENOMEM or EWOULDBLOCK */ + err = break_lease(inode, FMODE_WRITE | O_NONBLOCK); + if (err == -EWOULDBLOCK) + err = -ETIMEDOUT; + if (err) /* ENOMEM or EWOULDBLOCK */ goto out_nfserr; - host_err = get_write_access(inode); - if (host_err) + err = get_write_access(inode); + if (err) goto out_nfserr; size_change = 1; - host_err = locks_verify_truncate(inode, NULL, iap->ia_size); - if (host_err) { + err = locks_verify_truncate(inode, NULL, iap->ia_size); + if (err) { put_write_access(inode); goto out_nfserr; } @@ -359,8 +357,8 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap, err = nfserr_notsync; if (!check_guard || guardtime == inode->i_ctime.tv_sec) { fh_lock(fhp); - host_err = notify_change(dentry, iap); - err = nfserrno(host_err); + err = notify_change(dentry, iap); + err = nfserrno(err); fh_unlock(fhp); } if (size_change) @@ -372,7 +370,7 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap, return err; out_nfserr: - err = nfserrno(host_err); + err = nfserrno(err); goto out; } @@ -422,12 +420,11 @@ set_nfsv4_acl_one(struct dentry *dentry, struct posix_acl *pacl, char *key) return error; } -__be32 +int nfsd4_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfs4_acl *acl) { - __be32 error; - int host_error; + int error; struct dentry *dentry; struct inode *inode; struct posix_acl *pacl = NULL, *dpacl = NULL; @@ -443,20 +440,20 @@ nfsd4_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, if (S_ISDIR(inode->i_mode)) flags = NFS4_ACL_DIR; - host_error = nfs4_acl_nfsv4_to_posix(acl, &pacl, &dpacl, flags); - if (host_error == -EINVAL) { + error = nfs4_acl_nfsv4_to_posix(acl, &pacl, &dpacl, flags); + if (error == -EINVAL) { error = nfserr_attrnotsupp; goto out; - } else if (host_error < 0) + } else if (error < 0) goto out_nfserr; - host_error = set_nfsv4_acl_one(dentry, pacl, POSIX_ACL_XATTR_ACCESS); - if (host_error < 0) + error = set_nfsv4_acl_one(dentry, pacl, POSIX_ACL_XATTR_ACCESS); + if (error < 0) goto out_nfserr; if (S_ISDIR(inode->i_mode)) { - host_error = set_nfsv4_acl_one(dentry, dpacl, POSIX_ACL_XATTR_DEFAULT); - if (host_error < 0) + error = set_nfsv4_acl_one(dentry, dpacl, POSIX_ACL_XATTR_DEFAULT); + if (error < 0) goto out_nfserr; } @@ -467,7 +464,7 @@ nfsd4_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, posix_acl_release(dpacl); return (error); out_nfserr: - error = nfserrno(host_error); + error = nfserrno(error); goto out; } @@ -574,14 +571,14 @@ static struct accessmap nfs3_anyaccess[] = { { 0, 0 } }; -__be32 +int nfsd_access(struct svc_rqst *rqstp, struct svc_fh *fhp, u32 *access, u32 *supported) { struct accessmap *map; struct svc_export *export; struct dentry *dentry; u32 query, result = 0, sresult = 0; - __be32 error; + unsigned int error; error = fh_verify(rqstp, fhp, 0, MAY_NOP); if (error) @@ -601,7 +598,7 @@ nfsd_access(struct svc_rqst *rqstp, struct svc_fh *fhp, u32 *access, u32 *suppor query = *access; for (; map->access; map++) { if (map->access & query) { - __be32 err2; + unsigned int err2; sresult |= map->access; @@ -640,15 +637,13 @@ nfsd_access(struct svc_rqst *rqstp, struct svc_fh *fhp, u32 *access, u32 *suppor * The access argument indicates the type of open (read/write/lock) * N.B. After this call fhp needs an fh_put */ -__be32 +int nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access, struct file **filp) { struct dentry *dentry; struct inode *inode; - int flags = O_RDONLY|O_LARGEFILE; - __be32 err; - int host_err; + int flags = O_RDONLY|O_LARGEFILE, err; /* * If we get here, then the client has already done an "open", @@ -678,10 +673,10 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, * Check to see if there are any leases on this file. * This may block while leases are broken. */ - host_err = break_lease(inode, O_NONBLOCK | ((access & MAY_WRITE) ? FMODE_WRITE : 0)); - if (host_err == -EWOULDBLOCK) - host_err = -ETIMEDOUT; - if (host_err) /* NOMEM or WOULDBLOCK */ + err = break_lease(inode, O_NONBLOCK | ((access & MAY_WRITE) ? FMODE_WRITE : 0)); + if (err == -EWOULDBLOCK) + err = -ETIMEDOUT; + if (err) /* NOMEM or WOULDBLOCK */ goto out_nfserr; if (access & MAY_WRITE) { @@ -694,9 +689,10 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, } *filp = dentry_open(dget(dentry), mntget(fhp->fh_export->ex_mnt), flags); if (IS_ERR(*filp)) - host_err = PTR_ERR(*filp); + err = PTR_ERR(*filp); out_nfserr: - err = nfserrno(host_err); + if (err) + err = nfserrno(err); out: return err; } @@ -834,15 +830,14 @@ nfsd_read_actor(read_descriptor_t *desc, struct page *page, unsigned long offset return size; } -static __be32 +static int nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, loff_t offset, struct kvec *vec, int vlen, unsigned long *count) { struct inode *inode; struct raparms *ra; mm_segment_t oldfs; - __be32 err; - int host_err; + int err; err = nfserr_perm; inode = file->f_dentry->d_inode; @@ -860,12 +855,12 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, if (file->f_op->sendfile && rqstp->rq_sendfile_ok) { rqstp->rq_resused = 1; - host_err = file->f_op->sendfile(file, &offset, *count, + err = file->f_op->sendfile(file, &offset, *count, nfsd_read_actor, rqstp); } else { oldfs = get_fs(); set_fs(KERNEL_DS); - host_err = vfs_readv(file, (struct iovec __user *)vec, vlen, &offset); + err = vfs_readv(file, (struct iovec __user *)vec, vlen, &offset); set_fs(oldfs); } @@ -879,13 +874,13 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, spin_unlock(&rab->pb_lock); } - if (host_err >= 0) { - nfsdstats.io_read += host_err; - *count = host_err; + if (err >= 0) { + nfsdstats.io_read += err; + *count = err; err = 0; fsnotify_access(file->f_dentry); } else - err = nfserrno(host_err); + err = nfserrno(err); out: return err; } @@ -900,7 +895,7 @@ static void kill_suid(struct dentry *dentry) mutex_unlock(&dentry->d_inode->i_mutex); } -static __be32 +static int nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, loff_t offset, struct kvec *vec, int vlen, unsigned long cnt, int *stablep) @@ -909,8 +904,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, struct dentry *dentry; struct inode *inode; mm_segment_t oldfs; - __be32 err = 0; - int host_err; + int err = 0; int stable = *stablep; #ifdef MSNFS @@ -946,18 +940,18 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, /* Write the data. */ oldfs = get_fs(); set_fs(KERNEL_DS); - host_err = vfs_writev(file, (struct iovec __user *)vec, vlen, &offset); + err = vfs_writev(file, (struct iovec __user *)vec, vlen, &offset); set_fs(oldfs); - if (host_err >= 0) { + if (err >= 0) { nfsdstats.io_write += cnt; fsnotify_modify(file->f_dentry); } /* clear setuid/setgid flag after write */ - if (host_err >= 0 && (inode->i_mode & (S_ISUID | S_ISGID))) + if (err >= 0 && (inode->i_mode & (S_ISUID | S_ISGID))) kill_suid(dentry); - if (host_err >= 0 && stable) { + if (err >= 0 && stable) { static ino_t last_ino; static dev_t last_dev; @@ -983,7 +977,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, if (inode->i_state & I_DIRTY) { dprintk("nfsd: write sync %d\n", current->pid); - host_err=nfsd_sync(file); + err=nfsd_sync(file); } #if 0 wake_up(&inode->i_wait); @@ -993,11 +987,11 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, last_dev = inode->i_sb->s_dev; } - dprintk("nfsd: write complete host_err=%d\n", host_err); - if (host_err >= 0) + dprintk("nfsd: write complete err=%d\n", err); + if (err >= 0) err = 0; else - err = nfserrno(host_err); + err = nfserrno(err); out: return err; } @@ -1007,12 +1001,12 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, * on entry. On return, *count contains the number of bytes actually read. * N.B. After this call fhp needs an fh_put */ -__be32 +int nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, loff_t offset, struct kvec *vec, int vlen, unsigned long *count) { - __be32 err; + int err; if (file) { err = nfsd_permission(fhp->fh_export, fhp->fh_dentry, @@ -1036,12 +1030,12 @@ nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, * The stable flag requests synchronous writes. * N.B. After this call fhp needs an fh_put */ -__be32 +int nfsd_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, loff_t offset, struct kvec *vec, int vlen, unsigned long cnt, int *stablep) { - __be32 err = 0; + int err = 0; if (file) { err = nfsd_permission(fhp->fh_export, fhp->fh_dentry, @@ -1073,12 +1067,12 @@ nfsd_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, * Unfortunately we cannot lock the file to make sure we return full WCC * data to the client, as locking happens lower down in the filesystem. */ -__be32 +int nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset, unsigned long count) { struct file *file; - __be32 err; + int err; if ((u64)count > ~(u64)offset) return nfserr_inval; @@ -1106,15 +1100,14 @@ nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp, * * N.B. Every call to nfsd_create needs an fh_put for _both_ fhp and resfhp */ -__be32 +int nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, char *fname, int flen, struct iattr *iap, int type, dev_t rdev, struct svc_fh *resfhp) { struct dentry *dentry, *dchild = NULL; struct inode *dirp; - __be32 err; - int host_err; + int err; err = nfserr_perm; if (!flen) @@ -1141,7 +1134,7 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, /* called from nfsd_proc_mkdir, or possibly nfsd3_proc_create */ fh_lock_nested(fhp, I_MUTEX_PARENT); dchild = lookup_one_len(fname, dentry, flen); - host_err = PTR_ERR(dchild); + err = PTR_ERR(dchild); if (IS_ERR(dchild)) goto out_nfserr; err = fh_compose(resfhp, fhp->fh_export, dchild, fhp); @@ -1177,25 +1170,25 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, /* * Get the dir op function pointer. */ - err = 0; + err = nfserr_perm; switch (type) { case S_IFREG: - host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL); + err = vfs_create(dirp, dchild, iap->ia_mode, NULL); break; case S_IFDIR: - host_err = vfs_mkdir(dirp, dchild, iap->ia_mode); + err = vfs_mkdir(dirp, dchild, iap->ia_mode); break; case S_IFCHR: case S_IFBLK: case S_IFIFO: case S_IFSOCK: - host_err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev); + err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev); break; default: printk("nfsd: bad file type %o in nfsd_create\n", type); - host_err = -EINVAL; + err = -EINVAL; } - if (host_err < 0) + if (err < 0) goto out_nfserr; if (EX_ISSYNC(fhp->fh_export)) { @@ -1210,7 +1203,7 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, * directories via NFS. */ if ((iap->ia_valid &= ~(ATTR_UID|ATTR_GID|ATTR_MODE)) != 0) { - __be32 err2 = nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0); + int err2 = nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0); if (err2) err = err2; } @@ -1225,7 +1218,7 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, return err; out_nfserr: - err = nfserrno(host_err); + err = nfserrno(err); goto out; } @@ -1233,16 +1226,15 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, /* * NFSv3 version of nfsd_create */ -__be32 +int nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, char *fname, int flen, struct iattr *iap, struct svc_fh *resfhp, int createmode, u32 *verifier, - int *truncp, int *created) + int *truncp) { struct dentry *dentry, *dchild = NULL; struct inode *dirp; - __be32 err; - int host_err; + int err; __u32 v_mtime=0, v_atime=0; int v_mode=0; @@ -1272,7 +1264,7 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, * Compose the response file handle. */ dchild = lookup_one_len(fname, dentry, flen); - host_err = PTR_ERR(dchild); + err = PTR_ERR(dchild); if (IS_ERR(dchild)) goto out_nfserr; @@ -1328,11 +1320,9 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, goto out; } - host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL); - if (host_err < 0) + err = vfs_create(dirp, dchild, iap->ia_mode, NULL); + if (err < 0) goto out_nfserr; - if (created) - *created = 1; if (EX_ISSYNC(fhp->fh_export)) { err = nfserrno(nfsd_sync_dir(dentry)); @@ -1360,7 +1350,7 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, */ set_attr: if ((iap->ia_valid &= ~(ATTR_UID|ATTR_GID)) != 0) { - __be32 err2 = nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0); + int err2 = nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0); if (err2) err = err2; } @@ -1378,7 +1368,7 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, return err; out_nfserr: - err = nfserrno(host_err); + err = nfserrno(err); goto out; } #endif /* CONFIG_NFSD_V3 */ @@ -1388,14 +1378,13 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, * fits into the buffer. On return, it contains the true length. * N.B. After this call fhp needs an fh_put */ -__be32 +int nfsd_readlink(struct svc_rqst *rqstp, struct svc_fh *fhp, char *buf, int *lenp) { struct dentry *dentry; struct inode *inode; mm_segment_t oldfs; - __be32 err; - int host_err; + int err; err = fh_verify(rqstp, fhp, S_IFLNK, MAY_NOP); if (err) @@ -1414,18 +1403,18 @@ nfsd_readlink(struct svc_rqst *rqstp, struct svc_fh *fhp, char *buf, int *lenp) */ oldfs = get_fs(); set_fs(KERNEL_DS); - host_err = inode->i_op->readlink(dentry, buf, *lenp); + err = inode->i_op->readlink(dentry, buf, *lenp); set_fs(oldfs); - if (host_err < 0) + if (err < 0) goto out_nfserr; - *lenp = host_err; + *lenp = err; err = 0; out: return err; out_nfserr: - err = nfserrno(host_err); + err = nfserrno(err); goto out; } @@ -1433,7 +1422,7 @@ nfsd_readlink(struct svc_rqst *rqstp, struct svc_fh *fhp, char *buf, int *lenp) * Create a symlink and look up its inode * N.B. After this call _both_ fhp and resfhp need an fh_put */ -__be32 +int nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp, char *fname, int flen, char *path, int plen, @@ -1441,8 +1430,7 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap) { struct dentry *dentry, *dnew; - __be32 err, cerr; - int host_err; + int err, cerr; umode_t mode; err = nfserr_noent; @@ -1458,7 +1446,7 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp, fh_lock(fhp); dentry = fhp->fh_dentry; dnew = lookup_one_len(fname, dentry, flen); - host_err = PTR_ERR(dnew); + err = PTR_ERR(dnew); if (IS_ERR(dnew)) goto out_nfserr; @@ -1470,21 +1458,21 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp, if (unlikely(path[plen] != 0)) { char *path_alloced = kmalloc(plen+1, GFP_KERNEL); if (path_alloced == NULL) - host_err = -ENOMEM; + err = -ENOMEM; else { strncpy(path_alloced, path, plen); path_alloced[plen] = 0; - host_err = vfs_symlink(dentry->d_inode, dnew, path_alloced, mode); + err = vfs_symlink(dentry->d_inode, dnew, path_alloced, mode); kfree(path_alloced); } } else - host_err = vfs_symlink(dentry->d_inode, dnew, path, mode); + err = vfs_symlink(dentry->d_inode, dnew, path, mode); - if (!host_err) { + if (!err) if (EX_ISSYNC(fhp->fh_export)) - host_err = nfsd_sync_dir(dentry); - } - err = nfserrno(host_err); + err = nfsd_sync_dir(dentry); + if (err) + err = nfserrno(err); fh_unlock(fhp); cerr = fh_compose(resfhp, fhp->fh_export, dnew, fhp); @@ -1494,7 +1482,7 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp, return err; out_nfserr: - err = nfserrno(host_err); + err = nfserrno(err); goto out; } @@ -1502,14 +1490,13 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp, * Create a hardlink * N.B. After this call _both_ ffhp and tfhp need an fh_put */ -__be32 +int nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *name, int len, struct svc_fh *tfhp) { struct dentry *ddir, *dnew, *dold; struct inode *dirp, *dest; - __be32 err; - int host_err; + int err; err = fh_verify(rqstp, ffhp, S_IFDIR, MAY_CREATE); if (err) @@ -1530,25 +1517,24 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp, dirp = ddir->d_inode; dnew = lookup_one_len(name, ddir, len); - host_err = PTR_ERR(dnew); + err = PTR_ERR(dnew); if (IS_ERR(dnew)) goto out_nfserr; dold = tfhp->fh_dentry; dest = dold->d_inode; - host_err = vfs_link(dold, dirp, dnew); - if (!host_err) { + err = vfs_link(dold, dirp, dnew); + if (!err) { if (EX_ISSYNC(ffhp->fh_export)) { err = nfserrno(nfsd_sync_dir(ddir)); write_inode_now(dest, 1); } - err = 0; } else { - if (host_err == -EXDEV && rqstp->rq_vers == 2) + if (err == -EXDEV && rqstp->rq_vers == 2) err = nfserr_acces; else - err = nfserrno(host_err); + err = nfserrno(err); } dput(dnew); @@ -1558,7 +1544,7 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp, return err; out_nfserr: - err = nfserrno(host_err); + err = nfserrno(err); goto out_unlock; } @@ -1566,14 +1552,13 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp, * Rename a file * N.B. After this call _both_ ffhp and tfhp need an fh_put */ -__be32 +int nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen, struct svc_fh *tfhp, char *tname, int tlen) { struct dentry *fdentry, *tdentry, *odentry, *ndentry, *trap; struct inode *fdir, *tdir; - __be32 err; - int host_err; + int err; err = fh_verify(rqstp, ffhp, S_IFDIR, MAY_REMOVE); if (err) @@ -1604,22 +1589,22 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen, fill_pre_wcc(tfhp); odentry = lookup_one_len(fname, fdentry, flen); - host_err = PTR_ERR(odentry); + err = PTR_ERR(odentry); if (IS_ERR(odentry)) goto out_nfserr; - host_err = -ENOENT; + err = -ENOENT; if (!odentry->d_inode) goto out_dput_old; - host_err = -EINVAL; + err = -EINVAL; if (odentry == trap) goto out_dput_old; ndentry = lookup_one_len(tname, tdentry, tlen); - host_err = PTR_ERR(ndentry); + err = PTR_ERR(ndentry); if (IS_ERR(ndentry)) goto out_dput_old; - host_err = -ENOTEMPTY; + err = -ENOTEMPTY; if (ndentry == trap) goto out_dput_new; @@ -1627,14 +1612,14 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen, if ((ffhp->fh_export->ex_flags & NFSEXP_MSNFS) && ((atomic_read(&odentry->d_count) > 1) || (atomic_read(&ndentry->d_count) > 1))) { - host_err = -EPERM; + err = -EPERM; } else #endif - host_err = vfs_rename(fdir, odentry, tdir, ndentry); - if (!host_err && EX_ISSYNC(tfhp->fh_export)) { - host_err = nfsd_sync_dir(tdentry); - if (!host_err) - host_err = nfsd_sync_dir(fdentry); + err = vfs_rename(fdir, odentry, tdir, ndentry); + if (!err && EX_ISSYNC(tfhp->fh_export)) { + err = nfsd_sync_dir(tdentry); + if (!err) + err = nfsd_sync_dir(fdentry); } out_dput_new: @@ -1642,7 +1627,8 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen, out_dput_old: dput(odentry); out_nfserr: - err = nfserrno(host_err); + if (err) + err = nfserrno(err); /* we cannot reply on fh_unlock on the two filehandles, * as that would do the wrong thing if the two directories @@ -1661,14 +1647,13 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen, * Unlink a file or directory * N.B. After this call fhp needs an fh_put */ -__be32 +int nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, char *fname, int flen) { struct dentry *dentry, *rdentry; struct inode *dirp; - __be32 err; - int host_err; + int err; err = nfserr_acces; if (!flen || isdotent(fname, flen)) @@ -1682,7 +1667,7 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, dirp = dentry->d_inode; rdentry = lookup_one_len(fname, dentry, flen); - host_err = PTR_ERR(rdentry); + err = PTR_ERR(rdentry); if (IS_ERR(rdentry)) goto out_nfserr; @@ -1699,23 +1684,22 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, #ifdef MSNFS if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) && (atomic_read(&rdentry->d_count) > 1)) { - host_err = -EPERM; + err = -EPERM; } else #endif - host_err = vfs_unlink(dirp, rdentry); + err = vfs_unlink(dirp, rdentry); } else { /* It's RMDIR */ - host_err = vfs_rmdir(dirp, rdentry); + err = vfs_rmdir(dirp, rdentry); } dput(rdentry); - if (host_err) - goto out_nfserr; - if (EX_ISSYNC(fhp->fh_export)) - host_err = nfsd_sync_dir(dentry); + if (err == 0 && + EX_ISSYNC(fhp->fh_export)) + err = nfsd_sync_dir(dentry); out_nfserr: - err = nfserrno(host_err); + err = nfserrno(err); out: return err; } @@ -1724,12 +1708,11 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, * Read entries from a directory. * The NFSv3/4 verifier we ignore for now. */ -__be32 +int nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t *offsetp, struct readdir_cd *cdp, encode_dent_fn func) { - __be32 err; - int host_err; + int err; struct file *file; loff_t offset = *offsetp; @@ -1751,10 +1734,10 @@ nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t *offsetp, do { cdp->err = nfserr_eof; /* will be cleared on successful read */ - host_err = vfs_readdir(file, (filldir_t) func, cdp); - } while (host_err >=0 && cdp->err == nfs_ok); - if (host_err) - err = nfserrno(host_err); + err = vfs_readdir(file, (filldir_t) func, cdp); + } while (err >=0 && cdp->err == nfs_ok); + if (err) + err = nfserrno(err); else err = cdp->err; *offsetp = vfs_llseek(file, 0, 1); @@ -1771,10 +1754,10 @@ nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t *offsetp, * Get file system stats * N.B. After this call fhp needs an fh_put */ -__be32 +int nfsd_statfs(struct svc_rqst *rqstp, struct svc_fh *fhp, struct kstatfs *stat) { - __be32 err = fh_verify(rqstp, fhp, 0, MAY_NOP); + int err = fh_verify(rqstp, fhp, 0, MAY_NOP); if (!err && vfs_statfs(fhp->fh_dentry,stat)) err = nfserr_io; return err; @@ -1783,7 +1766,7 @@ nfsd_statfs(struct svc_rqst *rqstp, struct svc_fh *fhp, struct kstatfs *stat) /* * Check for a user's access permissions to this inode. */ -__be32 +int nfsd_permission(struct svc_export *exp, struct dentry *dentry, int acc) { struct inode *inode = dentry->d_inode; diff --git a/trunk/fs/ocfs2/cluster/nodemanager.c b/trunk/fs/ocfs2/cluster/nodemanager.c index d11753c50bc1..e1fceb8aa32d 100644 --- a/trunk/fs/ocfs2/cluster/nodemanager.c +++ b/trunk/fs/ocfs2/cluster/nodemanager.c @@ -152,16 +152,14 @@ static struct o2nm_node *o2nm_node_ip_tree_lookup(struct o2nm_cluster *cluster, struct o2nm_node *node, *ret = NULL; while (*p) { - int cmp; - parent = *p; node = rb_entry(parent, struct o2nm_node, nd_ip_node); - cmp = memcmp(&ip_needle, &node->nd_ipv4_address, - sizeof(ip_needle)); - if (cmp < 0) + if (memcmp(&ip_needle, &node->nd_ipv4_address, + sizeof(ip_needle)) < 0) p = &(*p)->rb_left; - else if (cmp > 0) + else if (memcmp(&ip_needle, &node->nd_ipv4_address, + sizeof(ip_needle)) > 0) p = &(*p)->rb_right; else { ret = node; diff --git a/trunk/fs/ocfs2/file.c b/trunk/fs/ocfs2/file.c index 1be74c4e7814..d9ba0a931a03 100644 --- a/trunk/fs/ocfs2/file.c +++ b/trunk/fs/ocfs2/file.c @@ -30,7 +30,6 @@ #include #include #include -#include #define MLOG_MASK_PREFIX ML_INODE #include @@ -692,12 +691,6 @@ static int ocfs2_zero_extend(struct inode *inode, } start_off += sb->s_blocksize; - - /* - * Very large extends have the potential to lock up - * the cpu for extended periods of time. - */ - cond_resched(); } out: @@ -735,36 +728,31 @@ static int ocfs2_extend_file(struct inode *inode, clusters_to_add = ocfs2_clusters_for_bytes(inode->i_sb, new_i_size) - OCFS2_I(inode)->ip_clusters; - /* - * protect the pages that ocfs2_zero_extend is going to be - * pulling into the page cache.. we do this before the - * metadata extend so that we don't get into the situation - * where we've extended the metadata but can't get the data - * lock to zero. - */ - ret = ocfs2_data_lock(inode, 1); - if (ret < 0) { - mlog_errno(ret); - goto out; - } - if (clusters_to_add) { + /* + * protect the pages that ocfs2_zero_extend is going to + * be pulling into the page cache.. we do this before the + * metadata extend so that we don't get into the situation + * where we've extended the metadata but can't get the data + * lock to zero. + */ + ret = ocfs2_data_lock(inode, 1); + if (ret < 0) { + mlog_errno(ret); + goto out; + } + ret = ocfs2_extend_allocation(inode, clusters_to_add); if (ret < 0) { mlog_errno(ret); goto out_unlock; } - } - /* - * Call this even if we don't add any clusters to the tree. We - * still need to zero the area between the old i_size and the - * new i_size. - */ - ret = ocfs2_zero_extend(inode, (u64)new_i_size - tail_to_skip); - if (ret < 0) { - mlog_errno(ret); - goto out_unlock; + ret = ocfs2_zero_extend(inode, (u64)new_i_size - tail_to_skip); + if (ret < 0) { + mlog_errno(ret); + goto out_unlock; + } } if (!tail_to_skip) { @@ -776,7 +764,8 @@ static int ocfs2_extend_file(struct inode *inode, } out_unlock: - ocfs2_data_unlock(inode, 1); + if (clusters_to_add) /* this is the only case in which we lock */ + ocfs2_data_unlock(inode, 1); out: return ret; diff --git a/trunk/fs/ocfs2/namei.c b/trunk/fs/ocfs2/namei.c index a57b751d4f40..259155f0eb2e 100644 --- a/trunk/fs/ocfs2/namei.c +++ b/trunk/fs/ocfs2/namei.c @@ -1085,6 +1085,14 @@ static int ocfs2_rename(struct inode *old_dir, BUG(); } + if (atomic_read(&old_dentry->d_count) > 2) { + shrink_dcache_parent(old_dentry); + if (atomic_read(&old_dentry->d_count) > 2) { + status = -EBUSY; + goto bail; + } + } + /* Assume a directory heirarchy thusly: * a/b/c * a/d diff --git a/trunk/fs/ocfs2/super.c b/trunk/fs/ocfs2/super.c index 76b46ebbb10c..4c29cd7cc8e6 100644 --- a/trunk/fs/ocfs2/super.c +++ b/trunk/fs/ocfs2/super.c @@ -339,7 +339,7 @@ static unsigned long long ocfs2_max_file_offset(unsigned int blockshift) #if BITS_PER_LONG == 32 # if defined(CONFIG_LBD) - BUILD_BUG_ON(sizeof(sector_t) != 8); + BUG_ON(sizeof(sector_t) != 8); pagefactor = PAGE_CACHE_SIZE; bitshift = BITS_PER_LONG; # else diff --git a/trunk/fs/partitions/check.c b/trunk/fs/partitions/check.c index 6fb4b6150d77..51c6a748df49 100644 --- a/trunk/fs/partitions/check.c +++ b/trunk/fs/partitions/check.c @@ -376,48 +376,18 @@ static char *make_block_name(struct gendisk *disk) return name; } -static int disk_sysfs_symlinks(struct gendisk *disk) +static void disk_sysfs_symlinks(struct gendisk *disk) { struct device *target = get_device(disk->driverfs_dev); - int err; - char *disk_name = NULL; - if (target) { - disk_name = make_block_name(disk); - if (!disk_name) { - err = -ENOMEM; - goto err_out; + char *disk_name = make_block_name(disk); + sysfs_create_link(&disk->kobj,&target->kobj,"device"); + if (disk_name) { + sysfs_create_link(&target->kobj,&disk->kobj,disk_name); + kfree(disk_name); } - - err = sysfs_create_link(&disk->kobj, &target->kobj, "device"); - if (err) - goto err_out_disk_name; - - err = sysfs_create_link(&target->kobj, &disk->kobj, disk_name); - if (err) - goto err_out_dev_link; } - - err = sysfs_create_link(&disk->kobj, &block_subsys.kset.kobj, - "subsystem"); - if (err) - goto err_out_disk_name_lnk; - - kfree(disk_name); - - return 0; - -err_out_disk_name_lnk: - if (target) { - sysfs_remove_link(&target->kobj, disk_name); -err_out_dev_link: - sysfs_remove_link(&disk->kobj, "device"); -err_out_disk_name: - kfree(disk_name); -err_out: - put_device(target); - } - return err; + sysfs_create_link(&disk->kobj, &block_subsys.kset.kobj, "subsystem"); } /* Not exported, helper to add_disk(). */ @@ -436,11 +406,7 @@ void register_disk(struct gendisk *disk) *s = '!'; if ((err = kobject_add(&disk->kobj))) return; - err = disk_sysfs_symlinks(disk); - if (err) { - kobject_del(&disk->kobj); - return; - } + disk_sysfs_symlinks(disk); disk_sysfs_add_subdirs(disk); /* No minors to use for partitions */ diff --git a/trunk/fs/partitions/msdos.c b/trunk/fs/partitions/msdos.c index 8c7af1777819..4f8df71e49d3 100644 --- a/trunk/fs/partitions/msdos.c +++ b/trunk/fs/partitions/msdos.c @@ -32,11 +32,13 @@ #include #define SYS_IND(p) (get_unaligned(&p->sys_ind)) -#define NR_SECTS(p) ({ __le32 __a = get_unaligned(&p->nr_sects); \ +#define NR_SECTS(p) ({ __typeof__(p->nr_sects) __a = \ + get_unaligned(&p->nr_sects); \ le32_to_cpu(__a); \ }) -#define START_SECT(p) ({ __le32 __a = get_unaligned(&p->start_sect); \ +#define START_SECT(p) ({ __typeof__(p->start_sect) __a = \ + get_unaligned(&p->start_sect); \ le32_to_cpu(__a); \ }) diff --git a/trunk/fs/proc/base.c b/trunk/fs/proc/base.c index 795319c54f72..82da55b5cffe 100644 --- a/trunk/fs/proc/base.c +++ b/trunk/fs/proc/base.c @@ -72,7 +72,6 @@ #include #include #include -#include #include "internal.h" /* NOTE: @@ -87,7 +86,7 @@ /* Worst case buffer size needed for holding an integer. */ -#define PROC_NUMBUF 13 +#define PROC_NUMBUF 10 struct pid_entry { int len; @@ -442,8 +441,7 @@ static int mountstats_open(struct inode *inode, struct file *file) if (task) { task_lock(task); - if (task->nsproxy) - namespace = task->nsproxy->namespace; + namespace = task->nsproxy->namespace; if (namespace) get_namespace(namespace); task_unlock(task); @@ -691,8 +689,7 @@ static ssize_t oom_adjust_write(struct file *file, const char __user *buf, if (copy_from_user(buffer, buf, count)) return -EFAULT; oom_adjust = simple_strtol(buffer, &end, 0); - if ((oom_adjust < OOM_ADJUST_MIN || oom_adjust > OOM_ADJUST_MAX) && - oom_adjust != OOM_DISABLE) + if ((oom_adjust < -16 || oom_adjust > 15) && oom_adjust != OOM_DISABLE) return -EINVAL; if (*end == '\n') end++; diff --git a/trunk/fs/proc/proc_misc.c b/trunk/fs/proc/proc_misc.c index 93c43b676e59..8d88e58ed5cc 100644 --- a/trunk/fs/proc/proc_misc.c +++ b/trunk/fs/proc/proc_misc.c @@ -647,7 +647,7 @@ static ssize_t write_sysrq_trigger(struct file *file, const char __user *buf, if (get_user(c, buf)) return -EFAULT; - __handle_sysrq(c, NULL, 0); + __handle_sysrq(c, NULL, NULL, 0); } return count; } diff --git a/trunk/fs/reiserfs/bitmap.c b/trunk/fs/reiserfs/bitmap.c index e3d466a228d4..1bfae42117ca 100644 --- a/trunk/fs/reiserfs/bitmap.c +++ b/trunk/fs/reiserfs/bitmap.c @@ -1304,8 +1304,8 @@ struct buffer_head *reiserfs_read_bitmap_block(struct super_block *sb, bh = sb_bread(sb, block); if (bh == NULL) - reiserfs_warning(sb, "sh-2029: %s: bitmap block (#%u) " - "reading failed", __FUNCTION__, block); + reiserfs_warning(sb, "sh-2029: %s: bitmap block (#%lu) " + "reading failed", __FUNCTION__, bh->b_blocknr); else { if (buffer_locked(bh)) { PROC_INFO_INC(sb, scan_bitmap.wait); diff --git a/trunk/fs/reiserfs/file.c b/trunk/fs/reiserfs/file.c index ac14318c81ba..b67ce9354048 100644 --- a/trunk/fs/reiserfs/file.c +++ b/trunk/fs/reiserfs/file.c @@ -74,8 +74,7 @@ static int reiserfs_file_release(struct inode *inode, struct file *filp) igrab(inode); reiserfs_warning(inode->i_sb, "pinning inode %lu because the " - "preallocation can't be freed", - inode->i_ino); + "preallocation can't be freed"); goto out; } } diff --git a/trunk/fs/reiserfs/journal.c b/trunk/fs/reiserfs/journal.c index ac93174c9639..ad8cbc49883a 100644 --- a/trunk/fs/reiserfs/journal.c +++ b/trunk/fs/reiserfs/journal.c @@ -53,7 +53,6 @@ #include #include #include -#include /* gets a struct reiserfs_journal_list * from a list head */ #define JOURNAL_LIST_ENTRY(h) (list_entry((h), struct reiserfs_journal_list, \ @@ -971,7 +970,7 @@ int reiserfs_async_progress_wait(struct super_block *s) DEFINE_WAIT(wait); struct reiserfs_journal *j = SB_JOURNAL(s); if (atomic_read(&j->j_async_throttle)) - congestion_wait(WRITE, HZ / 10); + blk_congestion_wait(WRITE, HZ / 10); return 0; } @@ -1464,7 +1463,7 @@ static int flush_journal_list(struct super_block *s, } /* if someone has this block in a newer transaction, just make - ** sure they are committed, and don't try writing it to disk + ** sure they are commited, and don't try writing it to disk */ if (pjl) { if (atomic_read(&pjl->j_commit_left)) @@ -3384,7 +3383,7 @@ static int remove_from_transaction(struct super_block *p_s_sb, /* ** for any cnode in a journal list, it can only be dirtied of all the -** transactions that include it are committed to disk. +** transactions that include it are commited to disk. ** this checks through each transaction, and returns 1 if you are allowed to dirty, ** and 0 if you aren't ** @@ -3426,7 +3425,7 @@ static int can_dirty(struct reiserfs_journal_cnode *cn) } /* syncs the commit blocks, but does not force the real buffers to disk -** will wait until the current transaction is done/committed before returning +** will wait until the current transaction is done/commited before returning */ int journal_end_sync(struct reiserfs_transaction_handle *th, struct super_block *p_s_sb, unsigned long nblocks) diff --git a/trunk/fs/reiserfs/super.c b/trunk/fs/reiserfs/super.c index 17249994110f..c89aa2338191 100644 --- a/trunk/fs/reiserfs/super.c +++ b/trunk/fs/reiserfs/super.c @@ -430,30 +430,21 @@ int remove_save_link(struct inode *inode, int truncate) return journal_end(&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT); } -static void reiserfs_kill_sb(struct super_block *s) -{ - if (REISERFS_SB(s)) { - if (REISERFS_SB(s)->xattr_root) { - d_invalidate(REISERFS_SB(s)->xattr_root); - dput(REISERFS_SB(s)->xattr_root); - REISERFS_SB(s)->xattr_root = NULL; - } - - if (REISERFS_SB(s)->priv_root) { - d_invalidate(REISERFS_SB(s)->priv_root); - dput(REISERFS_SB(s)->priv_root); - REISERFS_SB(s)->priv_root = NULL; - } - } - - kill_block_super(s); -} - static void reiserfs_put_super(struct super_block *s) { struct reiserfs_transaction_handle th; th.t_trans_id = 0; + if (REISERFS_SB(s)->xattr_root) { + d_invalidate(REISERFS_SB(s)->xattr_root); + dput(REISERFS_SB(s)->xattr_root); + } + + if (REISERFS_SB(s)->priv_root) { + d_invalidate(REISERFS_SB(s)->priv_root); + dput(REISERFS_SB(s)->priv_root); + } + /* change file system state to current state if it was mounted with read-write permissions */ if (!(s->s_flags & MS_RDONLY)) { if (!journal_begin(&th, s, 10)) { @@ -1619,7 +1610,6 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) "jmacd-8: reiserfs_fill_super: unable to read bitmap"); goto error; } - errval = -EINVAL; #ifdef CONFIG_REISERFS_CHECK SWARN(silent, s, "CONFIG_REISERFS_CHECK is set ON"); SWARN(silent, s, "- it is slow mode for debugging."); @@ -2166,7 +2156,7 @@ struct file_system_type reiserfs_fs_type = { .owner = THIS_MODULE, .name = "reiserfs", .get_sb = get_super_block, - .kill_sb = reiserfs_kill_sb, + .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; diff --git a/trunk/fs/splice.c b/trunk/fs/splice.c index da74583a00ee..13e92dd19fbb 100644 --- a/trunk/fs/splice.c +++ b/trunk/fs/splice.c @@ -74,7 +74,7 @@ static int page_cache_pipe_buf_steal(struct pipe_inode_info *pipe, wait_on_page_writeback(page); if (PagePrivate(page)) - try_to_release_page(page, GFP_KERNEL); + try_to_release_page(page, mapping_gfp_mask(mapping)); /* * If we succeeded in removing the mapping, set LRU flag @@ -333,7 +333,7 @@ __generic_file_splice_read(struct file *in, loff_t *ppos, break; error = add_to_page_cache_lru(page, mapping, index, - GFP_KERNEL); + mapping_gfp_mask(mapping)); if (unlikely(error)) { page_cache_release(page); if (error == -EEXIST) @@ -557,6 +557,7 @@ static int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf, { struct file *file = sd->file; struct address_space *mapping = file->f_mapping; + gfp_t gfp_mask = mapping_gfp_mask(mapping); unsigned int offset, this_len; struct page *page; pgoff_t index; @@ -590,7 +591,7 @@ static int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf, goto find_page; page = buf->page; - if (add_to_page_cache(page, mapping, index, GFP_KERNEL)) { + if (add_to_page_cache(page, mapping, index, gfp_mask)) { unlock_page(page); goto find_page; } @@ -606,13 +607,13 @@ static int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf, ret = -ENOMEM; page = page_cache_alloc_cold(mapping); if (unlikely(!page)) - goto out_ret; + goto out_nomem; /* * This will also lock the page */ ret = add_to_page_cache_lru(page, mapping, index, - GFP_KERNEL); + gfp_mask); if (unlikely(ret)) goto out; } @@ -665,7 +666,7 @@ static int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf, if (sd->pos + this_len > isize) vmtruncate(mapping->host, isize); - goto out_ret; + goto out; } if (buf->page != page) { @@ -697,7 +698,7 @@ static int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf, out: page_cache_release(page); unlock_page(page); -out_ret: +out_nomem: return ret; } @@ -706,9 +707,9 @@ static int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf, * key here is the 'actor' worker passed in that actually moves the data * to the wanted destination. See pipe_to_file/pipe_to_sendpage above. */ -static ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, - struct file *out, loff_t *ppos, size_t len, - unsigned int flags, splice_actor *actor) +ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out, + loff_t *ppos, size_t len, unsigned int flags, + splice_actor *actor) { int ret, do_wakeup, err; struct splice_desc sd; @@ -721,6 +722,9 @@ static ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, sd.file = out; sd.pos = *ppos; + if (pipe->inode) + mutex_lock(&pipe->inode->i_mutex); + for (;;) { if (pipe->nrbufs) { struct pipe_buffer *buf = pipe->bufs + pipe->curbuf; @@ -793,6 +797,9 @@ static ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, pipe_wait(pipe); } + if (pipe->inode) + mutex_unlock(&pipe->inode->i_mutex); + if (do_wakeup) { smp_mb(); if (waitqueue_active(&pipe->wait)) @@ -803,73 +810,6 @@ static ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, return ret; } -ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out, - loff_t *ppos, size_t len, unsigned int flags, - splice_actor *actor) -{ - ssize_t ret; - struct inode *inode = out->f_mapping->host; - - /* - * The actor worker might be calling ->prepare_write and - * ->commit_write. Most of the time, these expect i_mutex to - * be held. Since this may result in an ABBA deadlock with - * pipe->inode, we have to order lock acquiry here. - */ - inode_double_lock(inode, pipe->inode); - ret = __splice_from_pipe(pipe, out, ppos, len, flags, actor); - inode_double_unlock(inode, pipe->inode); - - return ret; -} - -/** - * generic_file_splice_write_nolock - generic_file_splice_write without mutexes - * @pipe: pipe info - * @out: file to write to - * @len: number of bytes to splice - * @flags: splice modifier flags - * - * Will either move or copy pages (determined by @flags options) from - * the given pipe inode to the given file. The caller is responsible - * for acquiring i_mutex on both inodes. - * - */ -ssize_t -generic_file_splice_write_nolock(struct pipe_inode_info *pipe, struct file *out, - loff_t *ppos, size_t len, unsigned int flags) -{ - struct address_space *mapping = out->f_mapping; - struct inode *inode = mapping->host; - ssize_t ret; - int err; - - err = remove_suid(out->f_dentry); - if (unlikely(err)) - return err; - - ret = __splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_file); - if (ret > 0) { - *ppos += ret; - - /* - * If file or inode is SYNC and we actually wrote some data, - * sync it. - */ - if (unlikely((out->f_flags & O_SYNC) || IS_SYNC(inode))) { - err = generic_osync_inode(inode, mapping, - OSYNC_METADATA|OSYNC_DATA); - - if (err) - ret = err; - } - } - - return ret; -} - -EXPORT_SYMBOL(generic_file_splice_write_nolock); - /** * generic_file_splice_write - splice data from a pipe to a file * @pipe: pipe info @@ -886,21 +826,12 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out, loff_t *ppos, size_t len, unsigned int flags) { struct address_space *mapping = out->f_mapping; - struct inode *inode = mapping->host; ssize_t ret; - int err; - - err = should_remove_suid(out->f_dentry); - if (unlikely(err)) { - mutex_lock(&inode->i_mutex); - err = __remove_suid(out->f_dentry, err); - mutex_unlock(&inode->i_mutex); - if (err) - return err; - } ret = splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_file); if (ret > 0) { + struct inode *inode = mapping->host; + *ppos += ret; /* @@ -908,6 +839,8 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out, * sync it. */ if (unlikely((out->f_flags & O_SYNC) || IS_SYNC(inode))) { + int err; + mutex_lock(&inode->i_mutex); err = generic_osync_inode(inode, mapping, OSYNC_METADATA|OSYNC_DATA); @@ -1108,19 +1041,6 @@ long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, EXPORT_SYMBOL(do_splice_direct); -/* - * After the inode slimming patch, i_pipe/i_bdev/i_cdev share the same - * location, so checking ->i_pipe is not enough to verify that this is a - * pipe. - */ -static inline struct pipe_inode_info *pipe_info(struct inode *inode) -{ - if (S_ISFIFO(inode->i_mode)) - return inode->i_pipe; - - return NULL; -} - /* * Determine where to splice to/from. */ @@ -1132,7 +1052,7 @@ static long do_splice(struct file *in, loff_t __user *off_in, loff_t offset, *off; long ret; - pipe = pipe_info(in->f_dentry->d_inode); + pipe = in->f_dentry->d_inode->i_pipe; if (pipe) { if (off_in) return -ESPIPE; @@ -1153,7 +1073,7 @@ static long do_splice(struct file *in, loff_t __user *off_in, return ret; } - pipe = pipe_info(out->f_dentry->d_inode); + pipe = out->f_dentry->d_inode->i_pipe; if (pipe) { if (off_out) return -ESPIPE; @@ -1311,7 +1231,7 @@ static int get_iovec_page_array(const struct iovec __user *iov, static long do_vmsplice(struct file *file, const struct iovec __user *iov, unsigned long nr_segs, unsigned int flags) { - struct pipe_inode_info *pipe; + struct pipe_inode_info *pipe = file->f_dentry->d_inode->i_pipe; struct page *pages[PIPE_BUFFERS]; struct partial_page partial[PIPE_BUFFERS]; struct splice_pipe_desc spd = { @@ -1321,8 +1241,7 @@ static long do_vmsplice(struct file *file, const struct iovec __user *iov, .ops = &user_page_pipe_buf_ops, }; - pipe = pipe_info(file->f_dentry->d_inode); - if (!pipe) + if (unlikely(!pipe)) return -EBADF; if (unlikely(nr_segs > UIO_MAXIOV)) return -EINVAL; @@ -1481,7 +1400,13 @@ static int link_pipe(struct pipe_inode_info *ipipe, * grabbing by inode address. Otherwise two different processes * could deadlock (one doing tee from A -> B, the other from B -> A). */ - inode_double_lock(ipipe->inode, opipe->inode); + if (ipipe->inode < opipe->inode) { + mutex_lock_nested(&ipipe->inode->i_mutex, I_MUTEX_PARENT); + mutex_lock_nested(&opipe->inode->i_mutex, I_MUTEX_CHILD); + } else { + mutex_lock_nested(&opipe->inode->i_mutex, I_MUTEX_PARENT); + mutex_lock_nested(&ipipe->inode->i_mutex, I_MUTEX_CHILD); + } do { if (!opipe->readers) { @@ -1525,7 +1450,8 @@ static int link_pipe(struct pipe_inode_info *ipipe, i++; } while (len); - inode_double_unlock(ipipe->inode, opipe->inode); + mutex_unlock(&ipipe->inode->i_mutex); + mutex_unlock(&opipe->inode->i_mutex); /* * If we put data in the output pipe, wakeup any potential readers. @@ -1549,8 +1475,8 @@ static int link_pipe(struct pipe_inode_info *ipipe, static long do_tee(struct file *in, struct file *out, size_t len, unsigned int flags) { - struct pipe_inode_info *ipipe = pipe_info(in->f_dentry->d_inode); - struct pipe_inode_info *opipe = pipe_info(out->f_dentry->d_inode); + struct pipe_inode_info *ipipe = in->f_dentry->d_inode->i_pipe; + struct pipe_inode_info *opipe = out->f_dentry->d_inode->i_pipe; int ret = -EINVAL; /* diff --git a/trunk/fs/super.c b/trunk/fs/super.c index 47e554c12e76..aec99ddbe53f 100644 --- a/trunk/fs/super.c +++ b/trunk/fs/super.c @@ -260,17 +260,17 @@ int fsync_super(struct super_block *sb) * that need destruction out of superblock, call generic_shutdown_super() * and release aforementioned objects. Note: dentries and inodes _are_ * taken care of and do not need specific handling. - * - * Upon calling this function, the filesystem may no longer alter or - * rearrange the set of dentries belonging to this super_block, nor may it - * change the attachments of dentries to inodes. */ void generic_shutdown_super(struct super_block *sb) { + struct dentry *root = sb->s_root; struct super_operations *sop = sb->s_op; - if (sb->s_root) { - shrink_dcache_for_umount(sb); + if (root) { + sb->s_root = NULL; + shrink_dcache_parent(root); + shrink_dcache_sb(sb); + dput(root); fsync_super(sb); lock_super(sb); sb->s_flags &= ~MS_ACTIVE; diff --git a/trunk/fs/sysfs/dir.c b/trunk/fs/sysfs/dir.c index a5782e8c7f07..3aa3434621ca 100644 --- a/trunk/fs/sysfs/dir.c +++ b/trunk/fs/sysfs/dir.c @@ -372,51 +372,6 @@ int sysfs_rename_dir(struct kobject * kobj, const char *new_name) return error; } -int sysfs_move_dir(struct kobject *kobj, struct kobject *new_parent) -{ - struct dentry *old_parent_dentry, *new_parent_dentry, *new_dentry; - struct sysfs_dirent *new_parent_sd, *sd; - int error; - - if (!new_parent) - return -EINVAL; - - old_parent_dentry = kobj->parent ? - kobj->parent->dentry : sysfs_mount->mnt_sb->s_root; - new_parent_dentry = new_parent->dentry; - -again: - mutex_lock(&old_parent_dentry->d_inode->i_mutex); - if (!mutex_trylock(&new_parent_dentry->d_inode->i_mutex)) { - mutex_unlock(&old_parent_dentry->d_inode->i_mutex); - goto again; - } - - new_parent_sd = new_parent_dentry->d_fsdata; - sd = kobj->dentry->d_fsdata; - - new_dentry = lookup_one_len(kobj->name, new_parent_dentry, - strlen(kobj->name)); - if (IS_ERR(new_dentry)) { - error = PTR_ERR(new_dentry); - goto out; - } else - error = 0; - d_add(new_dentry, NULL); - d_move(kobj->dentry, new_dentry); - dput(new_dentry); - - /* Remove from old parent's list and insert into new parent's list. */ - list_del_init(&sd->s_sibling); - list_add(&sd->s_sibling, &new_parent_sd->s_children); - -out: - mutex_unlock(&new_parent_dentry->d_inode->i_mutex); - mutex_unlock(&old_parent_dentry->d_inode->i_mutex); - - return error; -} - static int sysfs_dir_open(struct inode *inode, struct file *file) { struct dentry * dentry = file->f_dentry; diff --git a/trunk/fs/sysfs/file.c b/trunk/fs/sysfs/file.c index 95c165101c98..146f1dedec84 100644 --- a/trunk/fs/sysfs/file.c +++ b/trunk/fs/sysfs/file.c @@ -190,9 +190,6 @@ fill_write_buffer(struct sysfs_buffer * buffer, const char __user * buf, size_t count = PAGE_SIZE - 1; error = copy_from_user(buffer->page,buf,count); buffer->needs_read_fill = 1; - /* if buf is assumed to contain a string, terminate it by \0, - so e.g. sscanf() can scan the string easily */ - buffer->page[count] = 0; return error ? -EFAULT : count; } @@ -486,12 +483,17 @@ int sysfs_update_file(struct kobject * kobj, const struct attribute * attr) (victim->d_parent->d_inode == dir->d_inode)) { victim->d_inode->i_mtime = CURRENT_TIME; fsnotify_modify(victim); + + /** + * Drop reference from initial sysfs_get_dentry(). + */ + dput(victim); res = 0; } else d_drop(victim); /** - * Drop the reference acquired from lookup_one_len() above. + * Drop the reference acquired from sysfs_get_dentry() above. */ dput(victim); } diff --git a/trunk/fs/sysv/super.c b/trunk/fs/sysv/super.c index dc9e7dc07fb7..350cba5d6803 100644 --- a/trunk/fs/sysv/super.c +++ b/trunk/fs/sysv/super.c @@ -358,11 +358,16 @@ static int sysv_fill_super(struct super_block *sb, void *data, int silent) unsigned long blocknr; int size = 0, i; - BUILD_BUG_ON(1024 != sizeof (struct xenix_super_block)); - BUILD_BUG_ON(512 != sizeof (struct sysv4_super_block)); - BUILD_BUG_ON(512 != sizeof (struct sysv2_super_block)); - BUILD_BUG_ON(500 != sizeof (struct coh_super_block)); - BUILD_BUG_ON(64 != sizeof (struct sysv_inode)); + if (1024 != sizeof (struct xenix_super_block)) + panic("Xenix FS: bad superblock size"); + if (512 != sizeof (struct sysv4_super_block)) + panic("SystemV FS: bad superblock size"); + if (512 != sizeof (struct sysv2_super_block)) + panic("SystemV FS: bad superblock size"); + if (500 != sizeof (struct coh_super_block)) + panic("Coherent FS: bad superblock size"); + if (64 != sizeof (struct sysv_inode)) + panic("sysv fs: bad inode size"); sbi = kzalloc(sizeof(struct sysv_sb_info), GFP_KERNEL); if (!sbi) diff --git a/trunk/fs/udf/super.c b/trunk/fs/udf/super.c index 1aea6a4f9a4a..1d3b5d2070e5 100644 --- a/trunk/fs/udf/super.c +++ b/trunk/fs/udf/super.c @@ -1621,10 +1621,9 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) goto error_out; } - if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_READ_ONLY) { + if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_READ_ONLY) printk("UDF-fs: Partition marked readonly; forcing readonly mount\n"); sb->s_flags |= MS_RDONLY; - } if ( udf_find_fileset(sb, &fileset, &rootdir) ) { diff --git a/trunk/fs/ufs/util.c b/trunk/fs/ufs/util.c index 17437574f79c..22f820a9b15c 100644 --- a/trunk/fs/ufs/util.c +++ b/trunk/fs/ufs/util.c @@ -184,13 +184,14 @@ void _ubh_memcpyubh_(struct ufs_sb_private_info * uspi, dev_t ufs_get_inode_dev(struct super_block *sb, struct ufs_inode_info *ufsi) { - __u32 fs32; + __fs32 fs32; dev_t dev; if ((UFS_SB(sb)->s_flags & UFS_ST_MASK) == UFS_ST_SUNx86) - fs32 = fs32_to_cpu(sb, ufsi->i_u1.i_data[1]); + fs32 = ufsi->i_u1.i_data[1]; else - fs32 = fs32_to_cpu(sb, ufsi->i_u1.i_data[0]); + fs32 = ufsi->i_u1.i_data[0]; + fs32 = fs32_to_cpu(sb, fs32); switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) { case UFS_ST_SUNx86: case UFS_ST_SUN: @@ -211,7 +212,7 @@ ufs_get_inode_dev(struct super_block *sb, struct ufs_inode_info *ufsi) void ufs_set_inode_dev(struct super_block *sb, struct ufs_inode_info *ufsi, dev_t dev) { - __u32 fs32; + __fs32 fs32; switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) { case UFS_ST_SUNx86: @@ -226,10 +227,11 @@ ufs_set_inode_dev(struct super_block *sb, struct ufs_inode_info *ufsi, dev_t dev fs32 = old_encode_dev(dev); break; } + fs32 = cpu_to_fs32(sb, fs32); if ((UFS_SB(sb)->s_flags & UFS_ST_MASK) == UFS_ST_SUNx86) - ufsi->i_u1.i_data[1] = cpu_to_fs32(sb, fs32); + ufsi->i_u1.i_data[1] = fs32; else - ufsi->i_u1.i_data[0] = cpu_to_fs32(sb, fs32); + ufsi->i_u1.i_data[0] = fs32; } /** diff --git a/trunk/fs/vfat/namei.c b/trunk/fs/vfat/namei.c index 0afd745a37cd..edb711ff7b05 100644 --- a/trunk/fs/vfat/namei.c +++ b/trunk/fs/vfat/namei.c @@ -1004,7 +1004,6 @@ static struct inode_operations vfat_dir_inode_operations = { .rmdir = vfat_rmdir, .rename = vfat_rename, .setattr = fat_notify_change, - .getattr = fat_getattr, }; static int vfat_fill_super(struct super_block *sb, void *data, int silent) diff --git a/trunk/fs/xattr.c b/trunk/fs/xattr.c index 0901bdc2ce24..c32f15b5f60f 100644 --- a/trunk/fs/xattr.c +++ b/trunk/fs/xattr.c @@ -48,21 +48,14 @@ xattr_permission(struct inode *inode, const char *name, int mask) return 0; /* - * The trusted.* namespace can only be accessed by a privileged user. + * The trusted.* namespace can only accessed by a privilegued user. */ if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN)) return (capable(CAP_SYS_ADMIN) ? 0 : -EPERM); - /* In user.* namespace, only regular files and directories can have - * extended attributes. For sticky directories, only the owner and - * privileged user can write attributes. - */ if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) { - if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode)) - return -EPERM; - if (S_ISDIR(inode->i_mode) && (inode->i_mode & S_ISVTX) && - (mask & MAY_WRITE) && (current->fsuid != inode->i_uid) && - !capable(CAP_FOWNER)) + if (!S_ISREG(inode->i_mode) && + (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX)) return -EPERM; } @@ -142,26 +135,6 @@ vfs_getxattr(struct dentry *dentry, char *name, void *value, size_t size) } EXPORT_SYMBOL_GPL(vfs_getxattr); -ssize_t -vfs_listxattr(struct dentry *d, char *list, size_t size) -{ - ssize_t error; - - error = security_inode_listxattr(d); - if (error) - return error; - error = -EOPNOTSUPP; - if (d->d_inode->i_op && d->d_inode->i_op->listxattr) { - error = d->d_inode->i_op->listxattr(d, list, size); - } else { - error = security_inode_listsecurity(d->d_inode, list, size); - if (size && error > size) - error = -ERANGE; - } - return error; -} -EXPORT_SYMBOL_GPL(vfs_listxattr); - int vfs_removexattr(struct dentry *dentry, char *name) { @@ -373,7 +346,17 @@ listxattr(struct dentry *d, char __user *list, size_t size) return -ENOMEM; } - error = vfs_listxattr(d, klist, size); + error = security_inode_listxattr(d); + if (error) + goto out; + error = -EOPNOTSUPP; + if (d->d_inode->i_op && d->d_inode->i_op->listxattr) { + error = d->d_inode->i_op->listxattr(d, klist, size); + } else { + error = security_inode_listsecurity(d->d_inode, klist, size); + if (size && error > size) + error = -ERANGE; + } if (error > 0) { if (size && copy_to_user(list, klist, error)) error = -EFAULT; @@ -382,6 +365,7 @@ listxattr(struct dentry *d, char __user *list, size_t size) than XATTR_LIST_MAX bytes. Not possible. */ error = -E2BIG; } +out: kfree(klist); return error; } diff --git a/trunk/fs/xfs/Makefile-linux-2.6 b/trunk/fs/xfs/Makefile-linux-2.6 index b49989bb89ad..291948d5085a 100644 --- a/trunk/fs/xfs/Makefile-linux-2.6 +++ b/trunk/fs/xfs/Makefile-linux-2.6 @@ -21,7 +21,22 @@ EXTRA_CFLAGS += -Ifs/xfs -Ifs/xfs/linux-2.6 -funsigned-char XFS_LINUX := linux-2.6 ifeq ($(CONFIG_XFS_DEBUG),y) - EXTRA_CFLAGS += -g + EXTRA_CFLAGS += -g -DSTATIC="" -DDEBUG + EXTRA_CFLAGS += -DXFS_BUF_LOCK_TRACKING +endif +ifeq ($(CONFIG_XFS_TRACE),y) + EXTRA_CFLAGS += -DXFS_ALLOC_TRACE + EXTRA_CFLAGS += -DXFS_ATTR_TRACE + EXTRA_CFLAGS += -DXFS_BLI_TRACE + EXTRA_CFLAGS += -DXFS_BMAP_TRACE + EXTRA_CFLAGS += -DXFS_BMBT_TRACE + EXTRA_CFLAGS += -DXFS_DIR2_TRACE + EXTRA_CFLAGS += -DXFS_DQUOT_TRACE + EXTRA_CFLAGS += -DXFS_ILOCK_TRACE + EXTRA_CFLAGS += -DXFS_LOG_TRACE + EXTRA_CFLAGS += -DXFS_RW_TRACE + EXTRA_CFLAGS += -DXFS_BUF_TRACE + EXTRA_CFLAGS += -DXFS_VNODE_TRACE endif obj-$(CONFIG_XFS_FS) += xfs.o diff --git a/trunk/fs/xfs/linux-2.6/kmem.c b/trunk/fs/xfs/linux-2.6/kmem.c index 004baf600611..d59737589815 100644 --- a/trunk/fs/xfs/linux-2.6/kmem.c +++ b/trunk/fs/xfs/linux-2.6/kmem.c @@ -21,7 +21,6 @@ #include #include #include -#include #include "time.h" #include "kmem.h" @@ -54,7 +53,7 @@ kmem_alloc(size_t size, unsigned int __nocast flags) printk(KERN_ERR "XFS: possible memory allocation " "deadlock in %s (mode:0x%x)\n", __FUNCTION__, lflags); - congestion_wait(WRITE, HZ/50); + blk_congestion_wait(WRITE, HZ/50); } while (1); } @@ -132,7 +131,7 @@ kmem_zone_alloc(kmem_zone_t *zone, unsigned int __nocast flags) printk(KERN_ERR "XFS: possible memory allocation " "deadlock in %s (mode:0x%x)\n", __FUNCTION__, lflags); - congestion_wait(WRITE, HZ/50); + blk_congestion_wait(WRITE, HZ/50); } while (1); } diff --git a/trunk/fs/xfs/linux-2.6/xfs_buf.c b/trunk/fs/xfs/linux-2.6/xfs_buf.c index d3382843698e..9bbadafdcb00 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_buf.c +++ b/trunk/fs/xfs/linux-2.6/xfs_buf.c @@ -15,7 +15,6 @@ * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "xfs.h" #include #include #include @@ -31,7 +30,7 @@ #include #include #include -#include +#include "xfs_linux.h" STATIC kmem_zone_t *xfs_buf_zone; STATIC kmem_shaker_t xfs_buf_shake; @@ -396,7 +395,7 @@ _xfs_buf_lookup_pages( XFS_STATS_INC(xb_page_retries); xfsbufd_wakeup(0, gfp_mask); - congestion_wait(WRITE, HZ/50); + blk_congestion_wait(WRITE, HZ/50); goto retry; } @@ -1406,7 +1405,7 @@ xfs_alloc_bufhash( btp->bt_hashshift = external ? 3 : 8; /* 8 or 256 buckets */ btp->bt_hashmask = (1 << btp->bt_hashshift) - 1; btp->bt_hash = kmem_zalloc((1 << btp->bt_hashshift) * - sizeof(xfs_bufhash_t), KM_SLEEP | KM_LARGE); + sizeof(xfs_bufhash_t), KM_SLEEP); for (i = 0; i < (1 << btp->bt_hashshift); i++) { spin_lock_init(&btp->bt_hash[i].bh_lock); INIT_LIST_HEAD(&btp->bt_hash[i].bh_list); diff --git a/trunk/fs/xfs/linux-2.6/xfs_dmapi_priv.h b/trunk/fs/xfs/linux-2.6/xfs_dmapi_priv.h deleted file mode 100644 index a8b0b1685eed..000000000000 --- a/trunk/fs/xfs/linux-2.6/xfs_dmapi_priv.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2000-2006 Silicon Graphics, Inc. - * All Rights Reserved. - * - * 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. - * - * This program is distributed in the hope that it would 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 the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ -#ifndef __XFS_DMAPI_PRIV_H__ -#define __XFS_DMAPI_PRIV_H__ - -/* - * Based on IO_ISDIRECT, decide which i_ flag is set. - */ -#define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \ - DM_FLAGS_IMUX : 0) -#define DM_SEM_FLAG_WR (DM_FLAGS_IALLOCSEM_WR | DM_FLAGS_IMUX) - -#endif /*__XFS_DMAPI_PRIV_H__*/ diff --git a/trunk/fs/xfs/linux-2.6/xfs_ioctl.c b/trunk/fs/xfs/linux-2.6/xfs_ioctl.c index 74d094829a4d..a74f854d91e6 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_ioctl.c +++ b/trunk/fs/xfs/linux-2.6/xfs_ioctl.c @@ -341,11 +341,8 @@ xfs_open_by_handle( put_unused_fd(new_fd); return -XFS_ERROR(-PTR_ERR(filp)); } - if (inode->i_mode & S_IFREG) { - /* invisible operation should not change atime */ - filp->f_flags |= O_NOATIME; + if (inode->i_mode & S_IFREG) filp->f_op = &xfs_invis_file_operations; - } fd_install(new_fd, filp); return new_fd; diff --git a/trunk/fs/xfs/linux-2.6/xfs_super.c b/trunk/fs/xfs/linux-2.6/xfs_super.c index de05abbbe7fd..38c4d128a8c0 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_super.c +++ b/trunk/fs/xfs/linux-2.6/xfs_super.c @@ -227,7 +227,9 @@ xfs_initialize_vnode( xfs_revalidate_inode(XFS_BHVTOM(bdp), vp, ip); xfs_set_inodeops(inode); - xfs_iflags_clear(ip, XFS_INEW); + spin_lock(&ip->i_flags_lock); + ip->i_flags &= ~XFS_INEW; + spin_unlock(&ip->i_flags_lock); barrier(); unlock_new_inode(inode); diff --git a/trunk/fs/xfs/support/debug.c b/trunk/fs/xfs/support/debug.c index 4363512d2f90..c75f68361e33 100644 --- a/trunk/fs/xfs/support/debug.c +++ b/trunk/fs/xfs/support/debug.c @@ -15,9 +15,11 @@ * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include #include "debug.h" #include "spin.h" +#include +#include +#include static char message[256]; /* keep it off the stack */ static DEFINE_SPINLOCK(xfs_err_lock); diff --git a/trunk/fs/xfs/support/move.c b/trunk/fs/xfs/support/move.c index ac8617ca3909..caefa17b80fe 100644 --- a/trunk/fs/xfs/support/move.c +++ b/trunk/fs/xfs/support/move.c @@ -22,7 +22,7 @@ * as we go. */ int -xfs_uio_read(caddr_t src, size_t len, struct uio *uio) +uio_read(caddr_t src, size_t len, struct uio *uio) { size_t count; diff --git a/trunk/fs/xfs/support/move.h b/trunk/fs/xfs/support/move.h index 977879c24ff5..97a2498d2da3 100644 --- a/trunk/fs/xfs/support/move.h +++ b/trunk/fs/xfs/support/move.h @@ -65,6 +65,6 @@ struct uio { typedef struct uio uio_t; typedef struct iovec iovec_t; -extern int xfs_uio_read (caddr_t, size_t, uio_t *); +extern int uio_read (caddr_t, size_t, uio_t *); #endif /* __XFS_SUPPORT_MOVE_H__ */ diff --git a/trunk/fs/xfs/xfs.h b/trunk/fs/xfs/xfs.h index bf0a12040b13..1a48dbb902a7 100644 --- a/trunk/fs/xfs/xfs.h +++ b/trunk/fs/xfs/xfs.h @@ -17,28 +17,5 @@ */ #ifndef __XFS_H__ #define __XFS_H__ - -#ifdef CONFIG_XFS_DEBUG -#define STATIC -#define DEBUG 1 -#define XFS_BUF_LOCK_TRACKING 1 -/* #define QUOTADEBUG 1 */ -#endif - -#ifdef CONFIG_XFS_TRACE -#define XFS_ALLOC_TRACE 1 -#define XFS_ATTR_TRACE 1 -#define XFS_BLI_TRACE 1 -#define XFS_BMAP_TRACE 1 -#define XFS_BMBT_TRACE 1 -#define XFS_DIR2_TRACE 1 -#define XFS_DQUOT_TRACE 1 -#define XFS_ILOCK_TRACE 1 -#define XFS_LOG_TRACE 1 -#define XFS_RW_TRACE 1 -#define XFS_BUF_TRACE 1 -#define XFS_VNODE_TRACE 1 -#endif - #include #endif /* __XFS_H__ */ diff --git a/trunk/fs/xfs/xfs_bmap.c b/trunk/fs/xfs/xfs_bmap.c index 498ad50d1f45..5b050c06795f 100644 --- a/trunk/fs/xfs/xfs_bmap.c +++ b/trunk/fs/xfs/xfs_bmap.c @@ -1171,8 +1171,6 @@ xfs_bmap_add_extent_delay_real( xfs_bmap_trace_pre_update(fname, "0", ip, idx, XFS_DATA_FORK); xfs_bmbt_set_blockcount(ep, temp); r[0] = *new; - r[1].br_state = PREV.br_state; - r[1].br_startblock = 0; r[1].br_startoff = new_endoff; temp2 = PREV.br_startoff + PREV.br_blockcount - new_endoff; r[1].br_blockcount = temp2; diff --git a/trunk/fs/xfs/xfs_dir2.c b/trunk/fs/xfs/xfs_dir2.c index 8e8e5279334a..8edbe1adb95b 100644 --- a/trunk/fs/xfs/xfs_dir2.c +++ b/trunk/fs/xfs/xfs_dir2.c @@ -678,7 +678,7 @@ xfs_dir2_put_dirent64_uio( idbp->d_off = pa->cook; idbp->d_name[namelen] = '\0'; memcpy(idbp->d_name, pa->name, namelen); - rval = xfs_uio_read((caddr_t)idbp, reclen, uio); + rval = uio_read((caddr_t)idbp, reclen, uio); pa->done = (rval == 0); return rval; } diff --git a/trunk/fs/xfs/xfs_dmapi.h b/trunk/fs/xfs/xfs_dmapi.h index adc3d251240d..4e7865ad6f0e 100644 --- a/trunk/fs/xfs/xfs_dmapi.h +++ b/trunk/fs/xfs/xfs_dmapi.h @@ -157,9 +157,27 @@ typedef enum { #define DM_FLAGS_IALLOCSEM_WR 0x020 /* thread holds i_alloc_sem wr */ /* - * Pull in platform specific event flags defines + * Based on IO_ISDIRECT, decide which i_ flag is set. */ -#include "xfs_dmapi_priv.h" +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) +#define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \ + DM_FLAGS_IMUX : 0) +#define DM_SEM_FLAG_WR (DM_FLAGS_IALLOCSEM_WR | DM_FLAGS_IMUX) +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) && \ + (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)) +#define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \ + DM_FLAGS_IALLOCSEM_RD : DM_FLAGS_IMUX) +#define DM_SEM_FLAG_WR (DM_FLAGS_IALLOCSEM_WR | DM_FLAGS_IMUX) +#endif + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,21) +#define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \ + 0 : DM_FLAGS_IMUX) +#define DM_SEM_FLAG_WR (DM_FLAGS_IMUX) +#endif + /* * Macros to turn caller specified delay/block flags into diff --git a/trunk/fs/xfs/xfs_iget.c b/trunk/fs/xfs/xfs_iget.c index c1c89dac19cc..b73d216ecaf9 100644 --- a/trunk/fs/xfs/xfs_iget.c +++ b/trunk/fs/xfs/xfs_iget.c @@ -215,7 +215,7 @@ xfs_iget_core( * If INEW is set this inode is being set up * we need to pause and try again. */ - if (xfs_iflags_test(ip, XFS_INEW)) { + if (ip->i_flags & XFS_INEW) { read_unlock(&ih->ih_lock); delay(1); XFS_STATS_INC(xs_ig_frecycle); @@ -230,50 +230,22 @@ xfs_iget_core( * on its way out of the system, * we need to pause and try again. */ - if (xfs_iflags_test(ip, XFS_IRECLAIM)) { + if (ip->i_flags & XFS_IRECLAIM) { read_unlock(&ih->ih_lock); delay(1); XFS_STATS_INC(xs_ig_frecycle); goto again; } - ASSERT(xfs_iflags_test(ip, XFS_IRECLAIMABLE)); - - /* - * If lookup is racing with unlink, then we - * should return an error immediately so we - * don't remove it from the reclaim list and - * potentially leak the inode. - */ - if ((ip->i_d.di_mode == 0) && - !(flags & XFS_IGET_CREATE)) { - read_unlock(&ih->ih_lock); - return ENOENT; - } - - /* - * There may be transactions sitting in the - * incore log buffers or being flushed to disk - * at this time. We can't clear the - * XFS_IRECLAIMABLE flag until these - * transactions have hit the disk, otherwise we - * will void the guarantee the flag provides - * xfs_iunpin() - */ - if (xfs_ipincount(ip)) { - read_unlock(&ih->ih_lock); - xfs_log_force(mp, 0, - XFS_LOG_FORCE|XFS_LOG_SYNC); - XFS_STATS_INC(xs_ig_frecycle); - goto again; - } vn_trace_exit(vp, "xfs_iget.alloc", (inst_t *)__return_address); XFS_STATS_INC(xs_ig_found); - xfs_iflags_clear(ip, XFS_IRECLAIMABLE); + spin_lock(&ip->i_flags_lock); + ip->i_flags &= ~XFS_IRECLAIMABLE; + spin_unlock(&ip->i_flags_lock); version = ih->ih_version; read_unlock(&ih->ih_lock); xfs_ihash_promote(ih, ip, version); @@ -327,7 +299,10 @@ xfs_iget_core( if (lock_flags != 0) xfs_ilock(ip, lock_flags); - xfs_iflags_clear(ip, XFS_ISTALE); + spin_lock(&ip->i_flags_lock); + ip->i_flags &= ~XFS_ISTALE; + spin_unlock(&ip->i_flags_lock); + vn_trace_exit(vp, "xfs_iget.found", (inst_t *)__return_address); goto return_ip; @@ -396,7 +371,10 @@ xfs_iget_core( ih->ih_next = ip; ip->i_udquot = ip->i_gdquot = NULL; ih->ih_version++; - xfs_iflags_set(ip, XFS_INEW); + spin_lock(&ip->i_flags_lock); + ip->i_flags |= XFS_INEW; + spin_unlock(&ip->i_flags_lock); + write_unlock(&ih->ih_lock); /* @@ -647,7 +625,7 @@ xfs_iput_new(xfs_inode_t *ip, vn_trace_entry(vp, "xfs_iput_new", (inst_t *)__return_address); if ((ip->i_d.di_mode == 0)) { - ASSERT(!xfs_iflags_test(ip, XFS_IRECLAIMABLE)); + ASSERT(!(ip->i_flags & XFS_IRECLAIMABLE)); vn_mark_bad(vp); } if (inode->i_state & I_NEW) @@ -705,7 +683,6 @@ xfs_ireclaim(xfs_inode_t *ip) /* * Free all memory associated with the inode. */ - xfs_iunlock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); xfs_idestroy(ip); } diff --git a/trunk/fs/xfs/xfs_inode.c b/trunk/fs/xfs/xfs_inode.c index 44dfac521285..c27d7d495aa0 100644 --- a/trunk/fs/xfs/xfs_inode.c +++ b/trunk/fs/xfs/xfs_inode.c @@ -2193,7 +2193,7 @@ xfs_ifree_cluster( /* Inode not in memory or we found it already, * nothing to do */ - if (!ip || xfs_iflags_test(ip, XFS_ISTALE)) { + if (!ip || (ip->i_flags & XFS_ISTALE)) { read_unlock(&ih->ih_lock); continue; } @@ -2215,7 +2215,10 @@ xfs_ifree_cluster( if (ip == free_ip) { if (xfs_iflock_nowait(ip)) { - xfs_iflags_set(ip, XFS_ISTALE); + spin_lock(&ip->i_flags_lock); + ip->i_flags |= XFS_ISTALE; + spin_unlock(&ip->i_flags_lock); + if (xfs_inode_clean(ip)) { xfs_ifunlock(ip); } else { @@ -2228,7 +2231,9 @@ xfs_ifree_cluster( if (xfs_ilock_nowait(ip, XFS_ILOCK_EXCL)) { if (xfs_iflock_nowait(ip)) { - xfs_iflags_set(ip, XFS_ISTALE); + spin_lock(&ip->i_flags_lock); + ip->i_flags |= XFS_ISTALE; + spin_unlock(&ip->i_flags_lock); if (xfs_inode_clean(ip)) { xfs_ifunlock(ip); @@ -2258,7 +2263,9 @@ xfs_ifree_cluster( AIL_LOCK(mp,s); iip->ili_flush_lsn = iip->ili_item.li_lsn; AIL_UNLOCK(mp, s); - xfs_iflags_set(iip->ili_inode, XFS_ISTALE); + spin_lock(&iip->ili_inode->i_flags_lock); + iip->ili_inode->i_flags |= XFS_ISTALE; + spin_unlock(&iip->ili_inode->i_flags_lock); pre_flushed++; } lip = lip->li_bio_list; @@ -2741,39 +2748,42 @@ xfs_iunpin( { ASSERT(atomic_read(&ip->i_pincount) > 0); - if (atomic_dec_and_lock(&ip->i_pincount, &ip->i_flags_lock)) { - + if (atomic_dec_and_test(&ip->i_pincount)) { /* - * If the inode is currently being reclaimed, the link between - * the bhv_vnode and the xfs_inode will be broken after the - * XFS_IRECLAIM* flag is set. Hence, if these flags are not - * set, then we can move forward and mark the linux inode dirty - * knowing that it is still valid as it won't freed until after - * the bhv_vnode<->xfs_inode link is broken in xfs_reclaim. The - * i_flags_lock is used to synchronise the setting of the - * XFS_IRECLAIM* flags and the breaking of the link, and so we - * can execute atomically w.r.t to reclaim by holding this lock - * here. + * If the inode is currently being reclaimed, the + * linux inode _and_ the xfs vnode may have been + * freed so we cannot reference either of them safely. + * Hence we should not try to do anything to them + * if the xfs inode is currently in the reclaim + * path. * - * However, we still need to issue the unpin wakeup call as the - * inode reclaim may be blocked waiting for the inode to become - * unpinned. + * However, we still need to issue the unpin wakeup + * call as the inode reclaim may be blocked waiting for + * the inode to become unpinned. */ + struct inode *inode = NULL; - if (!__xfs_iflags_test(ip, XFS_IRECLAIM|XFS_IRECLAIMABLE)) { + spin_lock(&ip->i_flags_lock); + if (!(ip->i_flags & (XFS_IRECLAIM|XFS_IRECLAIMABLE))) { bhv_vnode_t *vp = XFS_ITOV_NULL(ip); - struct inode *inode = NULL; - - BUG_ON(vp == NULL); - inode = vn_to_inode(vp); - BUG_ON(inode->i_state & I_CLEAR); /* make sync come back and flush this inode */ - if (!(inode->i_state & (I_NEW|I_FREEING))) - mark_inode_dirty_sync(inode); + if (vp) { + inode = vn_to_inode(vp); + + if (!(inode->i_state & + (I_NEW|I_FREEING|I_CLEAR))) { + inode = igrab(inode); + if (inode) + mark_inode_dirty_sync(inode); + } else + inode = NULL; + } } spin_unlock(&ip->i_flags_lock); wake_up(&ip->i_ipin_wait); + if (inode) + iput(inode); } } diff --git a/trunk/fs/xfs/xfs_inode.h b/trunk/fs/xfs/xfs_inode.h index bc823720d88f..e96eb0835fe6 100644 --- a/trunk/fs/xfs/xfs_inode.h +++ b/trunk/fs/xfs/xfs_inode.h @@ -305,47 +305,6 @@ typedef struct xfs_inode { #endif } xfs_inode_t; - -/* - * i_flags helper functions - */ -static inline void -__xfs_iflags_set(xfs_inode_t *ip, unsigned short flags) -{ - ip->i_flags |= flags; -} - -static inline void -xfs_iflags_set(xfs_inode_t *ip, unsigned short flags) -{ - spin_lock(&ip->i_flags_lock); - __xfs_iflags_set(ip, flags); - spin_unlock(&ip->i_flags_lock); -} - -static inline void -xfs_iflags_clear(xfs_inode_t *ip, unsigned short flags) -{ - spin_lock(&ip->i_flags_lock); - ip->i_flags &= ~flags; - spin_unlock(&ip->i_flags_lock); -} - -static inline int -__xfs_iflags_test(xfs_inode_t *ip, unsigned short flags) -{ - return (ip->i_flags & flags); -} - -static inline int -xfs_iflags_test(xfs_inode_t *ip, unsigned short flags) -{ - int ret; - spin_lock(&ip->i_flags_lock); - ret = __xfs_iflags_test(ip, flags); - spin_unlock(&ip->i_flags_lock); - return ret; -} #endif /* __KERNEL__ */ diff --git a/trunk/fs/xfs/xfs_vnodeops.c b/trunk/fs/xfs/xfs_vnodeops.c index bda774a04b8f..061e2ffdd1de 100644 --- a/trunk/fs/xfs/xfs_vnodeops.c +++ b/trunk/fs/xfs/xfs_vnodeops.c @@ -1013,7 +1013,7 @@ xfs_readlink( pathlen = (int)ip->i_d.di_size; if (ip->i_df.if_flags & XFS_IFINLINE) { - error = xfs_uio_read(ip->i_df.if_u1.if_data, pathlen, uiop); + error = uio_read(ip->i_df.if_u1.if_data, pathlen, uiop); } else { /* @@ -1044,7 +1044,7 @@ xfs_readlink( byte_cnt = pathlen; pathlen -= byte_cnt; - error = xfs_uio_read(XFS_BUF_PTR(bp), byte_cnt, uiop); + error = uio_read(XFS_BUF_PTR(bp), byte_cnt, uiop); xfs_buf_relse (bp); } @@ -3827,16 +3827,11 @@ xfs_reclaim( */ xfs_synchronize_atime(ip); - /* - * If we have nothing to flush with this inode then complete the - * teardown now, otherwise break the link between the xfs inode and the - * linux inode and clean up the xfs inode later. This avoids flushing - * the inode to disk during the delete operation itself. - * - * When breaking the link, we need to set the XFS_IRECLAIMABLE flag - * first to ensure that xfs_iunpin() will never see an xfs inode - * that has a linux inode being reclaimed. Synchronisation is provided - * by the i_flags_lock. + /* If we have nothing to flush with this inode then complete the + * teardown now, otherwise break the link between the xfs inode + * and the linux inode and clean up the xfs inode later. This + * avoids flushing the inode to disk during the delete operation + * itself. */ if (!ip->i_update_core && (ip->i_itemp == NULL)) { xfs_ilock(ip, XFS_ILOCK_EXCL); @@ -3845,13 +3840,13 @@ xfs_reclaim( } else { xfs_mount_t *mp = ip->i_mount; - /* Protect sync and unpin from us */ + /* Protect sync from us */ XFS_MOUNT_ILOCK(mp); - spin_lock(&ip->i_flags_lock); - __xfs_iflags_set(ip, XFS_IRECLAIMABLE); vn_bhv_remove(VN_BHV_HEAD(vp), XFS_ITOBHV(ip)); - spin_unlock(&ip->i_flags_lock); list_add_tail(&ip->i_reclaim, &mp->m_del_inodes); + spin_lock(&ip->i_flags_lock); + ip->i_flags |= XFS_IRECLAIMABLE; + spin_unlock(&ip->i_flags_lock); XFS_MOUNT_IUNLOCK(mp); } return 0; @@ -3877,8 +3872,8 @@ xfs_finish_reclaim( */ write_lock(&ih->ih_lock); spin_lock(&ip->i_flags_lock); - if (__xfs_iflags_test(ip, XFS_IRECLAIM) || - (!__xfs_iflags_test(ip, XFS_IRECLAIMABLE) && vp == NULL)) { + if ((ip->i_flags & XFS_IRECLAIM) || + (!(ip->i_flags & XFS_IRECLAIMABLE) && vp == NULL)) { spin_unlock(&ip->i_flags_lock); write_unlock(&ih->ih_lock); if (locked) { @@ -3887,7 +3882,7 @@ xfs_finish_reclaim( } return 1; } - __xfs_iflags_set(ip, XFS_IRECLAIM); + ip->i_flags |= XFS_IRECLAIM; spin_unlock(&ip->i_flags_lock); write_unlock(&ih->ih_lock); diff --git a/trunk/include/acpi/aclocal.h b/trunk/include/acpi/aclocal.h index 063c4b54290f..a4d0e73d5aca 100644 --- a/trunk/include/acpi/aclocal.h +++ b/trunk/include/acpi/aclocal.h @@ -708,7 +708,7 @@ struct acpi_bit_register_info { * must be preserved. */ #define ACPI_PM1_STATUS_PRESERVED_BITS 0x0800 /* Bit 11 */ -#define ACPI_PM1_CONTROL_PRESERVED_BITS 0x0200 /* Bit 9 (whatever) */ +#define ACPI_PM1_CONTROL_PRESERVED_BITS 0x0201 /* Bit 9, Bit 0 (SCI_EN) */ /* * Register IDs diff --git a/trunk/include/acpi/acpi_bus.h b/trunk/include/acpi/acpi_bus.h index fdd10953b2b6..f338e40bd544 100644 --- a/trunk/include/acpi/acpi_bus.h +++ b/trunk/include/acpi/acpi_bus.h @@ -357,7 +357,7 @@ struct device *acpi_get_physical_device(acpi_handle); /* helper */ acpi_handle acpi_get_child(acpi_handle, acpi_integer); acpi_handle acpi_get_pci_rootbridge_handle(unsigned int, unsigned int); -#define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)((dev)->archdata.acpi_handle)) +#define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)((dev)->firmware_data)) #endif /* CONFIG_ACPI */ diff --git a/trunk/include/acpi/pdc_intel.h b/trunk/include/acpi/pdc_intel.h index e72bfdd887f9..c5472be6f3a2 100644 --- a/trunk/include/acpi/pdc_intel.h +++ b/trunk/include/acpi/pdc_intel.h @@ -13,7 +13,6 @@ #define ACPI_PDC_SMP_C_SWCOORD (0x0040) #define ACPI_PDC_SMP_T_SWCOORD (0x0080) #define ACPI_PDC_C_C1_FFH (0x0100) -#define ACPI_PDC_C_C2C3_FFH (0x0200) #define ACPI_PDC_EST_CAPABILITY_SMP (ACPI_PDC_SMP_C1PT | \ ACPI_PDC_C_C1_HALT | \ @@ -24,10 +23,8 @@ ACPI_PDC_SMP_P_SWCOORD | \ ACPI_PDC_P_FFH) -#define ACPI_PDC_C_CAPABILITY_SMP (ACPI_PDC_SMP_C2C3 | \ - ACPI_PDC_SMP_C1PT | \ - ACPI_PDC_C_C1_HALT | \ - ACPI_PDC_C_C1_FFH | \ - ACPI_PDC_C_C2C3_FFH) +#define ACPI_PDC_C_CAPABILITY_SMP (ACPI_PDC_SMP_C2C3 | \ + ACPI_PDC_SMP_C1PT | \ + ACPI_PDC_C_C1_HALT) #endif /* __PDC_INTEL_H__ */ diff --git a/trunk/include/acpi/processor.h b/trunk/include/acpi/processor.h index 7798d2a9f793..9dd5b75961f8 100644 --- a/trunk/include/acpi/processor.h +++ b/trunk/include/acpi/processor.h @@ -29,9 +29,6 @@ #define DOMAIN_COORD_TYPE_SW_ANY 0xfd #define DOMAIN_COORD_TYPE_HW_ALL 0xfe -#define ACPI_CSTATE_SYSTEMIO (0) -#define ACPI_CSTATE_FFH (1) - /* Power Management */ struct acpi_processor_cx; @@ -61,8 +58,6 @@ struct acpi_processor_cx { u8 valid; u8 type; u32 address; - u8 space_id; - u8 index; u32 latency; u32 latency_ticks; u32 power; @@ -211,9 +206,6 @@ void arch_acpi_processor_init_pdc(struct acpi_processor *pr); #ifdef ARCH_HAS_POWER_INIT void acpi_processor_power_init_bm_check(struct acpi_processor_flags *flags, unsigned int cpu); -int acpi_processor_ffh_cstate_probe(unsigned int cpu, - struct acpi_processor_cx *cx, struct acpi_power_register *reg); -void acpi_processor_ffh_cstate_enter(struct acpi_processor_cx *cstate); #else static inline void acpi_processor_power_init_bm_check(struct acpi_processor_flags @@ -222,16 +214,6 @@ static inline void acpi_processor_power_init_bm_check(struct flags->bm_check = 1; return; } -static inline int acpi_processor_ffh_cstate_probe(unsigned int cpu, - struct acpi_processor_cx *cx, struct acpi_power_register *reg) -{ - return -1; -} -static inline void acpi_processor_ffh_cstate_enter( - struct acpi_processor_cx *cstate) -{ - return; -} #endif /* in processor_perflib.c */ diff --git a/trunk/include/asm-alpha/device.h b/trunk/include/asm-alpha/device.h deleted file mode 100644 index d8f9872b0e2d..000000000000 --- a/trunk/include/asm-alpha/device.h +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Arch specific extensions to struct device - * - * This file is released under the GPLv2 - */ -#include - diff --git a/trunk/include/asm-alpha/io.h b/trunk/include/asm-alpha/io.h index 5d15af24573b..f5ae98c25d1f 100644 --- a/trunk/include/asm-alpha/io.h +++ b/trunk/include/asm-alpha/io.h @@ -533,6 +533,19 @@ extern void outsl (unsigned long port, const void *src, unsigned long count); #define eth_io_copy_and_sum(skb,src,len,unused) \ memcpy_fromio((skb)->data,src,len) +static inline int +check_signature(const volatile void __iomem *io_addr, + const unsigned char *signature, int length) +{ + do { + if (readb(io_addr) != *signature) + return 0; + io_addr++; + signature++; + } while (--length); + return 1; +} + /* * The Alpha Jensen hardware for some rather strange reason puts * the RTC clock at 0x170 instead of 0x70. Probably due to some diff --git a/trunk/include/asm-alpha/irq_regs.h b/trunk/include/asm-alpha/irq_regs.h deleted file mode 100644 index 3dd9c0b70270..000000000000 --- a/trunk/include/asm-alpha/irq_regs.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/include/asm-alpha/machvec.h b/trunk/include/asm-alpha/machvec.h index a86c083cdf7f..aced22f91752 100644 --- a/trunk/include/asm-alpha/machvec.h +++ b/trunk/include/asm-alpha/machvec.h @@ -15,6 +15,7 @@ struct task_struct; struct mm_struct; +struct pt_regs; struct vm_area_struct; struct linux_hose_info; struct pci_dev; @@ -78,8 +79,8 @@ struct alpha_machine_vector void (*update_irq_hw)(unsigned long, unsigned long, int); void (*ack_irq)(unsigned long); - void (*device_interrupt)(unsigned long vector); - void (*machine_check)(u64 vector, u64 la); + void (*device_interrupt)(unsigned long vector, struct pt_regs *regs); + void (*machine_check)(u64 vector, u64 la, struct pt_regs *regs); void (*smp_callin)(void); void (*init_arch)(void); diff --git a/trunk/include/asm-arm/arch-clps711x/time.h b/trunk/include/asm-arm/arch-clps711x/time.h index 5edaae1c61d3..0e4a3901d3b3 100644 --- a/trunk/include/asm-arm/arch-clps711x/time.h +++ b/trunk/include/asm-arm/arch-clps711x/time.h @@ -26,9 +26,8 @@ extern void clps711x_setup_timer(void); * IRQ handler for the timer */ static irqreturn_t -p720t_timer_interrupt(int irq, void *dev_id) +p720t_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct pt_regs *regs = get_irq_regs(); do_leds(); do_timer(1); #ifndef CONFIG_SMP diff --git a/trunk/include/asm-arm/arch-ebsa110/io.h b/trunk/include/asm-arm/arch-ebsa110/io.h index 722c5e086285..ae048441c9ed 100644 --- a/trunk/include/asm-arm/arch-ebsa110/io.h +++ b/trunk/include/asm-arm/arch-ebsa110/io.h @@ -27,9 +27,9 @@ void __outw(u16 val, unsigned int port); u32 __inl(unsigned int port); void __outl(u32 val, unsigned int port); -u8 __readb(const volatile void __iomem *addr); -u16 __readw(const volatile void __iomem *addr); -u32 __readl(const volatile void __iomem *addr); +u8 __readb(void __iomem *addr); +u16 __readw(void __iomem *addr); +u32 __readl(void __iomem *addr); void __writeb(u8 val, void __iomem *addr); void __writew(u16 val, void __iomem *addr); @@ -64,14 +64,8 @@ void __writel(u32 val, void __iomem *addr); #define writew(v,b) __writew(v,b) #define writel(v,b) __writel(v,b) -static inline void __iomem *__arch_ioremap(unsigned long cookie, size_t size, - unsigned int flags) -{ - return (void __iomem *)cookie; -} - -#define __arch_ioremap __arch_ioremap -#define __arch_iounmap(cookie) do { } while (0) +#define __arch_ioremap(cookie,sz,c) ((void __iomem *)(cookie)) +#define __arch_iounmap(cookie) do { } while (0) extern void insb(unsigned int port, void *buf, int sz); extern void insw(unsigned int port, void *buf, int sz); diff --git a/trunk/include/asm-arm/arch-imx/imx-dma.h b/trunk/include/asm-arm/arch-imx/imx-dma.h index 5b1066da4e1f..599f03e5a9ef 100644 --- a/trunk/include/asm-arm/arch-imx/imx-dma.h +++ b/trunk/include/asm-arm/arch-imx/imx-dma.h @@ -45,8 +45,8 @@ struct imx_dma_channel { const char *name; - void (*irq_handler) (int, void *); - void (*err_handler) (int, void *, int errcode); + void (*irq_handler) (int, void *, struct pt_regs *); + void (*err_handler) (int, void *, struct pt_regs *, int errcode); void *data; dmamode_t dma_mode; struct scatterlist *sg; @@ -77,8 +77,8 @@ imx_dma_setup_sg(imx_dmach_t dma_ch, int imx_dma_setup_handlers(imx_dmach_t dma_ch, - void (*irq_handler) (int, void *), - void (*err_handler) (int, void *, int), void *data); + void (*irq_handler) (int, void *, struct pt_regs *), + void (*err_handler) (int, void *, struct pt_regs *, int), void *data); void imx_dma_enable(imx_dmach_t dma_ch); diff --git a/trunk/include/asm-arm/arch-l7200/time.h b/trunk/include/asm-arm/arch-l7200/time.h index ea22f7fff9cd..c69cb508735f 100644 --- a/trunk/include/asm-arm/arch-l7200/time.h +++ b/trunk/include/asm-arm/arch-l7200/time.h @@ -43,9 +43,8 @@ * Handler for RTC timer interrupt */ static irqreturn_t -timer_interrupt(int irq, void *dev_id) +timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct pt_regs *regs = get_irq_regs(); do_timer(1); #ifndef CONFIG_SMP update_process_times(user_mode(regs)); diff --git a/trunk/include/asm-arm/arch-pnx4008/dma.h b/trunk/include/asm-arm/arch-pnx4008/dma.h index 418f15283ff1..3aee1204795b 100644 --- a/trunk/include/asm-arm/arch-pnx4008/dma.h +++ b/trunk/include/asm-arm/arch-pnx4008/dma.h @@ -137,7 +137,7 @@ extern void pnx4008_free_ll_entry(struct pnx4008_dma_ll *, dma_addr_t); extern void pnx4008_free_ll(u32 ll_dma, struct pnx4008_dma_ll *); extern int pnx4008_request_channel(char *, int, - void (*)(int, int, void *), + void (*)(int, int, void *, struct pt_regs *), void *); extern void pnx4008_free_channel(int); extern int pnx4008_config_dma(int, int, int); diff --git a/trunk/include/asm-arm/arch-pxa/dma.h b/trunk/include/asm-arm/arch-pxa/dma.h index bed042d71d68..a008150abc59 100644 --- a/trunk/include/asm-arm/arch-pxa/dma.h +++ b/trunk/include/asm-arm/arch-pxa/dma.h @@ -56,7 +56,7 @@ for ( \ int pxa_request_dma (char *name, pxa_dma_prio prio, - void (*irq_handler)(int, void *), + void (*irq_handler)(int, void *, struct pt_regs *), void *data); void pxa_free_dma (int dma_ch); diff --git a/trunk/include/asm-arm/arch-pxa/irqs.h b/trunk/include/asm-arm/arch-pxa/irqs.h index 67ed43674c63..f3bc70eee35b 100644 --- a/trunk/include/asm-arm/arch-pxa/irqs.h +++ b/trunk/include/asm-arm/arch-pxa/irqs.h @@ -73,7 +73,7 @@ #define IRQ_TO_GPIO(i) (((i) < IRQ_GPIO(2)) ? ((i) - IRQ_GPIO0) : IRQ_TO_GPIO_2_x(i)) #if defined(CONFIG_PXA25x) -#define PXA_LAST_GPIO 84 +#define PXA_LAST_GPIO 80 #elif defined(CONFIG_PXA27x) #define PXA_LAST_GPIO 127 #endif diff --git a/trunk/include/asm-arm/arch-pxa/mmc.h b/trunk/include/asm-arm/arch-pxa/mmc.h index a38a28c4bbd8..88c17dd02ed2 100644 --- a/trunk/include/asm-arm/arch-pxa/mmc.h +++ b/trunk/include/asm-arm/arch-pxa/mmc.h @@ -10,7 +10,7 @@ struct mmc_host; struct pxamci_platform_data { unsigned int ocr_mask; /* available voltages */ unsigned long detect_delay; /* delay in jiffies before detecting cards after interrupt */ - int (*init)(struct device *, irq_handler_t , void *); + int (*init)(struct device *, irqreturn_t (*)(int, void *, struct pt_regs *), void *); int (*get_ro)(struct device *); void (*setpower)(struct device *, unsigned int); void (*exit)(struct device *, void *); diff --git a/trunk/include/asm-arm/arch-pxa/pxa-regs.h b/trunk/include/asm-arm/arch-pxa/pxa-regs.h index cff752f35230..f5cc65dd7d0d 100644 --- a/trunk/include/asm-arm/arch-pxa/pxa-regs.h +++ b/trunk/include/asm-arm/arch-pxa/pxa-regs.h @@ -1681,7 +1681,6 @@ #define SSSR_TINT (1 << 19) /* Receiver Time-out Interrupt */ #define SSSR_PINT (1 << 18) /* Peripheral Trailing Byte Interrupt */ -#define SSPSP_FSRT (1 << 25) /* Frame Sync Relative Timing */ #define SSPSP_DMYSTOP(x) (x << 23) /* Dummy Stop */ #define SSPSP_SFRMWDTH(x) (x << 16) /* Serial Frame Width */ #define SSPSP_SFRMDLY(x) (x << 9) /* Serial Frame Delay */ @@ -2242,7 +2241,7 @@ #define CICR1_TBIT (1 << 31) /* Transparency bit */ #define CICR1_RGBT_CONV (0x3 << 30) /* RGBT conversion mask */ -#define CICR1_PPL (0x7ff << 15) /* Pixels per line mask */ +#define CICR1_PPL (0x3f << 15) /* Pixels per line mask */ #define CICR1_RGB_CONV (0x7 << 12) /* RGB conversion mask */ #define CICR1_RGB_F (1 << 11) /* RGB format */ #define CICR1_YCBCR_F (1 << 10) /* YCbCr format */ @@ -2268,7 +2267,7 @@ #define CICR3_VSW (0x3f << 10) /* Vertical sync pulse width mask */ #define CICR3_BFPW (0x3f << 3) /* Beginning-of-frame pixel clock wait count mask */ -#define CICR3_LPF (0x7ff << 0) /* Lines per frame mask */ +#define CICR3_LPF (0x3ff << 0) /* Lines per frame mask */ #define CICR4_MCLK_DLY (0x3 << 24) /* MCLK Data Capture Delay mask */ #define CICR4_PCLK_EN (1 << 23) /* Pixel clock enable */ @@ -2289,8 +2288,8 @@ #define CISR_EOL (1 << 8) /* End of line */ #define CISR_PAR_ERR (1 << 7) /* Parity error */ #define CISR_CQD (1 << 6) /* Camera interface quick disable */ -#define CISR_CDD (1 << 5) /* Camera interface disable done */ -#define CISR_SOF (1 << 4) /* Start of frame */ +#define CISR_SOF (1 << 5) /* Start of frame */ +#define CISR_CDD (1 << 4) /* Camera interface disable done */ #define CISR_EOF (1 << 3) /* End of frame */ #define CISR_IFO_2 (1 << 2) /* FIFO overrun for Channel 2 */ #define CISR_IFO_1 (1 << 1) /* FIFO overrun for Channel 1 */ diff --git a/trunk/include/asm-arm/arch-pxa/udc.h b/trunk/include/asm-arm/arch-pxa/udc.h index 646480d37256..121cd241115d 100644 --- a/trunk/include/asm-arm/arch-pxa/udc.h +++ b/trunk/include/asm-arm/arch-pxa/udc.h @@ -4,8 +4,23 @@ * This supports machine-specific differences in how the PXA2xx * USB Device Controller (UDC) is wired. * + * It is set in linux/arch/arm/mach-pxa/.c and used in + * the probe routine of linux/drivers/usb/gadget/pxa2xx_udc.c */ -#include +struct pxa2xx_udc_mach_info { + int (*udc_is_connected)(void); /* do we see host? */ + void (*udc_command)(int cmd); +#define PXA2XX_UDC_CMD_CONNECT 0 /* let host see us */ +#define PXA2XX_UDC_CMD_DISCONNECT 1 /* so host won't see us */ + + /* Boards following the design guidelines in the developer's manual, + * with on-chip GPIOs not Lubbock's wierd hardware, can have a sane + * VBUS IRQ and omit the methods above. Store the GPIO number + * here; for GPIO 0, also mask in one of the pxa_gpio_mode() bits. + */ + u16 gpio_vbus; /* high == vbus present */ + u16 gpio_pullup; /* high == pullup activated */ +}; extern void pxa_set_udc_info(struct pxa2xx_udc_mach_info *info); diff --git a/trunk/include/asm-arm/arch-sa1100/jornada720.h b/trunk/include/asm-arm/arch-sa1100/jornada720.h index 3f37ca07806d..1b8e8a304800 100644 --- a/trunk/include/asm-arm/arch-sa1100/jornada720.h +++ b/trunk/include/asm-arm/arch-sa1100/jornada720.h @@ -19,20 +19,6 @@ #define GPIO_JORNADA720_KEYBOARD_IRQ IRQ_GPIO0 #define GPIO_JORNADA720_MOUSE_IRQ IRQ_GPIO9 -/* MCU COMMANDS */ -#define MCU_GetBatteryData 0xc0 -#define MCU_GetScanKeyCode 0x90 -#define MCU_GetTouchSamples 0xa0 -#define MCU_GetContrast 0xD0 -#define MCU_SetContrast 0xD1 -#define MCU_GetBrightness 0xD2 -#define MCU_SetBrightness 0xD3 -#define MCU_ContrastOff 0xD8 -#define MCU_BrightnessOff 0xD9 -#define MCU_PWMOFF 0xDF -#define MCU_TxDummy 0x11 -#define MCU_ErrorCode 0x00 - #ifndef __ASSEMBLY__ void jornada720_mcu_init(void); diff --git a/trunk/include/asm-arm/arch-versatile/hardware.h b/trunk/include/asm-arm/arch-versatile/hardware.h index edc06598d187..41c1bee342ad 100644 --- a/trunk/include/asm-arm/arch-versatile/hardware.h +++ b/trunk/include/asm-arm/arch-versatile/hardware.h @@ -28,8 +28,8 @@ /* * PCI space virtual addresses */ -#define VERSATILE_PCI_VIRT_BASE (void __iomem *)0xe8000000ul -#define VERSATILE_PCI_CFG_VIRT_BASE (void __iomem *)0xe9000000ul +#define VERSATILE_PCI_VIRT_BASE 0xe8000000 +#define VERSATILE_PCI_CFG_VIRT_BASE 0xe9000000 #if 0 #define VERSATILE_PCI_VIRT_MEM_BASE0 0xf4000000 diff --git a/trunk/include/asm-arm/device.h b/trunk/include/asm-arm/device.h deleted file mode 100644 index d8f9872b0e2d..000000000000 --- a/trunk/include/asm-arm/device.h +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Arch specific extensions to struct device - * - * This file is released under the GPLv2 - */ -#include - diff --git a/trunk/include/asm-arm/dma-mapping.h b/trunk/include/asm-arm/dma-mapping.h index 666617711c81..55eb4dc3253d 100644 --- a/trunk/include/asm-arm/dma-mapping.h +++ b/trunk/include/asm-arm/dma-mapping.h @@ -12,10 +12,6 @@ * uncached, unwrite-buffered mapped memory space for use with DMA * devices. This is the "generic" version. The PCI specific version * is in pci.h - * - * Note: Drivers should NOT use this function directly, as it will break - * platforms with CONFIG_DMABOUNCE. - * Use the driver DMA support - see dma-mapping.h (dma_sync_*) */ extern void consistent_sync(void *kaddr, size_t size, int rw); diff --git a/trunk/include/asm-arm/hardware/sharpsl_pm.h b/trunk/include/asm-arm/hardware/sharpsl_pm.h index 2d00db22b981..a836e76a14f7 100644 --- a/trunk/include/asm-arm/hardware/sharpsl_pm.h +++ b/trunk/include/asm-arm/hardware/sharpsl_pm.h @@ -100,7 +100,7 @@ extern struct sharpsl_pm_status sharpsl_pm; void sharpsl_battery_kick(void); void sharpsl_pm_led(int val); -irqreturn_t sharpsl_ac_isr(int irq, void *dev_id); -irqreturn_t sharpsl_chrg_full_isr(int irq, void *dev_id); -irqreturn_t sharpsl_fatal_isr(int irq, void *dev_id); +irqreturn_t sharpsl_ac_isr(int irq, void *dev_id, struct pt_regs *fp); +irqreturn_t sharpsl_chrg_full_isr(int irq, void *dev_id, struct pt_regs *fp); +irqreturn_t sharpsl_fatal_isr(int irq, void *dev_id, struct pt_regs *fp); diff --git a/trunk/include/asm-arm/hw_irq.h b/trunk/include/asm-arm/hw_irq.h index 98d594a973d6..ea856971989a 100644 --- a/trunk/include/asm-arm/hw_irq.h +++ b/trunk/include/asm-arm/hw_irq.h @@ -12,7 +12,7 @@ if (!(action->flags & IRQF_TIMER) && system_timer->dyn_tick) { \ write_seqlock(&xtime_lock); \ if (system_timer->dyn_tick->state & DYN_TICK_ENABLED) \ - system_timer->dyn_tick->handler(irq, NULL); \ + system_timer->dyn_tick->handler(irq, 0, regs); \ write_sequnlock(&xtime_lock); \ } #endif diff --git a/trunk/include/asm-arm/io.h b/trunk/include/asm-arm/io.h index ae999fd5dc67..8076a85c3675 100644 --- a/trunk/include/asm-arm/io.h +++ b/trunk/include/asm-arm/io.h @@ -63,7 +63,7 @@ extern void __raw_readsl(const void __iomem *addr, void *data, int longlen); */ extern void __iomem * __ioremap_pfn(unsigned long, unsigned long, size_t, unsigned long); extern void __iomem * __ioremap(unsigned long, size_t, unsigned long); -extern void __iounmap(volatile void __iomem *addr); +extern void __iounmap(void __iomem *addr); /* * Bad read/write accesses... @@ -193,6 +193,23 @@ extern void _memset_io(volatile void __iomem *, int, size_t); #define eth_io_copy_and_sum(s,c,l,b) \ eth_copy_and_sum((s),__mem_pci(c),(l),(b)) +static inline int +check_signature(void __iomem *io_addr, const unsigned char *signature, + int length) +{ + int retval = 0; + do { + if (readb(io_addr) != *signature) + goto out; + io_addr++; + signature++; + length--; + } while (length); + retval = 1; +out: + return retval; +} + #elif !defined(readb) #define readb(c) (__readwrite_bug("readb"),0) diff --git a/trunk/include/asm-arm/irq_regs.h b/trunk/include/asm-arm/irq_regs.h deleted file mode 100644 index 3dd9c0b70270..000000000000 --- a/trunk/include/asm-arm/irq_regs.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/include/asm-arm/mach/irq.h b/trunk/include/asm-arm/mach/irq.h index 0e017ecf2096..131f33733d25 100644 --- a/trunk/include/asm-arm/mach/irq.h +++ b/trunk/include/asm-arm/mach/irq.h @@ -30,9 +30,10 @@ extern int show_fiq_list(struct seq_file *, void *); /* * Obsolete inline function for calling irq descriptor handlers. */ -static inline void desc_handle_irq(unsigned int irq, struct irq_desc *desc) +static inline void desc_handle_irq(unsigned int irq, struct irq_desc *desc, + struct pt_regs *regs) { - desc->handle_irq(irq, desc); + desc->handle_irq(irq, desc, regs); } void set_irq_flags(unsigned int irq, unsigned int flags); @@ -50,10 +51,10 @@ void set_irq_flags(unsigned int irq, unsigned int flags); #define irqdesc irq_desc #define irqchip irq_chip -#define do_bad_IRQ(irq,desc) \ +#define do_bad_IRQ(irq,desc,regs) \ do { \ spin_lock(&desc->lock); \ - handle_bad_irq(irq, desc); \ + handle_bad_irq(irq, desc, regs); \ spin_unlock(&desc->lock); \ } while(0) diff --git a/trunk/include/asm-arm/mach/time.h b/trunk/include/asm-arm/mach/time.h index 5dc357013b79..1eb93f5c0d6c 100644 --- a/trunk/include/asm-arm/mach/time.h +++ b/trunk/include/asm-arm/mach/time.h @@ -57,7 +57,7 @@ struct dyn_tick_timer { int (*enable)(void); /* Enables dynamic tick */ int (*disable)(void); /* Disables dynamic tick */ void (*reprogram)(unsigned long); /* Reprograms the timer */ - int (*handler)(int, void *); + int (*handler)(int, void *, struct pt_regs *); }; void timer_dyn_reprogram(void); @@ -66,7 +66,7 @@ void timer_dyn_reprogram(void); #endif extern struct sys_timer *system_timer; -extern void timer_tick(void); +extern void timer_tick(struct pt_regs *); /* * Kernel time keeping support. diff --git a/trunk/include/asm-arm/mach/udc_pxa2xx.h b/trunk/include/asm-arm/mach/udc_pxa2xx.h deleted file mode 100644 index ff0a95715a07..000000000000 --- a/trunk/include/asm-arm/mach/udc_pxa2xx.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * linux/include/asm-arm/mach/udc_pxa2xx.h - * - * This supports machine-specific differences in how the PXA2xx - * USB Device Controller (UDC) is wired. - * - * It is set in linux/arch/arm/mach-pxa/.c or in - * linux/arch/mach-ixp4xx/.c and used in - * the probe routine of linux/drivers/usb/gadget/pxa2xx_udc.c - */ - -struct pxa2xx_udc_mach_info { - int (*udc_is_connected)(void); /* do we see host? */ - void (*udc_command)(int cmd); -#define PXA2XX_UDC_CMD_CONNECT 0 /* let host see us */ -#define PXA2XX_UDC_CMD_DISCONNECT 1 /* so host won't see us */ - - /* Boards following the design guidelines in the developer's manual, - * with on-chip GPIOs not Lubbock's wierd hardware, can have a sane - * VBUS IRQ and omit the methods above. Store the GPIO number - * here; for GPIO 0, also mask in one of the pxa_gpio_mode() bits. - */ - u16 gpio_vbus; /* high == vbus present */ - u16 gpio_pullup; /* high == pullup activated */ -}; - diff --git a/trunk/include/asm-arm/uaccess.h b/trunk/include/asm-arm/uaccess.h index 5f420a0149f1..87aba57a66c4 100644 --- a/trunk/include/asm-arm/uaccess.h +++ b/trunk/include/asm-arm/uaccess.h @@ -110,7 +110,7 @@ extern int __get_user_4(void *); #define get_user(x,p) \ ({ \ const register typeof(*(p)) __user *__p asm("r0") = (p);\ - register unsigned long __r2 asm("r2"); \ + register unsigned int __r2 asm("r2"); \ register int __e asm("r0"); \ switch (sizeof(*(__p))) { \ case 1: \ @@ -383,19 +383,19 @@ do { \ #ifdef CONFIG_MMU -extern unsigned long __must_check __copy_from_user(void *to, const void __user *from, unsigned long n); -extern unsigned long __must_check __copy_to_user(void __user *to, const void *from, unsigned long n); -extern unsigned long __must_check __clear_user(void __user *addr, unsigned long n); +extern unsigned long __copy_from_user(void *to, const void __user *from, unsigned long n); +extern unsigned long __copy_to_user(void __user *to, const void *from, unsigned long n); +extern unsigned long __clear_user(void __user *addr, unsigned long n); #else #define __copy_from_user(to,from,n) (memcpy(to, (void __force *)from, n), 0) #define __copy_to_user(to,from,n) (memcpy((void __force *)to, from, n), 0) #define __clear_user(addr,n) (memset((void __force *)addr, 0, n), 0) #endif -extern unsigned long __must_check __strncpy_from_user(char *to, const char __user *from, unsigned long count); -extern unsigned long __must_check __strnlen_user(const char __user *s, long n); +extern unsigned long __strncpy_from_user(char *to, const char __user *from, unsigned long count); +extern unsigned long __strnlen_user(const char __user *s, long n); -static inline unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long n) +static inline unsigned long copy_from_user(void *to, const void __user *from, unsigned long n) { if (access_ok(VERIFY_READ, from, n)) n = __copy_from_user(to, from, n); @@ -404,7 +404,7 @@ static inline unsigned long __must_check copy_from_user(void *to, const void __u return n; } -static inline unsigned long __must_check copy_to_user(void __user *to, const void *from, unsigned long n) +static inline unsigned long copy_to_user(void __user *to, const void *from, unsigned long n) { if (access_ok(VERIFY_WRITE, to, n)) n = __copy_to_user(to, from, n); @@ -414,14 +414,14 @@ static inline unsigned long __must_check copy_to_user(void __user *to, const voi #define __copy_to_user_inatomic __copy_to_user #define __copy_from_user_inatomic __copy_from_user -static inline unsigned long __must_check clear_user(void __user *to, unsigned long n) +static inline unsigned long clear_user(void __user *to, unsigned long n) { if (access_ok(VERIFY_WRITE, to, n)) n = __clear_user(to, n); return n; } -static inline long __must_check strncpy_from_user(char *dst, const char __user *src, long count) +static inline long strncpy_from_user(char *dst, const char __user *src, long count) { long res = -EFAULT; if (access_ok(VERIFY_READ, src, 1)) @@ -431,7 +431,7 @@ static inline long __must_check strncpy_from_user(char *dst, const char __user * #define strlen_user(s) strnlen_user(s, ~0UL >> 1) -static inline long __must_check strnlen_user(const char __user *s, long n) +static inline long strnlen_user(const char __user *s, long n) { unsigned long res = 0; diff --git a/trunk/include/asm-arm26/device.h b/trunk/include/asm-arm26/device.h deleted file mode 100644 index d8f9872b0e2d..000000000000 --- a/trunk/include/asm-arm26/device.h +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Arch specific extensions to struct device - * - * This file is released under the GPLv2 - */ -#include - diff --git a/trunk/include/asm-avr32/atomic.h b/trunk/include/asm-avr32/atomic.h index c40b6032c480..e0b9c44c126c 100644 --- a/trunk/include/asm-avr32/atomic.h +++ b/trunk/include/asm-avr32/atomic.h @@ -41,7 +41,7 @@ static inline int atomic_sub_return(int i, atomic_t *v) " stcond %1, %0\n" " brne 1b" : "=&r"(result), "=o"(v->counter) - : "m"(v->counter), "rKs21"(i) + : "m"(v->counter), "ir"(i) : "cc"); return result; @@ -58,7 +58,7 @@ static inline int atomic_add_return(int i, atomic_t *v) { int result; - if (__builtin_constant_p(i) && (i >= -1048575) && (i <= 1048576)) + if (__builtin_constant_p(i)) result = atomic_sub_return(-i, v); else asm volatile( @@ -101,7 +101,7 @@ static inline int atomic_sub_unless(atomic_t *v, int a, int u) " mov %1, 1\n" "1:" : "=&r"(tmp), "=&r"(result), "=o"(v->counter) - : "m"(v->counter), "rKs21"(a), "rKs21"(u) + : "m"(v->counter), "ir"(a), "ir"(u) : "cc", "memory"); return result; @@ -121,7 +121,7 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u) { int tmp, result; - if (__builtin_constant_p(a) && (a >= -1048575) && (a <= 1048576)) + if (__builtin_constant_p(a)) result = atomic_sub_unless(v, -a, u); else { result = 0; diff --git a/trunk/include/asm-avr32/device.h b/trunk/include/asm-avr32/device.h deleted file mode 100644 index d8f9872b0e2d..000000000000 --- a/trunk/include/asm-avr32/device.h +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Arch specific extensions to struct device - * - * This file is released under the GPLv2 - */ -#include - diff --git a/trunk/include/asm-avr32/io.h b/trunk/include/asm-avr32/io.h index eec47500fa66..2fc8f111dce9 100644 --- a/trunk/include/asm-avr32/io.h +++ b/trunk/include/asm-avr32/io.h @@ -76,39 +76,6 @@ static inline unsigned int readl(const volatile void __iomem *addr) #define readsw(p, d, l) __raw_readsw((unsigned int)p, d, l) #define readsl(p, d, l) __raw_readsl((unsigned int)p, d, l) - -/* - * io{read,write}{8,16,32} macros in both le (for PCI style consumers) and native be - */ -#ifndef ioread8 - -#define ioread8(p) ({ unsigned int __v = __raw_readb(p); __v; }) - -#define ioread16(p) ({ unsigned int __v = le16_to_cpu(__raw_readw(p)); __v; }) -#define ioread16be(p) ({ unsigned int __v = be16_to_cpu(__raw_readw(p)); __v; }) - -#define ioread32(p) ({ unsigned int __v = le32_to_cpu(__raw_readl(p)); __v; }) -#define ioread32be(p) ({ unsigned int __v = be32_to_cpu(__raw_readl(p)); __v; }) - -#define iowrite8(v,p) __raw_writeb(v, p) - -#define iowrite16(v,p) __raw_writew(cpu_to_le16(v), p) -#define iowrite16be(v,p) __raw_writew(cpu_to_be16(v), p) - -#define iowrite32(v,p) __raw_writel(cpu_to_le32(v), p) -#define iowrite32be(v,p) __raw_writel(cpu_to_be32(v), p) - -#define ioread8_rep(p,d,c) __raw_readsb(p,d,c) -#define ioread16_rep(p,d,c) __raw_readsw(p,d,c) -#define ioread32_rep(p,d,c) __raw_readsl(p,d,c) - -#define iowrite8_rep(p,s,c) __raw_writesb(p,s,c) -#define iowrite16_rep(p,s,c) __raw_writesw(p,s,c) -#define iowrite32_rep(p,s,c) __raw_writesl(p,s,c) - -#endif - - /* * These two are only here because ALSA _thinks_ it needs them... */ diff --git a/trunk/include/asm-avr32/irq_regs.h b/trunk/include/asm-avr32/irq_regs.h deleted file mode 100644 index 3dd9c0b70270..000000000000 --- a/trunk/include/asm-avr32/irq_regs.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/include/asm-avr32/unistd.h b/trunk/include/asm-avr32/unistd.h index 56ed1f9d348a..a50e5004550c 100644 --- a/trunk/include/asm-avr32/unistd.h +++ b/trunk/include/asm-avr32/unistd.h @@ -280,10 +280,9 @@ #define __NR_sync_file_range 262 #define __NR_tee 263 #define __NR_vmsplice 264 -#define __NR_epoll_pwait 265 #ifdef __KERNEL__ -#define NR_syscalls 266 +#define NR_syscalls 265 #define __ARCH_WANT_IPC_PARSE_VERSION diff --git a/trunk/include/asm-cris/device.h b/trunk/include/asm-cris/device.h deleted file mode 100644 index d8f9872b0e2d..000000000000 --- a/trunk/include/asm-cris/device.h +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Arch specific extensions to struct device - * - * This file is released under the GPLv2 - */ -#include - diff --git a/trunk/include/asm-frv/device.h b/trunk/include/asm-frv/device.h deleted file mode 100644 index d8f9872b0e2d..000000000000 --- a/trunk/include/asm-frv/device.h +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Arch specific extensions to struct device - * - * This file is released under the GPLv2 - */ -#include - diff --git a/trunk/include/asm-frv/dma.h b/trunk/include/asm-frv/dma.h index 683c47d48a5b..18d6bb8f84fc 100644 --- a/trunk/include/asm-frv/dma.h +++ b/trunk/include/asm-frv/dma.h @@ -24,7 +24,10 @@ /* * FRV DMA controller management */ -typedef irqreturn_t (*dma_irq_handler_t)(int dmachan, unsigned long cstr, void *data); +struct pt_regs; + +typedef irqreturn_t (*dma_irq_handler_t)(int dmachan, unsigned long cstr, void *data, + struct pt_regs *regs); extern void frv_dma_init(void); diff --git a/trunk/include/asm-frv/highmem.h b/trunk/include/asm-frv/highmem.h index 0f390f41f816..e2247c22a638 100644 --- a/trunk/include/asm-frv/highmem.h +++ b/trunk/include/asm-frv/highmem.h @@ -82,11 +82,11 @@ extern struct page *kmap_atomic_to_page(void *ptr); dampr = paddr | xAMPRx_L | xAMPRx_M | xAMPRx_S | xAMPRx_SS_16Kb | xAMPRx_V; \ \ if (type != __KM_CACHE) \ - asm volatile("movgs %0,dampr"#ampr :: "r"(dampr) : "memory"); \ + asm volatile("movgs %0,dampr"#ampr :: "r"(dampr)); \ else \ asm volatile("movgs %0,iampr"#ampr"\n" \ "movgs %0,dampr"#ampr"\n" \ - :: "r"(dampr) : "memory" \ + :: "r"(dampr) \ ); \ \ asm("movsg damlr"#ampr",%0" : "=r"(damlr)); \ @@ -104,7 +104,7 @@ extern struct page *kmap_atomic_to_page(void *ptr); asm volatile("movgs %0,tplr \n" \ "movgs %1,tppr \n" \ "tlbpr %0,gr0,#2,#1" \ - : : "r"(damlr), "r"(dampr) : "memory"); \ + : : "r"(damlr), "r"(dampr)); \ \ /*printk("TLB: SECN sl=%d L=%08lx P=%08lx\n", slot, damlr, dampr);*/ \ \ @@ -115,7 +115,7 @@ static inline void *kmap_atomic(struct page *page, enum km_type type) { unsigned long paddr; - inc_preempt_count(); + preempt_disable(); paddr = page_to_phys(page); switch (type) { @@ -138,16 +138,16 @@ static inline void *kmap_atomic(struct page *page, enum km_type type) } } -#define __kunmap_atomic_primary(type, ampr) \ -do { \ - asm volatile("movgs gr0,dampr"#ampr"\n" ::: "memory"); \ - if (type == __KM_CACHE) \ - asm volatile("movgs gr0,iampr"#ampr"\n" ::: "memory"); \ +#define __kunmap_atomic_primary(type, ampr) \ +do { \ + asm volatile("movgs gr0,dampr"#ampr"\n"); \ + if (type == __KM_CACHE) \ + asm volatile("movgs gr0,iampr"#ampr"\n"); \ } while(0) -#define __kunmap_atomic_secondary(slot, vaddr) \ -do { \ - asm volatile("tlbpr %0,gr0,#4,#1" : : "r"(vaddr) : "memory"); \ +#define __kunmap_atomic_secondary(slot, vaddr) \ +do { \ + asm volatile("tlbpr %0,gr0,#4,#1" : : "r"(vaddr)); \ } while(0) static inline void kunmap_atomic(void *kvaddr, enum km_type type) @@ -170,8 +170,7 @@ static inline void kunmap_atomic(void *kvaddr, enum km_type type) default: BUG(); } - dec_preempt_count(); - preempt_check_resched(); + preempt_enable(); } #endif /* !__ASSEMBLY__ */ diff --git a/trunk/include/asm-frv/io.h b/trunk/include/asm-frv/io.h index 20e44fe00abf..7765f5528894 100644 --- a/trunk/include/asm-frv/io.h +++ b/trunk/include/asm-frv/io.h @@ -385,6 +385,27 @@ static inline void pci_iounmap(struct pci_dev *dev, void __iomem *p) */ #define xlate_dev_kmem_ptr(p) p +/* + * Check BIOS signature + */ +static inline int check_signature(volatile void __iomem *io_addr, + const unsigned char *signature, int length) +{ + int retval = 0; + + do { + if (readb(io_addr) != *signature) + goto out; + io_addr++; + signature++; + length--; + } while (length); + + retval = 1; +out: + return retval; +} + #endif /* __KERNEL__ */ #endif /* _ASM_IO_H */ diff --git a/trunk/include/asm-frv/irq_regs.h b/trunk/include/asm-frv/irq_regs.h deleted file mode 100644 index d22e83289ad1..000000000000 --- a/trunk/include/asm-frv/irq_regs.h +++ /dev/null @@ -1,27 +0,0 @@ -/* FRV per-CPU frame pointer holder - * - * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. - * Written by David Howells (dhowells@redhat.com) - * - * 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. - */ - -#ifndef _ASM_IRQ_REGS_H -#define _ASM_IRQ_REGS_H - -/* - * Per-cpu current frame pointer - the location of the last exception frame on - * the stack - * - on FRV, GR28 is dedicated to keeping a pointer to the current exception - * frame - */ -#define ARCH_HAS_OWN_IRQ_REGS - -#ifndef __ASSEMBLY__ -#define get_irq_regs() (__frame) -#endif - -#endif /* _ASM_IRQ_REGS_H */ diff --git a/trunk/include/asm-frv/ptrace.h b/trunk/include/asm-frv/ptrace.h index 9a2241b8eb1e..7ff525162a72 100644 --- a/trunk/include/asm-frv/ptrace.h +++ b/trunk/include/asm-frv/ptrace.h @@ -12,7 +12,6 @@ #define _ASM_PTRACE_H #include -#include #define in_syscall(regs) (((regs)->tbr & TBR_TT) == TBR_TT_TRAP0) diff --git a/trunk/include/asm-generic/bitops/sched.h b/trunk/include/asm-generic/bitops/sched.h index 815bb0148060..5ef93a4d009f 100644 --- a/trunk/include/asm-generic/bitops/sched.h +++ b/trunk/include/asm-generic/bitops/sched.h @@ -15,7 +15,7 @@ static inline int sched_find_first_bit(const unsigned long *b) #if BITS_PER_LONG == 64 if (unlikely(b[0])) return __ffs(b[0]); - if (likely(b[1])) + if (unlikely(b[1])) return __ffs(b[1]) + 64; return __ffs(b[2]) + 128; #elif BITS_PER_LONG == 32 diff --git a/trunk/include/asm-generic/bug.h b/trunk/include/asm-generic/bug.h index c92ae0f166ff..a5250895155e 100644 --- a/trunk/include/asm-generic/bug.h +++ b/trunk/include/asm-generic/bug.h @@ -37,21 +37,18 @@ #endif #ifndef HAVE_ARCH_WARN_ON -#define WARN_ON(condition) ({ \ - typeof(condition) __ret_warn_on = (condition); \ - unlikely(__ret_warn_on); \ -}) +#define WARN_ON(condition) unlikely((condition)) #endif #endif -#define WARN_ON_ONCE(condition) ({ \ - static int __warned; \ - typeof(condition) __ret_warn_once = (condition); \ - \ - if (unlikely(__ret_warn_once)) \ - if (WARN_ON(!__warned)) \ - __warned = 1; \ - unlikely(__ret_warn_once); \ +#define WARN_ON_ONCE(condition) ({ \ + static int __warn_once = 1; \ + typeof(condition) __ret_warn_once = (condition);\ + \ + if (likely(__warn_once)) \ + if (WARN_ON(__ret_warn_once)) \ + __warn_once = 0; \ + unlikely(__ret_warn_once); \ }) #ifdef CONFIG_SMP diff --git a/trunk/include/asm-generic/device.h b/trunk/include/asm-generic/device.h deleted file mode 100644 index c17c9600f220..000000000000 --- a/trunk/include/asm-generic/device.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Arch specific extensions to struct device - * - * This file is released under the GPLv2 - */ -#ifndef _ASM_GENERIC_DEVICE_H -#define _ASM_GENERIC_DEVICE_H - -struct dev_archdata { -}; - -#endif /* _ASM_GENERIC_DEVICE_H */ diff --git a/trunk/include/asm-generic/irq_regs.h b/trunk/include/asm-generic/irq_regs.h deleted file mode 100644 index 5ae1d07d4a12..000000000000 --- a/trunk/include/asm-generic/irq_regs.h +++ /dev/null @@ -1,37 +0,0 @@ -/* Fallback per-CPU frame pointer holder - * - * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. - * Written by David Howells (dhowells@redhat.com) - * - * 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. - */ - -#ifndef _ASM_GENERIC_IRQ_REGS_H -#define _ASM_GENERIC_IRQ_REGS_H - -#include - -/* - * Per-cpu current frame pointer - the location of the last exception frame on - * the stack - */ -DECLARE_PER_CPU(struct pt_regs *, __irq_regs); - -static inline struct pt_regs *get_irq_regs(void) -{ - return __get_cpu_var(__irq_regs); -} - -static inline struct pt_regs *set_irq_regs(struct pt_regs *new_regs) -{ - struct pt_regs *old_regs, **pp_regs = &__get_cpu_var(__irq_regs); - - old_regs = *pp_regs; - *pp_regs = new_regs; - return old_regs; -} - -#endif /* _ASM_GENERIC_IRQ_REGS_H */ diff --git a/trunk/include/asm-generic/percpu.h b/trunk/include/asm-generic/percpu.h index 196376262240..6d45ee5472af 100644 --- a/trunk/include/asm-generic/percpu.h +++ b/trunk/include/asm-generic/percpu.h @@ -15,7 +15,7 @@ extern unsigned long __per_cpu_offset[NR_CPUS]; /* var is in discarded region: offset to particular copy we want */ #define per_cpu(var, cpu) (*({ \ - extern int simple_identifier_##var(void); \ + extern int simple_indentifier_##var(void); \ RELOC_HIDE(&per_cpu__##var, __per_cpu_offset[cpu]); })) #define __get_cpu_var(var) per_cpu(var, smp_processor_id()) #define __raw_get_cpu_var(var) per_cpu(var, raw_smp_processor_id()) diff --git a/trunk/include/asm-generic/vmlinux.lds.h b/trunk/include/asm-generic/vmlinux.lds.h index e60d6f21fa62..69240b52f8e1 100644 --- a/trunk/include/asm-generic/vmlinux.lds.h +++ b/trunk/include/asm-generic/vmlinux.lds.h @@ -125,10 +125,6 @@ *(__param) \ VMLINUX_SYMBOL(__stop___param) = .; \ } \ - \ - /* Unwind data binary search table */ \ - EH_FRAME_HDR \ - \ __end_rodata = .; \ . = ALIGN(4096); @@ -161,18 +157,6 @@ *(.kprobes.text) \ VMLINUX_SYMBOL(__kprobes_text_end) = .; -#ifdef CONFIG_STACK_UNWIND - /* 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) = .; \ - } -#else -#define EH_FRAME_HDR -#endif - /* DWARF debug sections. Symbols in the DWARF debugging sections are relative to the beginning of the section so we begin them at 0. */ @@ -213,22 +197,3 @@ #define NOTES \ .notes : { *(.note.*) } :note - -#define INITCALLS \ - *(.initcall0.init) \ - *(.initcall0s.init) \ - *(.initcall1.init) \ - *(.initcall1s.init) \ - *(.initcall2.init) \ - *(.initcall2s.init) \ - *(.initcall3.init) \ - *(.initcall3s.init) \ - *(.initcall4.init) \ - *(.initcall4s.init) \ - *(.initcall5.init) \ - *(.initcall5s.init) \ - *(.initcall6.init) \ - *(.initcall6s.init) \ - *(.initcall7.init) \ - *(.initcall7s.init) - diff --git a/trunk/include/asm-h8300/device.h b/trunk/include/asm-h8300/device.h deleted file mode 100644 index d8f9872b0e2d..000000000000 --- a/trunk/include/asm-h8300/device.h +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Arch specific extensions to struct device - * - * This file is released under the GPLv2 - */ -#include - diff --git a/trunk/include/asm-i386/acpi.h b/trunk/include/asm-i386/acpi.h index c80b3a94511a..6016632d032f 100644 --- a/trunk/include/asm-i386/acpi.h +++ b/trunk/include/asm-i386/acpi.h @@ -132,7 +132,6 @@ extern int acpi_gsi_to_irq(u32 gsi, unsigned int *irq); #ifdef CONFIG_X86_IO_APIC extern int acpi_skip_timer_override; -extern int acpi_use_timer_override; #endif static inline void acpi_noirq_set(void) { acpi_noirq = 1; } diff --git a/trunk/include/asm-i386/apic.h b/trunk/include/asm-i386/apic.h index b9529578fc37..3a42b7d6fc92 100644 --- a/trunk/include/asm-i386/apic.h +++ b/trunk/include/asm-i386/apic.h @@ -98,7 +98,7 @@ extern void sync_Arb_IDs (void); extern void init_bsp_APIC (void); extern void setup_local_APIC (void); extern void init_apic_mappings (void); -extern void smp_local_timer_interrupt (void); +extern void smp_local_timer_interrupt (struct pt_regs * regs); extern void setup_boot_APIC_clock (void); extern void setup_secondary_APIC_clock (void); extern int APIC_init_uniprocessor (void); @@ -107,7 +107,7 @@ extern void enable_APIC_timer(void); extern void enable_NMI_through_LVT0 (void * dummy); -void smp_send_timer_broadcast_ipi(void); +void smp_send_timer_broadcast_ipi(struct pt_regs *regs); void switch_APIC_timer_to_ipi(void *cpumask); void switch_ipi_to_APIC_timer(void *cpumask); #define ARCH_APICTIMER_STOPS_ON_C3 1 diff --git a/trunk/include/asm-i386/arch_hooks.h b/trunk/include/asm-i386/arch_hooks.h index a8c1fca9726d..238cf4275b96 100644 --- a/trunk/include/asm-i386/arch_hooks.h +++ b/trunk/include/asm-i386/arch_hooks.h @@ -14,7 +14,7 @@ extern void init_ISA_irqs(void); extern void apic_intr_init(void); extern void smp_intr_init(void); -extern irqreturn_t timer_interrupt(int irq, void *dev_id); +extern irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs); /* these are the defined hooks */ extern void intr_init_hook(void); diff --git a/trunk/include/asm-i386/device.h b/trunk/include/asm-i386/device.h deleted file mode 100644 index 849604c70e6b..000000000000 --- a/trunk/include/asm-i386/device.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Arch specific extensions to struct device - * - * This file is released under the GPLv2 - */ -#ifndef _ASM_I386_DEVICE_H -#define _ASM_I386_DEVICE_H - -struct dev_archdata { -#ifdef CONFIG_ACPI - void *acpi_handle; -#endif -}; - -#endif /* _ASM_I386_DEVICE_H */ diff --git a/trunk/include/asm-i386/floppy.h b/trunk/include/asm-i386/floppy.h index 44ef2f55a8e9..359ead60b718 100644 --- a/trunk/include/asm-i386/floppy.h +++ b/trunk/include/asm-i386/floppy.h @@ -51,7 +51,7 @@ static char *virtual_dma_addr; static int virtual_dma_mode; static int doing_pdma; -static irqreturn_t floppy_hardint(int irq, void *dev_id) +static irqreturn_t floppy_hardint(int irq, void *dev_id, struct pt_regs * regs) { register unsigned char st; @@ -63,7 +63,7 @@ static irqreturn_t floppy_hardint(int irq, void *dev_id) static int dma_wait=0; #endif if (!doing_pdma) - return floppy_interrupt(irq, dev_id); + return floppy_interrupt(irq, dev_id, regs); #ifdef TRACE_FLPY_INT if(!calls) @@ -106,7 +106,7 @@ static irqreturn_t floppy_hardint(int irq, void *dev_id) dma_wait=0; #endif doing_pdma = 0; - floppy_interrupt(irq, dev_id); + floppy_interrupt(irq, dev_id, regs); return IRQ_HANDLED; } #ifdef TRACE_FLPY_INT diff --git a/trunk/include/asm-i386/hpet.h b/trunk/include/asm-i386/hpet.h index e47be9a56cc2..af5d435519d1 100644 --- a/trunk/include/asm-i386/hpet.h +++ b/trunk/include/asm-i386/hpet.h @@ -108,7 +108,7 @@ extern int hpet_set_alarm_time(unsigned char hrs, unsigned char min, unsigned ch extern int hpet_set_periodic_freq(unsigned long freq); extern int hpet_rtc_dropped_irq(void); extern int hpet_rtc_timer_init(void); -extern irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id); +extern irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs); #endif /* CONFIG_HPET_EMULATE_RTC */ #endif /* CONFIG_HPET_TIMER */ #endif /* _I386_HPET_H */ diff --git a/trunk/include/asm-i386/hw_irq.h b/trunk/include/asm-i386/hw_irq.h index 0bedbdf5e907..88f02a073561 100644 --- a/trunk/include/asm-i386/hw_irq.h +++ b/trunk/include/asm-i386/hw_irq.h @@ -26,6 +26,9 @@ * Interrupt entry/exit code at both C and assembly level */ +extern u8 irq_vector[NR_IRQ_VECTORS]; +#define IO_APIC_VECTOR(irq) (irq_vector[irq]) + extern void (*interrupt[NR_IRQS])(void); #ifdef CONFIG_SMP @@ -38,7 +41,7 @@ fastcall void call_function_interrupt(void); fastcall void apic_timer_interrupt(void); fastcall void error_interrupt(void); fastcall void spurious_interrupt(void); -fastcall void thermal_interrupt(void); +fastcall void thermal_interrupt(struct pt_regs *); #define platform_legacy_irq(irq) ((irq) < 16) #endif diff --git a/trunk/include/asm-i386/io.h b/trunk/include/asm-i386/io.h index 68df0dc3ab8f..b3724fe93ff1 100644 --- a/trunk/include/asm-i386/io.h +++ b/trunk/include/asm-i386/io.h @@ -224,6 +224,33 @@ static inline void memcpy_toio(volatile void __iomem *dst, const void *src, int #define eth_io_copy_and_sum(a,b,c,d) eth_copy_and_sum((a),(void __force *)(b),(c),(d)) +/** + * check_signature - find BIOS signatures + * @io_addr: mmio address to check + * @signature: signature block + * @length: length of signature + * + * Perform a signature comparison with the mmio address io_addr. This + * address should have been obtained by ioremap. + * Returns 1 on a match. + */ + +static inline int check_signature(volatile void __iomem * io_addr, + const unsigned char *signature, int length) +{ + int retval = 0; + do { + if (readb(io_addr) != *signature) + goto out; + io_addr++; + signature++; + length--; + } while (length); + retval = 1; +out: + return retval; +} + /* * Cache management * diff --git a/trunk/include/asm-i386/io_apic.h b/trunk/include/asm-i386/io_apic.h index 059a9ff28b4d..276ea7e8144a 100644 --- a/trunk/include/asm-i386/io_apic.h +++ b/trunk/include/asm-i386/io_apic.h @@ -12,6 +12,10 @@ #ifdef CONFIG_X86_IO_APIC +#define IO_APIC_BASE(idx) \ + ((volatile int *)(__fix_to_virt(FIX_IO_APIC_BASE_0 + idx) \ + + (mp_ioapics[idx].mpc_apicaddr & ~PAGE_MASK))) + /* * The structure of the IO-APIC: */ @@ -115,8 +119,31 @@ extern struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES]; /* non-0 if default (table-less) MP configuration */ extern int mpc_default_type; -/* Older SiS APIC requires we rewrite the index register */ +static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg) +{ + *IO_APIC_BASE(apic) = reg; + return *(IO_APIC_BASE(apic)+4); +} + +static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned int value) +{ + *IO_APIC_BASE(apic) = reg; + *(IO_APIC_BASE(apic)+4) = value; +} + +/* + * Re-write a value: to be used for read-modify-write + * cycles where the read already set up the index register. + * + * Older SiS APIC requires we rewrite the index regiser + */ extern int sis_apic_bug; +static inline void io_apic_modify(unsigned int apic, unsigned int reg, unsigned int value) +{ + if (sis_apic_bug) + *IO_APIC_BASE(apic) = reg; + *(IO_APIC_BASE(apic)+4) = value; +} /* 1 if "noapic" boot option passed */ extern int skip_ioapic_setup; diff --git a/trunk/include/asm-i386/irq_regs.h b/trunk/include/asm-i386/irq_regs.h deleted file mode 100644 index 3dd9c0b70270..000000000000 --- a/trunk/include/asm-i386/irq_regs.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/include/asm-i386/mach-default/do_timer.h b/trunk/include/asm-i386/mach-default/do_timer.h index 7d606e3364ae..4182c347ef85 100644 --- a/trunk/include/asm-i386/mach-default/do_timer.h +++ b/trunk/include/asm-i386/mach-default/do_timer.h @@ -14,11 +14,11 @@ * timer interrupt as a means of triggering reschedules etc. **/ -static inline void do_timer_interrupt_hook(void) +static inline void do_timer_interrupt_hook(struct pt_regs *regs) { do_timer(1); #ifndef CONFIG_SMP - update_process_times(user_mode_vm(get_irq_regs())); + update_process_times(user_mode_vm(regs)); #endif /* * In the SMP case we use the local APIC timer interrupt to do the @@ -26,10 +26,10 @@ static inline void do_timer_interrupt_hook(void) * system, in that case we have to call the local interrupt handler. */ #ifndef CONFIG_X86_LOCAL_APIC - profile_tick(CPU_PROFILING); + profile_tick(CPU_PROFILING, regs); #else if (!using_apic_timer) - smp_local_timer_interrupt(); + smp_local_timer_interrupt(regs); #endif } diff --git a/trunk/include/asm-i386/mach-summit/mach_apic.h b/trunk/include/asm-i386/mach-summit/mach_apic.h index 43e5bd8f4a19..ef0671e5d5c5 100644 --- a/trunk/include/asm-i386/mach-summit/mach_apic.h +++ b/trunk/include/asm-i386/mach-summit/mach_apic.h @@ -88,11 +88,7 @@ static inline void clustered_apic_check(void) static inline int apicid_to_node(int logical_apicid) { -#ifdef CONFIG_SMP return apicid_2_node[hard_smp_processor_id()]; -#else - return 0; -#endif } /* Mapping from cpu number to logical apicid */ diff --git a/trunk/include/asm-i386/mach-visws/do_timer.h b/trunk/include/asm-i386/mach-visws/do_timer.h new file mode 100644 index 000000000000..8db618c5a72b --- /dev/null +++ b/trunk/include/asm-i386/mach-visws/do_timer.h @@ -0,0 +1,53 @@ +/* defines for inline arch setup functions */ + +#include +#include +#include "cobalt.h" + +static inline void do_timer_interrupt_hook(struct pt_regs *regs) +{ + /* Clear the interrupt */ + co_cpu_write(CO_CPU_STAT,co_cpu_read(CO_CPU_STAT) & ~CO_STAT_TIMEINTR); + + do_timer(1); +#ifndef CONFIG_SMP + update_process_times(user_mode_vm(regs)); +#endif +/* + * In the SMP case we use the local APIC timer interrupt to do the + * profiling, except when we simulate SMP mode on a uniprocessor + * system, in that case we have to call the local interrupt handler. + */ +#ifndef CONFIG_X86_LOCAL_APIC + profile_tick(CPU_PROFILING, regs); +#else + if (!using_apic_timer) + smp_local_timer_interrupt(regs); +#endif +} + +static inline int do_timer_overflow(int count) +{ + int i; + + spin_lock(&i8259A_lock); + /* + * This is tricky when I/O APICs are used; + * see do_timer_interrupt(). + */ + i = inb(0x20); + spin_unlock(&i8259A_lock); + + /* assumption about timer being IRQ0 */ + if (i & 0x01) { + /* + * We cannot detect lost timer interrupts ... + * well, that's why we call them lost, don't we? :) + * [hmm, on the Pentium and Alpha we can ... sort of] + */ + count -= LATCH; + } else { + printk("do_slow_gettimeoffset(): hardware timer problem?\n"); + } + return count; +} diff --git a/trunk/include/asm-i386/mach-visws/mach_apic.h b/trunk/include/asm-i386/mach-visws/mach_apic.h index 18afe6b6fc4d..de438c7147a8 100644 --- a/trunk/include/asm-i386/mach-visws/mach_apic.h +++ b/trunk/include/asm-i386/mach-visws/mach_apic.h @@ -51,11 +51,6 @@ static inline void clustered_apic_check(void) { } -static inline int apicid_to_node(int logical_apicid) -{ - return 0; -} - /* Mapping from cpu number to logical apicid */ static inline int cpu_to_logical_apicid(int cpu) { diff --git a/trunk/include/asm-i386/mach-voyager/do_timer.h b/trunk/include/asm-i386/mach-voyager/do_timer.h index 04e69c104a74..099fe9f5c1b2 100644 --- a/trunk/include/asm-i386/mach-voyager/do_timer.h +++ b/trunk/include/asm-i386/mach-voyager/do_timer.h @@ -1,14 +1,14 @@ /* defines for inline arch setup functions */ #include -static inline void do_timer_interrupt_hook(void) +static inline void do_timer_interrupt_hook(struct pt_regs *regs) { do_timer(1); #ifndef CONFIG_SMP - update_process_times(user_mode_vm(irq_regs)); + update_process_times(user_mode_vm(regs)); #endif - voyager_timer_interrupt(); + voyager_timer_interrupt(regs); } static inline int do_timer_overflow(int count) diff --git a/trunk/include/asm-i386/processor.h b/trunk/include/asm-i386/processor.h index e0ddca94d50c..2277127696d2 100644 --- a/trunk/include/asm-i386/processor.h +++ b/trunk/include/asm-i386/processor.h @@ -306,8 +306,6 @@ static inline void __mwait(unsigned long eax, unsigned long ecx) : :"a" (eax), "c" (ecx)); } -extern void mwait_idle_with_hints(unsigned long eax, unsigned long ecx); - /* from system description table in BIOS. Mostly for MCA use, but others may find it useful. */ extern unsigned int machine_id; diff --git a/trunk/include/asm-i386/smp.h b/trunk/include/asm-i386/smp.h index bd59c1508e71..6aa1206f6e2a 100644 --- a/trunk/include/asm-i386/smp.h +++ b/trunk/include/asm-i386/smp.h @@ -46,6 +46,8 @@ extern u8 x86_cpu_to_apicid[]; #define cpu_physical_id(cpu) x86_cpu_to_apicid[cpu] +extern u8 apicid_2_node[]; + #ifdef CONFIG_HOTPLUG_CPU extern void cpu_exit_clear(void); extern void cpu_uninit(void); @@ -99,9 +101,6 @@ extern unsigned int num_processors; #endif #ifndef __ASSEMBLY__ - -extern u8 apicid_2_node[]; - #ifdef CONFIG_X86_LOCAL_APIC static __inline int logical_smp_processor_id(void) { diff --git a/trunk/include/asm-i386/uaccess.h b/trunk/include/asm-i386/uaccess.h index eef5133b9ce2..54d905ebc63d 100644 --- a/trunk/include/asm-i386/uaccess.h +++ b/trunk/include/asm-i386/uaccess.h @@ -404,6 +404,20 @@ unsigned long __must_check __copy_from_user_ll_nocache_nozero(void *to, * anything, so this is accurate. */ +/** + * __copy_to_user: - Copy a block of data into user space, with less checking. + * @to: Destination address, in user space. + * @from: Source address, in kernel space. + * @n: Number of bytes to copy. + * + * Context: User context only. This function may sleep. + * + * Copy data from kernel space to user space. Caller must check + * the specified block with access_ok() before calling this function. + * + * Returns number of bytes that could not be copied. + * On success, this will be zero. + */ static __always_inline unsigned long __must_check __copy_to_user_inatomic(void __user *to, const void *from, unsigned long n) { @@ -425,27 +439,35 @@ __copy_to_user_inatomic(void __user *to, const void *from, unsigned long n) return __copy_to_user_ll(to, from, n); } +static __always_inline unsigned long __must_check +__copy_to_user(void __user *to, const void *from, unsigned long n) +{ + might_sleep(); + return __copy_to_user_inatomic(to, from, n); +} + /** - * __copy_to_user: - Copy a block of data into user space, with less checking. - * @to: Destination address, in user space. - * @from: Source address, in kernel space. + * __copy_from_user: - Copy a block of data from user space, with less checking. + * @to: Destination address, in kernel space. + * @from: Source address, in user space. * @n: Number of bytes to copy. * * Context: User context only. This function may sleep. * - * Copy data from kernel space to user space. Caller must check + * Copy data from user space to kernel space. Caller must check * the specified block with access_ok() before calling this function. * * Returns number of bytes that could not be copied. * On success, this will be zero. + * + * If some data could not be copied, this function will pad the copied + * data to the requested size using zero bytes. + * + * An alternate version - __copy_from_user_inatomic() - may be called from + * atomic context and will fail rather than sleep. In this case the + * uncopied bytes will *NOT* be padded with zeros. See fs/filemap.h + * for explanation of why this is needed. */ -static __always_inline unsigned long __must_check -__copy_to_user(void __user *to, const void *from, unsigned long n) -{ - might_sleep(); - return __copy_to_user_inatomic(to, from, n); -} - static __always_inline unsigned long __copy_from_user_inatomic(void *to, const void __user *from, unsigned long n) { @@ -471,29 +493,6 @@ __copy_from_user_inatomic(void *to, const void __user *from, unsigned long n) } return __copy_from_user_ll_nozero(to, from, n); } - -/** - * __copy_from_user: - Copy a block of data from user space, with less checking. - * @to: Destination address, in kernel space. - * @from: Source address, in user space. - * @n: Number of bytes to copy. - * - * Context: User context only. This function may sleep. - * - * Copy data from user space to kernel space. Caller must check - * the specified block with access_ok() before calling this function. - * - * Returns number of bytes that could not be copied. - * On success, this will be zero. - * - * If some data could not be copied, this function will pad the copied - * data to the requested size using zero bytes. - * - * An alternate version - __copy_from_user_inatomic() - may be called from - * atomic context and will fail rather than sleep. In this case the - * uncopied bytes will *NOT* be padded with zeros. See fs/filemap.h - * for explanation of why this is needed. - */ static __always_inline unsigned long __copy_from_user(void *to, const void __user *from, unsigned long n) { diff --git a/trunk/include/asm-i386/unistd.h b/trunk/include/asm-i386/unistd.h index beeeaf6b054a..3ca7ab963d7d 100644 --- a/trunk/include/asm-i386/unistd.h +++ b/trunk/include/asm-i386/unistd.h @@ -324,11 +324,10 @@ #define __NR_vmsplice 316 #define __NR_move_pages 317 #define __NR_getcpu 318 -#define __NR_epoll_pwait 319 #ifdef __KERNEL__ -#define NR_syscalls 320 +#define NR_syscalls 319 #include /* diff --git a/trunk/include/asm-i386/vic.h b/trunk/include/asm-i386/vic.h index 53100f353612..4abfcfb91eb8 100644 --- a/trunk/include/asm-i386/vic.h +++ b/trunk/include/asm-i386/vic.h @@ -58,4 +58,4 @@ static const int VIC_CPI_Registers[] = #define VIC_BOOT_INTERRUPT_MASK 0xfe -extern void smp_vic_timer_interrupt(void); +extern void smp_vic_timer_interrupt(struct pt_regs *regs); diff --git a/trunk/include/asm-i386/voyager.h b/trunk/include/asm-i386/voyager.h index 5b27838905b2..aaf432dd7673 100644 --- a/trunk/include/asm-i386/voyager.h +++ b/trunk/include/asm-i386/voyager.h @@ -118,33 +118,33 @@ typedef struct voyager_module { } voyager_module_t; typedef struct voyager_eeprom_hdr { - __u8 module_id[4]; - __u8 version_id; - __u8 config_id; - __u16 boundry_id; /* boundary scan id */ - __u16 ee_size; /* size of EEPROM */ - __u8 assembly[11]; /* assembly # */ - __u8 assembly_rev; /* assembly rev */ - __u8 tracer[4]; /* tracer number */ - __u16 assembly_cksum; /* asm checksum */ - __u16 power_consump; /* pwr requirements */ - __u16 num_asics; /* number of asics */ - __u16 bist_time; /* min. bist time */ - __u16 err_log_offset; /* error log offset */ - __u16 scan_path_offset;/* scan path offset */ - __u16 cct_offset; - __u16 log_length; /* length of err log */ - __u16 xsum_end; /* offset to end of + __u8 module_id[4] __attribute__((packed)); + __u8 version_id __attribute__((packed)); + __u8 config_id __attribute__((packed)); + __u16 boundry_id __attribute__((packed)); /* boundary scan id */ + __u16 ee_size __attribute__((packed)); /* size of EEPROM */ + __u8 assembly[11] __attribute__((packed)); /* assembly # */ + __u8 assembly_rev __attribute__((packed)); /* assembly rev */ + __u8 tracer[4] __attribute__((packed)); /* tracer number */ + __u16 assembly_cksum __attribute__((packed)); /* asm checksum */ + __u16 power_consump __attribute__((packed)); /* pwr requirements */ + __u16 num_asics __attribute__((packed)); /* number of asics */ + __u16 bist_time __attribute__((packed)); /* min. bist time */ + __u16 err_log_offset __attribute__((packed)); /* error log offset */ + __u16 scan_path_offset __attribute__((packed));/* scan path offset */ + __u16 cct_offset __attribute__((packed)); + __u16 log_length __attribute__((packed)); /* length of err log */ + __u16 xsum_end __attribute__((packed)); /* offset to end of checksum */ - __u8 reserved[4]; - __u8 sflag; /* starting sentinal */ - __u8 part_number[13]; /* prom part number */ - __u8 version[10]; /* version number */ - __u8 signature[8]; - __u16 eeprom_chksum; - __u32 data_stamp_offset; - __u8 eflag ; /* ending sentinal */ -} __attribute__((packed)) voyager_eprom_hdr_t; + __u8 reserved[4] __attribute__((packed)); + __u8 sflag __attribute__((packed)); /* starting sentinal */ + __u8 part_number[13] __attribute__((packed)); /* prom part number */ + __u8 version[10] __attribute__((packed)); /* version number */ + __u8 signature[8] __attribute__((packed)); + __u16 eeprom_chksum __attribute__((packed)); + __u32 data_stamp_offset __attribute__((packed)); + __u8 eflag __attribute__((packed)); /* ending sentinal */ +} voyager_eprom_hdr_t; @@ -155,30 +155,30 @@ typedef struct voyager_eeprom_hdr { * in the module EPROMs. We really only care about the IDs and * offsets */ typedef struct voyager_sp_table { - __u8 asic_id; - __u8 bypass_flag; - __u16 asic_data_offset; - __u16 config_data_offset; -} __attribute__((packed)) voyager_sp_table_t; + __u8 asic_id __attribute__((packed)); + __u8 bypass_flag __attribute__((packed)); + __u16 asic_data_offset __attribute__((packed)); + __u16 config_data_offset __attribute__((packed)); +} voyager_sp_table_t; typedef struct voyager_jtag_table { - __u8 icode[4]; - __u8 runbist[4]; - __u8 intest[4]; - __u8 samp_preld[4]; - __u8 ireg_len; -} __attribute__((packed)) voyager_jtt_t; + __u8 icode[4] __attribute__((packed)); + __u8 runbist[4] __attribute__((packed)); + __u8 intest[4] __attribute__((packed)); + __u8 samp_preld[4] __attribute__((packed)); + __u8 ireg_len __attribute__((packed)); +} voyager_jtt_t; typedef struct voyager_asic_data_table { - __u8 jtag_id[4]; - __u16 length_bsr; - __u16 length_bist_reg; - __u32 bist_clk; - __u16 subaddr_bits; - __u16 seed_bits; - __u16 sig_bits; - __u16 jtag_offset; -} __attribute__((packed)) voyager_at_t; + __u8 jtag_id[4] __attribute__((packed)); + __u16 length_bsr __attribute__((packed)); + __u16 length_bist_reg __attribute__((packed)); + __u32 bist_clk __attribute__((packed)); + __u16 subaddr_bits __attribute__((packed)); + __u16 seed_bits __attribute__((packed)); + __u16 sig_bits __attribute__((packed)); + __u16 jtag_offset __attribute__((packed)); +} voyager_at_t; /* Voyager Interrupt Controller (VIC) registers */ @@ -328,52 +328,52 @@ struct voyager_bios_info { #define NUMBER_OF_POS_REGS 8 typedef struct { - __u8 MC_Slot; - __u8 POS_Values[NUMBER_OF_POS_REGS]; -} __attribute__((packed)) MC_SlotInformation_t; + __u8 MC_Slot __attribute__((packed)); + __u8 POS_Values[NUMBER_OF_POS_REGS] __attribute__((packed)); +} MC_SlotInformation_t; struct QuadDescription { - __u8 Type; /* for type 0 (DYADIC or MONADIC) all fields + __u8 Type __attribute__((packed)); /* for type 0 (DYADIC or MONADIC) all fields * will be zero except for slot */ - __u8 StructureVersion; - __u32 CPI_BaseAddress; - __u32 LARC_BankSize; - __u32 LocalMemoryStateBits; - __u8 Slot; /* Processor slots 1 - 4 */ -} __attribute__((packed)); + __u8 StructureVersion __attribute__((packed)); + __u32 CPI_BaseAddress __attribute__((packed)); + __u32 LARC_BankSize __attribute__((packed)); + __u32 LocalMemoryStateBits __attribute__((packed)); + __u8 Slot __attribute__((packed)); /* Processor slots 1 - 4 */ +}; struct ProcBoardInfo { - __u8 Type; - __u8 StructureVersion; - __u8 NumberOfBoards; - struct QuadDescription QuadData[MAX_PROCESSOR_BOARDS]; -} __attribute__((packed)); + __u8 Type __attribute__((packed)); + __u8 StructureVersion __attribute__((packed)); + __u8 NumberOfBoards __attribute__((packed)); + struct QuadDescription QuadData[MAX_PROCESSOR_BOARDS] __attribute__((packed)); +}; struct CacheDescription { - __u8 Level; - __u32 TotalSize; - __u16 LineSize; - __u8 Associativity; - __u8 CacheType; - __u8 WriteType; - __u8 Number_CPUs_SharedBy; - __u8 Shared_CPUs_Hardware_IDs[MAX_SHARED_CPUS]; + __u8 Level __attribute__((packed)); + __u32 TotalSize __attribute__((packed)); + __u16 LineSize __attribute__((packed)); + __u8 Associativity __attribute__((packed)); + __u8 CacheType __attribute__((packed)); + __u8 WriteType __attribute__((packed)); + __u8 Number_CPUs_SharedBy __attribute__((packed)); + __u8 Shared_CPUs_Hardware_IDs[MAX_SHARED_CPUS] __attribute__((packed)); -} __attribute__((packed)); +}; struct CPU_Description { - __u8 CPU_HardwareId; - char *FRU_String; - __u8 NumberOfCacheLevels; - struct CacheDescription CacheLevelData[MAX_CACHE_LEVELS]; -} __attribute__((packed)); + __u8 CPU_HardwareId __attribute__((packed)); + char *FRU_String __attribute__((packed)); + __u8 NumberOfCacheLevels __attribute__((packed)); + struct CacheDescription CacheLevelData[MAX_CACHE_LEVELS] __attribute__((packed)); +}; struct CPU_Info { - __u8 Type; - __u8 StructureVersion; - __u8 NumberOf_CPUs; - struct CPU_Description CPU_Data[MAX_CPUS]; -} __attribute__((packed)); + __u8 Type __attribute__((packed)); + __u8 StructureVersion __attribute__((packed)); + __u8 NumberOf_CPUs __attribute__((packed)); + struct CPU_Description CPU_Data[MAX_CPUS] __attribute__((packed)); +}; /* @@ -505,8 +505,8 @@ extern int voyager_memory_detect(int region, __u32 *addr, __u32 *length); extern void voyager_smp_intr_init(void); extern __u8 voyager_extended_cmos_read(__u16 cmos_address); extern void voyager_smp_dump(void); -extern void voyager_timer_interrupt(void); -extern void smp_local_timer_interrupt(void); +extern void voyager_timer_interrupt(struct pt_regs *regs); +extern void smp_local_timer_interrupt(struct pt_regs * regs); extern void voyager_power_off(void); extern void smp_voyager_power_off(void *dummy); extern void voyager_restart(void); diff --git a/trunk/include/asm-ia64/device.h b/trunk/include/asm-ia64/device.h deleted file mode 100644 index 3db6daf7f251..000000000000 --- a/trunk/include/asm-ia64/device.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Arch specific extensions to struct device - * - * This file is released under the GPLv2 - */ -#ifndef _ASM_IA64_DEVICE_H -#define _ASM_IA64_DEVICE_H - -struct dev_archdata { -#ifdef CONFIG_ACPI - void *acpi_handle; -#endif -}; - -#endif /* _ASM_IA64_DEVICE_H */ diff --git a/trunk/include/asm-ia64/io.h b/trunk/include/asm-ia64/io.h index 6311e168cd34..43bfff6c6b87 100644 --- a/trunk/include/asm-ia64/io.h +++ b/trunk/include/asm-ia64/io.h @@ -32,7 +32,7 @@ */ #define IO_SPACE_LIMIT 0xffffffffffffffffUL -#define MAX_IO_SPACES_BITS 8 +#define MAX_IO_SPACES_BITS 4 #define MAX_IO_SPACES (1UL << MAX_IO_SPACES_BITS) #define IO_SPACE_BITS 24 #define IO_SPACE_SIZE (1UL << IO_SPACE_BITS) @@ -417,8 +417,6 @@ __writeq (unsigned long val, volatile void __iomem *addr) # define outl_p outl #endif -# ifdef __KERNEL__ - extern void __iomem * ioremap(unsigned long offset, unsigned long size); extern void __iomem * ioremap_nocache (unsigned long offset, unsigned long size); @@ -432,6 +430,8 @@ iounmap (volatile void __iomem *addr) #define dmi_iounmap(x,l) iounmap(x) #define dmi_alloc(l) kmalloc(l, GFP_ATOMIC) +# ifdef __KERNEL__ + /* * String version of IO memory access ops: */ diff --git a/trunk/include/asm-ia64/irq_regs.h b/trunk/include/asm-ia64/irq_regs.h deleted file mode 100644 index 3dd9c0b70270..000000000000 --- a/trunk/include/asm-ia64/irq_regs.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/include/asm-ia64/machvec.h b/trunk/include/asm-ia64/machvec.h index 8f784f8e45b0..90cba967df35 100644 --- a/trunk/include/asm-ia64/machvec.h +++ b/trunk/include/asm-ia64/machvec.h @@ -26,7 +26,7 @@ typedef void ia64_mv_setup_t (char **); typedef void ia64_mv_cpu_init_t (void); typedef void ia64_mv_irq_init_t (void); typedef void ia64_mv_send_ipi_t (int, int, int, int); -typedef void ia64_mv_timer_interrupt_t (int, void *); +typedef void ia64_mv_timer_interrupt_t (int, void *, struct pt_regs *); typedef void ia64_mv_global_tlb_purge_t (struct mm_struct *, unsigned long, unsigned long, unsigned long); typedef void ia64_mv_tlb_migrate_finish_t (struct mm_struct *); typedef unsigned int ia64_mv_local_vector_to_irq (u8); @@ -36,7 +36,6 @@ typedef int ia64_mv_pci_legacy_read_t (struct pci_bus *, u16 port, u32 *val, typedef int ia64_mv_pci_legacy_write_t (struct pci_bus *, u16 port, u32 val, u8 size); typedef void ia64_mv_migrate_t(struct task_struct * task); -typedef void ia64_mv_pci_fixup_bus_t (struct pci_bus *); /* DMA-mapping interface: */ typedef void ia64_mv_dma_init (void); @@ -96,13 +95,8 @@ machvec_noop_task (struct task_struct *task) { } -static inline void -machvec_noop_bus (struct pci_bus *bus) -{ -} - extern void machvec_setup (char **); -extern void machvec_timer_interrupt (int, void *); +extern void machvec_timer_interrupt (int, void *, struct pt_regs *); extern void machvec_dma_sync_single (struct device *, dma_addr_t, size_t, int); extern void machvec_dma_sync_sg (struct device *, struct scatterlist *, int, int); extern void machvec_tlb_migrate_finish (struct mm_struct *); @@ -165,7 +159,6 @@ extern void machvec_tlb_migrate_finish (struct mm_struct *); # define platform_migrate ia64_mv.migrate # define platform_setup_msi_irq ia64_mv.setup_msi_irq # define platform_teardown_msi_irq ia64_mv.teardown_msi_irq -# define platform_pci_fixup_bus ia64_mv.pci_fixup_bus # endif /* __attribute__((__aligned__(16))) is required to make size of the @@ -217,7 +210,6 @@ struct ia64_machine_vector { ia64_mv_migrate_t *migrate; ia64_mv_setup_msi_irq_t *setup_msi_irq; ia64_mv_teardown_msi_irq_t *teardown_msi_irq; - ia64_mv_pci_fixup_bus_t *pci_fixup_bus; } __attribute__((__aligned__(16))); /* align attrib? see above comment */ #define MACHVEC_INIT(name) \ @@ -265,7 +257,6 @@ struct ia64_machine_vector { platform_migrate, \ platform_setup_msi_irq, \ platform_teardown_msi_irq, \ - platform_pci_fixup_bus, \ } extern struct ia64_machine_vector ia64_mv; @@ -425,8 +416,5 @@ extern int ia64_pci_legacy_write(struct pci_bus *bus, u16 port, u32 val, u8 size #ifndef platform_teardown_msi_irq # define platform_teardown_msi_irq ((ia64_mv_teardown_msi_irq_t*)NULL) #endif -#ifndef platform_pci_fixup_bus -# define platform_pci_fixup_bus machvec_noop_bus -#endif #endif /* _ASM_IA64_MACHVEC_H */ diff --git a/trunk/include/asm-ia64/machvec_sn2.h b/trunk/include/asm-ia64/machvec_sn2.h index 83325f6db03e..c54b165b1c17 100644 --- a/trunk/include/asm-ia64/machvec_sn2.h +++ b/trunk/include/asm-ia64/machvec_sn2.h @@ -69,7 +69,6 @@ extern ia64_mv_dma_supported sn_dma_supported; extern ia64_mv_migrate_t sn_migrate; extern ia64_mv_setup_msi_irq_t sn_setup_msi_irq; extern ia64_mv_teardown_msi_irq_t sn_teardown_msi_irq; -extern ia64_mv_pci_fixup_bus_t sn_pci_fixup_bus; /* @@ -128,7 +127,6 @@ extern ia64_mv_pci_fixup_bus_t sn_pci_fixup_bus; #define platform_setup_msi_irq ((ia64_mv_setup_msi_irq_t*)NULL) #define platform_teardown_msi_irq ((ia64_mv_teardown_msi_irq_t*)NULL) #endif -#define platform_pci_fixup_bus sn_pci_fixup_bus #include diff --git a/trunk/include/asm-ia64/pal.h b/trunk/include/asm-ia64/pal.h index 4283ddcc25fb..2c8fd92d0ece 100644 --- a/trunk/include/asm-ia64/pal.h +++ b/trunk/include/asm-ia64/pal.h @@ -764,7 +764,7 @@ struct ia64_pal_retval { * (generally 0) MUST be passed. Reserved parameters are not optional * parameters. */ -extern struct ia64_pal_retval ia64_pal_call_static (u64, u64, u64, u64); +extern struct ia64_pal_retval ia64_pal_call_static (u64, u64, u64, u64, u64); extern struct ia64_pal_retval ia64_pal_call_stacked (u64, u64, u64, u64); extern struct ia64_pal_retval ia64_pal_call_phys_static (u64, u64, u64, u64); extern struct ia64_pal_retval ia64_pal_call_phys_stacked (u64, u64, u64, u64); @@ -774,7 +774,14 @@ extern void ia64_load_scratch_fpregs (struct ia64_fpreg *); #define PAL_CALL(iprv,a0,a1,a2,a3) do { \ struct ia64_fpreg fr[6]; \ ia64_save_scratch_fpregs(fr); \ - iprv = ia64_pal_call_static(a0, a1, a2, a3); \ + iprv = ia64_pal_call_static(a0, a1, a2, a3, 0); \ + ia64_load_scratch_fpregs(fr); \ +} while (0) + +#define PAL_CALL_IC_OFF(iprv,a0,a1,a2,a3) do { \ + struct ia64_fpreg fr[6]; \ + ia64_save_scratch_fpregs(fr); \ + iprv = ia64_pal_call_static(a0, a1, a2, a3, 1); \ ia64_load_scratch_fpregs(fr); \ } while (0) diff --git a/trunk/include/asm-ia64/pci.h b/trunk/include/asm-ia64/pci.h index 825eb7d882e6..ef616fd4cb1b 100644 --- a/trunk/include/asm-ia64/pci.h +++ b/trunk/include/asm-ia64/pci.h @@ -26,18 +26,16 @@ void pcibios_config_init(void); struct pci_dev; /* - * PCI_DMA_BUS_IS_PHYS should be set to 1 if there is _necessarily_ a direct - * correspondence between device bus addresses and CPU physical addresses. - * Platforms with a hardware I/O MMU _must_ turn this off to suppress the - * bounce buffer handling code in the block and network device layers. - * Platforms with separate bus address spaces _must_ turn this off and provide - * a device DMA mapping implementation that takes care of the necessary + * PCI_DMA_BUS_IS_PHYS should be set to 1 if there is _necessarily_ a direct correspondence + * between device bus addresses and CPU physical addresses. Platforms with a hardware I/O + * MMU _must_ turn this off to suppress the bounce buffer handling code in the block and + * network device layers. Platforms with separate bus address spaces _must_ turn this off + * and provide a device DMA mapping implementation that takes care of the necessary * address translation. * - * For now, the ia64 platforms which may have separate/multiple bus address - * spaces all have I/O MMUs which support the merging of physically - * discontiguous buffers, so we can use that as the sole factor to determine - * the setting of PCI_DMA_BUS_IS_PHYS. + * For now, the ia64 platforms which may have separate/multiple bus address spaces all + * have I/O MMUs which support the merging of physically discontiguous buffers, so we can + * use that as the sole factor to determine the setting of PCI_DMA_BUS_IS_PHYS. */ extern unsigned long ia64_max_iommu_merge_mask; #define PCI_DMA_BUS_IS_PHYS (ia64_max_iommu_merge_mask == ~0UL) @@ -54,6 +52,9 @@ pcibios_penalize_isa_irq (int irq, int active) /* We don't do dynamic PCI IRQ allocation */ } +#define HAVE_ARCH_PCI_MWI 1 +extern int pcibios_prep_mwi (struct pci_dev *); + #include /* pci_unmap_{single,page} is not a nop, thus... */ diff --git a/trunk/include/asm-ia64/sal.h b/trunk/include/asm-ia64/sal.h index d000689d9142..0b210abbe003 100644 --- a/trunk/include/asm-ia64/sal.h +++ b/trunk/include/asm-ia64/sal.h @@ -659,7 +659,6 @@ ia64_sal_freq_base (unsigned long which, unsigned long *ticks_per_second, } extern s64 ia64_sal_cache_flush (u64 cache_type); -extern void __init check_sal_cache_flush (void); /* Initialize all the processor and platform level instruction and data caches */ static inline s64 diff --git a/trunk/include/asm-ia64/sn/acpi.h b/trunk/include/asm-ia64/sn/acpi.h deleted file mode 100644 index 2850a7ef5e71..000000000000 --- a/trunk/include/asm-ia64/sn/acpi.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2006 Silicon Graphics, Inc. All rights reserved. - */ - -#ifndef _ASM_IA64_SN_ACPI_H -#define _ASM_IA64_SN_ACPI_H - -#include "acpi/acglobal.h" - -#define SN_ACPI_BASE_SUPPORT() (acpi_gbl_DSDT->oem_revision >= 0x20101) - -#endif /* _ASM_IA64_SN_ACPI_H */ diff --git a/trunk/include/asm-ia64/sn/addrs.h b/trunk/include/asm-ia64/sn/addrs.h index e715c794b186..1d9efe541662 100644 --- a/trunk/include/asm-ia64/sn/addrs.h +++ b/trunk/include/asm-ia64/sn/addrs.h @@ -136,13 +136,9 @@ */ #define TO_PHYS(x) (TO_PHYS_MASK & (x)) #define TO_CAC(x) (CAC_BASE | TO_PHYS(x)) -#ifdef CONFIG_SGI_SN #define TO_AMO(x) (AMO_BASE | TO_PHYS(x)) #define TO_GET(x) (GET_BASE | TO_PHYS(x)) -#else -#define TO_AMO(x) ({ BUG(); x; }) -#define TO_GET(x) ({ BUG(); x; }) -#endif + /* * Covert from processor physical address to II/TIO physical address: diff --git a/trunk/include/asm-ia64/sn/pcibr_provider.h b/trunk/include/asm-ia64/sn/pcibr_provider.h index da3eade0cae2..e3b0c3fe5eed 100644 --- a/trunk/include/asm-ia64/sn/pcibr_provider.h +++ b/trunk/include/asm-ia64/sn/pcibr_provider.h @@ -135,7 +135,7 @@ extern void pcireg_intr_addr_addr_set(struct pcibus_info *, int, u64 extern void pcireg_force_intr_set(struct pcibus_info *, int); extern u64 pcireg_wrb_flush_get(struct pcibus_info *, int); extern void pcireg_int_ate_set(struct pcibus_info *, int, u64); -extern u64 __iomem * pcireg_int_ate_addr(struct pcibus_info *, int); +extern u64 * pcireg_int_ate_addr(struct pcibus_info *, int); extern void pcibr_force_interrupt(struct sn_irq_info *sn_irq_info); extern void pcibr_change_devices_irq(struct sn_irq_info *sn_irq_info); extern int pcibr_ate_alloc(struct pcibus_info *, int); diff --git a/trunk/include/asm-ia64/sn/pcidev.h b/trunk/include/asm-ia64/sn/pcidev.h index 9fe89a93d880..eac3561574be 100644 --- a/trunk/include/asm-ia64/sn/pcidev.h +++ b/trunk/include/asm-ia64/sn/pcidev.h @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1992 - 1997, 2000-2006 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 1992 - 1997, 2000-2005 Silicon Graphics, Inc. All rights reserved. */ #ifndef _ASM_IA64_SN_PCI_PCIDEV_H #define _ASM_IA64_SN_PCI_PCIDEV_H @@ -12,29 +12,31 @@ /* * In ia64, pci_dev->sysdata must be a *pci_controller. To provide access to - * the pcidev_info structs for all devices under a controller, we keep a - * list of pcidev_info under pci_controller->platform_data. + * the pcidev_info structs for all devices under a controller, we extend the + * definition of pci_controller, via sn_pci_controller, to include a list + * of pcidev_info. */ -struct sn_platform_data { - void *provider_soft; +struct sn_pci_controller { + struct pci_controller pci_controller; struct list_head pcidev_info; }; -#define SN_PLATFORM_DATA(busdev) \ - ((struct sn_platform_data *)(PCI_CONTROLLER(busdev)->platform_data)) +#define SN_PCI_CONTROLLER(dev) ((struct sn_pci_controller *) dev->sysdata) #define SN_PCIDEV_INFO(dev) sn_pcidev_info_get(dev) +#define SN_PCIBUS_BUSSOFT_INFO(pci_bus) \ + (struct pcibus_info *)((struct pcibus_bussoft *)(PCI_CONTROLLER((pci_bus))->platform_data)) /* * Given a pci_bus, return the sn pcibus_bussoft struct. Note that * this only works for root busses, not for busses represented by PPB's. */ #define SN_PCIBUS_BUSSOFT(pci_bus) \ - ((struct pcibus_bussoft *)(SN_PLATFORM_DATA(pci_bus)->provider_soft)) + ((struct pcibus_bussoft *)(PCI_CONTROLLER((pci_bus))->platform_data)) #define SN_PCIBUS_BUSSOFT_INFO(pci_bus) \ - ((struct pcibus_info *)(SN_PLATFORM_DATA(pci_bus)->provider_soft)) + (struct pcibus_info *)((struct pcibus_bussoft *)(PCI_CONTROLLER((pci_bus))->platform_data)) /* * Given a struct pci_dev, return the sn pcibus_bussoft struct. Note * that this is not equivalent to SN_PCIBUS_BUSSOFT(pci_dev->bus) due @@ -70,6 +72,8 @@ extern void sn_irq_fixup(struct pci_dev *pci_dev, struct sn_irq_info *sn_irq_info); extern void sn_irq_unfixup(struct pci_dev *pci_dev); extern struct pcidev_info * sn_pcidev_info_get(struct pci_dev *); +extern void sn_pci_controller_fixup(int segment, int busnum, + struct pci_bus *bus); extern void sn_bus_store_sysdata(struct pci_dev *dev); extern void sn_bus_free_sysdata(void); extern void sn_generate_path(struct pci_bus *pci_bus, char *address); diff --git a/trunk/include/asm-ia64/sn/sn_feature_sets.h b/trunk/include/asm-ia64/sn/sn_feature_sets.h index bfdc36273ed4..30dcfa442e53 100644 --- a/trunk/include/asm-ia64/sn/sn_feature_sets.h +++ b/trunk/include/asm-ia64/sn/sn_feature_sets.h @@ -44,14 +44,8 @@ extern int sn_prom_feature_available(int id); * Once enabled, a feature cannot be disabled. * * By default, features are disabled unless explicitly enabled. - * - * These defines must be kept in sync with the corresponding - * PROM definitions in feature_sets.h. */ #define OSF_MCA_SLV_TO_OS_INIT_SLV 0 #define OSF_FEAT_LOG_SBES 1 -#define OSF_ACPI_ENABLE 2 -#define OSF_PCISEGMENT_ENABLE 3 - #endif /* _ASM_IA64_SN_FEATURE_SETS_H */ diff --git a/trunk/include/asm-ia64/sn/sn_sal.h b/trunk/include/asm-ia64/sn/sn_sal.h index be5d83ad7cb1..ba826b3f75bb 100644 --- a/trunk/include/asm-ia64/sn/sn_sal.h +++ b/trunk/include/asm-ia64/sn/sn_sal.h @@ -77,7 +77,6 @@ #define SN_SAL_IOIF_GET_WIDGET_DMAFLUSH_LIST 0x02000058 // deprecated #define SN_SAL_IOIF_GET_DEVICE_DMAFLUSH_LIST 0x0200005a -#define SN_SAL_IOIF_INIT 0x0200005f #define SN_SAL_HUB_ERROR_INTERRUPT 0x02000060 #define SN_SAL_BTE_RECOVER 0x02000061 #define SN_SAL_RESERVED_DO_NOT_USE 0x02000062 diff --git a/trunk/include/asm-ia64/sn/tioca_provider.h b/trunk/include/asm-ia64/sn/tioca_provider.h index 9a820ac61be3..65cdd73c2a57 100644 --- a/trunk/include/asm-ia64/sn/tioca_provider.h +++ b/trunk/include/asm-ia64/sn/tioca_provider.h @@ -162,11 +162,11 @@ static inline void tioca_tlbflush(struct tioca_kernel *tioca_kernel) { volatile u64 tmp; - volatile struct tioca __iomem *ca_base; + volatile struct tioca *ca_base; struct tioca_common *tioca_common; tioca_common = tioca_kernel->ca_common; - ca_base = (struct tioca __iomem *)tioca_common->ca_common.bs_base; + ca_base = (struct tioca *)tioca_common->ca_common.bs_base; /* * Explicit flushes not needed if GART is in cached mode diff --git a/trunk/include/asm-ia64/sn/tioce_provider.h b/trunk/include/asm-ia64/sn/tioce_provider.h index 32c32f30b099..6d62b13f7ae7 100644 --- a/trunk/include/asm-ia64/sn/tioce_provider.h +++ b/trunk/include/asm-ia64/sn/tioce_provider.h @@ -53,7 +53,7 @@ struct tioce_dmamap { u64 ct_start; /* coretalk start address */ u64 pci_start; /* bus start address */ - u64 __iomem *ate_hw;/* hw ptr of first ate in map */ + u64 *ate_hw; /* hw ptr of first ate in map */ u64 *ate_shadow; /* shadow ptr of firat ate */ u16 ate_count; /* # ate's in the map */ }; diff --git a/trunk/include/asm-ia64/sn/xpc.h b/trunk/include/asm-ia64/sn/xpc.h index 1d45e1518fb3..35e1386f37ab 100644 --- a/trunk/include/asm-ia64/sn/xpc.h +++ b/trunk/include/asm-ia64/sn/xpc.h @@ -669,7 +669,7 @@ extern struct device *xpc_part; extern struct device *xpc_chan; extern int xpc_disengage_request_timelimit; extern int xpc_disengage_request_timedout; -extern irqreturn_t xpc_notify_IRQ_handler(int, void *); +extern irqreturn_t xpc_notify_IRQ_handler(int, void *, struct pt_regs *); extern void xpc_dropped_IPI_check(struct xpc_partition *); extern void xpc_activate_partition(struct xpc_partition *); extern void xpc_activate_kthreads(struct xpc_channel *, int); diff --git a/trunk/include/asm-ia64/uaccess.h b/trunk/include/asm-ia64/uaccess.h index 449c8c0fa2bd..9adb51211c22 100644 --- a/trunk/include/asm-ia64/uaccess.h +++ b/trunk/include/asm-ia64/uaccess.h @@ -389,7 +389,7 @@ xlate_dev_kmem_ptr (char * p) struct page *page; char * ptr; - page = virt_to_page((unsigned long)p); + page = virt_to_page((unsigned long)p >> PAGE_SHIFT); if (PageUncached(page)) ptr = (char *)__pa(p) + __IA64_UNCACHED_OFFSET; else diff --git a/trunk/include/asm-m32r/device.h b/trunk/include/asm-m32r/device.h deleted file mode 100644 index d8f9872b0e2d..000000000000 --- a/trunk/include/asm-m32r/device.h +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Arch specific extensions to struct device - * - * This file is released under the GPLv2 - */ -#include - diff --git a/trunk/include/asm-m32r/io.h b/trunk/include/asm-m32r/io.h index d06933bd6318..70ad1c949c2b 100644 --- a/trunk/include/asm-m32r/io.h +++ b/trunk/include/asm-m32r/io.h @@ -166,6 +166,38 @@ static inline void _writel(unsigned long l, unsigned long addr) #define flush_write_buffers() do { } while (0) /* M32R_FIXME */ +/** + * check_signature - find BIOS signatures + * @io_addr: mmio address to check + * @signature: signature block + * @length: length of signature + * + * Perform a signature comparison with the ISA mmio address io_addr. + * Returns 1 on a match. + * + * This function is deprecated. New drivers should use ioremap and + * check_signature. + */ + +static inline int check_signature(void __iomem *io_addr, + const unsigned char *signature, int length) +{ + int retval = 0; +#if 0 +printk("check_signature\n"); + do { + if (readb(io_addr) != *signature) + goto out; + io_addr++; + signature++; + length--; + } while (length); + retval = 1; +out: +#endif + return retval; +} + static inline void memset_io(volatile void __iomem *addr, unsigned char val, int count) { diff --git a/trunk/include/asm-m32r/irq_regs.h b/trunk/include/asm-m32r/irq_regs.h deleted file mode 100644 index 3dd9c0b70270..000000000000 --- a/trunk/include/asm-m32r/irq_regs.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/include/asm-m68k/atari_stdma.h b/trunk/include/asm-m68k/atari_stdma.h index 8e389b7fa70c..b4eadf852738 100644 --- a/trunk/include/asm-m68k/atari_stdma.h +++ b/trunk/include/asm-m68k/atari_stdma.h @@ -8,7 +8,8 @@ /***************************** Prototypes *****************************/ -void stdma_lock(irq_handler_t handler, void *data); +void stdma_lock(irqreturn_t (*handler)(int, void *, struct pt_regs *), + void *data); void stdma_release( void ); int stdma_others_waiting( void ); int stdma_islocked( void ); diff --git a/trunk/include/asm-m68k/device.h b/trunk/include/asm-m68k/device.h deleted file mode 100644 index d8f9872b0e2d..000000000000 --- a/trunk/include/asm-m68k/device.h +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Arch specific extensions to struct device - * - * This file is released under the GPLv2 - */ -#include - diff --git a/trunk/include/asm-m68k/dma-mapping.h b/trunk/include/asm-m68k/dma-mapping.h index d90d841d3dfd..cebbb03370ec 100644 --- a/trunk/include/asm-m68k/dma-mapping.h +++ b/trunk/include/asm-m68k/dma-mapping.h @@ -5,7 +5,6 @@ struct scatterlist; -#ifndef CONFIG_MMU_SUN3 static inline int dma_supported(struct device *dev, u64 mask) { return 1; @@ -27,7 +26,7 @@ static inline int dma_is_consistent(dma_addr_t dma_addr) } extern void *dma_alloc_coherent(struct device *, size_t, - dma_addr_t *, gfp_t); + dma_addr_t *, int); extern void dma_free_coherent(struct device *, size_t, void *, dma_addr_t); @@ -89,8 +88,4 @@ static inline int dma_mapping_error(dma_addr_t handle) return 0; } -#else -#include -#endif - #endif /* _M68K_DMA_MAPPING_H */ diff --git a/trunk/include/asm-m68k/floppy.h b/trunk/include/asm-m68k/floppy.h index 45dc908932a3..57f4fdda65ab 100644 --- a/trunk/include/asm-m68k/floppy.h +++ b/trunk/include/asm-m68k/floppy.h @@ -17,7 +17,8 @@ #include -asmlinkage irqreturn_t floppy_hardint(int irq, void *dev_id); +asmlinkage irqreturn_t floppy_hardint(int irq, void *dev_id, + struct pt_regs *regs); /* constants... */ @@ -183,7 +184,8 @@ static void fd_disable_dma(void) /* this is the only truly Q40 specific function */ -asmlinkage irqreturn_t floppy_hardint(int irq, void *dev_id) +asmlinkage irqreturn_t floppy_hardint(int irq, void *dev_id, + struct pt_regs *regs) { register unsigned char st; @@ -196,7 +198,7 @@ asmlinkage irqreturn_t floppy_hardint(int irq, void *dev_id) static int dma_wait=0; #endif if(!doing_pdma) { - floppy_interrupt(irq, dev_id); + floppy_interrupt(irq, dev_id, regs); return IRQ_HANDLED; } @@ -244,7 +246,7 @@ asmlinkage irqreturn_t floppy_hardint(int irq, void *dev_id) dma_wait=0; #endif doing_pdma = 0; - floppy_interrupt(irq, dev_id); + floppy_interrupt(irq, dev_id, regs); return IRQ_HANDLED; } #ifdef TRACE_FLPY_INT diff --git a/trunk/include/asm-m68k/ide.h b/trunk/include/asm-m68k/ide.h index f9ffb2cbbae8..365f76fb8013 100644 --- a/trunk/include/asm-m68k/ide.h +++ b/trunk/include/asm-m68k/ide.h @@ -123,7 +123,7 @@ static __inline__ void ide_release_lock (void) } static __inline__ void -ide_get_lock(irq_handler_t handler, void *data) +ide_get_lock(irqreturn_t (*handler)(int, void *, struct pt_regs *), void *data) { if (MACH_IS_ATARI) { if (falconide_intr_lock == 0) { diff --git a/trunk/include/asm-m68k/irq.h b/trunk/include/asm-m68k/irq.h index 4901cb105e2f..3257f9881002 100644 --- a/trunk/include/asm-m68k/irq.h +++ b/trunk/include/asm-m68k/irq.h @@ -83,7 +83,7 @@ struct pt_regs; * interrupt source (if it supports chaining). */ typedef struct irq_node { - int (*handler)(int, void *); + int (*handler)(int, void *, struct pt_regs *); void *dev_id; struct irq_node *next; unsigned long flags; @@ -93,12 +93,12 @@ typedef struct irq_node { /* * This structure has only 4 elements for speed reasons */ -struct irq_handler { - int (*handler)(int, void *); +typedef struct irq_handler { + int (*handler)(int, void *, struct pt_regs *); unsigned long flags; void *dev_id; const char *devname; -}; +} irq_handler_t; struct irq_controller { const char *name; @@ -122,7 +122,6 @@ extern void m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt, void (*handler)(unsigned int, struct pt_regs *)); extern void m68k_setup_irq_controller(struct irq_controller *, unsigned int, unsigned int); -asmlinkage void m68k_handle_int(unsigned int); -asmlinkage void __m68k_handle_int(unsigned int, struct pt_regs *); +asmlinkage void m68k_handle_int(unsigned int, struct pt_regs *); #endif /* _M68K_IRQ_H_ */ diff --git a/trunk/include/asm-m68k/irq_regs.h b/trunk/include/asm-m68k/irq_regs.h deleted file mode 100644 index 3dd9c0b70270..000000000000 --- a/trunk/include/asm-m68k/irq_regs.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/include/asm-m68k/mac_iop.h b/trunk/include/asm-m68k/mac_iop.h index a2c7e6fcca38..b0d2e3473537 100644 --- a/trunk/include/asm-m68k/mac_iop.h +++ b/trunk/include/asm-m68k/mac_iop.h @@ -143,17 +143,17 @@ struct iop_msg { int status; /* status of this message */ __u8 message[IOP_MSG_LEN]; /* the message being sent/received */ __u8 reply[IOP_MSG_LEN]; /* the reply to the message */ - void (*handler)(struct iop_msg *); + void (*handler)(struct iop_msg *, struct pt_regs *); /* function to call when reply recvd */ }; extern int iop_scc_present,iop_ism_present; extern int iop_listen(uint, uint, - void (*handler)(struct iop_msg *), + void (*handler)(struct iop_msg *, struct pt_regs *), const char *); extern int iop_send_message(uint, uint, void *, uint, __u8 *, - void (*)(struct iop_msg *)); + void (*)(struct iop_msg *, struct pt_regs *)); extern void iop_complete_message(struct iop_msg *); extern void iop_upload_code(uint, __u8 *, uint, __u16); extern void iop_download_code(uint, __u8 *, uint, __u16); diff --git a/trunk/include/asm-m68k/machdep.h b/trunk/include/asm-m68k/machdep.h index 26d2b91209c5..df898f27e434 100644 --- a/trunk/include/asm-m68k/machdep.h +++ b/trunk/include/asm-m68k/machdep.h @@ -10,7 +10,7 @@ struct rtc_time; struct rtc_pll_info; struct buffer_head; -extern void (*mach_sched_init) (irq_handler_t handler); +extern void (*mach_sched_init) (irqreturn_t (*handler)(int, void *, struct pt_regs *)); /* machine dependent irq functions */ extern void (*mach_init_IRQ) (void); extern void (*mach_get_model) (char *model); diff --git a/trunk/include/asm-m68k/signal.h b/trunk/include/asm-m68k/signal.h index 3db8a81942f1..de1ba6ead3b4 100644 --- a/trunk/include/asm-m68k/signal.h +++ b/trunk/include/asm-m68k/signal.h @@ -198,7 +198,6 @@ static inline int sigfindinword(unsigned long word) return word ^ 31; } -struct pt_regs; extern void ptrace_signal_deliver(struct pt_regs *regs, void *cookie); #endif /* __KERNEL__ */ diff --git a/trunk/include/asm-m68k/string.h b/trunk/include/asm-m68k/string.h index 2eb7df1e0f5d..6c59215b285e 100644 --- a/trunk/include/asm-m68k/string.h +++ b/trunk/include/asm-m68k/string.h @@ -1,114 +1,138 @@ #ifndef _M68K_STRING_H_ #define _M68K_STRING_H_ -#include -#include +#include +#include -static inline size_t __kernel_strlen(const char *s) +#define __HAVE_ARCH_STRCPY +static inline char * strcpy(char * dest,const char *src) { - const char *sc; + char *xdest = dest; + + __asm__ __volatile__ + ("1:\tmoveb %1@+,%0@+\n\t" + "jne 1b" + : "=a" (dest), "=a" (src) + : "0" (dest), "1" (src) : "memory"); + return xdest; +} - for (sc = s; *sc++; ) - ; - return sc - s - 1; +#define __HAVE_ARCH_STRNCPY +static inline char * strncpy(char *dest, const char *src, size_t n) +{ + char *xdest = dest; + + if (n == 0) + return xdest; + + __asm__ __volatile__ + ("1:\tmoveb %1@+,%0@+\n\t" + "jeq 2f\n\t" + "subql #1,%2\n\t" + "jne 1b\n\t" + "2:" + : "=a" (dest), "=a" (src), "=d" (n) + : "0" (dest), "1" (src), "2" (n) + : "memory"); + return xdest; } -static inline char *__kernel_strcpy(char *dest, const char *src) +#define __HAVE_ARCH_STRCAT +static inline char * strcat(char * dest, const char * src) { - char *xdest = dest; - - asm volatile ("\n" - "1: move.b (%1)+,(%0)+\n" - " jne 1b" - : "+a" (dest), "+a" (src) - : : "memory"); - return xdest; + char *tmp = dest; + + while (*dest) + dest++; + while ((*dest++ = *src++)) + ; + + return tmp; } -#ifndef __IN_STRING_C +#define __HAVE_ARCH_STRNCAT +static inline char * strncat(char *dest, const char *src, size_t count) +{ + char *tmp = dest; + + if (count) { + while (*dest) + dest++; + while ((*dest++ = *src++)) { + if (--count == 0) { + *dest++='\0'; + break; + } + } + } -#define __HAVE_ARCH_STRLEN -#define strlen(s) (__builtin_constant_p(s) ? \ - __builtin_strlen(s) : \ - __kernel_strlen(s)) + return tmp; +} -#define __HAVE_ARCH_STRNLEN -static inline size_t strnlen(const char *s, size_t count) +#define __HAVE_ARCH_STRCHR +static inline char * strchr(const char * s, int c) { - const char *sc = s; - - asm volatile ("\n" - "1: subq.l #1,%1\n" - " jcs 2f\n" - " tst.b (%0)+\n" - " jne 1b\n" - " subq.l #1,%0\n" - "2:" - : "+a" (sc), "+d" (count)); - return sc - s; + const char ch = c; + + for(; *s != ch; ++s) + if (*s == '\0') + return( NULL ); + return( (char *) s); } -#define __HAVE_ARCH_STRCPY -#if __GNUC__ >= 4 -#define strcpy(d, s) (__builtin_constant_p(s) && \ - __builtin_strlen(s) <= 32 ? \ - __builtin_strcpy(d, s) : \ - __kernel_strcpy(d, s)) -#else -#define strcpy(d, s) __kernel_strcpy(d, s) -#endif +/* strstr !! */ -#define __HAVE_ARCH_STRNCPY -static inline char *strncpy(char *dest, const char *src, size_t n) +#define __HAVE_ARCH_STRLEN +static inline size_t strlen(const char * s) { - char *xdest = dest; - - asm volatile ("\n" - " jra 2f\n" - "1: move.b (%1),(%0)+\n" - " jeq 2f\n" - " addq.l #1,%1\n" - "2: subq.l #1,%2\n" - " jcc 1b\n" - : "+a" (dest), "+a" (src), "+d" (n) - : : "memory"); - return xdest; + const char *sc; + for (sc = s; *sc != '\0'; ++sc) ; + return(sc - s); } -#define __HAVE_ARCH_STRCAT -#define strcat(d, s) ({ \ - char *__d = (d); \ - strcpy(__d + strlen(__d), (s)); \ -}) +/* strnlen !! */ -#define __HAVE_ARCH_STRCHR -static inline char *strchr(const char *s, int c) +#define __HAVE_ARCH_STRCMP +static inline int strcmp(const char * cs,const char * ct) { - char sc, ch = c; - - for (; (sc = *s++) != ch; ) { - if (!sc) - return NULL; - } - return (char *)s - 1; + char __res; + + __asm__ + ("1:\tmoveb %0@+,%2\n\t" /* get *cs */ + "cmpb %1@+,%2\n\t" /* compare a byte */ + "jne 2f\n\t" /* not equal, break out */ + "tstb %2\n\t" /* at end of cs? */ + "jne 1b\n\t" /* no, keep going */ + "jra 3f\n\t" /* strings are equal */ + "2:\tsubb %1@-,%2\n\t" /* *cs - *ct */ + "3:" + : "=a" (cs), "=a" (ct), "=d" (__res) + : "0" (cs), "1" (ct)); + return __res; } -#define __HAVE_ARCH_STRCMP -static inline int strcmp(const char *cs, const char *ct) +#define __HAVE_ARCH_STRNCMP +static inline int strncmp(const char * cs,const char * ct,size_t count) { - char res; - - asm ("\n" - "1: move.b (%0)+,%2\n" /* get *cs */ - " cmp.b (%1)+,%2\n" /* compare a byte */ - " jne 2f\n" /* not equal, break out */ - " tst.b %2\n" /* at end of cs? */ - " jne 1b\n" /* no, keep going */ - " jra 3f\n" /* strings are equal */ - "2: sub.b -(%1),%2\n" /* *cs - *ct */ - "3:" - : "+a" (cs), "+a" (ct), "=d" (res)); - return res; + char __res; + + if (!count) + return 0; + __asm__ + ("1:\tmovb %0@+,%3\n\t" /* get *cs */ + "cmpb %1@+,%3\n\t" /* compare a byte */ + "jne 3f\n\t" /* not equal, break out */ + "tstb %3\n\t" /* at end of cs? */ + "jeq 4f\n\t" /* yes, all done */ + "subql #1,%2\n\t" /* no, adjust count */ + "jne 1b\n\t" /* more to do, keep going */ + "2:\tmoveq #0,%3\n\t" /* strings are equal */ + "jra 4f\n\t" + "3:\tsubb %1@-,%3\n\t" /* *cs - *ct */ + "4:" + : "=a" (cs), "=a" (ct), "=d" (count), "=d" (__res) + : "0" (cs), "1" (ct), "2" (count)); + return __res; } #define __HAVE_ARCH_MEMSET @@ -126,6 +150,4 @@ extern void *memmove(void *, const void *, __kernel_size_t); extern int memcmp(const void *, const void *, __kernel_size_t); #define memcmp(d, s, n) __builtin_memcmp(d, s, n) -#endif - #endif /* _M68K_STRING_H_ */ diff --git a/trunk/include/asm-m68k/sun3mmu.h b/trunk/include/asm-m68k/sun3mmu.h index d8f17a0d8c9f..6c8c17d047a1 100644 --- a/trunk/include/asm-m68k/sun3mmu.h +++ b/trunk/include/asm-m68k/sun3mmu.h @@ -4,7 +4,6 @@ #ifndef __SUN3_MMU_H__ #define __SUN3_MMU_H__ -#include #include #include @@ -161,7 +160,7 @@ static inline void sun3_put_context(unsigned char c) return; } -extern void __iomem *sun3_ioremap(unsigned long phys, unsigned long size, +extern void *sun3_ioremap(unsigned long phys, unsigned long size, unsigned long type); extern int sun3_map_test(unsigned long addr, char *val); diff --git a/trunk/include/asm-m68k/sun3xflop.h b/trunk/include/asm-m68k/sun3xflop.h index 32c45f84ac60..ca8cc4113843 100644 --- a/trunk/include/asm-m68k/sun3xflop.h +++ b/trunk/include/asm-m68k/sun3xflop.h @@ -111,7 +111,8 @@ static void sun3x_82072_fd_outb(unsigned char value, int port) } -asmlinkage irqreturn_t sun3xflop_hardint(int irq, void *dev_id) +asmlinkage irqreturn_t sun3xflop_hardint(int irq, void *dev_id, + struct pt_regs * regs) { register unsigned char st; @@ -124,7 +125,7 @@ asmlinkage irqreturn_t sun3xflop_hardint(int irq, void *dev_id) static int dma_wait=0; #endif if(!doing_pdma) { - floppy_interrupt(irq, dev_id); + floppy_interrupt(irq, dev_id, regs); return IRQ_HANDLED; } @@ -188,7 +189,7 @@ asmlinkage irqreturn_t sun3xflop_hardint(int irq, void *dev_id) dma_wait=0; #endif - floppy_interrupt(irq, dev_id); + floppy_interrupt(irq, dev_id, regs); return IRQ_HANDLED; } diff --git a/trunk/include/asm-m68k/system.h b/trunk/include/asm-m68k/system.h index 243dd13e6bfc..131a0cb0f491 100644 --- a/trunk/include/asm-m68k/system.h +++ b/trunk/include/asm-m68k/system.h @@ -78,13 +78,13 @@ static inline int irqs_disabled(void) #define mb() barrier() #define rmb() barrier() #define wmb() barrier() -#define read_barrier_depends() ((void)0) -#define set_mb(var, value) ({ (var) = (value); wmb(); }) +#define read_barrier_depends() do { } while(0) +#define set_mb(var, value) do { xchg(&var, value); } while (0) #define smp_mb() barrier() #define smp_rmb() barrier() #define smp_wmb() barrier() -#define smp_read_barrier_depends() ((void)0) +#define smp_read_barrier_depends() do { } while(0) #define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) diff --git a/trunk/include/asm-m68k/uaccess.h b/trunk/include/asm-m68k/uaccess.h index e4c9f080ff20..88b1f47400e1 100644 --- a/trunk/include/asm-m68k/uaccess.h +++ b/trunk/include/asm-m68k/uaccess.h @@ -76,7 +76,7 @@ asm volatile ("\n" \ break; \ case 8: \ { \ - const void __user *__pu_ptr = (ptr); \ + const void *__pu_ptr = (ptr); \ asm volatile ("\n" \ "1: moves.l %2,(%1)+\n" \ "2: moves.l %R2,(%1)\n" \ @@ -125,7 +125,7 @@ asm volatile ("\n" \ " .previous" \ : "+d" (res), "=&" #reg (__gu_val) \ : "m" (*(ptr)), "i" (err)); \ - (x) = (typeof(*(ptr)))(unsigned long)__gu_val; \ + (x) = (typeof(*(ptr)))(long)__gu_val; \ }) #define __get_user(x, ptr) \ @@ -221,16 +221,16 @@ __constant_copy_from_user(void *to, const void __user *from, unsigned long n) switch (n) { case 1: - __get_user_asm(res, *(u8 *)to, (u8 __user *)from, u8, b, d, 1); + __get_user_asm(res, *(u8 *)to, (u8 *)from, u8, b, d, 1); break; case 2: - __get_user_asm(res, *(u16 *)to, (u16 __user *)from, u16, w, d, 2); + __get_user_asm(res, *(u16 *)to, (u16 *)from, u16, w, d, 2); break; case 3: __constant_copy_from_user_asm(res, to, from, tmp, 3, w, b,); break; case 4: - __get_user_asm(res, *(u32 *)to, (u32 __user *)from, u32, l, r, 4); + __get_user_asm(res, *(u32 *)to, (u32 *)from, u32, l, r, 4); break; case 5: __constant_copy_from_user_asm(res, to, from, tmp, 5, l, b,); @@ -302,16 +302,16 @@ __constant_copy_to_user(void __user *to, const void *from, unsigned long n) switch (n) { case 1: - __put_user_asm(res, *(u8 *)from, (u8 __user *)to, b, d, 1); + __put_user_asm(res, *(u8 *)from, (u8 *)to, b, d, 1); break; case 2: - __put_user_asm(res, *(u16 *)from, (u16 __user *)to, w, d, 2); + __put_user_asm(res, *(u16 *)from, (u16 *)to, w, d, 2); break; case 3: __constant_copy_to_user_asm(res, to, from, tmp, 3, w, b,); break; case 4: - __put_user_asm(res, *(u32 *)from, (u32 __user *)to, l, r, 4); + __put_user_asm(res, *(u32 *)from, (u32 *)to, l, r, 4); break; case 5: __constant_copy_to_user_asm(res, to, from, tmp, 5, l, b,); diff --git a/trunk/include/asm-m68k/unistd.h b/trunk/include/asm-m68k/unistd.h index ad4348058c66..3ab716f0fc18 100644 --- a/trunk/include/asm-m68k/unistd.h +++ b/trunk/include/asm-m68k/unistd.h @@ -284,39 +284,10 @@ #define __NR_add_key 279 #define __NR_request_key 280 #define __NR_keyctl 281 -#define __NR_ioprio_set 282 -#define __NR_ioprio_get 283 -#define __NR_inotify_init 284 -#define __NR_inotify_add_watch 285 -#define __NR_inotify_rm_watch 286 -#define __NR_migrate_pages 287 -#define __NR_openat 288 -#define __NR_mkdirat 289 -#define __NR_mknodat 290 -#define __NR_fchownat 291 -#define __NR_futimesat 292 -#define __NR_fstatat64 293 -#define __NR_unlinkat 294 -#define __NR_renameat 295 -#define __NR_linkat 296 -#define __NR_symlinkat 297 -#define __NR_readlinkat 298 -#define __NR_fchmodat 299 -#define __NR_faccessat 300 -#define __NR_pselect6 301 -#define __NR_ppoll 302 -#define __NR_unshare 303 -#define __NR_set_robust_list 304 -#define __NR_get_robust_list 305 -#define __NR_splice 306 -#define __NR_sync_file_range 307 -#define __NR_tee 308 -#define __NR_vmsplice 309 -#define __NR_move_pages 310 #ifdef __KERNEL__ -#define NR_syscalls 311 +#define NR_syscalls 282 #include /* user-visible error numbers are in the range -1 - -MAX_ERRNO: see diff --git a/trunk/include/asm-m68k/user.h b/trunk/include/asm-m68k/user.h index d7c0b109bd45..e8d5a64c7e79 100644 --- a/trunk/include/asm-m68k/user.h +++ b/trunk/include/asm-m68k/user.h @@ -81,7 +81,7 @@ struct user{ unsigned long magic; /* To uniquely identify a core file */ char u_comm[32]; /* User command that was responsible */ }; -#define NBPG 4096 +#define NBPG PAGE_SIZE #define UPAGES 1 #define HOST_TEXT_START_ADDR (u.start_code) #define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG) diff --git a/trunk/include/asm-m68knommu/device.h b/trunk/include/asm-m68knommu/device.h deleted file mode 100644 index d8f9872b0e2d..000000000000 --- a/trunk/include/asm-m68knommu/device.h +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Arch specific extensions to struct device - * - * This file is released under the GPLv2 - */ -#include - diff --git a/trunk/include/asm-m68knommu/irq_regs.h b/trunk/include/asm-m68knommu/irq_regs.h deleted file mode 100644 index 3dd9c0b70270..000000000000 --- a/trunk/include/asm-m68knommu/irq_regs.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/include/asm-m68knommu/irqnode.h b/trunk/include/asm-m68knommu/irqnode.h index 6132a9858b52..a2503dfc554c 100644 --- a/trunk/include/asm-m68knommu/irqnode.h +++ b/trunk/include/asm-m68knommu/irqnode.h @@ -8,7 +8,7 @@ * interrupt source (if it supports chaining). */ typedef struct irq_node { - irq_handler_t handler; + irqreturn_t (*handler)(int, void *, struct pt_regs *); unsigned long flags; void *dev_id; const char *devname; @@ -18,12 +18,12 @@ typedef struct irq_node { /* * This structure has only 4 elements for speed reasons */ -struct irq_entry { - irq_handler_t handler; +typedef struct irq_handler { + irqreturn_t (*handler)(int, void *, struct pt_regs *); unsigned long flags; void *dev_id; const char *devname; -}; +} irq_handler_t; /* count of spurious interrupts */ extern volatile unsigned int num_spurious; diff --git a/trunk/include/asm-m68knommu/machdep.h b/trunk/include/asm-m68knommu/machdep.h index 6ce28f8e0ead..27c90afd3339 100644 --- a/trunk/include/asm-m68knommu/machdep.h +++ b/trunk/include/asm-m68knommu/machdep.h @@ -18,7 +18,7 @@ extern int (*mach_kbdrate) (struct kbd_repeat *); extern void (*mach_kbd_leds) (unsigned int); /* machine dependent irq functions */ extern void (*mach_init_IRQ) (void); -extern irq_handler_t mach_default_handler; +extern irqreturn_t (*(*mach_default_handler)[]) (int, void *, struct pt_regs *); extern int (*mach_request_irq) (unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id); extern void (*mach_free_irq) (unsigned int irq, void *dev_id); diff --git a/trunk/include/asm-m68knommu/mcfmbus.h b/trunk/include/asm-m68knommu/mcfmbus.h index 319899c47a2c..13df9d41bd1a 100644 --- a/trunk/include/asm-m68knommu/mcfmbus.h +++ b/trunk/include/asm-m68knommu/mcfmbus.h @@ -37,7 +37,7 @@ #define MCFMBUS_MFDR_MBC(a) ((a)&0x3F) /*M-Bus Clock*/ /* -* Define bit flags in Control Register +* Define bit flags in Controll Register */ #define MCFMBUS_MBCR_MEN (0x80) /* M-Bus Enable */ diff --git a/trunk/include/asm-m68knommu/unistd.h b/trunk/include/asm-m68knommu/unistd.h index ebaf03197114..daafb5d43ef1 100644 --- a/trunk/include/asm-m68knommu/unistd.h +++ b/trunk/include/asm-m68knommu/unistd.h @@ -281,43 +281,14 @@ #define __NR_mq_notify 275 #define __NR_mq_getsetattr 276 #define __NR_waitid 277 -#define __NR_vserver 278 +#define __NR_sys_setaltroot 278 #define __NR_add_key 279 #define __NR_request_key 280 #define __NR_keyctl 281 -#define __NR_ioprio_set 282 -#define __NR_ioprio_get 283 -#define __NR_inotify_init 284 -#define __NR_inotify_add_watch 285 -#define __NR_inotify_rm_watch 286 -#define __NR_migrate_pages 287 -#define __NR_openat 288 -#define __NR_mkdirat 289 -#define __NR_mknodat 290 -#define __NR_fchownat 291 -#define __NR_futimesat 292 -#define __NR_fstatat64 293 -#define __NR_unlinkat 294 -#define __NR_renameat 295 -#define __NR_linkat 296 -#define __NR_symlinkat 297 -#define __NR_readlinkat 298 -#define __NR_fchmodat 299 -#define __NR_faccessat 300 -#define __NR_pselect6 301 -#define __NR_ppoll 302 -#define __NR_unshare 303 -#define __NR_set_robust_list 304 -#define __NR_get_robust_list 305 -#define __NR_splice 306 -#define __NR_sync_file_range 307 -#define __NR_tee 308 -#define __NR_vmsplice 309 -#define __NR_move_pages 310 - + #ifdef __KERNEL__ -#define NR_syscalls 311 +#define NR_syscalls 282 #include /* user-visible error numbers are in the range -1 - -MAX_ERRNO: see diff --git a/trunk/include/asm-mips/addrspace.h b/trunk/include/asm-mips/addrspace.h index c6275088cf65..45c706e34df1 100644 --- a/trunk/include/asm-mips/addrspace.h +++ b/trunk/include/asm-mips/addrspace.h @@ -19,16 +19,12 @@ #define _ATYPE_ #define _ATYPE32_ #define _ATYPE64_ -#define _CONST64_(x) x +#define _LLCONST_(x) x #else #define _ATYPE_ __PTRDIFF_TYPE__ #define _ATYPE32_ int -#define _ATYPE64_ __s64 -#ifdef CONFIG_64BIT -#define _CONST64_(x) x ## L -#else -#define _CONST64_(x) x ## LL -#endif +#define _ATYPE64_ long long +#define _LLCONST_(x) x ## LL #endif /* @@ -52,7 +48,7 @@ */ #define CPHYSADDR(a) ((_ACAST32_(a)) & 0x1fffffff) #define XPHYSADDR(a) ((_ACAST64_(a)) & \ - _CONST64_(0x000000ffffffffff)) + _LLCONST_(0x000000ffffffffff)) #ifdef CONFIG_64BIT @@ -61,14 +57,14 @@ * The compatibility segments use the full 64-bit sign extended value. Note * the R8000 doesn't have them so don't reference these in generic MIPS code. */ -#define XKUSEG _CONST64_(0x0000000000000000) -#define XKSSEG _CONST64_(0x4000000000000000) -#define XKPHYS _CONST64_(0x8000000000000000) -#define XKSEG _CONST64_(0xc000000000000000) -#define CKSEG0 _CONST64_(0xffffffff80000000) -#define CKSEG1 _CONST64_(0xffffffffa0000000) -#define CKSSEG _CONST64_(0xffffffffc0000000) -#define CKSEG3 _CONST64_(0xffffffffe0000000) +#define XKUSEG _LLCONST_(0x0000000000000000) +#define XKSSEG _LLCONST_(0x4000000000000000) +#define XKPHYS _LLCONST_(0x8000000000000000) +#define XKSEG _LLCONST_(0xc000000000000000) +#define CKSEG0 _LLCONST_(0xffffffff80000000) +#define CKSEG1 _LLCONST_(0xffffffffa0000000) +#define CKSSEG _LLCONST_(0xffffffffc0000000) +#define CKSEG3 _LLCONST_(0xffffffffe0000000) #define CKSEG0ADDR(a) (CPHYSADDR(a) | CKSEG0) #define CKSEG1ADDR(a) (CPHYSADDR(a) | CKSEG1) @@ -126,7 +122,7 @@ #define PHYS_TO_XKSEG_UNCACHED(p) PHYS_TO_XKPHYS(K_CALG_UNCACHED,(p)) #define PHYS_TO_XKSEG_CACHED(p) PHYS_TO_XKPHYS(K_CALG_COH_SHAREABLE,(p)) #define XKPHYS_TO_PHYS(p) ((p) & TO_PHYS_MASK) -#define PHYS_TO_XKPHYS(cm,a) (_CONST64_(0x8000000000000000) | \ +#define PHYS_TO_XKPHYS(cm,a) (_LLCONST_(0x8000000000000000) | \ ((cm)<<59) | (a)) #if defined (CONFIG_CPU_R4300) \ @@ -136,20 +132,20 @@ || defined (CONFIG_CPU_NEVADA) \ || defined (CONFIG_CPU_TX49XX) \ || defined (CONFIG_CPU_MIPS64) -#define TO_PHYS_MASK _CONST64_(0x0000000fffffffff) /* 2^^36 - 1 */ +#define TO_PHYS_MASK _LLCONST_(0x0000000fffffffff) /* 2^^36 - 1 */ #endif #if defined (CONFIG_CPU_R8000) /* We keep KUSIZE consistent with R4000 for now (2^^40) instead of (2^^48) */ -#define TO_PHYS_MASK _CONST64_(0x000000ffffffffff) /* 2^^40 - 1 */ +#define TO_PHYS_MASK _LLCONST_(0x000000ffffffffff) /* 2^^40 - 1 */ #endif #if defined (CONFIG_CPU_R10000) -#define TO_PHYS_MASK _CONST64_(0x000000ffffffffff) /* 2^^40 - 1 */ +#define TO_PHYS_MASK _LLCONST_(0x000000ffffffffff) /* 2^^40 - 1 */ #endif #if defined(CONFIG_CPU_SB1) || defined(CONFIG_CPU_SB1A) -#define TO_PHYS_MASK _CONST64_(0x00000fffffffffff) /* 2^^44 - 1 */ +#define TO_PHYS_MASK _LLCONST_(0x00000fffffffffff) /* 2^^44 - 1 */ #endif #ifndef CONFIG_CPU_R8000 @@ -159,7 +155,7 @@ * in order to catch bugs in the source code. */ -#define COMPAT_K1BASE32 _CONST64_(0xffffffffa0000000) +#define COMPAT_K1BASE32 _LLCONST_(0xffffffffa0000000) #define PHYS_TO_COMPATK1(x) ((x) | COMPAT_K1BASE32) /* 32-bit compat k1 */ #endif diff --git a/trunk/include/asm-mips/asm.h b/trunk/include/asm-mips/asm.h index 838eb3144d81..e3038a4599ee 100644 --- a/trunk/include/asm-mips/asm.h +++ b/trunk/include/asm-mips/asm.h @@ -344,7 +344,6 @@ symbol = value #define PTR_L lw #define PTR_S sw #define PTR_LA la -#define PTR_LI li #define PTR_SLL sll #define PTR_SLLV sllv #define PTR_SRL srl @@ -369,7 +368,6 @@ symbol = value #define PTR_L ld #define PTR_S sd #define PTR_LA dla -#define PTR_LI dli #define PTR_SLL dsll #define PTR_SLLV dsllv #define PTR_SRL dsrl diff --git a/trunk/include/asm-mips/atomic.h b/trunk/include/asm-mips/atomic.h index 7978d8e11647..e64abc0d8221 100644 --- a/trunk/include/asm-mips/atomic.h +++ b/trunk/include/asm-mips/atomic.h @@ -9,8 +9,16 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1996, 97, 99, 2000, 03, 04, 06 by Ralf Baechle + * Copyright (C) 1996, 97, 99, 2000, 03, 04 by Ralf Baechle */ + +/* + * As workaround for the ATOMIC_DEC_AND_LOCK / atomic_dec_and_lock mess in + * we have to include outside the + * main big wrapper ... + */ +#include + #ifndef _ASM_ATOMIC_H #define _ASM_ATOMIC_H diff --git a/trunk/include/asm-mips/bitops.h b/trunk/include/asm-mips/bitops.h index b9007411b60f..1bb89c5a10ee 100644 --- a/trunk/include/asm-mips/bitops.h +++ b/trunk/include/asm-mips/bitops.h @@ -10,32 +10,51 @@ #define _ASM_BITOPS_H #include -#include #include #include #include /* sigh ... */ #include -#include -#include #if (_MIPS_SZLONG == 32) #define SZLONG_LOG 5 #define SZLONG_MASK 31UL #define __LL "ll " #define __SC "sc " +#define cpu_to_lelongp(x) cpu_to_le32p((__u32 *) (x)) #elif (_MIPS_SZLONG == 64) #define SZLONG_LOG 6 #define SZLONG_MASK 63UL #define __LL "lld " #define __SC "scd " +#define cpu_to_lelongp(x) cpu_to_le64p((__u64 *) (x)) #endif +#ifdef __KERNEL__ + +#include +#include +#include + /* * clear_bit() doesn't provide any barrier for the compiler. */ #define smp_mb__before_clear_bit() smp_mb() #define smp_mb__after_clear_bit() smp_mb() +/* + * Only disable interrupt for kernel mode stuff to keep usermode stuff + * that dares to use kernel include files alive. + */ + +#define __bi_flags unsigned long flags +#define __bi_local_irq_save(x) local_irq_save(x) +#define __bi_local_irq_restore(x) local_irq_restore(x) +#else +#define __bi_flags +#define __bi_local_irq_save(x) +#define __bi_local_irq_restore(x) +#endif /* __KERNEL__ */ + /* * set_bit - Atomically set a bit in memory * @nr: the bit to set @@ -74,13 +93,13 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) } else { volatile unsigned long *a = addr; unsigned long mask; - unsigned long flags; + __bi_flags; a += nr >> SZLONG_LOG; mask = 1UL << (nr & SZLONG_MASK); - local_irq_save(flags); + __bi_local_irq_save(flags); *a |= mask; - local_irq_restore(flags); + __bi_local_irq_restore(flags); } } @@ -122,13 +141,13 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) } else { volatile unsigned long *a = addr; unsigned long mask; - unsigned long flags; + __bi_flags; a += nr >> SZLONG_LOG; mask = 1UL << (nr & SZLONG_MASK); - local_irq_save(flags); + __bi_local_irq_save(flags); *a &= ~mask; - local_irq_restore(flags); + __bi_local_irq_restore(flags); } } @@ -172,13 +191,13 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr) } else { volatile unsigned long *a = addr; unsigned long mask; - unsigned long flags; + __bi_flags; a += nr >> SZLONG_LOG; mask = 1UL << (nr & SZLONG_MASK); - local_irq_save(flags); + __bi_local_irq_save(flags); *a ^= mask; - local_irq_restore(flags); + __bi_local_irq_restore(flags); } } @@ -239,14 +258,14 @@ static inline int test_and_set_bit(unsigned long nr, volatile unsigned long *a = addr; unsigned long mask; int retval; - unsigned long flags; + __bi_flags; a += nr >> SZLONG_LOG; mask = 1UL << (nr & SZLONG_MASK); - local_irq_save(flags); + __bi_local_irq_save(flags); retval = (mask & *a) != 0; *a |= mask; - local_irq_restore(flags); + __bi_local_irq_restore(flags); return retval; } @@ -311,14 +330,14 @@ static inline int test_and_clear_bit(unsigned long nr, volatile unsigned long *a = addr; unsigned long mask; int retval; - unsigned long flags; + __bi_flags; a += nr >> SZLONG_LOG; mask = 1UL << (nr & SZLONG_MASK); - local_irq_save(flags); + __bi_local_irq_save(flags); retval = (mask & *a) != 0; *a &= ~mask; - local_irq_restore(flags); + __bi_local_irq_restore(flags); return retval; } @@ -380,19 +399,23 @@ static inline int test_and_change_bit(unsigned long nr, } else { volatile unsigned long *a = addr; unsigned long mask, retval; - unsigned long flags; + __bi_flags; a += nr >> SZLONG_LOG; mask = 1UL << (nr & SZLONG_MASK); - local_irq_save(flags); + __bi_local_irq_save(flags); retval = (mask & *a) != 0; *a ^= mask; - local_irq_restore(flags); + __bi_local_irq_restore(flags); return retval; } } +#undef __bi_flags +#undef __bi_local_irq_save +#undef __bi_local_irq_restore + #include /* diff --git a/trunk/include/asm-mips/bug.h b/trunk/include/asm-mips/bug.h index 4d560a533940..7b4739dc8f3f 100644 --- a/trunk/include/asm-mips/bug.h +++ b/trunk/include/asm-mips/bug.h @@ -1,7 +1,6 @@ #ifndef __ASM_BUG_H #define __ASM_BUG_H -#include #ifdef CONFIG_BUG @@ -14,17 +13,6 @@ do { \ #define HAVE_ARCH_BUG -#if (_MIPS_ISA > _MIPS_ISA_MIPS1) - -#define BUG_ON(condition) \ -do { \ - __asm__ __volatile__("tne $0, %0" : : "r" (condition)); \ -} while (0) - -#define HAVE_ARCH_BUG_ON - -#endif /* _MIPS_ISA > _MIPS_ISA_MIPS1 */ - #endif #include diff --git a/trunk/include/asm-mips/cacheflush.h b/trunk/include/asm-mips/cacheflush.h index e3c9925876a3..9ab59e2bb233 100644 --- a/trunk/include/asm-mips/cacheflush.h +++ b/trunk/include/asm-mips/cacheflush.h @@ -55,13 +55,24 @@ extern void (*flush_icache_range)(unsigned long start, unsigned long end); #define flush_cache_vmap(start, end) flush_cache_all() #define flush_cache_vunmap(start, end) flush_cache_all() -extern void copy_to_user_page(struct vm_area_struct *vma, +static inline void copy_to_user_page(struct vm_area_struct *vma, struct page *page, unsigned long vaddr, void *dst, const void *src, - unsigned long len); + unsigned long len) +{ + if (cpu_has_dc_aliases) + flush_cache_page(vma, vaddr, page_to_pfn(page)); + memcpy(dst, src, len); + __flush_icache_page(vma, page); +} -extern void copy_from_user_page(struct vm_area_struct *vma, +static inline void copy_from_user_page(struct vm_area_struct *vma, struct page *page, unsigned long vaddr, void *dst, const void *src, - unsigned long len); + unsigned long len) +{ + if (cpu_has_dc_aliases) + flush_cache_page(vma, vaddr, page_to_pfn(page)); + memcpy(dst, src, len); +} extern void (*flush_cache_sigtramp)(unsigned long addr); extern void (*flush_icache_all)(void); diff --git a/trunk/include/asm-mips/cpu-info.h b/trunk/include/asm-mips/cpu-info.h index 610d0cdeaa9e..a2f0c8ea9160 100644 --- a/trunk/include/asm-mips/cpu-info.h +++ b/trunk/include/asm-mips/cpu-info.h @@ -22,12 +22,12 @@ * Descriptor for a cache */ struct cache_desc { - unsigned int waysize; /* Bytes per way */ + unsigned short linesz; /* Size of line in bytes */ + unsigned short ways; /* Number of ways */ unsigned short sets; /* Number of lines per set */ - unsigned char ways; /* Number of ways */ - unsigned char linesz; /* Size of line in bytes */ - unsigned char waybit; /* Bits to select in a cache set */ - unsigned char flags; /* Flags describing cache properties */ + unsigned int waysize; /* Bytes per way */ + unsigned int waybit; /* Bits to select in a cache set */ + unsigned int flags; /* Flags describing cache properties */ }; /* diff --git a/trunk/include/asm-mips/dec/ecc.h b/trunk/include/asm-mips/dec/ecc.h index 707ffdbc9add..19495a490e72 100644 --- a/trunk/include/asm-mips/dec/ecc.h +++ b/trunk/include/asm-mips/dec/ecc.h @@ -49,7 +49,8 @@ struct pt_regs; extern void dec_ecc_be_init(void); extern int dec_ecc_be_handler(struct pt_regs *regs, int is_fixup); -extern irqreturn_t dec_ecc_be_interrupt(int irq, void *dev_id); +extern irqreturn_t dec_ecc_be_interrupt(int irq, void *dev_id, + struct pt_regs *regs); #endif #endif /* __ASM_MIPS_DEC_ECC_H */ diff --git a/trunk/include/asm-mips/dec/kn01.h b/trunk/include/asm-mips/dec/kn01.h index 28fa717ac423..eb522aa1e226 100644 --- a/trunk/include/asm-mips/dec/kn01.h +++ b/trunk/include/asm-mips/dec/kn01.h @@ -84,7 +84,8 @@ extern spinlock_t kn01_lock; extern void dec_kn01_be_init(void); extern int dec_kn01_be_handler(struct pt_regs *regs, int is_fixup); -extern irqreturn_t dec_kn01_be_interrupt(int irq, void *dev_id); +extern irqreturn_t dec_kn01_be_interrupt(int irq, void *dev_id, + struct pt_regs *regs); #endif #endif /* __ASM_MIPS_DEC_KN01_H */ diff --git a/trunk/include/asm-mips/dec/kn02.h b/trunk/include/asm-mips/dec/kn02.h index 93430b5f4724..8319ad77b250 100644 --- a/trunk/include/asm-mips/dec/kn02.h +++ b/trunk/include/asm-mips/dec/kn02.h @@ -82,9 +82,11 @@ #ifndef __ASSEMBLY__ +#include #include extern u32 cached_kn02_csr; +extern spinlock_t kn02_lock; extern void init_kn02_irqs(int base); #endif diff --git a/trunk/include/asm-mips/dec/kn02xa.h b/trunk/include/asm-mips/dec/kn02xa.h index b56b4577f6ef..a25f3d7da7f7 100644 --- a/trunk/include/asm-mips/dec/kn02xa.h +++ b/trunk/include/asm-mips/dec/kn02xa.h @@ -78,7 +78,8 @@ struct pt_regs; extern void dec_kn02xa_be_init(void); extern int dec_kn02xa_be_handler(struct pt_regs *regs, int is_fixup); -extern irqreturn_t dec_kn02xa_be_interrupt(int irq, void *dev_id); +extern irqreturn_t dec_kn02xa_be_interrupt(int irq, void *dev_id, + struct pt_regs *regs); #endif #endif /* __ASM_MIPS_DEC_KN02XA_H */ diff --git a/trunk/include/asm-mips/device.h b/trunk/include/asm-mips/device.h deleted file mode 100644 index d8f9872b0e2d..000000000000 --- a/trunk/include/asm-mips/device.h +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Arch specific extensions to struct device - * - * This file is released under the GPLv2 - */ -#include - diff --git a/trunk/include/asm-mips/div64.h b/trunk/include/asm-mips/div64.h index d107832de1b6..5f7dcf5452e7 100644 --- a/trunk/include/asm-mips/div64.h +++ b/trunk/include/asm-mips/div64.h @@ -82,6 +82,27 @@ #if (_MIPS_SZLONG == 64) +/* + * Don't use this one in new code + */ +#define do_div64_32(res, high, low, base) ({ \ + unsigned int __quot, __mod; \ + unsigned long __div; \ + unsigned int __low, __high, __base; \ + \ + __high = (high); \ + __low = (low); \ + __div = __high; \ + __div = __div << 32 | __low; \ + __base = (base); \ + \ + __mod = __div % __base; \ + __div = __div / __base; \ + \ + __quot = __div; \ + (res) = __quot; \ + __mod; }) + /* * Hey, we're already 64-bit, no * need to play games.. diff --git a/trunk/include/asm-mips/dma.h b/trunk/include/asm-mips/dma.h index 23f789c80845..e85849ac165f 100644 --- a/trunk/include/asm-mips/dma.h +++ b/trunk/include/asm-mips/dma.h @@ -74,9 +74,7 @@ * */ -#ifndef GENERIC_ISA_DMA_SUPPORT_BROKEN #define MAX_DMA_CHANNELS 8 -#endif /* * The maximum address in KSEG0 that we can perform a DMA transfer to on this diff --git a/trunk/include/asm-mips/fixmap.h b/trunk/include/asm-mips/fixmap.h index 02c8a13fc894..6959bdb59310 100644 --- a/trunk/include/asm-mips/fixmap.h +++ b/trunk/include/asm-mips/fixmap.h @@ -45,16 +45,8 @@ * fix-mapped? */ enum fixed_addresses { -#define FIX_N_COLOURS 8 - FIX_CMAP_BEGIN, -#ifdef CONFIG_MIPS_MT_SMTC - FIX_CMAP_END = FIX_CMAP_BEGIN + (FIX_N_COLOURS * NR_CPUS), -#else - FIX_CMAP_END = FIX_CMAP_BEGIN + FIX_N_COLOURS, -#endif #ifdef CONFIG_HIGHMEM - /* reserved pte's for temporary kernel mappings */ - FIX_KMAP_BEGIN = FIX_CMAP_END + 1, + FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */ FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1, #endif __end_of_fixed_addresses @@ -78,9 +70,9 @@ extern void __set_fixmap (enum fixed_addresses idx, * at the top of mem.. */ #if defined(CONFIG_CPU_TX39XX) || defined(CONFIG_CPU_TX49XX) -#define FIXADDR_TOP ((unsigned long)(long)(int)(0xff000000 - 0x20000)) +#define FIXADDR_TOP (0xff000000UL - 0x2000) #else -#define FIXADDR_TOP ((unsigned long)(long)(int)0xfffe0000) +#define FIXADDR_TOP (0xffffe000UL) #endif #define FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT) #define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE) diff --git a/trunk/include/asm-mips/fpu.h b/trunk/include/asm-mips/fpu.h index efef843b93f0..58c561a9ec6b 100644 --- a/trunk/include/asm-mips/fpu.h +++ b/trunk/include/asm-mips/fpu.h @@ -134,11 +134,9 @@ static inline void restore_fp(struct task_struct *tsk) static inline fpureg_t *get_fpu_regs(struct task_struct *tsk) { - if (tsk == current) { - preempt_disable(); - if (is_fpu_owner()) + if (cpu_has_fpu) { + if ((tsk == current) && __is_fpu_owner()) _save_fp(current); - preempt_enable(); } return tsk->thread.fpu.fpr; diff --git a/trunk/include/asm-mips/gt64120.h b/trunk/include/asm-mips/gt64120.h index 4bf8e28f8850..2edd171bb6cd 100644 --- a/trunk/include/asm-mips/gt64120.h +++ b/trunk/include/asm-mips/gt64120.h @@ -451,13 +451,6 @@ #define GT_SDRAM_OPMODE_OP_MODE 3 #define GT_SDRAM_OPMODE_OP_CBR 4 -#define GT_TC_CONTROL_ENTC0_SHF 0 -#define GT_TC_CONTROL_ENTC0_MSK (MSK(1) << GT_TC_CONTROL_ENTC0_SHF) -#define GT_TC_CONTROL_ENTC0_BIT GT_TC_CONTROL_ENTC0_MSK -#define GT_TC_CONTROL_SELTC0_SHF 1 -#define GT_TC_CONTROL_SELTC0_MSK (MSK(1) << GT_TC_CONTROL_SELTC0_SHF) -#define GT_TC_CONTROL_SELTC0_BIT GT_TC_CONTROL_SELTC0_MSK - #define GT_PCI0_BARE_SWSCS3BOOTDIS_SHF 0 #define GT_PCI0_BARE_SWSCS3BOOTDIS_MSK (MSK(1) << GT_PCI0_BARE_SWSCS3BOOTDIS_SHF) @@ -530,13 +523,6 @@ #define GT_PCI0_CMD_SWORDSWAP_MSK (MSK(1) << GT_PCI0_CMD_SWORDSWAP_SHF) #define GT_PCI0_CMD_SWORDSWAP_BIT GT_PCI0_CMD_SWORDSWAP_MSK -#define GT_INTR_T0EXP_SHF 8 -#define GT_INTR_T0EXP_MSK (MSK(1) << GT_INTR_T0EXP_SHF) -#define GT_INTR_T0EXP_BIT GT_INTR_T0EXP_MSK -#define GT_INTR_RETRYCTR0_SHF 20 -#define GT_INTR_RETRYCTR0_MSK (MSK(1) << GT_INTR_RETRYCTR0_SHF) -#define GT_INTR_RETRYCTR0_BIT GT_INTR_RETRYCTR0_MSK - /* * Misc */ diff --git a/trunk/include/asm-mips/io.h b/trunk/include/asm-mips/io.h index d77b657c09c7..df624e1ee6e2 100644 --- a/trunk/include/asm-mips/io.h +++ b/trunk/include/asm-mips/io.h @@ -113,7 +113,7 @@ static inline void set_io_port_base(unsigned long base) * almost all conceivable cases a device driver should not be using * this function */ -static inline unsigned long virt_to_phys(volatile const void *address) +static inline unsigned long virt_to_phys(volatile void * address) { return (unsigned long)address - PAGE_OFFSET; } @@ -172,7 +172,7 @@ extern unsigned long isa_slot_offset; #define page_to_phys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT) extern void __iomem * __ioremap(phys_t offset, phys_t size, unsigned long flags); -extern void __iounmap(const volatile void __iomem *addr); +extern void __iounmap(volatile void __iomem *addr); static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size, unsigned long flags) @@ -279,7 +279,7 @@ static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size, #define ioremap_uncached_accelerated(offset, size) \ __ioremap_mode((offset), (size), _CACHE_UNCACHED_ACCELERATED) -static inline void iounmap(const volatile void __iomem *addr) +static inline void iounmap(volatile void __iomem *addr) { #define __IS_KSEG1(addr) (((unsigned long)(addr) & ~0x1fffffffUL) == CKSEG1) @@ -561,6 +561,32 @@ extern void pci_iounmap(struct pci_dev *dev, void __iomem *); */ #define eth_io_copy_and_sum(skb,src,len,unused) memcpy_fromio((skb)->data,(src),(len)) +/* + * check_signature - find BIOS signatures + * @io_addr: mmio address to check + * @signature: signature block + * @length: length of signature + * + * Perform a signature comparison with the mmio address io_addr. This + * address should have been obtained by ioremap. + * Returns 1 on a match. + */ +static inline int check_signature(char __iomem *io_addr, + const unsigned char *signature, int length) +{ + int retval = 0; + do { + if (readb(io_addr) != *signature) + goto out; + io_addr++; + signature++; + length--; + } while (length); + retval = 1; +out: + return retval; +} + /* * The caches on some architectures aren't dma-coherent and have need to * handle this in software. There are three types of operations that diff --git a/trunk/include/asm-mips/irq.h b/trunk/include/asm-mips/irq.h index 67657089efa7..d35c61776a02 100644 --- a/trunk/include/asm-mips/irq.h +++ b/trunk/include/asm-mips/irq.h @@ -24,6 +24,10 @@ static inline int irq_canonicalize(int irq) #define irq_canonicalize(irq) (irq) /* Sane hardware, sane code ... */ #endif +struct pt_regs; + +extern asmlinkage unsigned int do_IRQ(unsigned int irq, struct pt_regs *regs); + #ifdef CONFIG_MIPS_MT_SMTC /* * Clear interrupt mask handling "backstop" if irq_hwmask @@ -41,6 +45,8 @@ do { \ #define __DO_IRQ_SMTC_HOOK() do { } while (0) #endif +#ifdef CONFIG_PREEMPT + /* * do_IRQ handles all normal device IRQ's (the special * SMP cross-CPU interrupts have their own specific @@ -49,16 +55,18 @@ do { \ * Ideally there should be away to get this into kernel/irq/handle.c to * avoid the overhead of a call for just a tiny function ... */ -#define do_IRQ(irq) \ +#define do_IRQ(irq, regs) \ do { \ irq_enter(); \ __DO_IRQ_SMTC_HOOK(); \ - generic_handle_irq(irq); \ + __do_IRQ((irq), (regs)); \ irq_exit(); \ } while (0) +#endif + extern void arch_init_irq(void); -extern void spurious_interrupt(void); +extern void spurious_interrupt(struct pt_regs *regs); #ifdef CONFIG_MIPS_MT_SMTC struct irqaction; @@ -68,8 +76,4 @@ extern int setup_irq_smtc(unsigned int irq, struct irqaction * new, unsigned long hwmask); #endif /* CONFIG_MIPS_MT_SMTC */ -extern int allocate_irqno(void); -extern void alloc_legacy_irqno(void); -extern void free_irqno(unsigned int irq); - #endif /* _ASM_IRQ_H */ diff --git a/trunk/include/asm-mips/irq_regs.h b/trunk/include/asm-mips/irq_regs.h deleted file mode 100644 index 33bd2a06de57..000000000000 --- a/trunk/include/asm-mips/irq_regs.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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. - * - * Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org) - */ -#ifndef __ASM_IRQ_REGS_H -#define __ASM_IRQ_REGS_H - -#define ARCH_HAS_OWN_IRQ_REGS - -#include - -static inline struct pt_regs *get_irq_regs(void) -{ - return current_thread_info()->regs; -} - -#endif /* __ASM_IRQ_REGS_H */ diff --git a/trunk/include/asm-mips/jmr3927/irq.h b/trunk/include/asm-mips/jmr3927/irq.h index e3e7ed38da6c..fe551f33a74f 100644 --- a/trunk/include/asm-mips/jmr3927/irq.h +++ b/trunk/include/asm-mips/jmr3927/irq.h @@ -45,6 +45,10 @@ extern int toshibaboards_setup_irq(int irq, struct irqaction * new); +#ifdef CONFIG_TX_BRANCH_LIKELY_BUG_WORKAROUND +extern void tx_branch_likely_bug_fixup(struct pt_regs *regs); +#endif + extern int (*toshibaboards_gen_iack)(void); #endif /* !__ASSEMBLY__ */ diff --git a/trunk/include/asm-mips/kexec.h b/trunk/include/asm-mips/kexec.h deleted file mode 100644 index b25267ebcb09..000000000000 --- a/trunk/include/asm-mips/kexec.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * kexec.h for kexec - * Created by on Thu Oct 12 14:59:34 2006 - * - * This source code is licensed under the GNU General Public License, - * Version 2. See the file COPYING for more details. - */ - -#ifndef _MIPS_KEXEC -# define _MIPS_KEXEC - -/* Maximum physical address we can use pages from */ -#define KEXEC_SOURCE_MEMORY_LIMIT (0x20000000) -/* Maximum address we can reach in physical address mode */ -#define KEXEC_DESTINATION_MEMORY_LIMIT (0x20000000) - /* Maximum address we can use for the control code buffer */ -#define KEXEC_CONTROL_MEMORY_LIMIT (0x20000000) - -#define KEXEC_CONTROL_CODE_SIZE 4096 - -/* The native architecture */ -#define KEXEC_ARCH KEXEC_ARCH_MIPS - -#define MAX_NOTE_BYTES 1024 - -static inline void crash_setup_regs(struct pt_regs *newregs, - struct pt_regs *oldregs) -{ - /* Dummy implementation for now */ -} - -#endif /* !_MIPS_KEXEC */ diff --git a/trunk/include/asm-mips/mach-au1x00/au1000_dma.h b/trunk/include/asm-mips/mach-au1x00/au1000_dma.h index 9f29520e8fb0..810f2fa33444 100644 --- a/trunk/include/asm-mips/mach-au1x00/au1000_dma.h +++ b/trunk/include/asm-mips/mach-au1x00/au1000_dma.h @@ -123,7 +123,8 @@ struct dma_chan { extern struct dma_chan au1000_dma_table[]; extern int request_au1000_dma(int dev_id, const char *dev_str, - irq_handler_t irqhandler, + irqreturn_t (*irqhandler)(int, void *, + struct pt_regs *), unsigned long irqflags, void *irq_dev_id); extern void free_au1000_dma(unsigned int dmanr); diff --git a/trunk/include/asm-mips/mach-au1x00/au1000_usbdev.h b/trunk/include/asm-mips/mach-au1x00/au1000_usbdev.h new file mode 100644 index 000000000000..05bc74bed0b1 --- /dev/null +++ b/trunk/include/asm-mips/mach-au1x00/au1000_usbdev.h @@ -0,0 +1,73 @@ +/* + * BRIEF MODULE DESCRIPTION + * Au1000 USB Device-Side Driver + * + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * stevel@mvista.com or source@mvista.com + * + * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#define USBDEV_REV 0x0110 // BCD +#define USBDEV_EP0_MAX_PACKET_SIZE 64 + +typedef enum { + ATTACHED = 0, + POWERED, + DEFAULT, + ADDRESS, + CONFIGURED +} usbdev_state_t; + +typedef enum { + CB_NEW_STATE = 0, + CB_PKT_COMPLETE +} usbdev_cb_type_t; + + +typedef struct usbdev_pkt { + int ep_addr; // ep addr this packet routed to + int size; // size of payload in bytes + unsigned status; // packet status + struct usbdev_pkt* next; // function layer can't touch this + u8 payload[0]; // the payload +} usbdev_pkt_t; + +#define PKT_STATUS_ACK (1<<0) +#define PKT_STATUS_NAK (1<<1) +#define PKT_STATUS_SU (1<<2) + +extern int usbdev_init(struct usb_device_descriptor* dev_desc, + struct usb_config_descriptor* config_desc, + struct usb_interface_descriptor* if_desc, + struct usb_endpoint_descriptor* ep_desc, + struct usb_string_descriptor* str_desc[], + void (*cb)(usbdev_cb_type_t, unsigned long, void *), + void* cb_data); + +extern void usbdev_exit(void); + +extern int usbdev_alloc_packet (int ep_addr, int data_size, + usbdev_pkt_t** pkt); +extern int usbdev_send_packet (int ep_addr, usbdev_pkt_t* pkt); +extern int usbdev_receive_packet(int ep_addr, usbdev_pkt_t** pkt); +extern int usbdev_get_byte_count(int ep_addr); diff --git a/trunk/include/asm-mips/mach-au1x00/au1xxx_ide.h b/trunk/include/asm-mips/mach-au1x00/au1xxx_ide.h index e9fa252f8a3f..301e71300779 100644 --- a/trunk/include/asm-mips/mach-au1x00/au1xxx_ide.h +++ b/trunk/include/asm-mips/mach-au1x00/au1xxx_ide.h @@ -170,8 +170,10 @@ int __init auide_probe(void); static int auide_dma_host_on(ide_drive_t *drive); static int auide_dma_lostirq(ide_drive_t *drive); static int auide_dma_on(ide_drive_t *drive); - static void auide_ddma_tx_callback(int irq, void *param); - static void auide_ddma_rx_callback(int irq, void *param); + static void auide_ddma_tx_callback(int irq, void *param, + struct pt_regs *regs); + static void auide_ddma_rx_callback(int irq, void *param, + struct pt_regs *regs); static int auide_dma_off_quietly(ide_drive_t *drive); #endif /* end CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */ diff --git a/trunk/include/asm-mips/mach-cobalt/cobalt.h b/trunk/include/asm-mips/mach-cobalt/cobalt.h index 00b0fc68d5cb..b3c5ecbec03c 100644 --- a/trunk/include/asm-mips/mach-cobalt/cobalt.h +++ b/trunk/include/asm-mips/mach-cobalt/cobalt.h @@ -67,9 +67,34 @@ #define COBALT_BRD_ID_QUBE2 0x5 #define COBALT_BRD_ID_RAQ2 0x6 +/* + * Galileo chipset access macros for the Cobalt. The base address for + * the GT64111 chip is 0x14000000 + * + * Most of this really should go into a separate GT64111 header file. + */ +#define GT64111_IO_BASE 0x10000000UL +#define GT64111_IO_END 0x11ffffffUL +#define GT64111_MEM_BASE 0x12000000UL +#define GT64111_MEM_END 0x13ffffffUL +#define GT64111_BASE 0x14000000UL +#define GALILEO_REG(ofs) CKSEG1ADDR(GT64111_BASE + (unsigned long)(ofs)) + +#define GALILEO_INL(port) (*(volatile unsigned int *) GALILEO_REG(port)) +#define GALILEO_OUTL(val, port) \ +do { \ + *(volatile unsigned int *) GALILEO_REG(port) = (val); \ +} while (0) + +#define GALILEO_INTR_T0EXP (1 << 8) +#define GALILEO_INTR_RETRY_CTR (1 << 20) + +#define GALILEO_ENTC0 0x01 +#define GALILEO_SELTC0 0x02 + #define PCI_CFG_SET(devfn,where) \ - GT_WRITE(GT_PCI0_CFGADDR_OFS, (0x80000000 | (PCI_SLOT (devfn) << 11) | \ - (PCI_FUNC (devfn) << 8) | (where))) + GALILEO_OUTL((0x80000000 | (PCI_SLOT (devfn) << 11) | \ + (PCI_FUNC (devfn) << 8) | (where)), GT_PCI0_CFGADDR_OFS) #define COBALT_LED_PORT (*(volatile unsigned char *) CKSEG1ADDR(0x1c000000)) # define COBALT_LED_BAR_LEFT (1 << 0) /* Qube */ diff --git a/trunk/include/asm-mips/mach-cobalt/mach-gt64120.h b/trunk/include/asm-mips/mach-cobalt/mach-gt64120.h index ae9c5523c7ef..587fc4378f44 100644 --- a/trunk/include/asm-mips/mach-cobalt/mach-gt64120.h +++ b/trunk/include/asm-mips/mach-cobalt/mach-gt64120.h @@ -1,27 +1 @@ -/* - * Copyright (C) 2006 Yoichi Yuasa - * - * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#ifndef _COBALT_MACH_GT64120_H -#define _COBALT_MACH_GT64120_H - -/* - * Cobalt uses GT64111. GT64111 is almost the same as GT64120. - */ - -#define GT64120_BASE CKSEG1ADDR(GT_DEF_BASE) - -#endif /* _COBALT_MACH_GT64120_H */ +/* there's something here ... in the dark */ diff --git a/trunk/include/asm-mips/marvell.h b/trunk/include/asm-mips/marvell.h index df94955b098a..6bb2125bb053 100644 --- a/trunk/include/asm-mips/marvell.h +++ b/trunk/include/asm-mips/marvell.h @@ -53,6 +53,6 @@ struct mv_pci_controller { unsigned long config_vreg; }; -extern void ll_mv64340_irq(void); +extern void ll_mv64340_irq(struct pt_regs *regs); #endif /* __ASM_MIPS_MARVELL_H */ diff --git a/trunk/include/asm-mips/mipsmtregs.h b/trunk/include/asm-mips/mipsmtregs.h index 3e9468f424f4..f637ce70758f 100644 --- a/trunk/include/asm-mips/mipsmtregs.h +++ b/trunk/include/asm-mips/mipsmtregs.h @@ -352,8 +352,6 @@ do { \ #define write_vpe_c0_vpecontrol(val) mttc0(1, 1, val) #define read_vpe_c0_vpeconf0() mftc0(1, 2) #define write_vpe_c0_vpeconf0(val) mttc0(1, 2, val) -#define read_vpe_c0_count() mftc0(9, 0) -#define write_vpe_c0_count(val) mttc0(9, 0, val) #define read_vpe_c0_status() mftc0(12, 0) #define write_vpe_c0_status(val) mttc0(12, 0, val) #define read_vpe_c0_cause() mftc0(13, 0) diff --git a/trunk/include/asm-mips/mipsregs.h b/trunk/include/asm-mips/mipsregs.h index 9985cb7c16e7..1f318d707998 100644 --- a/trunk/include/asm-mips/mipsregs.h +++ b/trunk/include/asm-mips/mipsregs.h @@ -545,6 +545,62 @@ #define MIPS_FPIR_L (_ULCAST_(1) << 21) #define MIPS_FPIR_F64 (_ULCAST_(1) << 22) +/* + * R10000 performance counter definitions. + * + * FIXME: The R10000 performance counter opens a nice way to implement CPU + * time accounting with a precission of one cycle. I don't have + * R10000 silicon but just a manual, so ... + */ + +/* + * Events counted by counter #0 + */ +#define CE0_CYCLES 0 +#define CE0_INSN_ISSUED 1 +#define CE0_LPSC_ISSUED 2 +#define CE0_S_ISSUED 3 +#define CE0_SC_ISSUED 4 +#define CE0_SC_FAILED 5 +#define CE0_BRANCH_DECODED 6 +#define CE0_QW_WB_SECONDARY 7 +#define CE0_CORRECTED_ECC_ERRORS 8 +#define CE0_ICACHE_MISSES 9 +#define CE0_SCACHE_I_MISSES 10 +#define CE0_SCACHE_I_WAY_MISSPREDICTED 11 +#define CE0_EXT_INTERVENTIONS_REQ 12 +#define CE0_EXT_INVALIDATE_REQ 13 +#define CE0_VIRTUAL_COHERENCY_COND 14 +#define CE0_INSN_GRADUATED 15 + +/* + * Events counted by counter #1 + */ +#define CE1_CYCLES 0 +#define CE1_INSN_GRADUATED 1 +#define CE1_LPSC_GRADUATED 2 +#define CE1_S_GRADUATED 3 +#define CE1_SC_GRADUATED 4 +#define CE1_FP_INSN_GRADUATED 5 +#define CE1_QW_WB_PRIMARY 6 +#define CE1_TLB_REFILL 7 +#define CE1_BRANCH_MISSPREDICTED 8 +#define CE1_DCACHE_MISS 9 +#define CE1_SCACHE_D_MISSES 10 +#define CE1_SCACHE_D_WAY_MISSPREDICTED 11 +#define CE1_EXT_INTERVENTION_HITS 12 +#define CE1_EXT_INVALIDATE_REQ 13 +#define CE1_SP_HINT_TO_CEXCL_SC_BLOCKS 14 +#define CE1_SP_HINT_TO_SHARED_SC_BLOCKS 15 + +/* + * These flags define in which privilege mode the counters count events + */ +#define CEB_USER 8 /* Count events in user mode, EXL = ERL = 0 */ +#define CEB_SUPERVISOR 4 /* Count events in supvervisor mode EXL = ERL = 0 */ +#define CEB_KERNEL 2 /* Count events in kernel mode EXL = ERL = 0 */ +#define CEB_EXL 1 /* Count events with EXL = 1, ERL = 0 */ + #ifndef __ASSEMBLY__ /* diff --git a/trunk/include/asm-mips/msc01_ic.h b/trunk/include/asm-mips/msc01_ic.h index aa7ad9a71762..64f17208d602 100644 --- a/trunk/include/asm-mips/msc01_ic.h +++ b/trunk/include/asm-mips/msc01_ic.h @@ -145,7 +145,7 @@ typedef struct msc_irqmap { #define MSC01_IRQ_EDGE 1 extern void __init init_msc_irqs(unsigned int base, msc_irqmap_t *imp, int nirq); -extern void ll_msc_irq(void); +extern void ll_msc_irq(struct pt_regs *regs); #endif /* __ASM_MIPS_BOARDS_MSC01_IC_H */ diff --git a/trunk/include/asm-mips/page.h b/trunk/include/asm-mips/page.h index 0dc1a45c27ed..85b258ee7090 100644 --- a/trunk/include/asm-mips/page.h +++ b/trunk/include/asm-mips/page.h @@ -34,9 +34,7 @@ #ifndef __ASSEMBLY__ -#include #include -#include extern void clear_page(void * page); extern void copy_page(void * to, void * from); @@ -136,14 +134,8 @@ typedef struct { unsigned long pgprot; } pgprot_t; /* to align the pointer to the (next) page boundary */ #define PAGE_ALIGN(addr) (((addr) + PAGE_SIZE - 1) & PAGE_MASK) -#if defined(CONFIG_64BIT) && !defined(CONFIG_BUILD_ELF64) -#define __pa_page_offset(x) ((unsigned long)(x) < CKSEG0 ? PAGE_OFFSET : CKSEG0) -#else -#define __pa_page_offset(x) PAGE_OFFSET -#endif -#define __pa(x) ((unsigned long)(x) - __pa_page_offset(x)) -#define __pa_symbol(x) __pa(RELOC_HIDE((unsigned long)(x),0)) -#define __va(x) ((void *)((unsigned long)(x) + PAGE_OFFSET)) +#define __pa(x) ((unsigned long) (x) - PAGE_OFFSET) +#define __va(x) ((void *)((unsigned long) (x) + PAGE_OFFSET)) #define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) @@ -168,8 +160,8 @@ typedef struct { unsigned long pgprot; } pgprot_t; #endif -#define virt_to_page(kaddr) pfn_to_page(PFN_DOWN(virt_to_phys(kaddr))) -#define virt_addr_valid(kaddr) pfn_valid(PFN_DOWN(virt_to_phys(kaddr))) +#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) +#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) diff --git a/trunk/include/asm-mips/pgalloc.h b/trunk/include/asm-mips/pgalloc.h index af121c67dc71..582c1fe6cc4a 100644 --- a/trunk/include/asm-mips/pgalloc.h +++ b/trunk/include/asm-mips/pgalloc.h @@ -48,7 +48,7 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm) ret = (pgd_t *) __get_free_pages(GFP_KERNEL, PGD_ORDER); if (ret) { - init = pgd_offset(&init_mm, 0UL); + init = pgd_offset(&init_mm, 0); pgd_init((unsigned long)ret); memcpy(ret + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD, (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); diff --git a/trunk/include/asm-mips/pgtable-64.h b/trunk/include/asm-mips/pgtable-64.h index b9b1e86493ee..d05fb6f38aa7 100644 --- a/trunk/include/asm-mips/pgtable-64.h +++ b/trunk/include/asm-mips/pgtable-64.h @@ -14,7 +14,6 @@ #include #include #include -#include #include @@ -104,13 +103,6 @@ #define VMALLOC_START MAP_BASE #define VMALLOC_END \ (VMALLOC_START + PTRS_PER_PGD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE) -#if defined(CONFIG_MODULES) && !defined(CONFIG_BUILD_ELF64) && \ - VMALLOC_START != CKSSEG -/* Load modules into 32bit-compatible segment. */ -#define MODULE_START CKSSEG -#define MODULE_END (FIXADDR_START-2*PAGE_SIZE) -extern pgd_t module_pg_dir[PTRS_PER_PGD]; -#endif #define pte_ERROR(e) \ printk("%s:%d: bad pte %016lx.\n", __FILE__, __LINE__, pte_val(e)) @@ -182,12 +174,7 @@ static inline void pud_clear(pud_t *pudp) #define __pmd_offset(address) pmd_index(address) /* to find an entry in a kernel page-table-directory */ -#ifdef MODULE_START -#define pgd_offset_k(address) \ - ((address) >= MODULE_START ? module_pg_dir : pgd_offset(&init_mm, 0UL)) -#else -#define pgd_offset_k(address) pgd_offset(&init_mm, 0UL) -#endif +#define pgd_offset_k(address) pgd_offset(&init_mm, 0) #define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1)) #define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1)) diff --git a/trunk/include/asm-mips/pgtable.h b/trunk/include/asm-mips/pgtable.h index f2e1325fec6c..1ca4d1e185c7 100644 --- a/trunk/include/asm-mips/pgtable.h +++ b/trunk/include/asm-mips/pgtable.h @@ -67,7 +67,7 @@ extern unsigned long empty_zero_page; extern unsigned long zero_page_mask; #define ZERO_PAGE(vaddr) \ - (virt_to_page((void *)(empty_zero_page + (((unsigned long)(vaddr)) & zero_page_mask)))) + (virt_to_page(empty_zero_page + (((unsigned long)(vaddr)) & zero_page_mask))) #define __HAVE_ARCH_MOVE_PTE #define move_pte(pte, prot, old_addr, new_addr) \ diff --git a/trunk/include/asm-mips/ptrace.h b/trunk/include/asm-mips/ptrace.h index 30bf555faeaa..5f3a9075cd28 100644 --- a/trunk/include/asm-mips/ptrace.h +++ b/trunk/include/asm-mips/ptrace.h @@ -80,6 +80,8 @@ struct pt_regs { #define instruction_pointer(regs) ((regs)->cp0_epc) #define profile_pc(regs) instruction_pointer(regs) +extern void show_regs(struct pt_regs *); + extern asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit); #endif diff --git a/trunk/include/asm-mips/sibyte/sb1250.h b/trunk/include/asm-mips/sibyte/sb1250.h index 2ba6988ddc8e..b09e16c93ca0 100644 --- a/trunk/include/asm-mips/sibyte/sb1250.h +++ b/trunk/include/asm-mips/sibyte/sb1250.h @@ -51,8 +51,8 @@ extern void sb1250_mask_irq(int cpu, int irq); extern void sb1250_unmask_irq(int cpu, int irq); extern void sb1250_smp_finish(void); -extern void bcm1480_hpt_setup(void); extern void bcm1480_time_init(void); +extern unsigned long bcm1480_gettimeoffset(void); extern void bcm1480_mask_irq(int cpu, int irq); extern void bcm1480_unmask_irq(int cpu, int irq); extern void bcm1480_smp_finish(void); diff --git a/trunk/include/asm-mips/stackframe.h b/trunk/include/asm-mips/stackframe.h index 1fae5dc58138..158a4cd12e46 100644 --- a/trunk/include/asm-mips/stackframe.h +++ b/trunk/include/asm-mips/stackframe.h @@ -59,43 +59,69 @@ .endm #ifdef CONFIG_SMP -#ifdef CONFIG_MIPS_MT_SMTC -#define PTEBASE_SHIFT 19 /* TCBIND */ -#else -#define PTEBASE_SHIFT 23 /* CONTEXT */ -#endif .macro get_saved_sp /* SMP variation */ +#ifdef CONFIG_32BIT #ifdef CONFIG_MIPS_MT_SMTC - mfc0 k0, CP0_TCBIND -#else - MFC0 k0, CP0_CONTEXT -#endif -#if defined(CONFIG_BUILD_ELF64) || (defined(CONFIG_64BIT) && __GNUC__ < 4) - lui k1, %highest(kernelsp) - daddiu k1, %higher(kernelsp) - dsll k1, 16 - daddiu k1, %hi(kernelsp) - dsll k1, 16 + .set mips32 + mfc0 k0, CP0_TCBIND; + .set mips0 + lui k1, %hi(kernelsp) + srl k0, k0, 19 + /* No need to shift down and up to clear bits 0-1 */ #else + mfc0 k0, CP0_CONTEXT lui k1, %hi(kernelsp) + srl k0, k0, 23 +#endif + addu k1, k0 + LONG_L k1, %lo(kernelsp)(k1) #endif - LONG_SRL k0, PTEBASE_SHIFT - LONG_ADDU k1, k0 +#ifdef CONFIG_64BIT +#ifdef CONFIG_MIPS_MT_SMTC + .set mips64 + mfc0 k0, CP0_TCBIND; + .set mips0 + lui k0, %highest(kernelsp) + dsrl k1, 19 + /* No need to shift down and up to clear bits 0-2 */ +#else + MFC0 k1, CP0_CONTEXT + lui k0, %highest(kernelsp) + dsrl k1, 23 + daddiu k0, %higher(kernelsp) + dsll k0, k0, 16 + daddiu k0, %hi(kernelsp) + dsll k0, k0, 16 +#endif /* CONFIG_MIPS_MT_SMTC */ + daddu k1, k1, k0 LONG_L k1, %lo(kernelsp)(k1) +#endif /* CONFIG_64BIT */ .endm .macro set_saved_sp stackp temp temp2 +#ifdef CONFIG_32BIT +#ifdef CONFIG_MIPS_MT_SMTC + mfc0 \temp, CP0_TCBIND + srl \temp, 19 +#else + mfc0 \temp, CP0_CONTEXT + srl \temp, 23 +#endif +#endif +#ifdef CONFIG_64BIT #ifdef CONFIG_MIPS_MT_SMTC mfc0 \temp, CP0_TCBIND + dsrl \temp, 19 #else MFC0 \temp, CP0_CONTEXT + dsrl \temp, 23 +#endif #endif - LONG_SRL \temp, PTEBASE_SHIFT LONG_S \stackp, kernelsp(\temp) .endm #else .macro get_saved_sp /* Uniprocessor variation */ -#if defined(CONFIG_BUILD_ELF64) || (defined(CONFIG_64BIT) && __GNUC__ < 4) +#ifdef CONFIG_64BIT lui k1, %highest(kernelsp) daddiu k1, %higher(kernelsp) dsll k1, k1, 16 diff --git a/trunk/include/asm-mips/system.h b/trunk/include/asm-mips/system.h index 3056feed5a36..dcb4701d5728 100644 --- a/trunk/include/asm-mips/system.h +++ b/trunk/include/asm-mips/system.h @@ -392,7 +392,7 @@ static inline unsigned long __cmpxchg_u64(volatile int * m, unsigned long old, { __u64 retval; - if (cpu_has_llsc && R10000_LLSC_WAR) { + if (cpu_has_llsc) { __asm__ __volatile__( " .set push \n" " .set noat \n" diff --git a/trunk/include/asm-mips/termbits.h b/trunk/include/asm-mips/termbits.h index b62ec7c521cc..fa6d04dac56b 100644 --- a/trunk/include/asm-mips/termbits.h +++ b/trunk/include/asm-mips/termbits.h @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1995, 96, 99, 2001, 06 Ralf Baechle + * Copyright (C) 1995, 1996, 1999, 2001 Ralf Baechle * Copyright (C) 1999 Silicon Graphics, Inc. * Copyright (C) 2001 MIPS Technologies, Inc. */ @@ -13,8 +13,14 @@ #include typedef unsigned char cc_t; -typedef unsigned int speed_t; -typedef unsigned int tcflag_t; +#if (_MIPS_SZLONG == 32) +typedef unsigned long speed_t; +typedef unsigned long tcflag_t; +#endif +#if (_MIPS_SZLONG == 64) +typedef __u32 speed_t; +typedef __u32 tcflag_t; +#endif /* * The ABI says nothing about NCC but seems to use NCCS as diff --git a/trunk/include/asm-mips/thread_info.h b/trunk/include/asm-mips/thread_info.h index e475c45ea263..ae8ada5b42a9 100644 --- a/trunk/include/asm-mips/thread_info.h +++ b/trunk/include/asm-mips/thread_info.h @@ -34,7 +34,6 @@ struct thread_info { 0-0xFFFFFFFF for kernel-thread */ struct restart_block restart_block; - struct pt_regs *regs; }; /* diff --git a/trunk/include/asm-mips/time.h b/trunk/include/asm-mips/time.h index a632cef830a2..2d543735668b 100644 --- a/trunk/include/asm-mips/time.h +++ b/trunk/include/asm-mips/time.h @@ -21,7 +21,6 @@ #include #include #include -#include extern spinlock_t rtc_lock; @@ -45,10 +44,11 @@ extern int (*mips_timer_state)(void); extern void (*mips_timer_ack)(void); /* - * High precision timer clocksource. - * If .read is NULL, an R4k-compatible timer setup is attempted. + * High precision timer functions. + * If mips_hpt_read is NULL, an R4k-compatible timer setup is attempted. */ -extern struct clocksource clocksource_mips; +extern unsigned int (*mips_hpt_read)(void); +extern void (*mips_hpt_init)(unsigned int); /* * to_tm() converts system time back to (year, mon, day, hour, min, sec). @@ -57,21 +57,28 @@ extern struct clocksource clocksource_mips; */ extern void to_tm(unsigned long tim, struct rtc_time *tm); +/* + * do_gettimeoffset(). By default, this func pointer points to + * do_null_gettimeoffset(), which leads to the same resolution as HZ. + * Higher resolution versions are available, which give ~1us resolution. + */ +extern unsigned long (*do_gettimeoffset)(void); + /* * high-level timer interrupt routines. */ -extern irqreturn_t timer_interrupt(int irq, void *dev_id); +extern irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs); /* * the corresponding low-level timer interrupt routine. */ -extern asmlinkage void ll_timer_interrupt(int irq); +extern asmlinkage void ll_timer_interrupt(int irq, struct pt_regs *regs); /* * profiling and process accouting is done separately in local_timer_interrupt */ -extern void local_timer_interrupt(int irq, void *dev_id); -extern asmlinkage void ll_local_timer_interrupt(int irq); +extern void local_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs); +extern asmlinkage void ll_local_timer_interrupt(int irq, struct pt_regs *regs); /* * board specific routines required by time_init(). diff --git a/trunk/include/asm-mips/unistd.h b/trunk/include/asm-mips/unistd.h index ec56aa52f669..685c91467e63 100644 --- a/trunk/include/asm-mips/unistd.h +++ b/trunk/include/asm-mips/unistd.h @@ -331,19 +331,16 @@ #define __NR_move_pages (__NR_Linux + 308) #define __NR_set_robust_list (__NR_Linux + 309) #define __NR_get_robust_list (__NR_Linux + 310) -#define __NR_kexec_load (__NR_Linux + 311) -#define __NR_getcpu (__NR_Linux + 312) -#define __NR_epoll_pwait (__NR_Linux + 313) /* * Offset of the last Linux o32 flavoured syscall */ -#define __NR_Linux_syscalls 313 +#define __NR_Linux_syscalls 310 #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */ #define __NR_O32_Linux 4000 -#define __NR_O32_Linux_syscalls 313 +#define __NR_O32_Linux_syscalls 310 #if _MIPS_SIM == _MIPS_SIM_ABI64 @@ -621,19 +618,16 @@ #define __NR_move_pages (__NR_Linux + 267) #define __NR_set_robust_list (__NR_Linux + 268) #define __NR_get_robust_list (__NR_Linux + 269) -#define __NR_kexec_load (__NR_Linux + 270) -#define __NR_getcpu (__NR_Linux + 271) -#define __NR_epoll_pwait (__NR_Linux + 272) /* * Offset of the last Linux 64-bit flavoured syscall */ -#define __NR_Linux_syscalls 272 +#define __NR_Linux_syscalls 269 #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */ #define __NR_64_Linux 5000 -#define __NR_64_Linux_syscalls 272 +#define __NR_64_Linux_syscalls 269 #if _MIPS_SIM == _MIPS_SIM_NABI32 @@ -915,19 +909,16 @@ #define __NR_move_pages (__NR_Linux + 271) #define __NR_set_robust_list (__NR_Linux + 272) #define __NR_get_robust_list (__NR_Linux + 273) -#define __NR_kexec_load (__NR_Linux + 274) -#define __NR_getcpu (__NR_Linux + 275) -#define __NR_epoll_pwait (__NR_Linux + 276) /* * Offset of the last N32 flavoured syscall */ -#define __NR_Linux_syscalls 276 +#define __NR_Linux_syscalls 273 #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */ #define __NR_N32_Linux 6000 -#define __NR_N32_Linux_syscalls 276 +#define __NR_N32_Linux_syscalls 273 #ifdef __KERNEL__ @@ -1195,7 +1186,6 @@ type name (atype a,btype b,ctype c,dtype d,etype e,ftype f) \ #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 #define __ARCH_WANT_SYS_ALARM diff --git a/trunk/include/asm-mips/vr41xx/vr41xx.h b/trunk/include/asm-mips/vr41xx/vr41xx.h index 88b492f6ea9c..dd3eb3dc5886 100644 --- a/trunk/include/asm-mips/vr41xx/vr41xx.h +++ b/trunk/include/asm-mips/vr41xx/vr41xx.h @@ -75,7 +75,7 @@ extern void vr41xx_mask_clock(vr41xx_clock_t clock); * Interrupt Control Unit */ extern int vr41xx_set_intassign(unsigned int irq, unsigned char intassign); -extern int cascade_irq(unsigned int irq, int (*get_irq)(unsigned int)); +extern int cascade_irq(unsigned int irq, int (*get_irq)(unsigned int, struct pt_regs *)); #define PIUINT_COMMAND 0x0040 #define PIUINT_DATA 0x0020 diff --git a/trunk/include/asm-parisc/device.h b/trunk/include/asm-parisc/device.h deleted file mode 100644 index d8f9872b0e2d..000000000000 --- a/trunk/include/asm-parisc/device.h +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Arch specific extensions to struct device - * - * This file is released under the GPLv2 - */ -#include - diff --git a/trunk/include/asm-parisc/dma.h b/trunk/include/asm-parisc/dma.h index 31ad0f05af3d..da2cf373e31c 100644 --- a/trunk/include/asm-parisc/dma.h +++ b/trunk/include/asm-parisc/dma.h @@ -17,10 +17,10 @@ /* ** DMA_CHUNK_SIZE is used by the SCSI mid-layer to break up -** (or rather not merge) DMAs into manageable chunks. +** (or rather not merge) DMA's into managable chunks. ** On parisc, this is more of the software/tuning constraint -** rather than the HW. I/O MMU allocation algorithms can be -** faster with smaller sizes (to some degree). +** rather than the HW. I/O MMU allocation alogorithms can be +** faster with smaller size is (to some degree). */ #define DMA_CHUNK_SIZE (BITS_PER_LONG*PAGE_SIZE) diff --git a/trunk/include/asm-parisc/irq_regs.h b/trunk/include/asm-parisc/irq_regs.h deleted file mode 100644 index 3dd9c0b70270..000000000000 --- a/trunk/include/asm-parisc/irq_regs.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/include/asm-parisc/pci.h b/trunk/include/asm-parisc/pci.h index 7b3be9ac0dda..7b8ad118d2fe 100644 --- a/trunk/include/asm-parisc/pci.h +++ b/trunk/include/asm-parisc/pci.h @@ -149,7 +149,7 @@ extern int parisc_bus_is_phys; /* in arch/parisc/kernel/setup.c */ /* ** Most PCI devices (eg Tulip, NCR720) also export the same registers ** to both MMIO and I/O port space. Due to poor performance of I/O Port -** access under HP PCI bus adapters, strongly recommend the use of MMIO +** access under HP PCI bus adapters, strongly reccomend use of MMIO ** address space. ** ** While I'm at it more PA programming notes: diff --git a/trunk/include/asm-parisc/pdc.h b/trunk/include/asm-parisc/pdc.h index 423c2b84b4a0..c9b2e35326ee 100644 --- a/trunk/include/asm-parisc/pdc.h +++ b/trunk/include/asm-parisc/pdc.h @@ -774,6 +774,8 @@ int pdc_sti_call(unsigned long func, unsigned long flags, unsigned long inptr, unsigned long outputr, unsigned long glob_cfg); +extern void pdc_init(void); + static inline char * os_id_to_string(u16 os_id) { switch(os_id) { case OS_ID_NONE: return "No OS"; diff --git a/trunk/include/asm-parisc/ropes.h b/trunk/include/asm-parisc/ropes.h index 007a880615eb..5542dd00472b 100644 --- a/trunk/include/asm-parisc/ropes.h +++ b/trunk/include/asm-parisc/ropes.h @@ -14,7 +14,7 @@ #endif /* -** The number of pdir entries to "free" before issuing +** The number of pdir entries to "free" before issueing ** a read to PCOM register to flush out PCOM writes. ** Interacts with allocation granularity (ie 4 or 8 entries ** allocated and free'd/purged at a time might make this diff --git a/trunk/include/asm-parisc/semaphore.h b/trunk/include/asm-parisc/semaphore.h index d45827a21f94..c9ee41cd0707 100644 --- a/trunk/include/asm-parisc/semaphore.h +++ b/trunk/include/asm-parisc/semaphore.h @@ -115,8 +115,7 @@ extern __inline__ int down_interruptible(struct semaphore * sem) */ extern __inline__ int down_trylock(struct semaphore * sem) { - unsigned long flags; - int count; + int flags, count; spin_lock_irqsave(&sem->sentry, flags); count = sem->count - 1; @@ -132,8 +131,7 @@ extern __inline__ int down_trylock(struct semaphore * sem) */ extern __inline__ void up(struct semaphore * sem) { - unsigned long flags; - + int flags; spin_lock_irqsave(&sem->sentry, flags); if (sem->count < 0) { __up(sem); diff --git a/trunk/include/asm-powerpc/asm-compat.h b/trunk/include/asm-powerpc/asm-compat.h index c89bd58ee283..8e64be0cc47d 100644 --- a/trunk/include/asm-powerpc/asm-compat.h +++ b/trunk/include/asm-powerpc/asm-compat.h @@ -14,58 +14,6 @@ # define ASM_CONST(x) __ASM_CONST(x) #endif - -/* - * Feature section common macros - * - * Note that the entries now contain offsets between the table entry - * and the code rather than absolute code pointers in order to be - * useable with the vdso shared library. There is also an assumption - * that values will be negative, that is, the fixup table has to be - * located after the code it fixes up. - */ -#ifdef CONFIG_PPC64 -#ifdef __powerpc64__ -/* 64 bits kernel, 64 bits code */ -#define MAKE_FTR_SECTION_ENTRY(msk, val, label, sect) \ -99: \ - .section sect,"a"; \ - .align 3; \ -98: \ - .llong msk; \ - .llong val; \ - .llong label##b-98b; \ - .llong 99b-98b; \ - .previous -#else /* __powerpc64__ */ -/* 64 bits kernel, 32 bits code (ie. vdso32) */ -#define MAKE_FTR_SECTION_ENTRY(msk, val, label, sect) \ -99: \ - .section sect,"a"; \ - .align 3; \ -98: \ - .llong msk; \ - .llong val; \ - .long 0xffffffff; \ - .long label##b-98b; \ - .long 0xffffffff; \ - .long 99b-98b; \ - .previous -#endif /* !__powerpc64__ */ -#else /* CONFIG_PPC64 */ -/* 32 bits kernel, 32 bits code */ -#define MAKE_FTR_SECTION_ENTRY(msk, val, label, sect) \ -99: \ - .section sect,"a"; \ - .align 2; \ -98: \ - .long msk; \ - .long val; \ - .long label##b-98b; \ - .long 99b-98b; \ - .previous -#endif /* !CONFIG_PPC64 */ - #ifdef __powerpc64__ /* operations for longs and pointers */ diff --git a/trunk/include/asm-powerpc/cputable.h b/trunk/include/asm-powerpc/cputable.h index a9a40149a7c0..12707ab9dc98 100644 --- a/trunk/include/asm-powerpc/cputable.h +++ b/trunk/include/asm-powerpc/cputable.h @@ -89,11 +89,8 @@ struct cpu_spec { extern struct cpu_spec *cur_cpu_spec; -extern unsigned int __start___ftr_fixup, __stop___ftr_fixup; - -extern struct cpu_spec *identify_cpu(unsigned long offset); -extern void do_feature_fixups(unsigned long value, void *fixup_start, - void *fixup_end); +extern void identify_cpu(unsigned long offset, unsigned long cpu); +extern void do_cpu_ftr_fixups(unsigned long offset); #endif /* __ASSEMBLY__ */ @@ -147,7 +144,6 @@ extern void do_feature_fixups(unsigned long value, void *fixup_start, #define CPU_FTR_CI_LARGE_PAGE LONG_ASM_CONST(0x0000100000000000) #define CPU_FTR_PAUSE_ZERO LONG_ASM_CONST(0x0000200000000000) #define CPU_FTR_PURR LONG_ASM_CONST(0x0000400000000000) -#define CPU_FTR_CELL_TB_BUG LONG_ASM_CONST(0x0000800000000000) #ifndef __ASSEMBLY__ @@ -336,7 +332,7 @@ extern void do_feature_fixups(unsigned long value, void *fixup_start, #define CPU_FTRS_CELL (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \ CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \ - CPU_FTR_PAUSE_ZERO | CPU_FTR_CI_LARGE_PAGE | CPU_FTR_CELL_TB_BUG) + CPU_FTR_PAUSE_ZERO | CPU_FTR_CI_LARGE_PAGE) #define CPU_FTRS_PA6T (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \ CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | \ CPU_FTR_ALTIVEC_COMP | CPU_FTR_CI_LARGE_PAGE | \ @@ -435,12 +431,29 @@ static inline int cpu_has_feature(unsigned long feature) #ifdef __ASSEMBLY__ -#define BEGIN_FTR_SECTION_NESTED(label) label: -#define BEGIN_FTR_SECTION BEGIN_FTR_SECTION_NESTED(97) -#define END_FTR_SECTION_NESTED(msk, val, label) \ - MAKE_FTR_SECTION_ENTRY(msk, val, label, __ftr_fixup) +#define BEGIN_FTR_SECTION 98: + +#ifndef __powerpc64__ #define END_FTR_SECTION(msk, val) \ - END_FTR_SECTION_NESTED(msk, val, 97) +99: \ + .section __ftr_fixup,"a"; \ + .align 2; \ + .long msk; \ + .long val; \ + .long 98b; \ + .long 99b; \ + .previous +#else /* __powerpc64__ */ +#define END_FTR_SECTION(msk, val) \ +99: \ + .section __ftr_fixup,"a"; \ + .align 3; \ + .llong msk; \ + .llong val; \ + .llong 98b; \ + .llong 99b; \ + .previous +#endif /* __powerpc64__ */ #define END_FTR_SECTION_IFSET(msk) END_FTR_SECTION((msk), (msk)) #define END_FTR_SECTION_IFCLR(msk) END_FTR_SECTION((msk), 0) diff --git a/trunk/include/asm-powerpc/current.h b/trunk/include/asm-powerpc/current.h index b8708aedf925..1938d6abd255 100644 --- a/trunk/include/asm-powerpc/current.h +++ b/trunk/include/asm-powerpc/current.h @@ -14,17 +14,7 @@ struct task_struct; #ifdef __powerpc64__ #include -static inline struct task_struct *get_current(void) -{ - struct task_struct *task; - - __asm__ __volatile__("ld %0,%1(13)" - : "=r" (task) - : "i" (offsetof(struct paca_struct, __current))); - - return task; -} -#define current get_current() +#define current (get_paca()->__current) #else diff --git a/trunk/include/asm-powerpc/device.h b/trunk/include/asm-powerpc/device.h deleted file mode 100644 index d8f9872b0e2d..000000000000 --- a/trunk/include/asm-powerpc/device.h +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Arch specific extensions to struct device - * - * This file is released under the GPLv2 - */ -#include - diff --git a/trunk/include/asm-powerpc/firmware.h b/trunk/include/asm-powerpc/firmware.h index fdf9aff71150..1022737f4f34 100644 --- a/trunk/include/asm-powerpc/firmware.h +++ b/trunk/include/asm-powerpc/firmware.h @@ -96,16 +96,19 @@ extern void machine_check_fwnmi(void); /* This is true if we are using the firmware NMI handler (typically LPAR) */ extern int fwnmi_active; -extern unsigned int __start___fw_ftr_fixup, __stop___fw_ftr_fixup; - #else /* __ASSEMBLY__ */ -#define BEGIN_FW_FTR_SECTION_NESTED(label) label: -#define BEGIN_FW_FTR_SECTION BEGIN_FW_FTR_SECTION_NESTED(97) -#define END_FW_FTR_SECTION_NESTED(msk, val, label) \ - MAKE_FTR_SECTION_ENTRY(msk, val, label, __fw_ftr_fixup) +#define BEGIN_FW_FTR_SECTION 96: + #define END_FW_FTR_SECTION(msk, val) \ - END_FW_FTR_SECTION_NESTED(msk, val, 97) +97: \ + .section __fw_ftr_fixup,"a"; \ + .align 3; \ + .llong msk; \ + .llong val; \ + .llong 96b; \ + .llong 97b; \ + .previous #define END_FW_FTR_SECTION_IFSET(msk) END_FW_FTR_SECTION((msk), (msk)) #define END_FW_FTR_SECTION_IFCLR(msk) END_FW_FTR_SECTION((msk), 0) diff --git a/trunk/include/asm-powerpc/i8259.h b/trunk/include/asm-powerpc/i8259.h index db1362f8c603..c80e113052cd 100644 --- a/trunk/include/asm-powerpc/i8259.h +++ b/trunk/include/asm-powerpc/i8259.h @@ -6,11 +6,10 @@ #ifdef CONFIG_PPC_MERGE extern void i8259_init(struct device_node *node, unsigned long intack_addr); -extern unsigned int i8259_irq(void); -extern struct irq_host *i8259_get_host(void); +extern unsigned int i8259_irq(struct pt_regs *regs); #else extern void i8259_init(unsigned long intack_addr, int offset); -extern int i8259_irq(void); +extern int i8259_irq(struct pt_regs *regs); #endif #endif /* __KERNEL__ */ diff --git a/trunk/include/asm-powerpc/ibmebus.h b/trunk/include/asm-powerpc/ibmebus.h index 3493429b70f5..7ab195a27888 100644 --- a/trunk/include/asm-powerpc/ibmebus.h +++ b/trunk/include/asm-powerpc/ibmebus.h @@ -65,7 +65,7 @@ void ibmebus_unregister_driver(struct ibmebus_driver *drv); int ibmebus_request_irq(struct ibmebus_dev *dev, u32 ist, - irq_handler_t handler, + irqreturn_t (*handler)(int, void*, struct pt_regs *), unsigned long irq_flags, const char * devname, void *dev_id); void ibmebus_free_irq(struct ibmebus_dev *dev, u32 ist, void *dev_id); diff --git a/trunk/include/asm-powerpc/io.h b/trunk/include/asm-powerpc/io.h index c2c5f14b5f5f..cbbd8c648df1 100644 --- a/trunk/include/asm-powerpc/io.h +++ b/trunk/include/asm-powerpc/io.h @@ -163,11 +163,8 @@ extern void _outsl_ns(volatile u32 __iomem *port, const void *buf, long count); static inline void mmiowb(void) { - unsigned long tmp; - - __asm__ __volatile__("sync; li %0,0; stb %0,%1(13)" - : "=&r" (tmp) : "i" (offsetof(struct paca_struct, io_sync)) - : "memory"); + __asm__ __volatile__ ("sync" : : : "memory"); + get_paca()->io_sync = 0; } /* @@ -407,6 +404,32 @@ static inline void __out_be64(volatile unsigned long __iomem *addr, unsigned lon #include +/** + * check_signature - find BIOS signatures + * @io_addr: mmio address to check + * @signature: signature block + * @length: length of signature + * + * Perform a signature comparison with the mmio address io_addr. This + * address should have been obtained by ioremap. + * Returns 1 on a match. + */ +static inline int check_signature(const volatile void __iomem * io_addr, + const unsigned char *signature, int length) +{ + int retval = 0; + do { + if (readb(io_addr) != *signature) + goto out; + io_addr++; + signature++; + length--; + } while (length); + retval = 1; +out: + return retval; +} + /* Nothing to do */ #define dma_cache_inv(_start,_size) do { } while (0) diff --git a/trunk/include/asm-powerpc/iommu.h b/trunk/include/asm-powerpc/iommu.h index 39fad685ffab..a5e98641a2ae 100644 --- a/trunk/include/asm-powerpc/iommu.h +++ b/trunk/include/asm-powerpc/iommu.h @@ -22,35 +22,17 @@ #define _ASM_IOMMU_H #ifdef __KERNEL__ -#include +#include #include #include #include -#include -#include - -#define IOMMU_PAGE_SHIFT 12 -#define IOMMU_PAGE_SIZE (ASM_CONST(1) << IOMMU_PAGE_SHIFT) -#define IOMMU_PAGE_MASK (~((1 << IOMMU_PAGE_SHIFT) - 1)) -#define IOMMU_PAGE_ALIGN(addr) _ALIGN_UP(addr, IOMMU_PAGE_SIZE) - -#ifndef __ASSEMBLY__ - -/* Pure 2^n version of get_order */ -static __inline__ __attribute_const__ int get_iommu_order(unsigned long size) -{ - return __ilog2((size - 1) >> IOMMU_PAGE_SHIFT) + 1; -} - -#endif /* __ASSEMBLY__ */ - /* * IOMAP_MAX_ORDER defines the largest contiguous block * of dma space we can get. IOMAP_MAX_ORDER = 13 * allows up to 2**12 pages (4096 * 4096) = 16 MB */ -#define IOMAP_MAX_ORDER 13 +#define IOMAP_MAX_ORDER 13 struct iommu_table { unsigned long it_busno; /* Bus number this table belongs to */ diff --git a/trunk/include/asm-powerpc/ipic.h b/trunk/include/asm-powerpc/ipic.h index 9fbb03415860..1ce09a35906e 100644 --- a/trunk/include/asm-powerpc/ipic.h +++ b/trunk/include/asm-powerpc/ipic.h @@ -79,12 +79,12 @@ extern void ipic_clear_mcp_status(u32 mask); #ifdef CONFIG_PPC_MERGE extern void ipic_init(struct device_node *node, unsigned int flags); -extern unsigned int ipic_get_irq(void); +extern unsigned int ipic_get_irq(struct pt_regs *regs); #else extern void ipic_init(phys_addr_t phys_addr, unsigned int flags, unsigned int irq_offset, unsigned char *senses, unsigned int senses_count); -extern int ipic_get_irq(void); +extern int ipic_get_irq(struct pt_regs *regs); #endif #endif /* __ASM_IPIC_H__ */ diff --git a/trunk/include/asm-powerpc/irq.h b/trunk/include/asm-powerpc/irq.h index f960f5346f40..89ed545b446b 100644 --- a/trunk/include/asm-powerpc/irq.h +++ b/trunk/include/asm-powerpc/irq.h @@ -825,7 +825,7 @@ extern struct thread_info *softirq_ctx[NR_CPUS]; extern void irq_ctx_init(void); extern void call_do_softirq(struct thread_info *tp); -extern int call_handle_irq(int irq, void *p1, +extern int call_handle_irq(int irq, void *p1, void *p2, struct thread_info *tp, void *func); #else #define irq_ctx_init() diff --git a/trunk/include/asm-powerpc/irq_regs.h b/trunk/include/asm-powerpc/irq_regs.h deleted file mode 100644 index ba94b51a0a70..000000000000 --- a/trunk/include/asm-powerpc/irq_regs.h +++ /dev/null @@ -1,2 +0,0 @@ -#include - diff --git a/trunk/include/asm-powerpc/iseries/hv_lp_event.h b/trunk/include/asm-powerpc/iseries/hv_lp_event.h index 6ce2ce1e2690..4065a4de4935 100644 --- a/trunk/include/asm-powerpc/iseries/hv_lp_event.h +++ b/trunk/include/asm-powerpc/iseries/hv_lp_event.h @@ -50,7 +50,7 @@ struct HvLpEvent { u64 xCorrelationToken; /* Unique value for source/type x10-x17 */ }; -typedef void (*LpEventHandler)(struct HvLpEvent *); +typedef void (*LpEventHandler)(struct HvLpEvent *, struct pt_regs *); /* Register a handler for an event type - returns 0 on success */ extern int HvLpEvent_registerHandler(HvLpEvent_Type eventType, diff --git a/trunk/include/asm-powerpc/iseries/it_lp_queue.h b/trunk/include/asm-powerpc/iseries/it_lp_queue.h index 428278838821..3f6814769295 100644 --- a/trunk/include/asm-powerpc/iseries/it_lp_queue.h +++ b/trunk/include/asm-powerpc/iseries/it_lp_queue.h @@ -72,7 +72,7 @@ struct hvlpevent_queue { extern struct hvlpevent_queue hvlpevent_queue; extern int hvlpevent_is_pending(void); -extern void process_hvlpevents(void); +extern void process_hvlpevents(struct pt_regs *); extern void setup_hvlpevent_queue(void); #endif /* _ASM_POWERPC_ISERIES_IT_LP_QUEUE_H */ diff --git a/trunk/include/asm-powerpc/machdep.h b/trunk/include/asm-powerpc/machdep.h index dac90dc341cb..c17c13742401 100644 --- a/trunk/include/asm-powerpc/machdep.h +++ b/trunk/include/asm-powerpc/machdep.h @@ -97,7 +97,7 @@ struct machdep_calls { void (*show_percpuinfo)(struct seq_file *m, int i); void (*init_IRQ)(void); - unsigned int (*get_irq)(void); + unsigned int (*get_irq)(struct pt_regs *); #ifdef CONFIG_KEXEC void (*kexec_cpu_down)(int crash_shutdown, int secondary); #endif diff --git a/trunk/include/asm-powerpc/mpic.h b/trunk/include/asm-powerpc/mpic.h index ef0a5458d2b2..a9f9604b9eff 100644 --- a/trunk/include/asm-powerpc/mpic.h +++ b/trunk/include/asm-powerpc/mpic.h @@ -409,9 +409,9 @@ extern void mpic_send_ipi(unsigned int ipi_no, unsigned int cpu_mask); void smp_mpic_message_pass(int target, int msg); /* Fetch interrupt from a given mpic */ -extern unsigned int mpic_get_one_irq(struct mpic *mpic); +extern unsigned int mpic_get_one_irq(struct mpic *mpic, struct pt_regs *regs); /* This one gets to the primary mpic */ -extern unsigned int mpic_get_irq(void); +extern unsigned int mpic_get_irq(struct pt_regs *regs); /* Set the EPIC clock ratio */ void mpic_set_clk_ratio(struct mpic *mpic, u32 clock_ratio); diff --git a/trunk/include/asm-powerpc/oprofile_impl.h b/trunk/include/asm-powerpc/oprofile_impl.h index 07a10e590c1d..5b33994cd488 100644 --- a/trunk/include/asm-powerpc/oprofile_impl.h +++ b/trunk/include/asm-powerpc/oprofile_impl.h @@ -42,7 +42,7 @@ struct op_powerpc_model { void (*reg_setup) (struct op_counter_config *, struct op_system_config *, int num_counters); - void (*cpu_setup) (struct op_counter_config *); + void (*cpu_setup) (void *); void (*start) (struct op_counter_config *); void (*stop) (void); void (*handle_interrupt) (struct pt_regs *, @@ -121,90 +121,7 @@ static inline void ctr_write(unsigned int i, unsigned int val) break; } } -#else /* CONFIG_FSL_BOOKE */ -static inline u32 get_pmlca(int ctr) -{ - u32 pmlca; - - switch (ctr) { - case 0: - pmlca = mfpmr(PMRN_PMLCA0); - break; - case 1: - pmlca = mfpmr(PMRN_PMLCA1); - break; - case 2: - pmlca = mfpmr(PMRN_PMLCA2); - break; - case 3: - pmlca = mfpmr(PMRN_PMLCA3); - break; - default: - panic("Bad ctr number\n"); - } - - return pmlca; -} - -static inline void set_pmlca(int ctr, u32 pmlca) -{ - switch (ctr) { - case 0: - mtpmr(PMRN_PMLCA0, pmlca); - break; - case 1: - mtpmr(PMRN_PMLCA1, pmlca); - break; - case 2: - mtpmr(PMRN_PMLCA2, pmlca); - break; - case 3: - mtpmr(PMRN_PMLCA3, pmlca); - break; - default: - panic("Bad ctr number\n"); - } -} - -static inline unsigned int ctr_read(unsigned int i) -{ - switch(i) { - case 0: - return mfpmr(PMRN_PMC0); - case 1: - return mfpmr(PMRN_PMC1); - case 2: - return mfpmr(PMRN_PMC2); - case 3: - return mfpmr(PMRN_PMC3); - default: - return 0; - } -} - -static inline void ctr_write(unsigned int i, unsigned int val) -{ - switch(i) { - case 0: - mtpmr(PMRN_PMC0, val); - break; - case 1: - mtpmr(PMRN_PMC1, val); - break; - case 2: - mtpmr(PMRN_PMC2, val); - break; - case 3: - mtpmr(PMRN_PMC3, val); - break; - default: - break; - } -} - - -#endif /* CONFIG_FSL_BOOKE */ - +#endif /* !CONFIG_FSL_BOOKE */ extern void op_powerpc_backtrace(struct pt_regs * const regs, unsigned int depth); diff --git a/trunk/include/asm-powerpc/pci.h b/trunk/include/asm-powerpc/pci.h index 721c97f09b20..46afd29b904e 100644 --- a/trunk/include/asm-powerpc/pci.h +++ b/trunk/include/asm-powerpc/pci.h @@ -62,13 +62,19 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) } #ifdef CONFIG_PPC64 - -/* - * We want to avoid touching the cacheline size or MWI bit. - * pSeries firmware sets the cacheline size (which is not the cpu cacheline - * size in all cases) and hardware treats MWI the same as memory write. - */ -#define PCI_DISABLE_MWI +#define HAVE_ARCH_PCI_MWI 1 +static inline int pcibios_prep_mwi(struct pci_dev *dev) +{ + /* + * We would like to avoid touching the cacheline size or MWI bit + * but we cant do that with the current pcibios_prep_mwi + * interface. pSeries firmware sets the cacheline size (which is not + * the cpu cacheline size in all cases) and hardware treats MWI + * the same as memory write. So we dont touch the cacheline size + * here and allow the generic code to set the MWI bit. + */ + return 0; +} extern struct dma_mapping_ops pci_dma_ops; diff --git a/trunk/include/asm-powerpc/pmc.h b/trunk/include/asm-powerpc/pmc.h index 8588be68e0ad..07d6a4279319 100644 --- a/trunk/include/asm-powerpc/pmc.h +++ b/trunk/include/asm-powerpc/pmc.h @@ -32,5 +32,18 @@ void release_pmc_hardware(void); void power4_enable_pmcs(void); #endif +#ifdef CONFIG_FSL_BOOKE +void init_pmc_stop(int ctr); +void set_pmc_event(int ctr, int event); +void set_pmc_user_kernel(int ctr, int user, int kernel); +void set_pmc_marked(int ctr, int mark0, int mark1); +void pmc_start_ctr(int ctr, int enable); +void pmc_start_ctrs(int enable); +void pmc_stop_ctrs(void); +void dump_pmcs(void); + +extern struct op_powerpc_model op_model_fsl_booke; +#endif + #endif /* __KERNEL__ */ #endif /* _POWERPC_PMC_H */ diff --git a/trunk/include/asm-powerpc/ppc_asm.h b/trunk/include/asm-powerpc/ppc_asm.h index fa083d8e4663..a940cfe040da 100644 --- a/trunk/include/asm-powerpc/ppc_asm.h +++ b/trunk/include/asm-powerpc/ppc_asm.h @@ -30,9 +30,9 @@ BEGIN_FTR_SECTION; \ mfspr ra,SPRN_PURR; /* get processor util. reg */ \ END_FTR_SECTION_IFSET(CPU_FTR_PURR); \ BEGIN_FTR_SECTION; \ - MFTB(ra); /* or get TB if no PURR */ \ + mftb ra; /* or get TB if no PURR */ \ END_FTR_SECTION_IFCLR(CPU_FTR_PURR); \ - ld rb,PACA_STARTPURR(r13); \ + ld rb,PACA_STARTPURR(r13); \ std ra,PACA_STARTPURR(r13); \ subf rb,rb,ra; /* subtract start value */ \ ld ra,PACA_USER_TIME(r13); \ @@ -45,9 +45,9 @@ BEGIN_FTR_SECTION; \ mfspr ra,SPRN_PURR; /* get processor util. reg */ \ END_FTR_SECTION_IFSET(CPU_FTR_PURR); \ BEGIN_FTR_SECTION; \ - MFTB(ra); /* or get TB if no PURR */ \ + mftb ra; /* or get TB if no PURR */ \ END_FTR_SECTION_IFCLR(CPU_FTR_PURR); \ - ld rb,PACA_STARTPURR(r13); \ + ld rb,PACA_STARTPURR(r13); \ std ra,PACA_STARTPURR(r13); \ subf rb,rb,ra; /* subtract start value */ \ ld ra,PACA_SYSTEM_TIME(r13); \ @@ -274,16 +274,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_601) #define ISYNC_601 #endif -#ifdef CONFIG_PPC_CELL -#define MFTB(dest) \ -90: mftb dest; \ -BEGIN_FTR_SECTION_NESTED(96); \ - cmpwi dest,0; \ - beq- 90b; \ -END_FTR_SECTION_NESTED(CPU_FTR_CELL_TB_BUG, CPU_FTR_CELL_TB_BUG, 96) -#else -#define MFTB(dest) mftb dest -#endif #ifndef CONFIG_SMP #define TLBSYNC diff --git a/trunk/include/asm-powerpc/prom.h b/trunk/include/asm-powerpc/prom.h index ec11d44eaeb5..524629769336 100644 --- a/trunk/include/asm-powerpc/prom.h +++ b/trunk/include/asm-powerpc/prom.h @@ -134,7 +134,7 @@ extern struct device_node *of_find_all_nodes(struct device_node *prev); extern struct device_node *of_get_parent(const struct device_node *node); extern struct device_node *of_get_next_child(const struct device_node *node, struct device_node *prev); -extern struct property *of_find_property(const struct device_node *np, +extern struct property *of_find_property(struct device_node *np, const char *name, int *lenp); extern struct device_node *of_node_get(struct device_node *node); @@ -158,12 +158,10 @@ extern void of_detach_node(const struct device_node *); extern void finish_device_tree(void); extern void unflatten_device_tree(void); extern void early_init_devtree(void *); -extern int device_is_compatible(const struct device_node *device, - const char *); +extern int device_is_compatible(struct device_node *device, const char *); extern int machine_is_compatible(const char *compat); -extern const void *get_property(const struct device_node *node, - const char *name, - int *lenp); +extern const void *get_property(struct device_node *node, const char *name, + int *lenp); extern void print_properties(struct device_node *node); extern int prom_n_addr_cells(struct device_node* np); extern int prom_n_size_cells(struct device_node* np); diff --git a/trunk/include/asm-powerpc/reg.h b/trunk/include/asm-powerpc/reg.h index 6faae7b14d55..3a9fcc15811b 100644 --- a/trunk/include/asm-powerpc/reg.h +++ b/trunk/include/asm-powerpc/reg.h @@ -503,7 +503,7 @@ /* * An mtfsf instruction with the L bit set. On CPUs that support this a - * full 64bits of FPSCR is restored and on other CPUs the L bit is ignored. + * full 64bits of FPSCR is restored and on other CPUs it is ignored. * * Until binutils gets the new form of mtfsf, hardwire the instruction. */ @@ -591,7 +591,6 @@ #define PV_630 0x0040 #define PV_630p 0x0041 #define PV_970MP 0x0044 -#define PV_970GX 0x0045 #define PV_BE 0x0070 #define PV_PA6T 0x0090 @@ -619,35 +618,10 @@ : "=r" (rval)); rval;}) #define mtspr(rn, v) asm volatile("mtspr " __stringify(rn) ",%0" : : "r" (v)) -#ifdef __powerpc64__ -#ifdef CONFIG_PPC_CELL -#define mftb() ({unsigned long rval; \ - asm volatile( \ - "90: mftb %0;\n" \ - "97: cmpwi %0,0;\n" \ - " beq- 90b;\n" \ - "99:\n" \ - ".section __ftr_fixup,\"a\"\n" \ - ".align 3\n" \ - "98:\n" \ - " .llong %1\n" \ - " .llong %1\n" \ - " .llong 97b-98b\n" \ - " .llong 99b-98b\n" \ - ".previous" \ - : "=r" (rval) : "i" (CPU_FTR_CELL_TB_BUG)); rval;}) -#else #define mftb() ({unsigned long rval; \ asm volatile("mftb %0" : "=r" (rval)); rval;}) -#endif /* !CONFIG_PPC_CELL */ - -#else /* __powerpc64__ */ - #define mftbl() ({unsigned long rval; \ asm volatile("mftbl %0" : "=r" (rval)); rval;}) -#define mftbu() ({unsigned long rval; \ - asm volatile("mftbu %0" : "=r" (rval)); rval;}) -#endif /* !__powerpc64__ */ #define mttbl(v) asm volatile("mttbl %0":: "r"(v)) #define mttbu(v) asm volatile("mttbu %0":: "r"(v)) diff --git a/trunk/include/asm-powerpc/smp.h b/trunk/include/asm-powerpc/smp.h index 20ea7c70bc38..068f119aa298 100644 --- a/trunk/include/asm-powerpc/smp.h +++ b/trunk/include/asm-powerpc/smp.h @@ -34,7 +34,8 @@ extern void cpu_die(void); #ifdef CONFIG_SMP extern void smp_send_debugger_break(int cpu); -extern void smp_message_recv(int); +struct pt_regs; +extern void smp_message_recv(int, struct pt_regs *); #ifdef CONFIG_HOTPLUG_CPU extern void fixup_irqs(cpumask_t map); diff --git a/trunk/include/asm-powerpc/spu.h b/trunk/include/asm-powerpc/spu.h index e73ea00efd8b..b42b53c40f5d 100644 --- a/trunk/include/asm-powerpc/spu.h +++ b/trunk/include/asm-powerpc/spu.h @@ -138,7 +138,6 @@ struct spu { void (* ibox_callback)(struct spu *spu); void (* stop_callback)(struct spu *spu); void (* mfc_callback)(struct spu *spu); - void (* dma_callback)(struct spu *spu, int type); char irq_c0[8]; char irq_c1[8]; @@ -148,7 +147,6 @@ struct spu { }; struct spu *spu_alloc(void); -struct spu *spu_alloc_node(int node); void spu_free(struct spu *spu); int spu_irq_class_0_bottom(struct spu *spu); int spu_irq_class_1_bottom(struct spu *spu); @@ -170,22 +168,6 @@ extern struct spufs_calls { struct module *owner; } spufs_calls; -/* return status from spu_run, same as in libspe */ -#define SPE_EVENT_DMA_ALIGNMENT 0x0008 /*A DMA alignment error */ -#define SPE_EVENT_SPE_ERROR 0x0010 /*An illegal instruction error*/ -#define SPE_EVENT_SPE_DATA_SEGMENT 0x0020 /*A DMA segmentation error */ -#define SPE_EVENT_SPE_DATA_STORAGE 0x0040 /*A DMA storage error */ -#define SPE_EVENT_INVALID_DMA 0x0800 /* Invalid MFC DMA */ - -/* - * Flags for sys_spu_create. - */ -#define SPU_CREATE_EVENTS_ENABLED 0x0001 -#define SPU_CREATE_GANG 0x0002 - -#define SPU_CREATE_FLAG_ALL 0x0003 /* mask of all valid flags */ - - #ifdef CONFIG_SPU_FS_MODULE int register_spu_syscalls(struct spufs_calls *calls); void unregister_spu_syscalls(struct spufs_calls *calls); @@ -200,24 +182,6 @@ static inline void unregister_spu_syscalls(struct spufs_calls *calls) #endif /* MODULE */ -/* - * Notifier blocks: - * - * oprofile can get notified when a context switch is performed - * on an spe. The notifer function that gets called is passed - * a pointer to the SPU structure as well as the object-id that - * identifies the binary running on that SPU now. - * - * For a context save, the object-id that is passed is zero, - * identifying that the kernel will run from that moment on. - * - * For a context restore, the object-id is the value written - * to object-id spufs file from user space and the notifer - * function can assume that spu->ctx is valid. - */ -int spu_switch_event_register(struct notifier_block * n); -int spu_switch_event_unregister(struct notifier_block * n); - /* * This defines the Local Store, Problem Area and Privlege Area of an SPU. */ diff --git a/trunk/include/asm-powerpc/systbl.h b/trunk/include/asm-powerpc/systbl.h index 97b435484177..eac85ce101b6 100644 --- a/trunk/include/asm-powerpc/systbl.h +++ b/trunk/include/asm-powerpc/systbl.h @@ -261,7 +261,7 @@ SYSX(sys_ni_syscall, ppc_fadvise64_64, ppc_fadvise64_64) PPC_SYS_SPU(rtas) OLDSYS(debug_setcontext) SYSCALL(ni_syscall) -COMPAT_SYS(migrate_pages) +SYSCALL(ni_syscall) COMPAT_SYS(mbind) COMPAT_SYS(get_mempolicy) COMPAT_SYS(set_mempolicy) @@ -304,4 +304,3 @@ SYSCALL_SPU(fchmodat) SYSCALL_SPU(faccessat) COMPAT_SYS_SPU(get_robust_list) COMPAT_SYS_SPU(set_robust_list) -COMPAT_SYS(move_pages) diff --git a/trunk/include/asm-powerpc/system.h b/trunk/include/asm-powerpc/system.h index f7b1227d6454..43627596003b 100644 --- a/trunk/include/asm-powerpc/system.h +++ b/trunk/include/asm-powerpc/system.h @@ -25,8 +25,8 @@ * * We have to use the sync instructions for mb(), since lwsync doesn't * order loads with respect to previous stores. Lwsync is fine for - * rmb(), though. Note that rmb() actually uses a sync on 32-bit - * architectures. + * rmb(), though. Note that lwsync is interpreted as sync by + * 32-bit and older 64-bit CPUs. * * For wmb(), we use sync since wmb is used in drivers to order * stores to system memory with respect to writes to the device. @@ -34,7 +34,7 @@ * SMP since it is only used to order updates to system memory. */ #define mb() __asm__ __volatile__ ("sync" : : : "memory") -#define rmb() __asm__ __volatile__ (__stringify(LWSYNC) : : : "memory") +#define rmb() __asm__ __volatile__ ("lwsync" : : : "memory") #define wmb() __asm__ __volatile__ ("sync" : : : "memory") #define read_barrier_depends() do { } while(0) diff --git a/trunk/include/asm-powerpc/tce.h b/trunk/include/asm-powerpc/tce.h index f663634cccc9..c9483adbf599 100644 --- a/trunk/include/asm-powerpc/tce.h +++ b/trunk/include/asm-powerpc/tce.h @@ -22,8 +22,6 @@ #define _ASM_POWERPC_TCE_H #ifdef __KERNEL__ -#include - /* * Tces come in two formats, one for the virtual bus and a different * format for PCI @@ -35,6 +33,7 @@ #define TCE_SHIFT 12 #define TCE_PAGE_SIZE (1 << TCE_SHIFT) +#define TCE_PAGE_FACTOR (PAGE_SHIFT - TCE_SHIFT) #define TCE_ENTRY_SIZE 8 /* each TCE is 64 bits */ diff --git a/trunk/include/asm-powerpc/time.h b/trunk/include/asm-powerpc/time.h index 4cff977ad526..b051d4c88c3b 100644 --- a/trunk/include/asm-powerpc/time.h +++ b/trunk/include/asm-powerpc/time.h @@ -39,6 +39,10 @@ extern void generic_calibrate_decr(void); extern void wakeup_decrementer(void); extern void snapshot_timebase(void); +#ifdef CONFIG_RTC_CLASS +extern int __init rtc_class_hookup(void); +#endif + /* Some sane defaults: 125 MHz timebase, 1GHz processor */ extern unsigned long ppc_proc_freq; #define DEFAULT_PROC_FREQ (DEFAULT_TB_FREQ * 8) @@ -78,35 +82,30 @@ struct div_result { #define __USE_RTC() 0 #endif -#ifdef CONFIG_PPC64 - -/* For compatibility, get_tbl() is defined as get_tb() on ppc64 */ -#define get_tbl get_tb - -#else - +/* On ppc64 this gets us the whole timebase; on ppc32 just the lower half */ static inline unsigned long get_tbl(void) { -#if defined(CONFIG_403GCX) unsigned long tbl; + +#if defined(CONFIG_403GCX) asm volatile("mfspr %0, 0x3dd" : "=r" (tbl)); - return tbl; #else - return mftbl(); + asm volatile("mftb %0" : "=r" (tbl)); #endif + return tbl; } static inline unsigned int get_tbu(void) { -#ifdef CONFIG_403GCX unsigned int tbu; + +#if defined(CONFIG_403GCX) asm volatile("mfspr %0, 0x3dc" : "=r" (tbu)); - return tbu; #else - return mftbu(); + asm volatile("mftbu %0" : "=r" (tbu)); #endif + return tbu; } -#endif /* !CONFIG_PPC64 */ static inline unsigned int get_rtcl(void) { @@ -132,7 +131,7 @@ static inline u64 get_tb(void) { return mftb(); } -#else /* CONFIG_PPC64 */ +#else static inline u64 get_tb(void) { unsigned int tbhi, tblo, tbhi2; @@ -145,7 +144,7 @@ static inline u64 get_tb(void) return ((u64)tbhi << 32) | tblo; } -#endif /* !CONFIG_PPC64 */ +#endif static inline void set_tb(unsigned int upper, unsigned int lower) { diff --git a/trunk/include/asm-powerpc/timex.h b/trunk/include/asm-powerpc/timex.h index 92dedde761d1..3b9a8e786806 100644 --- a/trunk/include/asm-powerpc/timex.h +++ b/trunk/include/asm-powerpc/timex.h @@ -8,7 +8,6 @@ */ #include -#include #define CLOCK_TICK_RATE 1024000 /* Underlying HZ */ @@ -16,11 +15,13 @@ typedef unsigned long cycles_t; static inline cycles_t get_cycles(void) { -#ifdef __powerpc64__ - return mftb(); -#else cycles_t ret; +#ifdef __powerpc64__ + + __asm__ __volatile__("mftb %0" : "=r" (ret) : ); + +#else /* * For the "cycle" counter we use the timebase lower half. * Currently only used on SMP. @@ -29,19 +30,18 @@ static inline cycles_t get_cycles(void) ret = 0; __asm__ __volatile__( - "97: mftb %0\n" + "98: mftb %0\n" "99:\n" ".section __ftr_fixup,\"a\"\n" - ".align 2\n" - "98:\n" " .long %1\n" " .long 0\n" - " .long 97b-98b\n" - " .long 99b-98b\n" + " .long 98b\n" + " .long 99b\n" ".previous" : "=r" (ret) : "i" (CPU_FTR_601)); - return ret; #endif + + return ret; } #endif /* __KERNEL__ */ diff --git a/trunk/include/asm-powerpc/topology.h b/trunk/include/asm-powerpc/topology.h index 9fe7894ee035..8f7ee16781a4 100644 --- a/trunk/include/asm-powerpc/topology.h +++ b/trunk/include/asm-powerpc/topology.h @@ -96,13 +96,7 @@ static inline void sysfs_remove_device_from_node(struct sys_device *dev, #ifdef CONFIG_SMP #include -#define smt_capable() (cpu_has_feature(CPU_FTR_SMT)) - -#ifdef CONFIG_PPC64 -#include - -#define topology_thread_siblings(cpu) (cpu_sibling_map[cpu]) -#endif +#define smt_capable() (cpu_has_feature(CPU_FTR_SMT)) #endif #endif /* __KERNEL__ */ diff --git a/trunk/include/asm-powerpc/unistd.h b/trunk/include/asm-powerpc/unistd.h index 0e4ea37f6466..464a48cce7f5 100644 --- a/trunk/include/asm-powerpc/unistd.h +++ b/trunk/include/asm-powerpc/unistd.h @@ -276,7 +276,7 @@ #define __NR_rtas 255 #define __NR_sys_debug_setcontext 256 /* Number 257 is reserved for vserver */ -#define __NR_migrate_pages 258 +/* 258 currently unused */ #define __NR_mbind 259 #define __NR_get_mempolicy 260 #define __NR_set_mempolicy 261 @@ -323,11 +323,10 @@ #define __NR_faccessat 298 #define __NR_get_robust_list 299 #define __NR_set_robust_list 300 -#define __NR_move_pages 301 #ifdef __KERNEL__ -#define __NR_syscalls 302 +#define __NR_syscalls 301 #define __NR__exit __NR_exit #define NR_syscalls __NR_syscalls diff --git a/trunk/include/asm-ppc/commproc.h b/trunk/include/asm-ppc/commproc.h index 7b06b4e6bf30..3247bea5fc2b 100644 --- a/trunk/include/asm-ppc/commproc.h +++ b/trunk/include/asm-ppc/commproc.h @@ -690,7 +690,8 @@ typedef struct risc_timer_pram { #define CICR_IEN ((uint)0x00000080) /* Int. enable */ #define CICR_SPS ((uint)0x00000001) /* SCC Spread */ -extern void cpm_install_handler(int vec, void (*handler)(void *), void *dev_id); +extern void cpm_install_handler(int vec, + void (*handler)(void *, struct pt_regs *regs), void *dev_id); extern void cpm_free_handler(int vec); #endif /* __CPM_8XX__ */ diff --git a/trunk/include/asm-ppc/device.h b/trunk/include/asm-ppc/device.h deleted file mode 100644 index d8f9872b0e2d..000000000000 --- a/trunk/include/asm-ppc/device.h +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Arch specific extensions to struct device - * - * This file is released under the GPLv2 - */ -#include - diff --git a/trunk/include/asm-ppc/floppy.h b/trunk/include/asm-ppc/floppy.h index ae316e6d2ca9..d3963ca79ad8 100644 --- a/trunk/include/asm-ppc/floppy.h +++ b/trunk/include/asm-ppc/floppy.h @@ -38,14 +38,14 @@ static int virtual_dma_mode; static int doing_vdma; static struct fd_dma_ops *fd_ops; -static irqreturn_t floppy_hardint(int irq, void *dev_id) +static irqreturn_t floppy_hardint(int irq, void *dev_id, struct pt_regs * regs) { unsigned char st; int lcount; char *lptr; if (!doing_vdma) - return floppy_interrupt(irq, dev_id); + return floppy_interrupt(irq, dev_id, regs); st = 1; @@ -69,7 +69,7 @@ static irqreturn_t floppy_hardint(int irq, void *dev_id) virtual_dma_residue += virtual_dma_count; virtual_dma_count=0; doing_vdma = 0; - floppy_interrupt(irq, dev_id); + floppy_interrupt(irq, dev_id, regs); return IRQ_HANDLED; } return IRQ_HANDLED; diff --git a/trunk/include/asm-ppc/gt64260.h b/trunk/include/asm-ppc/gt64260.h index 9e63b3cfffca..cd0ef644943d 100644 --- a/trunk/include/asm-ppc/gt64260.h +++ b/trunk/include/asm-ppc/gt64260.h @@ -315,7 +315,7 @@ int gt64260_get_base(u32 *base); int gt64260_pci_exclude_device(u8 bus, u8 devfn); void gt64260_init_irq(void); -int gt64260_get_irq(void); +int gt64260_get_irq(struct pt_regs *regs); void gt64260_mpsc_progress(char *s, unsigned short hex); diff --git a/trunk/include/asm-ppc/io.h b/trunk/include/asm-ppc/io.h index a4c411b753ef..3d9a9e6f3321 100644 --- a/trunk/include/asm-ppc/io.h +++ b/trunk/include/asm-ppc/io.h @@ -439,6 +439,22 @@ extern inline void * phys_to_virt(unsigned long address) #define iobarrier_r() eieio() #define iobarrier_w() eieio() +static inline int check_signature(volatile void __iomem * io_addr, + const unsigned char *signature, int length) +{ + int retval = 0; + do { + if (readb(io_addr) != *signature) + goto out; + io_addr++; + signature++; + length--; + } while (length); + retval = 1; +out: + return retval; +} + /* * Here comes the ppc implementation of the IOMAP * interfaces. diff --git a/trunk/include/asm-ppc/machdep.h b/trunk/include/asm-ppc/machdep.h index 293a444a1d77..da7746738aee 100644 --- a/trunk/include/asm-ppc/machdep.h +++ b/trunk/include/asm-ppc/machdep.h @@ -43,7 +43,7 @@ struct machdep_calls { /* Optional, may be NULL. */ unsigned int (*irq_canonicalize)(unsigned int irq); void (*init_IRQ)(void); - int (*get_irq)(void); + int (*get_irq)(struct pt_regs *); /* A general init function, called by ppc_init in init/main.c. May be NULL. DEPRECATED ! */ diff --git a/trunk/include/asm-ppc/mpc52xx.h b/trunk/include/asm-ppc/mpc52xx.h index 64c8874618dc..7e9842805a28 100644 --- a/trunk/include/asm-ppc/mpc52xx.h +++ b/trunk/include/asm-ppc/mpc52xx.h @@ -415,7 +415,7 @@ struct mpc52xx_cdm { #ifndef __ASSEMBLY__ extern void mpc52xx_init_irq(void); -extern int mpc52xx_get_irq(void); +extern int mpc52xx_get_irq(struct pt_regs *regs); extern unsigned long mpc52xx_find_end_of_memory(void); extern void mpc52xx_set_bat(void); diff --git a/trunk/include/asm-ppc/mv64x60.h b/trunk/include/asm-ppc/mv64x60.h index db3776f18198..663edbee3e91 100644 --- a/trunk/include/asm-ppc/mv64x60.h +++ b/trunk/include/asm-ppc/mv64x60.h @@ -336,9 +336,9 @@ int mv64x60_pci_exclude_device(u8 bus, u8 devfn); void gt64260_init_irq(void); -int gt64260_get_irq(void); +int gt64260_get_irq(struct pt_regs *regs); void mv64360_init_irq(void); -int mv64360_get_irq(void); +int mv64360_get_irq(struct pt_regs *regs); u32 mv64x60_mask(u32 val, u32 num_bits); u32 mv64x60_shift_left(u32 val, u32 num_bits); diff --git a/trunk/include/asm-ppc/open_pic.h b/trunk/include/asm-ppc/open_pic.h index 778d5726212c..a4fe962d9f73 100644 --- a/trunk/include/asm-ppc/open_pic.h +++ b/trunk/include/asm-ppc/open_pic.h @@ -48,12 +48,12 @@ extern void openpic_init(int linux_irq_offset); extern void openpic_init_nmi_irq(u_int irq); extern void openpic_set_irq_priority(u_int irq, u_int pri); extern void openpic_hookup_cascade(u_int irq, char *name, - int (*cascade_fn)(void)); + int (*cascade_fn)(struct pt_regs *)); extern u_int openpic_irq(void); extern void openpic_eoi(void); extern void openpic_request_IPIs(void); extern void do_openpic_setup_cpu(void); -extern int openpic_get_irq(void); +extern int openpic_get_irq(struct pt_regs *regs); extern void openpic_reset_processor_phys(u_int cpumask); extern void openpic_setup_ISU(int isu_num, unsigned long addr); extern void openpic_cause_IPI(u_int ipi, cpumask_t cpumask); @@ -93,6 +93,6 @@ extern void openpic2_init(int linux_irq_offset); extern void openpic2_init_nmi_irq(u_int irq); extern u_int openpic2_irq(void); extern void openpic2_eoi(void); -extern int openpic2_get_irq(void); +extern int openpic2_get_irq(struct pt_regs *regs); extern void openpic2_setup_ISU(int isu_num, unsigned long addr); #endif /* _PPC_KERNEL_OPEN_PIC_H */ diff --git a/trunk/include/asm-ppc/smp.h b/trunk/include/asm-ppc/smp.h index e75791ea33a6..0b7fa89589df 100644 --- a/trunk/include/asm-ppc/smp.h +++ b/trunk/include/asm-ppc/smp.h @@ -39,7 +39,7 @@ extern struct smp_ops_t *smp_ops; extern void smp_send_tlb_invalidate(int); extern void smp_send_xmon_break(int cpu); struct pt_regs; -extern void smp_message_recv(int); +extern void smp_message_recv(int, struct pt_regs *); extern int __cpu_disable(void); extern void __cpu_die(unsigned int cpu); diff --git a/trunk/include/asm-s390/cio.h b/trunk/include/asm-s390/cio.h index 81287d86329d..da063cd5f0a0 100644 --- a/trunk/include/asm-s390/cio.h +++ b/trunk/include/asm-s390/cio.h @@ -275,12 +275,6 @@ struct ccw_dev_id { u16 devno; }; -static inline int ccw_dev_id_is_equal(struct ccw_dev_id *dev_id1, - struct ccw_dev_id *dev_id2) -{ - return !memcmp(dev_id1, dev_id2, sizeof(struct ccw_dev_id)); -} - extern int diag210(struct diag210 *addr); extern void wait_cons_dev(void); diff --git a/trunk/include/asm-s390/device.h b/trunk/include/asm-s390/device.h deleted file mode 100644 index d8f9872b0e2d..000000000000 --- a/trunk/include/asm-s390/device.h +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Arch specific extensions to struct device - * - * This file is released under the GPLv2 - */ -#include - diff --git a/trunk/include/asm-s390/hardirq.h b/trunk/include/asm-s390/hardirq.h index c2f6a8782d31..e84b7ef54aac 100644 --- a/trunk/include/asm-s390/hardirq.h +++ b/trunk/include/asm-s390/hardirq.h @@ -32,6 +32,6 @@ typedef struct { #define HARDIRQ_BITS 8 -extern void account_ticks(void); +extern void account_ticks(struct pt_regs *); #endif /* __ASM_HARDIRQ_H */ diff --git a/trunk/include/asm-s390/irq_regs.h b/trunk/include/asm-s390/irq_regs.h deleted file mode 100644 index 3dd9c0b70270..000000000000 --- a/trunk/include/asm-s390/irq_regs.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/include/asm-s390/percpu.h b/trunk/include/asm-s390/percpu.h index 9ea7f1023e57..495ad99c7635 100644 --- a/trunk/include/asm-s390/percpu.h +++ b/trunk/include/asm-s390/percpu.h @@ -16,7 +16,7 @@ #if defined(__s390x__) && defined(MODULE) #define __reloc_hide(var,offset) (*({ \ - extern int simple_identifier_##var(void); \ + extern int simple_indentifier_##var(void); \ unsigned long *__ptr; \ asm ( "larl %0,per_cpu__"#var"@GOTENT" \ : "=a" (__ptr) : "X" (per_cpu__##var) ); \ @@ -25,7 +25,7 @@ #else #define __reloc_hide(var, offset) (*({ \ - extern int simple_identifier_##var(void); \ + extern int simple_indentifier_##var(void); \ unsigned long __ptr; \ asm ( "" : "=a" (__ptr) : "0" (&per_cpu__##var) ); \ (typeof(&per_cpu__##var)) (__ptr + (offset)); })) diff --git a/trunk/include/asm-s390/pgtable.h b/trunk/include/asm-s390/pgtable.h index 36bb6dacf008..519f0a5ff181 100644 --- a/trunk/include/asm-s390/pgtable.h +++ b/trunk/include/asm-s390/pgtable.h @@ -200,45 +200,18 @@ extern char empty_zero_page[PAGE_SIZE]; */ /* Hardware bits in the page table entry */ -#define _PAGE_RO 0x200 /* HW read-only bit */ -#define _PAGE_INVALID 0x400 /* HW invalid bit */ -#define _PAGE_SWT 0x001 /* SW pte type bit t */ -#define _PAGE_SWX 0x002 /* SW pte type bit x */ +#define _PAGE_RO 0x200 /* HW read-only */ +#define _PAGE_INVALID 0x400 /* HW invalid */ -/* Six different types of pages. */ +/* Mask and six different types of pages. */ +#define _PAGE_TYPE_MASK 0x601 #define _PAGE_TYPE_EMPTY 0x400 #define _PAGE_TYPE_NONE 0x401 -#define _PAGE_TYPE_SWAP 0x403 -#define _PAGE_TYPE_FILE 0x601 /* bit 0x002 is used for offset !! */ +#define _PAGE_TYPE_SWAP 0x600 +#define _PAGE_TYPE_FILE 0x601 #define _PAGE_TYPE_RO 0x200 #define _PAGE_TYPE_RW 0x000 -/* - * PTE type bits are rather complicated. handle_pte_fault uses pte_present, - * pte_none and pte_file to find out the pte type WITHOUT holding the page - * table lock. ptep_clear_flush on the other hand uses ptep_clear_flush to - * invalidate a given pte. ipte sets the hw invalid bit and clears all tlbs - * for the page. The page table entry is set to _PAGE_TYPE_EMPTY afterwards. - * This change is done while holding the lock, but the intermediate step - * of a previously valid pte with the hw invalid bit set can be observed by - * handle_pte_fault. That makes it necessary that all valid pte types with - * the hw invalid bit set must be distinguishable from the four pte types - * empty, none, swap and file. - * - * irxt ipte irxt - * _PAGE_TYPE_EMPTY 1000 -> 1000 - * _PAGE_TYPE_NONE 1001 -> 1001 - * _PAGE_TYPE_SWAP 1011 -> 1011 - * _PAGE_TYPE_FILE 11?1 -> 11?1 - * _PAGE_TYPE_RO 0100 -> 1100 - * _PAGE_TYPE_RW 0000 -> 1000 - * - * pte_none is true for bits combinations 1000, 1100 - * pte_present is true for bits combinations 0000, 0010, 0100, 0110, 1001 - * pte_file is true for bits combinations 1101, 1111 - * swap pte is 1011 and 0001, 0011, 0101, 0111, 1010 and 1110 are invalid. - */ - #ifndef __s390x__ /* Bits in the segment table entry */ @@ -392,21 +365,18 @@ static inline int pmd_bad(pmd_t pmd) static inline int pte_none(pte_t pte) { - return (pte_val(pte) & _PAGE_INVALID) && !(pte_val(pte) & _PAGE_SWT); + return (pte_val(pte) & _PAGE_TYPE_MASK) == _PAGE_TYPE_EMPTY; } static inline int pte_present(pte_t pte) { - unsigned long mask = _PAGE_RO | _PAGE_INVALID | _PAGE_SWT | _PAGE_SWX; - return (pte_val(pte) & mask) == _PAGE_TYPE_NONE || - (!(pte_val(pte) & _PAGE_INVALID) && - !(pte_val(pte) & _PAGE_SWT)); + return !(pte_val(pte) & _PAGE_INVALID) || + (pte_val(pte) & _PAGE_TYPE_MASK) == _PAGE_TYPE_NONE; } static inline int pte_file(pte_t pte) { - unsigned long mask = _PAGE_RO | _PAGE_INVALID | _PAGE_SWT; - return (pte_val(pte) & mask) == _PAGE_TYPE_FILE; + return (pte_val(pte) & _PAGE_TYPE_MASK) == _PAGE_TYPE_FILE; } #define pte_same(a,b) (pte_val(a) == pte_val(b)) diff --git a/trunk/include/asm-s390/s390_ext.h b/trunk/include/asm-s390/s390_ext.h index df9b1017b703..e9a2862b230d 100644 --- a/trunk/include/asm-s390/s390_ext.h +++ b/trunk/include/asm-s390/s390_ext.h @@ -10,7 +10,7 @@ * Martin Schwidefsky (schwidefsky@de.ibm.com) */ -typedef void (*ext_int_handler_t)(__u16 code); +typedef void (*ext_int_handler_t)(struct pt_regs *regs, __u16 code); /* * Warning: if you change ext_int_info_t you have to change the diff --git a/trunk/include/asm-s390/timer.h b/trunk/include/asm-s390/timer.h index 30e5cbe570f2..fcd6c256a2d1 100644 --- a/trunk/include/asm-s390/timer.h +++ b/trunk/include/asm-s390/timer.h @@ -26,7 +26,7 @@ struct vtimer_list { spinlock_t lock; unsigned long magic; - void (*function)(unsigned long); + void (*function)(unsigned long, struct pt_regs*); unsigned long data; }; diff --git a/trunk/include/asm-s390/unistd.h b/trunk/include/asm-s390/unistd.h index 71d3c21b84f0..a19238cbcffa 100644 --- a/trunk/include/asm-s390/unistd.h +++ b/trunk/include/asm-s390/unistd.h @@ -249,9 +249,8 @@ #define __NR_vmsplice 309 /* Number 310 is reserved for new sys_move_pages */ #define __NR_getcpu 311 -#define __NR_epoll_pwait 312 -#define NR_syscalls 313 +#define NR_syscalls 312 /* * There are some system calls that are not present on 64 bit, some diff --git a/trunk/include/asm-sh/cpu-sh4/ubc.h b/trunk/include/asm-sh/cpu-sh4/ubc.h index c86e17050935..3d0943167659 100644 --- a/trunk/include/asm-sh/cpu-sh4/ubc.h +++ b/trunk/include/asm-sh/cpu-sh4/ubc.h @@ -3,7 +3,6 @@ * * Copyright (C) 1999 Niibe Yutaka * Copyright (C) 2003 Paul Mundt - * Copyright (C) 2006 Lineo Solutions Inc. support SH4A UBC * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -12,41 +11,6 @@ #ifndef __ASM_CPU_SH4_UBC_H #define __ASM_CPU_SH4_UBC_H -#if defined(CONFIG_CPU_SH4A) -#define UBC_CBR0 0xff200000 -#define UBC_CRR0 0xff200004 -#define UBC_CAR0 0xff200008 -#define UBC_CAMR0 0xff20000c -#define UBC_CBR1 0xff200020 -#define UBC_CRR1 0xff200024 -#define UBC_CAR1 0xff200028 -#define UBC_CAMR1 0xff20002c -#define UBC_CDR1 0xff200030 -#define UBC_CDMR1 0xff200034 -#define UBC_CETR1 0xff200038 -#define UBC_CCMFR 0xff200600 -#define UBC_CBCR 0xff200620 - -/* CBR */ -#define UBC_CBR_AIE (0x01<<30) -#define UBC_CBR_ID_INST (0x01<<4) -#define UBC_CBR_RW_READ (0x01<<1) -#define UBC_CBR_CE (0x01) - -#define UBC_CBR_AIV_MASK (0x00FF0000) -#define UBC_CBR_AIV_SHIFT (16) -#define UBC_CBR_AIV_SET(asid) (((asid)< - diff --git a/trunk/include/asm-sh/edosk7705.h b/trunk/include/asm-sh/edosk7705/io.h similarity index 100% rename from trunk/include/asm-sh/edosk7705.h rename to trunk/include/asm-sh/edosk7705/io.h diff --git a/trunk/include/asm-sh/hp6xx.h b/trunk/include/asm-sh/hp6xx/hp6xx.h similarity index 100% rename from trunk/include/asm-sh/hp6xx.h rename to trunk/include/asm-sh/hp6xx/hp6xx.h diff --git a/trunk/include/asm-sh/hp6xx/ide.h b/trunk/include/asm-sh/hp6xx/ide.h new file mode 100644 index 000000000000..570395a5ebe5 --- /dev/null +++ b/trunk/include/asm-sh/hp6xx/ide.h @@ -0,0 +1,8 @@ +#ifndef __ASM_SH_HP6XX_IDE_H +#define __ASM_SH_HP6XX_IDE_H + +#define IRQ_CFCARD 93 +#define IRQ_PCMCIA 94 + +#endif /* __ASM_SH_HP6XX_IDE_H */ + diff --git a/trunk/include/asm-sh/hp6xx/io.h b/trunk/include/asm-sh/hp6xx/io.h new file mode 100644 index 000000000000..2044476ab199 --- /dev/null +++ b/trunk/include/asm-sh/hp6xx/io.h @@ -0,0 +1,10 @@ +#ifndef __ASM_SH_HP6XX_IO_H +#define __ASM_SH_HP6XX_IO_H + +/* + * Nothing special here.. just use the generic cchip io routines. + */ +#include + +#endif /* __ASM_SH_HP6XX_IO_H */ + diff --git a/trunk/include/asm-sh/hs7751rvoip.h b/trunk/include/asm-sh/hs7751rvoip/hs7751rvoip.h similarity index 100% rename from trunk/include/asm-sh/hs7751rvoip.h rename to trunk/include/asm-sh/hs7751rvoip/hs7751rvoip.h diff --git a/trunk/include/asm-sh/hs7751rvoip/ide.h b/trunk/include/asm-sh/hs7751rvoip/ide.h new file mode 100644 index 000000000000..65ad1d0f763b --- /dev/null +++ b/trunk/include/asm-sh/hs7751rvoip/ide.h @@ -0,0 +1,8 @@ +#ifndef __ASM_SH_HS7751RVOIP_IDE_H +#define __ASM_SH_HS7751RVOIP_IDE_H + +/* Nothing to see here.. */ +#include + +#endif /* __ASM_SH_HS7751RVOIP_IDE_H */ + diff --git a/trunk/include/asm-sh/hw_irq.h b/trunk/include/asm-sh/hw_irq.h index 80ee1cda7498..fed26616967a 100644 --- a/trunk/include/asm-sh/hw_irq.h +++ b/trunk/include/asm-sh/hw_irq.h @@ -1,8 +1,4 @@ #ifndef __ASM_SH_HW_IRQ_H #define __ASM_SH_HW_IRQ_H -#include - -extern atomic_t irq_err_count; - #endif /* __ASM_SH_HW_IRQ_H */ diff --git a/trunk/include/asm-sh/io.h b/trunk/include/asm-sh/io.h index a0e55b09e4fd..ed12d38e8c00 100644 --- a/trunk/include/asm-sh/io.h +++ b/trunk/include/asm-sh/io.h @@ -304,6 +304,22 @@ __ioremap_mode(unsigned long offset, unsigned long size, unsigned long flags) #define iounmap(addr) \ __iounmap((addr)) +static inline int check_signature(char __iomem *io_addr, + const unsigned char *signature, int length) +{ + int retval = 0; + do { + if (readb(io_addr) != *signature) + goto out; + io_addr++; + signature++; + length--; + } while (length); + retval = 1; +out: + return retval; +} + /* * The caches on some architectures aren't dma-coherent and have need to * handle this in software. There are three types of operations that diff --git a/trunk/include/asm-sh/irq-sh7780.h b/trunk/include/asm-sh/irq-sh7780.h index 19912ae6a7f7..895c5780e454 100644 --- a/trunk/include/asm-sh/irq-sh7780.h +++ b/trunk/include/asm-sh/irq-sh7780.h @@ -6,6 +6,16 @@ * * Copyright (C) 2004 Takashi SHUDO */ + +#ifdef CONFIG_IDE +# ifndef IRQ_CFCARD +# define IRQ_CFCARD 14 +# endif +# ifndef IRQ_PCMCIA +# define IRQ_PCMCIA 15 +# endif +#endif + #define INTC_BASE 0xffd00000 #define INTC_ICR0 (INTC_BASE+0x0) #define INTC_ICR1 (INTC_BASE+0x1c) diff --git a/trunk/include/asm-sh/irq.h b/trunk/include/asm-sh/irq.h index 6cd3e9e2a76a..0e5f365aff70 100644 --- a/trunk/include/asm-sh/irq.h +++ b/trunk/include/asm-sh/irq.h @@ -14,6 +14,16 @@ #include #include /* for pt_regs */ +#if defined(CONFIG_SH_HP6XX) || \ + defined(CONFIG_SH_RTS7751R2D) || \ + defined(CONFIG_SH_HS7751RVOIP) || \ + defined(CONFIG_SH_HS7751RVOIP) || \ + defined(CONFIG_SH_SH03) || \ + defined(CONFIG_SH_R7780RP) || \ + defined(CONFIG_SH_LANDISK) +#include +#endif + #ifndef CONFIG_CPU_SUBTYPE_SH7780 #define INTC_DMAC0_MSK 0 @@ -28,6 +38,15 @@ #define INTC_IPRD 0xffd00010UL #endif +#ifdef CONFIG_IDE +# ifndef IRQ_CFCARD +# define IRQ_CFCARD 14 +# endif +# ifndef IRQ_PCMCIA +# define IRQ_PCMCIA 15 +# endif +#endif + #define TIMER_IRQ 16 #define TIMER_IPR_ADDR INTC_IPRA #define TIMER_IPR_POS 3 @@ -327,17 +346,11 @@ extern unsigned short *irq_mask_register; */ void init_IRQ_pint(void); -struct ipr_data { - unsigned int irq; - unsigned int addr; /* Address of Interrupt Priority Register */ - int shift; /* Shifts of the 16-bit data */ - int priority; /* The priority */ -}; - /* * Function for "on chip support modules". */ -extern void make_ipr_irq(struct ipr_data *table, unsigned int nr_irqs); +extern void make_ipr_irq(unsigned int irq, unsigned int addr, + int pos, int priority); extern void make_imask_irq(unsigned int irq); #if defined(CONFIG_CPU_SUBTYPE_SH7300) @@ -684,15 +697,13 @@ extern int ipr_irq_demux(int irq); #define INTC2_INTPRI_OFFSET 0x00 -struct intc2_data { - unsigned short irq; - unsigned char ipr_offset, ipr_shift; - unsigned char msk_offset, msk_shift; - unsigned char priority; -}; - -void make_intc2_irq(struct intc2_data *, unsigned int nr_irqs); +void make_intc2_irq(unsigned int irq, + unsigned int ipr_offset, unsigned int ipr_shift, + unsigned int msk_offset, unsigned int msk_shift, + unsigned int priority); void init_IRQ_intc2(void); +void intc2_add_clear_irq(int irq, int (*fn)(int)); + #endif extern int shmse_irq_demux(int irq); diff --git a/trunk/include/asm-sh/irq_regs.h b/trunk/include/asm-sh/irq_regs.h deleted file mode 100644 index 3dd9c0b70270..000000000000 --- a/trunk/include/asm-sh/irq_regs.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/include/asm-sh/landisk/ide.h b/trunk/include/asm-sh/landisk/ide.h new file mode 100644 index 000000000000..6490e28415ed --- /dev/null +++ b/trunk/include/asm-sh/landisk/ide.h @@ -0,0 +1,14 @@ +/* + * modifed by kogiidena + * 2005.03.03 + */ + +#ifndef __ASM_SH_LANDISK_IDE_H +#define __ASM_SH_LANDISK_IDE_H + +/* Nothing to see here.. */ +#include +#define IRQ_CFCARD IRQ_FATA /* CF Card IRQ */ +#define IRQ_PCMCIA IRQ_ATA /* PCMCIA IRQ */ + +#endif /* __ASM_SH_LANDISK_IDE_H */ diff --git a/trunk/include/asm-sh/processor.h b/trunk/include/asm-sh/processor.h index 45bb74e35d32..474773853cd1 100644 --- a/trunk/include/asm-sh/processor.h +++ b/trunk/include/asm-sh/processor.h @@ -255,8 +255,6 @@ extern void save_fpu(struct task_struct *__tsk, struct pt_regs *regs); */ #define thread_saved_pc(tsk) (tsk->thread.pc) -void show_trace(struct task_struct *tsk, unsigned long *sp, - struct pt_regs *regs); extern unsigned long get_wchan(struct task_struct *p); #define KSTK_EIP(tsk) ((tsk)->thread.pc) diff --git a/trunk/include/asm-sh/r7780rp/ide.h b/trunk/include/asm-sh/r7780rp/ide.h new file mode 100644 index 000000000000..a1ed78e0f617 --- /dev/null +++ b/trunk/include/asm-sh/r7780rp/ide.h @@ -0,0 +1,8 @@ +#ifndef __ASM_SH_R7780RP_IDE_H +#define __ASM_SH_R7780RP_IDE_H + +/* Nothing to see here.. */ +#include + +#endif /* __ASM_SH_R7780RP_IDE_H */ + diff --git a/trunk/include/asm-sh/r7780rp.h b/trunk/include/asm-sh/r7780rp/r7780rp.h similarity index 96% rename from trunk/include/asm-sh/r7780rp.h rename to trunk/include/asm-sh/r7780rp/r7780rp.h index c18f648a7995..f95d9dba31a2 100644 --- a/trunk/include/asm-sh/r7780rp.h +++ b/trunk/include/asm-sh/r7780rp/r7780rp.h @@ -72,6 +72,8 @@ #define PA_AX88796L 0xa4100400 /* AX88796L Area */ #define PA_SC1602BSLB 0xa6000000 /* SC1602BSLB Area */ +#define PA_AREA5_IO 0xb4000000 /* Area 5 IO Memory */ +#define PA_AREA6_IO 0xb8000000 /* Area 6 IO Memory */ #define PA_IDE_OFFSET 0x1f0 /* CF IDE Offset */ #define AX88796L_IO_BASE 0x1000 /* AX88796L IO Base Address */ @@ -81,6 +83,7 @@ #define IRQ_PCISLOT2 66 /* PCI Slot #2 IRQ */ #define IRQ_PCISLOT3 67 /* PCI Slot #3 IRQ */ #define IRQ_PCISLOT4 68 /* PCI Slot #4 IRQ */ +#define IRQ_CFCARD 1 /* CF Card IRQ */ // #define IRQ_CFINST 0 /* CF Card Insert IRQ */ #define IRQ_TP 2 /* Touch Panel IRQ */ #define IRQ_SCI1 3 /* SCI1 IRQ */ @@ -143,6 +146,8 @@ #define PA_AX88796L 0xa5800400 /* AX88796L Area */ #define PA_SC1602BSLB 0xa6000000 /* SC1602BSLB Area */ +#define PA_AREA5_IO 0xb4000000 /* Area 5 IO Memory */ +#define PA_AREA6_IO 0xb8000000 /* Area 6 IO Memory */ #define PA_IDE_OFFSET 0x1f0 /* CF IDE Offset */ #define AX88796L_IO_BASE 0x1000 /* AX88796L IO Base Address */ @@ -152,6 +157,7 @@ #define IRQ_PCISLOT2 1 /* PCI Slot #2 IRQ */ #define IRQ_PCISLOT3 2 /* PCI Slot #3 IRQ */ #define IRQ_PCISLOT4 3 /* PCI Slot #4 IRQ */ +#define IRQ_CFCARD 4 /* CF Card IRQ */ #define IRQ_CFINST 5 /* CF Card Insert IRQ */ #define IRQ_M66596 6 /* M66596 IRQ */ #define IRQ_SDCARD 7 /* SD Card IRQ */ diff --git a/trunk/include/asm-sh/rts7751r2d/ide.h b/trunk/include/asm-sh/rts7751r2d/ide.h new file mode 100644 index 000000000000..416f96b407cb --- /dev/null +++ b/trunk/include/asm-sh/rts7751r2d/ide.h @@ -0,0 +1,8 @@ +#ifndef __ASM_SH_RTS7751R2D_IDE_H +#define __ASM_SH_RTS7751R2D_IDE_H + +/* Nothing to see here.. */ +#include + +#endif /* __ASM_SH_RTS7751R2D_IDE_H */ + diff --git a/trunk/include/asm-sh/rts7751r2d.h b/trunk/include/asm-sh/rts7751r2d/rts7751r2d.h similarity index 100% rename from trunk/include/asm-sh/rts7751r2d.h rename to trunk/include/asm-sh/rts7751r2d/rts7751r2d.h diff --git a/trunk/include/asm-sh/sh03/ide.h b/trunk/include/asm-sh/sh03/ide.h new file mode 100644 index 000000000000..73ee92e5c79e --- /dev/null +++ b/trunk/include/asm-sh/sh03/ide.h @@ -0,0 +1,7 @@ +#ifndef __ASM_SH_SH03_IDE_H +#define __ASM_SH_SH03_IDE_H + +#define IRQ_CFCARD 8 +#define IRQ_PCMCIA 8 + +#endif /* __ASM_SH_SH03_IDE_H */ diff --git a/trunk/include/asm-sh/shmin.h b/trunk/include/asm-sh/shmin/shmin.h similarity index 100% rename from trunk/include/asm-sh/shmin.h rename to trunk/include/asm-sh/shmin/shmin.h diff --git a/trunk/include/asm-sh/system.h b/trunk/include/asm-sh/system.h index 3340126f4e0f..6c1f8fde5ac4 100644 --- a/trunk/include/asm-sh/system.h +++ b/trunk/include/asm-sh/system.h @@ -353,13 +353,6 @@ static inline unsigned long __cmpxchg(volatile void * ptr, unsigned long old, (unsigned long)_n_, sizeof(*(ptr))); \ }) -extern void *set_exception_table_vec(unsigned int vec, void *handler); - -static inline void *set_exception_table_evt(unsigned int evt, void *handler) -{ - return set_exception_table_vec(evt >> 5, handler); -} - /* XXX * disable hlt during certain critical i/o operations */ diff --git a/trunk/include/asm-sh/timer.h b/trunk/include/asm-sh/timer.h index 5df842bcf7b6..c7ab28095ba0 100644 --- a/trunk/include/asm-sh/timer.h +++ b/trunk/include/asm-sh/timer.h @@ -8,9 +8,8 @@ struct sys_timer_ops { int (*init)(void); int (*start)(void); int (*stop)(void); -#ifndef CONFIG_GENERIC_TIME unsigned long (*get_offset)(void); -#endif + unsigned long (*get_frequency)(void); }; struct sys_timer { @@ -25,17 +24,21 @@ struct sys_timer { extern struct sys_timer tmu_timer; extern struct sys_timer *sys_timer; -#ifndef CONFIG_GENERIC_TIME static inline unsigned long get_timer_offset(void) { return sys_timer->ops->get_offset(); } -#endif + +static inline unsigned long get_timer_frequency(void) +{ + return sys_timer->ops->get_frequency(); +} /* arch/sh/kernel/timers/timer.c */ struct sys_timer *get_sys_timer(void); /* arch/sh/kernel/time.c */ -void handle_timer_tick(void); +void handle_timer_tick(struct pt_regs *); #endif /* __ASM_SH_TIMER_H */ + diff --git a/trunk/include/asm-sh/unistd.h b/trunk/include/asm-sh/unistd.h index 1c2abde122cd..f1a0cbc966be 100644 --- a/trunk/include/asm-sh/unistd.h +++ b/trunk/include/asm-sh/unistd.h @@ -324,11 +324,8 @@ #define __NR_sync_file_range 314 #define __NR_tee 315 #define __NR_vmsplice 316 -#define __NR_move_pages 317 -#define __NR_getcpu 318 -#define __NR_epoll_pwait 319 -#define NR_syscalls 320 +#define NR_syscalls 317 #ifdef __KERNEL__ diff --git a/trunk/include/asm-sh64/device.h b/trunk/include/asm-sh64/device.h deleted file mode 100644 index d8f9872b0e2d..000000000000 --- a/trunk/include/asm-sh64/device.h +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Arch specific extensions to struct device - * - * This file is released under the GPLv2 - */ -#include - diff --git a/trunk/include/asm-sh64/io.h b/trunk/include/asm-sh64/io.h index 14d8e7b4bf4b..252fedbb6621 100644 --- a/trunk/include/asm-sh64/io.h +++ b/trunk/include/asm-sh64/io.h @@ -178,6 +178,22 @@ extern void iounmap(void *addr); unsigned long onchip_remap(unsigned long addr, unsigned long size, const char* name); extern void onchip_unmap(unsigned long vaddr); +static __inline__ int check_signature(volatile void __iomem *io_addr, + const unsigned char *signature, int length) +{ + int retval = 0; + do { + if (readb(io_addr) != *signature) + goto out; + io_addr++; + signature++; + length--; + } while (length); + retval = 1; +out: + return retval; +} + /* * The caches on some architectures aren't dma-coherent and have need to * handle this in software. There are three types of operations that diff --git a/trunk/include/asm-sparc/device.h b/trunk/include/asm-sparc/device.h deleted file mode 100644 index d8f9872b0e2d..000000000000 --- a/trunk/include/asm-sparc/device.h +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Arch specific extensions to struct device - * - * This file is released under the GPLv2 - */ -#include - diff --git a/trunk/include/asm-sparc/elf.h b/trunk/include/asm-sparc/elf.h index aaf6ef40ee2f..83a3dd15a6ed 100644 --- a/trunk/include/asm-sparc/elf.h +++ b/trunk/include/asm-sparc/elf.h @@ -8,6 +8,11 @@ #include +#ifdef __KERNEL__ +#include +#include +#endif + /* * Sparc section types */ @@ -72,23 +77,6 @@ typedef unsigned long elf_greg_t; #define ELF_NGREG 38 typedef elf_greg_t elf_gregset_t[ELF_NGREG]; -typedef struct { - union { - unsigned long pr_regs[32]; - double pr_dregs[16]; - } pr_fr; - unsigned long __unused; - unsigned long pr_fsr; - unsigned char pr_qcnt; - unsigned char pr_q_entrysize; - unsigned char pr_en; - unsigned int pr_q[64]; -} elf_fpregset_t; - -#ifdef __KERNEL__ -#include -#include - /* Format is: * G0 --> G7 * O0 --> O7 @@ -111,7 +99,20 @@ do { unsigned long *dest = &(__elf_regs[0]); \ dest[34] = src->npc; \ dest[35] = src->y; \ dest[36] = dest[37] = 0; /* XXX */ \ -} while(0); /* Janitors: Don't touch this semicolon. */ +} while(0); /* Janitors: Don't touch this colon. */ + +typedef struct { + union { + unsigned long pr_regs[32]; + double pr_dregs[16]; + } pr_fr; + unsigned long __unused; + unsigned long pr_fsr; + unsigned char pr_qcnt; + unsigned char pr_q_entrysize; + unsigned char pr_en; + unsigned int pr_q[64]; +} elf_fpregset_t; #define ELF_CORE_COPY_TASK_REGS(__tsk, __elf_regs) \ ({ ELF_CORE_COPY_REGS((*(__elf_regs)), (__tsk)->thread.kregs); 1; }) @@ -164,8 +165,8 @@ do { unsigned long *dest = &(__elf_regs[0]); \ #define ELF_PLATFORM (NULL) +#ifdef __KERNEL__ #define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX) - -#endif /* __KERNEL__ */ +#endif #endif /* !(__ASMSPARC_ELF_H) */ diff --git a/trunk/include/asm-sparc/floppy.h b/trunk/include/asm-sparc/floppy.h index 9073c84218ce..c53b332c850a 100644 --- a/trunk/include/asm-sparc/floppy.h +++ b/trunk/include/asm-sparc/floppy.h @@ -262,7 +262,7 @@ static __inline__ void sun_fd_enable_dma(void) } /* Our low-level entry point in arch/sparc/kernel/entry.S */ -irqreturn_t floppy_hardint(int irq, void *unused); +irqreturn_t floppy_hardint(int irq, void *unused, struct pt_regs *regs); static int sun_fd_request_irq(void) { diff --git a/trunk/include/asm-sparc/irq.h b/trunk/include/asm-sparc/irq.h index ff520ea97473..3141ddfea97d 100644 --- a/trunk/include/asm-sparc/irq.h +++ b/trunk/include/asm-sparc/irq.h @@ -76,8 +76,8 @@ static inline void load_profile_irq(int cpu, int limit) BTFIXUP_CALL(load_profile_irq)(cpu, limit); } -extern void (*sparc_init_timers)(irq_handler_t lvl10_irq); -extern void claim_ticker14(irq_handler_t irq_handler, +extern void (*sparc_init_timers)(irqreturn_t (*lvl10_irq)(int, void *, struct pt_regs *)); +extern void claim_ticker14(irqreturn_t (*irq_handler)(int, void *, struct pt_regs *), int irq, unsigned int timeout); @@ -91,7 +91,7 @@ BTFIXUPDEF_CALL(void, set_irq_udt, int) #define set_irq_udt(cpu) BTFIXUP_CALL(set_irq_udt)(cpu) #endif -extern int request_fast_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, __const__ char *devname); +extern int request_fast_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long flags, __const__ char *devname); /* On the sun4m, just like the timers, we have both per-cpu and master * interrupt registers. diff --git a/trunk/include/asm-sparc/irq_regs.h b/trunk/include/asm-sparc/irq_regs.h deleted file mode 100644 index 3dd9c0b70270..000000000000 --- a/trunk/include/asm-sparc/irq_regs.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/include/asm-sparc/spinlock.h b/trunk/include/asm-sparc/spinlock.h index de2249b267c6..557d08959d2f 100644 --- a/trunk/include/asm-sparc/spinlock.h +++ b/trunk/include/asm-sparc/spinlock.h @@ -129,7 +129,6 @@ static inline void __raw_write_lock(raw_rwlock_t *rw) : /* no outputs */ : "r" (lp) : "g2", "g4", "memory", "cc"); - *(volatile __u32 *)&lp->lock = ~0U; } static inline int __raw_write_trylock(raw_rwlock_t *rw) @@ -145,40 +144,15 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw) val = rw->lock & ~0xff; if (val) ((volatile u8*)&rw->lock)[3] = 0; - else - *(volatile u32*)&rw->lock = ~0U; } return (val == 0); } -static inline int __read_trylock(raw_rwlock_t *rw) -{ - register raw_rwlock_t *lp asm("g1"); - register int res asm("o0"); - lp = rw; - __asm__ __volatile__( - "mov %%o7, %%g4\n\t" - "call ___rw_read_try\n\t" - " ldstub [%%g1 + 3], %%g2\n" - : "=r" (res) - : "r" (lp) - : "g2", "g4", "memory", "cc"); - return res; -} - -#define __raw_read_trylock(lock) \ -({ unsigned long flags; \ - int res; \ - local_irq_save(flags); \ - res = __read_trylock(lock); \ - local_irq_restore(flags); \ - res; \ -}) - #define __raw_write_unlock(rw) do { (rw)->lock = 0; } while(0) #define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock) +#define __raw_read_trylock(lock) generic__raw_read_trylock(lock) #define _raw_spin_relax(lock) cpu_relax() #define _raw_read_relax(lock) cpu_relax() diff --git a/trunk/include/asm-sparc/unistd.h b/trunk/include/asm-sparc/unistd.h index f7827fa4cd5e..c7a495afc82e 100644 --- a/trunk/include/asm-sparc/unistd.h +++ b/trunk/include/asm-sparc/unistd.h @@ -318,15 +318,12 @@ #define __NR_unshare 299 #define __NR_set_robust_list 300 #define __NR_get_robust_list 301 -#define __NR_migrate_pages 302 - -#define NR_SYSCALLS 303 #ifdef __KERNEL__ -/* WARNING: You MAY NOT add syscall numbers larger than 302, since +/* WARNING: You MAY NOT add syscall numbers larger than 301, since * all of the syscall tables in the Sparc kernel are - * sized to have 302 entries (starting at zero). Therefore - * find a free slot in the 0-302 range. + * sized to have 301 entries (starting at zero). Therefore + * find a free slot in the 0-301 range. */ #define _syscall0(type,name) \ diff --git a/trunk/include/asm-sparc64/compat.h b/trunk/include/asm-sparc64/compat.h index 36511ca51416..c73935dc7ba1 100644 --- a/trunk/include/asm-sparc64/compat.h +++ b/trunk/include/asm-sparc64/compat.h @@ -164,7 +164,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr) return (u32)(unsigned long)uptr; } -static inline void __user *compat_alloc_user_space(long len) +static __inline__ void __user *compat_alloc_user_space(long len) { struct pt_regs *regs = current_thread_info()->kregs; unsigned long usp = regs->u_regs[UREG_I6]; @@ -174,10 +174,7 @@ static inline void __user *compat_alloc_user_space(long len) else usp &= 0xffffffffUL; - usp -= len; - usp &= ~0x7UL; - - return (void __user *) usp; + return (void __user *) (usp - len); } struct compat_ipc64_perm { diff --git a/trunk/include/asm-sparc64/device.h b/trunk/include/asm-sparc64/device.h deleted file mode 100644 index d8f9872b0e2d..000000000000 --- a/trunk/include/asm-sparc64/device.h +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Arch specific extensions to struct device - * - * This file is released under the GPLv2 - */ -#include - diff --git a/trunk/include/asm-sparc64/floppy.h b/trunk/include/asm-sparc64/floppy.h index dbe033e494db..abf150038019 100644 --- a/trunk/include/asm-sparc64/floppy.h +++ b/trunk/include/asm-sparc64/floppy.h @@ -208,7 +208,7 @@ static void sun_fd_enable_dma(void) pdma_areasize = pdma_size; } -irqreturn_t sparc_floppy_irq(int irq, void *dev_cookie) +irqreturn_t sparc_floppy_irq(int irq, void *dev_cookie, struct pt_regs *regs) { if (likely(doing_pdma)) { void __iomem *stat = (void __iomem *) fdc_status; @@ -255,7 +255,7 @@ irqreturn_t sparc_floppy_irq(int irq, void *dev_cookie) } main_interrupt: - return floppy_interrupt(irq, dev_cookie); + return floppy_interrupt(irq, dev_cookie, regs); } static int sun_fd_request_irq(void) @@ -311,7 +311,7 @@ struct sun_pci_dma_op { static struct sun_pci_dma_op sun_pci_dma_current = { -1U, 0, 0, NULL}; static struct sun_pci_dma_op sun_pci_dma_pending = { -1U, 0, 0, NULL}; -extern irqreturn_t floppy_interrupt(int irq, void *dev_id); +extern irqreturn_t floppy_interrupt(int irq, void *dev_id, struct pt_regs *regs); static unsigned char sun_pci_fd_inb(unsigned long port) { @@ -446,7 +446,7 @@ static int sun_pci_fd_eject(int drive) void sun_pci_fd_dma_callback(struct ebus_dma_info *p, int event, void *cookie) { - floppy_interrupt(0, NULL); + floppy_interrupt(0, NULL, NULL); } /* diff --git a/trunk/include/asm-sparc64/futex.h b/trunk/include/asm-sparc64/futex.h index 7392fc4a954e..dee40206b221 100644 --- a/trunk/include/asm-sparc64/futex.h +++ b/trunk/include/asm-sparc64/futex.h @@ -87,22 +87,24 @@ static inline int futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval) { __asm__ __volatile__( - "\n1: casa [%3] %%asi, %2, %0\n" - "2:\n" + "\n1: lduwa [%2] %%asi, %0\n" + "2: casa [%2] %%asi, %0, %1\n" + "3:\n" " .section .fixup,#alloc,#execinstr\n" " .align 4\n" - "3: ba 2b\n" - " mov %4, %0\n" + "4: ba 3b\n" + " mov %3, %0\n" " .previous\n" " .section __ex_table,\"a\"\n" " .align 4\n" - " .word 1b, 3b\n" + " .word 1b, 4b\n" + " .word 2b, 4b\n" " .previous\n" - : "=r" (newval) - : "0" (newval), "r" (oldval), "r" (uaddr), "i" (-EFAULT) + : "=&r" (oldval) + : "r" (newval), "r" (uaddr), "i" (-EFAULT) : "memory"); - return newval; + return oldval; } #endif /* !(_SPARC64_FUTEX_H) */ diff --git a/trunk/include/asm-sparc64/io.h b/trunk/include/asm-sparc64/io.h index 30b912d8e8bc..0056770e83ad 100644 --- a/trunk/include/asm-sparc64/io.h +++ b/trunk/include/asm-sparc64/io.h @@ -440,6 +440,21 @@ _memcpy_toio(volatile void __iomem *dst, const void *src, __kernel_size_t n) #define memcpy_toio(d,s,sz) _memcpy_toio(d,s,sz) +static inline int check_signature(void __iomem *io_addr, + const unsigned char *signature, + int length) +{ + int retval = 0; + do { + if (readb(io_addr) != *signature++) + goto out; + io_addr++; + } while (--length); + retval = 1; +out: + return retval; +} + #define mmiowb() #ifdef __KERNEL__ diff --git a/trunk/include/asm-sparc64/irq_regs.h b/trunk/include/asm-sparc64/irq_regs.h deleted file mode 100644 index 3dd9c0b70270..000000000000 --- a/trunk/include/asm-sparc64/irq_regs.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/include/asm-sparc64/pci.h b/trunk/include/asm-sparc64/pci.h index ca6560288ae8..e1ea67bc32f2 100644 --- a/trunk/include/asm-sparc64/pci.h +++ b/trunk/include/asm-sparc64/pci.h @@ -18,8 +18,6 @@ #define PCI_IRQ_NONE 0xffffffff -#define PCI_CACHE_LINE_BYTES 64 - static inline void pcibios_set_master(struct pci_dev *dev) { /* No special bus mastering setup handling */ @@ -293,6 +291,10 @@ extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, enum pci_mmap_state mmap_state, int write_combine); +/* Platform specific MWI support. */ +#define HAVE_ARCH_PCI_MWI +extern int pcibios_prep_mwi(struct pci_dev *dev); + extern void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, struct resource *res); diff --git a/trunk/include/asm-sparc64/unistd.h b/trunk/include/asm-sparc64/unistd.h index 63669dad0d72..124cf076717f 100644 --- a/trunk/include/asm-sparc64/unistd.h +++ b/trunk/include/asm-sparc64/unistd.h @@ -320,16 +320,12 @@ #define __NR_unshare 299 #define __NR_set_robust_list 300 #define __NR_get_robust_list 301 -#define __NR_migrate_pages 302 - -#define NR_SYSCALLS 303 #ifdef __KERNEL__ - -/* WARNING: You MAY NOT add syscall numbers larger than 302, since +/* WARNING: You MAY NOT add syscall numbers larger than 301, since * all of the syscall tables in the Sparc kernel are - * sized to have 302 entries (starting at zero). Therefore - * find a free slot in the 0-302 range. + * sized to have 301 entries (starting at zero). Therefore + * find a free slot in the 0-301 range. */ #define _syscall0(type,name) \ diff --git a/trunk/include/asm-um/archparam-ppc.h b/trunk/include/asm-um/archparam-ppc.h index 4269d8a37b4f..172cd6ffacc4 100644 --- a/trunk/include/asm-um/archparam-ppc.h +++ b/trunk/include/asm-um/archparam-ppc.h @@ -1,6 +1,15 @@ #ifndef __UM_ARCHPARAM_PPC_H #define __UM_ARCHPARAM_PPC_H +/********* Bits for asm-um/hw_irq.h **********/ + +struct hw_interrupt_type; + +/********* Bits for asm-um/hardirq.h **********/ + +#define irq_enter(cpu, irq) hardirq_enter(cpu) +#define irq_exit(cpu, irq) hardirq_exit(cpu) + /********* Bits for asm-um/string.h **********/ #define __HAVE_ARCH_STRRCHR diff --git a/trunk/include/asm-um/common.lds.S b/trunk/include/asm-um/common.lds.S index f0454516dd31..1010153faaf9 100644 --- a/trunk/include/asm-um/common.lds.S +++ b/trunk/include/asm-um/common.lds.S @@ -42,7 +42,13 @@ __initcall_start = .; .initcall.init : { - INITCALLS + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) } __initcall_end = .; diff --git a/trunk/include/asm-um/device.h b/trunk/include/asm-um/device.h deleted file mode 100644 index d8f9872b0e2d..000000000000 --- a/trunk/include/asm-um/device.h +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Arch specific extensions to struct device - * - * This file is released under the GPLv2 - */ -#include - diff --git a/trunk/include/asm-um/irq_regs.h b/trunk/include/asm-um/irq_regs.h deleted file mode 100644 index 3dd9c0b70270..000000000000 --- a/trunk/include/asm-um/irq_regs.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/include/asm-v850/device.h b/trunk/include/asm-v850/device.h deleted file mode 100644 index d8f9872b0e2d..000000000000 --- a/trunk/include/asm-v850/device.h +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Arch specific extensions to struct device - * - * This file is released under the GPLv2 - */ -#include - diff --git a/trunk/include/asm-x86_64/acpi.h b/trunk/include/asm-x86_64/acpi.h index 9d1916e59c04..ed59aa4c6ff9 100644 --- a/trunk/include/asm-x86_64/acpi.h +++ b/trunk/include/asm-x86_64/acpi.h @@ -163,7 +163,6 @@ extern u8 x86_acpiid_to_apicid[]; #define ARCH_HAS_POWER_INIT 1 extern int acpi_skip_timer_override; -extern int acpi_use_timer_override; #endif /*__KERNEL__*/ diff --git a/trunk/include/asm-x86_64/apic.h b/trunk/include/asm-x86_64/apic.h index e81d0f289f0b..9e66d32330c9 100644 --- a/trunk/include/asm-x86_64/apic.h +++ b/trunk/include/asm-x86_64/apic.h @@ -77,7 +77,7 @@ extern void sync_Arb_IDs (void); extern void init_bsp_APIC (void); extern void setup_local_APIC (void); extern void init_apic_mappings (void); -extern void smp_local_timer_interrupt (void); +extern void smp_local_timer_interrupt (struct pt_regs * regs); extern void setup_boot_APIC_clock (void); extern void setup_secondary_APIC_clock (void); extern int APIC_init_uniprocessor (void); diff --git a/trunk/include/asm-x86_64/device.h b/trunk/include/asm-x86_64/device.h deleted file mode 100644 index 3afa03f33a36..000000000000 --- a/trunk/include/asm-x86_64/device.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Arch specific extensions to struct device - * - * This file is released under the GPLv2 - */ -#ifndef _ASM_X86_64_DEVICE_H -#define _ASM_X86_64_DEVICE_H - -struct dev_archdata { -#ifdef CONFIG_ACPI - void *acpi_handle; -#endif -}; - -#endif /* _ASM_X86_64_DEVICE_H */ diff --git a/trunk/include/asm-x86_64/floppy.h b/trunk/include/asm-x86_64/floppy.h index 6ea13c3806f3..32ff5d132714 100644 --- a/trunk/include/asm-x86_64/floppy.h +++ b/trunk/include/asm-x86_64/floppy.h @@ -51,7 +51,7 @@ static char *virtual_dma_addr; static int virtual_dma_mode; static int doing_pdma; -static irqreturn_t floppy_hardint(int irq, void *dev_id) +static irqreturn_t floppy_hardint(int irq, void *dev_id, struct pt_regs * regs) { register unsigned char st; @@ -63,7 +63,7 @@ static irqreturn_t floppy_hardint(int irq, void *dev_id) static int dma_wait=0; #endif if (!doing_pdma) - return floppy_interrupt(irq, dev_id); + return floppy_interrupt(irq, dev_id, regs); #ifdef TRACE_FLPY_INT if(!calls) @@ -106,7 +106,7 @@ static irqreturn_t floppy_hardint(int irq, void *dev_id) dma_wait=0; #endif doing_pdma = 0; - floppy_interrupt(irq, dev_id); + floppy_interrupt(irq, dev_id, regs); return IRQ_HANDLED; } #ifdef TRACE_FLPY_INT diff --git a/trunk/include/asm-x86_64/genapic.h b/trunk/include/asm-x86_64/genapic.h index a0e9a4b93484..81e714665344 100644 --- a/trunk/include/asm-x86_64/genapic.h +++ b/trunk/include/asm-x86_64/genapic.h @@ -18,7 +18,6 @@ struct genapic { u32 int_dest_mode; int (*apic_id_registered)(void); cpumask_t (*target_cpus)(void); - cpumask_t (*vector_allocation_domain)(int cpu); void (*init_apic_ldr)(void); /* ipi */ void (*send_IPI_mask)(cpumask_t mask, int vector); diff --git a/trunk/include/asm-x86_64/hw_irq.h b/trunk/include/asm-x86_64/hw_irq.h index 179cce755aa7..53d0d9fd10d6 100644 --- a/trunk/include/asm-x86_64/hw_irq.h +++ b/trunk/include/asm-x86_64/hw_irq.h @@ -74,10 +74,10 @@ #ifndef __ASSEMBLY__ +extern unsigned int irq_vector[NR_IRQ_VECTORS]; typedef int vector_irq_t[NR_VECTORS]; DECLARE_PER_CPU(vector_irq_t, vector_irq); -extern void __setup_vector_irq(int cpu); -extern spinlock_t vector_lock; +#define IO_APIC_VECTOR(irq) (irq_vector[irq]) /* * Various low-level irq details needed by irq.c, process.c, diff --git a/trunk/include/asm-x86_64/io.h b/trunk/include/asm-x86_64/io.h index 6ee9fadaaacb..70e91fe76344 100644 --- a/trunk/include/asm-x86_64/io.h +++ b/trunk/include/asm-x86_64/io.h @@ -254,6 +254,33 @@ void memset_io(volatile void __iomem *a, int b, size_t c); #define eth_io_copy_and_sum(a,b,c,d) eth_copy_and_sum((a),(void *)(b),(c),(d)) +/** + * check_signature - find BIOS signatures + * @io_addr: mmio address to check + * @signature: signature block + * @length: length of signature + * + * Perform a signature comparison with the mmio address io_addr. This + * address should have been obtained by ioremap. + * Returns 1 on a match. + */ + +static inline int check_signature(void __iomem *io_addr, + const unsigned char *signature, int length) +{ + int retval = 0; + do { + if (readb(io_addr) != *signature) + goto out; + io_addr++; + signature++; + length--; + } while (length); + retval = 1; +out: + return retval; +} + /* Nothing to do */ #define dma_cache_inv(_start,_size) do { } while (0) diff --git a/trunk/include/asm-x86_64/io_apic.h b/trunk/include/asm-x86_64/io_apic.h index 561ecbfd4cb5..171ec2dc8c04 100644 --- a/trunk/include/asm-x86_64/io_apic.h +++ b/trunk/include/asm-x86_64/io_apic.h @@ -12,6 +12,10 @@ #define APIC_MISMATCH_DEBUG +#define IO_APIC_BASE(idx) \ + ((volatile int *)(__fix_to_virt(FIX_IO_APIC_BASE_0 + idx) \ + + (mp_ioapics[idx].mpc_apicaddr & ~PAGE_MASK))) + /* * The structure of the IO-APIC: */ @@ -115,6 +119,36 @@ extern struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES]; /* non-0 if default (table-less) MP configuration */ extern int mpc_default_type; +static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg) +{ + *IO_APIC_BASE(apic) = reg; + return *(IO_APIC_BASE(apic)+4); +} + +static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned int value) +{ + *IO_APIC_BASE(apic) = reg; + *(IO_APIC_BASE(apic)+4) = value; +} + +/* + * Re-write a value: to be used for read-modify-write + * cycles where the read already set up the index register. + */ +static inline void io_apic_modify(unsigned int apic, unsigned int value) +{ + *(IO_APIC_BASE(apic)+4) = value; +} + +/* + * Synchronize the IO-APIC and the CPU by doing + * a dummy read from the IO-APIC + */ +static inline void io_apic_sync(unsigned int apic) +{ + (void) *(IO_APIC_BASE(apic)+4); +} + /* 1 if "noapic" boot option passed */ extern int skip_ioapic_setup; diff --git a/trunk/include/asm-x86_64/irq_regs.h b/trunk/include/asm-x86_64/irq_regs.h deleted file mode 100644 index 3dd9c0b70270..000000000000 --- a/trunk/include/asm-x86_64/irq_regs.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/include/asm-x86_64/mach_apic.h b/trunk/include/asm-x86_64/mach_apic.h index 7b7115a0c1c9..d33422450c00 100644 --- a/trunk/include/asm-x86_64/mach_apic.h +++ b/trunk/include/asm-x86_64/mach_apic.h @@ -17,7 +17,6 @@ #define INT_DELIVERY_MODE (genapic->int_delivery_mode) #define INT_DEST_MODE (genapic->int_dest_mode) #define TARGET_CPUS (genapic->target_cpus()) -#define vector_allocation_domain (genapic->vector_allocation_domain) #define apic_id_registered (genapic->apic_id_registered) #define init_apic_ldr (genapic->init_apic_ldr) #define send_IPI_mask (genapic->send_IPI_mask) diff --git a/trunk/include/asm-x86_64/pda.h b/trunk/include/asm-x86_64/pda.h index 5642634843c4..14996d962bac 100644 --- a/trunk/include/asm-x86_64/pda.h +++ b/trunk/include/asm-x86_64/pda.h @@ -109,15 +109,6 @@ extern struct x8664_pda _proxy_pda; #define sub_pda(field,val) pda_to_op("sub",field,val) #define or_pda(field,val) pda_to_op("or",field,val) -/* This is not atomic against other CPUs -- CPU preemption needs to be off */ -#define test_and_clear_bit_pda(bit,field) ({ \ - int old__; \ - asm volatile("btr %2,%%gs:%c3\n\tsbbl %0,%0" \ - : "=r" (old__), "+m" (_proxy_pda.field) \ - : "dIr" (bit), "i" (pda_offset(field)) : "memory"); \ - old__; \ -}) - #endif #define PDA_STACKOFFSET (5*8) diff --git a/trunk/include/asm-x86_64/percpu.h b/trunk/include/asm-x86_64/percpu.h index 5ed0ef340842..285756010c51 100644 --- a/trunk/include/asm-x86_64/percpu.h +++ b/trunk/include/asm-x86_64/percpu.h @@ -32,13 +32,13 @@ /* var is in discarded region: offset to particular copy we want */ #define per_cpu(var, cpu) (*({ \ - extern int simple_identifier_##var(void); \ + extern int simple_indentifier_##var(void); \ RELOC_HIDE(&per_cpu__##var, __per_cpu_offset(cpu)); })) #define __get_cpu_var(var) (*({ \ - extern int simple_identifier_##var(void); \ + extern int simple_indentifier_##var(void); \ RELOC_HIDE(&per_cpu__##var, __my_cpu_offset()); })) #define __raw_get_cpu_var(var) (*({ \ - extern int simple_identifier_##var(void); \ + extern int simple_indentifier_##var(void); \ RELOC_HIDE(&per_cpu__##var, __my_cpu_offset()); })) /* A macro to avoid #include hell... */ diff --git a/trunk/include/asm-x86_64/pgtable.h b/trunk/include/asm-x86_64/pgtable.h index 0555c1c4d8fa..6899e770b173 100644 --- a/trunk/include/asm-x86_64/pgtable.h +++ b/trunk/include/asm-x86_64/pgtable.h @@ -366,7 +366,6 @@ static inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot) { pte_t pte; pte_val(pte) = physpage | pgprot_val(pgprot); - pte_val(pte) &= __supported_pte_mask; return pte; } diff --git a/trunk/include/asm-x86_64/processor.h b/trunk/include/asm-x86_64/processor.h index cef17e0f828c..de9c3147ee4c 100644 --- a/trunk/include/asm-x86_64/processor.h +++ b/trunk/include/asm-x86_64/processor.h @@ -475,8 +475,6 @@ static inline void __mwait(unsigned long eax, unsigned long ecx) : :"a" (eax), "c" (ecx)); } -extern void mwait_idle_with_hints(unsigned long eax, unsigned long ecx); - #define stack_current() \ ({ \ struct thread_info *ti; \ diff --git a/trunk/include/asm-x86_64/proto.h b/trunk/include/asm-x86_64/proto.h index e72cfcdf5344..c28fc2db2171 100644 --- a/trunk/include/asm-x86_64/proto.h +++ b/trunk/include/asm-x86_64/proto.h @@ -66,7 +66,7 @@ extern void free_bootmem_generic(unsigned long phys, unsigned len); extern void load_gs_index(unsigned gs); extern void stop_timer_interrupt(void); -extern void main_timer_handler(void); +extern void main_timer_handler(struct pt_regs *regs); extern unsigned long end_pfn_map; @@ -122,11 +122,9 @@ extern int fix_aperture; extern int reboot_force; extern int notsc_setup(char *); -extern int timer_over_8254; - extern int gsi_irq_sharing(int gsi); -extern void smp_local_timer_interrupt(void); +extern void smp_local_timer_interrupt(struct pt_regs * regs); long do_arch_prctl(struct task_struct *task, int code, unsigned long addr); diff --git a/trunk/include/asm-x86_64/vsyscall.h b/trunk/include/asm-x86_64/vsyscall.h index 01d1c17e2849..fd452fc2c037 100644 --- a/trunk/include/asm-x86_64/vsyscall.h +++ b/trunk/include/asm-x86_64/vsyscall.h @@ -59,6 +59,8 @@ extern seqlock_t xtime_lock; extern int sysctl_vsyscall; +extern void vsyscall_set_cpu(int cpu); + #define ARCH_HAVE_XTIME_LOCK 1 #endif /* __KERNEL__ */ diff --git a/trunk/include/asm-xtensa/device.h b/trunk/include/asm-xtensa/device.h deleted file mode 100644 index d8f9872b0e2d..000000000000 --- a/trunk/include/asm-xtensa/device.h +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Arch specific extensions to struct device - * - * This file is released under the GPLv2 - */ -#include - diff --git a/trunk/include/linux/Kbuild b/trunk/include/linux/Kbuild index a1155a2beb32..5114ff18101d 100644 --- a/trunk/include/linux/Kbuild +++ b/trunk/include/linux/Kbuild @@ -120,7 +120,6 @@ header-y += netrom.h header-y += nfs2.h header-y += nfs4_mount.h header-y += nfs_mount.h -header-y += oom.h header-y += param.h header-y += pci_ids.h header-y += pci_regs.h diff --git a/trunk/include/linux/acpi.h b/trunk/include/linux/acpi.h index 2b0c955590fe..88b5dfd8ee12 100644 --- a/trunk/include/linux/acpi.h +++ b/trunk/include/linux/acpi.h @@ -494,9 +494,6 @@ void acpi_pci_unregister_driver(struct acpi_pci_driver *driver); extern int ec_read(u8 addr, u8 *val); extern int ec_write(u8 addr, u8 val); -extern int ec_transaction(u8 command, - const u8 *wdata, unsigned wdata_len, - u8 *rdata, unsigned rdata_len); #endif /*CONFIG_ACPI_EC*/ diff --git a/trunk/include/linux/adb.h b/trunk/include/linux/adb.h index 64d8878e1444..b7305b178279 100644 --- a/trunk/include/linux/adb.h +++ b/trunk/include/linux/adb.h @@ -90,10 +90,10 @@ extern struct blocking_notifier_head adb_client_list; int adb_request(struct adb_request *req, void (*done)(struct adb_request *), int flags, int nbytes, ...); int adb_register(int default_id,int handler_id,struct adb_ids *ids, - void (*handler)(unsigned char *, int, int)); + void (*handler)(unsigned char *, int, struct pt_regs *, int)); int adb_unregister(int index); void adb_poll(void); -void adb_input(unsigned char *, int, int); +void adb_input(unsigned char *, int, struct pt_regs *, int); int adb_reset_bus(void); int adb_try_handler_change(int address, int new_id); diff --git a/trunk/include/linux/arcdevice.h b/trunk/include/linux/arcdevice.h index 2f85049cfb3d..231ba090ae34 100644 --- a/trunk/include/linux/arcdevice.h +++ b/trunk/include/linux/arcdevice.h @@ -334,7 +334,7 @@ void arcnet_dump_skb(struct net_device *dev, struct sk_buff *skb, char *desc); #endif void arcnet_unregister_proto(struct ArcProto *proto); -irqreturn_t arcnet_interrupt(int irq, void *dev_id); +irqreturn_t arcnet_interrupt(int irq, void *dev_id, struct pt_regs *regs); struct net_device *alloc_arcdev(char *name); #endif /* __KERNEL__ */ diff --git a/trunk/include/linux/backing-dev.h b/trunk/include/linux/backing-dev.h index 7011d6255593..f7a1390d67f5 100644 --- a/trunk/include/linux/backing-dev.h +++ b/trunk/include/linux/backing-dev.h @@ -10,8 +10,6 @@ #include -struct page; - /* * Bits in backing_dev_info.state */ @@ -90,11 +88,6 @@ static inline int bdi_rw_congested(struct backing_dev_info *bdi) (1 << BDI_write_congested)); } -void clear_bdi_congested(struct backing_dev_info *bdi, int rw); -void set_bdi_congested(struct backing_dev_info *bdi, int rw); -long congestion_wait(int rw, long timeout); -void congestion_end(int rw); - #define bdi_cap_writeback_dirty(bdi) \ (!((bdi)->capabilities & BDI_CAP_NO_WRITEBACK)) diff --git a/trunk/include/linux/bitmap.h b/trunk/include/linux/bitmap.h index 64b4641904fe..dcc5de7cc487 100644 --- a/trunk/include/linux/bitmap.h +++ b/trunk/include/linux/bitmap.h @@ -46,8 +46,7 @@ * bitmap_remap(dst, src, old, new, nbits) *dst = map(old, new)(src) * bitmap_bitremap(oldbit, old, new, nbits) newbit = map(old, new)(oldbit) * bitmap_scnprintf(buf, len, src, nbits) Print bitmap src to buf - * bitmap_parse(buf, buflen, dst, nbits) Parse bitmap dst from kernel buf - * bitmap_parse_user(ubuf, ulen, dst, nbits) Parse bitmap dst from user buf + * bitmap_parse(ubuf, ulen, dst, nbits) Parse bitmap dst from user buf * bitmap_scnlistprintf(buf, len, src, nbits) Print bitmap src as list to buf * bitmap_parselist(buf, dst, nbits) Parse bitmap dst from list * bitmap_find_free_region(bitmap, bits, order) Find and allocate bit region @@ -107,9 +106,7 @@ extern int __bitmap_weight(const unsigned long *bitmap, int bits); extern int bitmap_scnprintf(char *buf, unsigned int len, const unsigned long *src, int nbits); -extern int __bitmap_parse(const char *buf, unsigned int buflen, int is_user, - unsigned long *dst, int nbits); -extern int bitmap_parse_user(const char __user *ubuf, unsigned int ulen, +extern int bitmap_parse(const char __user *ubuf, unsigned int ulen, unsigned long *dst, int nbits); extern int bitmap_scnlistprintf(char *buf, unsigned int len, const unsigned long *src, int nbits); @@ -273,12 +270,6 @@ static inline void bitmap_shift_left(unsigned long *dst, __bitmap_shift_left(dst, src, n, nbits); } -static inline int bitmap_parse(const char *buf, unsigned int buflen, - unsigned long *maskp, int nmaskbits) -{ - return __bitmap_parse(buf, buflen, 0, maskp, nmaskbits); -} - #endif /* __ASSEMBLY__ */ #endif /* __LINUX_BITMAP_H */ diff --git a/trunk/include/linux/blkdev.h b/trunk/include/linux/blkdev.h index e1c7286165ff..26f7856ff812 100644 --- a/trunk/include/linux/blkdev.h +++ b/trunk/include/linux/blkdev.h @@ -157,7 +157,6 @@ enum rq_cmd_type_bits { REQ_TYPE_ATA_CMD, REQ_TYPE_ATA_TASK, REQ_TYPE_ATA_TASKFILE, - REQ_TYPE_ATA_PC, }; /* @@ -651,26 +650,6 @@ extern void blk_recount_segments(request_queue_t *, struct bio *); extern int scsi_cmd_ioctl(struct file *, struct gendisk *, unsigned int, void __user *); extern int sg_scsi_ioctl(struct file *, struct request_queue *, struct gendisk *, struct scsi_ioctl_command __user *); - -/* - * A queue has just exitted congestion. Note this in the global counter of - * congested queues, and wake up anyone who was waiting for requests to be - * put back. - */ -static inline void blk_clear_queue_congested(request_queue_t *q, int rw) -{ - clear_bdi_congested(&q->backing_dev_info, rw); -} - -/* - * A queue has just entered congestion. Flag that in the queue's VM-visible - * state flags and increment the global gounter of congested queues. - */ -static inline void blk_set_queue_congested(request_queue_t *q, int rw) -{ - set_bdi_congested(&q->backing_dev_info, rw); -} - extern void blk_start_queue(request_queue_t *q); extern void blk_stop_queue(request_queue_t *q); extern void blk_sync_queue(struct request_queue *q); @@ -678,11 +657,10 @@ extern void __blk_stop_queue(request_queue_t *q); extern void blk_run_queue(request_queue_t *); extern void blk_start_queueing(request_queue_t *); extern void blk_queue_activity_fn(request_queue_t *, activity_fn *, void *); -extern int blk_rq_map_user(request_queue_t *, struct request *, void __user *, unsigned long); -extern int blk_rq_unmap_user(struct request *); +extern int blk_rq_map_user(request_queue_t *, struct request *, void __user *, unsigned int); +extern int blk_rq_unmap_user(struct bio *, unsigned int); extern int blk_rq_map_kern(request_queue_t *, struct request *, void *, unsigned int, gfp_t); -extern int blk_rq_map_user_iov(request_queue_t *, struct request *, - struct sg_iovec *, int, unsigned int); +extern int blk_rq_map_user_iov(request_queue_t *, struct request *, struct sg_iovec *, int); extern int blk_execute_rq(request_queue_t *, struct gendisk *, struct request *, int); extern void blk_execute_rq_nowait(request_queue_t *, struct gendisk *, @@ -786,8 +764,10 @@ extern int blk_queue_init_tags(request_queue_t *, int, struct blk_queue_tag *); extern void blk_queue_free_tags(request_queue_t *); extern int blk_queue_resize_tags(request_queue_t *, int); extern void blk_queue_invalidate_tags(request_queue_t *); +extern long blk_congestion_wait(int rw, long timeout); extern struct blk_queue_tag *blk_init_tags(int); extern void blk_free_tags(struct blk_queue_tag *); +extern void blk_congestion_end(int rw); static inline struct request *blk_map_queue_find_tag(struct blk_queue_tag *bqt, int tag) diff --git a/trunk/include/linux/blktrace_api.h b/trunk/include/linux/blktrace_api.h index 3680ff9a30ed..b99a714fcac6 100644 --- a/trunk/include/linux/blktrace_api.h +++ b/trunk/include/linux/blktrace_api.h @@ -49,15 +49,6 @@ enum blktrace_act { __BLK_TA_REMAP, /* bio was remapped */ }; -/* - * Notify events. - */ -enum blktrace_notify { - __BLK_TN_PROCESS = 0, /* establish pid/name mapping */ - __BLK_TN_TIMESTAMP, /* include system clock */ -}; - - /* * Trace actions in full. Additionally, read or write is masked */ @@ -77,9 +68,6 @@ enum blktrace_notify { #define BLK_TA_BOUNCE (__BLK_TA_BOUNCE) #define BLK_TA_REMAP (__BLK_TA_REMAP | BLK_TC_ACT(BLK_TC_QUEUE)) -#define BLK_TN_PROCESS (__BLK_TN_PROCESS | BLK_TC_ACT(BLK_TC_NOTIFY)) -#define BLK_TN_TIMESTAMP (__BLK_TN_TIMESTAMP | BLK_TC_ACT(BLK_TC_NOTIFY)) - #define BLK_IO_TRACE_MAGIC 0x65617400 #define BLK_IO_TRACE_VERSION 0x07 diff --git a/trunk/include/linux/buffer_head.h b/trunk/include/linux/buffer_head.h index 5d9fb0e94156..131ffd37e716 100644 --- a/trunk/include/linux/buffer_head.h +++ b/trunk/include/linux/buffer_head.h @@ -69,8 +69,6 @@ struct buffer_head { bh_end_io_t *b_end_io; /* I/O completion */ void *b_private; /* reserved for b_end_io */ struct list_head b_assoc_buffers; /* associated with another mapping */ - struct address_space *b_assoc_map; /* mapping this buffer is - associated with */ atomic_t b_count; /* users using this buffer_head */ }; diff --git a/trunk/include/linux/carta_random32.h b/trunk/include/linux/carta_random32.h deleted file mode 100644 index f6f3bd9f20b5..000000000000 --- a/trunk/include/linux/carta_random32.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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/cdrom.h b/trunk/include/linux/cdrom.h index bbbe7b4da0bb..3c9b0bc05123 100644 --- a/trunk/include/linux/cdrom.h +++ b/trunk/include/linux/cdrom.h @@ -749,7 +749,7 @@ struct request_sense { #define MRW_MODE_PC 0x03 struct mrw_feature_desc { - __be16 feature_code; + __u16 feature_code; #if defined(__BIG_ENDIAN_BITFIELD) __u8 reserved1 : 2; __u8 feature_version : 4; @@ -776,7 +776,7 @@ struct mrw_feature_desc { /* cf. mmc4r02g.pdf 5.3.10 Random Writable Feature (0020h) pg 197 of 635 */ struct rwrt_feature_desc { - __be16 feature_code; + __u16 feature_code; #if defined(__BIG_ENDIAN_BITFIELD) __u8 reserved1 : 2; __u8 feature_version : 4; @@ -803,7 +803,7 @@ struct rwrt_feature_desc { }; typedef struct { - __be16 disc_information_length; + __u16 disc_information_length; #if defined(__BIG_ENDIAN_BITFIELD) __u8 reserved1 : 3; __u8 erasable : 1; @@ -849,7 +849,7 @@ typedef struct { } disc_information; typedef struct { - __be16 track_information_length; + __u16 track_information_length; __u8 track_lsb; __u8 session_lsb; __u8 reserved1; @@ -880,12 +880,12 @@ typedef struct { __u8 lra_v : 1; __u8 reserved3 : 6; #endif - __be32 track_start; - __be32 next_writable; - __be32 free_blocks; - __be32 fixed_packet_size; - __be32 track_size; - __be32 last_rec_address; + __u32 track_start; + __u32 next_writable; + __u32 free_blocks; + __u32 fixed_packet_size; + __u32 track_size; + __u32 last_rec_address; } track_information; struct feature_header { @@ -896,12 +896,12 @@ struct feature_header { }; struct mode_page_header { - __be16 mode_data_length; + __u16 mode_data_length; __u8 medium_type; __u8 reserved1; __u8 reserved2; __u8 reserved3; - __be16 desc_length; + __u16 desc_length; }; #ifdef __KERNEL__ @@ -1106,7 +1106,7 @@ typedef struct { #endif __u8 session_format; __u8 reserved6; - __be32 packet_size; + __u32 packet_size; __u16 audio_pause; __u8 mcn[16]; __u8 isrc[16]; @@ -1151,7 +1151,7 @@ typedef struct { } rpc_state_t; struct event_header { - __be16 data_len; + __u16 data_len; #if defined(__BIG_ENDIAN_BITFIELD) __u8 nea : 1; __u8 reserved1 : 4; diff --git a/trunk/include/linux/compat.h b/trunk/include/linux/compat.h index 80b17f440ec1..ef5cd192784c 100644 --- a/trunk/include/linux/compat.h +++ b/trunk/include/linux/compat.h @@ -163,7 +163,7 @@ asmlinkage long compat_sys_set_robust_list(struct compat_robust_list_head __user *head, compat_size_t len); asmlinkage long -compat_sys_get_robust_list(int pid, compat_uptr_t __user *head_ptr, +compat_sys_get_robust_list(int pid, compat_uptr_t *head_ptr, compat_size_t __user *len_ptr); long compat_sys_semctl(int first, int second, int third, void __user *uptr); @@ -196,7 +196,7 @@ asmlinkage long compat_sys_select(int n, compat_ulong_t __user *inp, #define BITS_TO_COMPAT_LONGS(bits) \ (((bits)+BITS_PER_COMPAT_LONG-1)/BITS_PER_COMPAT_LONG) -long compat_get_bitmap(unsigned long *mask, const compat_ulong_t __user *umask, +long compat_get_bitmap(unsigned long *mask, compat_ulong_t __user *umask, unsigned long bitmap_size); long compat_put_bitmap(compat_ulong_t __user *umask, unsigned long *mask, unsigned long bitmap_size); @@ -230,9 +230,5 @@ asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp); extern int compat_printk(const char *fmt, ...); extern void sigset_from_compat(sigset_t *set, compat_sigset_t *compat); -asmlinkage long compat_sys_migrate_pages(compat_pid_t pid, - compat_ulong_t maxnode, const compat_ulong_t __user *old_nodes, - const compat_ulong_t __user *new_nodes); - #endif /* CONFIG_COMPAT */ #endif /* _LINUX_COMPAT_H */ diff --git a/trunk/include/linux/compat_ioctl.h b/trunk/include/linux/compat_ioctl.h index c26c3adcfacf..4e1663d7691e 100644 --- a/trunk/include/linux/compat_ioctl.h +++ b/trunk/include/linux/compat_ioctl.h @@ -61,23 +61,17 @@ COMPATIBLE_IOCTL(FIGETBSZ) * Some need translations, these do not. */ COMPATIBLE_IOCTL(HDIO_GET_IDENTITY) -COMPATIBLE_IOCTL(HDIO_DRIVE_TASK) +COMPATIBLE_IOCTL(HDIO_SET_DMA) +COMPATIBLE_IOCTL(HDIO_SET_UNMASKINTR) +COMPATIBLE_IOCTL(HDIO_SET_NOWERR) +COMPATIBLE_IOCTL(HDIO_SET_32BIT) +COMPATIBLE_IOCTL(HDIO_SET_MULTCOUNT) COMPATIBLE_IOCTL(HDIO_DRIVE_CMD) -ULONG_IOCTL(HDIO_SET_MULTCOUNT) -ULONG_IOCTL(HDIO_SET_UNMASKINTR) -ULONG_IOCTL(HDIO_SET_KEEPSETTINGS) -ULONG_IOCTL(HDIO_SET_32BIT) -ULONG_IOCTL(HDIO_SET_NOWERR) -ULONG_IOCTL(HDIO_SET_DMA) -ULONG_IOCTL(HDIO_SET_PIO_MODE) -ULONG_IOCTL(HDIO_SET_NICE) -ULONG_IOCTL(HDIO_SET_WCACHE) -ULONG_IOCTL(HDIO_SET_ACOUSTIC) -ULONG_IOCTL(HDIO_SET_BUSSTATE) -ULONG_IOCTL(HDIO_SET_ADDRESS) +COMPATIBLE_IOCTL(HDIO_DRIVE_TASK) +COMPATIBLE_IOCTL(HDIO_SET_PIO_MODE) +COMPATIBLE_IOCTL(HDIO_SET_NICE) +COMPATIBLE_IOCTL(HDIO_SET_KEEPSETTINGS) COMPATIBLE_IOCTL(HDIO_SCAN_HWIF) -/* 0x330 is reserved -- it used to be HDIO_GETGEO_BIG */ -COMPATIBLE_IOCTL(0x330) /* 0x02 -- Floppy ioctls */ COMPATIBLE_IOCTL(FDMSGON) COMPATIBLE_IOCTL(FDMSGOFF) @@ -131,7 +125,6 @@ COMPATIBLE_IOCTL(RUN_ARRAY) COMPATIBLE_IOCTL(STOP_ARRAY) COMPATIBLE_IOCTL(STOP_ARRAY_RO) COMPATIBLE_IOCTL(RESTART_ARRAY_RW) -COMPATIBLE_IOCTL(GET_BITMAP_FILE) ULONG_IOCTL(SET_BITMAP_FILE) /* DM */ COMPATIBLE_IOCTL(DM_VERSION_32) diff --git a/trunk/include/linux/config.h b/trunk/include/linux/config.h new file mode 100644 index 000000000000..479ffb0a22d8 --- /dev/null +++ b/trunk/include/linux/config.h @@ -0,0 +1,9 @@ +#ifndef _LINUX_CONFIG_H +#define _LINUX_CONFIG_H +/* This file is no longer in use and kept only for backward compatibility. + * autoconf.h is now included via -imacros on the commandline + */ +#warning Including config.h is deprecated. +#include + +#endif diff --git a/trunk/include/linux/cpumask.h b/trunk/include/linux/cpumask.h index d0e8c8b0e34d..b268a3c0c376 100644 --- a/trunk/include/linux/cpumask.h +++ b/trunk/include/linux/cpumask.h @@ -8,8 +8,8 @@ * See detailed comments in the file linux/bitmap.h describing the * data type on which these cpumasks are based. * - * For details of cpumask_scnprintf() and cpumask_parse_user(), - * see bitmap_scnprintf() and bitmap_parse_user() in lib/bitmap.c. + * For details of cpumask_scnprintf() and cpumask_parse(), + * see bitmap_scnprintf() and bitmap_parse() in lib/bitmap.c. * For details of cpulist_scnprintf() and cpulist_parse(), see * bitmap_scnlistprintf() and bitmap_parselist(), also in bitmap.c. * For details of cpu_remap(), see bitmap_bitremap in lib/bitmap.c @@ -49,7 +49,7 @@ * unsigned long *cpus_addr(mask) Array of unsigned long's in mask * * int cpumask_scnprintf(buf, len, mask) Format cpumask for printing - * int cpumask_parse_user(ubuf, ulen, mask) Parse ascii string as cpumask + * int cpumask_parse(ubuf, ulen, mask) Parse ascii string as cpumask * int cpulist_scnprintf(buf, len, mask) Format cpumask as list for printing * int cpulist_parse(buf, map) Parse ascii string as cpulist * int cpu_remap(oldbit, old, new) newbit = map(old, new)(oldbit) @@ -273,12 +273,12 @@ static inline int __cpumask_scnprintf(char *buf, int len, return bitmap_scnprintf(buf, len, srcp->bits, nbits); } -#define cpumask_parse_user(ubuf, ulen, dst) \ - __cpumask_parse_user((ubuf), (ulen), &(dst), NR_CPUS) -static inline int __cpumask_parse_user(const char __user *buf, int len, +#define cpumask_parse(ubuf, ulen, dst) \ + __cpumask_parse((ubuf), (ulen), &(dst), NR_CPUS) +static inline int __cpumask_parse(const char __user *buf, int len, cpumask_t *dstp, int nbits) { - return bitmap_parse_user(buf, len, dstp->bits, nbits); + return bitmap_parse(buf, len, dstp->bits, nbits); } #define cpulist_scnprintf(buf, len, src) \ diff --git a/trunk/include/linux/crypto.h b/trunk/include/linux/crypto.h index 6485e9716b36..8f2ffa4caabf 100644 --- a/trunk/include/linux/crypto.h +++ b/trunk/include/linux/crypto.h @@ -245,7 +245,7 @@ int crypto_alg_available(const char *name, u32 flags) __deprecated_for_modules; int crypto_has_alg(const char *name, u32 type, u32 mask); #else -static int crypto_alg_available(const char *name, u32 flags) +static int crypto_alg_available(const char *name, u32 flags); __deprecated_for_modules; static inline int crypto_alg_available(const char *name, u32 flags) { diff --git a/trunk/include/linux/dcache.h b/trunk/include/linux/dcache.h index 63f64a9a5bf7..44605be59409 100644 --- a/trunk/include/linux/dcache.h +++ b/trunk/include/linux/dcache.h @@ -230,7 +230,6 @@ extern struct dentry * d_alloc_anon(struct inode *); extern struct dentry * d_splice_alias(struct inode *, struct dentry *); extern void shrink_dcache_sb(struct super_block *); extern void shrink_dcache_parent(struct dentry *); -extern void shrink_dcache_for_umount(struct super_block *); extern int d_invalidate(struct dentry *); /* only used at mount-time */ diff --git a/trunk/include/linux/dccp.h b/trunk/include/linux/dccp.h index 53553c99cad6..d6f4ec467a4b 100644 --- a/trunk/include/linux/dccp.h +++ b/trunk/include/linux/dccp.h @@ -191,7 +191,7 @@ enum { /* this structure is argument to DCCP_SOCKOPT_CHANGE_X */ struct dccp_so_feat { __u8 dccpsf_feat; - __u8 __user *dccpsf_val; + __u8 *dccpsf_val; __u8 dccpsf_len; }; diff --git a/trunk/include/linux/device.h b/trunk/include/linux/device.h index 583a341e016c..662e6a10144e 100644 --- a/trunk/include/linux/device.h +++ b/trunk/include/linux/device.h @@ -21,7 +21,6 @@ #include #include #include -#include #define DEVICE_NAME_SIZE 50 #define DEVICE_NAME_HALF __stringify(20) /* Less than half to accommodate slop */ @@ -43,8 +42,6 @@ struct bus_type { struct klist klist_devices; struct klist klist_drivers; - struct blocking_notifier_head bus_notifier; - struct bus_attribute * bus_attrs; struct device_attribute * dev_attrs; struct driver_attribute * drv_attrs; @@ -78,29 +75,6 @@ int __must_check bus_for_each_drv(struct bus_type *bus, struct device_driver *start, void *data, int (*fn)(struct device_driver *, void *)); -/* - * Bus notifiers: Get notified of addition/removal of devices - * and binding/unbinding of drivers to devices. - * In the long run, it should be a replacement for the platform - * notify hooks. - */ -struct notifier_block; - -extern int bus_register_notifier(struct bus_type *bus, - struct notifier_block *nb); -extern int bus_unregister_notifier(struct bus_type *bus, - struct notifier_block *nb); - -/* All 4 notifers below get called with the target struct device * - * as an argument. Note that those functions are likely to be called - * with the device semaphore held in the core, so be careful. - */ -#define BUS_NOTIFY_ADD_DEVICE 0x00000001 /* device added */ -#define BUS_NOTIFY_DEL_DEVICE 0x00000002 /* device removed */ -#define BUS_NOTIFY_BOUND_DRIVER 0x00000003 /* driver bound to device */ -#define BUS_NOTIFY_UNBIND_DRIVER 0x00000004 /* driver about to be - unbound */ - /* driverfs interface for exporting bus attributes */ struct bus_attribute { @@ -369,6 +343,8 @@ struct device { void *driver_data; /* data private to the driver */ void *platform_data; /* Platform specific data, device core doesn't touch it */ + void *firmware_data; /* Firmware specific data (e.g. ACPI, + BIOS data),reserved for device core*/ struct dev_pm_info power; u64 *dma_mask; /* dma mask (if dma'able device) */ @@ -382,8 +358,6 @@ struct device { struct dma_coherent_mem *dma_mem; /* internal for coherent mem override */ - /* arch specific additions */ - struct dev_archdata archdata; /* class_device migration path */ struct list_head node; @@ -419,12 +393,9 @@ extern void device_unregister(struct device * dev); extern void device_initialize(struct device * dev); extern int __must_check device_add(struct device * dev); extern void device_del(struct device * dev); -extern int device_for_each_child(struct device *, void *, +extern int __must_check device_for_each_child(struct device *, void *, int (*fn)(struct device *, void *)); -extern struct device *device_find_child(struct device *, void *data, - int (*match)(struct device *, void *)); extern int device_rename(struct device *dev, char *new_name); -extern int device_move(struct device *dev, struct device *new_parent); /* * Manual binding of a device to driver. See drivers/base/bus.c @@ -444,6 +415,8 @@ extern struct device *device_create(struct class *cls, struct device *parent, __attribute__((format(printf,4,5))); extern void device_destroy(struct class *cls, dev_t devt); +extern int virtual_device_parent(struct device *dev); + /* * Platform "fixup" functions - allow the platform to have their say * about devices and actions that the general device layer doesn't diff --git a/trunk/include/linux/dmi.h b/trunk/include/linux/dmi.h index 904bf3d2d90b..38dc403be70b 100644 --- a/trunk/include/linux/dmi.h +++ b/trunk/include/linux/dmi.h @@ -69,7 +69,6 @@ extern struct dmi_device * dmi_find_device(int type, const char *name, struct dmi_device *from); extern void dmi_scan_machine(void); extern int dmi_get_year(int field); -extern int dmi_name_in_vendors(char *str); #else @@ -78,7 +77,6 @@ static inline char * dmi_get_system_info(int field) { return NULL; } static inline struct dmi_device * dmi_find_device(int type, const char *name, struct dmi_device *from) { return NULL; } static inline int dmi_get_year(int year) { return 0; } -static inline int dmi_name_in_vendors(char *s) { return 0; } #endif diff --git a/trunk/include/linux/elevator.h b/trunk/include/linux/elevator.h index a24931d24404..b3370ef5164d 100644 --- a/trunk/include/linux/elevator.h +++ b/trunk/include/linux/elevator.h @@ -21,11 +21,11 @@ typedef void (elevator_completed_req_fn) (request_queue_t *, struct request *); typedef int (elevator_may_queue_fn) (request_queue_t *, int); typedef int (elevator_set_req_fn) (request_queue_t *, struct request *, gfp_t); -typedef void (elevator_put_req_fn) (struct request *); +typedef void (elevator_put_req_fn) (request_queue_t *, struct request *); typedef void (elevator_activate_req_fn) (request_queue_t *, struct request *); typedef void (elevator_deactivate_req_fn) (request_queue_t *, struct request *); -typedef void *(elevator_init_fn) (request_queue_t *); +typedef void *(elevator_init_fn) (request_queue_t *, elevator_t *); typedef void (elevator_exit_fn) (elevator_t *); struct elevator_ops @@ -70,6 +70,7 @@ struct elevator_type { struct list_head list; struct elevator_ops ops; + struct elevator_type *elevator_type; struct elv_fs_entry *elevator_attrs; char elevator_name[ELV_NAME_MAX]; struct module *elevator_owner; diff --git a/trunk/include/linux/ext4_fs.h b/trunk/include/linux/ext4_fs.h deleted file mode 100644 index 498503ee613d..000000000000 --- a/trunk/include/linux/ext4_fs.h +++ /dev/null @@ -1,994 +0,0 @@ -/* - * linux/include/linux/ext4_fs.h - * - * Copyright (C) 1992, 1993, 1994, 1995 - * Remy Card (card@masi.ibp.fr) - * Laboratoire MASI - Institut Blaise Pascal - * Universite Pierre et Marie Curie (Paris VI) - * - * from - * - * linux/include/linux/minix_fs.h - * - * Copyright (C) 1991, 1992 Linus Torvalds - */ - -#ifndef _LINUX_EXT4_FS_H -#define _LINUX_EXT4_FS_H - -#include -#include -#include - -/* - * The second extended filesystem constants/structures - */ - -/* - * Define EXT4FS_DEBUG to produce debug messages - */ -#undef EXT4FS_DEBUG - -/* - * Define EXT4_RESERVATION to reserve data blocks for expanding files - */ -#define EXT4_DEFAULT_RESERVE_BLOCKS 8 -/*max window size: 1024(direct blocks) + 3([t,d]indirect blocks) */ -#define EXT4_MAX_RESERVE_BLOCKS 1027 -#define EXT4_RESERVE_WINDOW_NOT_ALLOCATED 0 -/* - * Always enable hashed directories - */ -#define CONFIG_EXT4_INDEX - -/* - * Debug code - */ -#ifdef EXT4FS_DEBUG -#define ext4_debug(f, a...) \ - do { \ - printk (KERN_DEBUG "EXT4-fs DEBUG (%s, %d): %s:", \ - __FILE__, __LINE__, __FUNCTION__); \ - printk (KERN_DEBUG f, ## a); \ - } while (0) -#else -#define ext4_debug(f, a...) do {} while (0) -#endif - -/* - * Special inodes numbers - */ -#define EXT4_BAD_INO 1 /* Bad blocks inode */ -#define EXT4_ROOT_INO 2 /* Root inode */ -#define EXT4_BOOT_LOADER_INO 5 /* Boot loader inode */ -#define EXT4_UNDEL_DIR_INO 6 /* Undelete directory inode */ -#define EXT4_RESIZE_INO 7 /* Reserved group descriptors inode */ -#define EXT4_JOURNAL_INO 8 /* Journal inode */ - -/* First non-reserved inode for old ext4 filesystems */ -#define EXT4_GOOD_OLD_FIRST_INO 11 - -/* - * Maximal count of links to a file - */ -#define EXT4_LINK_MAX 32000 - -/* - * Macro-instructions used to manage several block sizes - */ -#define EXT4_MIN_BLOCK_SIZE 1024 -#define EXT4_MAX_BLOCK_SIZE 4096 -#define EXT4_MIN_BLOCK_LOG_SIZE 10 -#ifdef __KERNEL__ -# define EXT4_BLOCK_SIZE(s) ((s)->s_blocksize) -#else -# define EXT4_BLOCK_SIZE(s) (EXT4_MIN_BLOCK_SIZE << (s)->s_log_block_size) -#endif -#define EXT4_ADDR_PER_BLOCK(s) (EXT4_BLOCK_SIZE(s) / sizeof (__u32)) -#ifdef __KERNEL__ -# define EXT4_BLOCK_SIZE_BITS(s) ((s)->s_blocksize_bits) -#else -# define EXT4_BLOCK_SIZE_BITS(s) ((s)->s_log_block_size + 10) -#endif -#ifdef __KERNEL__ -#define EXT4_ADDR_PER_BLOCK_BITS(s) (EXT4_SB(s)->s_addr_per_block_bits) -#define EXT4_INODE_SIZE(s) (EXT4_SB(s)->s_inode_size) -#define EXT4_FIRST_INO(s) (EXT4_SB(s)->s_first_ino) -#else -#define EXT4_INODE_SIZE(s) (((s)->s_rev_level == EXT4_GOOD_OLD_REV) ? \ - EXT4_GOOD_OLD_INODE_SIZE : \ - (s)->s_inode_size) -#define EXT4_FIRST_INO(s) (((s)->s_rev_level == EXT4_GOOD_OLD_REV) ? \ - EXT4_GOOD_OLD_FIRST_INO : \ - (s)->s_first_ino) -#endif - -/* - * Macro-instructions used to manage fragments - */ -#define EXT4_MIN_FRAG_SIZE 1024 -#define EXT4_MAX_FRAG_SIZE 4096 -#define EXT4_MIN_FRAG_LOG_SIZE 10 -#ifdef __KERNEL__ -# define EXT4_FRAG_SIZE(s) (EXT4_SB(s)->s_frag_size) -# define EXT4_FRAGS_PER_BLOCK(s) (EXT4_SB(s)->s_frags_per_block) -#else -# define EXT4_FRAG_SIZE(s) (EXT4_MIN_FRAG_SIZE << (s)->s_log_frag_size) -# define EXT4_FRAGS_PER_BLOCK(s) (EXT4_BLOCK_SIZE(s) / EXT4_FRAG_SIZE(s)) -#endif - -/* - * Structure of a blocks group descriptor - */ -struct ext4_group_desc -{ - __le32 bg_block_bitmap; /* Blocks bitmap block */ - __le32 bg_inode_bitmap; /* Inodes bitmap block */ - __le32 bg_inode_table; /* Inodes table block */ - __le16 bg_free_blocks_count; /* Free blocks count */ - __le16 bg_free_inodes_count; /* Free inodes count */ - __le16 bg_used_dirs_count; /* Directories count */ - __u16 bg_flags; - __u32 bg_reserved[3]; - __le32 bg_block_bitmap_hi; /* Blocks bitmap block MSB */ - __le32 bg_inode_bitmap_hi; /* Inodes bitmap block MSB */ - __le32 bg_inode_table_hi; /* Inodes table block MSB */ -}; - -#ifdef __KERNEL__ -#include -#include -#endif -/* - * Macro-instructions used to manage group descriptors - */ -#define EXT4_MIN_DESC_SIZE 32 -#define EXT4_MIN_DESC_SIZE_64BIT 64 -#define EXT4_MAX_DESC_SIZE EXT4_MIN_BLOCK_SIZE -#define EXT4_DESC_SIZE(s) (EXT4_SB(s)->s_desc_size) -#ifdef __KERNEL__ -# define EXT4_BLOCKS_PER_GROUP(s) (EXT4_SB(s)->s_blocks_per_group) -# define EXT4_DESC_PER_BLOCK(s) (EXT4_SB(s)->s_desc_per_block) -# define EXT4_INODES_PER_GROUP(s) (EXT4_SB(s)->s_inodes_per_group) -# define EXT4_DESC_PER_BLOCK_BITS(s) (EXT4_SB(s)->s_desc_per_block_bits) -#else -# define EXT4_BLOCKS_PER_GROUP(s) ((s)->s_blocks_per_group) -# define EXT4_DESC_PER_BLOCK(s) (EXT4_BLOCK_SIZE(s) / EXT4_DESC_SIZE(s)) -# define EXT4_INODES_PER_GROUP(s) ((s)->s_inodes_per_group) -#endif - -/* - * Constants relative to the data blocks - */ -#define EXT4_NDIR_BLOCKS 12 -#define EXT4_IND_BLOCK EXT4_NDIR_BLOCKS -#define EXT4_DIND_BLOCK (EXT4_IND_BLOCK + 1) -#define EXT4_TIND_BLOCK (EXT4_DIND_BLOCK + 1) -#define EXT4_N_BLOCKS (EXT4_TIND_BLOCK + 1) - -/* - * Inode flags - */ -#define EXT4_SECRM_FL 0x00000001 /* Secure deletion */ -#define EXT4_UNRM_FL 0x00000002 /* Undelete */ -#define EXT4_COMPR_FL 0x00000004 /* Compress file */ -#define EXT4_SYNC_FL 0x00000008 /* Synchronous updates */ -#define EXT4_IMMUTABLE_FL 0x00000010 /* Immutable file */ -#define EXT4_APPEND_FL 0x00000020 /* writes to file may only append */ -#define EXT4_NODUMP_FL 0x00000040 /* do not dump file */ -#define EXT4_NOATIME_FL 0x00000080 /* do not update atime */ -/* Reserved for compression usage... */ -#define EXT4_DIRTY_FL 0x00000100 -#define EXT4_COMPRBLK_FL 0x00000200 /* One or more compressed clusters */ -#define EXT4_NOCOMPR_FL 0x00000400 /* Don't compress */ -#define EXT4_ECOMPR_FL 0x00000800 /* Compression error */ -/* End compression flags --- maybe not all used */ -#define EXT4_INDEX_FL 0x00001000 /* hash-indexed directory */ -#define EXT4_IMAGIC_FL 0x00002000 /* AFS directory */ -#define EXT4_JOURNAL_DATA_FL 0x00004000 /* file data should be journaled */ -#define EXT4_NOTAIL_FL 0x00008000 /* file tail should not be merged */ -#define EXT4_DIRSYNC_FL 0x00010000 /* dirsync behaviour (directories only) */ -#define EXT4_TOPDIR_FL 0x00020000 /* Top of directory hierarchies*/ -#define EXT4_RESERVED_FL 0x80000000 /* reserved for ext4 lib */ -#define EXT4_EXTENTS_FL 0x00080000 /* Inode uses extents */ - -#define EXT4_FL_USER_VISIBLE 0x000BDFFF /* User visible flags */ -#define EXT4_FL_USER_MODIFIABLE 0x000380FF /* User modifiable flags */ - -/* - * Inode dynamic state flags - */ -#define EXT4_STATE_JDATA 0x00000001 /* journaled data exists */ -#define EXT4_STATE_NEW 0x00000002 /* inode is newly created */ -#define EXT4_STATE_XATTR 0x00000004 /* has in-inode xattrs */ - -/* Used to pass group descriptor data when online resize is done */ -struct ext4_new_group_input { - __u32 group; /* Group number for this data */ - __u64 block_bitmap; /* Absolute block number of block bitmap */ - __u64 inode_bitmap; /* Absolute block number of inode bitmap */ - __u64 inode_table; /* Absolute block number of inode table start */ - __u32 blocks_count; /* Total number of blocks in this group */ - __u16 reserved_blocks; /* Number of reserved blocks in this group */ - __u16 unused; -}; - -/* The struct ext4_new_group_input in kernel space, with free_blocks_count */ -struct ext4_new_group_data { - __u32 group; - __u64 block_bitmap; - __u64 inode_bitmap; - __u64 inode_table; - __u32 blocks_count; - __u16 reserved_blocks; - __u16 unused; - __u32 free_blocks_count; -}; - - -/* - * ioctl commands - */ -#define EXT4_IOC_GETFLAGS FS_IOC_GETFLAGS -#define EXT4_IOC_SETFLAGS FS_IOC_SETFLAGS -#define EXT4_IOC_GETVERSION _IOR('f', 3, long) -#define EXT4_IOC_SETVERSION _IOW('f', 4, long) -#define EXT4_IOC_GROUP_EXTEND _IOW('f', 7, unsigned long) -#define EXT4_IOC_GROUP_ADD _IOW('f', 8,struct ext4_new_group_input) -#define EXT4_IOC_GETVERSION_OLD FS_IOC_GETVERSION -#define EXT4_IOC_SETVERSION_OLD FS_IOC_SETVERSION -#ifdef CONFIG_JBD_DEBUG -#define EXT4_IOC_WAIT_FOR_READONLY _IOR('f', 99, long) -#endif -#define EXT4_IOC_GETRSVSZ _IOR('f', 5, long) -#define EXT4_IOC_SETRSVSZ _IOW('f', 6, long) - -/* - * ioctl commands in 32 bit emulation - */ -#define EXT4_IOC32_GETFLAGS FS_IOC32_GETFLAGS -#define EXT4_IOC32_SETFLAGS FS_IOC32_SETFLAGS -#define EXT4_IOC32_GETVERSION _IOR('f', 3, int) -#define EXT4_IOC32_SETVERSION _IOW('f', 4, int) -#define EXT4_IOC32_GETRSVSZ _IOR('f', 5, int) -#define EXT4_IOC32_SETRSVSZ _IOW('f', 6, int) -#define EXT4_IOC32_GROUP_EXTEND _IOW('f', 7, unsigned int) -#ifdef CONFIG_JBD_DEBUG -#define EXT4_IOC32_WAIT_FOR_READONLY _IOR('f', 99, int) -#endif -#define EXT4_IOC32_GETVERSION_OLD FS_IOC32_GETVERSION -#define EXT4_IOC32_SETVERSION_OLD FS_IOC32_SETVERSION - - -/* - * Mount options - */ -struct ext4_mount_options { - unsigned long s_mount_opt; - uid_t s_resuid; - gid_t s_resgid; - unsigned long s_commit_interval; -#ifdef CONFIG_QUOTA - int s_jquota_fmt; - char *s_qf_names[MAXQUOTAS]; -#endif -}; - -/* - * Structure of an inode on the disk - */ -struct ext4_inode { - __le16 i_mode; /* File mode */ - __le16 i_uid; /* Low 16 bits of Owner Uid */ - __le32 i_size; /* Size in bytes */ - __le32 i_atime; /* Access time */ - __le32 i_ctime; /* Creation time */ - __le32 i_mtime; /* Modification time */ - __le32 i_dtime; /* Deletion Time */ - __le16 i_gid; /* Low 16 bits of Group Id */ - __le16 i_links_count; /* Links count */ - __le32 i_blocks; /* Blocks count */ - __le32 i_flags; /* File flags */ - union { - struct { - __u32 l_i_reserved1; - } linux1; - struct { - __u32 h_i_translator; - } hurd1; - struct { - __u32 m_i_reserved1; - } masix1; - } osd1; /* OS dependent 1 */ - __le32 i_block[EXT4_N_BLOCKS];/* Pointers to blocks */ - __le32 i_generation; /* File version (for NFS) */ - __le32 i_file_acl; /* File ACL */ - __le32 i_dir_acl; /* Directory ACL */ - __le32 i_faddr; /* Fragment address */ - union { - struct { - __u8 l_i_frag; /* Fragment number */ - __u8 l_i_fsize; /* Fragment size */ - __le16 l_i_file_acl_high; - __le16 l_i_uid_high; /* these 2 fields */ - __le16 l_i_gid_high; /* were reserved2[0] */ - __u32 l_i_reserved2; - } linux2; - struct { - __u8 h_i_frag; /* Fragment number */ - __u8 h_i_fsize; /* Fragment size */ - __u16 h_i_mode_high; - __u16 h_i_uid_high; - __u16 h_i_gid_high; - __u32 h_i_author; - } hurd2; - struct { - __u8 m_i_frag; /* Fragment number */ - __u8 m_i_fsize; /* Fragment size */ - __le16 m_i_file_acl_high; - __u32 m_i_reserved2[2]; - } masix2; - } osd2; /* OS dependent 2 */ - __le16 i_extra_isize; - __le16 i_pad1; -}; - -#define i_size_high i_dir_acl - -#if defined(__KERNEL__) || defined(__linux__) -#define i_reserved1 osd1.linux1.l_i_reserved1 -#define i_frag osd2.linux2.l_i_frag -#define i_fsize osd2.linux2.l_i_fsize -#define i_file_acl_high osd2.linux2.l_i_file_acl_high -#define i_uid_low i_uid -#define i_gid_low i_gid -#define i_uid_high osd2.linux2.l_i_uid_high -#define i_gid_high osd2.linux2.l_i_gid_high -#define i_reserved2 osd2.linux2.l_i_reserved2 - -#elif defined(__GNU__) - -#define i_translator osd1.hurd1.h_i_translator -#define i_frag osd2.hurd2.h_i_frag; -#define i_fsize osd2.hurd2.h_i_fsize; -#define i_uid_high osd2.hurd2.h_i_uid_high -#define i_gid_high osd2.hurd2.h_i_gid_high -#define i_author osd2.hurd2.h_i_author - -#elif defined(__masix__) - -#define i_reserved1 osd1.masix1.m_i_reserved1 -#define i_frag osd2.masix2.m_i_frag -#define i_fsize osd2.masix2.m_i_fsize -#define i_file_acl_high osd2.masix2.m_i_file_acl_high -#define i_reserved2 osd2.masix2.m_i_reserved2 - -#endif /* defined(__KERNEL__) || defined(__linux__) */ - -/* - * File system states - */ -#define EXT4_VALID_FS 0x0001 /* Unmounted cleanly */ -#define EXT4_ERROR_FS 0x0002 /* Errors detected */ -#define EXT4_ORPHAN_FS 0x0004 /* Orphans being recovered */ - -/* - * Mount flags - */ -#define EXT4_MOUNT_CHECK 0x00001 /* Do mount-time checks */ -#define EXT4_MOUNT_OLDALLOC 0x00002 /* Don't use the new Orlov allocator */ -#define EXT4_MOUNT_GRPID 0x00004 /* Create files with directory's group */ -#define EXT4_MOUNT_DEBUG 0x00008 /* Some debugging messages */ -#define EXT4_MOUNT_ERRORS_CONT 0x00010 /* Continue on errors */ -#define EXT4_MOUNT_ERRORS_RO 0x00020 /* Remount fs ro on errors */ -#define EXT4_MOUNT_ERRORS_PANIC 0x00040 /* Panic on errors */ -#define EXT4_MOUNT_MINIX_DF 0x00080 /* Mimics the Minix statfs */ -#define EXT4_MOUNT_NOLOAD 0x00100 /* Don't use existing journal*/ -#define EXT4_MOUNT_ABORT 0x00200 /* Fatal error detected */ -#define EXT4_MOUNT_DATA_FLAGS 0x00C00 /* Mode for data writes: */ -#define EXT4_MOUNT_JOURNAL_DATA 0x00400 /* Write data to journal */ -#define EXT4_MOUNT_ORDERED_DATA 0x00800 /* Flush data before commit */ -#define EXT4_MOUNT_WRITEBACK_DATA 0x00C00 /* No data ordering */ -#define EXT4_MOUNT_UPDATE_JOURNAL 0x01000 /* Update the journal format */ -#define EXT4_MOUNT_NO_UID32 0x02000 /* Disable 32-bit UIDs */ -#define EXT4_MOUNT_XATTR_USER 0x04000 /* Extended user attributes */ -#define EXT4_MOUNT_POSIX_ACL 0x08000 /* POSIX Access Control Lists */ -#define EXT4_MOUNT_RESERVATION 0x10000 /* Preallocation */ -#define EXT4_MOUNT_BARRIER 0x20000 /* Use block barriers */ -#define EXT4_MOUNT_NOBH 0x40000 /* No bufferheads */ -#define EXT4_MOUNT_QUOTA 0x80000 /* Some quota option set */ -#define EXT4_MOUNT_USRQUOTA 0x100000 /* "old" user quota */ -#define EXT4_MOUNT_GRPQUOTA 0x200000 /* "old" group quota */ -#define EXT4_MOUNT_EXTENTS 0x400000 /* Extents support */ - -/* Compatibility, for having both ext2_fs.h and ext4_fs.h included at once */ -#ifndef _LINUX_EXT2_FS_H -#define clear_opt(o, opt) o &= ~EXT4_MOUNT_##opt -#define set_opt(o, opt) o |= EXT4_MOUNT_##opt -#define test_opt(sb, opt) (EXT4_SB(sb)->s_mount_opt & \ - EXT4_MOUNT_##opt) -#else -#define EXT2_MOUNT_NOLOAD EXT4_MOUNT_NOLOAD -#define EXT2_MOUNT_ABORT EXT4_MOUNT_ABORT -#define EXT2_MOUNT_DATA_FLAGS EXT4_MOUNT_DATA_FLAGS -#endif - -#define ext4_set_bit ext2_set_bit -#define ext4_set_bit_atomic ext2_set_bit_atomic -#define ext4_clear_bit ext2_clear_bit -#define ext4_clear_bit_atomic ext2_clear_bit_atomic -#define ext4_test_bit ext2_test_bit -#define ext4_find_first_zero_bit ext2_find_first_zero_bit -#define ext4_find_next_zero_bit ext2_find_next_zero_bit - -/* - * Maximal mount counts between two filesystem checks - */ -#define EXT4_DFL_MAX_MNT_COUNT 20 /* Allow 20 mounts */ -#define EXT4_DFL_CHECKINTERVAL 0 /* Don't use interval check */ - -/* - * Behaviour when detecting errors - */ -#define EXT4_ERRORS_CONTINUE 1 /* Continue execution */ -#define EXT4_ERRORS_RO 2 /* Remount fs read-only */ -#define EXT4_ERRORS_PANIC 3 /* Panic */ -#define EXT4_ERRORS_DEFAULT EXT4_ERRORS_CONTINUE - -/* - * Structure of the super block - */ -struct ext4_super_block { -/*00*/ __le32 s_inodes_count; /* Inodes count */ - __le32 s_blocks_count; /* Blocks count */ - __le32 s_r_blocks_count; /* Reserved blocks count */ - __le32 s_free_blocks_count; /* Free blocks count */ -/*10*/ __le32 s_free_inodes_count; /* Free inodes count */ - __le32 s_first_data_block; /* First Data Block */ - __le32 s_log_block_size; /* Block size */ - __le32 s_log_frag_size; /* Fragment size */ -/*20*/ __le32 s_blocks_per_group; /* # Blocks per group */ - __le32 s_frags_per_group; /* # Fragments per group */ - __le32 s_inodes_per_group; /* # Inodes per group */ - __le32 s_mtime; /* Mount time */ -/*30*/ __le32 s_wtime; /* Write time */ - __le16 s_mnt_count; /* Mount count */ - __le16 s_max_mnt_count; /* Maximal mount count */ - __le16 s_magic; /* Magic signature */ - __le16 s_state; /* File system state */ - __le16 s_errors; /* Behaviour when detecting errors */ - __le16 s_minor_rev_level; /* minor revision level */ -/*40*/ __le32 s_lastcheck; /* time of last check */ - __le32 s_checkinterval; /* max. time between checks */ - __le32 s_creator_os; /* OS */ - __le32 s_rev_level; /* Revision level */ -/*50*/ __le16 s_def_resuid; /* Default uid for reserved blocks */ - __le16 s_def_resgid; /* Default gid for reserved blocks */ - /* - * These fields are for EXT4_DYNAMIC_REV superblocks only. - * - * Note: the difference between the compatible feature set and - * the incompatible feature set is that if there is a bit set - * in the incompatible feature set that the kernel doesn't - * know about, it should refuse to mount the filesystem. - * - * e2fsck's requirements are more strict; if it doesn't know - * about a feature in either the compatible or incompatible - * feature set, it must abort and not try to meddle with - * things it doesn't understand... - */ - __le32 s_first_ino; /* First non-reserved inode */ - __le16 s_inode_size; /* size of inode structure */ - __le16 s_block_group_nr; /* block group # of this superblock */ - __le32 s_feature_compat; /* compatible feature set */ -/*60*/ __le32 s_feature_incompat; /* incompatible feature set */ - __le32 s_feature_ro_compat; /* readonly-compatible feature set */ -/*68*/ __u8 s_uuid[16]; /* 128-bit uuid for volume */ -/*78*/ char s_volume_name[16]; /* volume name */ -/*88*/ char s_last_mounted[64]; /* directory where last mounted */ -/*C8*/ __le32 s_algorithm_usage_bitmap; /* For compression */ - /* - * Performance hints. Directory preallocation should only - * happen if the EXT4_FEATURE_COMPAT_DIR_PREALLOC flag is on. - */ - __u8 s_prealloc_blocks; /* Nr of blocks to try to preallocate*/ - __u8 s_prealloc_dir_blocks; /* Nr to preallocate for dirs */ - __le16 s_reserved_gdt_blocks; /* Per group desc for online growth */ - /* - * Journaling support valid if EXT4_FEATURE_COMPAT_HAS_JOURNAL set. - */ -/*D0*/ __u8 s_journal_uuid[16]; /* uuid of journal superblock */ -/*E0*/ __le32 s_journal_inum; /* inode number of journal file */ - __le32 s_journal_dev; /* device number of journal file */ - __le32 s_last_orphan; /* start of list of inodes to delete */ - __le32 s_hash_seed[4]; /* HTREE hash seed */ - __u8 s_def_hash_version; /* Default hash version to use */ - __u8 s_reserved_char_pad; - __le16 s_desc_size; /* size of group descriptor */ -/*100*/ __le32 s_default_mount_opts; - __le32 s_first_meta_bg; /* First metablock block group */ - __le32 s_mkfs_time; /* When the filesystem was created */ - __le32 s_jnl_blocks[17]; /* Backup of the journal inode */ - /* 64bit support valid if EXT4_FEATURE_COMPAT_64BIT */ -/*150*/ __le32 s_blocks_count_hi; /* Blocks count */ - __le32 s_r_blocks_count_hi; /* Reserved blocks count */ - __le32 s_free_blocks_count_hi; /* Free blocks count */ - __u32 s_reserved[169]; /* Padding to the end of the block */ -}; - -#ifdef __KERNEL__ -static inline struct ext4_sb_info * EXT4_SB(struct super_block *sb) -{ - return sb->s_fs_info; -} -static inline struct ext4_inode_info *EXT4_I(struct inode *inode) -{ - return container_of(inode, struct ext4_inode_info, vfs_inode); -} - -static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino) -{ - return ino == EXT4_ROOT_INO || - ino == EXT4_JOURNAL_INO || - ino == EXT4_RESIZE_INO || - (ino >= EXT4_FIRST_INO(sb) && - ino <= le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count)); -} -#else -/* Assume that user mode programs are passing in an ext4fs superblock, not - * a kernel struct super_block. This will allow us to call the feature-test - * macros from user land. */ -#define EXT4_SB(sb) (sb) -#endif - -#define NEXT_ORPHAN(inode) EXT4_I(inode)->i_dtime - -/* - * Codes for operating systems - */ -#define EXT4_OS_LINUX 0 -#define EXT4_OS_HURD 1 -#define EXT4_OS_MASIX 2 -#define EXT4_OS_FREEBSD 3 -#define EXT4_OS_LITES 4 - -/* - * Revision levels - */ -#define EXT4_GOOD_OLD_REV 0 /* The good old (original) format */ -#define EXT4_DYNAMIC_REV 1 /* V2 format w/ dynamic inode sizes */ - -#define EXT4_CURRENT_REV EXT4_GOOD_OLD_REV -#define EXT4_MAX_SUPP_REV EXT4_DYNAMIC_REV - -#define EXT4_GOOD_OLD_INODE_SIZE 128 - -/* - * Feature set definitions - */ - -#define EXT4_HAS_COMPAT_FEATURE(sb,mask) \ - ( EXT4_SB(sb)->s_es->s_feature_compat & cpu_to_le32(mask) ) -#define EXT4_HAS_RO_COMPAT_FEATURE(sb,mask) \ - ( EXT4_SB(sb)->s_es->s_feature_ro_compat & cpu_to_le32(mask) ) -#define EXT4_HAS_INCOMPAT_FEATURE(sb,mask) \ - ( EXT4_SB(sb)->s_es->s_feature_incompat & cpu_to_le32(mask) ) -#define EXT4_SET_COMPAT_FEATURE(sb,mask) \ - EXT4_SB(sb)->s_es->s_feature_compat |= cpu_to_le32(mask) -#define EXT4_SET_RO_COMPAT_FEATURE(sb,mask) \ - EXT4_SB(sb)->s_es->s_feature_ro_compat |= cpu_to_le32(mask) -#define EXT4_SET_INCOMPAT_FEATURE(sb,mask) \ - EXT4_SB(sb)->s_es->s_feature_incompat |= cpu_to_le32(mask) -#define EXT4_CLEAR_COMPAT_FEATURE(sb,mask) \ - EXT4_SB(sb)->s_es->s_feature_compat &= ~cpu_to_le32(mask) -#define EXT4_CLEAR_RO_COMPAT_FEATURE(sb,mask) \ - EXT4_SB(sb)->s_es->s_feature_ro_compat &= ~cpu_to_le32(mask) -#define EXT4_CLEAR_INCOMPAT_FEATURE(sb,mask) \ - EXT4_SB(sb)->s_es->s_feature_incompat &= ~cpu_to_le32(mask) - -#define EXT4_FEATURE_COMPAT_DIR_PREALLOC 0x0001 -#define EXT4_FEATURE_COMPAT_IMAGIC_INODES 0x0002 -#define EXT4_FEATURE_COMPAT_HAS_JOURNAL 0x0004 -#define EXT4_FEATURE_COMPAT_EXT_ATTR 0x0008 -#define EXT4_FEATURE_COMPAT_RESIZE_INODE 0x0010 -#define EXT4_FEATURE_COMPAT_DIR_INDEX 0x0020 - -#define EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001 -#define EXT4_FEATURE_RO_COMPAT_LARGE_FILE 0x0002 -#define EXT4_FEATURE_RO_COMPAT_BTREE_DIR 0x0004 - -#define EXT4_FEATURE_INCOMPAT_COMPRESSION 0x0001 -#define EXT4_FEATURE_INCOMPAT_FILETYPE 0x0002 -#define EXT4_FEATURE_INCOMPAT_RECOVER 0x0004 /* Needs recovery */ -#define EXT4_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 /* Journal device */ -#define EXT4_FEATURE_INCOMPAT_META_BG 0x0010 -#define EXT4_FEATURE_INCOMPAT_EXTENTS 0x0040 /* extents support */ -#define EXT4_FEATURE_INCOMPAT_64BIT 0x0080 - -#define EXT4_FEATURE_COMPAT_SUPP EXT2_FEATURE_COMPAT_EXT_ATTR -#define EXT4_FEATURE_INCOMPAT_SUPP (EXT4_FEATURE_INCOMPAT_FILETYPE| \ - EXT4_FEATURE_INCOMPAT_RECOVER| \ - EXT4_FEATURE_INCOMPAT_META_BG| \ - EXT4_FEATURE_INCOMPAT_EXTENTS| \ - EXT4_FEATURE_INCOMPAT_64BIT) -#define EXT4_FEATURE_RO_COMPAT_SUPP (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER| \ - EXT4_FEATURE_RO_COMPAT_LARGE_FILE| \ - EXT4_FEATURE_RO_COMPAT_BTREE_DIR) - -/* - * Default values for user and/or group using reserved blocks - */ -#define EXT4_DEF_RESUID 0 -#define EXT4_DEF_RESGID 0 - -/* - * Default mount options - */ -#define EXT4_DEFM_DEBUG 0x0001 -#define EXT4_DEFM_BSDGROUPS 0x0002 -#define EXT4_DEFM_XATTR_USER 0x0004 -#define EXT4_DEFM_ACL 0x0008 -#define EXT4_DEFM_UID16 0x0010 -#define EXT4_DEFM_JMODE 0x0060 -#define EXT4_DEFM_JMODE_DATA 0x0020 -#define EXT4_DEFM_JMODE_ORDERED 0x0040 -#define EXT4_DEFM_JMODE_WBACK 0x0060 - -/* - * Structure of a directory entry - */ -#define EXT4_NAME_LEN 255 - -struct ext4_dir_entry { - __le32 inode; /* Inode number */ - __le16 rec_len; /* Directory entry length */ - __le16 name_len; /* Name length */ - char name[EXT4_NAME_LEN]; /* File name */ -}; - -/* - * The new version of the directory entry. Since EXT4 structures are - * stored in intel byte order, and the name_len field could never be - * bigger than 255 chars, it's safe to reclaim the extra byte for the - * file_type field. - */ -struct ext4_dir_entry_2 { - __le32 inode; /* Inode number */ - __le16 rec_len; /* Directory entry length */ - __u8 name_len; /* Name length */ - __u8 file_type; - char name[EXT4_NAME_LEN]; /* File name */ -}; - -/* - * Ext4 directory file types. Only the low 3 bits are used. The - * other bits are reserved for now. - */ -#define EXT4_FT_UNKNOWN 0 -#define EXT4_FT_REG_FILE 1 -#define EXT4_FT_DIR 2 -#define EXT4_FT_CHRDEV 3 -#define EXT4_FT_BLKDEV 4 -#define EXT4_FT_FIFO 5 -#define EXT4_FT_SOCK 6 -#define EXT4_FT_SYMLINK 7 - -#define EXT4_FT_MAX 8 - -/* - * EXT4_DIR_PAD defines the directory entries boundaries - * - * NOTE: It must be a multiple of 4 - */ -#define EXT4_DIR_PAD 4 -#define EXT4_DIR_ROUND (EXT4_DIR_PAD - 1) -#define EXT4_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT4_DIR_ROUND) & \ - ~EXT4_DIR_ROUND) -/* - * Hash Tree Directory indexing - * (c) Daniel Phillips, 2001 - */ - -#ifdef CONFIG_EXT4_INDEX - #define is_dx(dir) (EXT4_HAS_COMPAT_FEATURE(dir->i_sb, \ - EXT4_FEATURE_COMPAT_DIR_INDEX) && \ - (EXT4_I(dir)->i_flags & EXT4_INDEX_FL)) -#define EXT4_DIR_LINK_MAX(dir) (!is_dx(dir) && (dir)->i_nlink >= EXT4_LINK_MAX) -#define EXT4_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2 || (dir)->i_nlink == 1) -#else - #define is_dx(dir) 0 -#define EXT4_DIR_LINK_MAX(dir) ((dir)->i_nlink >= EXT4_LINK_MAX) -#define EXT4_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2) -#endif - -/* Legal values for the dx_root hash_version field: */ - -#define DX_HASH_LEGACY 0 -#define DX_HASH_HALF_MD4 1 -#define DX_HASH_TEA 2 - -#ifdef __KERNEL__ - -/* hash info structure used by the directory hash */ -struct dx_hash_info -{ - u32 hash; - u32 minor_hash; - int hash_version; - u32 *seed; -}; - -#define EXT4_HTREE_EOF 0x7fffffff - -/* - * Control parameters used by ext4_htree_next_block - */ -#define HASH_NB_ALWAYS 1 - - -/* - * Describe an inode's exact location on disk and in memory - */ -struct ext4_iloc -{ - struct buffer_head *bh; - unsigned long offset; - unsigned long block_group; -}; - -static inline struct ext4_inode *ext4_raw_inode(struct ext4_iloc *iloc) -{ - return (struct ext4_inode *) (iloc->bh->b_data + iloc->offset); -} - -/* - * This structure is stuffed into the struct file's private_data field - * for directories. It is where we put information so that we can do - * readdir operations in hash tree order. - */ -struct dir_private_info { - struct rb_root root; - struct rb_node *curr_node; - struct fname *extra_fname; - loff_t last_pos; - __u32 curr_hash; - __u32 curr_minor_hash; - __u32 next_hash; -}; - -/* calculate the first block number of the group */ -static inline ext4_fsblk_t -ext4_group_first_block_no(struct super_block *sb, unsigned long group_no) -{ - return group_no * (ext4_fsblk_t)EXT4_BLOCKS_PER_GROUP(sb) + - le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block); -} - -/* - * Special error return code only used by dx_probe() and its callers. - */ -#define ERR_BAD_DX_DIR -75000 - -void ext4_get_group_no_and_offset(struct super_block *sb, ext4_fsblk_t blocknr, - unsigned long *blockgrpp, ext4_grpblk_t *offsetp); - -/* - * Function prototypes - */ - -/* - * Ok, these declarations are also in but none of the - * ext4 source programs needs to include it so they are duplicated here. - */ -# define NORET_TYPE /**/ -# define ATTRIB_NORET __attribute__((noreturn)) -# define NORET_AND noreturn, - -/* balloc.c */ -extern unsigned int ext4_block_group(struct super_block *sb, - ext4_fsblk_t blocknr); -extern ext4_grpblk_t ext4_block_group_offset(struct super_block *sb, - ext4_fsblk_t blocknr); -extern int ext4_bg_has_super(struct super_block *sb, int group); -extern unsigned long ext4_bg_num_gdb(struct super_block *sb, int group); -extern ext4_fsblk_t ext4_new_block (handle_t *handle, struct inode *inode, - ext4_fsblk_t goal, int *errp); -extern ext4_fsblk_t ext4_new_blocks (handle_t *handle, struct inode *inode, - ext4_fsblk_t goal, unsigned long *count, int *errp); -extern void ext4_free_blocks (handle_t *handle, struct inode *inode, - ext4_fsblk_t block, unsigned long count); -extern void ext4_free_blocks_sb (handle_t *handle, struct super_block *sb, - ext4_fsblk_t block, unsigned long count, - unsigned long *pdquot_freed_blocks); -extern ext4_fsblk_t ext4_count_free_blocks (struct super_block *); -extern void ext4_check_blocks_bitmap (struct super_block *); -extern struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb, - unsigned int block_group, - struct buffer_head ** bh); -extern int ext4_should_retry_alloc(struct super_block *sb, int *retries); -extern void ext4_init_block_alloc_info(struct inode *); -extern void ext4_rsv_window_add(struct super_block *sb, struct ext4_reserve_window_node *rsv); - -/* dir.c */ -extern int ext4_check_dir_entry(const char *, struct inode *, - struct ext4_dir_entry_2 *, - struct buffer_head *, unsigned long); -extern int ext4_htree_store_dirent(struct file *dir_file, __u32 hash, - __u32 minor_hash, - struct ext4_dir_entry_2 *dirent); -extern void ext4_htree_free_dir_info(struct dir_private_info *p); - -/* fsync.c */ -extern int ext4_sync_file (struct file *, struct dentry *, int); - -/* hash.c */ -extern int ext4fs_dirhash(const char *name, int len, struct - dx_hash_info *hinfo); - -/* ialloc.c */ -extern struct inode * ext4_new_inode (handle_t *, struct inode *, int); -extern void ext4_free_inode (handle_t *, struct inode *); -extern struct inode * ext4_orphan_get (struct super_block *, unsigned long); -extern unsigned long ext4_count_free_inodes (struct super_block *); -extern unsigned long ext4_count_dirs (struct super_block *); -extern void ext4_check_inodes_bitmap (struct super_block *); -extern unsigned long ext4_count_free (struct buffer_head *, unsigned); - - -/* inode.c */ -int ext4_forget(handle_t *handle, int is_metadata, struct inode *inode, - struct buffer_head *bh, ext4_fsblk_t blocknr); -struct buffer_head * ext4_getblk (handle_t *, struct inode *, long, int, int *); -struct buffer_head * ext4_bread (handle_t *, struct inode *, int, int, int *); -int ext4_get_blocks_handle(handle_t *handle, struct inode *inode, - sector_t iblock, unsigned long maxblocks, struct buffer_head *bh_result, - int create, int extend_disksize); - -extern void ext4_read_inode (struct inode *); -extern int ext4_write_inode (struct inode *, int); -extern int ext4_setattr (struct dentry *, struct iattr *); -extern void ext4_delete_inode (struct inode *); -extern int ext4_sync_inode (handle_t *, struct inode *); -extern void ext4_discard_reservation (struct inode *); -extern void ext4_dirty_inode(struct inode *); -extern int ext4_change_inode_journal_flag(struct inode *, int); -extern int ext4_get_inode_loc(struct inode *, struct ext4_iloc *); -extern void ext4_truncate (struct inode *); -extern void ext4_set_inode_flags(struct inode *); -extern void ext4_set_aops(struct inode *inode); -extern int ext4_writepage_trans_blocks(struct inode *); -extern int ext4_block_truncate_page(handle_t *handle, struct page *page, - struct address_space *mapping, loff_t from); - -/* ioctl.c */ -extern int ext4_ioctl (struct inode *, struct file *, unsigned int, - unsigned long); -extern long ext4_compat_ioctl (struct file *, unsigned int, unsigned long); - -/* namei.c */ -extern int ext4_orphan_add(handle_t *, struct inode *); -extern int ext4_orphan_del(handle_t *, struct inode *); -extern int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash, - __u32 start_minor_hash, __u32 *next_hash); - -/* resize.c */ -extern int ext4_group_add(struct super_block *sb, - struct ext4_new_group_data *input); -extern int ext4_group_extend(struct super_block *sb, - struct ext4_super_block *es, - ext4_fsblk_t n_blocks_count); - -/* super.c */ -extern void ext4_error (struct super_block *, const char *, const char *, ...) - __attribute__ ((format (printf, 3, 4))); -extern void __ext4_std_error (struct super_block *, const char *, int); -extern void ext4_abort (struct super_block *, const char *, const char *, ...) - __attribute__ ((format (printf, 3, 4))); -extern void ext4_warning (struct super_block *, const char *, const char *, ...) - __attribute__ ((format (printf, 3, 4))); -extern void ext4_update_dynamic_rev (struct super_block *sb); -extern ext4_fsblk_t ext4_block_bitmap(struct super_block *sb, - struct ext4_group_desc *bg); -extern ext4_fsblk_t ext4_inode_bitmap(struct super_block *sb, - struct ext4_group_desc *bg); -extern ext4_fsblk_t ext4_inode_table(struct super_block *sb, - struct ext4_group_desc *bg); -extern void ext4_block_bitmap_set(struct super_block *sb, - struct ext4_group_desc *bg, ext4_fsblk_t blk); -extern void ext4_inode_bitmap_set(struct super_block *sb, - struct ext4_group_desc *bg, ext4_fsblk_t blk); -extern void ext4_inode_table_set(struct super_block *sb, - struct ext4_group_desc *bg, ext4_fsblk_t blk); - -static inline ext4_fsblk_t ext4_blocks_count(struct ext4_super_block *es) -{ - return ((ext4_fsblk_t)le32_to_cpu(es->s_blocks_count_hi) << 32) | - le32_to_cpu(es->s_blocks_count); -} - -static inline ext4_fsblk_t ext4_r_blocks_count(struct ext4_super_block *es) -{ - return ((ext4_fsblk_t)le32_to_cpu(es->s_r_blocks_count_hi) << 32) | - le32_to_cpu(es->s_r_blocks_count); -} - -static inline ext4_fsblk_t ext4_free_blocks_count(struct ext4_super_block *es) -{ - return ((ext4_fsblk_t)le32_to_cpu(es->s_free_blocks_count_hi) << 32) | - le32_to_cpu(es->s_free_blocks_count); -} - -static inline void ext4_blocks_count_set(struct ext4_super_block *es, - ext4_fsblk_t blk) -{ - es->s_blocks_count = cpu_to_le32((u32)blk); - es->s_blocks_count_hi = cpu_to_le32(blk >> 32); -} - -static inline void ext4_free_blocks_count_set(struct ext4_super_block *es, - ext4_fsblk_t blk) -{ - es->s_free_blocks_count = cpu_to_le32((u32)blk); - es->s_free_blocks_count_hi = cpu_to_le32(blk >> 32); -} - -static inline void ext4_r_blocks_count_set(struct ext4_super_block *es, - ext4_fsblk_t blk) -{ - es->s_r_blocks_count = cpu_to_le32((u32)blk); - es->s_r_blocks_count_hi = cpu_to_le32(blk >> 32); -} - - - -#define ext4_std_error(sb, errno) \ -do { \ - if ((errno)) \ - __ext4_std_error((sb), __FUNCTION__, (errno)); \ -} while (0) - -/* - * Inodes and files operations - */ - -/* dir.c */ -extern const struct file_operations ext4_dir_operations; - -/* file.c */ -extern struct inode_operations ext4_file_inode_operations; -extern const struct file_operations ext4_file_operations; - -/* namei.c */ -extern struct inode_operations ext4_dir_inode_operations; -extern struct inode_operations ext4_special_inode_operations; - -/* symlink.c */ -extern struct inode_operations ext4_symlink_inode_operations; -extern struct inode_operations ext4_fast_symlink_inode_operations; - -/* extents.c */ -extern int ext4_ext_tree_init(handle_t *handle, struct inode *); -extern int ext4_ext_writepage_trans_blocks(struct inode *, int); -extern int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, - ext4_fsblk_t iblock, - unsigned long max_blocks, struct buffer_head *bh_result, - int create, int extend_disksize); -extern void ext4_ext_truncate(struct inode *, struct page *); -extern void ext4_ext_init(struct super_block *); -extern void ext4_ext_release(struct super_block *); -static inline int -ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block, - unsigned long max_blocks, struct buffer_head *bh, - int create, int extend_disksize) -{ - if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) - return ext4_ext_get_blocks(handle, inode, block, max_blocks, - bh, create, extend_disksize); - return ext4_get_blocks_handle(handle, inode, block, max_blocks, bh, - create, extend_disksize); -} - - -#endif /* __KERNEL__ */ - -#endif /* _LINUX_EXT4_FS_H */ diff --git a/trunk/include/linux/ext4_fs_extents.h b/trunk/include/linux/ext4_fs_extents.h deleted file mode 100644 index a41cc24568ca..000000000000 --- a/trunk/include/linux/ext4_fs_extents.h +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright (c) 2003-2006, Cluster File Systems, Inc, info@clusterfs.com - * Written by Alex Tomas - * - * 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. - * - * 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 Licens - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111- - */ - -#ifndef _LINUX_EXT4_EXTENTS -#define _LINUX_EXT4_EXTENTS - -#include - -/* - * With AGRESSIVE_TEST defined, the capacity of index/leaf blocks - * becomes very small, so index split, in-depth growing and - * other hard changes happen much more often. - * This is for debug purposes only. - */ -#define AGRESSIVE_TEST_ - -/* - * With EXTENTS_STATS defined, the number of blocks and extents - * are collected in the truncate path. They'll be shown at - * umount time. - */ -#define EXTENTS_STATS__ - -/* - * If CHECK_BINSEARCH is defined, then the results of the binary search - * will also be checked by linear search. - */ -#define CHECK_BINSEARCH__ - -/* - * If EXT_DEBUG is defined you can use the 'extdebug' mount option - * to get lots of info about what's going on. - */ -#define EXT_DEBUG__ -#ifdef EXT_DEBUG -#define ext_debug(a...) printk(a) -#else -#define ext_debug(a...) -#endif - -/* - * If EXT_STATS is defined then stats numbers are collected. - * These number will be displayed at umount time. - */ -#define EXT_STATS_ - - -/* - * ext4_inode has i_block array (60 bytes total). - * The first 12 bytes store ext4_extent_header; - * the remainder stores an array of ext4_extent. - */ - -/* - * This is the extent on-disk structure. - * It's used at the bottom of the tree. - */ -struct ext4_extent { - __le32 ee_block; /* first logical block extent covers */ - __le16 ee_len; /* number of blocks covered by extent */ - __le16 ee_start_hi; /* high 16 bits of physical block */ - __le32 ee_start; /* low 32 bits of physical block */ -}; - -/* - * This is index on-disk structure. - * It's used at all the levels except the bottom. - */ -struct ext4_extent_idx { - __le32 ei_block; /* index covers logical blocks from 'block' */ - __le32 ei_leaf; /* pointer to the physical block of the next * - * level. leaf or next index could be there */ - __le16 ei_leaf_hi; /* high 16 bits of physical block */ - __u16 ei_unused; -}; - -/* - * Each block (leaves and indexes), even inode-stored has header. - */ -struct ext4_extent_header { - __le16 eh_magic; /* probably will support different formats */ - __le16 eh_entries; /* number of valid entries */ - __le16 eh_max; /* capacity of store in entries */ - __le16 eh_depth; /* has tree real underlying blocks? */ - __le32 eh_generation; /* generation of the tree */ -}; - -#define EXT4_EXT_MAGIC cpu_to_le16(0xf30a) - -/* - * Array of ext4_ext_path contains path to some extent. - * Creation/lookup routines use it for traversal/splitting/etc. - * Truncate uses it to simulate recursive walking. - */ -struct ext4_ext_path { - ext4_fsblk_t p_block; - __u16 p_depth; - struct ext4_extent *p_ext; - struct ext4_extent_idx *p_idx; - struct ext4_extent_header *p_hdr; - struct buffer_head *p_bh; -}; - -/* - * structure for external API - */ - -#define EXT4_EXT_CACHE_NO 0 -#define EXT4_EXT_CACHE_GAP 1 -#define EXT4_EXT_CACHE_EXTENT 2 - -/* - * to be called by ext4_ext_walk_space() - * negative retcode - error - * positive retcode - signal for ext4_ext_walk_space(), see below - * callback must return valid extent (passed or newly created) - */ -typedef int (*ext_prepare_callback)(struct inode *, struct ext4_ext_path *, - struct ext4_ext_cache *, - void *); - -#define EXT_CONTINUE 0 -#define EXT_BREAK 1 -#define EXT_REPEAT 2 - - -#define EXT_MAX_BLOCK 0xffffffff - -#define EXT_MAX_LEN ((1UL << 15) - 1) - - -#define EXT_FIRST_EXTENT(__hdr__) \ - ((struct ext4_extent *) (((char *) (__hdr__)) + \ - sizeof(struct ext4_extent_header))) -#define EXT_FIRST_INDEX(__hdr__) \ - ((struct ext4_extent_idx *) (((char *) (__hdr__)) + \ - sizeof(struct ext4_extent_header))) -#define EXT_HAS_FREE_INDEX(__path__) \ - (le16_to_cpu((__path__)->p_hdr->eh_entries) \ - < le16_to_cpu((__path__)->p_hdr->eh_max)) -#define EXT_LAST_EXTENT(__hdr__) \ - (EXT_FIRST_EXTENT((__hdr__)) + le16_to_cpu((__hdr__)->eh_entries) - 1) -#define EXT_LAST_INDEX(__hdr__) \ - (EXT_FIRST_INDEX((__hdr__)) + le16_to_cpu((__hdr__)->eh_entries) - 1) -#define EXT_MAX_EXTENT(__hdr__) \ - (EXT_FIRST_EXTENT((__hdr__)) + le16_to_cpu((__hdr__)->eh_max) - 1) -#define EXT_MAX_INDEX(__hdr__) \ - (EXT_FIRST_INDEX((__hdr__)) + le16_to_cpu((__hdr__)->eh_max) - 1) - -static inline struct ext4_extent_header *ext_inode_hdr(struct inode *inode) -{ - return (struct ext4_extent_header *) EXT4_I(inode)->i_data; -} - -static inline struct ext4_extent_header *ext_block_hdr(struct buffer_head *bh) -{ - return (struct ext4_extent_header *) bh->b_data; -} - -static inline unsigned short ext_depth(struct inode *inode) -{ - return le16_to_cpu(ext_inode_hdr(inode)->eh_depth); -} - -static inline void ext4_ext_tree_changed(struct inode *inode) -{ - EXT4_I(inode)->i_ext_generation++; -} - -static inline void -ext4_ext_invalidate_cache(struct inode *inode) -{ - EXT4_I(inode)->i_cached_extent.ec_type = EXT4_EXT_CACHE_NO; -} - -extern int ext4_extent_tree_init(handle_t *, struct inode *); -extern int ext4_ext_calc_credits_for_insert(struct inode *, struct ext4_ext_path *); -extern int ext4_ext_insert_extent(handle_t *, struct inode *, struct ext4_ext_path *, struct ext4_extent *); -extern int ext4_ext_walk_space(struct inode *, unsigned long, unsigned long, ext_prepare_callback, void *); -extern struct ext4_ext_path * ext4_ext_find_extent(struct inode *, int, struct ext4_ext_path *); - -#endif /* _LINUX_EXT4_EXTENTS */ - diff --git a/trunk/include/linux/ext4_fs_i.h b/trunk/include/linux/ext4_fs_i.h deleted file mode 100644 index bb42379cb7fd..000000000000 --- a/trunk/include/linux/ext4_fs_i.h +++ /dev/null @@ -1,158 +0,0 @@ -/* - * linux/include/linux/ext4_fs_i.h - * - * Copyright (C) 1992, 1993, 1994, 1995 - * Remy Card (card@masi.ibp.fr) - * Laboratoire MASI - Institut Blaise Pascal - * Universite Pierre et Marie Curie (Paris VI) - * - * from - * - * linux/include/linux/minix_fs_i.h - * - * Copyright (C) 1991, 1992 Linus Torvalds - */ - -#ifndef _LINUX_EXT4_FS_I -#define _LINUX_EXT4_FS_I - -#include -#include -#include -#include - -/* data type for block offset of block group */ -typedef int ext4_grpblk_t; - -/* data type for filesystem-wide blocks number */ -typedef unsigned long long ext4_fsblk_t; - -struct ext4_reserve_window { - ext4_fsblk_t _rsv_start; /* First byte reserved */ - ext4_fsblk_t _rsv_end; /* Last byte reserved or 0 */ -}; - -struct ext4_reserve_window_node { - struct rb_node rsv_node; - __u32 rsv_goal_size; - __u32 rsv_alloc_hit; - struct ext4_reserve_window rsv_window; -}; - -struct ext4_block_alloc_info { - /* information about reservation window */ - struct ext4_reserve_window_node rsv_window_node; - /* - * was i_next_alloc_block in ext4_inode_info - * is the logical (file-relative) number of the - * most-recently-allocated block in this file. - * We use this for detecting linearly ascending allocation requests. - */ - __u32 last_alloc_logical_block; - /* - * Was i_next_alloc_goal in ext4_inode_info - * is the *physical* companion to i_next_alloc_block. - * it the the physical block number of the block which was most-recentl - * allocated to this file. This give us the goal (target) for the next - * allocation when we detect linearly ascending requests. - */ - ext4_fsblk_t last_alloc_physical_block; -}; - -#define rsv_start rsv_window._rsv_start -#define rsv_end rsv_window._rsv_end - -/* - * storage for cached extent - */ -struct ext4_ext_cache { - ext4_fsblk_t ec_start; - __u32 ec_block; - __u32 ec_len; /* must be 32bit to return holes */ - __u32 ec_type; -}; - -/* - * third extended file system inode data in memory - */ -struct ext4_inode_info { - __le32 i_data[15]; /* unconverted */ - __u32 i_flags; -#ifdef EXT4_FRAGMENTS - __u32 i_faddr; - __u8 i_frag_no; - __u8 i_frag_size; -#endif - ext4_fsblk_t i_file_acl; - __u32 i_dir_acl; - __u32 i_dtime; - - /* - * i_block_group is the number of the block group which contains - * this file's inode. Constant across the lifetime of the inode, - * it is ued for making block allocation decisions - we try to - * place a file's data blocks near its inode block, and new inodes - * near to their parent directory's inode. - */ - __u32 i_block_group; - __u32 i_state; /* Dynamic state flags for ext4 */ - - /* block reservation info */ - struct ext4_block_alloc_info *i_block_alloc_info; - - __u32 i_dir_start_lookup; -#ifdef CONFIG_EXT4DEV_FS_XATTR - /* - * Extended attributes can be read independently of the main file - * data. Taking i_mutex even when reading would cause contention - * between readers of EAs and writers of regular file data, so - * instead we synchronize on xattr_sem when reading or changing - * EAs. - */ - struct rw_semaphore xattr_sem; -#endif -#ifdef CONFIG_EXT4DEV_FS_POSIX_ACL - struct posix_acl *i_acl; - struct posix_acl *i_default_acl; -#endif - - struct list_head i_orphan; /* unlinked but open inodes */ - - /* - * i_disksize keeps track of what the inode size is ON DISK, not - * in memory. During truncate, i_size is set to the new size by - * the VFS prior to calling ext4_truncate(), but the filesystem won't - * set i_disksize to 0 until the truncate is actually under way. - * - * The intent is that i_disksize always represents the blocks which - * are used by this file. This allows recovery to restart truncate - * on orphans if we crash during truncate. We actually write i_disksize - * into the on-disk inode when writing inodes out, instead of i_size. - * - * The only time when i_disksize and i_size may be different is when - * a truncate is in progress. The only things which change i_disksize - * are ext4_get_block (growth) and ext4_truncate (shrinkth). - */ - loff_t i_disksize; - - /* on-disk additional length */ - __u16 i_extra_isize; - - /* - * truncate_mutex is for serialising ext4_truncate() against - * ext4_getblock(). In the 2.4 ext2 design, great chunks of inode's - * data tree are chopped off during truncate. We can't do that in - * ext4 because whenever we perform intermediate commits during - * truncate, the inode and all the metadata blocks *must* be in a - * consistent state which allows truncation of the orphans to restart - * during recovery. Hence we must fix the get_block-vs-truncate race - * by other means, so we have truncate_mutex. - */ - struct mutex truncate_mutex; - struct inode vfs_inode; - - unsigned long i_ext_generation; - struct ext4_ext_cache i_cached_extent; -}; - -#endif /* _LINUX_EXT4_FS_I */ diff --git a/trunk/include/linux/ext4_fs_sb.h b/trunk/include/linux/ext4_fs_sb.h deleted file mode 100644 index 691a713139ce..000000000000 --- a/trunk/include/linux/ext4_fs_sb.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * linux/include/linux/ext4_fs_sb.h - * - * Copyright (C) 1992, 1993, 1994, 1995 - * Remy Card (card@masi.ibp.fr) - * Laboratoire MASI - Institut Blaise Pascal - * Universite Pierre et Marie Curie (Paris VI) - * - * from - * - * linux/include/linux/minix_fs_sb.h - * - * Copyright (C) 1991, 1992 Linus Torvalds - */ - -#ifndef _LINUX_EXT4_FS_SB -#define _LINUX_EXT4_FS_SB - -#ifdef __KERNEL__ -#include -#include -#include -#include -#endif -#include - -/* - * third extended-fs super-block data in memory - */ -struct ext4_sb_info { - unsigned long s_frag_size; /* Size of a fragment in bytes */ - unsigned long s_desc_size; /* Size of a group descriptor in bytes */ - unsigned long s_frags_per_block;/* Number of fragments per block */ - unsigned long s_inodes_per_block;/* Number of inodes per block */ - unsigned long s_frags_per_group;/* Number of fragments in a group */ - unsigned long s_blocks_per_group;/* Number of blocks in a group */ - unsigned long s_inodes_per_group;/* Number of inodes in a group */ - unsigned long s_itb_per_group; /* Number of inode table blocks per group */ - unsigned long s_gdb_count; /* Number of group descriptor blocks */ - unsigned long s_desc_per_block; /* Number of group descriptors per block */ - unsigned long s_groups_count; /* Number of groups in the fs */ - struct buffer_head * s_sbh; /* Buffer containing the super block */ - struct ext4_super_block * s_es; /* Pointer to the super block in the buffer */ - struct buffer_head ** s_group_desc; - unsigned long s_mount_opt; - uid_t s_resuid; - gid_t s_resgid; - unsigned short s_mount_state; - unsigned short s_pad; - int s_addr_per_block_bits; - int s_desc_per_block_bits; - int s_inode_size; - int s_first_ino; - spinlock_t s_next_gen_lock; - u32 s_next_generation; - u32 s_hash_seed[4]; - int s_def_hash_version; - struct percpu_counter s_freeblocks_counter; - struct percpu_counter s_freeinodes_counter; - struct percpu_counter s_dirs_counter; - struct blockgroup_lock s_blockgroup_lock; - - /* root of the per fs reservation window tree */ - spinlock_t s_rsv_window_lock; - struct rb_root s_rsv_window_root; - struct ext4_reserve_window_node s_rsv_window_head; - - /* Journaling */ - struct inode * s_journal_inode; - struct journal_s * s_journal; - struct list_head s_orphan; - unsigned long s_commit_interval; - struct block_device *journal_bdev; -#ifdef CONFIG_JBD_DEBUG - struct timer_list turn_ro_timer; /* For turning read-only (crash simulation) */ - wait_queue_head_t ro_wait_queue; /* For people waiting for the fs to go read-only */ -#endif -#ifdef CONFIG_QUOTA - char *s_qf_names[MAXQUOTAS]; /* Names of quota files with journalled quota */ - int s_jquota_fmt; /* Format of quota to use */ -#endif - -#ifdef EXTENTS_STATS - /* ext4 extents stats */ - unsigned long s_ext_min; - unsigned long s_ext_max; - unsigned long s_depth_max; - spinlock_t s_ext_stats_lock; - unsigned long s_ext_blocks; - unsigned long s_ext_extents; -#endif -}; - -#endif /* _LINUX_EXT4_FS_SB */ diff --git a/trunk/include/linux/ext4_jbd2.h b/trunk/include/linux/ext4_jbd2.h deleted file mode 100644 index 72dd631912e4..000000000000 --- a/trunk/include/linux/ext4_jbd2.h +++ /dev/null @@ -1,273 +0,0 @@ -/* - * linux/include/linux/ext4_jbd2.h - * - * Written by Stephen C. Tweedie , 1999 - * - * Copyright 1998--1999 Red Hat corp --- All Rights Reserved - * - * This file is part of the Linux kernel and is made available under - * the terms of the GNU General Public License, version 2, or at your - * option, any later version, incorporated herein by reference. - * - * Ext4-specific journaling extensions. - */ - -#ifndef _LINUX_EXT4_JBD_H -#define _LINUX_EXT4_JBD_H - -#include -#include -#include - -#define EXT4_JOURNAL(inode) (EXT4_SB((inode)->i_sb)->s_journal) - -/* Define the number of blocks we need to account to a transaction to - * modify one block of data. - * - * We may have to touch one inode, one bitmap buffer, up to three - * indirection blocks, the group and superblock summaries, and the data - * block to complete the transaction. - * - * For extents-enabled fs we may have to allocate and modify up to - * 5 levels of tree + root which are stored in the inode. */ - -#define EXT4_SINGLEDATA_TRANS_BLOCKS(sb) \ - (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS) \ - || test_opt(sb, EXTENTS) ? 27U : 8U) - -/* Extended attribute operations touch at most two data buffers, - * two bitmap buffers, and two group summaries, in addition to the inode - * and the superblock, which are already accounted for. */ - -#define EXT4_XATTR_TRANS_BLOCKS 6U - -/* Define the minimum size for a transaction which modifies data. This - * needs to take into account the fact that we may end up modifying two - * quota files too (one for the group, one for the user quota). The - * superblock only gets updated once, of course, so don't bother - * counting that again for the quota updates. */ - -#define EXT4_DATA_TRANS_BLOCKS(sb) (EXT4_SINGLEDATA_TRANS_BLOCKS(sb) + \ - EXT4_XATTR_TRANS_BLOCKS - 2 + \ - 2*EXT4_QUOTA_TRANS_BLOCKS(sb)) - -/* Delete operations potentially hit one directory's namespace plus an - * entire inode, plus arbitrary amounts of bitmap/indirection data. Be - * generous. We can grow the delete transaction later if necessary. */ - -#define EXT4_DELETE_TRANS_BLOCKS(sb) (2 * EXT4_DATA_TRANS_BLOCKS(sb) + 64) - -/* Define an arbitrary limit for the amount of data we will anticipate - * writing to any given transaction. For unbounded transactions such as - * write(2) and truncate(2) we can write more than this, but we always - * start off at the maximum transaction size and grow the transaction - * optimistically as we go. */ - -#define EXT4_MAX_TRANS_DATA 64U - -/* We break up a large truncate or write transaction once the handle's - * buffer credits gets this low, we need either to extend the - * transaction or to start a new one. Reserve enough space here for - * inode, bitmap, superblock, group and indirection updates for at least - * one block, plus two quota updates. Quota allocations are not - * needed. */ - -#define EXT4_RESERVE_TRANS_BLOCKS 12U - -#define EXT4_INDEX_EXTRA_TRANS_BLOCKS 8 - -#ifdef CONFIG_QUOTA -/* Amount of blocks needed for quota update - we know that the structure was - * allocated so we need to update only inode+data */ -#define EXT4_QUOTA_TRANS_BLOCKS(sb) (test_opt(sb, QUOTA) ? 2 : 0) -/* Amount of blocks needed for quota insert/delete - we do some block writes - * but inode, sb and group updates are done only once */ -#define EXT4_QUOTA_INIT_BLOCKS(sb) (test_opt(sb, QUOTA) ? (DQUOT_INIT_ALLOC*\ - (EXT4_SINGLEDATA_TRANS_BLOCKS(sb)-3)+3+DQUOT_INIT_REWRITE) : 0) -#define EXT4_QUOTA_DEL_BLOCKS(sb) (test_opt(sb, QUOTA) ? (DQUOT_DEL_ALLOC*\ - (EXT4_SINGLEDATA_TRANS_BLOCKS(sb)-3)+3+DQUOT_DEL_REWRITE) : 0) -#else -#define EXT4_QUOTA_TRANS_BLOCKS(sb) 0 -#define EXT4_QUOTA_INIT_BLOCKS(sb) 0 -#define EXT4_QUOTA_DEL_BLOCKS(sb) 0 -#endif - -int -ext4_mark_iloc_dirty(handle_t *handle, - struct inode *inode, - struct ext4_iloc *iloc); - -/* - * On success, We end up with an outstanding reference count against - * iloc->bh. This _must_ be cleaned up later. - */ - -int ext4_reserve_inode_write(handle_t *handle, struct inode *inode, - struct ext4_iloc *iloc); - -int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode); - -/* - * Wrapper functions with which ext4 calls into JBD. The intent here is - * to allow these to be turned into appropriate stubs so ext4 can control - * ext2 filesystems, so ext2+ext4 systems only nee one fs. This work hasn't - * been done yet. - */ - -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) -{ - int err = jbd2_journal_get_undo_access(handle, bh); - if (err) - ext4_journal_abort_handle(where, __FUNCTION__, bh, handle,err); - return 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; -} - -static inline void -ext4_journal_release_buffer(handle_t *handle, struct buffer_head *bh) -{ - jbd2_journal_release_buffer(handle, 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; -} - -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; -} - -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; -} - -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; -} - - -#define ext4_journal_get_undo_access(handle, bh) \ - __ext4_journal_get_undo_access(__FUNCTION__, (handle), (bh)) -#define ext4_journal_get_write_access(handle, bh) \ - __ext4_journal_get_write_access(__FUNCTION__, (handle), (bh)) -#define ext4_journal_revoke(handle, blocknr, bh) \ - __ext4_journal_revoke(__FUNCTION__, (handle), (blocknr), (bh)) -#define ext4_journal_get_create_access(handle, bh) \ - __ext4_journal_get_create_access(__FUNCTION__, (handle), (bh)) -#define ext4_journal_dirty_metadata(handle, bh) \ - __ext4_journal_dirty_metadata(__FUNCTION__, (handle), (bh)) -#define ext4_journal_forget(handle, bh) \ - __ext4_journal_forget(__FUNCTION__, (handle), (bh)) - -int ext4_journal_dirty_data(handle_t *handle, struct buffer_head *bh); - -handle_t *ext4_journal_start_sb(struct super_block *sb, int nblocks); -int __ext4_journal_stop(const char *where, handle_t *handle); - -static inline handle_t *ext4_journal_start(struct inode *inode, int nblocks) -{ - return ext4_journal_start_sb(inode->i_sb, nblocks); -} - -#define ext4_journal_stop(handle) \ - __ext4_journal_stop(__FUNCTION__, (handle)) - -static inline handle_t *ext4_journal_current_handle(void) -{ - return journal_current_handle(); -} - -static inline int ext4_journal_extend(handle_t *handle, int nblocks) -{ - return jbd2_journal_extend(handle, nblocks); -} - -static inline int ext4_journal_restart(handle_t *handle, int nblocks) -{ - return jbd2_journal_restart(handle, nblocks); -} - -static inline int ext4_journal_blocks_per_page(struct inode *inode) -{ - return jbd2_journal_blocks_per_page(inode); -} - -static inline int ext4_journal_force_commit(journal_t *journal) -{ - return jbd2_journal_force_commit(journal); -} - -/* super.c */ -int ext4_force_commit(struct super_block *sb); - -static inline int ext4_should_journal_data(struct inode *inode) -{ - if (!S_ISREG(inode->i_mode)) - return 1; - if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) - return 1; - if (EXT4_I(inode)->i_flags & EXT4_JOURNAL_DATA_FL) - return 1; - return 0; -} - -static inline int ext4_should_order_data(struct inode *inode) -{ - if (!S_ISREG(inode->i_mode)) - return 0; - if (EXT4_I(inode)->i_flags & EXT4_JOURNAL_DATA_FL) - return 0; - if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_ORDERED_DATA) - return 1; - return 0; -} - -static inline int ext4_should_writeback_data(struct inode *inode) -{ - if (!S_ISREG(inode->i_mode)) - return 0; - if (EXT4_I(inode)->i_flags & EXT4_JOURNAL_DATA_FL) - return 0; - if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA) - return 1; - return 0; -} - -#endif /* _LINUX_EXT4_JBD_H */ diff --git a/trunk/include/linux/fb.h b/trunk/include/linux/fb.h index fa23e0671bb3..3e69241e6a81 100644 --- a/trunk/include/linux/fb.h +++ b/trunk/include/linux/fb.h @@ -774,8 +774,8 @@ struct fb_info { #endif struct fb_ops *fbops; - struct device *device; /* This is the parent */ - struct device *dev; /* This is this fb device */ + struct device *device; + struct class_device *class_device; /* sysfs per device attrs */ int class_flag; /* private sysfs flags */ #ifdef CONFIG_FB_TILEBLITTING struct fb_tile_ops *tileops; /* Tile Blitting */ @@ -910,8 +910,8 @@ static inline void __fb_pad_aligned_buffer(u8 *dst, u32 d_pitch, /* drivers/video/fbsysfs.c */ extern struct fb_info *framebuffer_alloc(size_t size, struct device *dev); extern void framebuffer_release(struct fb_info *info); -extern int fb_init_device(struct fb_info *fb_info); -extern void fb_cleanup_device(struct fb_info *head); +extern int fb_init_class_device(struct fb_info *fb_info); +extern void fb_cleanup_class_device(struct fb_info *head); extern void fb_bl_default_curve(struct fb_info *fb_info, u8 off, u8 min, u8 max); /* drivers/video/fbmon.c */ diff --git a/trunk/include/linux/fs.h b/trunk/include/linux/fs.h index 2fe6e3f900ba..34406ed467c3 100644 --- a/trunk/include/linux/fs.h +++ b/trunk/include/linux/fs.h @@ -623,9 +623,6 @@ enum inode_i_mutex_lock_class I_MUTEX_QUOTA }; -extern void inode_double_lock(struct inode *inode1, struct inode *inode2); -extern void inode_double_unlock(struct inode *inode1, struct inode *inode2); - /* * NOTE: in a 32bit arch with a preemptable kernel and * an UP compile the i_size_read/write must be atomic @@ -659,11 +656,7 @@ static inline loff_t i_size_read(struct inode *inode) #endif } -/* - * NOTE: unlike i_size_read(), i_size_write() does need locking around it - * (normally i_mutex), otherwise on 32bit/SMP an update of i_size_seqcount - * can be lost, resulting in subsequent i_size_read() calls spinning forever. - */ + static inline void i_size_write(struct inode *inode, loff_t i_size) { #if BITS_PER_LONG==32 && defined(CONFIG_SMP) @@ -1712,8 +1705,6 @@ extern void __iget(struct inode * inode); extern void clear_inode(struct inode *); extern void destroy_inode(struct inode *); extern struct inode *new_inode(struct super_block *); -extern int __remove_suid(struct dentry *, int); -extern int should_remove_suid(struct dentry *); extern int remove_suid(struct dentry *); extern void remove_dquot_ref(struct super_block *, int, struct list_head *); @@ -1760,8 +1751,6 @@ extern ssize_t generic_file_splice_read(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int); extern ssize_t generic_file_splice_write(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int); -extern ssize_t generic_file_splice_write_nolock(struct pipe_inode_info *, - struct file *, loff_t *, size_t, unsigned int); extern ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe, struct file *out, loff_t *, size_t len, unsigned int flags); extern long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, diff --git a/trunk/include/linux/hiddev.h b/trunk/include/linux/hiddev.h index acbdae6d7ae1..945ba1ad14ac 100644 --- a/trunk/include/linux/hiddev.h +++ b/trunk/include/linux/hiddev.h @@ -222,7 +222,7 @@ struct hid_report; int hiddev_connect(struct hid_device *); void hiddev_disconnect(struct hid_device *); void hiddev_hid_event(struct hid_device *hid, struct hid_field *field, - struct hid_usage *usage, __s32 value); + struct hid_usage *usage, __s32 value, struct pt_regs *regs); void hiddev_report_event(struct hid_device *hid, struct hid_report *report); int __init hiddev_init(void); void hiddev_exit(void); @@ -230,7 +230,7 @@ void hiddev_exit(void); static inline int hiddev_connect(struct hid_device *hid) { return -1; } static inline void hiddev_disconnect(struct hid_device *hid) { } static inline void hiddev_hid_event(struct hid_device *hid, struct hid_field *field, - struct hid_usage *usage, __s32 value) { } + struct hid_usage *usage, __s32 value, struct pt_regs *regs) { } static inline void hiddev_report_event(struct hid_device *hid, struct hid_report *report) { } static inline int hiddev_init(void) { return 0; } static inline void hiddev_exit(void) { } diff --git a/trunk/include/linux/htirq.h b/trunk/include/linux/htirq.h index c96ea46737d0..1f15ce279a23 100644 --- a/trunk/include/linux/htirq.h +++ b/trunk/include/linux/htirq.h @@ -1,23 +1,15 @@ #ifndef LINUX_HTIRQ_H #define LINUX_HTIRQ_H -struct ht_irq_msg { - u32 address_lo; /* low 32 bits of the ht irq message */ - u32 address_hi; /* high 32 bits of the it irq message */ -}; - /* Helper functions.. */ -void fetch_ht_irq_msg(unsigned int irq, struct ht_irq_msg *msg); -void write_ht_irq_msg(unsigned int irq, struct ht_irq_msg *msg); +void write_ht_irq_low(unsigned int irq, u32 data); +void write_ht_irq_high(unsigned int irq, u32 data); +u32 read_ht_irq_low(unsigned int irq); +u32 read_ht_irq_high(unsigned int irq); void mask_ht_irq(unsigned int irq); void unmask_ht_irq(unsigned int irq); /* The arch hook for getting things started */ int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev); -/* For drivers of buggy hardware */ -typedef void (ht_irq_update_t)(struct pci_dev *dev, int irq, - struct ht_irq_msg *msg); -int __ht_create_irq(struct pci_dev *dev, int idx, ht_irq_update_t *update); - #endif /* LINUX_HTIRQ_H */ diff --git a/trunk/include/linux/hugetlb.h b/trunk/include/linux/hugetlb.h index ace64e57e17f..c25a38d8f600 100644 --- a/trunk/include/linux/hugetlb.h +++ b/trunk/include/linux/hugetlb.h @@ -17,7 +17,6 @@ int hugetlb_sysctl_handler(struct ctl_table *, int, struct file *, void __user * int copy_hugetlb_page_range(struct mm_struct *, struct mm_struct *, struct vm_area_struct *); int follow_hugetlb_page(struct mm_struct *, struct vm_area_struct *, struct page **, struct vm_area_struct **, unsigned long *, int *, int); void unmap_hugepage_range(struct vm_area_struct *, unsigned long, unsigned long); -void __unmap_hugepage_range(struct vm_area_struct *, unsigned long, unsigned long); int hugetlb_prefault(struct address_space *, struct vm_area_struct *); int hugetlb_report_meminfo(char *); int hugetlb_report_node_meminfo(int, char *); @@ -60,11 +59,8 @@ void hugetlb_free_pgd_range(struct mmu_gather **tlb, unsigned long addr, * If the arch doesn't supply something else, assume that hugepage * size aligned regions are ok without further preparation. */ -static inline int prepare_hugepage_range(unsigned long addr, unsigned long len, - pgoff_t pgoff) +static inline int prepare_hugepage_range(unsigned long addr, unsigned long len) { - if (pgoff & (~HPAGE_MASK >> PAGE_SHIFT)) - return -EINVAL; if (len & ~HPAGE_MASK) return -EINVAL; if (addr & ~HPAGE_MASK) @@ -72,8 +68,7 @@ static inline int prepare_hugepage_range(unsigned long addr, unsigned long len, return 0; } #else -int prepare_hugepage_range(unsigned long addr, unsigned long len, - pgoff_t pgoff); +int prepare_hugepage_range(unsigned long addr, unsigned long len); #endif #ifndef ARCH_HAS_SETCLEAR_HUGE_PTE @@ -111,7 +106,7 @@ static inline unsigned long hugetlb_total_pages(void) #define hugetlb_report_meminfo(buf) 0 #define hugetlb_report_node_meminfo(n, buf) 0 #define follow_huge_pmd(mm, addr, pmd, write) NULL -#define prepare_hugepage_range(addr,len,pgoff) (-EINVAL) +#define prepare_hugepage_range(addr, len) (-EINVAL) #define pmd_huge(x) 0 #define is_hugepage_only_range(mm, addr, len) 0 #define hugetlb_free_pgd_range(tlb, addr, end, floor, ceiling) ({BUG(); 0; }) diff --git a/trunk/include/linux/ide.h b/trunk/include/linux/ide.h index 9c2050293f17..07d8d725541f 100644 --- a/trunk/include/linux/ide.h +++ b/trunk/include/linux/ide.h @@ -1185,7 +1185,7 @@ extern void ide_stall_queue(ide_drive_t *drive, unsigned long timeout); extern int ide_spin_wait_hwgroup(ide_drive_t *); extern void ide_timer_expiry(unsigned long); -extern irqreturn_t ide_intr(int irq, void *dev_id); +extern irqreturn_t ide_intr(int irq, void *dev_id, struct pt_regs *regs); extern void do_ide_request(request_queue_t *); void ide_init_disk(struct gendisk *, ide_drive_t *); diff --git a/trunk/include/linux/if_vlan.h b/trunk/include/linux/if_vlan.h index 35cb38573583..ab2740832742 100644 --- a/trunk/include/linux/if_vlan.h +++ b/trunk/include/linux/if_vlan.h @@ -44,7 +44,7 @@ struct vlan_ethhdr { unsigned char h_source[ETH_ALEN]; /* source ether addr */ __be16 h_vlan_proto; /* Should always be 0x8100 */ __be16 h_vlan_TCI; /* Encapsulates priority and VLAN ID */ - __be16 h_vlan_encapsulated_proto; /* packet type ID field (or len) */ + unsigned short h_vlan_encapsulated_proto; /* packet type ID field (or len) */ }; #include diff --git a/trunk/include/linux/igmp.h b/trunk/include/linux/igmp.h index 21dd56905271..03f43e2893a4 100644 --- a/trunk/include/linux/igmp.h +++ b/trunk/include/linux/igmp.h @@ -191,7 +191,7 @@ struct ip_mc_list #define IGMPV3_MASK(value, nb) ((nb)>=32 ? (value) : ((1<<(nb))-1) & (value)) #define IGMPV3_EXP(thresh, nbmant, nbexp, value) \ ((value) < (thresh) ? (value) : \ - ((IGMPV3_MASK(value, nbmant) | (1<<(nbmant))) << \ + ((IGMPV3_MASK(value, nbmant) | (1<<(nbmant+nbexp))) << \ (IGMPV3_MASK((value) >> (nbmant), nbexp) + (nbexp)))) #define IGMPV3_QQIC(value) IGMPV3_EXP(0x80, 4, 3, value) diff --git a/trunk/include/linux/in6.h b/trunk/include/linux/in6.h index f28621f638e0..9be6a4756f0b 100644 --- a/trunk/include/linux/in6.h +++ b/trunk/include/linux/in6.h @@ -225,7 +225,7 @@ struct in6_flowlabel_req #endif /* - * Netfilter (1) + * Netfilter * * Following socket options are used in ip6_tables; * see include/linux/netfilter_ipv6/ip6_tables.h. @@ -240,14 +240,4 @@ struct in6_flowlabel_req #define IPV6_RECVTCLASS 66 #define IPV6_TCLASS 67 -/* - * Netfilter (2) - * - * Following socket options are used in ip6_tables; - * see include/linux/netfilter_ipv6/ip6_tables.h. - * - * IP6T_SO_GET_REVISION_MATCH 68 - * IP6T_SO_GET_REVISION_TARGET 69 - */ - #endif diff --git a/trunk/include/linux/init.h b/trunk/include/linux/init.h index 5eb5d24b7680..e92b1455d7af 100644 --- a/trunk/include/linux/init.h +++ b/trunk/include/linux/init.h @@ -84,37 +84,19 @@ extern void setup_arch(char **); * by link order. * For backwards compatibility, initcall() puts the call in * the device init subsection. - * - * The `id' arg to __define_initcall() is needed so that multiple initcalls - * can point at the same handler without causing duplicate-symbol build errors. */ -#define __define_initcall(level,fn,id) \ - static initcall_t __initcall_##fn##id __attribute_used__ \ +#define __define_initcall(level,fn) \ + static initcall_t __initcall_##fn __attribute_used__ \ __attribute__((__section__(".initcall" level ".init"))) = fn -/* - * A "pure" initcall has no dependencies on anything else, and purely - * initializes variables that couldn't be statically initialized. - * - * This only exists for built-in code, not for modules. - */ -#define pure_initcall(fn) __define_initcall("0",fn,1) - -#define core_initcall(fn) __define_initcall("1",fn,1) -#define core_initcall_sync(fn) __define_initcall("1s",fn,1s) -#define postcore_initcall(fn) __define_initcall("2",fn,2) -#define postcore_initcall_sync(fn) __define_initcall("2s",fn,2s) -#define arch_initcall(fn) __define_initcall("3",fn,3) -#define arch_initcall_sync(fn) __define_initcall("3s",fn,3s) -#define subsys_initcall(fn) __define_initcall("4",fn,4) -#define subsys_initcall_sync(fn) __define_initcall("4s",fn,4s) -#define fs_initcall(fn) __define_initcall("5",fn,5) -#define fs_initcall_sync(fn) __define_initcall("5s",fn,5s) -#define device_initcall(fn) __define_initcall("6",fn,6) -#define device_initcall_sync(fn) __define_initcall("6s",fn,6s) -#define late_initcall(fn) __define_initcall("7",fn,7) -#define late_initcall_sync(fn) __define_initcall("7s",fn,7s) +#define core_initcall(fn) __define_initcall("1",fn) +#define postcore_initcall(fn) __define_initcall("2",fn) +#define arch_initcall(fn) __define_initcall("3",fn) +#define subsys_initcall(fn) __define_initcall("4",fn) +#define fs_initcall(fn) __define_initcall("5",fn) +#define device_initcall(fn) __define_initcall("6",fn) +#define late_initcall(fn) __define_initcall("7",fn) #define __initcall(fn) device_initcall(fn) diff --git a/trunk/include/linux/input.h b/trunk/include/linux/input.h index c38507ba38b5..5770105471dd 100644 --- a/trunk/include/linux/input.h +++ b/trunk/include/linux/input.h @@ -953,6 +953,7 @@ struct input_dev { unsigned int repeat_key; struct timer_list timer; + struct pt_regs *regs; int state; int sync; @@ -1148,9 +1149,15 @@ static inline void input_report_switch(struct input_dev *dev, unsigned int code, input_event(dev, EV_SW, code, !!value); } +static inline void input_regs(struct input_dev *dev, struct pt_regs *regs) +{ + dev->regs = regs; +} + static inline void input_sync(struct input_dev *dev) { input_event(dev, EV_SYN, SYN_REPORT, 0); + dev->regs = NULL; } static inline void input_set_abs_params(struct input_dev *dev, int axis, int min, int max, int fuzz, int flat) diff --git a/trunk/include/linux/interrupt.h b/trunk/include/linux/interrupt.h index 5b83e7b59621..1f97e3d92639 100644 --- a/trunk/include/linux/interrupt.h +++ b/trunk/include/linux/interrupt.h @@ -64,10 +64,8 @@ #define SA_TRIGGER_RISING IRQF_TRIGGER_RISING #define SA_TRIGGER_MASK IRQF_TRIGGER_MASK -typedef irqreturn_t (*irq_handler_t)(int, void *); - struct irqaction { - irq_handler_t handler; + irqreturn_t (*handler)(int, void *, struct pt_regs *); unsigned long flags; cpumask_t mask; const char *name; @@ -77,8 +75,9 @@ struct irqaction { struct proc_dir_entry *dir; }; -extern irqreturn_t no_action(int cpl, void *dev_id); -extern int request_irq(unsigned int, irq_handler_t handler, +extern irqreturn_t no_action(int cpl, void *dev_id, struct pt_regs *regs); +extern int request_irq(unsigned int, + irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long, const char *, void *); extern void free_irq(unsigned int, void *); diff --git a/trunk/include/linux/io.h b/trunk/include/linux/io.h index 81877ea39309..aa3f5af670b5 100644 --- a/trunk/include/linux/io.h +++ b/trunk/include/linux/io.h @@ -18,7 +18,6 @@ #ifndef _LINUX_IO_H #define _LINUX_IO_H -#include #include #include @@ -28,31 +27,4 @@ void __iowrite64_copy(void __iomem *to, const void *from, size_t count); int ioremap_page_range(unsigned long addr, unsigned long end, unsigned long phys_addr, pgprot_t prot); -/** - * check_signature - find BIOS signatures - * @io_addr: mmio address to check - * @signature: signature block - * @length: length of signature - * - * Perform a signature comparison with the mmio address io_addr. This - * address should have been obtained by ioremap. - * Returns 1 on a match. - */ - -static inline int check_signature(const volatile void __iomem *io_addr, - const unsigned char *signature, int length) -{ - int retval = 0; - do { - if (readb(io_addr) != *signature) - goto out; - io_addr++; - signature++; - length--; - } while (length); - retval = 1; -out: - return retval; -} - #endif /* _LINUX_IO_H */ diff --git a/trunk/include/linux/ioc3.h b/trunk/include/linux/ioc3.h index 38b286e9a46c..da7c09e4ede6 100644 --- a/trunk/include/linux/ioc3.h +++ b/trunk/include/linux/ioc3.h @@ -63,7 +63,7 @@ struct ioc3_submodule { /* IRQ stuff */ unsigned int irq_mask; /* IOC3 IRQ mask, leave clear for Ethernet */ int reset_mask; /* non-zero if you want the ioc3.c module to reset interrupts */ - int (*intr) (struct ioc3_submodule *, struct ioc3_driver_data *, unsigned int); + int (*intr) (struct ioc3_submodule *, struct ioc3_driver_data *, unsigned int, struct pt_regs *); /* private submodule data */ void *data; /* assigned by submodule */ }; diff --git a/trunk/include/linux/ioc4.h b/trunk/include/linux/ioc4.h index 51e2b9fb6372..de73a3289cc2 100644 --- a/trunk/include/linux/ioc4.h +++ b/trunk/include/linux/ioc4.h @@ -157,7 +157,7 @@ struct ioc4_driver_data { unsigned long idd_bar0; struct pci_dev *idd_pdev; const struct pci_device_id *idd_pci_id; - struct ioc4_misc_regs __iomem *idd_misc_regs; + struct __iomem ioc4_misc_regs *idd_misc_regs; unsigned long count_period; void *idd_serial_data; unsigned int idd_variant; diff --git a/trunk/include/linux/ioport.h b/trunk/include/linux/ioport.h index cf8696d4a138..d42c83399071 100644 --- a/trunk/include/linux/ioport.h +++ b/trunk/include/linux/ioport.h @@ -89,7 +89,6 @@ struct resource_list { #define IORESOURCE_ROM_ENABLE (1<<0) /* ROM is enabled, same as PCI_ROM_ADDRESS_ENABLE */ #define IORESOURCE_ROM_SHADOW (1<<1) /* ROM is copy at C000:0 */ #define IORESOURCE_ROM_COPY (1<<2) /* ROM is alloc'd copy, resource field overlaid */ -#define IORESOURCE_ROM_BIOS_COPY (1<<3) /* ROM is BIOS copy, resource field overlaid */ /* PC/ISA/whatever - the normal PC address spaces: IO and memory */ extern struct resource ioport_resource; diff --git a/trunk/include/linux/ipmi_msgdefs.h b/trunk/include/linux/ipmi_msgdefs.h index 4d04d8b58a0a..22f5e2afda4f 100644 --- a/trunk/include/linux/ipmi_msgdefs.h +++ b/trunk/include/linux/ipmi_msgdefs.h @@ -75,8 +75,6 @@ #define IPMI_INVALID_COMMAND_ERR 0xc1 #define IPMI_ERR_MSG_TRUNCATED 0xc6 #define IPMI_LOST_ARBITRATION_ERR 0x81 -#define IPMI_BUS_ERR 0x82 -#define IPMI_NAK_ON_WRITE_ERR 0x83 #define IPMI_ERR_UNSPECIFIED 0xff #define IPMI_CHANNEL_PROTOCOL_IPMB 1 diff --git a/trunk/include/linux/ipx.h b/trunk/include/linux/ipx.h index eb19b4ea84f4..4f29c60964c4 100644 --- a/trunk/include/linux/ipx.h +++ b/trunk/include/linux/ipx.h @@ -7,8 +7,8 @@ struct sockaddr_ipx { sa_family_t sipx_family; - __be16 sipx_port; - __be32 sipx_network; + __u16 sipx_port; + __u32 sipx_network; unsigned char sipx_node[IPX_NODE_LEN]; __u8 sipx_type; unsigned char sipx_zero; /* 16 byte fill */ @@ -23,13 +23,13 @@ struct sockaddr_ipx { #define IPX_CRTITF 1 struct ipx_route_definition { - __be32 ipx_network; - __be32 ipx_router_network; + __u32 ipx_network; + __u32 ipx_router_network; unsigned char ipx_router_node[IPX_NODE_LEN]; }; struct ipx_interface_definition { - __be32 ipx_network; + __u32 ipx_network; unsigned char ipx_device[16]; unsigned char ipx_dlink_type; #define IPX_FRAME_NONE 0 @@ -55,8 +55,8 @@ struct ipx_config_data { */ struct ipx_route_def { - __be32 ipx_network; - __be32 ipx_router_network; + __u32 ipx_network; + __u32 ipx_router_network; #define IPX_ROUTE_NO_ROUTER 0 unsigned char ipx_router_node[IPX_NODE_LEN]; unsigned char ipx_device[16]; diff --git a/trunk/include/linux/irq.h b/trunk/include/linux/irq.h index 52fc4052a0ae..6f463606c318 100644 --- a/trunk/include/linux/irq.h +++ b/trunk/include/linux/irq.h @@ -21,12 +21,6 @@ #include #include -#include - -struct irq_desc; -typedef void fastcall (*irq_flow_handler_t)(unsigned int irq, - struct irq_desc *desc); - /* * IRQ line status. @@ -141,12 +135,13 @@ struct irq_chip { * @pending_mask: pending rebalanced interrupts * @dir: /proc/irq/ procfs entry * @affinity_entry: /proc/irq/smp_affinity procfs entry on SMP - * @name: flow handler name for /proc/interrupts output * * Pad this out to 32 bytes for cache and indexing reasons. */ struct irq_desc { - irq_flow_handler_t handle_irq; + void fastcall (*handle_irq)(unsigned int irq, + struct irq_desc *desc, + struct pt_regs *regs); struct irq_chip *chip; void *handler_data; void *chip_data; @@ -166,9 +161,8 @@ struct irq_desc { cpumask_t pending_mask; #endif #ifdef CONFIG_PROC_FS - struct proc_dir_entry *dir; + struct proc_dir_entry *dir; #endif - const char *name; } ____cacheline_aligned; extern struct irq_desc irq_desc[NR_IRQS]; @@ -260,25 +254,43 @@ static inline int select_smp_affinity(unsigned int irq) extern int no_irq_affinity; /* Handle irq action chains: */ -extern int handle_IRQ_event(unsigned int irq, struct irqaction *action); +extern int handle_IRQ_event(unsigned int irq, struct pt_regs *regs, + struct irqaction *action); /* * Built-in IRQ handlers for various IRQ types, * callable via desc->chip->handle_irq() */ -extern void fastcall handle_level_irq(unsigned int irq, struct irq_desc *desc); -extern void fastcall handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc); -extern void fastcall handle_edge_irq(unsigned int irq, struct irq_desc *desc); -extern void fastcall handle_simple_irq(unsigned int irq, struct irq_desc *desc); -extern void fastcall handle_percpu_irq(unsigned int irq, struct irq_desc *desc); -extern void fastcall handle_bad_irq(unsigned int irq, struct irq_desc *desc); +extern void fastcall +handle_level_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs); +extern void fastcall +handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc, + struct pt_regs *regs); +extern void fastcall +handle_edge_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs); +extern void fastcall +handle_simple_irq(unsigned int irq, struct irq_desc *desc, + struct pt_regs *regs); +extern void fastcall +handle_percpu_irq(unsigned int irq, struct irq_desc *desc, + struct pt_regs *regs); +extern void fastcall +handle_bad_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs); + +/* + * Get a descriptive string for the highlevel handler, for + * /proc/interrupts output: + */ +extern const char * +handle_irq_name(void fastcall (*handle)(unsigned int, struct irq_desc *, + struct pt_regs *)); /* * Monolithic do_IRQ implementation. * (is an explicit fastcall, because i386 4KSTACKS calls it from assembly) */ #ifndef CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ -extern fastcall unsigned int __do_IRQ(unsigned int irq); +extern fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs); #endif /* @@ -287,23 +299,23 @@ extern fastcall unsigned int __do_IRQ(unsigned int irq); * irqchip-style controller then we call the ->handle_irq() handler, * and it calls __do_IRQ() if it's attached to an irqtype-style controller. */ -static inline void generic_handle_irq(unsigned int irq) +static inline void generic_handle_irq(unsigned int irq, struct pt_regs *regs) { struct irq_desc *desc = irq_desc + irq; #ifdef CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ - desc->handle_irq(irq, desc); + desc->handle_irq(irq, desc, regs); #else if (likely(desc->handle_irq)) - desc->handle_irq(irq, desc); + desc->handle_irq(irq, desc, regs); else - __do_IRQ(irq); + __do_IRQ(irq, regs); #endif } /* Handling of unhandled and spurious interrupts: */ extern void note_interrupt(unsigned int irq, struct irq_desc *desc, - int action_ret); + int action_ret, struct pt_regs *regs); /* Resending of interrupts :*/ void check_irq_resend(struct irq_desc *desc, unsigned int irq); @@ -323,22 +335,24 @@ extern struct irq_chip dummy_irq_chip; extern void set_irq_chip_and_handler(unsigned int irq, struct irq_chip *chip, - irq_flow_handler_t handle); -extern void -set_irq_chip_and_handler_name(unsigned int irq, struct irq_chip *chip, - irq_flow_handler_t handle, const char *name); - + void fastcall (*handle)(unsigned int, + struct irq_desc *, + struct pt_regs *)); extern void -__set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained, - const char *name); +__set_irq_handler(unsigned int irq, + void fastcall (*handle)(unsigned int, struct irq_desc *, + struct pt_regs *), + int is_chained); /* * Set a highlevel flow handler for a given IRQ: */ static inline void -set_irq_handler(unsigned int irq, irq_flow_handler_t handle) +set_irq_handler(unsigned int irq, + void fastcall (*handle)(unsigned int, struct irq_desc *, + struct pt_regs *)) { - __set_irq_handler(irq, handle, 0, NULL); + __set_irq_handler(irq, handle, 0); } /* @@ -348,9 +362,10 @@ set_irq_handler(unsigned int irq, irq_flow_handler_t handle) */ static inline void set_irq_chained_handler(unsigned int irq, - irq_flow_handler_t handle) + void fastcall (*handle)(unsigned int, struct irq_desc *, + struct pt_regs *)) { - __set_irq_handler(irq, handle, 1, NULL); + __set_irq_handler(irq, handle, 1); } /* Handle dynamic irq creation and destruction */ diff --git a/trunk/include/linux/istallion.h b/trunk/include/linux/istallion.h index b55e2a035605..1f996621bc9c 100644 --- a/trunk/include/linux/istallion.h +++ b/trunk/include/linux/istallion.h @@ -100,7 +100,7 @@ typedef struct stlibrd { unsigned int iobase; int iosize; unsigned long memaddr; - void __iomem *membase; + void *membase; int memsize; int pagesize; int hostoffset; @@ -113,7 +113,7 @@ typedef struct stlibrd { void (*enable)(struct stlibrd *brdp); void (*reenable)(struct stlibrd *brdp); void (*disable)(struct stlibrd *brdp); - void __iomem *(*getmemptr)(struct stlibrd *brdp, unsigned long offset, int line); + char *(*getmemptr)(struct stlibrd *brdp, unsigned long offset, int line); void (*intr)(struct stlibrd *brdp); void (*reset)(struct stlibrd *brdp); stliport_t *ports[STL_MAXPORTS]; diff --git a/trunk/include/linux/ixjuser.h b/trunk/include/linux/ixjuser.h index 88b45895746d..fd1756d3a47e 100644 --- a/trunk/include/linux/ixjuser.h +++ b/trunk/include/linux/ixjuser.h @@ -315,7 +315,7 @@ typedef struct { * structures. If the freq0 variable is non-zero, the tone table contents * for the tone_index are updated to the frequencies and gains defined. It * should be noted that DTMF tones cannot be reassigned, so if DTMF tone -* table indexes are used in a cadence the frequency and gain variables will +* table indexs are used in a cadence the frequency and gain variables will * be ignored. * * If the array elements contain frequency parameters the driver will diff --git a/trunk/include/linux/jbd2.h b/trunk/include/linux/jbd2.h deleted file mode 100644 index ddb128795781..000000000000 --- a/trunk/include/linux/jbd2.h +++ /dev/null @@ -1,1107 +0,0 @@ -/* - * linux/include/linux/jbd2.h - * - * Written by Stephen C. Tweedie - * - * Copyright 1998-2000 Red Hat, Inc --- All Rights Reserved - * - * This file is part of the Linux kernel and is made available under - * the terms of the GNU General Public License, version 2, or at your - * option, any later version, incorporated herein by reference. - * - * Definitions for transaction data structures for the buffer cache - * filesystem journaling support. - */ - -#ifndef _LINUX_JBD_H -#define _LINUX_JBD_H - -/* Allow this file to be included directly into e2fsprogs */ -#ifndef __KERNEL__ -#include "jfs_compat.h" -#define JBD2_DEBUG -#define jfs_debug jbd_debug -#else - -#include -#include -#include -#include -#include -#include -#include - -#include -#endif - -#define journal_oom_retry 1 - -/* - * Define JBD_PARANIOD_IOFAIL to cause a kernel BUG() if ext3 finds - * certain classes of error which can occur due to failed IOs. Under - * normal use we want ext3 to continue after such errors, because - * hardware _can_ fail, but for debugging purposes when running tests on - * known-good hardware we may want to trap these errors. - */ -#undef JBD_PARANOID_IOFAIL - -/* - * The default maximum commit age, in seconds. - */ -#define JBD_DEFAULT_MAX_COMMIT_AGE 5 - -#ifdef CONFIG_JBD_DEBUG -/* - * Define JBD_EXPENSIVE_CHECKING to enable more expensive internal - * consistency checks. By default we don't do this unless - * CONFIG_JBD_DEBUG is on. - */ -#define JBD_EXPENSIVE_CHECKING -extern int jbd2_journal_enable_debug; - -#define jbd_debug(n, f, a...) \ - do { \ - if ((n) <= jbd2_journal_enable_debug) { \ - printk (KERN_DEBUG "(%s, %d): %s: ", \ - __FILE__, __LINE__, __FUNCTION__); \ - printk (f, ## a); \ - } \ - } while (0) -#else -#define jbd_debug(f, a...) /**/ -#endif - -extern void * __jbd2_kmalloc (const char *where, size_t size, gfp_t flags, int retry); -extern void * jbd2_slab_alloc(size_t size, gfp_t flags); -extern void jbd2_slab_free(void *ptr, size_t size); - -#define jbd_kmalloc(size, flags) \ - __jbd2_kmalloc(__FUNCTION__, (size), (flags), journal_oom_retry) -#define jbd_rep_kmalloc(size, flags) \ - __jbd2_kmalloc(__FUNCTION__, (size), (flags), 1) - -#define JBD2_MIN_JOURNAL_BLOCKS 1024 - -#ifdef __KERNEL__ - -/** - * typedef handle_t - The handle_t type represents a single atomic update being performed by some process. - * - * All filesystem modifications made by the process go - * through this handle. Recursive operations (such as quota operations) - * are gathered into a single update. - * - * The buffer credits field is used to account for journaled buffers - * being modified by the running process. To ensure that there is - * enough log space for all outstanding operations, we need to limit the - * number of outstanding buffers possible at any time. When the - * operation completes, any buffer credits not used are credited back to - * the transaction, so that at all times we know how many buffers the - * outstanding updates on a transaction might possibly touch. - * - * This is an opaque datatype. - **/ -typedef struct handle_s handle_t; /* Atomic operation type */ - - -/** - * typedef journal_t - The journal_t maintains all of the journaling state information for a single filesystem. - * - * journal_t is linked to from the fs superblock structure. - * - * We use the journal_t to keep track of all outstanding transaction - * activity on the filesystem, and to manage the state of the log - * writing process. - * - * This is an opaque datatype. - **/ -typedef struct journal_s journal_t; /* Journal control structure */ -#endif - -/* - * Internal structures used by the logging mechanism: - */ - -#define JBD2_MAGIC_NUMBER 0xc03b3998U /* The first 4 bytes of /dev/random! */ - -/* - * On-disk structures - */ - -/* - * Descriptor block types: - */ - -#define JBD2_DESCRIPTOR_BLOCK 1 -#define JBD2_COMMIT_BLOCK 2 -#define JBD2_SUPERBLOCK_V1 3 -#define JBD2_SUPERBLOCK_V2 4 -#define JBD2_REVOKE_BLOCK 5 - -/* - * Standard header for all descriptor blocks: - */ -typedef struct journal_header_s -{ - __be32 h_magic; - __be32 h_blocktype; - __be32 h_sequence; -} journal_header_t; - - -/* - * The block tag: used to describe a single buffer in the journal. - * t_blocknr_high is only used if INCOMPAT_64BIT is set, so this - * raw struct shouldn't be used for pointer math or sizeof() - use - * journal_tag_bytes(journal) instead to compute this. - */ -typedef struct journal_block_tag_s -{ - __be32 t_blocknr; /* The on-disk block number */ - __be32 t_flags; /* See below */ - __be32 t_blocknr_high; /* most-significant high 32bits. */ -} journal_block_tag_t; - -#define JBD_TAG_SIZE32 (offsetof(journal_block_tag_t, t_blocknr_high)) -#define JBD_TAG_SIZE64 (sizeof(journal_block_tag_t)) - -/* - * The revoke descriptor: used on disk to describe a series of blocks to - * be revoked from the log - */ -typedef struct jbd2_journal_revoke_header_s -{ - journal_header_t r_header; - __be32 r_count; /* Count of bytes used in the block */ -} jbd2_journal_revoke_header_t; - - -/* Definitions for the journal tag flags word: */ -#define JBD2_FLAG_ESCAPE 1 /* on-disk block is escaped */ -#define JBD2_FLAG_SAME_UUID 2 /* block has same uuid as previous */ -#define JBD2_FLAG_DELETED 4 /* block deleted by this transaction */ -#define JBD2_FLAG_LAST_TAG 8 /* last tag in this descriptor block */ - - -/* - * The journal superblock. All fields are in big-endian byte order. - */ -typedef struct journal_superblock_s -{ -/* 0x0000 */ - journal_header_t s_header; - -/* 0x000C */ - /* Static information describing the journal */ - __be32 s_blocksize; /* journal device blocksize */ - __be32 s_maxlen; /* total blocks in journal file */ - __be32 s_first; /* first block of log information */ - -/* 0x0018 */ - /* Dynamic information describing the current state of the log */ - __be32 s_sequence; /* first commit ID expected in log */ - __be32 s_start; /* blocknr of start of log */ - -/* 0x0020 */ - /* Error value, as set by jbd2_journal_abort(). */ - __be32 s_errno; - -/* 0x0024 */ - /* Remaining fields are only valid in a version-2 superblock */ - __be32 s_feature_compat; /* compatible feature set */ - __be32 s_feature_incompat; /* incompatible feature set */ - __be32 s_feature_ro_compat; /* readonly-compatible feature set */ -/* 0x0030 */ - __u8 s_uuid[16]; /* 128-bit uuid for journal */ - -/* 0x0040 */ - __be32 s_nr_users; /* Nr of filesystems sharing log */ - - __be32 s_dynsuper; /* Blocknr of dynamic superblock copy*/ - -/* 0x0048 */ - __be32 s_max_transaction; /* Limit of journal blocks per trans.*/ - __be32 s_max_trans_data; /* Limit of data blocks per trans. */ - -/* 0x0050 */ - __u32 s_padding[44]; - -/* 0x0100 */ - __u8 s_users[16*48]; /* ids of all fs'es sharing the log */ -/* 0x0400 */ -} journal_superblock_t; - -#define JBD2_HAS_COMPAT_FEATURE(j,mask) \ - ((j)->j_format_version >= 2 && \ - ((j)->j_superblock->s_feature_compat & cpu_to_be32((mask)))) -#define JBD2_HAS_RO_COMPAT_FEATURE(j,mask) \ - ((j)->j_format_version >= 2 && \ - ((j)->j_superblock->s_feature_ro_compat & cpu_to_be32((mask)))) -#define JBD2_HAS_INCOMPAT_FEATURE(j,mask) \ - ((j)->j_format_version >= 2 && \ - ((j)->j_superblock->s_feature_incompat & cpu_to_be32((mask)))) - -#define JBD2_FEATURE_INCOMPAT_REVOKE 0x00000001 -#define JBD2_FEATURE_INCOMPAT_64BIT 0x00000002 - -/* Features known to this kernel version: */ -#define JBD2_KNOWN_COMPAT_FEATURES 0 -#define JBD2_KNOWN_ROCOMPAT_FEATURES 0 -#define JBD2_KNOWN_INCOMPAT_FEATURES (JBD2_FEATURE_INCOMPAT_REVOKE | \ - JBD2_FEATURE_INCOMPAT_64BIT) - -#ifdef __KERNEL__ - -#include -#include - -#define JBD_ASSERTIONS -#ifdef JBD_ASSERTIONS -#define J_ASSERT(assert) \ -do { \ - if (!(assert)) { \ - printk (KERN_EMERG \ - "Assertion failure in %s() at %s:%d: \"%s\"\n", \ - __FUNCTION__, __FILE__, __LINE__, # assert); \ - BUG(); \ - } \ -} while (0) - -#if defined(CONFIG_BUFFER_DEBUG) -void buffer_assertion_failure(struct buffer_head *bh); -#define J_ASSERT_BH(bh, expr) \ - do { \ - if (!(expr)) \ - buffer_assertion_failure(bh); \ - J_ASSERT(expr); \ - } while (0) -#define J_ASSERT_JH(jh, expr) J_ASSERT_BH(jh2bh(jh), expr) -#else -#define J_ASSERT_BH(bh, expr) J_ASSERT(expr) -#define J_ASSERT_JH(jh, expr) J_ASSERT(expr) -#endif - -#else -#define J_ASSERT(assert) do { } while (0) -#endif /* JBD_ASSERTIONS */ - -#if defined(JBD_PARANOID_IOFAIL) -#define J_EXPECT(expr, why...) J_ASSERT(expr) -#define J_EXPECT_BH(bh, expr, why...) J_ASSERT_BH(bh, expr) -#define J_EXPECT_JH(jh, expr, why...) J_ASSERT_JH(jh, expr) -#else -#define __journal_expect(expr, why...) \ - ({ \ - int val = (expr); \ - if (!val) { \ - printk(KERN_ERR \ - "EXT3-fs unexpected failure: %s;\n",# expr); \ - printk(KERN_ERR why "\n"); \ - } \ - val; \ - }) -#define J_EXPECT(expr, why...) __journal_expect(expr, ## why) -#define J_EXPECT_BH(bh, expr, why...) __journal_expect(expr, ## why) -#define J_EXPECT_JH(jh, expr, why...) __journal_expect(expr, ## why) -#endif - -enum jbd_state_bits { - BH_JBD /* Has an attached ext3 journal_head */ - = BH_PrivateStart, - BH_JWrite, /* Being written to log (@@@ DEBUGGING) */ - BH_Freed, /* Has been freed (truncated) */ - BH_Revoked, /* Has been revoked from the log */ - BH_RevokeValid, /* Revoked flag is valid */ - BH_JBDDirty, /* Is dirty but journaled */ - BH_State, /* Pins most journal_head state */ - BH_JournalHead, /* Pins bh->b_private and jh->b_bh */ - BH_Unshadow, /* Dummy bit, for BJ_Shadow wakeup filtering */ -}; - -BUFFER_FNS(JBD, jbd) -BUFFER_FNS(JWrite, jwrite) -BUFFER_FNS(JBDDirty, jbddirty) -TAS_BUFFER_FNS(JBDDirty, jbddirty) -BUFFER_FNS(Revoked, revoked) -TAS_BUFFER_FNS(Revoked, revoked) -BUFFER_FNS(RevokeValid, revokevalid) -TAS_BUFFER_FNS(RevokeValid, revokevalid) -BUFFER_FNS(Freed, freed) - -static inline struct buffer_head *jh2bh(struct journal_head *jh) -{ - return jh->b_bh; -} - -static inline struct journal_head *bh2jh(struct buffer_head *bh) -{ - return bh->b_private; -} - -static inline void jbd_lock_bh_state(struct buffer_head *bh) -{ - bit_spin_lock(BH_State, &bh->b_state); -} - -static inline int jbd_trylock_bh_state(struct buffer_head *bh) -{ - return bit_spin_trylock(BH_State, &bh->b_state); -} - -static inline int jbd_is_locked_bh_state(struct buffer_head *bh) -{ - return bit_spin_is_locked(BH_State, &bh->b_state); -} - -static inline void jbd_unlock_bh_state(struct buffer_head *bh) -{ - bit_spin_unlock(BH_State, &bh->b_state); -} - -static inline void jbd_lock_bh_journal_head(struct buffer_head *bh) -{ - bit_spin_lock(BH_JournalHead, &bh->b_state); -} - -static inline void jbd_unlock_bh_journal_head(struct buffer_head *bh) -{ - bit_spin_unlock(BH_JournalHead, &bh->b_state); -} - -struct jbd2_revoke_table_s; - -/** - * struct handle_s - The handle_s type is the concrete type associated with - * handle_t. - * @h_transaction: Which compound transaction is this update a part of? - * @h_buffer_credits: Number of remaining buffers we are allowed to dirty. - * @h_ref: Reference count on this handle - * @h_err: Field for caller's use to track errors through large fs operations - * @h_sync: flag for sync-on-close - * @h_jdata: flag to force data journaling - * @h_aborted: flag indicating fatal error on handle - **/ - -/* Docbook can't yet cope with the bit fields, but will leave the documentation - * in so it can be fixed later. - */ - -struct handle_s -{ - /* Which compound transaction is this update a part of? */ - transaction_t *h_transaction; - - /* Number of remaining buffers we are allowed to dirty: */ - int h_buffer_credits; - - /* Reference count on this handle */ - int h_ref; - - /* Field for caller's use to track errors through large fs */ - /* operations */ - int h_err; - - /* Flags [no locking] */ - unsigned int h_sync: 1; /* sync-on-close */ - unsigned int h_jdata: 1; /* force data journaling */ - unsigned int h_aborted: 1; /* fatal error on handle */ -}; - - -/* The transaction_t type is the guts of the journaling mechanism. It - * tracks a compound transaction through its various states: - * - * RUNNING: accepting new updates - * LOCKED: Updates still running but we don't accept new ones - * RUNDOWN: Updates are tidying up but have finished requesting - * new buffers to modify (state not used for now) - * FLUSH: All updates complete, but we are still writing to disk - * COMMIT: All data on disk, writing commit record - * FINISHED: We still have to keep the transaction for checkpointing. - * - * The transaction keeps track of all of the buffers modified by a - * running transaction, and all of the buffers committed but not yet - * flushed to home for finished transactions. - */ - -/* - * Lock ranking: - * - * j_list_lock - * ->jbd_lock_bh_journal_head() (This is "innermost") - * - * j_state_lock - * ->jbd_lock_bh_state() - * - * jbd_lock_bh_state() - * ->j_list_lock - * - * j_state_lock - * ->t_handle_lock - * - * j_state_lock - * ->j_list_lock (journal_unmap_buffer) - * - */ - -struct transaction_s -{ - /* Pointer to the journal for this transaction. [no locking] */ - journal_t *t_journal; - - /* Sequence number for this transaction [no locking] */ - tid_t t_tid; - - /* - * Transaction's current state - * [no locking - only kjournald2 alters this] - * FIXME: needs barriers - * KLUDGE: [use j_state_lock] - */ - enum { - T_RUNNING, - T_LOCKED, - T_RUNDOWN, - T_FLUSH, - T_COMMIT, - T_FINISHED - } t_state; - - /* - * Where in the log does this transaction's commit start? [no locking] - */ - unsigned long t_log_start; - - /* Number of buffers on the t_buffers list [j_list_lock] */ - int t_nr_buffers; - - /* - * Doubly-linked circular list of all buffers reserved but not yet - * modified by this transaction [j_list_lock] - */ - struct journal_head *t_reserved_list; - - /* - * Doubly-linked circular list of all buffers under writeout during - * commit [j_list_lock] - */ - struct journal_head *t_locked_list; - - /* - * Doubly-linked circular list of all metadata buffers owned by this - * transaction [j_list_lock] - */ - struct journal_head *t_buffers; - - /* - * Doubly-linked circular list of all data buffers still to be - * flushed before this transaction can be committed [j_list_lock] - */ - struct journal_head *t_sync_datalist; - - /* - * Doubly-linked circular list of all forget buffers (superseded - * buffers which we can un-checkpoint once this transaction commits) - * [j_list_lock] - */ - struct journal_head *t_forget; - - /* - * Doubly-linked circular list of all buffers still to be flushed before - * this transaction can be checkpointed. [j_list_lock] - */ - struct journal_head *t_checkpoint_list; - - /* - * Doubly-linked circular list of all buffers submitted for IO while - * checkpointing. [j_list_lock] - */ - struct journal_head *t_checkpoint_io_list; - - /* - * Doubly-linked circular list of temporary buffers currently undergoing - * IO in the log [j_list_lock] - */ - struct journal_head *t_iobuf_list; - - /* - * Doubly-linked circular list of metadata buffers being shadowed by log - * IO. The IO buffers on the iobuf list and the shadow buffers on this - * list match each other one for one at all times. [j_list_lock] - */ - struct journal_head *t_shadow_list; - - /* - * Doubly-linked circular list of control buffers being written to the - * log. [j_list_lock] - */ - struct journal_head *t_log_list; - - /* - * Protects info related to handles - */ - spinlock_t t_handle_lock; - - /* - * Number of outstanding updates running on this transaction - * [t_handle_lock] - */ - int t_updates; - - /* - * Number of buffers reserved for use by all handles in this transaction - * handle but not yet modified. [t_handle_lock] - */ - int t_outstanding_credits; - - /* - * Forward and backward links for the circular list of all transactions - * awaiting checkpoint. [j_list_lock] - */ - transaction_t *t_cpnext, *t_cpprev; - - /* - * When will the transaction expire (become due for commit), in jiffies? - * [no locking] - */ - unsigned long t_expires; - - /* - * How many handles used this transaction? [t_handle_lock] - */ - int t_handle_count; - -}; - -/** - * struct journal_s - The journal_s type is the concrete type associated with - * journal_t. - * @j_flags: General journaling state flags - * @j_errno: Is there an outstanding uncleared error on the journal (from a - * prior abort)? - * @j_sb_buffer: First part of superblock buffer - * @j_superblock: Second part of superblock buffer - * @j_format_version: Version of the superblock format - * @j_state_lock: Protect the various scalars in the journal - * @j_barrier_count: Number of processes waiting to create a barrier lock - * @j_barrier: The barrier lock itself - * @j_running_transaction: The current running transaction.. - * @j_committing_transaction: the transaction we are pushing to disk - * @j_checkpoint_transactions: a linked circular list of all transactions - * waiting for checkpointing - * @j_wait_transaction_locked: Wait queue for waiting for a locked transaction - * to start committing, or for a barrier lock to be released - * @j_wait_logspace: Wait queue for waiting for checkpointing to complete - * @j_wait_done_commit: Wait queue for waiting for commit to complete - * @j_wait_checkpoint: Wait queue to trigger checkpointing - * @j_wait_commit: Wait queue to trigger commit - * @j_wait_updates: Wait queue to wait for updates to complete - * @j_checkpoint_mutex: Mutex for locking against concurrent checkpoints - * @j_head: Journal head - identifies the first unused block in the journal - * @j_tail: Journal tail - identifies the oldest still-used block in the - * journal. - * @j_free: Journal free - how many free blocks are there in the journal? - * @j_first: The block number of the first usable block - * @j_last: The block number one beyond the last usable block - * @j_dev: Device where we store the journal - * @j_blocksize: blocksize for the location where we store the journal. - * @j_blk_offset: starting block offset for into the device where we store the - * journal - * @j_fs_dev: Device which holds the client fs. For internal journal this will - * be equal to j_dev - * @j_maxlen: Total maximum capacity of the journal region on disk. - * @j_list_lock: Protects the buffer lists and internal buffer state. - * @j_inode: Optional inode where we store the journal. If present, all journal - * block numbers are mapped into this inode via bmap(). - * @j_tail_sequence: Sequence number of the oldest transaction in the log - * @j_transaction_sequence: Sequence number of the next transaction to grant - * @j_commit_sequence: Sequence number of the most recently committed - * transaction - * @j_commit_request: Sequence number of the most recent transaction wanting - * commit - * @j_uuid: Uuid of client object. - * @j_task: Pointer to the current commit thread for this journal - * @j_max_transaction_buffers: Maximum number of metadata buffers to allow in a - * single compound commit transaction - * @j_commit_interval: What is the maximum transaction lifetime before we begin - * a commit? - * @j_commit_timer: The timer used to wakeup the commit thread - * @j_revoke_lock: Protect the revoke table - * @j_revoke: The revoke table - maintains the list of revoked blocks in the - * current transaction. - * @j_revoke_table: alternate revoke tables for j_revoke - * @j_wbuf: array of buffer_heads for jbd2_journal_commit_transaction - * @j_wbufsize: maximum number of buffer_heads allowed in j_wbuf, the - * number that will fit in j_blocksize - * @j_last_sync_writer: most recent pid which did a synchronous write - * @j_private: An opaque pointer to fs-private information. - */ - -struct journal_s -{ - /* General journaling state flags [j_state_lock] */ - unsigned long j_flags; - - /* - * Is there an outstanding uncleared error on the journal (from a prior - * abort)? [j_state_lock] - */ - int j_errno; - - /* The superblock buffer */ - struct buffer_head *j_sb_buffer; - journal_superblock_t *j_superblock; - - /* Version of the superblock format */ - int j_format_version; - - /* - * Protect the various scalars in the journal - */ - spinlock_t j_state_lock; - - /* - * Number of processes waiting to create a barrier lock [j_state_lock] - */ - int j_barrier_count; - - /* The barrier lock itself */ - struct mutex j_barrier; - - /* - * Transactions: The current running transaction... - * [j_state_lock] [caller holding open handle] - */ - transaction_t *j_running_transaction; - - /* - * the transaction we are pushing to disk - * [j_state_lock] [caller holding open handle] - */ - transaction_t *j_committing_transaction; - - /* - * ... and a linked circular list of all transactions waiting for - * checkpointing. [j_list_lock] - */ - transaction_t *j_checkpoint_transactions; - - /* - * Wait queue for waiting for a locked transaction to start committing, - * or for a barrier lock to be released - */ - wait_queue_head_t j_wait_transaction_locked; - - /* Wait queue for waiting for checkpointing to complete */ - wait_queue_head_t j_wait_logspace; - - /* Wait queue for waiting for commit to complete */ - wait_queue_head_t j_wait_done_commit; - - /* Wait queue to trigger checkpointing */ - wait_queue_head_t j_wait_checkpoint; - - /* Wait queue to trigger commit */ - wait_queue_head_t j_wait_commit; - - /* Wait queue to wait for updates to complete */ - wait_queue_head_t j_wait_updates; - - /* Semaphore for locking against concurrent checkpoints */ - struct mutex j_checkpoint_mutex; - - /* - * Journal head: identifies the first unused block in the journal. - * [j_state_lock] - */ - unsigned long j_head; - - /* - * Journal tail: identifies the oldest still-used block in the journal. - * [j_state_lock] - */ - unsigned long j_tail; - - /* - * Journal free: how many free blocks are there in the journal? - * [j_state_lock] - */ - unsigned long j_free; - - /* - * Journal start and end: the block numbers of the first usable block - * and one beyond the last usable block in the journal. [j_state_lock] - */ - unsigned long j_first; - unsigned long j_last; - - /* - * Device, blocksize and starting block offset for the location where we - * store the journal. - */ - struct block_device *j_dev; - int j_blocksize; - unsigned long long j_blk_offset; - - /* - * Device which holds the client fs. For internal journal this will be - * equal to j_dev. - */ - struct block_device *j_fs_dev; - - /* Total maximum capacity of the journal region on disk. */ - unsigned int j_maxlen; - - /* - * Protects the buffer lists and internal buffer state. - */ - spinlock_t j_list_lock; - - /* Optional inode where we store the journal. If present, all */ - /* journal block numbers are mapped into this inode via */ - /* bmap(). */ - struct inode *j_inode; - - /* - * Sequence number of the oldest transaction in the log [j_state_lock] - */ - tid_t j_tail_sequence; - - /* - * Sequence number of the next transaction to grant [j_state_lock] - */ - tid_t j_transaction_sequence; - - /* - * Sequence number of the most recently committed transaction - * [j_state_lock]. - */ - tid_t j_commit_sequence; - - /* - * Sequence number of the most recent transaction wanting commit - * [j_state_lock] - */ - tid_t j_commit_request; - - /* - * Journal uuid: identifies the object (filesystem, LVM volume etc) - * backed by this journal. This will eventually be replaced by an array - * of uuids, allowing us to index multiple devices within a single - * journal and to perform atomic updates across them. - */ - __u8 j_uuid[16]; - - /* Pointer to the current commit thread for this journal */ - struct task_struct *j_task; - - /* - * Maximum number of metadata buffers to allow in a single compound - * commit transaction - */ - int j_max_transaction_buffers; - - /* - * What is the maximum transaction lifetime before we begin a commit? - */ - unsigned long j_commit_interval; - - /* The timer used to wakeup the commit thread: */ - struct timer_list j_commit_timer; - - /* - * The revoke table: maintains the list of revoked blocks in the - * current transaction. [j_revoke_lock] - */ - spinlock_t j_revoke_lock; - struct jbd2_revoke_table_s *j_revoke; - struct jbd2_revoke_table_s *j_revoke_table[2]; - - /* - * array of bhs for jbd2_journal_commit_transaction - */ - struct buffer_head **j_wbuf; - int j_wbufsize; - - pid_t j_last_sync_writer; - - /* - * An opaque pointer to fs-private information. ext3 puts its - * superblock pointer here - */ - void *j_private; -}; - -/* - * Journal flag definitions - */ -#define JBD2_UNMOUNT 0x001 /* Journal thread is being destroyed */ -#define JBD2_ABORT 0x002 /* Journaling has been aborted for errors. */ -#define JBD2_ACK_ERR 0x004 /* The errno in the sb has been acked */ -#define JBD2_FLUSHED 0x008 /* The journal superblock has been flushed */ -#define JBD2_LOADED 0x010 /* The journal superblock has been loaded */ -#define JBD2_BARRIER 0x020 /* Use IDE barriers */ - -/* - * Function declarations for the journaling transaction and buffer - * management - */ - -/* 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 *); -extern void jbd2_journal_refile_buffer(journal_t *, struct journal_head *); -extern void __jbd2_journal_file_buffer(struct journal_head *, transaction_t *, int); -extern void __journal_free_buffer(struct journal_head *bh); -extern void jbd2_journal_file_buffer(struct journal_head *, transaction_t *, int); -extern void __journal_clean_data_list(transaction_t *transaction); - -/* Log buffer allocation */ -extern struct journal_head * jbd2_journal_get_descriptor_buffer(journal_t *); -int jbd2_journal_next_log_block(journal_t *, unsigned long long *); - -/* Commit management */ -extern void jbd2_journal_commit_transaction(journal_t *); - -/* Checkpoint list management */ -int __jbd2_journal_clean_checkpoint_list(journal_t *journal); -int __jbd2_journal_remove_checkpoint(struct journal_head *); -void __jbd2_journal_insert_checkpoint(struct journal_head *, transaction_t *); - -/* Buffer IO */ -extern int -jbd2_journal_write_metadata_buffer(transaction_t *transaction, - struct journal_head *jh_in, - struct journal_head **jh_out, - unsigned long long blocknr); - -/* Transaction locking */ -extern void __wait_on_journal (journal_t *); - -/* - * Journal locking. - * - * We need to lock the journal during transaction state changes so that nobody - * ever tries to take a handle on the running transaction while we are in the - * middle of moving it to the commit phase. j_state_lock does this. - * - * Note that the locking is completely interrupt unsafe. We never touch - * journal structures from interrupts. - */ - -static inline handle_t *journal_current_handle(void) -{ - return current->journal_info; -} - -/* The journaling code user interface: - * - * Create and destroy handles - * Register buffer modifications against the current transaction. - */ - -extern handle_t *jbd2_journal_start(journal_t *, int nblocks); -extern int jbd2_journal_restart (handle_t *, int nblocks); -extern int jbd2_journal_extend (handle_t *, int nblocks); -extern int jbd2_journal_get_write_access(handle_t *, struct buffer_head *); -extern int jbd2_journal_get_create_access (handle_t *, struct buffer_head *); -extern int jbd2_journal_get_undo_access(handle_t *, struct buffer_head *); -extern int jbd2_journal_dirty_data (handle_t *, struct buffer_head *); -extern int jbd2_journal_dirty_metadata (handle_t *, struct buffer_head *); -extern void jbd2_journal_release_buffer (handle_t *, struct buffer_head *); -extern int jbd2_journal_forget (handle_t *, struct buffer_head *); -extern void journal_sync_buffer (struct buffer_head *); -extern void jbd2_journal_invalidatepage(journal_t *, - struct page *, unsigned long); -extern int jbd2_journal_try_to_free_buffers(journal_t *, struct page *, gfp_t); -extern int jbd2_journal_stop(handle_t *); -extern int jbd2_journal_flush (journal_t *); -extern void jbd2_journal_lock_updates (journal_t *); -extern void jbd2_journal_unlock_updates (journal_t *); - -extern journal_t * jbd2_journal_init_dev(struct block_device *bdev, - struct block_device *fs_dev, - unsigned long long start, int len, int bsize); -extern journal_t * jbd2_journal_init_inode (struct inode *); -extern int jbd2_journal_update_format (journal_t *); -extern int jbd2_journal_check_used_features - (journal_t *, unsigned long, unsigned long, unsigned long); -extern int jbd2_journal_check_available_features - (journal_t *, unsigned long, unsigned long, unsigned long); -extern int jbd2_journal_set_features - (journal_t *, unsigned long, unsigned long, unsigned long); -extern int jbd2_journal_create (journal_t *); -extern int jbd2_journal_load (journal_t *journal); -extern void jbd2_journal_destroy (journal_t *); -extern int jbd2_journal_recover (journal_t *journal); -extern int jbd2_journal_wipe (journal_t *, int); -extern int jbd2_journal_skip_recovery (journal_t *); -extern void jbd2_journal_update_superblock (journal_t *, int); -extern void __jbd2_journal_abort_hard (journal_t *); -extern void jbd2_journal_abort (journal_t *, int); -extern int jbd2_journal_errno (journal_t *); -extern void jbd2_journal_ack_err (journal_t *); -extern int jbd2_journal_clear_err (journal_t *); -extern int jbd2_journal_bmap(journal_t *, unsigned long, unsigned long long *); -extern int jbd2_journal_force_commit(journal_t *); - -/* - * journal_head management - */ -struct journal_head *jbd2_journal_add_journal_head(struct buffer_head *bh); -struct journal_head *jbd2_journal_grab_journal_head(struct buffer_head *bh); -void jbd2_journal_remove_journal_head(struct buffer_head *bh); -void jbd2_journal_put_journal_head(struct journal_head *jh); - -/* - * handle management - */ -extern kmem_cache_t *jbd2_handle_cache; - -static inline handle_t *jbd_alloc_handle(gfp_t gfp_flags) -{ - return kmem_cache_alloc(jbd2_handle_cache, gfp_flags); -} - -static inline void jbd_free_handle(handle_t *handle) -{ - kmem_cache_free(jbd2_handle_cache, handle); -} - -/* Primary revoke support */ -#define JOURNAL_REVOKE_DEFAULT_HASH 256 -extern int jbd2_journal_init_revoke(journal_t *, int); -extern void jbd2_journal_destroy_revoke_caches(void); -extern int jbd2_journal_init_revoke_caches(void); - -extern void jbd2_journal_destroy_revoke(journal_t *); -extern int jbd2_journal_revoke (handle_t *, unsigned long long, struct buffer_head *); -extern int jbd2_journal_cancel_revoke(handle_t *, struct journal_head *); -extern void jbd2_journal_write_revoke_records(journal_t *, transaction_t *); - -/* Recovery revoke support */ -extern int jbd2_journal_set_revoke(journal_t *, unsigned long long, tid_t); -extern int jbd2_journal_test_revoke(journal_t *, unsigned long long, tid_t); -extern void jbd2_journal_clear_revoke(journal_t *); -extern void jbd2_journal_switch_revoke_table(journal_t *journal); - -/* - * The log thread user interface: - * - * Request space in the current transaction, and force transaction commit - * transitions on demand. - */ - -int __jbd2_log_space_left(journal_t *); /* Called with journal locked */ -int jbd2_log_start_commit(journal_t *journal, tid_t tid); -int __jbd2_log_start_commit(journal_t *journal, tid_t tid); -int jbd2_journal_start_commit(journal_t *journal, tid_t *tid); -int jbd2_journal_force_commit_nested(journal_t *journal); -int jbd2_log_wait_commit(journal_t *journal, tid_t tid); -int jbd2_log_do_checkpoint(journal_t *journal); - -void __jbd2_log_wait_for_space(journal_t *journal); -extern void __jbd2_journal_drop_transaction(journal_t *, transaction_t *); -extern int jbd2_cleanup_journal_tail(journal_t *); - -/* Debugging code only: */ - -#define jbd_ENOSYS() \ -do { \ - printk (KERN_ERR "JBD unimplemented function %s\n", __FUNCTION__); \ - current->state = TASK_UNINTERRUPTIBLE; \ - schedule(); \ -} while (1) - -/* - * is_journal_abort - * - * Simple test wrapper function to test the JBD2_ABORT state flag. This - * bit, when set, indicates that we have had a fatal error somewhere, - * either inside the journaling layer or indicated to us by the client - * (eg. ext3), and that we and should not commit any further - * transactions. - */ - -static inline int is_journal_aborted(journal_t *journal) -{ - return journal->j_flags & JBD2_ABORT; -} - -static inline int is_handle_aborted(handle_t *handle) -{ - if (handle->h_aborted) - return 1; - return is_journal_aborted(handle->h_transaction->t_journal); -} - -static inline void jbd2_journal_abort_handle(handle_t *handle) -{ - handle->h_aborted = 1; -} - -#endif /* __KERNEL__ */ - -/* Comparison functions for transaction IDs: perform comparisons using - * modulo arithmetic so that they work over sequence number wraps. */ - -static inline int tid_gt(tid_t x, tid_t y) -{ - int difference = (x - y); - return (difference > 0); -} - -static inline int tid_geq(tid_t x, tid_t y) -{ - int difference = (x - y); - return (difference >= 0); -} - -extern int jbd2_journal_blocks_per_page(struct inode *inode); -extern size_t journal_tag_bytes(journal_t *journal); - -/* - * Return the minimum number of blocks which must be free in the journal - * before a new transaction may be started. Must be called under j_state_lock. - */ -static inline int jbd_space_needed(journal_t *journal) -{ - int nblocks = journal->j_max_transaction_buffers; - if (journal->j_committing_transaction) - nblocks += journal->j_committing_transaction-> - t_outstanding_credits; - return nblocks; -} - -/* - * Definitions which augment the buffer_head layer - */ - -/* journaling buffer types */ -#define BJ_None 0 /* Not journaled */ -#define BJ_SyncData 1 /* Normal data: flush before commit */ -#define BJ_Metadata 2 /* Normal journaled metadata */ -#define BJ_Forget 3 /* Buffer superseded by this transaction */ -#define BJ_IO 4 /* Buffer is for temporary IO use */ -#define BJ_Shadow 5 /* Buffer contents being shadowed to the log */ -#define BJ_LogCtl 6 /* Buffer contains log descriptors */ -#define BJ_Reserved 7 /* Buffer is reserved for access by journal */ -#define BJ_Locked 8 /* Locked for I/O during commit */ -#define BJ_Types 9 - -extern int jbd_blocks_per_page(struct inode *inode); - -#ifdef __KERNEL__ - -#define buffer_trace_init(bh) do {} while (0) -#define print_buffer_fields(bh) do {} while (0) -#define print_buffer_trace(bh) do {} while (0) -#define BUFFER_TRACE(bh, info) do {} while (0) -#define BUFFER_TRACE2(bh, bh2, info) do {} while (0) -#define JBUFFER_TRACE(jh, info) do {} while (0) - -#endif /* __KERNEL__ */ - -#endif /* _LINUX_JBD_H */ diff --git a/trunk/include/linux/jiffies.h b/trunk/include/linux/jiffies.h index 0ec6e28bccd2..c8d5f207c3d4 100644 --- a/trunk/include/linux/jiffies.h +++ b/trunk/include/linux/jiffies.h @@ -74,7 +74,7 @@ #define __jiffy_data __attribute__((section(".data"))) /* - * The 64-bit value is not atomic - you MUST NOT read it + * The 64-bit value is not volatile - you MUST NOT read it * without sampling the sequence number in xtime_lock. * get_jiffies_64() will do this for you as appropriate. */ diff --git a/trunk/include/linux/kernel.h b/trunk/include/linux/kernel.h index 6738283ac385..80f39cab470a 100644 --- a/trunk/include/linux/kernel.h +++ b/trunk/include/linux/kernel.h @@ -30,10 +30,8 @@ extern const char linux_banner[]; #define STACK_MAGIC 0xdeadbeef -#define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1) -#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask)) - #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#define ALIGN(x,a) (((x)+(a)-1UL)&~((a)-1UL)) #define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f)) #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) #define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y)) @@ -65,7 +63,7 @@ struct user; * context (spinlock, irq-handler, ...). * * This is a useful debugging help to be able to catch problems early and not - * be bitten later when the calling function happens to sleep when it is not + * be biten later when the calling function happens to sleep when it is not * supposed to. */ #ifdef CONFIG_PREEMPT_VOLUNTARY @@ -173,8 +171,6 @@ __attribute_const__ roundup_pow_of_two(unsigned long x) extern int printk_ratelimit(void); extern int __printk_ratelimit(int ratelimit_jiffies, int ratelimit_burst); -extern bool printk_timed_ratelimit(unsigned long *caller_jiffies, - unsigned int interval_msec); static inline void console_silent(void) { diff --git a/trunk/include/linux/kexec.h b/trunk/include/linux/kexec.h index a4ede62b339d..6427949ddf99 100644 --- a/trunk/include/linux/kexec.h +++ b/trunk/include/linux/kexec.h @@ -122,8 +122,6 @@ extern struct kimage *kexec_crash_image; #define KEXEC_ARCH_IA_64 (50 << 16) #define KEXEC_ARCH_S390 (22 << 16) #define KEXEC_ARCH_SH (42 << 16) -#define KEXEC_ARCH_MIPS_LE (10 << 16) -#define KEXEC_ARCH_MIPS ( 8 << 16) #define KEXEC_FLAGS (KEXEC_ON_CRASH) /* List of defined/legal kexec flags */ diff --git a/trunk/include/linux/kobject.h b/trunk/include/linux/kobject.h index d1c8d28fa92e..bcd9cd173c2c 100644 --- a/trunk/include/linux/kobject.h +++ b/trunk/include/linux/kobject.h @@ -47,7 +47,6 @@ enum kobject_action { KOBJ_UMOUNT = (__force kobject_action_t) 0x05, /* umount event for block devices (broken) */ KOBJ_OFFLINE = (__force kobject_action_t) 0x06, /* device offline */ KOBJ_ONLINE = (__force kobject_action_t) 0x07, /* device online */ - KOBJ_MOVE = (__force kobject_action_t) 0x08, /* device move */ }; struct kobject { @@ -77,7 +76,6 @@ extern int __must_check kobject_add(struct kobject *); extern void kobject_del(struct kobject *); extern int __must_check kobject_rename(struct kobject *, const char *new_name); -extern int __must_check kobject_move(struct kobject *, struct kobject *); extern int __must_check kobject_register(struct kobject *); extern void kobject_unregister(struct kobject *); @@ -266,8 +264,6 @@ extern int __must_check subsys_create_file(struct subsystem * , #if defined(CONFIG_HOTPLUG) void kobject_uevent(struct kobject *kobj, enum kobject_action action); -void kobject_uevent_env(struct kobject *kobj, enum kobject_action action, - char *envp[]); int add_uevent_var(char **envp, int num_envp, int *cur_index, char *buffer, int buffer_size, int *cur_len, @@ -275,10 +271,6 @@ int add_uevent_var(char **envp, int num_envp, int *cur_index, __attribute__((format (printf, 7, 8))); #else static inline void kobject_uevent(struct kobject *kobj, enum kobject_action action) { } -static inline void kobject_uevent_env(struct kobject *kobj, - enum kobject_action action, - char *envp[]) -{ } static inline int add_uevent_var(char **envp, int num_envp, int *cur_index, char *buffer, int buffer_size, int *cur_len, diff --git a/trunk/include/linux/libata.h b/trunk/include/linux/libata.h index abd2debebca2..d1af1dbeaeb4 100644 --- a/trunk/include/linux/libata.h +++ b/trunk/include/linux/libata.h @@ -143,7 +143,7 @@ enum { ATA_DFLAG_CFG_MASK = (1 << 8) - 1, ATA_DFLAG_PIO = (1 << 8), /* device limited to PIO mode */ - ATA_DFLAG_NCQ_OFF = (1 << 9), /* device limited to non-NCQ mode */ + ATA_DFLAG_NCQ_OFF = (1 << 9), /* devied limited to non-NCQ mode */ ATA_DFLAG_SUSPENDED = (1 << 10), /* device suspended */ ATA_DFLAG_INIT_MASK = (1 << 16) - 1, @@ -628,7 +628,7 @@ struct ata_port_operations { void (*error_handler) (struct ata_port *ap); void (*post_internal_cmd) (struct ata_queued_cmd *qc); - irq_handler_t irq_handler; + irqreturn_t (*irq_handler)(int, void *, struct pt_regs *); void (*irq_clear) (struct ata_port *); u32 (*scr_read) (struct ata_port *ap, unsigned int sc_reg); @@ -702,6 +702,7 @@ extern int ata_std_prereset(struct ata_port *ap); extern int ata_std_softreset(struct ata_port *ap, unsigned int *classes); extern int sata_std_hardreset(struct ata_port *ap, unsigned int *class); extern void ata_std_postreset(struct ata_port *ap, unsigned int *classes); +extern int ata_dev_revalidate(struct ata_device *dev, int post_reset); extern void ata_port_disable(struct ata_port *); extern void ata_std_ports(struct ata_ioports *ioaddr); #ifdef CONFIG_PCI @@ -768,7 +769,7 @@ extern void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf) extern int ata_port_start (struct ata_port *ap); extern void ata_port_stop (struct ata_port *ap); extern void ata_host_stop (struct ata_host *host); -extern irqreturn_t ata_interrupt (int irq, void *dev_instance); +extern irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs); extern void ata_mmio_data_xfer(struct ata_device *adev, unsigned char *buf, unsigned int buflen, int write_data); extern void ata_pio_data_xfer(struct ata_device *adev, unsigned char *buf, diff --git a/trunk/include/linux/lockd/bind.h b/trunk/include/linux/lockd/bind.h index aa50d89eacd7..81e3a185f951 100644 --- a/trunk/include/linux/lockd/bind.h +++ b/trunk/include/linux/lockd/bind.h @@ -10,11 +10,6 @@ #define LINUX_LOCKD_BIND_H #include -/* need xdr-encoded error codes too, so... */ -#include -#ifdef CONFIG_LOCKD_V4 -#include -#endif /* Dummy declarations */ struct svc_rqst; diff --git a/trunk/include/linux/lockd/lockd.h b/trunk/include/linux/lockd/lockd.h index 862d9730a60d..2909619c0295 100644 --- a/trunk/include/linux/lockd/lockd.h +++ b/trunk/include/linux/lockd/lockd.h @@ -154,7 +154,7 @@ int nlm_async_reply(struct nlm_rqst *, u32, const struct rpc_call_ops *); struct nlm_wait * nlmclnt_prepare_block(struct nlm_host *host, struct file_lock *fl); void nlmclnt_finish_block(struct nlm_wait *block); int nlmclnt_block(struct nlm_wait *block, struct nlm_rqst *req, long timeout); -__be32 nlmclnt_grant(const struct sockaddr_in *addr, const struct nlm_lock *); +u32 nlmclnt_grant(const struct sockaddr_in *addr, const struct nlm_lock *); void nlmclnt_recovery(struct nlm_host *); int nlmclnt_reclaim(struct nlm_host *, struct file_lock *); void nlmclnt_next_cookie(struct nlm_cookie *); @@ -184,12 +184,12 @@ typedef int (*nlm_host_match_fn_t)(struct nlm_host *cur, struct nlm_host *ref) /* * Server-side lock handling */ -__be32 nlmsvc_lock(struct svc_rqst *, struct nlm_file *, +u32 nlmsvc_lock(struct svc_rqst *, struct nlm_file *, struct nlm_lock *, int, struct nlm_cookie *); -__be32 nlmsvc_unlock(struct nlm_file *, struct nlm_lock *); -__be32 nlmsvc_testlock(struct nlm_file *, struct nlm_lock *, +u32 nlmsvc_unlock(struct nlm_file *, struct nlm_lock *); +u32 nlmsvc_testlock(struct nlm_file *, struct nlm_lock *, struct nlm_lock *); -__be32 nlmsvc_cancel_blocked(struct nlm_file *, struct nlm_lock *); +u32 nlmsvc_cancel_blocked(struct nlm_file *, struct nlm_lock *); unsigned long nlmsvc_retry_blocked(void); void nlmsvc_traverse_blocks(struct nlm_host *, struct nlm_file *, nlm_host_match_fn_t match); @@ -198,7 +198,7 @@ void nlmsvc_grant_reply(struct nlm_cookie *, u32); /* * File handling for the server personality */ -__be32 nlm_lookup_file(struct svc_rqst *, struct nlm_file **, +u32 nlm_lookup_file(struct svc_rqst *, struct nlm_file **, struct nfs_fh *); void nlm_release_file(struct nlm_file *); void nlmsvc_mark_resources(void); diff --git a/trunk/include/linux/lockd/share.h b/trunk/include/linux/lockd/share.h index 630c5bf69b07..cd7816e74c05 100644 --- a/trunk/include/linux/lockd/share.h +++ b/trunk/include/linux/lockd/share.h @@ -21,9 +21,9 @@ struct nlm_share { u32 s_mode; /* deny mode */ }; -__be32 nlmsvc_share_file(struct nlm_host *, struct nlm_file *, +u32 nlmsvc_share_file(struct nlm_host *, struct nlm_file *, struct nlm_args *); -__be32 nlmsvc_unshare_file(struct nlm_host *, struct nlm_file *, +u32 nlmsvc_unshare_file(struct nlm_host *, struct nlm_file *, struct nlm_args *); void nlmsvc_traverse_shares(struct nlm_host *, struct nlm_file *, nlm_host_match_fn_t); diff --git a/trunk/include/linux/lockd/xdr.h b/trunk/include/linux/lockd/xdr.h index 29e7d9fc9dad..bb0a0f1caa91 100644 --- a/trunk/include/linux/lockd/xdr.h +++ b/trunk/include/linux/lockd/xdr.h @@ -13,8 +13,6 @@ #include #include -struct svc_rqst; - #define NLM_MAXCOOKIELEN 32 #define NLM_MAXSTRLEN 1024 @@ -24,8 +22,6 @@ struct svc_rqst; #define nlm_lck_blocked __constant_htonl(NLM_LCK_BLOCKED) #define nlm_lck_denied_grace_period __constant_htonl(NLM_LCK_DENIED_GRACE_PERIOD) -#define nlm_drop_reply __constant_htonl(30000) - /* Lock info passed via NLM */ struct nlm_lock { char * caller; @@ -90,19 +86,19 @@ struct nlm_reboot { */ #define NLMSVC_XDRSIZE sizeof(struct nlm_args) -int nlmsvc_decode_testargs(struct svc_rqst *, __be32 *, struct nlm_args *); -int nlmsvc_encode_testres(struct svc_rqst *, __be32 *, struct nlm_res *); -int nlmsvc_decode_lockargs(struct svc_rqst *, __be32 *, struct nlm_args *); -int nlmsvc_decode_cancargs(struct svc_rqst *, __be32 *, struct nlm_args *); -int nlmsvc_decode_unlockargs(struct svc_rqst *, __be32 *, struct nlm_args *); -int nlmsvc_encode_res(struct svc_rqst *, __be32 *, struct nlm_res *); -int nlmsvc_decode_res(struct svc_rqst *, __be32 *, struct nlm_res *); -int nlmsvc_encode_void(struct svc_rqst *, __be32 *, void *); -int nlmsvc_decode_void(struct svc_rqst *, __be32 *, void *); -int nlmsvc_decode_shareargs(struct svc_rqst *, __be32 *, struct nlm_args *); -int nlmsvc_encode_shareres(struct svc_rqst *, __be32 *, struct nlm_res *); -int nlmsvc_decode_notify(struct svc_rqst *, __be32 *, struct nlm_args *); -int nlmsvc_decode_reboot(struct svc_rqst *, __be32 *, struct nlm_reboot *); +int nlmsvc_decode_testargs(struct svc_rqst *, u32 *, struct nlm_args *); +int nlmsvc_encode_testres(struct svc_rqst *, u32 *, struct nlm_res *); +int nlmsvc_decode_lockargs(struct svc_rqst *, u32 *, struct nlm_args *); +int nlmsvc_decode_cancargs(struct svc_rqst *, u32 *, struct nlm_args *); +int nlmsvc_decode_unlockargs(struct svc_rqst *, u32 *, struct nlm_args *); +int nlmsvc_encode_res(struct svc_rqst *, u32 *, struct nlm_res *); +int nlmsvc_decode_res(struct svc_rqst *, u32 *, struct nlm_res *); +int nlmsvc_encode_void(struct svc_rqst *, u32 *, void *); +int nlmsvc_decode_void(struct svc_rqst *, u32 *, void *); +int nlmsvc_decode_shareargs(struct svc_rqst *, u32 *, struct nlm_args *); +int nlmsvc_encode_shareres(struct svc_rqst *, u32 *, struct nlm_res *); +int nlmsvc_decode_notify(struct svc_rqst *, u32 *, struct nlm_args *); +int nlmsvc_decode_reboot(struct svc_rqst *, u32 *, struct nlm_reboot *); /* int nlmclt_encode_testargs(struct rpc_rqst *, u32 *, struct nlm_args *); int nlmclt_encode_lockargs(struct rpc_rqst *, u32 *, struct nlm_args *); diff --git a/trunk/include/linux/lockd/xdr4.h b/trunk/include/linux/lockd/xdr4.h index dd12b4c9e613..3cc1ae25009b 100644 --- a/trunk/include/linux/lockd/xdr4.h +++ b/trunk/include/linux/lockd/xdr4.h @@ -23,19 +23,19 @@ -int nlm4svc_decode_testargs(struct svc_rqst *, __be32 *, struct nlm_args *); -int nlm4svc_encode_testres(struct svc_rqst *, __be32 *, struct nlm_res *); -int nlm4svc_decode_lockargs(struct svc_rqst *, __be32 *, struct nlm_args *); -int nlm4svc_decode_cancargs(struct svc_rqst *, __be32 *, struct nlm_args *); -int nlm4svc_decode_unlockargs(struct svc_rqst *, __be32 *, struct nlm_args *); -int nlm4svc_encode_res(struct svc_rqst *, __be32 *, struct nlm_res *); -int nlm4svc_decode_res(struct svc_rqst *, __be32 *, struct nlm_res *); -int nlm4svc_encode_void(struct svc_rqst *, __be32 *, void *); -int nlm4svc_decode_void(struct svc_rqst *, __be32 *, void *); -int nlm4svc_decode_shareargs(struct svc_rqst *, __be32 *, struct nlm_args *); -int nlm4svc_encode_shareres(struct svc_rqst *, __be32 *, struct nlm_res *); -int nlm4svc_decode_notify(struct svc_rqst *, __be32 *, struct nlm_args *); -int nlm4svc_decode_reboot(struct svc_rqst *, __be32 *, struct nlm_reboot *); +int nlm4svc_decode_testargs(struct svc_rqst *, u32 *, struct nlm_args *); +int nlm4svc_encode_testres(struct svc_rqst *, u32 *, struct nlm_res *); +int nlm4svc_decode_lockargs(struct svc_rqst *, u32 *, struct nlm_args *); +int nlm4svc_decode_cancargs(struct svc_rqst *, u32 *, struct nlm_args *); +int nlm4svc_decode_unlockargs(struct svc_rqst *, u32 *, struct nlm_args *); +int nlm4svc_encode_res(struct svc_rqst *, u32 *, struct nlm_res *); +int nlm4svc_decode_res(struct svc_rqst *, u32 *, struct nlm_res *); +int nlm4svc_encode_void(struct svc_rqst *, u32 *, void *); +int nlm4svc_decode_void(struct svc_rqst *, u32 *, void *); +int nlm4svc_decode_shareargs(struct svc_rqst *, u32 *, struct nlm_args *); +int nlm4svc_encode_shareres(struct svc_rqst *, u32 *, struct nlm_res *); +int nlm4svc_decode_notify(struct svc_rqst *, u32 *, struct nlm_args *); +int nlm4svc_decode_reboot(struct svc_rqst *, u32 *, struct nlm_reboot *); /* int nlmclt_encode_testargs(struct rpc_rqst *, u32 *, struct nlm_args *); int nlmclt_encode_lockargs(struct rpc_rqst *, u32 *, struct nlm_args *); diff --git a/trunk/include/linux/lockdep.h b/trunk/include/linux/lockdep.h index 819f08f1310d..1314ca0f29be 100644 --- a/trunk/include/linux/lockdep.h +++ b/trunk/include/linux/lockdep.h @@ -202,7 +202,7 @@ extern int lockdep_internal(void); */ extern void lockdep_init_map(struct lockdep_map *lock, const char *name, - struct lock_class_key *key, int subclass); + struct lock_class_key *key); /* * Reinitialize a lock key - for cases where there is special locking or @@ -211,14 +211,9 @@ extern void lockdep_init_map(struct lockdep_map *lock, const char *name, * or they are too narrow (they suffer from a false class-split): */ #define lockdep_set_class(lock, key) \ - lockdep_init_map(&(lock)->dep_map, #key, key, 0) + lockdep_init_map(&(lock)->dep_map, #key, key) #define lockdep_set_class_and_name(lock, key, name) \ - lockdep_init_map(&(lock)->dep_map, name, key, 0) -#define lockdep_set_class_and_subclass(lock, key, sub) \ - lockdep_init_map(&(lock)->dep_map, #key, key, sub) -#define lockdep_set_subclass(lock, sub) \ - lockdep_init_map(&(lock)->dep_map, #lock, \ - (lock)->dep_map.key, sub) + lockdep_init_map(&(lock)->dep_map, name, key) /* * Acquire a lock. @@ -262,14 +257,10 @@ static inline int lockdep_internal(void) # define lock_release(l, n, i) do { } while (0) # define lockdep_init() do { } while (0) # define lockdep_info() do { } while (0) -# define lockdep_init_map(lock, name, key, sub) do { (void)(key); } while (0) +# define lockdep_init_map(lock, name, key) do { (void)(key); } while (0) # define lockdep_set_class(lock, key) do { (void)(key); } while (0) # define lockdep_set_class_and_name(lock, key, name) \ do { (void)(key); } while (0) -#define lockdep_set_class_and_subclass(lock, key, sub) \ - do { (void)(key); } while (0) -#define lockdep_set_subclass(lock, sub) do { } while (0) - # define INIT_LOCKDEP # define lockdep_reset() do { debug_locks = 1; } while (0) # define lockdep_free_key_range(start, size) do { } while (0) diff --git a/trunk/include/linux/magic.h b/trunk/include/linux/magic.h index 156c40fc664e..22036dd2ba36 100644 --- a/trunk/include/linux/magic.h +++ b/trunk/include/linux/magic.h @@ -8,7 +8,6 @@ #define EFS_SUPER_MAGIC 0x414A53 #define EXT2_SUPER_MAGIC 0xEF53 #define EXT3_SUPER_MAGIC 0xEF53 -#define EXT4_SUPER_MAGIC 0xEF53 #define HPFS_SUPER_MAGIC 0xf995e849 #define ISOFS_SUPER_MAGIC 0x9660 #define JFFS2_SUPER_MAGIC 0x72b6 diff --git a/trunk/include/linux/mempolicy.h b/trunk/include/linux/mempolicy.h index daabb3aa1ec6..09f0f575ddff 100644 --- a/trunk/include/linux/mempolicy.h +++ b/trunk/include/linux/mempolicy.h @@ -150,7 +150,7 @@ extern void mpol_rebind_mm(struct mm_struct *mm, nodemask_t *new); extern void mpol_fix_fork_child_flag(struct task_struct *p); #define set_cpuset_being_rebound(x) (cpuset_being_rebound = (x)) -#ifdef CONFIG_CPUSETS +#ifdef CONFIG_CPUSET #define current_cpuset_is_being_rebound() \ (cpuset_being_rebound == current->cpuset) #else diff --git a/trunk/include/linux/miscdevice.h b/trunk/include/linux/miscdevice.h index 326da7d500c7..b03cfb91e228 100644 --- a/trunk/include/linux/miscdevice.h +++ b/trunk/include/linux/miscdevice.h @@ -31,14 +31,15 @@ #define HPET_MINOR 228 struct device; +struct class_device; struct miscdevice { int minor; const char *name; const struct file_operations *fops; struct list_head list; - struct device *parent; - struct device *this_device; + struct device *dev; + struct class_device *class; }; extern int misc_register(struct miscdevice * misc); diff --git a/trunk/include/linux/mm.h b/trunk/include/linux/mm.h index d538de901965..b7966ab8cb6a 100644 --- a/trunk/include/linux/mm.h +++ b/trunk/include/linux/mm.h @@ -593,7 +593,6 @@ static inline int page_mapped(struct page *page) */ #define NOPAGE_SIGBUS (NULL) #define NOPAGE_OOM ((struct page *) (-1)) -#define NOPAGE_REFAULT ((struct page *) (-2)) /* Return to userspace, rerun */ /* * Error return values for the *_nopfn functions @@ -1103,7 +1102,12 @@ static inline void vm_stat_account(struct mm_struct *mm, #ifndef CONFIG_DEBUG_PAGEALLOC static inline void -kernel_map_pages(struct page *page, int numpages, int enable) {} +kernel_map_pages(struct page *page, int numpages, int enable) +{ + if (!PageHighMem(page) && !enable) + debug_check_no_locks_freed(page_address(page), + numpages * PAGE_SIZE); +} #endif extern struct vm_area_struct *get_gate_vma(struct task_struct *tsk); @@ -1115,6 +1119,9 @@ int in_gate_area_no_task(unsigned long addr); #define in_gate_area(task, addr) ({(void)task; in_gate_area_no_task(addr);}) #endif /* __HAVE_ARCH_GATE_AREA */ +/* /proc//oom_adj set to -17 protects from the oom-killer */ +#define OOM_DISABLE -17 + int drop_caches_sysctl_handler(struct ctl_table *, int, struct file *, void __user *, size_t *, loff_t *); unsigned long shrink_slab(unsigned long scanned, gfp_t gfp_mask, diff --git a/trunk/include/linux/mmc/host.h b/trunk/include/linux/mmc/host.h index 528e7d3fecb1..587264a58d56 100644 --- a/trunk/include/linux/mmc/host.h +++ b/trunk/include/linux/mmc/host.h @@ -74,8 +74,8 @@ struct mmc_card; struct device; struct mmc_host { - struct device *parent; - struct device class_dev; + struct device *dev; + struct class_device class_dev; int index; const struct mmc_host_ops *ops; unsigned int f_min; @@ -125,8 +125,8 @@ static inline void *mmc_priv(struct mmc_host *host) return (void *)host->private; } -#define mmc_dev(x) ((x)->parent) -#define mmc_hostname(x) ((x)->class_dev.bus_id) +#define mmc_dev(x) ((x)->dev) +#define mmc_hostname(x) ((x)->class_dev.class_id) extern int mmc_suspend_host(struct mmc_host *, pm_message_t); extern int mmc_resume_host(struct mmc_host *); diff --git a/trunk/include/linux/mmc/protocol.h b/trunk/include/linux/mmc/protocol.h index 08dec8d9e703..81c3f77f652c 100644 --- a/trunk/include/linux/mmc/protocol.h +++ b/trunk/include/linux/mmc/protocol.h @@ -83,7 +83,6 @@ /* Application commands */ #define SD_APP_SET_BUS_WIDTH 6 /* ac [1:0] bus width R1 */ -#define SD_APP_SEND_NUM_WR_BLKS 22 /* adtc R1 */ #define SD_APP_OP_COND 41 /* bcr [31:0] OCR R3 */ #define SD_APP_SEND_SCR 51 /* adtc R1 */ diff --git a/trunk/include/linux/mmzone.h b/trunk/include/linux/mmzone.h index e06683e2bea3..59855b8718a0 100644 --- a/trunk/include/linux/mmzone.h +++ b/trunk/include/linux/mmzone.h @@ -218,9 +218,13 @@ struct zone { * under - it drives the swappiness decision: whether to unmap mapped * pages. * - * Access to both this field is quite racy even on uniprocessor. But + * temp_priority is used to remember the scanning priority at which + * this zone was successfully refilled to free_pages == pages_high. + * + * Access to both these fields is quite racy even on uniprocessor. But * it is expected to average out OK. */ + int temp_priority; int prev_priority; @@ -670,12 +674,6 @@ void sparse_init(void); #define sparse_index_init(_sec, _nid) do {} while (0) #endif /* CONFIG_SPARSEMEM */ -#ifdef CONFIG_NODES_SPAN_OTHER_NODES -#define early_pfn_in_nid(pfn, nid) (early_pfn_to_nid(pfn) == (nid)) -#else -#define early_pfn_in_nid(pfn, nid) (1) -#endif - #ifndef early_pfn_valid #define early_pfn_valid(pfn) (1) #endif diff --git a/trunk/include/linux/module.h b/trunk/include/linux/module.h index 9258ffd8a7f0..4b2d8091a410 100644 --- a/trunk/include/linux/module.h +++ b/trunk/include/linux/module.h @@ -264,7 +264,6 @@ struct module struct module_attribute *modinfo_attrs; const char *version; const char *srcversion; - struct kobject *drivers_dir; /* Exported symbols */ const struct kernel_symbol *syms; @@ -318,6 +317,9 @@ struct module /* Am I unsafe to unload? */ int unsafe; + /* Am I GPL-compatible */ + int license_gplok; + unsigned int taints; /* same bits as kernel:tainted */ #ifdef CONFIG_MODULE_UNLOAD diff --git a/trunk/include/linux/mqueue.h b/trunk/include/linux/mqueue.h index 8b5a79615fbf..8db9d75541a6 100644 --- a/trunk/include/linux/mqueue.h +++ b/trunk/include/linux/mqueue.h @@ -18,6 +18,8 @@ #ifndef _LINUX_MQUEUE_H #define _LINUX_MQUEUE_H +#include + #define MQ_PRIO_MAX 32768 /* per-uid limit of kernel memory used by mqueue, in bytes */ #define MQ_BYTES_MAX 819200 diff --git a/trunk/include/linux/msdos_fs.h b/trunk/include/linux/msdos_fs.h index 24a9ef1506b6..ce6c85815cbd 100644 --- a/trunk/include/linux/msdos_fs.h +++ b/trunk/include/linux/msdos_fs.h @@ -402,8 +402,6 @@ extern const struct file_operations fat_file_operations; extern struct inode_operations fat_file_inode_operations; extern int fat_notify_change(struct dentry * dentry, struct iattr * attr); extern void fat_truncate(struct inode *inode); -extern int fat_getattr(struct vfsmount *mnt, struct dentry *dentry, - struct kstat *stat); /* fat/inode.c */ extern void fat_attach(struct inode *inode, loff_t i_pos); diff --git a/trunk/include/linux/mtd/nand.h b/trunk/include/linux/mtd/nand.h index 8b3ef4187219..70420bbae82b 100644 --- a/trunk/include/linux/mtd/nand.h +++ b/trunk/include/linux/mtd/nand.h @@ -355,7 +355,7 @@ struct nand_buffers { * @priv: [OPTIONAL] pointer to private chip date * @errstat: [OPTIONAL] hardware specific function to perform additional error status checks * (determine if errors are correctable) - * @write_page: [REPLACEABLE] High-level page write function + * @write_page [REPLACEABLE] High-level page write function */ struct nand_chip { diff --git a/trunk/include/linux/nbd.h b/trunk/include/linux/nbd.h index d6b6dc09ad97..e712e7d47cc2 100644 --- a/trunk/include/linux/nbd.h +++ b/trunk/include/linux/nbd.h @@ -15,8 +15,6 @@ #ifndef LINUX_NBD_H #define LINUX_NBD_H -#include - #define NBD_SET_SOCK _IO( 0xab, 0 ) #define NBD_SET_BLKSIZE _IO( 0xab, 1 ) #define NBD_SET_SIZE _IO( 0xab, 2 ) diff --git a/trunk/include/linux/net.h b/trunk/include/linux/net.h index 15c733b816f0..c257f716e00f 100644 --- a/trunk/include/linux/net.h +++ b/trunk/include/linux/net.h @@ -19,7 +19,6 @@ #define _LINUX_NET_H #include -#include #include struct poll_table_struct; @@ -194,9 +193,9 @@ extern int sock_map_fd(struct socket *sock); extern struct socket *sockfd_lookup(int fd, int *err); #define sockfd_put(sock) fput(sock->file) extern int net_ratelimit(void); - -#define net_random() random32() -#define net_srandom(seed) srandom32(seed) +extern unsigned long net_random(void); +extern void net_srandom(unsigned long); +extern void net_random_init(void); extern int kernel_sendmsg(struct socket *sock, struct msghdr *msg, struct kvec *vec, size_t num, size_t len); diff --git a/trunk/include/linux/netdevice.h b/trunk/include/linux/netdevice.h index 83b8c4f1d69d..9264139bd8df 100644 --- a/trunk/include/linux/netdevice.h +++ b/trunk/include/linux/netdevice.h @@ -93,10 +93,8 @@ struct netpoll_info; #endif #endif -#if !defined(CONFIG_NET_IPIP) && !defined(CONFIG_NET_IPIP_MODULE) && \ - !defined(CONFIG_NET_IPGRE) && !defined(CONFIG_NET_IPGRE_MODULE) && \ - !defined(CONFIG_IPV6_SIT) && !defined(CONFIG_IPV6_SIT_MODULE) && \ - !defined(CONFIG_IPV6_TUNNEL) && !defined(CONFIG_IPV6_TUNNEL_MODULE) +#if !defined(CONFIG_NET_IPIP) && \ + !defined(CONFIG_IPV6) && !defined(CONFIG_IPV6_MODULE) #define MAX_HEADER LL_MAX_HEADER #else #define MAX_HEADER (LL_MAX_HEADER + 48) diff --git a/trunk/include/linux/netfilter/x_tables.h b/trunk/include/linux/netfilter/x_tables.h index 022edfa97ed9..04319a76103a 100644 --- a/trunk/include/linux/netfilter/x_tables.h +++ b/trunk/include/linux/netfilter/x_tables.h @@ -96,6 +96,22 @@ struct _xt_align /* Error verdict. */ #define XT_ERROR_TARGET "ERROR" +/* + * New IP firewall options for [gs]etsockopt at the RAW IP level. + * Unlike BSD Linux inherits IP options so you don't have to use a raw + * socket for this. Instead we check rights in the calls. */ +#define XT_BASE_CTL 64 /* base for firewall socket options */ + +#define XT_SO_SET_REPLACE (XT_BASE_CTL) +#define XT_SO_SET_ADD_COUNTERS (XT_BASE_CTL + 1) +#define XT_SO_SET_MAX XT_SO_SET_ADD_COUNTERS + +#define XT_SO_GET_INFO (XT_BASE_CTL) +#define XT_SO_GET_ENTRIES (XT_BASE_CTL + 1) +#define XT_SO_GET_REVISION_MATCH (XT_BASE_CTL + 2) +#define XT_SO_GET_REVISION_TARGET (XT_BASE_CTL + 3) +#define XT_SO_GET_MAX XT_SO_GET_REVISION_TARGET + #define SET_COUNTER(c,b,p) do { (c).bcnt = (b); (c).pcnt = (p); } while(0) #define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0) diff --git a/trunk/include/linux/netfilter_arp/arp_tables.h b/trunk/include/linux/netfilter_arp/arp_tables.h index 0be235418a2f..44e39b61d9e7 100644 --- a/trunk/include/linux/netfilter_arp/arp_tables.h +++ b/trunk/include/linux/netfilter_arp/arp_tables.h @@ -112,20 +112,19 @@ struct arpt_entry * New IP firewall options for [gs]etsockopt at the RAW IP level. * Unlike BSD Linux inherits IP options so you don't have to use a raw * socket for this. Instead we check rights in the calls. - * - * ATTENTION: check linux/in.h before adding new number here. */ -#define ARPT_BASE_CTL 96 - -#define ARPT_SO_SET_REPLACE (ARPT_BASE_CTL) -#define ARPT_SO_SET_ADD_COUNTERS (ARPT_BASE_CTL + 1) -#define ARPT_SO_SET_MAX ARPT_SO_SET_ADD_COUNTERS - -#define ARPT_SO_GET_INFO (ARPT_BASE_CTL) -#define ARPT_SO_GET_ENTRIES (ARPT_BASE_CTL + 1) -/* #define ARPT_SO_GET_REVISION_MATCH (APRT_BASE_CTL + 2) */ -#define ARPT_SO_GET_REVISION_TARGET (ARPT_BASE_CTL + 3) -#define ARPT_SO_GET_MAX (ARPT_SO_GET_REVISION_TARGET) +#define ARPT_CTL_OFFSET 32 +#define ARPT_BASE_CTL (XT_BASE_CTL+ARPT_CTL_OFFSET) + +#define ARPT_SO_SET_REPLACE (XT_SO_SET_REPLACE+ARPT_CTL_OFFSET) +#define ARPT_SO_SET_ADD_COUNTERS (XT_SO_SET_ADD_COUNTERS+ARPT_CTL_OFFSET) +#define ARPT_SO_SET_MAX (XT_SO_SET_MAX+ARPT_CTL_OFFSET) + +#define ARPT_SO_GET_INFO (XT_SO_GET_INFO+ARPT_CTL_OFFSET) +#define ARPT_SO_GET_ENTRIES (XT_SO_GET_ENTRIES+ARPT_CTL_OFFSET) +/* #define ARPT_SO_GET_REVISION_MATCH XT_SO_GET_REVISION_MATCH */ +#define ARPT_SO_GET_REVISION_TARGET (XT_SO_GET_REVISION_TARGET+ARPT_CTL_OFFSET) +#define ARPT_SO_GET_MAX (XT_SO_GET_REVISION_TARGET+ARPT_CTL_OFFSET) /* CONTINUE verdict for targets */ #define ARPT_CONTINUE XT_CONTINUE diff --git a/trunk/include/linux/netfilter_ipv4/ip_tables.h b/trunk/include/linux/netfilter_ipv4/ip_tables.h index 4f06dad0bde9..a536bbdef145 100644 --- a/trunk/include/linux/netfilter_ipv4/ip_tables.h +++ b/trunk/include/linux/netfilter_ipv4/ip_tables.h @@ -101,21 +101,18 @@ struct ipt_entry /* * New IP firewall options for [gs]etsockopt at the RAW IP level. * Unlike BSD Linux inherits IP options so you don't have to use a raw - * socket for this. Instead we check rights in the calls. - * - * ATTENTION: check linux/in.h before adding new number here. - */ -#define IPT_BASE_CTL 64 - -#define IPT_SO_SET_REPLACE (IPT_BASE_CTL) -#define IPT_SO_SET_ADD_COUNTERS (IPT_BASE_CTL + 1) -#define IPT_SO_SET_MAX IPT_SO_SET_ADD_COUNTERS - -#define IPT_SO_GET_INFO (IPT_BASE_CTL) -#define IPT_SO_GET_ENTRIES (IPT_BASE_CTL + 1) -#define IPT_SO_GET_REVISION_MATCH (IPT_BASE_CTL + 2) -#define IPT_SO_GET_REVISION_TARGET (IPT_BASE_CTL + 3) -#define IPT_SO_GET_MAX IPT_SO_GET_REVISION_TARGET + * socket for this. Instead we check rights in the calls. */ +#define IPT_BASE_CTL XT_BASE_CTL + +#define IPT_SO_SET_REPLACE XT_SO_SET_REPLACE +#define IPT_SO_SET_ADD_COUNTERS XT_SO_SET_ADD_COUNTERS +#define IPT_SO_SET_MAX XT_SO_SET_MAX + +#define IPT_SO_GET_INFO XT_SO_GET_INFO +#define IPT_SO_GET_ENTRIES XT_SO_GET_ENTRIES +#define IPT_SO_GET_REVISION_MATCH XT_SO_GET_REVISION_MATCH +#define IPT_SO_GET_REVISION_TARGET XT_SO_GET_REVISION_TARGET +#define IPT_SO_GET_MAX XT_SO_GET_REVISION_TARGET #define IPT_CONTINUE XT_CONTINUE #define IPT_RETURN XT_RETURN diff --git a/trunk/include/linux/netfilter_ipv6/ip6_tables.h b/trunk/include/linux/netfilter_ipv6/ip6_tables.h index 4aed340401db..d7a8e9c0dad0 100644 --- a/trunk/include/linux/netfilter_ipv6/ip6_tables.h +++ b/trunk/include/linux/netfilter_ipv6/ip6_tables.h @@ -107,21 +107,18 @@ struct ip6t_entry /* * New IP firewall options for [gs]etsockopt at the RAW IP level. * Unlike BSD Linux inherits IP options so you don't have to use - * a raw socket for this. Instead we check rights in the calls. - * - * ATTENTION: check linux/in6.h before adding new number here. - */ -#define IP6T_BASE_CTL 64 - -#define IP6T_SO_SET_REPLACE (IP6T_BASE_CTL) -#define IP6T_SO_SET_ADD_COUNTERS (IP6T_BASE_CTL + 1) -#define IP6T_SO_SET_MAX IP6T_SO_SET_ADD_COUNTERS - -#define IP6T_SO_GET_INFO (IP6T_BASE_CTL) -#define IP6T_SO_GET_ENTRIES (IP6T_BASE_CTL + 1) -#define IP6T_SO_GET_REVISION_MATCH (IP6T_BASE_CTL + 4) -#define IP6T_SO_GET_REVISION_TARGET (IP6T_BASE_CTL + 5) -#define IP6T_SO_GET_MAX IP6T_SO_GET_REVISION_TARGET + * a raw socket for this. Instead we check rights in the calls. */ +#define IP6T_BASE_CTL XT_BASE_CTL + +#define IP6T_SO_SET_REPLACE XT_SO_SET_REPLACE +#define IP6T_SO_SET_ADD_COUNTERS XT_SO_SET_ADD_COUNTERS +#define IP6T_SO_SET_MAX XT_SO_SET_MAX + +#define IP6T_SO_GET_INFO XT_SO_GET_INFO +#define IP6T_SO_GET_ENTRIES XT_SO_GET_ENTRIES +#define IP6T_SO_GET_REVISION_MATCH XT_SO_GET_REVISION_MATCH +#define IP6T_SO_GET_REVISION_TARGET XT_SO_GET_REVISION_TARGET +#define IP6T_SO_GET_MAX XT_SO_GET_REVISION_TARGET /* CONTINUE verdict for targets */ #define IP6T_CONTINUE XT_CONTINUE diff --git a/trunk/include/linux/nfs_fs.h b/trunk/include/linux/nfs_fs.h index 45228c1a1195..76ff54846ada 100644 --- a/trunk/include/linux/nfs_fs.h +++ b/trunk/include/linux/nfs_fs.h @@ -157,7 +157,7 @@ struct nfs_inode { * This is the cookie verifier used for NFSv3 readdir * operations */ - __be32 cookieverf[2]; + __u32 cookieverf[2]; /* * This is the list of dirty unwritten pages. @@ -290,7 +290,6 @@ static inline int nfs_verify_change_attribute(struct inode *inode, unsigned long * linux/fs/nfs/inode.c */ extern int nfs_sync_mapping(struct address_space *mapping); -extern void nfs_zap_mapping(struct inode *inode, struct address_space *mapping); extern void nfs_zap_caches(struct inode *); extern struct inode *nfs_fhget(struct super_block *, struct nfs_fh *, struct nfs_fattr *); diff --git a/trunk/include/linux/nfs_xdr.h b/trunk/include/linux/nfs_xdr.h index 768c1ad5ff6f..dc5397d9d23c 100644 --- a/trunk/include/linux/nfs_xdr.h +++ b/trunk/include/linux/nfs_xdr.h @@ -266,7 +266,7 @@ struct nfs_writeargs { struct nfs_writeverf { enum nfs3_stable_how committed; - __be32 verifier[2]; + __u32 verifier[2]; }; struct nfs_writeres { @@ -420,7 +420,7 @@ struct nfs3_createargs { unsigned int len; struct iattr * sattr; enum nfs3_createmode createmode; - __be32 verifier[2]; + __u32 verifier[2]; }; struct nfs3_mkdirargs { @@ -467,7 +467,7 @@ struct nfs3_linkargs { struct nfs3_readdirargs { struct nfs_fh * fh; __u64 cookie; - __be32 verf[2]; + __u32 verf[2]; int plus; unsigned int count; struct page ** pages; @@ -503,7 +503,7 @@ struct nfs3_linkres { struct nfs3_readdirres { struct nfs_fattr * dir_attr; - __be32 * verf; + __u32 * verf; int plus; }; @@ -811,7 +811,7 @@ struct nfs_rpc_ops { int (*pathconf) (struct nfs_server *, struct nfs_fh *, struct nfs_pathconf *); int (*set_capabilities)(struct nfs_server *, struct nfs_fh *); - __be32 *(*decode_dirent)(__be32 *, struct nfs_entry *, int plus); + u32 * (*decode_dirent)(u32 *, struct nfs_entry *, int plus); void (*read_setup) (struct nfs_read_data *); int (*read_done) (struct rpc_task *, struct nfs_read_data *); void (*write_setup) (struct nfs_write_data *, int how); diff --git a/trunk/include/linux/nfsd/cache.h b/trunk/include/linux/nfsd/cache.h index 007480cd6a60..c3a3557c2a5b 100644 --- a/trunk/include/linux/nfsd/cache.h +++ b/trunk/include/linux/nfsd/cache.h @@ -26,14 +26,14 @@ struct svc_cacherep { c_type, /* status, buffer */ c_secure : 1; /* req came from port < 1024 */ struct sockaddr_in c_addr; - __be32 c_xid; + u32 c_xid; u32 c_prot; u32 c_proc; u32 c_vers; unsigned long c_timestamp; union { struct kvec u_vec; - __be32 u_status; + u32 u_status; } c_u; }; @@ -75,7 +75,7 @@ enum { void nfsd_cache_init(void); void nfsd_cache_shutdown(void); int nfsd_cache_lookup(struct svc_rqst *, int); -void nfsd_cache_update(struct svc_rqst *, int, __be32 *); +void nfsd_cache_update(struct svc_rqst *, int, u32 *); #endif /* __KERNEL__ */ #endif /* NFSCACHE_H */ diff --git a/trunk/include/linux/nfsd/export.h b/trunk/include/linux/nfsd/export.h index 045e38cdbe64..6e78ea969f49 100644 --- a/trunk/include/linux/nfsd/export.h +++ b/trunk/include/linux/nfsd/export.h @@ -117,8 +117,8 @@ struct svc_export * exp_parent(struct auth_domain *clp, struct cache_req *reqp); int exp_rootfh(struct auth_domain *, char *path, struct knfsd_fh *, int maxsize); -__be32 exp_pseudoroot(struct auth_domain *, struct svc_fh *fhp, struct cache_req *creq); -__be32 nfserrno(int errno); +int exp_pseudoroot(struct auth_domain *, struct svc_fh *fhp, struct cache_req *creq); +int nfserrno(int errno); extern struct cache_detail svc_export_cache; diff --git a/trunk/include/linux/nfsd/nfsd.h b/trunk/include/linux/nfsd/nfsd.h index edb54c3171b3..d0d4aae7085f 100644 --- a/trunk/include/linux/nfsd/nfsd.h +++ b/trunk/include/linux/nfsd/nfsd.h @@ -50,7 +50,7 @@ * Callback function for readdir */ struct readdir_cd { - __be32 err; /* 0, nfserr, or nfserr_eof */ + int err; /* 0, nfserr, or nfserr_eof */ }; typedef int (*encode_dent_fn)(struct readdir_cd *, const char *, int, loff_t, ino_t, unsigned int); @@ -64,7 +64,7 @@ extern struct svc_serv *nfsd_serv; * Function prototypes. */ int nfsd_svc(unsigned short port, int nrservs); -int nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp); +int nfsd_dispatch(struct svc_rqst *rqstp, u32 *statp); /* nfsd/vfs.c */ int fh_lock_parent(struct svc_fh *, struct dentry *); @@ -72,57 +72,57 @@ int nfsd_racache_init(int); void nfsd_racache_shutdown(void); int nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp, struct svc_export **expp); -__be32 nfsd_lookup(struct svc_rqst *, struct svc_fh *, +int nfsd_lookup(struct svc_rqst *, struct svc_fh *, const char *, int, struct svc_fh *); -__be32 nfsd_setattr(struct svc_rqst *, struct svc_fh *, +int nfsd_setattr(struct svc_rqst *, struct svc_fh *, struct iattr *, int, time_t); #ifdef CONFIG_NFSD_V4 -__be32 nfsd4_set_nfs4_acl(struct svc_rqst *, struct svc_fh *, +int nfsd4_set_nfs4_acl(struct svc_rqst *, struct svc_fh *, struct nfs4_acl *); int nfsd4_get_nfs4_acl(struct svc_rqst *, struct dentry *, struct nfs4_acl **); #endif /* CONFIG_NFSD_V4 */ -__be32 nfsd_create(struct svc_rqst *, struct svc_fh *, +int nfsd_create(struct svc_rqst *, struct svc_fh *, char *name, int len, struct iattr *attrs, int type, dev_t rdev, struct svc_fh *res); #ifdef CONFIG_NFSD_V3 -__be32 nfsd_access(struct svc_rqst *, struct svc_fh *, u32 *, u32 *); -__be32 nfsd_create_v3(struct svc_rqst *, struct svc_fh *, +int nfsd_access(struct svc_rqst *, struct svc_fh *, u32 *, u32 *); +int nfsd_create_v3(struct svc_rqst *, struct svc_fh *, char *name, int len, struct iattr *attrs, struct svc_fh *res, int createmode, - u32 *verifier, int *truncp, int *created); -__be32 nfsd_commit(struct svc_rqst *, struct svc_fh *, + u32 *verifier, int *truncp); +int nfsd_commit(struct svc_rqst *, struct svc_fh *, loff_t, unsigned long); #endif /* CONFIG_NFSD_V3 */ -__be32 nfsd_open(struct svc_rqst *, struct svc_fh *, int, +int nfsd_open(struct svc_rqst *, struct svc_fh *, int, int, struct file **); void nfsd_close(struct file *); -__be32 nfsd_read(struct svc_rqst *, struct svc_fh *, struct file *, +int nfsd_read(struct svc_rqst *, struct svc_fh *, struct file *, loff_t, struct kvec *, int, unsigned long *); -__be32 nfsd_write(struct svc_rqst *, struct svc_fh *,struct file *, +int nfsd_write(struct svc_rqst *, struct svc_fh *,struct file *, loff_t, struct kvec *,int, unsigned long, int *); -__be32 nfsd_readlink(struct svc_rqst *, struct svc_fh *, +int nfsd_readlink(struct svc_rqst *, struct svc_fh *, char *, int *); -__be32 nfsd_symlink(struct svc_rqst *, struct svc_fh *, +int nfsd_symlink(struct svc_rqst *, struct svc_fh *, char *name, int len, char *path, int plen, struct svc_fh *res, struct iattr *); -__be32 nfsd_link(struct svc_rqst *, struct svc_fh *, +int nfsd_link(struct svc_rqst *, struct svc_fh *, char *, int, struct svc_fh *); -__be32 nfsd_rename(struct svc_rqst *, +int nfsd_rename(struct svc_rqst *, struct svc_fh *, char *, int, struct svc_fh *, char *, int); -__be32 nfsd_remove(struct svc_rqst *, +int nfsd_remove(struct svc_rqst *, struct svc_fh *, char *, int); -__be32 nfsd_unlink(struct svc_rqst *, struct svc_fh *, int type, +int nfsd_unlink(struct svc_rqst *, struct svc_fh *, int type, char *name, int len); int nfsd_truncate(struct svc_rqst *, struct svc_fh *, unsigned long size); -__be32 nfsd_readdir(struct svc_rqst *, struct svc_fh *, +int nfsd_readdir(struct svc_rqst *, struct svc_fh *, loff_t *, struct readdir_cd *, encode_dent_fn); -__be32 nfsd_statfs(struct svc_rqst *, struct svc_fh *, +int nfsd_statfs(struct svc_rqst *, struct svc_fh *, struct kstatfs *); int nfsd_notify_change(struct inode *, struct iattr *); -__be32 nfsd_permission(struct svc_export *, struct dentry *, int); +int nfsd_permission(struct svc_export *, struct dentry *, int); int nfsd_sync_dir(struct dentry *dp); #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) @@ -238,7 +238,6 @@ void nfsd_lockd_shutdown(void); #define nfserr_badname __constant_htonl(NFSERR_BADNAME) #define nfserr_cb_path_down __constant_htonl(NFSERR_CB_PATH_DOWN) #define nfserr_locked __constant_htonl(NFSERR_LOCKED) -#define nfserr_replay_me __constant_htonl(NFSERR_REPLAY_ME) /* error codes for internal use */ /* if a request fails due to kmalloc failure, it gets dropped. diff --git a/trunk/include/linux/nfsd/nfsfh.h b/trunk/include/linux/nfsd/nfsfh.h index f3b51d62ec7d..069257ea99a0 100644 --- a/trunk/include/linux/nfsd/nfsfh.h +++ b/trunk/include/linux/nfsd/nfsfh.h @@ -157,7 +157,7 @@ typedef struct svc_fh { __u64 fh_post_size; /* i_size */ unsigned long fh_post_blocks; /* i_blocks */ unsigned long fh_post_blksize;/* i_blksize */ - __be32 fh_post_rdev[2];/* i_rdev */ + __u32 fh_post_rdev[2];/* i_rdev */ struct timespec fh_post_atime; /* i_atime */ struct timespec fh_post_mtime; /* i_mtime */ struct timespec fh_post_ctime; /* i_ctime */ @@ -209,9 +209,9 @@ extern char * SVCFH_fmt(struct svc_fh *fhp); /* * Function prototypes */ -__be32 fh_verify(struct svc_rqst *, struct svc_fh *, int, int); -__be32 fh_compose(struct svc_fh *, struct svc_export *, struct dentry *, struct svc_fh *); -__be32 fh_update(struct svc_fh *); +u32 fh_verify(struct svc_rqst *, struct svc_fh *, int, int); +int fh_compose(struct svc_fh *, struct svc_export *, struct dentry *, struct svc_fh *); +int fh_update(struct svc_fh *); void fh_put(struct svc_fh *); static __inline__ struct svc_fh * diff --git a/trunk/include/linux/nfsd/state.h b/trunk/include/linux/nfsd/state.h index c3673f487e84..8bf23cf8b603 100644 --- a/trunk/include/linux/nfsd/state.h +++ b/trunk/include/linux/nfsd/state.h @@ -125,7 +125,7 @@ struct nfs4_client { char cl_recdir[HEXDIR_LEN]; /* recovery dir */ nfs4_verifier cl_verifier; /* generated by client */ time_t cl_time; /* time of last lease renewal */ - __be32 cl_addr; /* client ipaddress */ + u32 cl_addr; /* client ipaddress */ struct svc_cred cl_cred; /* setclientid principal */ clientid_t cl_clientid; /* generated by server */ nfs4_verifier cl_confirm; /* generated by server */ @@ -164,7 +164,7 @@ update_stateid(stateid_t *stateid) * is cached. */ struct nfs4_replay { - __be32 rp_status; + u32 rp_status; unsigned int rp_buflen; char *rp_buf; unsigned intrp_allocated; @@ -273,19 +273,19 @@ struct nfs4_stateid { ((err) != nfserr_stale_stateid) && \ ((err) != nfserr_bad_stateid)) -extern __be32 nfsd4_renew(clientid_t *clid); -extern __be32 nfs4_preprocess_stateid_op(struct svc_fh *current_fh, +extern int nfsd4_renew(clientid_t *clid); +extern int nfs4_preprocess_stateid_op(struct svc_fh *current_fh, stateid_t *stateid, int flags, struct file **filp); extern void nfs4_lock_state(void); extern void nfs4_unlock_state(void); extern int nfs4_in_grace(void); -extern __be32 nfs4_check_open_reclaim(clientid_t *clid); +extern int nfs4_check_open_reclaim(clientid_t *clid); extern void put_nfs4_client(struct nfs4_client *clp); extern void nfs4_free_stateowner(struct kref *kref); extern void nfsd4_probe_callback(struct nfs4_client *clp); extern void nfsd4_cb_recall(struct nfs4_delegation *dp); extern void nfs4_put_delegation(struct nfs4_delegation *dp); -extern __be32 nfs4_make_rec_clidname(char *clidname, struct xdr_netobj *clname); +extern int nfs4_make_rec_clidname(char *clidname, struct xdr_netobj *clname); extern void nfsd4_init_recdir(char *recdir_name); extern int nfsd4_recdir_load(void); extern void nfsd4_shutdown_recdir(void); diff --git a/trunk/include/linux/nfsd/xdr.h b/trunk/include/linux/nfsd/xdr.h index 877192d3ae79..0e53de87d886 100644 --- a/trunk/include/linux/nfsd/xdr.h +++ b/trunk/include/linux/nfsd/xdr.h @@ -81,7 +81,7 @@ struct nfsd_readdirargs { struct svc_fh fh; __u32 cookie; __u32 count; - __be32 * buffer; + u32 * buffer; }; struct nfsd_attrstat { @@ -108,9 +108,9 @@ struct nfsd_readdirres { int count; struct readdir_cd common; - __be32 * buffer; + u32 * buffer; int buflen; - __be32 * offset; + u32 * offset; }; struct nfsd_statfsres { @@ -135,43 +135,43 @@ union nfsd_xdrstore { #define NFS2_SVC_XDRSIZE sizeof(union nfsd_xdrstore) -int nfssvc_decode_void(struct svc_rqst *, __be32 *, void *); -int nfssvc_decode_fhandle(struct svc_rqst *, __be32 *, struct nfsd_fhandle *); -int nfssvc_decode_sattrargs(struct svc_rqst *, __be32 *, +int nfssvc_decode_void(struct svc_rqst *, u32 *, void *); +int nfssvc_decode_fhandle(struct svc_rqst *, u32 *, struct nfsd_fhandle *); +int nfssvc_decode_sattrargs(struct svc_rqst *, u32 *, struct nfsd_sattrargs *); -int nfssvc_decode_diropargs(struct svc_rqst *, __be32 *, +int nfssvc_decode_diropargs(struct svc_rqst *, u32 *, struct nfsd_diropargs *); -int nfssvc_decode_readargs(struct svc_rqst *, __be32 *, +int nfssvc_decode_readargs(struct svc_rqst *, u32 *, struct nfsd_readargs *); -int nfssvc_decode_writeargs(struct svc_rqst *, __be32 *, +int nfssvc_decode_writeargs(struct svc_rqst *, u32 *, struct nfsd_writeargs *); -int nfssvc_decode_createargs(struct svc_rqst *, __be32 *, +int nfssvc_decode_createargs(struct svc_rqst *, u32 *, struct nfsd_createargs *); -int nfssvc_decode_renameargs(struct svc_rqst *, __be32 *, +int nfssvc_decode_renameargs(struct svc_rqst *, u32 *, struct nfsd_renameargs *); -int nfssvc_decode_readlinkargs(struct svc_rqst *, __be32 *, +int nfssvc_decode_readlinkargs(struct svc_rqst *, u32 *, struct nfsd_readlinkargs *); -int nfssvc_decode_linkargs(struct svc_rqst *, __be32 *, +int nfssvc_decode_linkargs(struct svc_rqst *, u32 *, struct nfsd_linkargs *); -int nfssvc_decode_symlinkargs(struct svc_rqst *, __be32 *, +int nfssvc_decode_symlinkargs(struct svc_rqst *, u32 *, struct nfsd_symlinkargs *); -int nfssvc_decode_readdirargs(struct svc_rqst *, __be32 *, +int nfssvc_decode_readdirargs(struct svc_rqst *, u32 *, struct nfsd_readdirargs *); -int nfssvc_encode_void(struct svc_rqst *, __be32 *, void *); -int nfssvc_encode_attrstat(struct svc_rqst *, __be32 *, struct nfsd_attrstat *); -int nfssvc_encode_diropres(struct svc_rqst *, __be32 *, struct nfsd_diropres *); -int nfssvc_encode_readlinkres(struct svc_rqst *, __be32 *, struct nfsd_readlinkres *); -int nfssvc_encode_readres(struct svc_rqst *, __be32 *, struct nfsd_readres *); -int nfssvc_encode_statfsres(struct svc_rqst *, __be32 *, struct nfsd_statfsres *); -int nfssvc_encode_readdirres(struct svc_rqst *, __be32 *, struct nfsd_readdirres *); +int nfssvc_encode_void(struct svc_rqst *, u32 *, void *); +int nfssvc_encode_attrstat(struct svc_rqst *, u32 *, struct nfsd_attrstat *); +int nfssvc_encode_diropres(struct svc_rqst *, u32 *, struct nfsd_diropres *); +int nfssvc_encode_readlinkres(struct svc_rqst *, u32 *, struct nfsd_readlinkres *); +int nfssvc_encode_readres(struct svc_rqst *, u32 *, struct nfsd_readres *); +int nfssvc_encode_statfsres(struct svc_rqst *, u32 *, struct nfsd_statfsres *); +int nfssvc_encode_readdirres(struct svc_rqst *, u32 *, struct nfsd_readdirres *); int nfssvc_encode_entry(struct readdir_cd *, const char *name, int namlen, loff_t offset, ino_t ino, unsigned int); -int nfssvc_release_fhandle(struct svc_rqst *, __be32 *, struct nfsd_fhandle *); +int nfssvc_release_fhandle(struct svc_rqst *, u32 *, struct nfsd_fhandle *); /* Helper functions for NFSv2 ACL code */ -__be32 *nfs2svc_encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp); -__be32 *nfs2svc_decode_fh(__be32 *p, struct svc_fh *fhp); +u32 *nfs2svc_encode_fattr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp); +u32 *nfs2svc_decode_fh(u32 *p, struct svc_fh *fhp); #endif /* LINUX_NFSD_H */ diff --git a/trunk/include/linux/nfsd/xdr3.h b/trunk/include/linux/nfsd/xdr3.h index 79963867b0d7..474d882dc2f3 100644 --- a/trunk/include/linux/nfsd/xdr3.h +++ b/trunk/include/linux/nfsd/xdr3.h @@ -51,7 +51,7 @@ struct nfsd3_createargs { int len; int createmode; struct iattr attrs; - __be32 * verf; + __u32 * verf; }; struct nfsd3_mknodargs { @@ -98,8 +98,8 @@ struct nfsd3_readdirargs { __u64 cookie; __u32 dircount; __u32 count; - __be32 * verf; - __be32 * buffer; + __u32 * verf; + u32 * buffer; }; struct nfsd3_commitargs { @@ -122,79 +122,79 @@ struct nfsd3_setaclargs { }; struct nfsd3_attrstat { - __be32 status; + __u32 status; struct svc_fh fh; struct kstat stat; }; /* LOOKUP, CREATE, MKDIR, SYMLINK, MKNOD */ struct nfsd3_diropres { - __be32 status; + __u32 status; struct svc_fh dirfh; struct svc_fh fh; }; struct nfsd3_accessres { - __be32 status; + __u32 status; struct svc_fh fh; __u32 access; }; struct nfsd3_readlinkres { - __be32 status; + __u32 status; struct svc_fh fh; __u32 len; }; struct nfsd3_readres { - __be32 status; + __u32 status; struct svc_fh fh; unsigned long count; int eof; }; struct nfsd3_writeres { - __be32 status; + __u32 status; struct svc_fh fh; unsigned long count; int committed; }; struct nfsd3_renameres { - __be32 status; + __u32 status; struct svc_fh ffh; struct svc_fh tfh; }; struct nfsd3_linkres { - __be32 status; + __u32 status; struct svc_fh tfh; struct svc_fh fh; }; struct nfsd3_readdirres { - __be32 status; + __u32 status; struct svc_fh fh; int count; - __be32 verf[2]; + __u32 verf[2]; struct readdir_cd common; - __be32 * buffer; + u32 * buffer; int buflen; - __be32 * offset; - __be32 * offset1; + u32 * offset; + u32 * offset1; struct svc_rqst * rqstp; }; struct nfsd3_fsstatres { - __be32 status; + __u32 status; struct kstatfs stats; __u32 invarsec; }; struct nfsd3_fsinfores { - __be32 status; + __u32 status; __u32 f_rtmax; __u32 f_rtpref; __u32 f_rtmult; @@ -207,7 +207,7 @@ struct nfsd3_fsinfores { }; struct nfsd3_pathconfres { - __be32 status; + __u32 status; __u32 p_link_max; __u32 p_name_max; __u32 p_no_trunc; @@ -217,12 +217,12 @@ struct nfsd3_pathconfres { }; struct nfsd3_commitres { - __be32 status; + __u32 status; struct svc_fh fh; }; struct nfsd3_getaclres { - __be32 status; + __u32 status; struct svc_fh fh; int mask; struct posix_acl *acl_access; @@ -266,70 +266,70 @@ union nfsd3_xdrstore { #define NFS3_SVC_XDRSIZE sizeof(union nfsd3_xdrstore) -int nfs3svc_decode_fhandle(struct svc_rqst *, __be32 *, struct nfsd_fhandle *); -int nfs3svc_decode_sattrargs(struct svc_rqst *, __be32 *, +int nfs3svc_decode_fhandle(struct svc_rqst *, u32 *, struct nfsd_fhandle *); +int nfs3svc_decode_sattrargs(struct svc_rqst *, u32 *, struct nfsd3_sattrargs *); -int nfs3svc_decode_diropargs(struct svc_rqst *, __be32 *, +int nfs3svc_decode_diropargs(struct svc_rqst *, u32 *, struct nfsd3_diropargs *); -int nfs3svc_decode_accessargs(struct svc_rqst *, __be32 *, +int nfs3svc_decode_accessargs(struct svc_rqst *, u32 *, struct nfsd3_accessargs *); -int nfs3svc_decode_readargs(struct svc_rqst *, __be32 *, +int nfs3svc_decode_readargs(struct svc_rqst *, u32 *, struct nfsd3_readargs *); -int nfs3svc_decode_writeargs(struct svc_rqst *, __be32 *, +int nfs3svc_decode_writeargs(struct svc_rqst *, u32 *, struct nfsd3_writeargs *); -int nfs3svc_decode_createargs(struct svc_rqst *, __be32 *, +int nfs3svc_decode_createargs(struct svc_rqst *, u32 *, struct nfsd3_createargs *); -int nfs3svc_decode_mkdirargs(struct svc_rqst *, __be32 *, +int nfs3svc_decode_mkdirargs(struct svc_rqst *, u32 *, struct nfsd3_createargs *); -int nfs3svc_decode_mknodargs(struct svc_rqst *, __be32 *, +int nfs3svc_decode_mknodargs(struct svc_rqst *, u32 *, struct nfsd3_mknodargs *); -int nfs3svc_decode_renameargs(struct svc_rqst *, __be32 *, +int nfs3svc_decode_renameargs(struct svc_rqst *, u32 *, struct nfsd3_renameargs *); -int nfs3svc_decode_readlinkargs(struct svc_rqst *, __be32 *, +int nfs3svc_decode_readlinkargs(struct svc_rqst *, u32 *, struct nfsd3_readlinkargs *); -int nfs3svc_decode_linkargs(struct svc_rqst *, __be32 *, +int nfs3svc_decode_linkargs(struct svc_rqst *, u32 *, struct nfsd3_linkargs *); -int nfs3svc_decode_symlinkargs(struct svc_rqst *, __be32 *, +int nfs3svc_decode_symlinkargs(struct svc_rqst *, u32 *, struct nfsd3_symlinkargs *); -int nfs3svc_decode_readdirargs(struct svc_rqst *, __be32 *, +int nfs3svc_decode_readdirargs(struct svc_rqst *, u32 *, struct nfsd3_readdirargs *); -int nfs3svc_decode_readdirplusargs(struct svc_rqst *, __be32 *, +int nfs3svc_decode_readdirplusargs(struct svc_rqst *, u32 *, struct nfsd3_readdirargs *); -int nfs3svc_decode_commitargs(struct svc_rqst *, __be32 *, +int nfs3svc_decode_commitargs(struct svc_rqst *, u32 *, struct nfsd3_commitargs *); -int nfs3svc_encode_voidres(struct svc_rqst *, __be32 *, void *); -int nfs3svc_encode_attrstat(struct svc_rqst *, __be32 *, +int nfs3svc_encode_voidres(struct svc_rqst *, u32 *, void *); +int nfs3svc_encode_attrstat(struct svc_rqst *, u32 *, struct nfsd3_attrstat *); -int nfs3svc_encode_wccstat(struct svc_rqst *, __be32 *, +int nfs3svc_encode_wccstat(struct svc_rqst *, u32 *, struct nfsd3_attrstat *); -int nfs3svc_encode_diropres(struct svc_rqst *, __be32 *, +int nfs3svc_encode_diropres(struct svc_rqst *, u32 *, struct nfsd3_diropres *); -int nfs3svc_encode_accessres(struct svc_rqst *, __be32 *, +int nfs3svc_encode_accessres(struct svc_rqst *, u32 *, struct nfsd3_accessres *); -int nfs3svc_encode_readlinkres(struct svc_rqst *, __be32 *, +int nfs3svc_encode_readlinkres(struct svc_rqst *, u32 *, struct nfsd3_readlinkres *); -int nfs3svc_encode_readres(struct svc_rqst *, __be32 *, struct nfsd3_readres *); -int nfs3svc_encode_writeres(struct svc_rqst *, __be32 *, struct nfsd3_writeres *); -int nfs3svc_encode_createres(struct svc_rqst *, __be32 *, +int nfs3svc_encode_readres(struct svc_rqst *, u32 *, struct nfsd3_readres *); +int nfs3svc_encode_writeres(struct svc_rqst *, u32 *, struct nfsd3_writeres *); +int nfs3svc_encode_createres(struct svc_rqst *, u32 *, struct nfsd3_diropres *); -int nfs3svc_encode_renameres(struct svc_rqst *, __be32 *, +int nfs3svc_encode_renameres(struct svc_rqst *, u32 *, struct nfsd3_renameres *); -int nfs3svc_encode_linkres(struct svc_rqst *, __be32 *, +int nfs3svc_encode_linkres(struct svc_rqst *, u32 *, struct nfsd3_linkres *); -int nfs3svc_encode_readdirres(struct svc_rqst *, __be32 *, +int nfs3svc_encode_readdirres(struct svc_rqst *, u32 *, struct nfsd3_readdirres *); -int nfs3svc_encode_fsstatres(struct svc_rqst *, __be32 *, +int nfs3svc_encode_fsstatres(struct svc_rqst *, u32 *, struct nfsd3_fsstatres *); -int nfs3svc_encode_fsinfores(struct svc_rqst *, __be32 *, +int nfs3svc_encode_fsinfores(struct svc_rqst *, u32 *, struct nfsd3_fsinfores *); -int nfs3svc_encode_pathconfres(struct svc_rqst *, __be32 *, +int nfs3svc_encode_pathconfres(struct svc_rqst *, u32 *, struct nfsd3_pathconfres *); -int nfs3svc_encode_commitres(struct svc_rqst *, __be32 *, +int nfs3svc_encode_commitres(struct svc_rqst *, u32 *, struct nfsd3_commitres *); -int nfs3svc_release_fhandle(struct svc_rqst *, __be32 *, +int nfs3svc_release_fhandle(struct svc_rqst *, u32 *, struct nfsd3_attrstat *); -int nfs3svc_release_fhandle2(struct svc_rqst *, __be32 *, +int nfs3svc_release_fhandle2(struct svc_rqst *, u32 *, struct nfsd3_fhandle_pair *); int nfs3svc_encode_entry(struct readdir_cd *, const char *name, int namlen, loff_t offset, ino_t ino, @@ -338,9 +338,9 @@ int nfs3svc_encode_entry_plus(struct readdir_cd *, const char *name, int namlen, loff_t offset, ino_t ino, unsigned int); /* Helper functions for NFSv3 ACL code */ -__be32 *nfs3svc_encode_post_op_attr(struct svc_rqst *rqstp, __be32 *p, +u32 *nfs3svc_encode_post_op_attr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp); -__be32 *nfs3svc_decode_fh(__be32 *p, struct svc_fh *fhp); +u32 *nfs3svc_decode_fh(u32 *p, struct svc_fh *fhp); #endif /* _LINUX_NFSD_XDR3_H */ diff --git a/trunk/include/linux/nfsd/xdr4.h b/trunk/include/linux/nfsd/xdr4.h index 45ca01b5f844..66e642762a07 100644 --- a/trunk/include/linux/nfsd/xdr4.h +++ b/trunk/include/linux/nfsd/xdr4.h @@ -258,9 +258,9 @@ struct nfsd4_readdir { struct svc_fh * rd_fhp; /* response */ struct readdir_cd common; - __be32 * buffer; + u32 * buffer; int buflen; - __be32 * offset; + u32 * offset; }; struct nfsd4_release_lockowner { @@ -334,7 +334,7 @@ struct nfsd4_write { struct nfsd4_op { int opnum; - __be32 status; + int status; union { struct nfsd4_access access; struct nfsd4_close close; @@ -371,12 +371,12 @@ struct nfsd4_op { struct nfsd4_compoundargs { /* scratch variables for XDR decode */ - __be32 * p; - __be32 * end; + u32 * p; + u32 * end; struct page ** pagelist; int pagelen; - __be32 tmp[8]; - __be32 * tmpp; + u32 tmp[8]; + u32 * tmpp; struct tmpbuf { struct tmpbuf *next; void (*release)(const void *); @@ -395,15 +395,15 @@ struct nfsd4_compoundargs { struct nfsd4_compoundres { /* scratch variables for XDR encode */ - __be32 * p; - __be32 * end; + u32 * p; + u32 * end; struct xdr_buf * xbuf; struct svc_rqst * rqstp; u32 taglen; char * tag; u32 opcnt; - __be32 * tagp; /* where to encode tag and opcount */ + u32 * tagp; /* where to encode tag and opcount */ }; #define NFS4_SVC_XDRSIZE sizeof(struct nfsd4_compoundargs) @@ -419,45 +419,45 @@ set_change_info(struct nfsd4_change_info *cinfo, struct svc_fh *fhp) cinfo->after_ctime_nsec = fhp->fh_post_ctime.tv_nsec; } -int nfs4svc_encode_voidres(struct svc_rqst *, __be32 *, void *); -int nfs4svc_decode_compoundargs(struct svc_rqst *, __be32 *, +int nfs4svc_encode_voidres(struct svc_rqst *, u32 *, void *); +int nfs4svc_decode_compoundargs(struct svc_rqst *, u32 *, struct nfsd4_compoundargs *); -int nfs4svc_encode_compoundres(struct svc_rqst *, __be32 *, +int nfs4svc_encode_compoundres(struct svc_rqst *, u32 *, struct nfsd4_compoundres *); void nfsd4_encode_operation(struct nfsd4_compoundres *, struct nfsd4_op *); void nfsd4_encode_replay(struct nfsd4_compoundres *resp, struct nfsd4_op *op); -__be32 nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, - struct dentry *dentry, __be32 *buffer, int *countp, +int nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, + struct dentry *dentry, u32 *buffer, int *countp, u32 *bmval, struct svc_rqst *); -extern __be32 nfsd4_setclientid(struct svc_rqst *rqstp, +extern int nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_setclientid *setclid); -extern __be32 nfsd4_setclientid_confirm(struct svc_rqst *rqstp, +extern int nfsd4_setclientid_confirm(struct svc_rqst *rqstp, struct nfsd4_setclientid_confirm *setclientid_confirm); -extern __be32 nfsd4_process_open1(struct nfsd4_open *open); -extern __be32 nfsd4_process_open2(struct svc_rqst *rqstp, +extern int nfsd4_process_open1(struct nfsd4_open *open); +extern int nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open); -extern __be32 nfsd4_open_confirm(struct svc_rqst *rqstp, +extern int nfsd4_open_confirm(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open_confirm *oc, struct nfs4_stateowner **); -extern __be32 nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh, +extern int nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_close *close, struct nfs4_stateowner **replay_owner); -extern __be32 nfsd4_open_downgrade(struct svc_rqst *rqstp, +extern int nfsd4_open_downgrade(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open_downgrade *od, struct nfs4_stateowner **replay_owner); -extern __be32 nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, +extern int nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock *lock, struct nfs4_stateowner **replay_owner); -extern __be32 nfsd4_lockt(struct svc_rqst *rqstp, struct svc_fh *current_fh, +extern int nfsd4_lockt(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lockt *lockt); -extern __be32 nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh, +extern int nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_locku *locku, struct nfs4_stateowner **replay_owner); -extern __be32 +extern int nfsd4_release_lockowner(struct svc_rqst *rqstp, struct nfsd4_release_lockowner *rlockowner); extern void nfsd4_release_compoundargs(struct nfsd4_compoundargs *); -extern __be32 nfsd4_delegreturn(struct svc_rqst *rqstp, +extern int nfsd4_delegreturn(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_delegreturn *dr); #endif diff --git a/trunk/include/linux/nodemask.h b/trunk/include/linux/nodemask.h index b1063e9cdb1b..5dce5c21822c 100644 --- a/trunk/include/linux/nodemask.h +++ b/trunk/include/linux/nodemask.h @@ -8,8 +8,8 @@ * See detailed comments in the file linux/bitmap.h describing the * data type on which these nodemasks are based. * - * For details of nodemask_scnprintf() and nodemask_parse_user(), - * see bitmap_scnprintf() and bitmap_parse_user() in lib/bitmap.c. + * For details of nodemask_scnprintf() and nodemask_parse(), + * see bitmap_scnprintf() and bitmap_parse() in lib/bitmap.c. * For details of nodelist_scnprintf() and nodelist_parse(), see * bitmap_scnlistprintf() and bitmap_parselist(), also in bitmap.c. * For details of node_remap(), see bitmap_bitremap in lib/bitmap.c. @@ -51,7 +51,7 @@ * unsigned long *nodes_addr(mask) Array of unsigned long's in mask * * int nodemask_scnprintf(buf, len, mask) Format nodemask for printing - * int nodemask_parse_user(ubuf, ulen, mask) Parse ascii string as nodemask + * int nodemask_parse(ubuf, ulen, mask) Parse ascii string as nodemask * int nodelist_scnprintf(buf, len, mask) Format nodemask as list for printing * int nodelist_parse(buf, map) Parse ascii string as nodelist * int node_remap(oldbit, old, new) newbit = map(old, new)(oldbit) @@ -288,12 +288,12 @@ static inline int __nodemask_scnprintf(char *buf, int len, return bitmap_scnprintf(buf, len, srcp->bits, nbits); } -#define nodemask_parse_user(ubuf, ulen, dst) \ - __nodemask_parse_user((ubuf), (ulen), &(dst), MAX_NUMNODES) -static inline int __nodemask_parse_user(const char __user *buf, int len, +#define nodemask_parse(ubuf, ulen, dst) \ + __nodemask_parse((ubuf), (ulen), &(dst), MAX_NUMNODES) +static inline int __nodemask_parse(const char __user *buf, int len, nodemask_t *dstp, int nbits) { - return bitmap_parse_user(buf, len, dstp->bits, nbits); + return bitmap_parse(buf, len, dstp->bits, nbits); } #define nodelist_scnprintf(buf, len, src) \ diff --git a/trunk/include/linux/nsproxy.h b/trunk/include/linux/nsproxy.h index 971d1c6dfc4b..f6baecdeecd6 100644 --- a/trunk/include/linux/nsproxy.h +++ b/trunk/include/linux/nsproxy.h @@ -45,10 +45,8 @@ static inline void exit_task_namespaces(struct task_struct *p) { struct nsproxy *ns = p->nsproxy; if (ns) { - task_lock(p); - p->nsproxy = NULL; - task_unlock(p); put_nsproxy(ns); + p->nsproxy = NULL; } } #endif diff --git a/trunk/include/linux/oom.h b/trunk/include/linux/oom.h deleted file mode 100644 index ad76463629a0..000000000000 --- a/trunk/include/linux/oom.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __INCLUDE_LINUX_OOM_H -#define __INCLUDE_LINUX_OOM_H - -/* /proc//oom_adj set to -17 protects from the oom-killer */ -#define OOM_DISABLE (-17) -/* inclusive */ -#define OOM_ADJUST_MIN (-16) -#define OOM_ADJUST_MAX 15 - -#endif diff --git a/trunk/include/linux/pagemap.h b/trunk/include/linux/pagemap.h index c3e255bf8594..64f950925151 100644 --- a/trunk/include/linux/pagemap.h +++ b/trunk/include/linux/pagemap.h @@ -52,23 +52,19 @@ static inline void mapping_set_gfp_mask(struct address_space *m, gfp_t mask) void release_pages(struct page **pages, int nr, int cold); #ifdef CONFIG_NUMA -extern struct page *__page_cache_alloc(gfp_t gfp); +extern struct page *page_cache_alloc(struct address_space *x); +extern struct page *page_cache_alloc_cold(struct address_space *x); #else -static inline struct page *__page_cache_alloc(gfp_t gfp) -{ - return alloc_pages(gfp, 0); -} -#endif - static inline struct page *page_cache_alloc(struct address_space *x) { - return __page_cache_alloc(mapping_gfp_mask(x)); + return alloc_pages(mapping_gfp_mask(x), 0); } static inline struct page *page_cache_alloc_cold(struct address_space *x) { - return __page_cache_alloc(mapping_gfp_mask(x)|__GFP_COLD); + return alloc_pages(mapping_gfp_mask(x)|__GFP_COLD, 0); } +#endif typedef int filler_t(void *, struct page *); diff --git a/trunk/include/linux/parport.h b/trunk/include/linux/parport.h index 80682aaa8f18..5bf321e82c99 100644 --- a/trunk/include/linux/parport.h +++ b/trunk/include/linux/parport.h @@ -229,7 +229,7 @@ struct pardevice { int (*preempt)(void *); void (*wakeup)(void *); void *private; - void (*irq_func)(int, void *); + void (*irq_func)(int, void *, struct pt_regs *); unsigned int flags; struct pardevice *next; struct pardevice *prev; @@ -375,7 +375,7 @@ extern void parport_put_port (struct parport *); struct pardevice *parport_register_device(struct parport *port, const char *name, int (*pf)(void *), void (*kf)(void *), - void (*irq_func)(int, void *), + void (*irq_func)(int, void *, struct pt_regs *), int flags, void *handle); /* parport_unregister unlinks a device from the chain. */ @@ -457,7 +457,7 @@ static __inline__ int parport_yield_blocking(struct pardevice *dev) #define PARPORT_FLAG_EXCL (1<<1) /* EXCL driver registered. */ /* IEEE1284 functions */ -extern void parport_ieee1284_interrupt (int, void *); +extern void parport_ieee1284_interrupt (int, void *, struct pt_regs *); extern int parport_negotiate (struct parport *, int mode); extern ssize_t parport_write (struct parport *, const void *buf, size_t len); extern ssize_t parport_read (struct parport *, void *buf, size_t len); @@ -502,7 +502,8 @@ extern void parport_daisy_fini (struct parport *port); extern struct pardevice *parport_open (int devnum, const char *name, int (*pf) (void *), void (*kf) (void *), - void (*irqf) (int, void *), + void (*irqf) (int, void *, + struct pt_regs *), int flags, void *handle); extern void parport_close (struct pardevice *dev); extern ssize_t parport_device_id (int devnum, char *buffer, size_t len); @@ -511,12 +512,13 @@ extern void parport_daisy_deselect_all (struct parport *port); extern int parport_daisy_select (struct parport *port, int daisy, int mode); /* Lowlevel drivers _can_ call this support function to handle irqs. */ -static __inline__ void parport_generic_irq(int irq, struct parport *port) +static __inline__ void parport_generic_irq(int irq, struct parport *port, + struct pt_regs *regs) { - parport_ieee1284_interrupt (irq, port); + parport_ieee1284_interrupt (irq, port, regs); read_lock(&port->cad_lock); if (port->cad && port->cad->irq_func) - port->cad->irq_func(irq, port->cad->private); + port->cad->irq_func(irq, port->cad->private, regs); read_unlock(&port->cad_lock); } diff --git a/trunk/include/linux/pci.h b/trunk/include/linux/pci.h index 01c707261f9c..5c604f5fad67 100644 --- a/trunk/include/linux/pci.h +++ b/trunk/include/linux/pci.h @@ -51,7 +51,6 @@ #include #include #include -#include #include /* File state for mmap()s on /proc/bus/pci/X/Y */ @@ -160,6 +159,7 @@ struct pci_dev { unsigned int transparent:1; /* Transparent PCI bridge */ unsigned int multifunction:1;/* Part of multi-function device */ /* keep track of device state */ + unsigned int is_enabled:1; /* pci_enable_device has been called */ unsigned int is_busmaster:1; /* device is busmaster */ unsigned int no_msi:1; /* device may not use msi */ unsigned int no_d1d2:1; /* only allow d0 or d3 */ @@ -167,7 +167,6 @@ struct pci_dev { unsigned int broken_parity_status:1; /* Device generates false positive parity */ unsigned int msi_enabled:1; unsigned int msix_enabled:1; - atomic_t enable_cnt; /* pci_enable_device has been called */ u32 saved_config_space[16]; /* config space saved at suspend time */ struct hlist_head saved_cap_space; @@ -444,7 +443,6 @@ extern void pci_remove_bus(struct pci_bus *b); extern void pci_remove_bus_device(struct pci_dev *dev); extern void pci_stop_bus_device(struct pci_dev *dev); void pci_setup_cardbus(struct pci_bus *bus); -extern void pci_sort_breadthfirst(void); /* Generic PCI functions exported to card drivers */ @@ -454,18 +452,13 @@ struct pci_dev *pci_find_slot (unsigned int bus, unsigned int devfn); int pci_find_capability (struct pci_dev *dev, int cap); int pci_find_next_capability (struct pci_dev *dev, u8 pos, int cap); int pci_find_ext_capability (struct pci_dev *dev, int cap); -struct pci_bus *pci_find_next_bus(const struct pci_bus *from); - -struct pci_dev *pci_get_device(unsigned int vendor, unsigned int device, - struct pci_dev *from); -struct pci_dev *pci_get_device_reverse(unsigned int vendor, unsigned int device, - struct pci_dev *from); +struct pci_bus * pci_find_next_bus(const struct pci_bus *from); +struct pci_dev *pci_get_device (unsigned int vendor, unsigned int device, struct pci_dev *from); struct pci_dev *pci_get_subsys (unsigned int vendor, unsigned int device, unsigned int ss_vendor, unsigned int ss_device, struct pci_dev *from); struct pci_dev *pci_get_slot (struct pci_bus *bus, unsigned int devfn); -struct pci_dev *pci_get_bus_and_slot (unsigned int bus, unsigned int devfn); struct pci_dev *pci_get_class (unsigned int class, struct pci_dev *from); int pci_dev_present(const struct pci_device_id *ids); @@ -665,12 +658,7 @@ static inline struct pci_dev *pci_find_device(unsigned int vendor, unsigned int static inline struct pci_dev *pci_find_slot(unsigned int bus, unsigned int devfn) { return NULL; } -static inline struct pci_dev *pci_get_device(unsigned int vendor, - unsigned int device, struct pci_dev *from) -{ return NULL; } - -static inline struct pci_dev *pci_get_device_reverse(unsigned int vendor, - unsigned int device, struct pci_dev *from) +static inline struct pci_dev *pci_get_device (unsigned int vendor, unsigned int device, struct pci_dev *from) { return NULL; } static inline struct pci_dev *pci_get_subsys (unsigned int vendor, unsigned int device, diff --git a/trunk/include/linux/pci_ids.h b/trunk/include/linux/pci_ids.h index e060a7637947..f069df245469 100644 --- a/trunk/include/linux/pci_ids.h +++ b/trunk/include/linux/pci_ids.h @@ -1213,7 +1213,6 @@ #define PCI_DEVICE_ID_NVIDIA_NVENET_21 0x0451 #define PCI_DEVICE_ID_NVIDIA_NVENET_22 0x0452 #define PCI_DEVICE_ID_NVIDIA_NVENET_23 0x0453 -#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE 0x0560 #define PCI_VENDOR_ID_IMS 0x10e0 #define PCI_DEVICE_ID_IMS_TT128 0x9128 @@ -2211,13 +2210,6 @@ #define PCI_DEVICE_ID_INTEL_ICH8_4 0x2815 #define PCI_DEVICE_ID_INTEL_ICH8_5 0x283e #define PCI_DEVICE_ID_INTEL_ICH8_6 0x2850 -#define PCI_DEVICE_ID_INTEL_ICH9_0 0x2910 -#define PCI_DEVICE_ID_INTEL_ICH9_1 0x2911 -#define PCI_DEVICE_ID_INTEL_ICH9_2 0x2912 -#define PCI_DEVICE_ID_INTEL_ICH9_3 0x2913 -#define PCI_DEVICE_ID_INTEL_ICH9_4 0x2914 -#define PCI_DEVICE_ID_INTEL_ICH9_5 0x2915 -#define PCI_DEVICE_ID_INTEL_ICH9_6 0x2930 #define PCI_DEVICE_ID_INTEL_82855PM_HB 0x3340 #define PCI_DEVICE_ID_INTEL_82830_HB 0x3575 #define PCI_DEVICE_ID_INTEL_82830_CGC 0x3577 @@ -2359,5 +2351,3 @@ #define PCI_DEVICE_ID_RME_DIGI32_PRO 0x9897 #define PCI_DEVICE_ID_RME_DIGI32_8 0x9898 -#define PCI_VENDOR_ID_QUICKNET 0x15E2 -#define PCI_DEVICE_ID_QUICKNET_XJ 0x0500 diff --git a/trunk/include/linux/pci_regs.h b/trunk/include/linux/pci_regs.h index 064b1dc71c22..c312a12ad2d6 100644 --- a/trunk/include/linux/pci_regs.h +++ b/trunk/include/linux/pci_regs.h @@ -292,12 +292,6 @@ #define PCI_MSI_DATA_64 12 /* 16 bits of data for 64-bit devices */ #define PCI_MSI_MASK_BIT 16 /* Mask bits register */ -/* MSI-X registers (these are at offset PCI_MSI_FLAGS) */ -#define PCI_MSIX_FLAGS_QSIZE 0x7FF -#define PCI_MSIX_FLAGS_ENABLE (1 << 15) -#define PCI_MSIX_FLAGS_BIRMASK (7 << 0) -#define PCI_MSIX_FLAGS_BITMASK (1 << 0) - /* CompactPCI Hotswap Register */ #define PCI_CHSWP_CSR 2 /* Control and Status Register */ @@ -377,7 +371,6 @@ #define PCI_EXP_DEVSTA_TRPND 0x20 /* Transactions Pending */ #define PCI_EXP_LNKCAP 12 /* Link Capabilities */ #define PCI_EXP_LNKCTL 16 /* Link Control */ -#define PCI_EXP_LNKCTL_CLKREQ_EN 0x100 /* Enable clkreq */ #define PCI_EXP_LNKSTA 18 /* Link Status */ #define PCI_EXP_SLTCAP 20 /* Slot Capabilities */ #define PCI_EXP_SLTCTL 24 /* Slot Control */ diff --git a/trunk/include/linux/percpu.h b/trunk/include/linux/percpu.h index 600e3d387ffc..46ec72fa2c84 100644 --- a/trunk/include/linux/percpu.h +++ b/trunk/include/linux/percpu.h @@ -19,7 +19,7 @@ * we force a syntax error here if it isn't. */ #define get_cpu_var(var) (*({ \ - extern int simple_identifier_##var(void); \ + extern int simple_indentifier_##var(void); \ preempt_disable(); \ &__get_cpu_var(var); })) #define put_cpu_var(var) preempt_enable() diff --git a/trunk/include/linux/personality.h b/trunk/include/linux/personality.h index 012cd558189b..80d780e5a8f5 100644 --- a/trunk/include/linux/personality.h +++ b/trunk/include/linux/personality.h @@ -1,8 +1,6 @@ #ifndef _LINUX_PERSONALITY_H #define _LINUX_PERSONALITY_H -#ifdef __KERNEL__ - /* * Handling of different ABIs (personalities). */ @@ -14,8 +12,6 @@ extern int register_exec_domain(struct exec_domain *); extern int unregister_exec_domain(struct exec_domain *); extern int __set_personality(unsigned long); -#endif /* __KERNEL__ */ - /* * Flags for bug emulation. * @@ -75,7 +71,6 @@ enum { PER_MASK = 0x00ff, }; -#ifdef __KERNEL__ /* * Description of an execution domain. @@ -114,8 +109,6 @@ struct exec_domain { * Change personality of the currently running process. */ #define set_personality(pers) \ - ((current->personality == (pers)) ? 0 : __set_personality(pers)) - -#endif /* __KERNEL__ */ + ((current->personality == pers) ? 0 : __set_personality(pers)) #endif /* _LINUX_PERSONALITY_H */ diff --git a/trunk/include/linux/platform_device.h b/trunk/include/linux/platform_device.h index 20f47b81d3fa..29cd6dee13db 100644 --- a/trunk/include/linux/platform_device.h +++ b/trunk/include/linux/platform_device.h @@ -58,12 +58,6 @@ struct platform_driver { extern int platform_driver_register(struct platform_driver *); extern void platform_driver_unregister(struct platform_driver *); -/* non-hotpluggable platform devices may use this so that probe() and - * its support may live in __init sections, conserving runtime memory. - */ -extern int platform_driver_probe(struct platform_driver *driver, - int (*probe)(struct platform_device *)); - #define platform_get_drvdata(_dev) dev_get_drvdata(&(_dev)->dev) #define platform_set_drvdata(_dev,data) dev_set_drvdata(&(_dev)->dev, (data)) diff --git a/trunk/include/linux/pm.h b/trunk/include/linux/pm.h index 070394e846d0..6b27e07aef19 100644 --- a/trunk/include/linux/pm.h +++ b/trunk/include/linux/pm.h @@ -116,9 +116,7 @@ typedef int __bitwise suspend_disk_method_t; #define PM_DISK_PLATFORM ((__force suspend_disk_method_t) 2) #define PM_DISK_SHUTDOWN ((__force suspend_disk_method_t) 3) #define PM_DISK_REBOOT ((__force suspend_disk_method_t) 4) -#define PM_DISK_TEST ((__force suspend_disk_method_t) 5) -#define PM_DISK_TESTPROC ((__force suspend_disk_method_t) 6) -#define PM_DISK_MAX ((__force suspend_disk_method_t) 7) +#define PM_DISK_MAX ((__force suspend_disk_method_t) 5) struct pm_ops { suspend_disk_method_t pm_disk_mode; diff --git a/trunk/include/linux/profile.h b/trunk/include/linux/profile.h index acce53fd38b6..e633004ae052 100644 --- a/trunk/include/linux/profile.h +++ b/trunk/include/linux/profile.h @@ -17,7 +17,7 @@ struct notifier_block; /* init basic kernel profiler */ void __init profile_init(void); -void profile_tick(int); +void profile_tick(int, struct pt_regs *); void profile_hit(int, void *); #ifdef CONFIG_PROC_FS void create_prof_cpu_mask(struct proc_dir_entry *); diff --git a/trunk/include/linux/raid/bitmap.h b/trunk/include/linux/raid/bitmap.h index ebd42a3710b4..84d887751855 100644 --- a/trunk/include/linux/raid/bitmap.h +++ b/trunk/include/linux/raid/bitmap.h @@ -146,16 +146,16 @@ enum bitmap_state { /* the superblock at the front of the bitmap file -- little endian */ typedef struct bitmap_super_s { - __le32 magic; /* 0 BITMAP_MAGIC */ - __le32 version; /* 4 the bitmap major for now, could change... */ - __u8 uuid[16]; /* 8 128 bit uuid - must match md device uuid */ - __le64 events; /* 24 event counter for the bitmap (1)*/ - __le64 events_cleared;/*32 event counter when last bit cleared (2) */ - __le64 sync_size; /* 40 the size of the md device's sync range(3) */ - __le32 state; /* 48 bitmap state information */ - __le32 chunksize; /* 52 the bitmap chunk size in bytes */ - __le32 daemon_sleep; /* 56 seconds between disk flushes */ - __le32 write_behind; /* 60 number of outstanding write-behind writes */ + __u32 magic; /* 0 BITMAP_MAGIC */ + __u32 version; /* 4 the bitmap major for now, could change... */ + __u8 uuid[16]; /* 8 128 bit uuid - must match md device uuid */ + __u64 events; /* 24 event counter for the bitmap (1)*/ + __u64 events_cleared;/*32 event counter when last bit cleared (2) */ + __u64 sync_size; /* 40 the size of the md device's sync range(3) */ + __u32 state; /* 48 bitmap state information */ + __u32 chunksize; /* 52 the bitmap chunk size in bytes */ + __u32 daemon_sleep; /* 56 seconds between disk flushes */ + __u32 write_behind; /* 60 number of outstanding write-behind writes */ __u8 pad[256 - 64]; /* set to zero */ } bitmap_super_t; diff --git a/trunk/include/linux/raid/md_p.h b/trunk/include/linux/raid/md_p.h index 3f2cd98c508b..b6ebc69bae54 100644 --- a/trunk/include/linux/raid/md_p.h +++ b/trunk/include/linux/raid/md_p.h @@ -206,52 +206,52 @@ static inline __u64 md_event(mdp_super_t *sb) { */ struct mdp_superblock_1 { /* constant array information - 128 bytes */ - __le32 magic; /* MD_SB_MAGIC: 0xa92b4efc - little endian */ - __le32 major_version; /* 1 */ - __le32 feature_map; /* bit 0 set if 'bitmap_offset' is meaningful */ - __le32 pad0; /* always set to 0 when writing */ + __u32 magic; /* MD_SB_MAGIC: 0xa92b4efc - little endian */ + __u32 major_version; /* 1 */ + __u32 feature_map; /* bit 0 set if 'bitmap_offset' is meaningful */ + __u32 pad0; /* always set to 0 when writing */ __u8 set_uuid[16]; /* user-space generated. */ char set_name[32]; /* set and interpreted by user-space */ - __le64 ctime; /* lo 40 bits are seconds, top 24 are microseconds or 0*/ - __le32 level; /* -4 (multipath), -1 (linear), 0,1,4,5 */ - __le32 layout; /* only for raid5 and raid10 currently */ - __le64 size; /* used size of component devices, in 512byte sectors */ + __u64 ctime; /* lo 40 bits are seconds, top 24 are microseconds or 0*/ + __u32 level; /* -4 (multipath), -1 (linear), 0,1,4,5 */ + __u32 layout; /* only for raid5 and raid10 currently */ + __u64 size; /* used size of component devices, in 512byte sectors */ - __le32 chunksize; /* in 512byte sectors */ - __le32 raid_disks; - __le32 bitmap_offset; /* sectors after start of superblock that bitmap starts + __u32 chunksize; /* in 512byte sectors */ + __u32 raid_disks; + __u32 bitmap_offset; /* sectors after start of superblock that bitmap starts * NOTE: signed, so bitmap can be before superblock * only meaningful of feature_map[0] is set. */ /* These are only valid with feature bit '4' */ - __le32 new_level; /* new level we are reshaping to */ - __le64 reshape_position; /* next address in array-space for reshape */ - __le32 delta_disks; /* change in number of raid_disks */ - __le32 new_layout; /* new layout */ - __le32 new_chunk; /* new chunk size (bytes) */ + __u32 new_level; /* new level we are reshaping to */ + __u64 reshape_position; /* next address in array-space for reshape */ + __u32 delta_disks; /* change in number of raid_disks */ + __u32 new_layout; /* new layout */ + __u32 new_chunk; /* new chunk size (bytes) */ __u8 pad1[128-124]; /* set to 0 when written */ /* constant this-device information - 64 bytes */ - __le64 data_offset; /* sector start of data, often 0 */ - __le64 data_size; /* sectors in this device that can be used for data */ - __le64 super_offset; /* sector start of this superblock */ - __le64 recovery_offset;/* sectors before this offset (from data_offset) have been recovered */ - __le32 dev_number; /* permanent identifier of this device - not role in raid */ - __le32 cnt_corrected_read; /* number of read errors that were corrected by re-writing */ + __u64 data_offset; /* sector start of data, often 0 */ + __u64 data_size; /* sectors in this device that can be used for data */ + __u64 super_offset; /* sector start of this superblock */ + __u64 recovery_offset;/* sectors before this offset (from data_offset) have been recovered */ + __u32 dev_number; /* permanent identifier of this device - not role in raid */ + __u32 cnt_corrected_read; /* number of read errors that were corrected by re-writing */ __u8 device_uuid[16]; /* user-space setable, ignored by kernel */ __u8 devflags; /* per-device flags. Only one defined...*/ #define WriteMostly1 1 /* mask for writemostly flag in above */ __u8 pad2[64-57]; /* set to 0 when writing */ /* array state information - 64 bytes */ - __le64 utime; /* 40 bits second, 24 btes microseconds */ - __le64 events; /* incremented when superblock updated */ - __le64 resync_offset; /* data before this offset (from data_offset) known to be in sync */ - __le32 sb_csum; /* checksum upto devs[max_dev] */ - __le32 max_dev; /* size of devs[] array to consider */ + __u64 utime; /* 40 bits second, 24 btes microseconds */ + __u64 events; /* incremented when superblock updated */ + __u64 resync_offset; /* data before this offset (from data_offset) known to be in sync */ + __u32 sb_csum; /* checksum upto devs[max_dev] */ + __u32 max_dev; /* size of devs[] array to consider */ __u8 pad3[64-32]; /* set to 0 when writing */ /* device state information. Indexed by dev_number. @@ -260,7 +260,7 @@ struct mdp_superblock_1 { * into the 'roles' value. If a device is spare or faulty, then it doesn't * have a meaningful role. */ - __le16 dev_roles[0]; /* role in array, or 0xffff for a spare, or 0xfffe for faulty */ + __u16 dev_roles[0]; /* role in array, or 0xffff for a spare, or 0xfffe for faulty */ }; /* feature_map bits */ diff --git a/trunk/include/linux/raid_class.h b/trunk/include/linux/raid_class.h index d22ad392242a..d0dd38b3a2fd 100644 --- a/trunk/include/linux/raid_class.h +++ b/trunk/include/linux/raid_class.h @@ -77,6 +77,5 @@ DEFINE_RAID_ATTRIBUTE(enum raid_state, state) struct raid_template *raid_class_attach(struct raid_function_template *); void raid_class_release(struct raid_template *); -int __must_check raid_component_add(struct raid_template *, struct device *, - struct device *); - +void raid_component_add(struct raid_template *, struct device *, + struct device *); diff --git a/trunk/include/linux/random.h b/trunk/include/linux/random.h index 0248b30e306d..5d6456bcdeba 100644 --- a/trunk/include/linux/random.h +++ b/trunk/include/linux/random.h @@ -69,9 +69,6 @@ extern struct file_operations random_fops, urandom_fops; unsigned int get_random_int(void); unsigned long randomize_range(unsigned long start, unsigned long end, unsigned long len); -u32 random32(void); -void srandom32(u32 seed); - #endif /* __KERNEL___ */ #endif /* _LINUX_RANDOM_H */ diff --git a/trunk/include/linux/reiserfs_fs_sb.h b/trunk/include/linux/reiserfs_fs_sb.h index 62a7169aed8b..73e0becec086 100644 --- a/trunk/include/linux/reiserfs_fs_sb.h +++ b/trunk/include/linux/reiserfs_fs_sb.h @@ -429,7 +429,7 @@ enum reiserfs_mount_options { /* -o hash={tea, rupasov, r5, detect} is meant for properly mounting ** reiserfs disks from 3.5.19 or earlier. 99% of the time, this option ** is not required. If the normal autodection code can't determine which -** hash to use (because both hashes had the same value for a file) +** hash to use (because both hases had the same value for a file) ** use this option to force a specific hash. It won't allow you to override ** the existing hash on the FS, so if you have a tea hash disk, and mount ** with -o hash=rupasov, the mount will fail. diff --git a/trunk/include/linux/rtc.h b/trunk/include/linux/rtc.h index 09ff4c3e2713..b89f09357054 100644 --- a/trunk/include/linux/rtc.h +++ b/trunk/include/linux/rtc.h @@ -208,7 +208,7 @@ int rtc_register(rtc_task_t *task); int rtc_unregister(rtc_task_t *task); int rtc_control(rtc_task_t *t, unsigned int cmd, unsigned long arg); void rtc_get_rtc_time(struct rtc_time *rtc_tm); -irqreturn_t rtc_interrupt(int irq, void *dev_id); +irqreturn_t rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs); #endif /* __KERNEL__ */ diff --git a/trunk/include/linux/sched.h b/trunk/include/linux/sched.h index eafe4a7b8237..331f4502e92b 100644 --- a/trunk/include/linux/sched.h +++ b/trunk/include/linux/sched.h @@ -466,6 +466,7 @@ struct signal_struct { struct pacct_struct pacct; /* per-process accounting information */ #endif #ifdef CONFIG_TASKSTATS + spinlock_t stats_lock; struct taskstats *stats; #endif }; @@ -1064,10 +1065,9 @@ static inline int pid_alive(struct task_struct *p) } /** - * is_init - check if a task structure is init - * @tsk: Task structure to be checked. - * - * Check if a task structure is the first user space task the kernel created. + * is_init - check if a task structure is the first user space + * task the kernel created. + * @p: Task structure to be checked. */ static inline int is_init(struct task_struct *tsk) { diff --git a/trunk/include/linux/security.h b/trunk/include/linux/security.h index b200b9856f32..9b5fea81f55e 100644 --- a/trunk/include/linux/security.h +++ b/trunk/include/linux/security.h @@ -882,8 +882,7 @@ struct request_sock; * Check permission when a flow selects a xfrm_policy for processing * XFRMs on a packet. The hook is called when selecting either a * per-socket policy or a generic xfrm policy. - * Return 0 if permission is granted, -ESRCH otherwise, or -errno - * on other errors. + * Return 0 if permission is granted. * @xfrm_state_pol_flow_match: * @x contains the state to match. * @xp contains the policy to check for a match. @@ -892,7 +891,6 @@ struct request_sock; * @xfrm_flow_state_match: * @fl contains the flow key to match. * @xfrm points to the xfrm_state to match. - * @xp points to the xfrm_policy to match. * Return 1 if there is a match. * @xfrm_decode_session: * @skb points to skb to decode. @@ -1390,8 +1388,7 @@ struct security_operations { int (*xfrm_policy_lookup)(struct xfrm_policy *xp, u32 fl_secid, u8 dir); int (*xfrm_state_pol_flow_match)(struct xfrm_state *x, struct xfrm_policy *xp, struct flowi *fl); - int (*xfrm_flow_state_match)(struct flowi *fl, struct xfrm_state *xfrm, - struct xfrm_policy *xp); + int (*xfrm_flow_state_match)(struct flowi *fl, struct xfrm_state *xfrm); int (*xfrm_decode_session)(struct sk_buff *skb, u32 *secid, int ckall); #endif /* CONFIG_SECURITY_NETWORK_XFRM */ @@ -3123,6 +3120,11 @@ static inline int security_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm return security_ops->xfrm_policy_alloc_security(xp, sec_ctx, NULL); } +static inline int security_xfrm_sock_policy_alloc(struct xfrm_policy *xp, struct sock *sk) +{ + return security_ops->xfrm_policy_alloc_security(xp, NULL, sk); +} + static inline int security_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new) { return security_ops->xfrm_policy_clone_security(old, new); @@ -3173,10 +3175,9 @@ static inline int security_xfrm_state_pol_flow_match(struct xfrm_state *x, return security_ops->xfrm_state_pol_flow_match(x, xp, fl); } -static inline int security_xfrm_flow_state_match(struct flowi *fl, - struct xfrm_state *xfrm, struct xfrm_policy *xp) +static inline int security_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm) { - return security_ops->xfrm_flow_state_match(fl, xfrm, xp); + return security_ops->xfrm_flow_state_match(fl, xfrm); } static inline int security_xfrm_decode_session(struct sk_buff *skb, u32 *secid) @@ -3196,6 +3197,11 @@ static inline int security_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm return 0; } +static inline int security_xfrm_sock_policy_alloc(struct xfrm_policy *xp, struct sock *sk) +{ + return 0; +} + static inline int security_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new) { return 0; @@ -3243,7 +3249,7 @@ static inline int security_xfrm_state_pol_flow_match(struct xfrm_state *x, } static inline int security_xfrm_flow_state_match(struct flowi *fl, - struct xfrm_state *xfrm, struct xfrm_policy *xp) + struct xfrm_state *xfrm) { return 1; } diff --git a/trunk/include/linux/serial_core.h b/trunk/include/linux/serial_core.h index 463ab953b092..b661c19f3f72 100644 --- a/trunk/include/linux/serial_core.h +++ b/trunk/include/linux/serial_core.h @@ -409,12 +409,13 @@ int uart_resume_port(struct uart_driver *reg, struct uart_port *port); * The following are helper functions for the low level drivers. */ static inline int -uart_handle_sysrq_char(struct uart_port *port, unsigned int ch) +uart_handle_sysrq_char(struct uart_port *port, unsigned int ch, + struct pt_regs *regs) { #ifdef SUPPORT_SYSRQ if (port->sysrq) { if (ch && time_before(jiffies, port->sysrq)) { - handle_sysrq(ch, port->info->tty); + handle_sysrq(ch, regs, port->info->tty); port->sysrq = 0; return 1; } @@ -424,7 +425,7 @@ uart_handle_sysrq_char(struct uart_port *port, unsigned int ch) return 0; } #ifndef SUPPORT_SYSRQ -#define uart_handle_sysrq_char(port,ch) uart_handle_sysrq_char(port, 0) +#define uart_handle_sysrq_char(port,ch,regs) uart_handle_sysrq_char(port, 0, NULL) #endif /* diff --git a/trunk/include/linux/serio.h b/trunk/include/linux/serio.h index b99c5ca9708d..c9069310b6ac 100644 --- a/trunk/include/linux/serio.h +++ b/trunk/include/linux/serio.h @@ -41,7 +41,6 @@ struct serio { void (*stop)(struct serio *); struct serio *parent, *child; - unsigned int depth; /* level of nesting in serio hierarchy */ struct serio_driver *drv; /* accessed from interrupt, must be protected by serio->lock and serio->sem */ struct mutex drv_mutex; /* protects serio->drv so attributes can pin driver */ @@ -61,7 +60,8 @@ struct serio_driver { unsigned int manual_bind; void (*write_wakeup)(struct serio *); - irqreturn_t (*interrupt)(struct serio *, unsigned char, unsigned int); + irqreturn_t (*interrupt)(struct serio *, unsigned char, + unsigned int, struct pt_regs *); int (*connect)(struct serio *, struct serio_driver *drv); int (*reconnect)(struct serio *); void (*disconnect)(struct serio *); @@ -75,7 +75,7 @@ int serio_open(struct serio *serio, struct serio_driver *drv); void serio_close(struct serio *serio); void serio_rescan(struct serio *serio); void serio_reconnect(struct serio *serio); -irqreturn_t serio_interrupt(struct serio *serio, unsigned char data, unsigned int flags); +irqreturn_t serio_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs); void __serio_register_port(struct serio *serio, struct module *owner); static inline void serio_register_port(struct serio *serio) diff --git a/trunk/include/linux/smb_fs.h b/trunk/include/linux/smb_fs.h index 13b3af547864..367d6c3e8ed4 100644 --- a/trunk/include/linux/smb_fs.h +++ b/trunk/include/linux/smb_fs.h @@ -43,17 +43,17 @@ static inline struct smb_inode_info *SMB_I(struct inode *inode) /* macro names are short for word, double-word, long value (?) */ #define WVAL(buf,pos) \ - (le16_to_cpu(get_unaligned((__le16 *)((u8 *)(buf) + (pos))))) + (le16_to_cpu(get_unaligned((u16 *)((u8 *)(buf) + (pos))))) #define DVAL(buf,pos) \ - (le32_to_cpu(get_unaligned((__le32 *)((u8 *)(buf) + (pos))))) + (le32_to_cpu(get_unaligned((u32 *)((u8 *)(buf) + (pos))))) #define LVAL(buf,pos) \ - (le64_to_cpu(get_unaligned((__le64 *)((u8 *)(buf) + (pos))))) + (le64_to_cpu(get_unaligned((u64 *)((u8 *)(buf) + (pos))))) #define WSET(buf,pos,val) \ - put_unaligned(cpu_to_le16((u16)(val)), (__le16 *)((u8 *)(buf) + (pos))) + put_unaligned(cpu_to_le16((u16)(val)), (u16 *)((u8 *)(buf) + (pos))) #define DSET(buf,pos,val) \ - put_unaligned(cpu_to_le32((u32)(val)), (__le32 *)((u8 *)(buf) + (pos))) + put_unaligned(cpu_to_le32((u32)(val)), (u32 *)((u8 *)(buf) + (pos))) #define LSET(buf,pos,val) \ - put_unaligned(cpu_to_le64((u64)(val)), (__le64 *)((u8 *)(buf) + (pos))) + put_unaligned(cpu_to_le64((u64)(val)), (u64 *)((u8 *)(buf) + (pos))) /* where to find the base of the SMB packet proper */ #define smb_base(buf) ((u8 *)(((u8 *)(buf))+4)) diff --git a/trunk/include/linux/spinlock.h b/trunk/include/linux/spinlock.h index 8451052ca66f..b800d2d68b32 100644 --- a/trunk/include/linux/spinlock.h +++ b/trunk/include/linux/spinlock.h @@ -183,27 +183,13 @@ do { \ #define read_lock(lock) _read_lock(lock) #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) - #define spin_lock_irqsave(lock, flags) flags = _spin_lock_irqsave(lock) #define read_lock_irqsave(lock, flags) flags = _read_lock_irqsave(lock) #define write_lock_irqsave(lock, flags) flags = _write_lock_irqsave(lock) - -#ifdef CONFIG_DEBUG_LOCK_ALLOC -#define spin_lock_irqsave_nested(lock, flags, subclass) \ - flags = _spin_lock_irqsave_nested(lock, subclass) -#else -#define spin_lock_irqsave_nested(lock, flags, subclass) \ - flags = _spin_lock_irqsave(lock) -#endif - #else - #define spin_lock_irqsave(lock, flags) _spin_lock_irqsave(lock, flags) #define read_lock_irqsave(lock, flags) _read_lock_irqsave(lock, flags) #define write_lock_irqsave(lock, flags) _write_lock_irqsave(lock, flags) -#define spin_lock_irqsave_nested(lock, flags, subclass) \ - spin_lock_irqsave(lock, flags) - #endif #define spin_lock_irq(lock) _spin_lock_irq(lock) diff --git a/trunk/include/linux/spinlock_api_smp.h b/trunk/include/linux/spinlock_api_smp.h index 8a2307ce7296..8828b8155e9c 100644 --- a/trunk/include/linux/spinlock_api_smp.h +++ b/trunk/include/linux/spinlock_api_smp.h @@ -32,8 +32,6 @@ void __lockfunc _read_lock_irq(rwlock_t *lock) __acquires(lock); void __lockfunc _write_lock_irq(rwlock_t *lock) __acquires(lock); unsigned long __lockfunc _spin_lock_irqsave(spinlock_t *lock) __acquires(lock); -unsigned long __lockfunc _spin_lock_irqsave_nested(spinlock_t *lock, int subclass) - __acquires(lock); unsigned long __lockfunc _read_lock_irqsave(rwlock_t *lock) __acquires(lock); unsigned long __lockfunc _write_lock_irqsave(rwlock_t *lock) diff --git a/trunk/include/linux/sunrpc/msg_prot.h b/trunk/include/linux/sunrpc/msg_prot.h index 606cb2165232..1e65f2dd80e5 100644 --- a/trunk/include/linux/sunrpc/msg_prot.h +++ b/trunk/include/linux/sunrpc/msg_prot.h @@ -56,9 +56,7 @@ enum rpc_accept_stat { RPC_PROG_MISMATCH = 2, RPC_PROC_UNAVAIL = 3, RPC_GARBAGE_ARGS = 4, - RPC_SYSTEM_ERR = 5, - /* internal use only */ - RPC_DROP_REPLY = 60000, + RPC_SYSTEM_ERR = 5 }; enum rpc_reject_stat { diff --git a/trunk/include/linux/sunrpc/svc.h b/trunk/include/linux/sunrpc/svc.h index 965d6c20086e..d6288e89fd9d 100644 --- a/trunk/include/linux/sunrpc/svc.h +++ b/trunk/include/linux/sunrpc/svc.h @@ -57,8 +57,7 @@ struct svc_serv { struct svc_stat * sv_stats; /* RPC statistics */ spinlock_t sv_lock; unsigned int sv_nrthreads; /* # of server threads */ - unsigned int sv_max_payload; /* datagram payload size */ - unsigned int sv_max_mesg; /* max_payload + 1 page for overheads */ + unsigned int sv_bufsz; /* datagram buffer size */ unsigned int sv_xdrsize; /* XDR buffer size */ struct list_head sv_permsocks; /* all permanent sockets */ @@ -335,7 +334,7 @@ struct svc_version { /* * RPC procedure info */ -typedef __be32 (*svc_procfunc)(struct svc_rqst *, void *argp, void *resp); +typedef int (*svc_procfunc)(struct svc_rqst *, void *argp, void *resp); struct svc_procedure { svc_procfunc pc_func; /* process the request */ kxdrproc_t pc_decode; /* XDR decode args */ diff --git a/trunk/include/linux/sunrpc/xdr.h b/trunk/include/linux/sunrpc/xdr.h index ac69e5511606..953723b09bc6 100644 --- a/trunk/include/linux/sunrpc/xdr.h +++ b/trunk/include/linux/sunrpc/xdr.h @@ -74,7 +74,6 @@ struct xdr_buf { #define rpc_proc_unavail __constant_htonl(RPC_PROC_UNAVAIL) #define rpc_garbage_args __constant_htonl(RPC_GARBAGE_ARGS) #define rpc_system_err __constant_htonl(RPC_SYSTEM_ERR) -#define rpc_drop_reply __constant_htonl(RPC_DROP_REPLY) #define rpc_auth_ok __constant_htonl(RPC_AUTH_OK) #define rpc_autherr_badcred __constant_htonl(RPC_AUTH_BADCRED) diff --git a/trunk/include/linux/syscalls.h b/trunk/include/linux/syscalls.h index 1912c6cbef55..3efcfc7e9c6c 100644 --- a/trunk/include/linux/syscalls.h +++ b/trunk/include/linux/syscalls.h @@ -431,10 +431,6 @@ asmlinkage long sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event __user *event); asmlinkage long sys_epoll_wait(int epfd, struct epoll_event __user *events, int maxevents, int timeout); -asmlinkage long sys_epoll_pwait(int epfd, struct epoll_event __user *events, - int maxevents, int timeout, - const sigset_t __user *sigmask, - size_t sigsetsize); asmlinkage long sys_gethostname(char __user *name, int len); asmlinkage long sys_sethostname(char __user *name, int len); asmlinkage long sys_setdomainname(char __user *name, int len); @@ -597,7 +593,7 @@ asmlinkage long sys_tee(int fdin, int fdout, size_t len, unsigned int flags); asmlinkage long sys_sync_file_range(int fd, loff_t offset, loff_t nbytes, unsigned int flags); asmlinkage long sys_get_robust_list(int pid, - struct robust_list_head __user * __user *head_ptr, + struct robust_list_head __user **head_ptr, size_t __user *len_ptr); asmlinkage long sys_set_robust_list(struct robust_list_head __user *head, size_t len); diff --git a/trunk/include/linux/sysctl.h b/trunk/include/linux/sysctl.h index d98562f1df76..1b24bd45e080 100644 --- a/trunk/include/linux/sysctl.h +++ b/trunk/include/linux/sysctl.h @@ -6,17 +6,10 @@ **************************************************************** **************************************************************** ** - ** WARNING: ** The values in this file are exported to user space via - ** the sysctl() binary interface. Do *NOT* change the - ** numbering of any existing values here, and do not change - ** any numbers within any one set of values. If you have to - ** have to redefine an existing interface, use a new number for it. - ** The kernel will then return -ENOTDIR to any application using - ** the old binary interface. - ** - ** For new interfaces unless you really need a binary number - ** please use CTL_UNNUMBERED. + ** the sysctl() binary interface. However this interface + ** is unstable and deprecated and will be removed in the future. + ** For a stable interface use /proc/sys. ** **************************************************************** **************************************************************** @@ -55,7 +48,6 @@ struct __sysctl_args { #ifdef __KERNEL__ #define CTL_ANY -1 /* Matches any name */ #define CTL_NONE 0 -#define CTL_UNNUMBERED CTL_NONE /* sysctl without a binary number */ #endif enum @@ -969,8 +961,8 @@ extern ctl_handler sysctl_ms_jiffies; /* * Register a set of sysctl names by calling register_sysctl_table * with an initialised array of ctl_table's. An entry with zero - * ctl_name and NULL procname terminates the table. table->de will be - * set up by the registration and need not be initialised in advance. + * ctl_name terminates the table. table->de will be set up by the + * registration and need not be initialised in advance. * * sysctl names can be mirrored automatically under /proc/sys. The * procname supplied controls /proc naming. @@ -981,10 +973,7 @@ extern ctl_handler sysctl_ms_jiffies; * Leaf nodes in the sysctl tree will be represented by a single file * under /proc; non-leaf nodes will be represented by directories. A * null procname disables /proc mirroring at this node. - * - * sysctl entries with a zero ctl_name will not be available through - * the binary sysctl interface. - * + * * sysctl(2) can automatically manage read and write requests through * the sysctl table. The data and maxlen fields of the ctl_table * struct enable minimal validation of the values being written to be diff --git a/trunk/include/linux/sysfs.h b/trunk/include/linux/sysfs.h index 2129d1b6c874..6d5c43d31dec 100644 --- a/trunk/include/linux/sysfs.h +++ b/trunk/include/linux/sysfs.h @@ -96,9 +96,6 @@ sysfs_remove_dir(struct kobject *); extern int __must_check sysfs_rename_dir(struct kobject *, const char *new_name); -extern int __must_check -sysfs_move_dir(struct kobject *, struct kobject *); - extern int __must_check sysfs_create_file(struct kobject *, const struct attribute *); @@ -145,11 +142,6 @@ static inline int sysfs_rename_dir(struct kobject * k, const char *new_name) return 0; } -static inline int sysfs_move_dir(struct kobject * k, struct kobject * new_parent) -{ - return 0; -} - static inline int sysfs_create_file(struct kobject * k, const struct attribute * a) { return 0; diff --git a/trunk/include/linux/sysrq.h b/trunk/include/linux/sysrq.h index 9df8833670cb..e657e523b9bf 100644 --- a/trunk/include/linux/sysrq.h +++ b/trunk/include/linux/sysrq.h @@ -29,7 +29,7 @@ struct tty_struct; #define SYSRQ_ENABLE_RTNICE 0x0100 struct sysrq_key_op { - void (*handler)(int, struct tty_struct *); + void (*handler)(int, struct pt_regs *, struct tty_struct *); char *help_msg; char *action_msg; int enable_mask; @@ -42,8 +42,8 @@ struct sysrq_key_op { * are available -- else NULL's). */ -void handle_sysrq(int, struct tty_struct *); -void __handle_sysrq(int, struct tty_struct *, int check_mask); +void handle_sysrq(int, struct pt_regs *, struct tty_struct *); +void __handle_sysrq(int, struct pt_regs *, struct tty_struct *, int check_mask); int register_sysrq_key(int, struct sysrq_key_op *); int unregister_sysrq_key(int, struct sysrq_key_op *); struct sysrq_key_op *__sysrq_get_key_op(int key); diff --git a/trunk/include/linux/taskstats_kern.h b/trunk/include/linux/taskstats_kern.h index 6562a2050a25..16894b7edcc8 100644 --- a/trunk/include/linux/taskstats_kern.h +++ b/trunk/include/linux/taskstats_kern.h @@ -23,26 +23,25 @@ static inline void taskstats_exit_free(struct taskstats *tidstats) static inline void taskstats_tgid_init(struct signal_struct *sig) { + spin_lock_init(&sig->stats_lock); sig->stats = NULL; } -static inline void taskstats_tgid_alloc(struct task_struct *tsk) +static inline void taskstats_tgid_alloc(struct signal_struct *sig) { - struct signal_struct *sig = tsk->signal; struct taskstats *stats; + unsigned long flags; - if (sig->stats != NULL) - return; - - /* No problem if kmem_cache_zalloc() fails */ stats = kmem_cache_zalloc(taskstats_cache, SLAB_KERNEL); + if (!stats) + return; - spin_lock_irq(&tsk->sighand->siglock); + spin_lock_irqsave(&sig->stats_lock, flags); if (!sig->stats) { sig->stats = stats; stats = NULL; } - spin_unlock_irq(&tsk->sighand->siglock); + spin_unlock_irqrestore(&sig->stats_lock, flags); if (stats) kmem_cache_free(taskstats_cache, stats); @@ -50,13 +49,23 @@ static inline void taskstats_tgid_alloc(struct task_struct *tsk) static inline void taskstats_tgid_free(struct signal_struct *sig) { - if (sig->stats) - kmem_cache_free(taskstats_cache, sig->stats); + struct taskstats *stats = NULL; + unsigned long flags; + + spin_lock_irqsave(&sig->stats_lock, flags); + if (sig->stats) { + stats = sig->stats; + sig->stats = NULL; + } + spin_unlock_irqrestore(&sig->stats_lock, flags); + if (stats) + kmem_cache_free(taskstats_cache, stats); } 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); +extern void taskstats_tgid_alloc(struct signal_struct *); #else static inline void taskstats_exit_alloc(struct taskstats **ptidstats, unsigned int *mycpu) {} @@ -68,7 +77,7 @@ static inline void taskstats_exit_send(struct task_struct *tsk, {} 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_alloc(struct signal_struct *sig) {} static inline void taskstats_tgid_free(struct signal_struct *sig) {} diff --git a/trunk/include/linux/tcp.h b/trunk/include/linux/tcp.h index 2d36f6db3706..0e058a2d1c6d 100644 --- a/trunk/include/linux/tcp.h +++ b/trunk/include/linux/tcp.h @@ -342,8 +342,6 @@ struct tcp_sock { unsigned long last_synq_overflow; - __u32 tso_deferred; - /* Receiver side RTT estimation */ struct { __u32 rtt; diff --git a/trunk/include/linux/textsearch.h b/trunk/include/linux/textsearch.h index 004808a6df1d..7dac8f04d28e 100644 --- a/trunk/include/linux/textsearch.h +++ b/trunk/include/linux/textsearch.h @@ -20,7 +20,7 @@ struct ts_config; /** * struct ts_state - search state * @offset: offset for next match - * @cb: control buffer, for persistent variables of get_next_block() + * @cb: control buffer, for persistant variables of get_next_block() */ struct ts_state { @@ -71,7 +71,7 @@ struct ts_config * Called repeatedly until 0 is returned. Must assign the * head of the next block of data to &*dst and return the length * of the block or 0 if at the end. consumed == 0 indicates - * a new search. May store/read persistent values in state->cb. + * a new search. May store/read persistant values in state->cb. */ unsigned int (*get_next_block)(unsigned int consumed, const u8 **dst, diff --git a/trunk/include/linux/tifm.h b/trunk/include/linux/tifm.h index dfb8052eee5e..203dd5e11ecb 100644 --- a/trunk/include/linux/tifm.h +++ b/trunk/include/linux/tifm.h @@ -17,7 +17,6 @@ #include #include #include -#include /* Host registers (relative to pci base address): */ enum { diff --git a/trunk/include/linux/timex.h b/trunk/include/linux/timex.h index db501dc23c29..049dfe4a11f2 100644 --- a/trunk/include/linux/timex.h +++ b/trunk/include/linux/timex.h @@ -293,9 +293,6 @@ extern void second_overflow(void); extern void update_ntp_one_tick(void); extern int do_adjtimex(struct timex *); -/* Don't use! Compatibility define for existing users. */ -#define tickadj (500/HZ ? : 1) - #endif /* KERNEL */ #endif /* LINUX_TIMEX_H */ diff --git a/trunk/include/linux/tipc.h b/trunk/include/linux/tipc.h index bea469455a0c..243a15f54002 100644 --- a/trunk/include/linux/tipc.h +++ b/trunk/include/linux/tipc.h @@ -129,7 +129,6 @@ static inline unsigned int tipc_node(__u32 addr) #define TIPC_SUB_PORTS 0x01 /* filter for port availability */ #define TIPC_SUB_SERVICE 0x02 /* filter for service availability */ -#define TIPC_SUB_CANCEL 0x04 /* cancel a subscription */ #if 0 /* The following filter options are not currently implemented */ #define TIPC_SUB_NO_BIND_EVTS 0x04 /* filter out "publish" events */ diff --git a/trunk/include/linux/tty.h b/trunk/include/linux/tty.h index 65321f911c1e..44091c0db0b4 100644 --- a/trunk/include/linux/tty.h +++ b/trunk/include/linux/tty.h @@ -276,8 +276,9 @@ extern int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc); extern int tty_unregister_ldisc(int disc); extern int tty_register_driver(struct tty_driver *driver); extern int tty_unregister_driver(struct tty_driver *driver); -extern struct device *tty_register_device(struct tty_driver *driver, - unsigned index, struct device *dev); +extern struct class_device *tty_register_device(struct tty_driver *driver, + unsigned index, + struct device *dev); extern void tty_unregister_device(struct tty_driver *driver, unsigned index); extern int tty_read_raw_data(struct tty_struct *tty, unsigned char *bufp, int buflen); diff --git a/trunk/include/linux/ufs_fs.h b/trunk/include/linux/ufs_fs.h index 28967eda9d7b..fc62887c5206 100644 --- a/trunk/include/linux/ufs_fs.h +++ b/trunk/include/linux/ufs_fs.h @@ -351,14 +351,6 @@ struct ufs2_csum_total { __fs64 cs_spare[3]; /* future expansion */ }; -struct ufs_csum_core { - __u64 cs_ndir; /* number of directories */ - __u64 cs_nbfree; /* number of free blocks */ - __u64 cs_nifree; /* number of free inodes */ - __u64 cs_nffree; /* number of free frags */ - __u64 cs_numclusters; /* number of free clusters */ -}; - /* * File system flags */ @@ -723,7 +715,7 @@ struct ufs_cg_private_info { struct ufs_sb_private_info { struct ufs_buffer_head s_ubh; /* buffer containing super block */ - struct ufs_csum_core cs_total; + struct ufs2_csum_total cs_total; __u32 s_sblkno; /* offset of super-blocks in filesys */ __u32 s_cblkno; /* offset of cg-block in filesys */ __u32 s_iblkno; /* offset of inode-blocks in filesys */ @@ -908,7 +900,7 @@ struct ufs_super_block_third { __fs64 fs_csaddr; /* blk addr of cyl grp summary area */ __fs64 fs_pendingblocks;/* blocks in process of being freed */ __fs32 fs_pendinginodes;/*inodes in process of being freed */ - } __attribute__ ((packed)) fs_u2; + } fs_u2; } fs_un1; union { struct { diff --git a/trunk/include/linux/unwind.h b/trunk/include/linux/unwind.h index 749928c161fb..73e1751d03dd 100644 --- a/trunk/include/linux/unwind.h +++ b/trunk/include/linux/unwind.h @@ -26,7 +26,6 @@ struct module; * Initialize unwind support. */ extern void unwind_init(void); -extern void unwind_setup(void); #ifdef CONFIG_MODULES @@ -74,7 +73,6 @@ extern int unwind_to_user(struct unwind_frame_info *); struct unwind_frame_info {}; static inline void unwind_init(void) {} -static inline void unwind_setup(void) {} #ifdef CONFIG_MODULES diff --git a/trunk/include/linux/usb.h b/trunk/include/linux/usb.h index 0cd73edeef13..190cc1b78fe2 100644 --- a/trunk/include/linux/usb.h +++ b/trunk/include/linux/usb.h @@ -313,13 +313,8 @@ struct usb_bus { /* This is arbitrary. * From USB 2.0 spec Table 11-13, offset 7, a hub can * have up to 255 ports. The most yet reported is 10. - * - * Current Wireless USB host hardware (Intel i1480 for example) allows - * up to 22 devices to connect. Upcoming hardware might raise that - * limit. Because the arrays need to add a bit for hub status data, we - * do 31, so plus one evens out to four bytes. */ -#define USB_MAXCHILDREN (31) +#define USB_MAXCHILDREN (16) struct usb_tt; @@ -362,8 +357,7 @@ struct usb_device { u8 portnum; /* Parent port number (origin 1) */ u8 level; /* Number of USB hub ancestors */ - unsigned discon_suspended:1; /* Disconnected while suspended */ - unsigned have_langid:1; /* whether string_langid is valid */ + int have_langid; /* whether string_langid is valid */ int string_langid; /* language ID for strings */ /* static strings from the device */ @@ -416,38 +410,15 @@ extern struct usb_device *usb_find_device(u16 vendor_id, u16 product_id); /* USB autosuspend and autoresume */ #ifdef CONFIG_USB_SUSPEND -extern int usb_autopm_set_interface(struct usb_interface *intf); extern int usb_autopm_get_interface(struct usb_interface *intf); extern void usb_autopm_put_interface(struct usb_interface *intf); -static inline void usb_autopm_enable(struct usb_interface *intf) -{ - intf->pm_usage_cnt = 0; - usb_autopm_set_interface(intf); -} - -static inline void usb_autopm_disable(struct usb_interface *intf) -{ - intf->pm_usage_cnt = 1; - usb_autopm_set_interface(intf); -} - #else - -static inline int usb_autopm_set_interface(struct usb_interface *intf) -{ return 0; } - -static inline int usb_autopm_get_interface(struct usb_interface *intf) -{ return 0; } - -static inline void usb_autopm_put_interface(struct usb_interface *intf) -{ } -static inline void usb_autopm_enable(struct usb_interface *intf) -{ } -static inline void usb_autopm_disable(struct usb_interface *intf) -{ } +#define usb_autopm_get_interface(intf) 0 +#define usb_autopm_put_interface(intf) do {} while (0) #endif + /*-------------------------------------------------------------------------*/ /* for drivers using iso endpoints */ @@ -519,137 +490,17 @@ static inline int usb_make_path (struct usb_device *dev, char *buf, /*-------------------------------------------------------------------------*/ -/** - * usb_endpoint_dir_in - check if the endpoint has IN direction - * @epd: endpoint to be checked - * - * Returns true if the endpoint is of type IN, otherwise it returns false. - */ -static inline int usb_endpoint_dir_in(const struct usb_endpoint_descriptor *epd) -{ - return ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN); -} - -/** - * usb_endpoint_dir_out - check if the endpoint has OUT direction - * @epd: endpoint to be checked - * - * Returns true if the endpoint is of type OUT, otherwise it returns false. - */ -static inline int usb_endpoint_dir_out(const struct usb_endpoint_descriptor *epd) -{ - return ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT); -} - -/** - * usb_endpoint_xfer_bulk - check if the endpoint has bulk transfer type - * @epd: endpoint to be checked - * - * Returns true if the endpoint is of type bulk, otherwise it returns false. - */ -static inline int usb_endpoint_xfer_bulk(const struct usb_endpoint_descriptor *epd) -{ - return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == - USB_ENDPOINT_XFER_BULK); -} - -/** - * usb_endpoint_xfer_int - check if the endpoint has interrupt transfer type - * @epd: endpoint to be checked - * - * Returns true if the endpoint is of type interrupt, otherwise it returns - * false. - */ -static inline int usb_endpoint_xfer_int(const struct usb_endpoint_descriptor *epd) -{ - return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == - USB_ENDPOINT_XFER_INT); -} - -/** - * usb_endpoint_xfer_isoc - check if the endpoint has isochronous transfer type - * @epd: endpoint to be checked - * - * Returns true if the endpoint is of type isochronous, otherwise it returns - * false. - */ -static inline int usb_endpoint_xfer_isoc(const struct usb_endpoint_descriptor *epd) -{ - return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == - USB_ENDPOINT_XFER_ISOC); -} - -/** - * usb_endpoint_is_bulk_in - check if the endpoint is bulk IN - * @epd: endpoint to be checked - * - * Returns true if the endpoint has bulk transfer type and IN direction, - * otherwise it returns false. - */ -static inline int usb_endpoint_is_bulk_in(const struct usb_endpoint_descriptor *epd) -{ - return (usb_endpoint_xfer_bulk(epd) && usb_endpoint_dir_in(epd)); -} - -/** - * usb_endpoint_is_bulk_out - check if the endpoint is bulk OUT - * @epd: endpoint to be checked - * - * Returns true if the endpoint has bulk transfer type and OUT direction, - * otherwise it returns false. - */ -static inline int usb_endpoint_is_bulk_out(const struct usb_endpoint_descriptor *epd) -{ - return (usb_endpoint_xfer_bulk(epd) && usb_endpoint_dir_out(epd)); -} - -/** - * usb_endpoint_is_int_in - check if the endpoint is interrupt IN - * @epd: endpoint to be checked - * - * Returns true if the endpoint has interrupt transfer type and IN direction, - * otherwise it returns false. - */ -static inline int usb_endpoint_is_int_in(const struct usb_endpoint_descriptor *epd) -{ - return (usb_endpoint_xfer_int(epd) && usb_endpoint_dir_in(epd)); -} - -/** - * usb_endpoint_is_int_out - check if the endpoint is interrupt OUT - * @epd: endpoint to be checked - * - * Returns true if the endpoint has interrupt transfer type and OUT direction, - * otherwise it returns false. - */ -static inline int usb_endpoint_is_int_out(const struct usb_endpoint_descriptor *epd) -{ - return (usb_endpoint_xfer_int(epd) && usb_endpoint_dir_out(epd)); -} - -/** - * usb_endpoint_is_isoc_in - check if the endpoint is isochronous IN - * @epd: endpoint to be checked - * - * Returns true if the endpoint has isochronous transfer type and IN direction, - * otherwise it returns false. - */ -static inline int usb_endpoint_is_isoc_in(const struct usb_endpoint_descriptor *epd) -{ - return (usb_endpoint_xfer_isoc(epd) && usb_endpoint_dir_in(epd)); -} - -/** - * usb_endpoint_is_isoc_out - check if the endpoint is isochronous OUT - * @epd: endpoint to be checked - * - * Returns true if the endpoint has isochronous transfer type and OUT direction, - * otherwise it returns false. - */ -static inline int usb_endpoint_is_isoc_out(const struct usb_endpoint_descriptor *epd) -{ - return (usb_endpoint_xfer_isoc(epd) && usb_endpoint_dir_out(epd)); -} +extern int usb_endpoint_dir_in(const struct usb_endpoint_descriptor *epd); +extern int usb_endpoint_dir_out(const struct usb_endpoint_descriptor *epd); +extern int usb_endpoint_xfer_bulk(const struct usb_endpoint_descriptor *epd); +extern int usb_endpoint_xfer_int(const struct usb_endpoint_descriptor *epd); +extern int usb_endpoint_xfer_isoc(const struct usb_endpoint_descriptor *epd); +extern int usb_endpoint_is_bulk_in(const struct usb_endpoint_descriptor *epd); +extern int usb_endpoint_is_bulk_out(const struct usb_endpoint_descriptor *epd); +extern int usb_endpoint_is_int_in(const struct usb_endpoint_descriptor *epd); +extern int usb_endpoint_is_int_out(const struct usb_endpoint_descriptor *epd); +extern int usb_endpoint_is_isoc_in(const struct usb_endpoint_descriptor *epd); +extern int usb_endpoint_is_isoc_out(const struct usb_endpoint_descriptor *epd); /*-------------------------------------------------------------------------*/ @@ -913,8 +764,9 @@ struct usb_iso_packet_descriptor { }; struct urb; +struct pt_regs; -typedef void (*usb_complete_t)(struct urb *); +typedef void (*usb_complete_t)(struct urb *, struct pt_regs *); /** * struct urb - USB Request Block diff --git a/trunk/include/linux/usb/serial.h b/trunk/include/linux/usb/serial.h index 91b3ea2bbb14..91c983eef899 100644 --- a/trunk/include/linux/usb/serial.h +++ b/trunk/include/linux/usb/serial.h @@ -226,10 +226,10 @@ struct usb_serial_driver { int (*tiocmget) (struct usb_serial_port *port, struct file *file); int (*tiocmset) (struct usb_serial_port *port, struct file *file, unsigned int set, unsigned int clear); - void (*read_int_callback)(struct urb *urb); - void (*write_int_callback)(struct urb *urb); - void (*read_bulk_callback)(struct urb *urb); - void (*write_bulk_callback)(struct urb *urb); + void (*read_int_callback)(struct urb *urb, struct pt_regs *regs); + void (*write_int_callback)(struct urb *urb, struct pt_regs *regs); + void (*read_bulk_callback)(struct urb *urb, struct pt_regs *regs); + void (*write_bulk_callback)(struct urb *urb, struct pt_regs *regs); }; #define to_usb_serial_driver(d) container_of(d, struct usb_serial_driver, driver) @@ -262,8 +262,8 @@ extern int usb_serial_generic_write (struct usb_serial_port *port, const unsigne extern void usb_serial_generic_close (struct usb_serial_port *port, struct file *filp); extern int usb_serial_generic_write_room (struct usb_serial_port *port); extern int usb_serial_generic_chars_in_buffer (struct usb_serial_port *port); -extern void usb_serial_generic_read_bulk_callback (struct urb *urb); -extern void usb_serial_generic_write_bulk_callback (struct urb *urb); +extern void usb_serial_generic_read_bulk_callback (struct urb *urb, struct pt_regs *regs); +extern void usb_serial_generic_write_bulk_callback (struct urb *urb, struct pt_regs *regs); extern void usb_serial_generic_shutdown (struct usb_serial *serial); extern int usb_serial_generic_register (int debug); extern void usb_serial_generic_deregister (void); diff --git a/trunk/include/linux/videodev2.h b/trunk/include/linux/videodev2.h index df5c4654360d..c5fdf6259548 100644 --- a/trunk/include/linux/videodev2.h +++ b/trunk/include/linux/videodev2.h @@ -243,7 +243,7 @@ struct v4l2_pix_format #define V4L2_PIX_FMT_YUV420 v4l2_fourcc('Y','U','1','2') /* 12 YUV 4:2:0 */ #define V4L2_PIX_FMT_YYUV v4l2_fourcc('Y','Y','U','V') /* 16 YUV 4:2:2 */ #define V4L2_PIX_FMT_HI240 v4l2_fourcc('H','I','2','4') /* 8 8-bit color */ -#define V4L2_PIX_FMT_HM12 v4l2_fourcc('H','M','1','2') /* 8 YUV 4:2:0 16x16 macroblocks */ +#define V4L2_PIX_FMT_HM12 v4l2_fourcc('H','M','1','2') /* 8 YUV 4:1:1 16x16 macroblocks */ /* see http://www.siliconimaging.com/RGB%20Bayer.htm */ #define V4L2_PIX_FMT_SBGGR8 v4l2_fourcc('B','A','8','1') /* 8 BGBG.. GRGR.. */ diff --git a/trunk/include/linux/vmalloc.h b/trunk/include/linux/vmalloc.h index 924e502905d4..ce5f1482e6be 100644 --- a/trunk/include/linux/vmalloc.h +++ b/trunk/include/linux/vmalloc.h @@ -23,14 +23,13 @@ struct vm_area_struct; #endif struct vm_struct { - /* keep next,addr,size together to speedup lookups */ - struct vm_struct *next; void *addr; unsigned long size; unsigned long flags; struct page **pages; unsigned int nr_pages; unsigned long phys_addr; + struct vm_struct *next; }; /* @@ -61,8 +60,7 @@ extern struct vm_struct *get_vm_area(unsigned long size, unsigned long flags); extern struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags, unsigned long start, unsigned long end); extern struct vm_struct *get_vm_area_node(unsigned long size, - unsigned long flags, int node, - gfp_t gfp_mask); + unsigned long flags, int node); extern struct vm_struct *remove_vm_area(void *addr); extern int map_vm_area(struct vm_struct *area, pgprot_t prot, struct page ***pages); diff --git a/trunk/include/linux/wait.h b/trunk/include/linux/wait.h index e820d00e1383..b3b9048421d8 100644 --- a/trunk/include/linux/wait.h +++ b/trunk/include/linux/wait.h @@ -79,15 +79,6 @@ struct task_struct; extern void init_waitqueue_head(wait_queue_head_t *q); -#ifdef CONFIG_LOCKDEP -# define __WAIT_QUEUE_HEAD_INIT_ONSTACK(name) \ - ({ init_waitqueue_head(&name); name; }) -# define DECLARE_WAIT_QUEUE_HEAD_ONSTACK(name) \ - wait_queue_head_t name = __WAIT_QUEUE_HEAD_INIT_ONSTACK(name) -#else -# define DECLARE_WAIT_QUEUE_HEAD_ONSTACK(name) DECLARE_WAIT_QUEUE_HEAD(name) -#endif - static inline void init_waitqueue_entry(wait_queue_t *q, struct task_struct *p) { q->flags = 0; diff --git a/trunk/include/linux/writeback.h b/trunk/include/linux/writeback.h index fc35e6bdfb93..a341c8032866 100644 --- a/trunk/include/linux/writeback.h +++ b/trunk/include/linux/writeback.h @@ -85,6 +85,7 @@ int wakeup_pdflush(long nr_pages); void laptop_io_completion(void); void laptop_sync_completion(void); void throttle_vm_writeout(void); +void writeback_congestion_end(void); /* These are exported to sysctl. */ extern int dirty_background_ratio; diff --git a/trunk/include/linux/xattr.h b/trunk/include/linux/xattr.h index 0e7f1e20ea45..cda8a96e2fa0 100644 --- a/trunk/include/linux/xattr.h +++ b/trunk/include/linux/xattr.h @@ -41,7 +41,6 @@ struct xattr_handler { }; ssize_t vfs_getxattr(struct dentry *, char *, void *, size_t); -ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size); int vfs_setxattr(struct dentry *, char *, void *, size_t, int); int vfs_removexattr(struct dentry *, char *); diff --git a/trunk/include/net/bluetooth/hci_core.h b/trunk/include/net/bluetooth/hci_core.h index c0fc39620f36..df22efcfcc0b 100644 --- a/trunk/include/net/bluetooth/hci_core.h +++ b/trunk/include/net/bluetooth/hci_core.h @@ -153,7 +153,6 @@ struct hci_conn { __u8 mode; __u8 type; __u8 out; - __u8 attempt; __u8 dev_class[3]; __u8 features[8]; __u16 interval; @@ -290,22 +289,6 @@ static inline struct hci_conn *hci_conn_hash_lookup_ba(struct hci_dev *hdev, return NULL; } -static inline struct hci_conn *hci_conn_hash_lookup_state(struct hci_dev *hdev, - __u8 type, __u16 state) -{ - struct hci_conn_hash *h = &hdev->conn_hash; - struct list_head *p; - struct hci_conn *c; - - list_for_each(p, &h->list) { - c = list_entry(p, struct hci_conn, list); - if (c->type == type && c->state == state) - return c; - } - return NULL; -} - -void hci_acl_connect(struct hci_conn *conn); void hci_acl_disconn(struct hci_conn *conn, __u8 reason); void hci_add_sco(struct hci_conn *conn, __u16 handle); diff --git a/trunk/include/net/dn.h b/trunk/include/net/dn.h index ac4ce9091747..465b78302782 100644 --- a/trunk/include/net/dn.h +++ b/trunk/include/net/dn.h @@ -199,6 +199,11 @@ static inline void dn_sk_ports_copy(struct flowi *fl, struct dn_scp *scp) { fl->uli_u.dnports.sport = scp->addrloc; fl->uli_u.dnports.dport = scp->addrrem; + fl->uli_u.dnports.objnum = scp->addr.sdn_objnum; + if (fl->uli_u.dnports.objnum == 0) { + fl->uli_u.dnports.objnamel = (__u8)dn_ntohs(scp->addr.sdn_objnamel); + memcpy(fl->uli_u.dnports.objname, scp->addr.sdn_objname, 16); + } } extern unsigned dn_mss_from_pmtu(struct net_device *dev, int mtu); diff --git a/trunk/include/net/flow.h b/trunk/include/net/flow.h index 5cda27cd9deb..ddf5f3ca1720 100644 --- a/trunk/include/net/flow.h +++ b/trunk/include/net/flow.h @@ -68,6 +68,9 @@ struct flowi { struct { __le16 sport; __le16 dport; + __u8 objnum; + __u8 objnamel; /* Not 16 bits since max val is 16 */ + __u8 objname[16]; /* Not zero terminated */ } dnports; __be32 spi; @@ -94,7 +97,7 @@ struct flowi { #define FLOW_DIR_FWD 2 struct sock; -typedef int (*flow_resolve_t)(struct flowi *key, u16 family, u8 dir, +typedef void (*flow_resolve_t)(struct flowi *key, u16 family, u8 dir, void **objp, atomic_t **obj_refp); extern void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir, diff --git a/trunk/include/net/ieee80211softmac.h b/trunk/include/net/ieee80211softmac.h index 617b672b1132..425b3a57ac74 100644 --- a/trunk/include/net/ieee80211softmac.h +++ b/trunk/include/net/ieee80211softmac.h @@ -63,11 +63,13 @@ struct ieee80211softmac_wpa { /* * Information about association + * + * Do we need a lock for this? + * We only ever use this structure inlined + * into our global struct. I've used its lock, + * but maybe we need a local one here? */ struct ieee80211softmac_assoc_info { - - struct mutex mutex; - /* * This is the requested ESSID. It is written * only by the WX handlers. @@ -97,13 +99,12 @@ struct ieee80211softmac_assoc_info { * * bssfixed is used for SIOCSIWAP. */ - u8 static_essid; - u8 short_preamble_available; - u8 associating; - u8 associated; - u8 assoc_wait; - u8 bssvalid; - u8 bssfixed; + u8 static_essid:1, + short_preamble_available:1, + associating:1, + assoc_wait:1, + bssvalid:1, + bssfixed:1; /* Scan retries remaining */ int scan_retry; @@ -228,10 +229,12 @@ struct ieee80211softmac_device { /* private stuff follows */ /* this lock protects this structure */ spinlock_t lock; - - u8 running; /* SoftMAC started? */ - u8 scanning; - + + /* couple of flags */ + u8 scanning:1, /* protects scanning from being done multiple times at once */ + associated:1, + running:1; + struct ieee80211softmac_scaninfo *scaninfo; struct ieee80211softmac_assoc_info associnfo; struct ieee80211softmac_bss_info bssinfo; @@ -247,7 +250,7 @@ struct ieee80211softmac_device { /* we need to keep a list of network structs we copied */ struct list_head network_list; - + /* This must be the last item so that it points to the data * allocated beyond this structure by alloc_ieee80211 */ u8 priv[0]; @@ -292,7 +295,7 @@ static inline u8 ieee80211softmac_suggest_txrate(struct ieee80211softmac_device { struct ieee80211softmac_txrates *txrates = &mac->txrates; - if (!mac->associnfo.associated) + if (!mac->associated) return txrates->mgt_mcast_rate; /* We are associated, sending unicast frame */ diff --git a/trunk/include/net/inet_ecn.h b/trunk/include/net/inet_ecn.h index 7849844a4911..d599c6bfbb86 100644 --- a/trunk/include/net/inet_ecn.h +++ b/trunk/include/net/inet_ecn.h @@ -48,7 +48,7 @@ static inline __u8 INET_ECN_encapsulate(__u8 outer, __u8 inner) #define IP6_ECN_flow_xmit(sk, label) do { \ if (INET_ECN_is_capable(inet_sk(sk)->tos)) \ - (label) |= htonl(INET_ECN_ECT_0 << 20); \ + (label) |= __constant_htons(INET_ECN_ECT_0 << 4); \ } while (0) static inline int IP_ECN_set_ce(struct iphdr *iph) diff --git a/trunk/include/net/inet_timewait_sock.h b/trunk/include/net/inet_timewait_sock.h index 5f48748fe017..6d14c22a00c5 100644 --- a/trunk/include/net/inet_timewait_sock.h +++ b/trunk/include/net/inet_timewait_sock.h @@ -196,7 +196,6 @@ static inline void inet_twsk_put(struct inet_timewait_sock *tw) { if (atomic_dec_and_test(&tw->tw_refcnt)) { struct module *owner = tw->tw_prot->owner; - twsk_destructor((struct sock *)tw); #ifdef SOCK_REFCNT_DEBUG printk(KERN_DEBUG "%s timewait_sock %p released\n", tw->tw_prot->name, tw); diff --git a/trunk/include/net/inetpeer.h b/trunk/include/net/inetpeer.h index aa10a8178e70..925573fd2aed 100644 --- a/trunk/include/net/inetpeer.h +++ b/trunk/include/net/inetpeer.h @@ -17,15 +17,14 @@ struct inet_peer { - /* group together avl_left,avl_right,v4daddr to speedup lookups */ struct inet_peer *avl_left, *avl_right; - __be32 v4daddr; /* peer's address */ - __u16 avl_height; - __u16 ip_id_count; /* IP ID for the next packet */ struct inet_peer *unused_next, **unused_prevp; - __u32 dtime; /* the time of last use of not + unsigned long dtime; /* the time of last use of not * referenced entries */ atomic_t refcnt; + __be32 v4daddr; /* peer's address */ + __u16 avl_height; + __u16 ip_id_count; /* IP ID for the next packet */ atomic_t rid; /* Frag reception counter */ __u32 tcp_ts; unsigned long tcp_ts_stamp; @@ -36,8 +35,21 @@ void inet_initpeers(void) __init; /* can be called with or without local BH being disabled */ struct inet_peer *inet_getpeer(__be32 daddr, int create); +extern spinlock_t inet_peer_unused_lock; +extern struct inet_peer **inet_peer_unused_tailp; /* can be called from BH context or outside */ -extern void inet_putpeer(struct inet_peer *p); +static inline void inet_putpeer(struct inet_peer *p) +{ + spin_lock_bh(&inet_peer_unused_lock); + if (atomic_dec_and_test(&p->refcnt)) { + p->unused_prevp = inet_peer_unused_tailp; + p->unused_next = NULL; + *inet_peer_unused_tailp = p; + inet_peer_unused_tailp = &p->unused_next; + p->dtime = jiffies; + } + spin_unlock_bh(&inet_peer_unused_lock); +} extern spinlock_t inet_peer_idlock; /* can be called with or without local BH being disabled */ diff --git a/trunk/include/net/ip6_route.h b/trunk/include/net/ip6_route.h index c14b70ed4c57..6ca6b71dfe0f 100644 --- a/trunk/include/net/ip6_route.h +++ b/trunk/include/net/ip6_route.h @@ -36,6 +36,13 @@ struct route_info { #define RT6_LOOKUP_F_REACHABLE 0x2 #define RT6_LOOKUP_F_HAS_SADDR 0x4 +struct pol_chain { + int type; + int priority; + struct fib6_node *rules; + struct pol_chain *next; +}; + extern struct rt6_info ip6_null_entry; #ifdef CONFIG_IPV6_MULTIPLE_TABLES diff --git a/trunk/include/net/ip_fib.h b/trunk/include/net/ip_fib.h index 949b932d2f08..82229146bac7 100644 --- a/trunk/include/net/ip_fib.h +++ b/trunk/include/net/ip_fib.h @@ -21,14 +21,17 @@ #include struct fib_config { + u8 fc_family; u8 fc_dst_len; + u8 fc_src_len; u8 fc_tos; u8 fc_protocol; u8 fc_scope; u8 fc_type; - /* 3 bytes unused */ + /* 1 byte unused */ u32 fc_table; __be32 fc_dst; + __be32 fc_src; __be32 fc_gw; int fc_oif; u32 fc_flags; diff --git a/trunk/include/net/ip_vs.h b/trunk/include/net/ip_vs.h index 903108e583f8..49c717e3b040 100644 --- a/trunk/include/net/ip_vs.h +++ b/trunk/include/net/ip_vs.h @@ -7,7 +7,6 @@ #define _IP_VS_H #include /* For __uXX types */ -#include /* For __beXX types in userland */ #define IP_VS_VERSION_CODE 0x010201 #define NVERSION(version) \ diff --git a/trunk/include/net/ipx.h b/trunk/include/net/ipx.h index c6b2ee610866..5c0cf33826c5 100644 --- a/trunk/include/net/ipx.h +++ b/trunk/include/net/ipx.h @@ -15,9 +15,9 @@ #include struct ipx_address { - __be32 net; + __u32 net; __u8 node[IPX_NODE_LEN]; - __be16 sock; + __u16 sock; }; #define ipx_broadcast_node "\377\377\377\377\377\377" @@ -26,9 +26,9 @@ struct ipx_address { #define IPX_MAX_PPROP_HOPS 8 struct ipxhdr { - __be16 ipx_checksum __attribute__ ((packed)); -#define IPX_NO_CHECKSUM __constant_htons(0xFFFF) - __be16 ipx_pktsize __attribute__ ((packed)); + __u16 ipx_checksum __attribute__ ((packed)); +#define IPX_NO_CHECKSUM 0xFFFF + __u16 ipx_pktsize __attribute__ ((packed)); __u8 ipx_tctrl; __u8 ipx_type; #define IPX_TYPE_UNKNOWN 0x00 @@ -48,14 +48,14 @@ static __inline__ struct ipxhdr *ipx_hdr(struct sk_buff *skb) struct ipx_interface { /* IPX address */ - __be32 if_netnum; + __u32 if_netnum; unsigned char if_node[IPX_NODE_LEN]; atomic_t refcnt; /* physical device info */ struct net_device *if_dev; struct datalink_proto *if_dlink; - __be16 if_dlink_type; + unsigned short if_dlink_type; /* socket support */ unsigned short if_sknum; @@ -71,7 +71,7 @@ struct ipx_interface { }; struct ipx_route { - __be32 ir_net; + __u32 ir_net; struct ipx_interface *ir_intrfc; unsigned char ir_routed; unsigned char ir_router_node[IPX_NODE_LEN]; @@ -82,10 +82,10 @@ struct ipx_route { #ifdef __KERNEL__ struct ipx_cb { u8 ipx_tctrl; - __be32 ipx_dest_net; - __be32 ipx_source_net; + u32 ipx_dest_net; + u32 ipx_source_net; struct { - __be32 netnum; + u32 netnum; int index; } last_hop; }; @@ -97,7 +97,7 @@ struct ipx_sock { struct sock sk; struct ipx_address dest_addr; struct ipx_interface *intrfc; - __be16 port; + unsigned short port; #ifdef CONFIG_IPX_INTERN unsigned char node[IPX_NODE_LEN]; #endif @@ -132,7 +132,7 @@ extern struct ipx_interface *ipx_primary_net; extern int ipx_proc_init(void); extern void ipx_proc_exit(void); -extern const char *ipx_frame_name(__be16); +extern const char *ipx_frame_name(unsigned short); extern const char *ipx_device_name(struct ipx_interface *intrfc); static __inline__ void ipxitf_hold(struct ipx_interface *intrfc) diff --git a/trunk/include/net/netlabel.h b/trunk/include/net/netlabel.h index 12c214b9eadf..c63a58058e21 100644 --- a/trunk/include/net/netlabel.h +++ b/trunk/include/net/netlabel.h @@ -34,7 +34,6 @@ #include #include #include -#include /* * NetLabel - A management interface for maintaining network packet label @@ -107,7 +106,6 @@ int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info); /* LSM security attributes */ struct netlbl_lsm_cache { - atomic_t refcount; void (*free) (const void *data); void *data; }; @@ -119,7 +117,7 @@ struct netlbl_lsm_secattr { unsigned char *mls_cat; size_t mls_cat_len; - struct netlbl_lsm_cache *cache; + struct netlbl_lsm_cache cache; }; /* @@ -127,43 +125,6 @@ struct netlbl_lsm_secattr { */ -/** - * netlbl_secattr_cache_alloc - Allocate and initialize a secattr cache - * @flags: the memory allocation flags - * - * Description: - * Allocate and initialize a netlbl_lsm_cache structure. Returns a pointer - * on success, NULL on failure. - * - */ -static inline struct netlbl_lsm_cache *netlbl_secattr_cache_alloc(gfp_t flags) -{ - struct netlbl_lsm_cache *cache; - - cache = kzalloc(sizeof(*cache), flags); - if (cache) - atomic_set(&cache->refcount, 1); - return cache; -} - -/** - * netlbl_secattr_cache_free - Frees a netlbl_lsm_cache struct - * @cache: the struct to free - * - * Description: - * Frees @secattr including all of the internal buffers. - * - */ -static inline void netlbl_secattr_cache_free(struct netlbl_lsm_cache *cache) -{ - if (!atomic_dec_and_test(&cache->refcount)) - return; - - if (cache->free) - cache->free(cache->data); - kfree(cache); -} - /** * netlbl_secattr_init - Initialize a netlbl_lsm_secattr struct * @secattr: the struct to initialize @@ -182,16 +143,20 @@ static inline int netlbl_secattr_init(struct netlbl_lsm_secattr *secattr) /** * netlbl_secattr_destroy - Clears a netlbl_lsm_secattr struct * @secattr: the struct to clear + * @clear_cache: cache clear flag * * Description: * Destroys the @secattr struct, including freeing all of the internal buffers. - * The struct must be reset with a call to netlbl_secattr_init() before reuse. + * If @clear_cache is true then free the cache fields, otherwise leave them + * intact. The struct must be reset with a call to netlbl_secattr_init() + * before reuse. * */ -static inline void netlbl_secattr_destroy(struct netlbl_lsm_secattr *secattr) +static inline void netlbl_secattr_destroy(struct netlbl_lsm_secattr *secattr, + u32 clear_cache) { - if (secattr->cache) - netlbl_secattr_cache_free(secattr->cache); + if (clear_cache && secattr->cache.data != NULL && secattr->cache.free) + secattr->cache.free(secattr->cache.data); kfree(secattr->domain); kfree(secattr->mls_cat); } @@ -213,14 +178,17 @@ static inline struct netlbl_lsm_secattr *netlbl_secattr_alloc(int flags) /** * netlbl_secattr_free - Frees a netlbl_lsm_secattr struct * @secattr: the struct to free + * @clear_cache: cache clear flag * * Description: - * Frees @secattr including all of the internal buffers. + * Frees @secattr including all of the internal buffers. If @clear_cache is + * true then free the cache fields, otherwise leave them intact. * */ -static inline void netlbl_secattr_free(struct netlbl_lsm_secattr *secattr) +static inline void netlbl_secattr_free(struct netlbl_lsm_secattr *secattr, + u32 clear_cache) { - netlbl_secattr_destroy(secattr); + netlbl_secattr_destroy(secattr, clear_cache); kfree(secattr); } diff --git a/trunk/include/net/sctp/sctp.h b/trunk/include/net/sctp/sctp.h index 764e3af5be93..ee68a3124076 100644 --- a/trunk/include/net/sctp/sctp.h +++ b/trunk/include/net/sctp/sctp.h @@ -139,7 +139,6 @@ int sctp_inet_listen(struct socket *sock, int backlog); void sctp_write_space(struct sock *sk); unsigned int sctp_poll(struct file *file, struct socket *sock, poll_table *wait); -void sctp_sock_rfree(struct sk_buff *skb); /* * sctp/primitive.c @@ -445,19 +444,6 @@ static inline struct list_head *sctp_list_dequeue(struct list_head *list) return result; } -/* SCTP version of skb_set_owner_r. We need this one because - * of the way we have to do receive buffer accounting on bundled - * chunks. - */ -static inline void sctp_skb_set_owner_r(struct sk_buff *skb, struct sock *sk) -{ - struct sctp_ulpevent *event = sctp_skb2event(skb); - - skb->sk = sk; - skb->destructor = sctp_sock_rfree; - atomic_add(event->rmem_len, &sk->sk_rmem_alloc); -} - /* Tests if the list has one and only one entry. */ static inline int sctp_list_single_entry(struct list_head *head) { diff --git a/trunk/include/net/sctp/ulpevent.h b/trunk/include/net/sctp/ulpevent.h index 1a4ddc1ec7d2..6c40cfc4832d 100644 --- a/trunk/include/net/sctp/ulpevent.h +++ b/trunk/include/net/sctp/ulpevent.h @@ -63,7 +63,6 @@ struct sctp_ulpevent { __u32 cumtsn; int msg_flags; int iif; - unsigned int rmem_len; }; /* Retrieve the skb this event sits inside of. */ diff --git a/trunk/include/net/sock.h b/trunk/include/net/sock.h index 9cdbae2a53a3..40bb90ebb2d1 100644 --- a/trunk/include/net/sock.h +++ b/trunk/include/net/sock.h @@ -882,16 +882,6 @@ static inline int sk_filter(struct sock *sk, struct sk_buff *skb) return err; } -/** - * sk_filter_rcu_free: Free a socket filter - * @rcu: rcu_head that contains the sk_filter to free - */ -static inline void sk_filter_rcu_free(struct rcu_head *rcu) -{ - struct sk_filter *fp = container_of(rcu, struct sk_filter, rcu); - kfree(fp); -} - /** * sk_filter_release: Release a socket filter * @sk: socket @@ -899,6 +889,12 @@ static inline void sk_filter_rcu_free(struct rcu_head *rcu) * * Remove a filter from a socket and release its resources. */ + +static inline void sk_filter_rcu_free(struct rcu_head *rcu) +{ + struct sk_filter *fp = container_of(rcu, struct sk_filter, rcu); + kfree(fp); +} static inline void sk_filter_release(struct sock *sk, struct sk_filter *fp) { diff --git a/trunk/include/net/timewait_sock.h b/trunk/include/net/timewait_sock.h index be293d795e38..2544281e1d5e 100644 --- a/trunk/include/net/timewait_sock.h +++ b/trunk/include/net/timewait_sock.h @@ -19,7 +19,6 @@ struct timewait_sock_ops { unsigned int twsk_obj_size; int (*twsk_unique)(struct sock *sk, struct sock *sktw, void *twp); - void (*twsk_destructor)(struct sock *sk); }; static inline int twsk_unique(struct sock *sk, struct sock *sktw, void *twp) @@ -29,10 +28,4 @@ static inline int twsk_unique(struct sock *sk, struct sock *sktw, void *twp) return 0; } -static inline void twsk_destructor(struct sock *sk) -{ - if (sk->sk_prot->twsk_prot->twsk_destructor != NULL) - sk->sk_prot->twsk_prot->twsk_destructor(sk); -} - #endif /* _TIMEWAIT_SOCK_H */ diff --git a/trunk/include/net/xfrm.h b/trunk/include/net/xfrm.h index 737fdb2ee8a4..1e2a4ddec96e 100644 --- a/trunk/include/net/xfrm.h +++ b/trunk/include/net/xfrm.h @@ -995,8 +995,7 @@ struct xfrm_state * xfrm_find_acq(u8 mode, u32 reqid, u8 proto, int create, unsigned short family); extern void xfrm_policy_flush(u8 type); extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol); -extern int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *xdst, - struct flowi *fl, int family, int strict); +extern int xfrm_bundle_ok(struct xfrm_dst *xdst, struct flowi *fl, int family, int strict); extern void xfrm_init_pmtu(struct dst_entry *dst); extern wait_queue_head_t km_waitq; diff --git a/trunk/include/rdma/ib_addr.h b/trunk/include/rdma/ib_addr.h index c094e5012862..81b62307621d 100644 --- a/trunk/include/rdma/ib_addr.h +++ b/trunk/include/rdma/ib_addr.h @@ -36,22 +36,6 @@ #include #include -struct rdma_addr_client { - atomic_t refcount; - struct completion comp; -}; - -/** - * rdma_addr_register_client - Register an address client. - */ -void rdma_addr_register_client(struct rdma_addr_client *client); - -/** - * rdma_addr_unregister_client - Deregister an address client. - * @client: Client object to deregister. - */ -void rdma_addr_unregister_client(struct rdma_addr_client *client); - struct rdma_dev_addr { unsigned char src_dev_addr[MAX_ADDR_LEN]; unsigned char dst_dev_addr[MAX_ADDR_LEN]; @@ -68,7 +52,6 @@ int rdma_translate_ip(struct sockaddr *addr, struct rdma_dev_addr *dev_addr); /** * rdma_resolve_ip - Resolve source and destination IP addresses to * RDMA hardware addresses. - * @client: Address client associated with request. * @src_addr: An optional source address to use in the resolution. If a * source address is not provided, a usable address will be returned via * the callback. @@ -81,8 +64,7 @@ int rdma_translate_ip(struct sockaddr *addr, struct rdma_dev_addr *dev_addr); * or been canceled. A status of 0 indicates success. * @context: User-specified context associated with the call. */ -int rdma_resolve_ip(struct rdma_addr_client *client, - struct sockaddr *src_addr, struct sockaddr *dst_addr, +int rdma_resolve_ip(struct sockaddr *src_addr, struct sockaddr *dst_addr, struct rdma_dev_addr *addr, int timeout_ms, void (*callback)(int status, struct sockaddr *src_addr, struct rdma_dev_addr *addr, void *context), diff --git a/trunk/include/rdma/ib_cm.h b/trunk/include/rdma/ib_cm.h index 5c070176d9ab..c9b4738be9d6 100644 --- a/trunk/include/rdma/ib_cm.h +++ b/trunk/include/rdma/ib_cm.h @@ -60,7 +60,6 @@ enum ib_cm_state { }; enum ib_cm_lap_state { - IB_CM_LAP_UNINIT, IB_CM_LAP_IDLE, IB_CM_LAP_SENT, IB_CM_LAP_RCVD, @@ -444,20 +443,13 @@ int ib_send_cm_drep(struct ib_cm_id *cm_id, u8 private_data_len); /** - * ib_cm_notify - Notifies the CM of an event reported to the consumer. + * ib_cm_establish - Forces a connection state to established. * @cm_id: Connection identifier to transition to established. - * @event: Type of event. * - * This routine should be invoked by users to notify the CM of relevant - * communication events. Events that should be reported to the CM and - * when to report them are: - * - * IB_EVENT_COMM_EST - Used when a message is received on a connected - * QP before an RTU has been received. - * IB_EVENT_PATH_MIG - Notifies the CM that the connection has failed over - * to the alternate path. + * This routine should be invoked by users who receive messages on a + * connected QP before an RTU has been received. */ -int ib_cm_notify(struct ib_cm_id *cm_id, enum ib_event_type event); +int ib_cm_establish(struct ib_cm_id *cm_id); /** * ib_send_cm_rej - Sends a connection rejection message to the diff --git a/trunk/include/rdma/ib_user_cm.h b/trunk/include/rdma/ib_user_cm.h index 37650afb982c..066c20b7cdfb 100644 --- a/trunk/include/rdma/ib_user_cm.h +++ b/trunk/include/rdma/ib_user_cm.h @@ -38,7 +38,7 @@ #include -#define IB_USER_CM_ABI_VERSION 5 +#define IB_USER_CM_ABI_VERSION 4 enum { IB_USER_CM_CMD_CREATE_ID, @@ -46,7 +46,7 @@ enum { IB_USER_CM_CMD_ATTR_ID, IB_USER_CM_CMD_LISTEN, - IB_USER_CM_CMD_NOTIFY, + IB_USER_CM_CMD_ESTABLISH, IB_USER_CM_CMD_SEND_REQ, IB_USER_CM_CMD_SEND_REP, @@ -117,9 +117,8 @@ struct ib_ucm_listen { __u32 reserved; }; -struct ib_ucm_notify { +struct ib_ucm_establish { __u32 id; - __u32 event; }; struct ib_ucm_private_data { diff --git a/trunk/include/rdma/ib_user_verbs.h b/trunk/include/rdma/ib_user_verbs.h index 64a721fcbc1c..db1b814b62cc 100644 --- a/trunk/include/rdma/ib_user_verbs.h +++ b/trunk/include/rdma/ib_user_verbs.h @@ -458,7 +458,7 @@ struct ib_uverbs_query_qp_resp { __u8 cur_qp_state; __u8 path_mtu; __u8 path_mig_state; - __u8 sq_draining; + __u8 en_sqd_async_notify; __u8 max_rd_atomic; __u8 max_dest_rd_atomic; __u8 min_rnr_timer; diff --git a/trunk/include/scsi/libiscsi.h b/trunk/include/scsi/libiscsi.h index 61eebec00a7b..401192e56e50 100644 --- a/trunk/include/scsi/libiscsi.h +++ b/trunk/include/scsi/libiscsi.h @@ -136,6 +136,7 @@ struct iscsi_conn { /* control data */ int id; /* CID */ + struct list_head item; /* maintains list of conns */ int c_stage; /* connection state */ /* * Preallocated buffer for pdus that have data but do not @@ -234,8 +235,10 @@ struct iscsi_session { * - mgmtpool, * * - r2tpool */ int state; /* session state */ + struct list_head item; int age; /* counts session re-opens */ + struct list_head connections; /* list of connections */ int cmds_max; /* size of cmds array */ struct iscsi_cmd_task **cmds; /* Original Cmds arr */ struct iscsi_queue cmdpool; /* PDU's pool */ diff --git a/trunk/include/scsi/libsas.h b/trunk/include/scsi/libsas.h index 1d77b63c5ea4..9582e8401669 100644 --- a/trunk/include/scsi/libsas.h +++ b/trunk/include/scsi/libsas.h @@ -35,7 +35,6 @@ #include #include #include -#include struct block_device; diff --git a/trunk/include/scsi/scsi.h b/trunk/include/scsi/scsi.h index 5c0e9791441c..84a6d5fe0920 100644 --- a/trunk/include/scsi/scsi.h +++ b/trunk/include/scsi/scsi.h @@ -97,7 +97,6 @@ extern const unsigned char scsi_command_size[8]; #define PERSISTENT_RESERVE_IN 0x5e #define PERSISTENT_RESERVE_OUT 0x5f #define REPORT_LUNS 0xa0 -#define MAINTENANCE_IN 0xa3 #define MOVE_MEDIUM 0xa5 #define EXCHANGE_MEDIUM 0xa6 #define READ_12 0xa8 @@ -115,8 +114,6 @@ extern const unsigned char scsi_command_size[8]; #define SERVICE_ACTION_IN 0x9e /* values for service action in */ #define SAI_READ_CAPACITY_16 0x10 -/* values for maintenance in */ -#define MI_REPORT_TARGET_PGS 0x0a /* Values for T10/04-262r7 */ #define ATA_16 0x85 /* 16-byte pass-thru */ @@ -433,7 +430,7 @@ struct scsi_lun { #define SCSI_IOCTL_GET_PCI 0x5387 /* Pull a u32 out of a SCSI message (using BE SCSI conventions) */ -static inline __u32 scsi_to_u32(__u8 *ptr) +static inline u32 scsi_to_u32(u8 *ptr) { return (ptr[0]<<24) + (ptr[1]<<16) + (ptr[2]<<8) + ptr[3]; } diff --git a/trunk/include/scsi/scsi_transport_iscsi.h b/trunk/include/scsi/scsi_transport_iscsi.h index 4b95c89c95c9..39e833260bd0 100644 --- a/trunk/include/scsi/scsi_transport_iscsi.h +++ b/trunk/include/scsi/scsi_transport_iscsi.h @@ -29,6 +29,7 @@ struct scsi_transport_template; struct iscsi_transport; struct Scsi_Host; +struct mempool_zone; struct iscsi_cls_conn; struct iscsi_conn; struct iscsi_cmd_task; @@ -156,6 +157,9 @@ struct iscsi_cls_conn { int active; /* must be accessed with the connlock */ struct device dev; /* sysfs transport/container device */ + struct mempool_zone *z_error; + struct mempool_zone *z_pdu; + struct list_head freequeue; }; #define iscsi_dev_to_conn(_dev) \ diff --git a/trunk/include/scsi/sg.h b/trunk/include/scsi/sg.h index 519c49a0fc11..0a487fe26d4f 100644 --- a/trunk/include/scsi/sg.h +++ b/trunk/include/scsi/sg.h @@ -11,10 +11,26 @@ Original driver (sg.h): * Copyright (C) 1992 Lawrence Foard Version 2 and 3 extensions to driver: -* Copyright (C) 1998 - 2006 Douglas Gilbert - - Version: 3.5.34 (20060920) - This version is for 2.6 series kernels. +* Copyright (C) 1998 - 2003 Douglas Gilbert + + Version: 3.5.29 (20030529) + This version is for 2.5 series kernels. + + Changes since 3.5.28 (20030308) + - fix bug introduced in version 3.1.24 (last segment of sgat list) + Changes since 3.5.27 (20020812) + - remove procfs entries: hosts, host_hdr + host_strs (now in sysfs) + - add sysfs sg driver params: def_reserved_size, allow_dio, version + - new boot option: "sg_allow_dio" and module parameter: "allow_dio" + - multiple internal changes due to scsi subsystem rework + Changes since 3.5.26 (20020708) + - re-add direct IO using Kai Makisara's work + - re-tab to 8, start using C99-isms + - simplify memory management + Changes since 3.5.25 (20020504) + - driverfs additions + - copy_to/from_user() fixes [William Stinson] + - disable kiobufs support For a full changelog see http://www.torque.net/sg @@ -24,7 +40,7 @@ Map of SG verions to the Linux kernels in which they appear: 2.1.40 2.2.20 3.0.x optional version 3 sg driver for 2.2 series 3.1.17++ 2.4.0++ - 3.5.30++ 2.6.0++ + 3.5.23++ 2.5.0++ Major new features in SG 3.x driver (cf SG 2.x drivers) - SG_IO ioctl() combines function if write() and read() @@ -35,15 +51,14 @@ Major new features in SG 3.x driver (cf SG 2.x drivers) data into kernel buffers and then use the CPU to copy the data into the user space (vice versa for writes). That is called "indirect" IO due to the double handling of data. There are two methods offered to remove the - redundant copy: 1) direct IO and 2) using the mmap() system call to map - the reserve buffer (this driver has one reserve buffer per fd) into the - user space. Both have their advantages. + redundant copy: 1) direct IO which uses the kernel kiobuf mechanism and + 2) using the mmap() system call to map the reserve buffer (this driver has + one reserve buffer per fd) into the user space. Both have their advantages. In terms of absolute speed mmap() is faster. If speed is not a concern, indirect IO should be fine. Read the documentation for more information. - ** N.B. To use direct IO 'echo 1 > /proc/scsi/sg/allow_dio' or - 'echo 1 > /sys/module/sg/parameters/allow_dio' is needed. - That attribute is 0 by default. ** + ** N.B. To use direct IO 'echo 1 > /proc/scsi/sg/allow_dio' may be + needed. That pseudo file's content is defaulted to 0. ** Historical note: this SCSI pass-through driver has been known as "sg" for a decade. In broader kernel discussions "sg" is used to refer to scatter @@ -57,17 +72,20 @@ Major new features in SG 3.x driver (cf SG 2.x drivers) http://www.torque.net/sg/p/sg_v3_ho.html This is a rendering from DocBook source [change the extension to "sgml" or "xml"]. There are renderings in "ps", "pdf", "rtf" and "txt" (soon). - The SG_IO ioctl is now found in other parts kernel (e.g. the block layer). - For more information see http://www.torque.net/sg/sg_io.html The older, version 2 documents discuss the original sg interface in detail: http://www.torque.net/sg/p/scsi-generic.txt http://www.torque.net/sg/p/scsi-generic_long.txt - Also available: /Documentation/scsi/scsi-generic.txt + A version of this document (potentially out of date) may also be found in + the kernel source tree, probably at: + Documentation/scsi/scsi-generic.txt . Utility and test programs are available at the sg web site. They are - packaged as sg3_utils (for the lk 2.4 and 2.6 series) and sg_utils - (for the lk 2.2 series). + bundled as sg_utils (for the lk 2.2 series) and sg3_utils (for the + lk 2.4 series). + + There is a HOWTO on the Linux SCSI subsystem in the lk 2.4 series at: + http://www.linuxdoc.org/HOWTO/SCSI-2.4-HOWTO */ @@ -220,12 +238,13 @@ typedef struct sg_req_info { /* used by SG_GET_REQUEST_TABLE ioctl() */ #define SG_GET_ACCESS_COUNT 0x2289 -#define SG_SCATTER_SZ (8 * 4096) +#define SG_SCATTER_SZ (8 * 4096) /* PAGE_SIZE not available to user */ /* Largest size (in bytes) a single scatter-gather list element can have. - The value used by the driver is 'max(SG_SCATTER_SZ, PAGE_SIZE)'. - This value should be a power of 2 (and may be rounded up internally). - If scatter-gather is not supported by adapter then this value is the - largest data block that can be read/written by a single scsi command. */ + The value must be a power of 2 and <= (PAGE_SIZE * 32) [131072 bytes on + i386]. The minimum value is PAGE_SIZE. If scatter-gather not supported + by adapter then this value is the largest data block that can be + read/written by a single scsi command. The user can find the value of + PAGE_SIZE by calling getpagesize() defined in unistd.h . */ #define SG_DEFAULT_RETRIES 0 diff --git a/trunk/include/sound/core.h b/trunk/include/sound/core.h index a994bea09cd6..b056ea925ecf 100644 --- a/trunk/include/sound/core.h +++ b/trunk/include/sound/core.h @@ -89,10 +89,10 @@ struct snd_device { struct snd_monitor_file { struct file *file; struct snd_monitor_file *next; - const struct file_operations *disconnected_f_op; - struct list_head shutdown_list; }; +struct snd_shutdown_f_ops; /* define it later in init.c */ + /* main structure for soundcard */ struct snd_card { @@ -132,7 +132,6 @@ struct snd_card { int shutdown; /* this card is going down */ int free_on_last_close; /* free in context of file_release */ wait_queue_head_t shutdown_sleep; - struct device *parent; struct device *dev; #ifdef CONFIG_PM @@ -188,14 +187,13 @@ struct snd_minor { int device; /* device number */ const struct file_operations *f_ops; /* file operations */ void *private_data; /* private data for f_ops->open */ - struct device *dev; /* device for sysfs */ + struct class_device *class_dev; /* class device for sysfs */ }; /* sound.c */ extern int snd_major; extern int snd_ecards_limit; -extern struct class *sound_class; void snd_request_card(int card); @@ -205,7 +203,7 @@ int snd_register_device(int type, struct snd_card *card, int dev, int snd_unregister_device(int type, struct snd_card *card, int dev); void *snd_lookup_minor_data(unsigned int minor, int type); int snd_add_device_sysfs_file(int type, struct snd_card *card, int dev, - struct device_attribute *attr); + const struct class_device_attribute *attr); #ifdef CONFIG_SND_OSSEMUL int snd_register_oss_device(int type, struct snd_card *card, int dev, @@ -257,7 +255,7 @@ int snd_card_file_add(struct snd_card *card, struct file *file); int snd_card_file_remove(struct snd_card *card, struct file *file); #ifndef snd_card_set_dev -#define snd_card_set_dev(card,devptr) ((card)->parent = (devptr)) +#define snd_card_set_dev(card,devptr) ((card)->dev = (devptr)) #endif /* device.c */ diff --git a/trunk/include/sound/cs4231.h b/trunk/include/sound/cs4231.h index ab51ce1ba9a5..60b5b92a1319 100644 --- a/trunk/include/sound/cs4231.h +++ b/trunk/include/sound/cs4231.h @@ -273,7 +273,7 @@ unsigned char snd_cs4236_ext_in(struct snd_cs4231 *chip, unsigned char reg); void snd_cs4231_mce_up(struct snd_cs4231 *chip); void snd_cs4231_mce_down(struct snd_cs4231 *chip); -irqreturn_t snd_cs4231_interrupt(int irq, void *dev_id); +irqreturn_t snd_cs4231_interrupt(int irq, void *dev_id, struct pt_regs *regs); const char *snd_cs4231_chip_id(struct snd_cs4231 *chip); diff --git a/trunk/include/sound/emu10k1.h b/trunk/include/sound/emu10k1.h index 3d3c1514cf71..892e310c504d 100644 --- a/trunk/include/sound/emu10k1.h +++ b/trunk/include/sound/emu10k1.h @@ -1194,7 +1194,7 @@ int snd_emu10k1_mixer(struct snd_emu10k1 * emu, int pcm_device, int multi_device int snd_emu10k1_timer(struct snd_emu10k1 * emu, int device); int snd_emu10k1_fx8010_new(struct snd_emu10k1 *emu, int device, struct snd_hwdep ** rhwdep); -irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id); +irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id, struct pt_regs *regs); void snd_emu10k1_voice_init(struct snd_emu10k1 * emu, int voice); int snd_emu10k1_init_efx(struct snd_emu10k1 *emu); diff --git a/trunk/include/sound/gus.h b/trunk/include/sound/gus.h index c49ea57db8cc..68a664ab97f3 100644 --- a/trunk/include/sound/gus.h +++ b/trunk/include/sound/gus.h @@ -638,7 +638,7 @@ int snd_gus_initialize(struct snd_gus_card * gus); /* gus_irq.c */ -irqreturn_t snd_gus_interrupt(int irq, void *dev_id); +irqreturn_t snd_gus_interrupt(int irq, void *dev_id, struct pt_regs *regs); #ifdef CONFIG_SND_DEBUG void snd_gus_irq_profile_init(struct snd_gus_card *gus); #endif diff --git a/trunk/include/sound/initval.h b/trunk/include/sound/initval.h index e85b90750a59..2ae76efc696f 100644 --- a/trunk/include/sound/initval.h +++ b/trunk/include/sound/initval.h @@ -53,7 +53,7 @@ #ifdef SNDRV_LEGACY_FIND_FREE_IRQ #include -static irqreturn_t snd_legacy_empty_irq_handler(int irq, void *dev_id) +static irqreturn_t snd_legacy_empty_irq_handler(int irq, void *dev_id, struct pt_regs *regs) { return IRQ_HANDLED; } diff --git a/trunk/include/sound/mpu401.h b/trunk/include/sound/mpu401.h index 8c88267e9bea..ac504321ea56 100644 --- a/trunk/include/sound/mpu401.h +++ b/trunk/include/sound/mpu401.h @@ -106,8 +106,10 @@ struct snd_mpu401 { */ -irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id); -irqreturn_t snd_mpu401_uart_interrupt_tx(int irq, void *dev_id); +irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id, + struct pt_regs *regs); +irqreturn_t snd_mpu401_uart_interrupt_tx(int irq, void *dev_id, + struct pt_regs *regs); int snd_mpu401_uart_new(struct snd_card *card, int device, diff --git a/trunk/include/sound/sb.h b/trunk/include/sound/sb.h index 2dd5c8e5b4fe..431d06675e36 100644 --- a/trunk/include/sound/sb.h +++ b/trunk/include/sound/sb.h @@ -100,7 +100,7 @@ struct snd_sb { struct snd_rawmidi *rmidi; struct snd_rawmidi_substream *midi_substream_input; struct snd_rawmidi_substream *midi_substream_output; - irq_handler_t rmidi_callback; + irqreturn_t (*rmidi_callback)(int irq, void *dev_id, struct pt_regs *regs); spinlock_t reg_lock; spinlock_t open_lock; @@ -286,7 +286,7 @@ int snd_sbdsp_reset(struct snd_sb *chip); int snd_sbdsp_create(struct snd_card *card, unsigned long port, int irq, - irq_handler_t irq_handler, + irqreturn_t (*irq_handler)(int, void *, struct pt_regs *), int dma8, int dma16, unsigned short hardware, struct snd_sb **r_chip); @@ -316,7 +316,7 @@ int snd_sb16dsp_pcm(struct snd_sb *chip, int device, struct snd_pcm ** rpcm); const struct snd_pcm_ops *snd_sb16dsp_get_pcm_ops(int direction); int snd_sb16dsp_configure(struct snd_sb *chip); /* sb16.c */ -irqreturn_t snd_sb16dsp_interrupt(int irq, void *dev_id); +irqreturn_t snd_sb16dsp_interrupt(int irq, void *dev_id, struct pt_regs *regs); /* exported mixer stuffs */ enum { diff --git a/trunk/include/sound/version.h b/trunk/include/sound/version.h index 17137f3a3b6f..2ee849d0e198 100644 --- a/trunk/include/sound/version.h +++ b/trunk/include/sound/version.h @@ -1,3 +1,3 @@ -/* include/version.h. Generated by alsa/ksync script. */ -#define CONFIG_SND_VERSION "1.0.13" -#define CONFIG_SND_DATE " (Tue Nov 28 14:07:24 2006 UTC)" +/* include/version.h. Generated by configure. */ +#define CONFIG_SND_VERSION "1.0.12rc1" +#define CONFIG_SND_DATE " (Thu Jun 22 13:55:50 2006 UTC)" diff --git a/trunk/include/sound/vx_core.h b/trunk/include/sound/vx_core.h index 217394652090..dbca14170615 100644 --- a/trunk/include/sound/vx_core.h +++ b/trunk/include/sound/vx_core.h @@ -228,7 +228,7 @@ void snd_vx_free_firmware(struct vx_core *chip); /* * interrupt handler; exported for pcmcia */ -irqreturn_t snd_vx_irq_handler(int irq, void *dev); +irqreturn_t snd_vx_irq_handler(int irq, void *dev, struct pt_regs *regs); /* * lowlevel functions diff --git a/trunk/init/Kconfig b/trunk/init/Kconfig index 14d484606fab..10382931eead 100644 --- a/trunk/init/Kconfig +++ b/trunk/init/Kconfig @@ -1,6 +1,5 @@ config DEFCONFIG_LIST string - depends on !UML option defconfig_list default "/lib/modules/$UNAME_RELEASE/.config" default "/etc/kernel-config" @@ -249,26 +248,6 @@ config CPUSETS Say N if unsure. -config SYSFS_DEPRECATED - bool "Create deprecated sysfs files" - default y - help - This option creates deprecated symlinks such as the - "device"-link, the :-link, and the - "bus"-link. It may also add deprecated key in the - uevent environment. - None of these features or values should be used today, as - they export driver core implementation details to userspace - or export properties which can't be kept stable across kernel - releases. - - If enabled, this option will also move any device structures - that belong to a class, back into the /sys/class heirachy, in - order to support older versions of udev. - - If you are using a distro that was released in 2006 or later, - it should be safe to say N here. - config RELAY bool "Kernel->user space relay support (formerly relayfs)" help @@ -324,19 +303,20 @@ config UID16 config SYSCTL_SYSCALL bool "Sysctl syscall support" if EMBEDDED - default y + default n select SYSCTL ---help--- - sys_sysctl uses binary paths that have been found challenging - to properly maintain and use. The interface in /proc/sys - using paths with ascii names is now the primary path to this - information. + Enable the deprecated sysctl system call. sys_sysctl uses + binary paths that have been found to be a major pain to maintain + and use. The interface in /proc/sys is now the primary and what + everyone uses. - Almost nothing using the binary sysctl interface so if you are - trying to save some space it is probably safe to disable this, - making your kernel marginally smaller. + Nothing has been using the binary sysctl interface for some + time now so nothing should break if you disable sysctl syscall + support, and your kernel will get marginally smaller. - If unsure say Y here. + Unless you have an application that uses the sys_sysctl interface + you should probably say N here. config KALLSYMS bool "Load all symbols for debugging/kksymoops" if EMBEDDED diff --git a/trunk/init/main.c b/trunk/init/main.c index 36f608a7cfba..ee123243fb53 100644 --- a/trunk/init/main.c +++ b/trunk/init/main.c @@ -503,7 +503,6 @@ asmlinkage void __init start_kernel(void) printk(KERN_NOTICE); printk(linux_banner); setup_arch(&command_line); - unwind_setup(); setup_per_cpu_areas(); smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */ diff --git a/trunk/ipc/msg.c b/trunk/ipc/msg.c index 1266b1d0c8e3..5b213d952545 100644 --- a/trunk/ipc/msg.c +++ b/trunk/ipc/msg.c @@ -52,7 +52,7 @@ struct msg_receiver { long r_msgtype; long r_maxsize; - struct msg_msg *volatile r_msg; + volatile struct msg_msg *r_msg; }; /* one msg_sender for each sleeping sender */ @@ -124,7 +124,6 @@ void msg_exit_ns(struct ipc_namespace *ns) } mutex_unlock(&msg_ids(ns).mutex); - ipc_fini_ids(ns->ids[IPC_MSG_IDS]); kfree(ns->ids[IPC_MSG_IDS]); ns->ids[IPC_MSG_IDS] = NULL; } diff --git a/trunk/ipc/sem.c b/trunk/ipc/sem.c index 21b3289d640c..0dafcc455f92 100644 --- a/trunk/ipc/sem.c +++ b/trunk/ipc/sem.c @@ -161,7 +161,6 @@ void sem_exit_ns(struct ipc_namespace *ns) } mutex_unlock(&sem_ids(ns).mutex); - ipc_fini_ids(ns->ids[IPC_SEM_IDS]); kfree(ns->ids[IPC_SEM_IDS]); ns->ids[IPC_SEM_IDS] = NULL; } diff --git a/trunk/ipc/shm.c b/trunk/ipc/shm.c index d1198dd07a1a..bfbd317ec11c 100644 --- a/trunk/ipc/shm.c +++ b/trunk/ipc/shm.c @@ -116,7 +116,6 @@ void shm_exit_ns(struct ipc_namespace *ns) } mutex_unlock(&shm_ids(ns).mutex); - ipc_fini_ids(ns->ids[IPC_SHM_IDS]); kfree(ns->ids[IPC_SHM_IDS]); ns->ids[IPC_SHM_IDS] = NULL; } diff --git a/trunk/ipc/util.c b/trunk/ipc/util.c index cd8bb14a431f..42479e4eec59 100644 --- a/trunk/ipc/util.c +++ b/trunk/ipc/util.c @@ -301,7 +301,7 @@ static int grow_ary(struct ipc_ids* ids, int newsize) */ rcu_assign_pointer(ids->entries, new); - __ipc_fini_ids(ids, old); + ipc_rcu_putref(old); return newsize; } diff --git a/trunk/ipc/util.h b/trunk/ipc/util.h index e3aa2c5c97dc..c8fd6b9d77b5 100644 --- a/trunk/ipc/util.h +++ b/trunk/ipc/util.h @@ -83,18 +83,6 @@ void* ipc_rcu_alloc(int size); void ipc_rcu_getref(void *ptr); void ipc_rcu_putref(void *ptr); -static inline void __ipc_fini_ids(struct ipc_ids *ids, - struct ipc_id_ary *entries) -{ - if (entries != &ids->nullentry) - ipc_rcu_putref(entries); -} - -static inline void ipc_fini_ids(struct ipc_ids *ids) -{ - __ipc_fini_ids(ids, ids->entries); -} - struct kern_ipc_perm* ipc_get(struct ipc_ids* ids, int id); struct kern_ipc_perm* ipc_lock(struct ipc_ids* ids, int id); void ipc_lock_by_ptr(struct kern_ipc_perm *ipcp); diff --git a/trunk/kernel/audit.c b/trunk/kernel/audit.c index 98106f6078b0..f9889ee77825 100644 --- a/trunk/kernel/audit.c +++ b/trunk/kernel/audit.c @@ -340,7 +340,7 @@ static int kauditd_thread(void *dummy) { struct sk_buff *skb; - while (!kthread_should_stop()) { + while (1) { skb = skb_dequeue(&audit_skb_queue); wake_up(&audit_backlog_wait); if (skb) { @@ -369,7 +369,6 @@ static int kauditd_thread(void *dummy) remove_wait_queue(&kauditd_wait, &wait); } } - return 0; } int audit_send_list(void *_dest) diff --git a/trunk/kernel/compat.c b/trunk/kernel/compat.c index 6952dd057300..75573e5d27b0 100644 --- a/trunk/kernel/compat.c +++ b/trunk/kernel/compat.c @@ -678,7 +678,7 @@ int get_compat_sigevent(struct sigevent *event, ? -EFAULT : 0; } -long compat_get_bitmap(unsigned long *mask, const compat_ulong_t __user *umask, +long compat_get_bitmap(unsigned long *mask, compat_ulong_t __user *umask, unsigned long bitmap_size) { int i, j; @@ -982,37 +982,4 @@ asmlinkage long compat_sys_move_pages(pid_t pid, unsigned long nr_pages, } return sys_move_pages(pid, nr_pages, pages, nodes, status, flags); } - -asmlinkage long compat_sys_migrate_pages(compat_pid_t pid, - compat_ulong_t maxnode, - const compat_ulong_t __user *old_nodes, - const compat_ulong_t __user *new_nodes) -{ - unsigned long __user *old = NULL; - unsigned long __user *new = NULL; - nodemask_t tmp_mask; - unsigned long nr_bits; - unsigned long size; - - nr_bits = min_t(unsigned long, maxnode - 1, MAX_NUMNODES); - size = ALIGN(nr_bits, BITS_PER_LONG) / 8; - if (old_nodes) { - if (compat_get_bitmap(nodes_addr(tmp_mask), old_nodes, nr_bits)) - return -EFAULT; - old = compat_alloc_user_space(new_nodes ? size * 2 : size); - if (new_nodes) - new = old + size / sizeof(unsigned long); - if (copy_to_user(old, nodes_addr(tmp_mask), size)) - return -EFAULT; - } - if (new_nodes) { - if (compat_get_bitmap(nodes_addr(tmp_mask), new_nodes, nr_bits)) - return -EFAULT; - if (new == NULL) - new = compat_alloc_user_space(size); - if (copy_to_user(new, nodes_addr(tmp_mask), size)) - return -EFAULT; - } - return sys_migrate_pages(pid, nr_bits + 1, old, new); -} #endif diff --git a/trunk/kernel/cpu.c b/trunk/kernel/cpu.c index 272254f20d97..32c96628463e 100644 --- a/trunk/kernel/cpu.c +++ b/trunk/kernel/cpu.c @@ -19,7 +19,7 @@ static DEFINE_MUTEX(cpu_add_remove_lock); static DEFINE_MUTEX(cpu_bitmask_lock); -static __cpuinitdata RAW_NOTIFIER_HEAD(cpu_chain); +static __cpuinitdata BLOCKING_NOTIFIER_HEAD(cpu_chain); /* If set, cpu_up and cpu_down will return -EBUSY and do nothing. * Should always be manipulated under cpu_add_remove_lock @@ -58,8 +58,8 @@ void unlock_cpu_hotplug(void) recursive_depth--; return; } - recursive = NULL; mutex_unlock(&cpu_bitmask_lock); + recursive = NULL; } EXPORT_SYMBOL_GPL(unlock_cpu_hotplug); @@ -68,11 +68,7 @@ EXPORT_SYMBOL_GPL(unlock_cpu_hotplug); /* Need to know about CPUs going up/down? */ int __cpuinit register_cpu_notifier(struct notifier_block *nb) { - int ret; - mutex_lock(&cpu_add_remove_lock); - ret = raw_notifier_chain_register(&cpu_chain, nb); - mutex_unlock(&cpu_add_remove_lock); - return ret; + return blocking_notifier_chain_register(&cpu_chain, nb); } #ifdef CONFIG_HOTPLUG_CPU @@ -81,9 +77,7 @@ EXPORT_SYMBOL(register_cpu_notifier); void unregister_cpu_notifier(struct notifier_block *nb) { - mutex_lock(&cpu_add_remove_lock); - raw_notifier_chain_unregister(&cpu_chain, nb); - mutex_unlock(&cpu_add_remove_lock); + blocking_notifier_chain_unregister(&cpu_chain, nb); } EXPORT_SYMBOL(unregister_cpu_notifier); @@ -132,7 +126,7 @@ static int _cpu_down(unsigned int cpu) if (!cpu_online(cpu)) return -EINVAL; - err = raw_notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE, + err = blocking_notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE, (void *)(long)cpu); if (err == NOTIFY_BAD) { printk("%s: attempt to take down CPU %u failed\n", @@ -150,19 +144,19 @@ static int _cpu_down(unsigned int cpu) p = __stop_machine_run(take_cpu_down, NULL, cpu); mutex_unlock(&cpu_bitmask_lock); - if (IS_ERR(p) || cpu_online(cpu)) { + if (IS_ERR(p)) { /* CPU didn't die: tell everyone. Can't complain. */ - if (raw_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED, + if (blocking_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED, (void *)(long)cpu) == NOTIFY_BAD) BUG(); - if (IS_ERR(p)) { - err = PTR_ERR(p); - goto out_allowed; - } - goto out_thread; + err = PTR_ERR(p); + goto out_allowed; } + if (cpu_online(cpu)) + goto out_thread; + /* Wait for it to sleep (leaving idle task). */ while (!idle_cpu(cpu)) yield(); @@ -175,7 +169,7 @@ static int _cpu_down(unsigned int cpu) put_cpu(); /* CPU is completely dead: tell everyone. Too late to complain. */ - if (raw_notifier_call_chain(&cpu_chain, CPU_DEAD, + if (blocking_notifier_call_chain(&cpu_chain, CPU_DEAD, (void *)(long)cpu) == NOTIFY_BAD) BUG(); @@ -212,7 +206,7 @@ static int __devinit _cpu_up(unsigned int cpu) if (cpu_online(cpu) || !cpu_present(cpu)) return -EINVAL; - ret = raw_notifier_call_chain(&cpu_chain, CPU_UP_PREPARE, hcpu); + ret = blocking_notifier_call_chain(&cpu_chain, CPU_UP_PREPARE, hcpu); if (ret == NOTIFY_BAD) { printk("%s: attempt to bring up CPU %u failed\n", __FUNCTION__, cpu); @@ -229,11 +223,11 @@ static int __devinit _cpu_up(unsigned int cpu) BUG_ON(!cpu_online(cpu)); /* Now call notifier in preparation. */ - raw_notifier_call_chain(&cpu_chain, CPU_ONLINE, hcpu); + blocking_notifier_call_chain(&cpu_chain, CPU_ONLINE, hcpu); out_notify: if (ret != 0) - raw_notifier_call_chain(&cpu_chain, + blocking_notifier_call_chain(&cpu_chain, CPU_UP_CANCELED, hcpu); return ret; diff --git a/trunk/kernel/cpuset.c b/trunk/kernel/cpuset.c index 6313c38c930e..9d850ae13b1b 100644 --- a/trunk/kernel/cpuset.c +++ b/trunk/kernel/cpuset.c @@ -2137,7 +2137,7 @@ static int cpuset_handle_cpuhp(struct notifier_block *nb, * See also the previous routine cpuset_handle_cpuhp(). */ -void cpuset_track_online_nodes(void) +void cpuset_track_online_nodes() { common_cpu_mem_hotplug_unplug(); } diff --git a/trunk/kernel/delayacct.c b/trunk/kernel/delayacct.c index 66a0ea48751d..36752f124c6a 100644 --- a/trunk/kernel/delayacct.c +++ b/trunk/kernel/delayacct.c @@ -66,7 +66,6 @@ static void delayacct_end(struct timespec *start, struct timespec *end, { struct timespec ts; s64 ns; - unsigned long flags; do_posix_clock_monotonic_gettime(end); ts = timespec_sub(*end, *start); @@ -74,10 +73,10 @@ static void delayacct_end(struct timespec *start, struct timespec *end, if (ns < 0) return; - spin_lock_irqsave(¤t->delays->lock, flags); + spin_lock(¤t->delays->lock); *total += ns; (*count)++; - spin_unlock_irqrestore(¤t->delays->lock, flags); + spin_unlock(¤t->delays->lock); } void __delayacct_blkio_start(void) @@ -105,7 +104,6 @@ int __delayacct_add_tsk(struct taskstats *d, struct task_struct *tsk) s64 tmp; struct timespec ts; unsigned long t1,t2,t3; - unsigned long flags; /* Though tsk->delays accessed later, early exit avoids * unnecessary returning of other data @@ -138,14 +136,14 @@ int __delayacct_add_tsk(struct taskstats *d, struct task_struct *tsk) /* zero XXX_total, non-zero XXX_count implies XXX stat overflowed */ - spin_lock_irqsave(&tsk->delays->lock, flags); + spin_lock(&tsk->delays->lock); tmp = d->blkio_delay_total + tsk->delays->blkio_delay; d->blkio_delay_total = (tmp < d->blkio_delay_total) ? 0 : tmp; tmp = d->swapin_delay_total + tsk->delays->swapin_delay; d->swapin_delay_total = (tmp < d->swapin_delay_total) ? 0 : tmp; d->blkio_count += tsk->delays->blkio_count; d->swapin_count += tsk->delays->swapin_count; - spin_unlock_irqrestore(&tsk->delays->lock, flags); + spin_unlock(&tsk->delays->lock); done: return 0; @@ -154,12 +152,11 @@ int __delayacct_add_tsk(struct taskstats *d, struct task_struct *tsk) __u64 __delayacct_blkio_ticks(struct task_struct *tsk) { __u64 ret; - unsigned long flags; - spin_lock_irqsave(&tsk->delays->lock, flags); + spin_lock(&tsk->delays->lock); ret = nsec_to_clock_t(tsk->delays->blkio_delay + tsk->delays->swapin_delay); - spin_unlock_irqrestore(&tsk->delays->lock, flags); + spin_unlock(&tsk->delays->lock); return ret; } diff --git a/trunk/kernel/exit.c b/trunk/kernel/exit.c index 06de6c4e8ca3..f250a5e3e281 100644 --- a/trunk/kernel/exit.c +++ b/trunk/kernel/exit.c @@ -128,7 +128,6 @@ static void __exit_signal(struct task_struct *tsk) flush_sigqueue(&tsk->pending); if (sig) { flush_sigqueue(&sig->shared_pending); - taskstats_tgid_free(sig); __cleanup_signal(sig); } } diff --git a/trunk/kernel/fork.c b/trunk/kernel/fork.c index 8cdd3e72ba55..7dc6140baac6 100644 --- a/trunk/kernel/fork.c +++ b/trunk/kernel/fork.c @@ -830,7 +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); + taskstats_tgid_alloc(current->signal); return 0; } sig = kmem_cache_alloc(signal_cachep, GFP_KERNEL); @@ -897,6 +897,7 @@ static inline int copy_signal(unsigned long clone_flags, struct task_struct * ts void __cleanup_signal(struct signal_struct *sig) { exit_thread_group_keys(sig); + taskstats_tgid_free(sig); kmem_cache_free(signal_cachep, sig); } @@ -983,8 +984,6 @@ static struct task_struct *copy_process(unsigned long clone_flags, if (!p) goto fork_out; - rt_mutex_init_task(p); - #ifdef CONFIG_TRACE_IRQFLAGS DEBUG_LOCKS_WARN_ON(!p->hardirqs_enabled); DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled); @@ -1089,6 +1088,8 @@ static struct task_struct *copy_process(unsigned long clone_flags, p->lockdep_recursion = 0; #endif + rt_mutex_init_task(p); + #ifdef CONFIG_DEBUG_MUTEXES p->blocked_on = NULL; /* not blocked yet */ #endif @@ -1315,8 +1316,9 @@ struct task_struct * __devinit fork_idle(int cpu) struct pt_regs regs; task = copy_process(CLONE_VM, 0, idle_regs(®s), 0, NULL, NULL, 0); - if (!IS_ERR(task)) - init_idle(task, cpu); + if (!task) + return ERR_PTR(-ENOMEM); + init_idle(task, cpu); return task; } diff --git a/trunk/kernel/futex.c b/trunk/kernel/futex.c index 93ef30ba209f..4aaf91951a43 100644 --- a/trunk/kernel/futex.c +++ b/trunk/kernel/futex.c @@ -1507,13 +1507,6 @@ static int futex_fd(u32 __user *uaddr, int signal) struct futex_q *q; struct file *filp; int ret, err; - static unsigned long printk_interval; - - if (printk_timed_ratelimit(&printk_interval, 60 * 60 * 1000)) { - printk(KERN_WARNING "Process `%s' used FUTEX_FD, which " - "will be removed from the kernel in June 2007\n", - current->comm); - } ret = -EINVAL; if (!valid_signal(signal)) @@ -1619,10 +1612,10 @@ sys_set_robust_list(struct robust_list_head __user *head, * @len_ptr: pointer to a length field, the kernel fills in the header size */ asmlinkage long -sys_get_robust_list(int pid, struct robust_list_head __user * __user *head_ptr, +sys_get_robust_list(int pid, struct robust_list_head __user **head_ptr, size_t __user *len_ptr) { - struct robust_list_head __user *head; + struct robust_list_head *head; unsigned long ret; if (!pid) @@ -1701,15 +1694,14 @@ int handle_futex_death(u32 __user *uaddr, struct task_struct *curr, int pi) * Fetch a robust-list pointer. Bit 0 signals PI futexes: */ static inline int fetch_robust_entry(struct robust_list __user **entry, - struct robust_list __user * __user *head, - int *pi) + struct robust_list __user **head, int *pi) { unsigned long uentry; - if (get_user(uentry, (unsigned long __user *)head)) + if (get_user(uentry, (unsigned long *)head)) return -EFAULT; - *entry = (void __user *)(uentry & ~1UL); + *entry = (void *)(uentry & ~1UL); *pi = uentry & 1; return 0; @@ -1747,7 +1739,7 @@ void exit_robust_list(struct task_struct *curr) return; if (pending) - handle_futex_death((void __user *)pending + futex_offset, curr, pip); + handle_futex_death((void *)pending + futex_offset, curr, pip); while (entry != &head->list) { /* @@ -1755,7 +1747,7 @@ void exit_robust_list(struct task_struct *curr) * don't process it twice: */ if (entry != pending) - if (handle_futex_death((void __user *)entry + futex_offset, + if (handle_futex_death((void *)entry + futex_offset, curr, pi)) return; /* diff --git a/trunk/kernel/futex_compat.c b/trunk/kernel/futex_compat.c index 50f24eea6cd0..c5cca3f65cb7 100644 --- a/trunk/kernel/futex_compat.c +++ b/trunk/kernel/futex_compat.c @@ -18,7 +18,7 @@ */ static inline int fetch_robust_entry(compat_uptr_t *uentry, struct robust_list __user **entry, - compat_uptr_t __user *head, int *pi) + compat_uptr_t *head, int *pi) { if (get_user(*uentry, head)) return -EFAULT; @@ -62,7 +62,7 @@ void compat_exit_robust_list(struct task_struct *curr) &head->list_op_pending, &pip)) return; if (upending) - handle_futex_death((void __user *)pending + futex_offset, curr, pip); + handle_futex_death((void *)pending + futex_offset, curr, pip); while (compat_ptr(uentry) != &head->list) { /* @@ -70,7 +70,7 @@ void compat_exit_robust_list(struct task_struct *curr) * dont process it twice: */ if (entry != pending) - if (handle_futex_death((void __user *)entry + futex_offset, + if (handle_futex_death((void *)entry + futex_offset, curr, pi)) return; @@ -78,7 +78,7 @@ void compat_exit_robust_list(struct task_struct *curr) * Fetch the next entry in the list: */ if (fetch_robust_entry(&uentry, &entry, - (compat_uptr_t __user *)&entry->next, &pi)) + (compat_uptr_t *)&entry->next, &pi)) return; /* * Avoid excessively long or circular lists: @@ -103,10 +103,10 @@ compat_sys_set_robust_list(struct compat_robust_list_head __user *head, } asmlinkage long -compat_sys_get_robust_list(int pid, compat_uptr_t __user *head_ptr, +compat_sys_get_robust_list(int pid, compat_uptr_t *head_ptr, compat_size_t __user *len_ptr) { - struct compat_robust_list_head __user *head; + struct compat_robust_list_head *head; unsigned long ret; if (!pid) diff --git a/trunk/kernel/irq/chip.c b/trunk/kernel/irq/chip.c index ebfd24a41858..4cf65f5c6a74 100644 --- a/trunk/kernel/irq/chip.c +++ b/trunk/kernel/irq/chip.c @@ -233,8 +233,6 @@ void irq_chip_set_defaults(struct irq_chip *chip) chip->shutdown = chip->disable; if (!chip->name) chip->name = chip->typename; - if (!chip->end) - chip->end = dummy_irq_chip.end; } static inline void mask_ack_irq(struct irq_desc *desc, int irq) @@ -251,6 +249,7 @@ static inline void mask_ack_irq(struct irq_desc *desc, int irq) * handle_simple_irq - Simple and software-decoded IRQs. * @irq: the interrupt number * @desc: the interrupt description structure for this irq + * @regs: pointer to a register structure * * Simple interrupts are either sent from a demultiplexing interrupt * handler or come from hardware, where no interrupt hardware control @@ -260,7 +259,7 @@ static inline void mask_ack_irq(struct irq_desc *desc, int irq) * unmask issues if necessary. */ void fastcall -handle_simple_irq(unsigned int irq, struct irq_desc *desc) +handle_simple_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs) { struct irqaction *action; irqreturn_t action_ret; @@ -280,9 +279,9 @@ handle_simple_irq(unsigned int irq, struct irq_desc *desc) desc->status |= IRQ_INPROGRESS; spin_unlock(&desc->lock); - action_ret = handle_IRQ_event(irq, action); + action_ret = handle_IRQ_event(irq, regs, action); if (!noirqdebug) - note_interrupt(irq, desc, action_ret); + note_interrupt(irq, desc, action_ret, regs); spin_lock(&desc->lock); desc->status &= ~IRQ_INPROGRESS; @@ -294,6 +293,7 @@ handle_simple_irq(unsigned int irq, struct irq_desc *desc) * handle_level_irq - Level type irq handler * @irq: the interrupt number * @desc: the interrupt description structure for this irq + * @regs: pointer to a register structure * * Level type interrupts are active as long as the hardware line has * the active level. This may require to mask the interrupt and unmask @@ -301,7 +301,7 @@ handle_simple_irq(unsigned int irq, struct irq_desc *desc) * interrupt line is back to inactive. */ void fastcall -handle_level_irq(unsigned int irq, struct irq_desc *desc) +handle_level_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs) { unsigned int cpu = smp_processor_id(); struct irqaction *action; @@ -329,9 +329,9 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc) desc->status &= ~IRQ_PENDING; spin_unlock(&desc->lock); - action_ret = handle_IRQ_event(irq, action); + action_ret = handle_IRQ_event(irq, regs, action); if (!noirqdebug) - note_interrupt(irq, desc, action_ret); + note_interrupt(irq, desc, action_ret, regs); spin_lock(&desc->lock); desc->status &= ~IRQ_INPROGRESS; @@ -345,6 +345,7 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc) * handle_fasteoi_irq - irq handler for transparent controllers * @irq: the interrupt number * @desc: the interrupt description structure for this irq + * @regs: pointer to a register structure * * Only a single callback will be issued to the chip: an ->eoi() * call when the interrupt has been serviced. This enables support @@ -352,7 +353,8 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc) * details in hardware, transparently. */ void fastcall -handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc) +handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc, + struct pt_regs *regs) { unsigned int cpu = smp_processor_id(); struct irqaction *action; @@ -380,9 +382,9 @@ handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc) desc->status &= ~IRQ_PENDING; spin_unlock(&desc->lock); - action_ret = handle_IRQ_event(irq, action); + action_ret = handle_IRQ_event(irq, regs, action); if (!noirqdebug) - note_interrupt(irq, desc, action_ret); + note_interrupt(irq, desc, action_ret, regs); spin_lock(&desc->lock); desc->status &= ~IRQ_INPROGRESS; @@ -396,6 +398,7 @@ handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc) * handle_edge_irq - edge type IRQ handler * @irq: the interrupt number * @desc: the interrupt description structure for this irq + * @regs: pointer to a register structure * * Interrupt occures on the falling and/or rising edge of a hardware * signal. The occurence is latched into the irq controller hardware @@ -409,7 +412,7 @@ handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc) * loop is left. */ void fastcall -handle_edge_irq(unsigned int irq, struct irq_desc *desc) +handle_edge_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs) { const unsigned int cpu = smp_processor_id(); @@ -460,9 +463,9 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc) desc->status &= ~IRQ_PENDING; spin_unlock(&desc->lock); - action_ret = handle_IRQ_event(irq, action); + action_ret = handle_IRQ_event(irq, regs, action); if (!noirqdebug) - note_interrupt(irq, desc, action_ret); + note_interrupt(irq, desc, action_ret, regs); spin_lock(&desc->lock); } while ((desc->status & (IRQ_PENDING | IRQ_DISABLED)) == IRQ_PENDING); @@ -477,11 +480,12 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc) * handle_percpu_IRQ - Per CPU local irq handler * @irq: the interrupt number * @desc: the interrupt description structure for this irq + * @regs: pointer to a register structure * * Per CPU interrupts on SMP machines without locking requirements */ void fastcall -handle_percpu_irq(unsigned int irq, struct irq_desc *desc) +handle_percpu_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs) { irqreturn_t action_ret; @@ -490,9 +494,9 @@ handle_percpu_irq(unsigned int irq, struct irq_desc *desc) if (desc->chip->ack) desc->chip->ack(irq); - action_ret = handle_IRQ_event(irq, desc->action); + action_ret = handle_IRQ_event(irq, regs, desc->action); if (!noirqdebug) - note_interrupt(irq, desc, action_ret); + note_interrupt(irq, desc, action_ret, regs); if (desc->chip->eoi) desc->chip->eoi(irq); @@ -501,8 +505,10 @@ handle_percpu_irq(unsigned int irq, struct irq_desc *desc) #endif /* CONFIG_SMP */ void -__set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained, - const char *name) +__set_irq_handler(unsigned int irq, + void fastcall (*handle)(unsigned int, irq_desc_t *, + struct pt_regs *), + int is_chained) { struct irq_desc *desc; unsigned long flags; @@ -543,7 +549,6 @@ __set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained, desc->depth = 1; } desc->handle_irq = handle; - desc->name = name; if (handle != handle_bad_irq && is_chained) { desc->status &= ~IRQ_DISABLED; @@ -556,16 +561,36 @@ __set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained, void set_irq_chip_and_handler(unsigned int irq, struct irq_chip *chip, - irq_flow_handler_t handle) + void fastcall (*handle)(unsigned int, + struct irq_desc *, + struct pt_regs *)) { set_irq_chip(irq, chip); - __set_irq_handler(irq, handle, 0, NULL); + __set_irq_handler(irq, handle, 0); } -void -set_irq_chip_and_handler_name(unsigned int irq, struct irq_chip *chip, - irq_flow_handler_t handle, const char *name) +/* + * Get a descriptive string for the highlevel handler, for + * /proc/interrupts output: + */ +const char * +handle_irq_name(void fastcall (*handle)(unsigned int, struct irq_desc *, + struct pt_regs *)) { - set_irq_chip(irq, chip); - __set_irq_handler(irq, handle, 0, name); + if (handle == handle_level_irq) + return "level "; + if (handle == handle_fasteoi_irq) + return "fasteoi"; + if (handle == handle_edge_irq) + return "edge "; + if (handle == handle_simple_irq) + return "simple "; +#ifdef CONFIG_SMP + if (handle == handle_percpu_irq) + return "percpu "; +#endif + if (handle == handle_bad_irq) + return "bad "; + + return NULL; } diff --git a/trunk/kernel/irq/handle.c b/trunk/kernel/irq/handle.c index a681912bc89a..4c6cdbaed661 100644 --- a/trunk/kernel/irq/handle.c +++ b/trunk/kernel/irq/handle.c @@ -27,7 +27,7 @@ * Handles spurious and unhandled IRQ's. It also prints a debugmessage. */ void fastcall -handle_bad_irq(unsigned int irq, struct irq_desc *desc) +handle_bad_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs) { print_irq_desc(irq, desc); kstat_this_cpu.irqs[irq]++; @@ -115,7 +115,7 @@ struct irq_chip dummy_irq_chip = { /* * Special, empty irq handler: */ -irqreturn_t no_action(int cpl, void *dev_id) +irqreturn_t no_action(int cpl, void *dev_id, struct pt_regs *regs) { return IRQ_NONE; } @@ -123,11 +123,13 @@ irqreturn_t no_action(int cpl, void *dev_id) /** * handle_IRQ_event - irq action chain handler * @irq: the interrupt number + * @regs: pointer to a register structure * @action: the interrupt action chain for this irq * * Handles the action chain of an irq event */ -irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action) +irqreturn_t handle_IRQ_event(unsigned int irq, struct pt_regs *regs, + struct irqaction *action) { irqreturn_t ret, retval = IRQ_NONE; unsigned int status = 0; @@ -138,7 +140,7 @@ irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action) local_irq_enable_in_hardirq(); do { - ret = action->handler(irq, action->dev_id); + ret = action->handler(irq, action->dev_id, regs); if (ret == IRQ_HANDLED) status |= action->flags; retval |= ret; @@ -156,6 +158,7 @@ irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action) /** * __do_IRQ - original all in one highlevel IRQ handler * @irq: the interrupt number + * @regs: pointer to a register structure * * __do_IRQ handles all normal device IRQ's (the special * SMP cross-CPU interrupts have their own specific @@ -164,7 +167,7 @@ irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action) * This is the original x86 implementation which is used for every * interrupt type. */ -fastcall unsigned int __do_IRQ(unsigned int irq) +fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs) { struct irq_desc *desc = irq_desc + irq; struct irqaction *action; @@ -179,7 +182,7 @@ fastcall unsigned int __do_IRQ(unsigned int irq) */ if (desc->chip->ack) desc->chip->ack(irq); - action_ret = handle_IRQ_event(irq, desc->action); + action_ret = handle_IRQ_event(irq, regs, desc->action); desc->chip->end(irq); return 1; } @@ -230,11 +233,11 @@ fastcall unsigned int __do_IRQ(unsigned int irq) spin_unlock(&desc->lock); - action_ret = handle_IRQ_event(irq, action); - if (!noirqdebug) - note_interrupt(irq, desc, action_ret); + action_ret = handle_IRQ_event(irq, regs, action); spin_lock(&desc->lock); + if (!noirqdebug) + note_interrupt(irq, desc, action_ret, regs); if (likely(!(desc->status & IRQ_PENDING))) break; desc->status &= ~IRQ_PENDING; diff --git a/trunk/kernel/irq/manage.c b/trunk/kernel/irq/manage.c index b385878c6e80..92be519eff26 100644 --- a/trunk/kernel/irq/manage.c +++ b/trunk/kernel/irq/manage.c @@ -216,7 +216,6 @@ int setup_irq(unsigned int irq, struct irqaction *new) { struct irq_desc *desc = irq_desc + irq; struct irqaction *old, **p; - const char *old_name = NULL; unsigned long flags; int shared = 0; @@ -256,10 +255,8 @@ int setup_irq(unsigned int irq, struct irqaction *new) * set the trigger type must match. */ if (!((old->flags & new->flags) & IRQF_SHARED) || - ((old->flags ^ new->flags) & IRQF_TRIGGER_MASK)) { - old_name = old->name; + ((old->flags ^ new->flags) & IRQF_TRIGGER_MASK)) goto mismatch; - } #if defined(CONFIG_IRQ_PER_CPU) /* All handlers must agree on per-cpuness */ @@ -325,13 +322,11 @@ int setup_irq(unsigned int irq, struct irqaction *new) return 0; mismatch: + spin_unlock_irqrestore(&desc->lock, flags); if (!(new->flags & IRQF_PROBE_SHARED)) { printk(KERN_ERR "IRQ handler type mismatch for IRQ %d\n", irq); - if (old_name) - printk(KERN_ERR "current handler: %s\n", old_name); dump_stack(); } - spin_unlock_irqrestore(&desc->lock, flags); return -EBUSY; } @@ -432,7 +427,8 @@ EXPORT_SYMBOL(free_irq); * IRQF_SAMPLE_RANDOM The interrupt can be used for entropy * */ -int request_irq(unsigned int irq, irq_handler_t handler, +int request_irq(unsigned int irq, + irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long irqflags, const char *devname, void *dev_id) { struct irqaction *action; @@ -479,3 +475,4 @@ int request_irq(unsigned int irq, irq_handler_t handler, return retval; } EXPORT_SYMBOL(request_irq); + diff --git a/trunk/kernel/irq/proc.c b/trunk/kernel/irq/proc.c index 9a352667007c..607c7809ad01 100644 --- a/trunk/kernel/irq/proc.c +++ b/trunk/kernel/irq/proc.c @@ -57,7 +57,7 @@ static int irq_affinity_write_proc(struct file *file, const char __user *buffer, if (!irq_desc[irq].chip->set_affinity || no_irq_affinity) return -EIO; - err = cpumask_parse_user(buffer, count, new_value); + err = cpumask_parse(buffer, count, new_value); if (err) return err; diff --git a/trunk/kernel/irq/resend.c b/trunk/kernel/irq/resend.c index 5bfeaed7e487..35f10f7ff94a 100644 --- a/trunk/kernel/irq/resend.c +++ b/trunk/kernel/irq/resend.c @@ -38,7 +38,7 @@ static void resend_irqs(unsigned long arg) clear_bit(irq, irqs_resend); desc = irq_desc + irq; local_irq_disable(); - desc->handle_irq(irq, desc); + desc->handle_irq(irq, desc, NULL); local_irq_enable(); } } diff --git a/trunk/kernel/irq/spurious.c b/trunk/kernel/irq/spurious.c index 543ea2e5ad93..417e98092cf2 100644 --- a/trunk/kernel/irq/spurious.c +++ b/trunk/kernel/irq/spurious.c @@ -16,7 +16,7 @@ static int irqfixup __read_mostly; /* * Recovery handler for misrouted interrupts. */ -static int misrouted_irq(int irq) +static int misrouted_irq(int irq, struct pt_regs *regs) { int i; int ok = 0; @@ -49,7 +49,7 @@ static int misrouted_irq(int irq) while (action) { /* Only shared IRQ handlers are safe to call */ if (action->flags & IRQF_SHARED) { - if (action->handler(i, action->dev_id) == + if (action->handler(i, action->dev_id, regs) == IRQ_HANDLED) ok = 1; } @@ -70,7 +70,7 @@ static int misrouted_irq(int irq) */ work = 1; spin_unlock(&desc->lock); - handle_IRQ_event(i, action); + handle_IRQ_event(i, regs, action); spin_lock(&desc->lock); desc->status &= ~IRQ_PENDING; } @@ -136,7 +136,7 @@ report_bad_irq(unsigned int irq, struct irq_desc *desc, irqreturn_t action_ret) } void note_interrupt(unsigned int irq, struct irq_desc *desc, - irqreturn_t action_ret) + irqreturn_t action_ret, struct pt_regs *regs) { if (unlikely(action_ret != IRQ_HANDLED)) { desc->irqs_unhandled++; @@ -147,7 +147,7 @@ void note_interrupt(unsigned int irq, struct irq_desc *desc, if (unlikely(irqfixup)) { /* Don't punish working computers */ if ((irqfixup == 2 && irq == 0) || action_ret == IRQ_NONE) { - int ok = misrouted_irq(irq); + int ok = misrouted_irq(irq, regs); if (action_ret == IRQ_NONE) desc->irqs_unhandled -= ok; } diff --git a/trunk/kernel/kmod.c b/trunk/kernel/kmod.c index 2b76dee28496..bb4e29d924e4 100644 --- a/trunk/kernel/kmod.c +++ b/trunk/kernel/kmod.c @@ -307,14 +307,14 @@ int call_usermodehelper_pipe(char *path, char **argv, char **envp, return 0; f = create_write_pipe(); - if (IS_ERR(f)) - return PTR_ERR(f); + if (!f) + return -ENOMEM; *filp = f; f = create_read_pipe(f); - if (IS_ERR(f)) { + if (!f) { free_write_pipe(*filp); - return PTR_ERR(f); + return -ENOMEM; } sub_info.stdin = f; diff --git a/trunk/kernel/lockdep.c b/trunk/kernel/lockdep.c index c9fefdb1a7db..4c0553461000 100644 --- a/trunk/kernel/lockdep.c +++ b/trunk/kernel/lockdep.c @@ -575,8 +575,6 @@ static noinline int print_circular_bug_tail(void) return 0; } -#define RECURSION_LIMIT 40 - static int noinline print_infinite_recursion_bug(void) { __raw_spin_unlock(&hash_lock); @@ -597,7 +595,7 @@ check_noncircular(struct lock_class *source, unsigned int depth) debug_atomic_inc(&nr_cyclic_check_recursions); if (depth > max_recursion_depth) max_recursion_depth = depth; - if (depth >= RECURSION_LIMIT) + if (depth >= 20) return print_infinite_recursion_bug(); /* * Check this lock's dependency list: @@ -647,7 +645,7 @@ find_usage_forwards(struct lock_class *source, unsigned int depth) if (depth > max_recursion_depth) max_recursion_depth = depth; - if (depth >= RECURSION_LIMIT) + if (depth >= 20) return print_infinite_recursion_bug(); debug_atomic_inc(&nr_find_usage_forwards_checks); @@ -686,7 +684,7 @@ find_usage_backwards(struct lock_class *source, unsigned int depth) if (depth > max_recursion_depth) max_recursion_depth = depth; - if (depth >= RECURSION_LIMIT) + if (depth >= 20) return print_infinite_recursion_bug(); debug_atomic_inc(&nr_find_usage_backwards_checks); @@ -1081,8 +1079,7 @@ static int static_obj(void *obj) */ for_each_possible_cpu(i) { start = (unsigned long) &__per_cpu_start + per_cpu_offset(i); - end = (unsigned long) &__per_cpu_start + PERCPU_ENOUGH_ROOM - + per_cpu_offset(i); + end = (unsigned long) &__per_cpu_end + per_cpu_offset(i); if ((addr >= start) && (addr < end)) return 1; @@ -1117,6 +1114,8 @@ static int count_matching_names(struct lock_class *new_class) return count + 1; } +extern void __error_too_big_MAX_LOCKDEP_SUBCLASSES(void); + /* * Register a lock's class in the hash-table, if the class is not present * yet. Otherwise we look it up. We cache the result in the lock object @@ -1154,7 +1153,8 @@ look_up_lock_class(struct lockdep_map *lock, unsigned int subclass) * (or spin_lock_init()) call - which acts as the key. For static * locks we use the lock object itself as the key. */ - BUILD_BUG_ON(sizeof(struct lock_class_key) > sizeof(struct lock_class)); + if (sizeof(struct lock_class_key) > sizeof(struct lock_class)) + __error_too_big_MAX_LOCKDEP_SUBCLASSES(); key = lock->key->subkeys + subclass; @@ -1177,7 +1177,7 @@ look_up_lock_class(struct lockdep_map *lock, unsigned int subclass) * itself, so actual lookup of the hash should be once per lock object. */ static inline struct lock_class * -register_lock_class(struct lockdep_map *lock, unsigned int subclass, int force) +register_lock_class(struct lockdep_map *lock, unsigned int subclass) { struct lockdep_subclass_key *key; struct list_head *hash_head; @@ -1249,7 +1249,7 @@ register_lock_class(struct lockdep_map *lock, unsigned int subclass, int force) out_unlock_set: __raw_spin_unlock(&hash_lock); - if (!subclass || force) + if (!subclass) lock->class_cache = class; DEBUG_LOCKS_WARN_ON(class->subclass != subclass); @@ -1937,7 +1937,7 @@ void trace_softirqs_off(unsigned long ip) * Initialize a lock instance's lock-class mapping info: */ void lockdep_init_map(struct lockdep_map *lock, const char *name, - struct lock_class_key *key, int subclass) + struct lock_class_key *key) { if (unlikely(!debug_locks)) return; @@ -1957,8 +1957,6 @@ void lockdep_init_map(struct lockdep_map *lock, const char *name, lock->name = name; lock->key = key; lock->class_cache = NULL; - if (subclass) - register_lock_class(lock, subclass, 1); } EXPORT_SYMBOL_GPL(lockdep_init_map); @@ -1997,7 +1995,7 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass, * Not cached yet or subclass? */ if (unlikely(!class)) { - class = register_lock_class(lock, subclass, 0); + class = register_lock_class(lock, subclass); if (!class) return 0; } diff --git a/trunk/kernel/module.c b/trunk/kernel/module.c index 45e01cb60101..7f60e782de1e 100644 --- a/trunk/kernel/module.c +++ b/trunk/kernel/module.c @@ -87,12 +87,6 @@ static inline int strong_try_module_get(struct module *mod) return try_module_get(mod); } -static inline void add_taint_module(struct module *mod, unsigned flag) -{ - add_taint(flag); - mod->taints |= flag; -} - /* A thread that wants to hold a reference to a module only while it * is running can call ths to safely exit. * nfsd and lockd use this. @@ -853,10 +847,12 @@ static int check_version(Elf_Shdr *sechdrs, return 0; } /* Not in module's version table. OK, but that taints the kernel. */ - if (!(tainted & TAINT_FORCED_MODULE)) + if (!(tainted & TAINT_FORCED_MODULE)) { printk("%s: no version for \"%s\" found: kernel tainted.\n", mod->name, symname); - add_taint_module(mod, TAINT_FORCED_MODULE); + add_taint(TAINT_FORCED_MODULE); + mod->taints |= TAINT_FORCED_MODULE; + } return 1; } @@ -914,8 +910,7 @@ static unsigned long resolve_symbol(Elf_Shdr *sechdrs, unsigned long ret; const unsigned long *crc; - ret = __find_symbol(name, &owner, &crc, - !(mod->taints & TAINT_PROPRIETARY_MODULE)); + ret = __find_symbol(name, &owner, &crc, mod->license_gplok); if (ret) { /* use_module can fail due to OOM, or module unloading */ if (!check_version(sechdrs, versindex, name, mod, crc) || @@ -1086,35 +1081,22 @@ static int mod_sysfs_setup(struct module *mod, goto out; kobj_set_kset_s(&mod->mkobj, module_subsys); mod->mkobj.mod = mod; - - /* delay uevent until full sysfs population */ - kobject_init(&mod->mkobj.kobj); - err = kobject_add(&mod->mkobj.kobj); + err = kobject_register(&mod->mkobj.kobj); if (err) goto out; - mod->drivers_dir = kobject_add_dir(&mod->mkobj.kobj, "drivers"); - if (!mod->drivers_dir) - goto out_unreg; - err = module_param_sysfs_setup(mod, kparam, num_params); if (err) - goto out_unreg_drivers; + goto out_unreg; err = module_add_modinfo_attrs(mod); if (err) - goto out_unreg_param; + goto out_unreg; - kobject_uevent(&mod->mkobj.kobj, KOBJ_ADD); return 0; -out_unreg_drivers: - kobject_unregister(mod->drivers_dir); -out_unreg_param: - module_param_sysfs_remove(mod); out_unreg: - kobject_del(&mod->mkobj.kobj); - kobject_put(&mod->mkobj.kobj); + kobject_unregister(&mod->mkobj.kobj); out: return err; } @@ -1123,7 +1105,6 @@ static void mod_kobject_remove(struct module *mod) { module_remove_modinfo_attrs(mod); module_param_sysfs_remove(mod); - kobject_unregister(mod->drivers_dir); kobject_unregister(&mod->mkobj.kobj); } @@ -1354,11 +1335,12 @@ static void set_license(struct module *mod, const char *license) if (!license) license = "unspecified"; - if (!license_is_gpl_compatible(license)) { - if (!(tainted & TAINT_PROPRIETARY_MODULE)) - printk(KERN_WARNING "%s: module license '%s' taints " - "kernel.\n", mod->name, license); - add_taint_module(mod, TAINT_PROPRIETARY_MODULE); + mod->license_gplok = license_is_gpl_compatible(license); + if (!mod->license_gplok && !(tainted & TAINT_PROPRIETARY_MODULE)) { + printk(KERN_WARNING "%s: module license '%s' taints kernel.\n", + mod->name, license); + add_taint(TAINT_PROPRIETARY_MODULE); + mod->taints |= TAINT_PROPRIETARY_MODULE; } } @@ -1637,7 +1619,8 @@ static struct module *load_module(void __user *umod, modmagic = get_modinfo(sechdrs, infoindex, "vermagic"); /* This is allowed: modprobe --force will invalidate it. */ if (!modmagic) { - add_taint_module(mod, TAINT_FORCED_MODULE); + add_taint(TAINT_FORCED_MODULE); + mod->taints |= TAINT_FORCED_MODULE; printk(KERN_WARNING "%s: no version magic, tainting kernel.\n", mod->name); } else if (!same_magic(modmagic, vermagic)) { @@ -1731,10 +1714,14 @@ static struct module *load_module(void __user *umod, /* Set up license info based on the info section */ set_license(mod, get_modinfo(sechdrs, infoindex, "license")); - if (strcmp(mod->name, "ndiswrapper") == 0) + if (strcmp(mod->name, "ndiswrapper") == 0) { + add_taint(TAINT_PROPRIETARY_MODULE); + mod->taints |= TAINT_PROPRIETARY_MODULE; + } + if (strcmp(mod->name, "driverloader") == 0) { add_taint(TAINT_PROPRIETARY_MODULE); - if (strcmp(mod->name, "driverloader") == 0) - add_taint_module(mod, TAINT_PROPRIETARY_MODULE); + mod->taints |= TAINT_PROPRIETARY_MODULE; + } /* Set up MODINFO_ATTR fields */ setup_modinfo(mod, sechdrs, infoindex); @@ -1779,7 +1766,8 @@ static struct module *load_module(void __user *umod, (mod->num_unused_gpl_syms && !unusedgplcrcindex)) { printk(KERN_WARNING "%s: No versions for exported symbols." " Tainting kernel.\n", mod->name); - add_taint_module(mod, TAINT_FORCED_MODULE); + add_taint(TAINT_FORCED_MODULE); + mod->taints |= TAINT_FORCED_MODULE; } #endif @@ -2144,33 +2132,9 @@ static void m_stop(struct seq_file *m, void *p) mutex_unlock(&module_mutex); } -static char *taint_flags(unsigned int taints, char *buf) -{ - int bx = 0; - - if (taints) { - buf[bx++] = '('; - if (taints & TAINT_PROPRIETARY_MODULE) - buf[bx++] = 'P'; - if (taints & TAINT_FORCED_MODULE) - buf[bx++] = 'F'; - /* - * TAINT_FORCED_RMMOD: could be added. - * TAINT_UNSAFE_SMP, TAINT_MACHINE_CHECK, TAINT_BAD_PAGE don't - * apply to modules. - */ - buf[bx++] = ')'; - } - buf[bx] = '\0'; - - return buf; -} - static int m_show(struct seq_file *m, void *p) { struct module *mod = list_entry(p, struct module, list); - char buf[8]; - seq_printf(m, "%s %lu", mod->name, mod->init_size + mod->core_size); print_unload_info(m, mod); @@ -2183,10 +2147,6 @@ static int m_show(struct seq_file *m, void *p) /* Used by oprofile and other similar tools. */ seq_printf(m, " 0x%p", mod->module_core); - /* Taints info */ - if (mod->taints) - seq_printf(m, " %s", taint_flags(mod->taints, buf)); - seq_printf(m, "\n"); return 0; } @@ -2275,6 +2235,28 @@ struct module *module_text_address(unsigned long addr) return mod; } +static char *taint_flags(unsigned int taints, char *buf) +{ + *buf = '\0'; + if (taints) { + int bx; + + buf[0] = '('; + bx = 1; + if (taints & TAINT_PROPRIETARY_MODULE) + buf[bx++] = 'P'; + if (taints & TAINT_FORCED_MODULE) + buf[bx++] = 'F'; + /* + * TAINT_FORCED_RMMOD: could be added. + * TAINT_UNSAFE_SMP, TAINT_MACHINE_CHECK, TAINT_BAD_PAGE don't + * apply to modules. + */ + buf[bx] = ')'; + } + return buf; +} + /* Don't grab lock, we're oopsing. */ void print_modules(void) { @@ -2289,14 +2271,11 @@ void print_modules(void) void module_add_driver(struct module *mod, struct device_driver *drv) { - int no_warn; - if (!mod || !drv) return; - /* Don't check return codes; these calls are idempotent */ - no_warn = sysfs_create_link(&drv->kobj, &mod->mkobj.kobj, "module"); - no_warn = sysfs_create_link(mod->drivers_dir, &drv->kobj, drv->name); + /* Don't check return code; this call is idempotent */ + sysfs_create_link(&drv->kobj, &mod->mkobj.kobj, "module"); } EXPORT_SYMBOL(module_add_driver); @@ -2305,8 +2284,6 @@ void module_remove_driver(struct device_driver *drv) if (!drv) return; sysfs_remove_link(&drv->kobj, "module"); - if (drv->owner && drv->owner->drivers_dir) - sysfs_remove_link(drv->owner->drivers_dir, drv->name); } EXPORT_SYMBOL(module_remove_driver); diff --git a/trunk/kernel/mutex-debug.c b/trunk/kernel/mutex-debug.c index 18651641a7b5..e3203c654dda 100644 --- a/trunk/kernel/mutex-debug.c +++ b/trunk/kernel/mutex-debug.c @@ -91,7 +91,7 @@ void debug_mutex_init(struct mutex *lock, const char *name, * Make sure we are not reinitializing a held lock: */ debug_check_no_locks_freed((void *)lock, sizeof(*lock)); - lockdep_init_map(&lock->dep_map, name, key, 0); + lockdep_init_map(&lock->dep_map, name, key); #endif lock->owner = NULL; lock->magic = lock; diff --git a/trunk/kernel/nsproxy.c b/trunk/kernel/nsproxy.c index 674aceb7335a..6ebdb82a0ce4 100644 --- a/trunk/kernel/nsproxy.c +++ b/trunk/kernel/nsproxy.c @@ -44,9 +44,11 @@ static inline struct nsproxy *clone_namespaces(struct nsproxy *orig) { struct nsproxy *ns; - ns = kmemdup(orig, sizeof(struct nsproxy), GFP_KERNEL); - if (ns) + ns = kmalloc(sizeof(struct nsproxy), GFP_KERNEL); + if (ns) { + memcpy(ns, orig, sizeof(struct nsproxy)); atomic_set(&ns->count, 1); + } return ns; } diff --git a/trunk/kernel/posix-cpu-timers.c b/trunk/kernel/posix-cpu-timers.c index 7c3e1e6dfb5b..479b16b44f79 100644 --- a/trunk/kernel/posix-cpu-timers.c +++ b/trunk/kernel/posix-cpu-timers.c @@ -87,19 +87,6 @@ static inline union cpu_time_count cpu_time_sub(const clockid_t which_clock, return a; } -/* - * Divide and limit the result to res >= 1 - * - * This is necessary to prevent signal delivery starvation, when the result of - * the division would be rounded down to 0. - */ -static inline cputime_t cputime_div_non_zero(cputime_t time, unsigned long div) -{ - cputime_t res = cputime_div(time, div); - - return max_t(cputime_t, res, 1); -} - /* * Update expiry time from increment, and increase overrun count, * given the current clock sample. @@ -496,8 +483,8 @@ static void process_timer_rebalance(struct task_struct *p, BUG(); break; case CPUCLOCK_PROF: - left = cputime_div_non_zero(cputime_sub(expires.cpu, val.cpu), - nthreads); + left = cputime_div(cputime_sub(expires.cpu, val.cpu), + nthreads); do { if (likely(!(t->flags & PF_EXITING))) { ticks = cputime_add(prof_ticks(t), left); @@ -511,8 +498,8 @@ static void process_timer_rebalance(struct task_struct *p, } while (t != p); break; case CPUCLOCK_VIRT: - left = cputime_div_non_zero(cputime_sub(expires.cpu, val.cpu), - nthreads); + left = cputime_div(cputime_sub(expires.cpu, val.cpu), + nthreads); do { if (likely(!(t->flags & PF_EXITING))) { ticks = cputime_add(virt_ticks(t), left); @@ -528,7 +515,6 @@ static void process_timer_rebalance(struct task_struct *p, case CPUCLOCK_SCHED: nsleft = expires.sched - val.sched; do_div(nsleft, nthreads); - nsleft = max_t(unsigned long long, nsleft, 1); do { if (likely(!(t->flags & PF_EXITING))) { ns = t->sched_time + nsleft; @@ -1173,13 +1159,12 @@ static void check_process_timers(struct task_struct *tsk, prof_left = cputime_sub(prof_expires, utime); prof_left = cputime_sub(prof_left, stime); - prof_left = cputime_div_non_zero(prof_left, nthreads); + prof_left = cputime_div(prof_left, nthreads); virt_left = cputime_sub(virt_expires, utime); - virt_left = cputime_div_non_zero(virt_left, nthreads); + virt_left = cputime_div(virt_left, nthreads); if (sched_expires) { sched_left = sched_expires - sched_time; do_div(sched_left, nthreads); - sched_left = max_t(unsigned long long, sched_left, 1); } else { sched_left = 0; } diff --git a/trunk/kernel/power/disk.c b/trunk/kernel/power/disk.c index b1fb7866b0b3..d72234942798 100644 --- a/trunk/kernel/power/disk.c +++ b/trunk/kernel/power/disk.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include "power.h" @@ -71,7 +70,7 @@ static inline void platform_finish(void) static int prepare_processes(void) { - int error = 0; + int error; pm_prepare_console(); @@ -84,12 +83,6 @@ static int prepare_processes(void) goto thaw; } - if (pm_disk_mode == PM_DISK_TESTPROC) { - printk("swsusp debug: Waiting for 5 seconds.\n"); - mdelay(5000); - goto thaw; - } - /* Free memory before shutting down devices. */ if (!(error = swsusp_shrink_memory())) return 0; @@ -126,21 +119,11 @@ int pm_suspend_disk(void) if (error) return error; - if (pm_disk_mode == PM_DISK_TESTPROC) - goto Thaw; - - suspend_console(); error = device_suspend(PMSG_FREEZE); if (error) { - resume_console(); printk("Some devices failed to suspend\n"); - goto Thaw; - } - - if (pm_disk_mode == PM_DISK_TEST) { - printk("swsusp debug: Waiting for 5 seconds.\n"); - mdelay(5000); - goto Done; + unprepare_processes(); + return error; } pr_debug("PM: snapshotting memory.\n"); @@ -150,24 +133,21 @@ int pm_suspend_disk(void) if (in_suspend) { device_resume(); - resume_console(); pr_debug("PM: writing image.\n"); error = swsusp_write(); if (!error) power_down(pm_disk_mode); else { swsusp_free(); - goto Thaw; + unprepare_processes(); + return error; } - } else { + } else pr_debug("PM: Image restored successfully.\n"); - } swsusp_free(); Done: device_resume(); - resume_console(); - Thaw: unprepare_processes(); return error; } @@ -232,9 +212,7 @@ static int software_resume(void) pr_debug("PM: Preparing devices for restore.\n"); - suspend_console(); if ((error = device_suspend(PMSG_PRETHAW))) { - resume_console(); printk("Some devices failed to suspend\n"); swsusp_free(); goto Thaw; @@ -246,7 +224,6 @@ static int software_resume(void) swsusp_resume(); pr_debug("PM: Restore failed, recovering.n"); device_resume(); - resume_console(); Thaw: unprepare_processes(); Done: @@ -264,8 +241,6 @@ static const char * const pm_disk_modes[] = { [PM_DISK_PLATFORM] = "platform", [PM_DISK_SHUTDOWN] = "shutdown", [PM_DISK_REBOOT] = "reboot", - [PM_DISK_TEST] = "test", - [PM_DISK_TESTPROC] = "testproc", }; /** @@ -320,19 +295,17 @@ static ssize_t disk_store(struct subsystem * s, const char * buf, size_t n) } } if (mode) { - if (mode == PM_DISK_SHUTDOWN || mode == PM_DISK_REBOOT || - mode == PM_DISK_TEST || mode == PM_DISK_TESTPROC) { + if (mode == PM_DISK_SHUTDOWN || mode == PM_DISK_REBOOT) pm_disk_mode = mode; - } else { + else { if (pm_ops && pm_ops->enter && (mode == pm_ops->pm_disk_mode)) pm_disk_mode = mode; else error = -EINVAL; } - } else { + } else error = -EINVAL; - } pr_debug("PM: suspend-to-disk mode set to '%s'\n", pm_disk_modes[mode]); diff --git a/trunk/kernel/power/poweroff.c b/trunk/kernel/power/poweroff.c index f1f900ac3164..7a4144ba3afd 100644 --- a/trunk/kernel/power/poweroff.c +++ b/trunk/kernel/power/poweroff.c @@ -23,7 +23,8 @@ static void do_poweroff(void *dummy) static DECLARE_WORK(poweroff_work, do_poweroff, NULL); -static void handle_poweroff(int key, struct tty_struct *tty) +static void handle_poweroff(int key, struct pt_regs *pt_regs, + struct tty_struct *tty) { schedule_work(&poweroff_work); } diff --git a/trunk/kernel/power/swap.c b/trunk/kernel/power/swap.c index 1a3b0dd2c3fc..9b2ee5344dee 100644 --- a/trunk/kernel/power/swap.c +++ b/trunk/kernel/power/swap.c @@ -425,8 +425,7 @@ static int submit(int rw, pgoff_t page_off, struct page *page, bio_set_pages_dirty(bio); bio_put(bio); } else { - if (rw == READ) - get_page(page); /* These pages are freed later */ + get_page(page); bio->bi_private = *bio_chain; *bio_chain = bio; submit_bio(rw | (1 << BIO_RW_SYNC), bio); diff --git a/trunk/kernel/power/user.c b/trunk/kernel/power/user.c index d991d3b0e5a4..72825c853cd7 100644 --- a/trunk/kernel/power/user.c +++ b/trunk/kernel/power/user.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include @@ -146,10 +145,10 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp, error = freeze_processes(); if (error) { thaw_processes(); - enable_nonboot_cpus(); error = -EBUSY; } } + enable_nonboot_cpus(); up(&pm_sem); if (!error) data->frozen = 1; @@ -174,14 +173,12 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp, /* Free memory before shutting down devices. */ error = swsusp_shrink_memory(); if (!error) { - suspend_console(); error = device_suspend(PMSG_FREEZE); if (!error) { in_suspend = 1; error = swsusp_suspend(); device_resume(); } - resume_console(); } up(&pm_sem); if (!error) @@ -199,13 +196,11 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp, snapshot_free_unused_memory(&data->handle); down(&pm_sem); pm_prepare_console(); - suspend_console(); error = device_suspend(PMSG_PRETHAW); if (!error) { error = swsusp_resume(); device_resume(); } - resume_console(); pm_restore_console(); up(&pm_sem); break; @@ -294,7 +289,6 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp, } /* Put devices to sleep */ - suspend_console(); error = device_suspend(PMSG_SUSPEND); if (error) { printk(KERN_ERR "Failed to suspend some devices.\n"); @@ -305,7 +299,7 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp, /* Wake up devices */ device_resume(); } - resume_console(); + if (pm_ops->finish) pm_ops->finish(PM_SUSPEND_MEM); diff --git a/trunk/kernel/printk.c b/trunk/kernel/printk.c index 66426552fbfe..771f5e861bcd 100644 --- a/trunk/kernel/printk.c +++ b/trunk/kernel/printk.c @@ -31,7 +31,6 @@ #include #include #include -#include #include @@ -821,8 +820,15 @@ void release_console_sem(void) console_locked = 0; up(&console_sem); spin_unlock_irqrestore(&logbuf_lock, flags); - if (wake_klogd && !oops_in_progress && waitqueue_active(&log_wait)) - wake_up_interruptible(&log_wait); + if (wake_klogd && !oops_in_progress && waitqueue_active(&log_wait)) { + /* + * If we printk from within the lock dependency code, + * from within the scheduler code, then do not lock + * up due to self-recursion: + */ + if (!lockdep_internal()) + wake_up_interruptible(&log_wait); + } } EXPORT_SYMBOL(release_console_sem); @@ -1102,23 +1108,3 @@ int printk_ratelimit(void) printk_ratelimit_burst); } EXPORT_SYMBOL(printk_ratelimit); - -/** - * printk_timed_ratelimit - caller-controlled printk ratelimiting - * @caller_jiffies: pointer to caller's state - * @interval_msecs: minimum interval between prints - * - * printk_timed_ratelimit() returns true if more than @interval_msecs - * milliseconds have elapsed since the last time printk_timed_ratelimit() - * returned true. - */ -bool printk_timed_ratelimit(unsigned long *caller_jiffies, - unsigned int interval_msecs) -{ - if (*caller_jiffies == 0 || time_after(jiffies, *caller_jiffies)) { - *caller_jiffies = jiffies + msecs_to_jiffies(interval_msecs); - return true; - } - return false; -} -EXPORT_SYMBOL(printk_timed_ratelimit); diff --git a/trunk/kernel/profile.c b/trunk/kernel/profile.c index f940b462eec9..fb660c7d35ba 100644 --- a/trunk/kernel/profile.c +++ b/trunk/kernel/profile.c @@ -25,7 +25,6 @@ #include #include #include -#include struct profile_hit { u32 pc, hits; @@ -367,10 +366,8 @@ void profile_hit(int type, void *__pc) } #endif /* !CONFIG_SMP */ -void profile_tick(int type) +void profile_tick(int type, struct pt_regs *regs) { - struct pt_regs *regs = get_irq_regs(); - if (type == CPU_PROFILING && timer_hook) timer_hook(regs); if (!user_mode(regs) && cpu_isset(smp_processor_id(), prof_cpu_mask)) @@ -399,7 +396,7 @@ static int prof_cpu_mask_write_proc (struct file *file, const char __user *buffe unsigned long full_count = count, err; cpumask_t new_value; - err = cpumask_parse_user(buffer, count, new_value); + err = cpumask_parse(buffer, count, new_value); if (err) return err; diff --git a/trunk/kernel/relay.c b/trunk/kernel/relay.c index f04bbdb56ac2..1d63ecddfa70 100644 --- a/trunk/kernel/relay.c +++ b/trunk/kernel/relay.c @@ -887,7 +887,7 @@ static int subbuf_read_actor(size_t read_start, from = buf->start + read_start; ret = avail; - if (copy_to_user(desc->arg.buf, from, avail)) { + if (copy_to_user(desc->arg.data, from, avail)) { desc->error = -EFAULT; ret = 0; } @@ -946,17 +946,24 @@ typedef int (*subbuf_actor_t) (size_t read_start, */ static inline ssize_t relay_file_read_subbufs(struct file *filp, loff_t *ppos, + size_t count, subbuf_actor_t subbuf_actor, read_actor_t actor, - read_descriptor_t *desc) + void *target) { struct rchan_buf *buf = filp->private_data; size_t read_start, avail; + read_descriptor_t desc; int ret; - if (!desc->count) + if (!count) return 0; + desc.written = 0; + desc.count = count; + desc.arg.data = target; + desc.error = 0; + mutex_lock(&filp->f_dentry->d_inode->i_mutex); do { if (!relay_file_read_avail(buf, *ppos)) @@ -967,19 +974,19 @@ static inline ssize_t relay_file_read_subbufs(struct file *filp, if (!avail) break; - avail = min(desc->count, avail); - ret = subbuf_actor(read_start, buf, avail, desc, actor); - if (desc->error < 0) + avail = min(desc.count, avail); + ret = subbuf_actor(read_start, buf, avail, &desc, actor); + if (desc.error < 0) break; if (ret) { relay_file_read_consume(buf, read_start, ret); *ppos = relay_file_read_end_pos(buf, read_start, ret); } - } while (desc->count && ret); + } while (desc.count && ret); mutex_unlock(&filp->f_dentry->d_inode->i_mutex); - return desc->written; + return desc.written; } static ssize_t relay_file_read(struct file *filp, @@ -987,13 +994,8 @@ static ssize_t relay_file_read(struct file *filp, size_t count, loff_t *ppos) { - read_descriptor_t desc; - desc.written = 0; - desc.count = count; - desc.arg.buf = buffer; - desc.error = 0; - return relay_file_read_subbufs(filp, ppos, subbuf_read_actor, - NULL, &desc); + return relay_file_read_subbufs(filp, ppos, count, subbuf_read_actor, + NULL, buffer); } static ssize_t relay_file_sendfile(struct file *filp, @@ -1002,13 +1004,8 @@ static ssize_t relay_file_sendfile(struct file *filp, read_actor_t actor, void *target) { - read_descriptor_t desc; - desc.written = 0; - desc.count = count; - desc.arg.data = target; - desc.error = 0; - return relay_file_read_subbufs(filp, ppos, subbuf_send_actor, - actor, &desc); + return relay_file_read_subbufs(filp, ppos, count, subbuf_send_actor, + actor, target); } struct file_operations relay_file_operations = { diff --git a/trunk/kernel/sched.c b/trunk/kernel/sched.c index 3399701c680e..53608a59d6e3 100644 --- a/trunk/kernel/sched.c +++ b/trunk/kernel/sched.c @@ -160,6 +160,15 @@ #define TASK_PREEMPTS_CURR(p, rq) \ ((p)->prio < (rq)->curr->prio) +/* + * task_timeslice() scales user-nice values [ -20 ... 0 ... 19 ] + * to time slice values: [800ms ... 100ms ... 5ms] + * + * The higher a thread's priority, the bigger timeslices + * it gets during one round of execution. But even the lowest + * priority thread gets MIN_TIMESLICE worth of execution time. + */ + #define SCALE_PRIO(x, prio) \ max(x * (MAX_PRIO - prio) / (MAX_USER_PRIO / 2), MIN_TIMESLICE) @@ -171,15 +180,6 @@ static unsigned int static_prio_timeslice(int static_prio) return SCALE_PRIO(DEF_TIMESLICE, static_prio); } -/* - * task_timeslice() scales user-nice values [ -20 ... 0 ... 19 ] - * to time slice values: [800ms ... 100ms ... 5ms] - * - * The higher a thread's priority, the bigger timeslices - * it gets during one round of execution. But even the lowest - * priority thread gets MIN_TIMESLICE worth of execution time. - */ - static inline unsigned int task_timeslice(struct task_struct *p) { return static_prio_timeslice(p->static_prio); @@ -1822,14 +1822,14 @@ context_switch(struct rq *rq, struct task_struct *prev, struct mm_struct *mm = next->mm; struct mm_struct *oldmm = prev->active_mm; - if (!mm) { + if (unlikely(!mm)) { next->active_mm = oldmm; atomic_inc(&oldmm->mm_count); enter_lazy_tlb(oldmm, next); } else switch_mm(oldmm, mm, next); - if (!prev->mm) { + if (unlikely(!prev->mm)) { prev->active_mm = NULL; WARN_ON(rq->prev_mm); rq->prev_mm = oldmm; @@ -3491,7 +3491,7 @@ asmlinkage void __sched preempt_schedule(void) * If there is a non-zero preempt_count or interrupts are disabled, * we do not want to preempt the current task. Just return.. */ - if (likely(ti->preempt_count || irqs_disabled())) + if (unlikely(ti->preempt_count || irqs_disabled())) return; need_resched: diff --git a/trunk/kernel/signal.c b/trunk/kernel/signal.c index df18c167a2a7..7ed8d5304bec 100644 --- a/trunk/kernel/signal.c +++ b/trunk/kernel/signal.c @@ -267,25 +267,18 @@ static struct sigqueue *__sigqueue_alloc(struct task_struct *t, gfp_t flags, int override_rlimit) { struct sigqueue *q = NULL; - struct user_struct *user; - /* - * In order to avoid problems with "switch_user()", we want to make - * sure that the compiler doesn't re-load "t->user" - */ - user = t->user; - barrier(); - atomic_inc(&user->sigpending); + atomic_inc(&t->user->sigpending); if (override_rlimit || - atomic_read(&user->sigpending) <= + atomic_read(&t->user->sigpending) <= t->signal->rlim[RLIMIT_SIGPENDING].rlim_cur) q = kmem_cache_alloc(sigqueue_cachep, flags); if (unlikely(q == NULL)) { - atomic_dec(&user->sigpending); + atomic_dec(&t->user->sigpending); } else { INIT_LIST_HEAD(&q->list); q->flags = 0; - q->user = get_uid(user); + q->user = get_uid(t->user); } return(q); } diff --git a/trunk/kernel/spinlock.c b/trunk/kernel/spinlock.c index 2c6c2bf85514..476c3741511b 100644 --- a/trunk/kernel/spinlock.c +++ b/trunk/kernel/spinlock.c @@ -293,27 +293,6 @@ void __lockfunc _spin_lock_nested(spinlock_t *lock, int subclass) } EXPORT_SYMBOL(_spin_lock_nested); -unsigned long __lockfunc _spin_lock_irqsave_nested(spinlock_t *lock, int subclass) -{ - unsigned long flags; - - local_irq_save(flags); - preempt_disable(); - spin_acquire(&lock->dep_map, subclass, 0, _RET_IP_); - /* - * On lockdep we dont want the hand-coded irq-enable of - * _raw_spin_lock_flags() code, because lockdep assumes - * that interrupts are not re-enabled during lock-acquire: - */ -#ifdef CONFIG_PROVE_SPIN_LOCKING - _raw_spin_lock(lock); -#else - _raw_spin_lock_flags(lock, &flags); -#endif - return flags; -} - -EXPORT_SYMBOL(_spin_lock_irqsave_nested); #endif diff --git a/trunk/kernel/sys_ni.c b/trunk/kernel/sys_ni.c index d7306d0f3dfc..7a3b2e75f040 100644 --- a/trunk/kernel/sys_ni.c +++ b/trunk/kernel/sys_ni.c @@ -49,7 +49,6 @@ cond_syscall(compat_sys_get_robust_list); cond_syscall(sys_epoll_create); cond_syscall(sys_epoll_ctl); cond_syscall(sys_epoll_wait); -cond_syscall(sys_epoll_pwait); cond_syscall(sys_semget); cond_syscall(sys_semop); cond_syscall(sys_semtimedop); @@ -135,7 +134,6 @@ cond_syscall(sys_madvise); cond_syscall(sys_mremap); cond_syscall(sys_remap_file_pages); cond_syscall(compat_sys_move_pages); -cond_syscall(compat_sys_migrate_pages); /* block-layer dependent */ cond_syscall(sys_bdflush); diff --git a/trunk/kernel/sysctl.c b/trunk/kernel/sysctl.c index 09e569f4792b..8020fb273c4f 100644 --- a/trunk/kernel/sysctl.c +++ b/trunk/kernel/sysctl.c @@ -136,10 +136,8 @@ static int parse_table(int __user *, int, void __user *, size_t __user *, static int proc_do_uts_string(ctl_table *table, int write, struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos); -#ifdef CONFIG_PROC_SYSCTL static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos); -#endif static ctl_table root_table[]; static struct ctl_table_header root_table_header = @@ -544,7 +542,6 @@ static ctl_table kern_table[] = { .proc_handler = &proc_dointvec, }, #endif -#ifdef CONFIG_PROC_SYSCTL { .ctl_name = KERN_CADPID, .procname = "cad_pid", @@ -553,7 +550,6 @@ static ctl_table kern_table[] = { .mode = 0600, .proc_handler = &proc_do_cad_pid, }, -#endif { .ctl_name = KERN_MAX_THREADS, .procname = "threads-max", @@ -1315,9 +1311,7 @@ static int parse_table(int __user *name, int nlen, return -ENOTDIR; if (get_user(n, name)) return -EFAULT; - for ( ; table->ctl_name || table->procname; table++) { - if (!table->ctl_name) - continue; + for ( ; table->ctl_name; table++) { if (n == table->ctl_name || table->ctl_name == CTL_ANY) { int error; if (table->child) { @@ -1534,7 +1528,7 @@ static void register_proc_table(ctl_table * table, struct proc_dir_entry *root, int len; mode_t mode; - for (; table->ctl_name || table->procname; table++) { + for (; table->ctl_name; table++) { /* Can't do anything without a proc name. */ if (!table->procname) continue; @@ -1581,7 +1575,7 @@ static void register_proc_table(ctl_table * table, struct proc_dir_entry *root, static void unregister_proc_table(ctl_table * table, struct proc_dir_entry *root) { struct proc_dir_entry *de; - for (; table->ctl_name || table->procname; table++) { + for (; table->ctl_name; table++) { if (!(de = table->de)) continue; if (de->mode & S_IFDIR) { @@ -2682,33 +2676,13 @@ int sysctl_ms_jiffies(ctl_table *table, int __user *name, int nlen, asmlinkage long sys_sysctl(struct __sysctl_args __user *args) { static int msg_count; - struct __sysctl_args tmp; - int name[CTL_MAXNAME]; - int i; - - /* Read in the sysctl name for better debug message logging */ - if (copy_from_user(&tmp, args, sizeof(tmp))) - return -EFAULT; - if (tmp.nlen <= 0 || tmp.nlen >= CTL_MAXNAME) - return -ENOTDIR; - for (i = 0; i < tmp.nlen; i++) - if (get_user(name[i], tmp.name + i)) - return -EFAULT; - - /* Ignore accesses to kernel.version */ - if ((tmp.nlen == 2) && (name[0] == CTL_KERN) && (name[1] == KERN_VERSION)) - goto out; if (msg_count < 5) { msg_count++; printk(KERN_INFO "warning: process `%s' used the removed sysctl " - "system call with ", current->comm); - for (i = 0; i < tmp.nlen; i++) - printk("%d.", name[i]); - printk("\n"); + "system call\n", current->comm); } -out: return -ENOSYS; } diff --git a/trunk/kernel/taskstats.c b/trunk/kernel/taskstats.c index f45c5e70773c..5d6a8c54ee85 100644 --- a/trunk/kernel/taskstats.c +++ b/trunk/kernel/taskstats.c @@ -77,8 +77,7 @@ static int prepare_reply(struct genl_info *info, u8 cmd, struct sk_buff **skbp, /* * If new attributes are added, please revisit this allocation */ - size = nlmsg_total_size(genlmsg_total_size(size)); - skb = nlmsg_new(size, GFP_KERNEL); + skb = nlmsg_new(genlmsg_total_size(size), GFP_KERNEL); if (!skb) return -ENOMEM; @@ -175,19 +174,21 @@ static void send_cpu_listeners(struct sk_buff *skb, unsigned int cpu) up_write(&listeners->sem); } -static int fill_pid(pid_t pid, struct task_struct *tsk, +static int fill_pid(pid_t pid, struct task_struct *pidtsk, struct taskstats *stats) { int rc = 0; + struct task_struct *tsk = pidtsk; - if (!tsk) { - rcu_read_lock(); + if (!pidtsk) { + read_lock(&tasklist_lock); tsk = find_task_by_pid(pid); - if (tsk) - get_task_struct(tsk); - rcu_read_unlock(); - if (!tsk) + if (!tsk) { + read_unlock(&tasklist_lock); return -ESRCH; + } + get_task_struct(tsk); + read_unlock(&tasklist_lock); } else get_task_struct(tsk); @@ -213,30 +214,39 @@ static int fill_pid(pid_t pid, struct task_struct *tsk, } -static int fill_tgid(pid_t tgid, struct task_struct *first, +static int fill_tgid(pid_t tgid, struct task_struct *tgidtsk, struct taskstats *stats) { - struct task_struct *tsk; + struct task_struct *tsk, *first; unsigned long flags; - int rc = -ESRCH; /* * Add additional stats from live tasks except zombie thread group * leaders who are already counted with the dead tasks */ - rcu_read_lock(); - if (!first) + first = tgidtsk; + if (!first) { + read_lock(&tasklist_lock); first = find_task_by_pid(tgid); + if (!first) { + read_unlock(&tasklist_lock); + return -ESRCH; + } + get_task_struct(first); + read_unlock(&tasklist_lock); + } else + get_task_struct(first); - if (!first || !lock_task_sighand(first, &flags)) - goto out; - + /* Start with stats from dead tasks */ + spin_lock_irqsave(&first->signal->stats_lock, flags); if (first->signal->stats) memcpy(stats, first->signal->stats, sizeof(*stats)); + spin_unlock_irqrestore(&first->signal->stats_lock, flags); tsk = first; + read_lock(&tasklist_lock); do { - if (tsk->exit_state) + if (tsk->exit_state == EXIT_ZOMBIE && thread_group_leader(tsk)) continue; /* * Accounting subsystem can call its functions here to @@ -247,18 +257,15 @@ static int fill_tgid(pid_t tgid, struct task_struct *first, delayacct_add_tsk(stats, tsk); } while_each_thread(first, tsk); - - unlock_task_sighand(first, &flags); - rc = 0; -out: - rcu_read_unlock(); - + read_unlock(&tasklist_lock); stats->version = TASKSTATS_VERSION; + /* * Accounting subsytems can also add calls here to modify * fields of taskstats. */ - return rc; + + return 0; } @@ -266,7 +273,7 @@ static void fill_tgid_exit(struct task_struct *tsk) { unsigned long flags; - spin_lock_irqsave(&tsk->sighand->siglock, flags); + spin_lock_irqsave(&tsk->signal->stats_lock, flags); if (!tsk->signal->stats) goto ret; @@ -278,7 +285,7 @@ static void fill_tgid_exit(struct task_struct *tsk) */ delayacct_add_tsk(tsk->signal->stats, tsk); ret: - spin_unlock_irqrestore(&tsk->sighand->siglock, flags); + spin_unlock_irqrestore(&tsk->signal->stats_lock, flags); return; } @@ -412,7 +419,7 @@ static int taskstats_user_cmd(struct sk_buff *skb, struct genl_info *info) return send_reply(rep_skb, info->snd_pid); nla_put_failure: - rc = genlmsg_cancel(rep_skb, reply); + return genlmsg_cancel(rep_skb, reply); err: nlmsg_free(rep_skb); return rc; @@ -454,26 +461,24 @@ void taskstats_exit_send(struct task_struct *tsk, struct taskstats *tidstats, size_t size; int is_thread_group; struct nlattr *na; + unsigned long flags; - if (!family_registered) + if (!family_registered || !tidstats) return; + spin_lock_irqsave(&tsk->signal->stats_lock, flags); + is_thread_group = tsk->signal->stats ? 1 : 0; + spin_unlock_irqrestore(&tsk->signal->stats_lock, flags); + + rc = 0; /* * Size includes space for nested attributes */ size = nla_total_size(sizeof(u32)) + nla_total_size(sizeof(struct taskstats)) + nla_total_size(0); - is_thread_group = (tsk->signal->stats != NULL); - if (is_thread_group) { - /* PID + STATS + TGID + STATS */ - size = 2 * size; - /* fill the tsk->signal->stats structure */ - fill_tgid_exit(tsk); - } - - if (!tidstats) - return; + if (is_thread_group) + size = 2 * size; /* PID + STATS + TGID + STATS */ rc = prepare_reply(NULL, TASKSTATS_CMD_NEW, &rep_skb, &reply, size); if (rc < 0) @@ -493,8 +498,11 @@ void taskstats_exit_send(struct task_struct *tsk, struct taskstats *tidstats, goto send; /* + * tsk has/had a thread group so fill the tsk->signal->stats structure * Doesn't matter if tsk is the leader or the last group member leaving */ + + fill_tgid_exit(tsk); if (!group_dead) goto send; @@ -511,6 +519,7 @@ void taskstats_exit_send(struct task_struct *tsk, struct taskstats *tidstats, nla_put_failure: genlmsg_cancel(rep_skb, reply); + goto ret; err_skb: nlmsg_free(rep_skb); ret: diff --git a/trunk/kernel/time/jiffies.c b/trunk/kernel/time/jiffies.c index a99b2a6e6a07..126bb30c4afe 100644 --- a/trunk/kernel/time/jiffies.c +++ b/trunk/kernel/time/jiffies.c @@ -57,7 +57,7 @@ static cycle_t jiffies_read(void) struct clocksource clocksource_jiffies = { .name = "jiffies", - .rating = 1, /* lowest valid rating*/ + .rating = 0, /* lowest rating*/ .read = jiffies_read, .mask = 0xffffffff, /*32bits*/ .mult = NSEC_PER_JIFFY << JIFFIES_SHIFT, /* details above */ diff --git a/trunk/kernel/time/ntp.c b/trunk/kernel/time/ntp.c index 3afeaa3a73f9..47195fa0ec4f 100644 --- a/trunk/kernel/time/ntp.c +++ b/trunk/kernel/time/ntp.c @@ -161,9 +161,9 @@ void second_overflow(void) time_adjust += MAX_TICKADJ; tick_length -= MAX_TICKADJ_SCALED; } else { + time_adjust = 0; tick_length += (s64)(time_adjust * NSEC_PER_USEC / HZ) << TICK_LENGTH_SHIFT; - time_adjust = 0; } } } diff --git a/trunk/kernel/tsacct.c b/trunk/kernel/tsacct.c index 96f77013d3f0..db443221ba5b 100644 --- a/trunk/kernel/tsacct.c +++ b/trunk/kernel/tsacct.c @@ -36,7 +36,7 @@ void bacct_add_tsk(struct taskstats *stats, struct task_struct *tsk) /* calculate task elapsed time in timespec */ do_posix_clock_monotonic_gettime(&uptime); - ts = timespec_sub(uptime, tsk->start_time); + ts = timespec_sub(uptime, current->group_leader->start_time); /* rebase elapsed time to usec */ ac_etime = timespec_to_ns(&ts); do_div(ac_etime, NSEC_PER_USEC); @@ -58,10 +58,7 @@ void bacct_add_tsk(struct taskstats *stats, struct task_struct *tsk) stats->ac_uid = tsk->uid; stats->ac_gid = tsk->gid; stats->ac_pid = tsk->pid; - rcu_read_lock(); - stats->ac_ppid = pid_alive(tsk) ? - rcu_dereference(tsk->real_parent)->tgid : 0; - rcu_read_unlock(); + stats->ac_ppid = (tsk->parent) ? tsk->parent->pid : 0; stats->ac_utime = cputime_to_msecs(tsk->utime) * USEC_PER_MSEC; stats->ac_stime = cputime_to_msecs(tsk->stime) * USEC_PER_MSEC; stats->ac_minflt = tsk->min_flt; @@ -80,17 +77,13 @@ void bacct_add_tsk(struct taskstats *stats, struct task_struct *tsk) */ void xacct_add_tsk(struct taskstats *stats, struct task_struct *p) { - struct mm_struct *mm; - /* convert pages-jiffies to Mbyte-usec */ stats->coremem = jiffies_to_usecs(p->acct_rss_mem1) * PAGE_SIZE / MB; stats->virtmem = jiffies_to_usecs(p->acct_vm_mem1) * PAGE_SIZE / MB; - mm = get_task_mm(p); - if (mm) { + if (p->mm) { /* adjust to KB unit */ - stats->hiwater_rss = mm->hiwater_rss * PAGE_SIZE / KB; - stats->hiwater_vm = mm->hiwater_vm * PAGE_SIZE / KB; - mmput(mm); + stats->hiwater_rss = p->mm->hiwater_rss * PAGE_SIZE / KB; + stats->hiwater_vm = p->mm->hiwater_vm * PAGE_SIZE / KB; } stats->read_char = p->rchar; stats->write_char = p->wchar; diff --git a/trunk/kernel/unwind.c b/trunk/kernel/unwind.c index ed0a21d4a902..2e2368607aab 100644 --- a/trunk/kernel/unwind.c +++ b/trunk/kernel/unwind.c @@ -11,15 +11,13 @@ #include #include -#include -#include +#include #include #include #include #include extern char __start_unwind[], __end_unwind[]; -extern const u8 __start_unwind_hdr[], __end_unwind_hdr[]; #define MAX_STACK_DEPTH 8 @@ -102,8 +100,6 @@ static struct unwind_table { } core, init; const void *address; unsigned long size; - const unsigned char *header; - unsigned long hdrsz; struct unwind_table *link; const char *name; } root_table; @@ -149,10 +145,6 @@ static struct unwind_table *find_table(unsigned long pc) return table; } -static unsigned long read_pointer(const u8 **pLoc, - const void *end, - signed ptrType); - static void init_unwind_table(struct unwind_table *table, const char *name, const void *core_start, @@ -160,30 +152,14 @@ static void init_unwind_table(struct unwind_table *table, const void *init_start, unsigned long init_size, const void *table_start, - unsigned long table_size, - const u8 *header_start, - unsigned long header_size) + unsigned long table_size) { - const u8 *ptr = header_start + 4; - const u8 *end = header_start + header_size; - table->core.pc = (unsigned long)core_start; table->core.range = core_size; table->init.pc = (unsigned long)init_start; table->init.range = init_size; table->address = table_start; table->size = table_size; - /* See if the linker provided table looks valid. */ - if (header_size <= 4 - || header_start[0] != 1 - || (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(); - table->header = header_start; table->link = NULL; table->name = name; } @@ -193,143 +169,7 @@ void __init unwind_init(void) init_unwind_table(&root_table, "kernel", _text, _end - _text, NULL, 0, - __start_unwind, __end_unwind - __start_unwind, - __start_unwind_hdr, __end_unwind_hdr - __start_unwind_hdr); -} - -static const u32 bad_cie, not_fde; -static const u32 *cie_for_fde(const u32 *fde, const struct unwind_table *); -static signed fde_pointer_type(const u32 *cie); - -struct eh_frame_hdr_table_entry { - unsigned long start, fde; -}; - -static int cmp_eh_frame_hdr_table_entries(const void *p1, const void *p2) -{ - const struct eh_frame_hdr_table_entry *e1 = p1; - const struct eh_frame_hdr_table_entry *e2 = p2; - - return (e1->start > e2->start) - (e1->start < e2->start); -} - -static void swap_eh_frame_hdr_table_entries(void *p1, void *p2, int size) -{ - struct eh_frame_hdr_table_entry *e1 = p1; - struct eh_frame_hdr_table_entry *e2 = p2; - unsigned long v; - - v = e1->start; - e1->start = e2->start; - e2->start = v; - v = e1->fde; - e1->fde = e2->fde; - e2->fde = v; -} - -static void __init setup_unwind_table(struct unwind_table *table, - void *(*alloc)(unsigned long)) -{ - const u8 *ptr; - unsigned long tableSize = table->size, hdrSize; - unsigned n; - const u32 *fde; - struct { - u8 version; - u8 eh_frame_ptr_enc; - u8 fde_count_enc; - u8 table_enc; - unsigned long eh_frame_ptr; - unsigned int fde_count; - struct eh_frame_hdr_table_entry table[]; - } __attribute__((__packed__)) *header; - - if (table->header) - return; - - if (table->hdrsz) - printk(KERN_WARNING ".eh_frame_hdr for '%s' present but unusable\n", - table->name); - - if (tableSize & (sizeof(*fde) - 1)) - return; - - for (fde = table->address, n = 0; - tableSize > sizeof(*fde) && tableSize - sizeof(*fde) >= *fde; - tableSize -= sizeof(*fde) + *fde, fde += 1 + *fde / sizeof(*fde)) { - const u32 *cie = cie_for_fde(fde, table); - signed ptrType; - - if (cie == ¬_fde) - continue; - if (cie == NULL - || cie == &bad_cie - || (ptrType = fde_pointer_type(cie)) < 0) - return; - ptr = (const u8 *)(fde + 2); - if (!read_pointer(&ptr, - (const u8 *)(fde + 1) + *fde, - ptrType)) - return; - ++n; - } - - if (tableSize || !n) - return; - - hdrSize = 4 + sizeof(unsigned long) + sizeof(unsigned int) - + 2 * n * sizeof(unsigned long); - header = alloc(hdrSize); - if (!header) - return; - header->version = 1; - header->eh_frame_ptr_enc = DW_EH_PE_abs|DW_EH_PE_native; - header->fde_count_enc = DW_EH_PE_abs|DW_EH_PE_data4; - header->table_enc = DW_EH_PE_abs|DW_EH_PE_native; - put_unaligned((unsigned long)table->address, &header->eh_frame_ptr); - BUILD_BUG_ON(offsetof(typeof(*header), fde_count) - % __alignof(typeof(header->fde_count))); - header->fde_count = n; - - BUILD_BUG_ON(offsetof(typeof(*header), table) - % __alignof(typeof(*header->table))); - for (fde = table->address, tableSize = table->size, n = 0; - tableSize; - tableSize -= sizeof(*fde) + *fde, fde += 1 + *fde / sizeof(*fde)) { - const u32 *cie = fde + 1 - fde[1] / sizeof(*fde); - - if (!fde[1]) - continue; /* this is a CIE */ - ptr = (const u8 *)(fde + 2); - header->table[n].start = read_pointer(&ptr, - (const u8 *)(fde + 1) + *fde, - fde_pointer_type(cie)); - header->table[n].fde = (unsigned long)fde; - ++n; - } - WARN_ON(n != header->fde_count); - - sort(header->table, - n, - sizeof(*header->table), - cmp_eh_frame_hdr_table_entries, - swap_eh_frame_hdr_table_entries); - - table->hdrsz = hdrSize; - smp_wmb(); - table->header = (const void *)header; -} - -static void *__init balloc(unsigned long sz) -{ - return __alloc_bootmem_nopanic(sz, - sizeof(unsigned int), - __pa(MAX_DMA_ADDRESS)); -} - -void __init unwind_setup(void) -{ - setup_unwind_table(&root_table, balloc); + __start_unwind, __end_unwind - __start_unwind); } #ifdef CONFIG_MODULES @@ -353,8 +193,7 @@ void *unwind_add_table(struct module *module, init_unwind_table(table, module->name, module->module_core, module->core_size, module->module_init, module->init_size, - table_start, table_size, - NULL, 0); + table_start, table_size); if (last_table) last_table->link = table; @@ -464,26 +303,6 @@ static sleb128_t get_sleb128(const u8 **pcur, const u8 *end) return value; } -static const u32 *cie_for_fde(const u32 *fde, const struct unwind_table *table) -{ - const u32 *cie; - - if (!*fde || (*fde & (sizeof(*fde) - 1))) - return &bad_cie; - if (!fde[1]) - return ¬_fde; /* this is a CIE */ - if ((fde[1] & (sizeof(*fde) - 1)) - || fde[1] > (unsigned long)(fde + 1) - (unsigned long)table->address) - return NULL; /* this is not a valid FDE */ - cie = fde + 1 - fde[1] / sizeof(*fde); - if (*cie <= sizeof(*cie) + 4 - || *cie >= fde[1] - sizeof(*fde) - || (*cie & (sizeof(*cie) - 1)) - || cie[1]) - return NULL; /* this is not a (valid) CIE */ - return cie; -} - static unsigned long read_pointer(const u8 **pLoc, const void *end, signed ptrType) @@ -791,108 +610,49 @@ int unwind(struct unwind_frame_info *frame) unsigned i; signed ptrType = -1; uleb128_t retAddrReg = 0; - const struct unwind_table *table; + struct unwind_table *table; struct unwind_state state; if (UNW_PC(frame) == 0) return -EINVAL; if ((table = find_table(pc)) != NULL && !(table->size & (sizeof(*fde) - 1))) { - const u8 *hdr = table->header; - unsigned long tableSize; - - smp_rmb(); - if (hdr && hdr[0] == 1) { - switch(hdr[3] & DW_EH_PE_FORM) { - case DW_EH_PE_native: tableSize = sizeof(unsigned long); break; - case DW_EH_PE_data2: tableSize = 2; break; - case DW_EH_PE_data4: tableSize = 4; break; - case DW_EH_PE_data8: tableSize = 8; break; - default: tableSize = 0; break; - } - ptr = hdr + 4; - end = hdr + table->hdrsz; - if (tableSize - && read_pointer(&ptr, end, hdr[1]) - == (unsigned long)table->address - && (i = read_pointer(&ptr, end, hdr[2])) > 0 - && i == (end - ptr) / (2 * tableSize) - && !((end - ptr) % (2 * tableSize))) { - do { - const u8 *cur = ptr + (i / 2) * (2 * tableSize); - - startLoc = read_pointer(&cur, - cur + tableSize, - hdr[3]); - if (pc < startLoc) - i /= 2; - else { - ptr = cur - tableSize; - i = (i + 1) / 2; - } - } while (startLoc && i > 1); - if (i == 1 - && (startLoc = read_pointer(&ptr, - ptr + tableSize, - hdr[3])) != 0 - && pc >= startLoc) - fde = (void *)read_pointer(&ptr, - ptr + tableSize, - hdr[3]); - } - } + unsigned long tableSize = table->size; - if (fde != NULL) { - cie = cie_for_fde(fde, table); - ptr = (const u8 *)(fde + 2); - if(cie != NULL - && cie != &bad_cie - && cie != ¬_fde - && (ptrType = fde_pointer_type(cie)) >= 0 - && read_pointer(&ptr, - (const u8 *)(fde + 1) + *fde, - 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); - if(pc >= endLoc) - fde = NULL; - } else - fde = NULL; - } - if (fde == NULL) { - for (fde = table->address, tableSize = table->size; - cie = NULL, tableSize > sizeof(*fde) - && tableSize - sizeof(*fde) >= *fde; - tableSize -= sizeof(*fde) + *fde, - fde += 1 + *fde / sizeof(*fde)) { - cie = cie_for_fde(fde, table); - if (cie == &bad_cie) { - cie = NULL; - break; - } - if (cie == NULL - || cie == ¬_fde - || (ptrType = fde_pointer_type(cie)) < 0) - continue; - ptr = (const u8 *)(fde + 2); - startLoc = read_pointer(&ptr, - (const u8 *)(fde + 1) + *fde, - ptrType); - if (!startLoc) - continue; - 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); - if (pc >= startLoc && pc < endLoc) - break; + for (fde = table->address; + tableSize > sizeof(*fde) && tableSize - sizeof(*fde) >= *fde; + tableSize -= sizeof(*fde) + *fde, + fde += 1 + *fde / sizeof(*fde)) { + if (!*fde || (*fde & (sizeof(*fde) - 1))) + break; + if (!fde[1]) + continue; /* this is a CIE */ + if ((fde[1] & (sizeof(*fde) - 1)) + || fde[1] > (unsigned long)(fde + 1) + - (unsigned long)table->address) + continue; /* this is not a valid FDE */ + cie = fde + 1 - fde[1] / sizeof(*fde); + if (*cie <= sizeof(*cie) + 4 + || *cie >= fde[1] - sizeof(*fde) + || (*cie & (sizeof(*cie) - 1)) + || cie[1] + || (ptrType = fde_pointer_type(cie)) < 0) { + cie = NULL; /* this is not a (valid) CIE */ + continue; } + ptr = (const u8 *)(fde + 2); + startLoc = read_pointer(&ptr, + (const u8 *)(fde + 1) + *fde, + ptrType); + endLoc = startLoc + + read_pointer(&ptr, + (const u8 *)(fde + 1) + *fde, + ptrType & DW_EH_PE_indirect + ? ptrType + : ptrType & (DW_EH_PE_FORM|DW_EH_PE_signed)); + if (pc >= startLoc && pc < endLoc) + break; + cie = NULL; } } if (cie != NULL) { @@ -938,11 +698,8 @@ int unwind(struct unwind_frame_info *frame) else { retAddrReg = state.version <= 1 ? *ptr++ : get_uleb128(&ptr, end); /* skip augmentation */ - if (((const char *)(cie + 2))[1] == 'z') { - uleb128_t augSize = get_uleb128(&ptr, end); - - ptr += augSize; - } + if (((const char *)(cie + 2))[1] == 'z') + ptr += get_uleb128(&ptr, end); if (ptr > end || retAddrReg >= ARRAY_SIZE(reg_info) || REG_INVALID(retAddrReg) @@ -966,7 +723,9 @@ int unwind(struct unwind_frame_info *frame) if (cie == NULL || fde == NULL) { #ifdef CONFIG_FRAME_POINTER unsigned long top, bottom; +#endif +#ifdef CONFIG_FRAME_POINTER top = STACK_TOP(frame->task); bottom = STACK_BOTTOM(frame->task); # if FRAME_RETADDR_OFFSET < 0 diff --git a/trunk/kernel/user.c b/trunk/kernel/user.c index 220e586127a0..6408c0424291 100644 --- a/trunk/kernel/user.c +++ b/trunk/kernel/user.c @@ -187,17 +187,6 @@ void switch_uid(struct user_struct *new_user) atomic_dec(&old_user->processes); switch_uid_keyring(new_user); current->user = new_user; - - /* - * We need to synchronize with __sigqueue_alloc() - * doing a get_uid(p->user).. If that saw the old - * user value, we need to wait until it has exited - * its critical region before we can free the old - * structure. - */ - smp_mb(); - spin_unlock_wait(¤t->sighand->siglock); - free_uid(old_user); suid_keys(current); } diff --git a/trunk/kernel/workqueue.c b/trunk/kernel/workqueue.c index 17c2f03d2c27..cfc737bffe6d 100644 --- a/trunk/kernel/workqueue.c +++ b/trunk/kernel/workqueue.c @@ -28,7 +28,6 @@ #include #include #include -#include /* * The per-CPU workqueue (if single thread, we always use the first @@ -99,7 +98,7 @@ static void __queue_work(struct cpu_workqueue_struct *cwq, * @wq: workqueue to use * @work: work to queue * - * Returns 0 if @work was already on a queue, non-zero otherwise. + * Returns non-zero if it was successfully added. * * We queue the work to the CPU it was submitted, but there is no * guarantee that it will be processed by that CPU. @@ -138,7 +137,7 @@ static void delayed_work_timer_fn(unsigned long __data) * @work: work to queue * @delay: number of jiffies to wait before queueing * - * Returns 0 if @work was already on a queue, non-zero otherwise. + * Returns non-zero if it was successfully added. */ int fastcall queue_delayed_work(struct workqueue_struct *wq, struct work_struct *work, unsigned long delay) @@ -169,7 +168,7 @@ EXPORT_SYMBOL_GPL(queue_delayed_work); * @work: work to queue * @delay: number of jiffies to wait before queueing * - * Returns 0 if @work was already on a queue, non-zero otherwise. + * Returns non-zero if it was successfully added. */ int queue_delayed_work_on(int cpu, struct workqueue_struct *wq, struct work_struct *work, unsigned long delay) @@ -246,12 +245,6 @@ static int worker_thread(void *__cwq) sigprocmask(SIG_BLOCK, &blocked, NULL); flush_signals(current); - /* - * We inherited MPOL_INTERLEAVE from the booting kernel. - * Set MPOL_DEFAULT to insure node local allocations. - */ - numa_default_policy(); - /* SIG_IGN makes children autoreap: see do_notify_parent(). */ sa.sa.sa_handler = SIG_IGN; sa.sa.sa_flags = 0; diff --git a/trunk/lib/Kconfig.debug b/trunk/lib/Kconfig.debug index d3679103a8e4..756a908c441d 100644 --- a/trunk/lib/Kconfig.debug +++ b/trunk/lib/Kconfig.debug @@ -71,7 +71,7 @@ config LOG_BUF_SHIFT config DETECT_SOFTLOCKUP bool "Detect Soft Lockups" - depends on DEBUG_KERNEL && !S390 + depends on DEBUG_KERNEL default y help Say Y here to enable the kernel to detect "soft lockups", @@ -341,7 +341,7 @@ config FRAME_POINTER config UNWIND_INFO bool "Compile the kernel with frame unwind information" - depends on !IA64 && !PARISC && !ARM + depends on !IA64 && !PARISC depends on !MODULES || !(MIPS || PPC || SUPERH || V850) help If you say Y here the resulting kernel image will be slightly larger @@ -371,20 +371,6 @@ config FORCED_INLINING become the default in the future, until then this option is there to test gcc for this. -config HEADERS_CHECK - bool "Run 'make headers_check' when building vmlinux" - depends on !UML - help - This option will extract the user-visible kernel headers whenever - building the kernel, and will run basic sanity checks on them to - ensure that exported files do not attempt to include files which - were not exported, etc. - - If you're making modifications to header files which are - relevant for userspace, say 'Y', and check the headers - exported to $(INSTALL_HDR_PATH) (usually 'usr/include' in - your build tree), to make sure they're suitable. - config RCU_TORTURE_TEST tristate "torture tests for RCU" depends on DEBUG_KERNEL diff --git a/trunk/lib/Makefile b/trunk/lib/Makefile index cf98fabaa549..b0361756e22e 100644 --- a/trunk/lib/Makefile +++ b/trunk/lib/Makefile @@ -5,14 +5,14 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \ bust_spinlocks.o rbtree.o radix-tree.o dump_stack.o \ idr.o div64.o int_sqrt.o bitmap.o extable.o prio_tree.o \ - sha1.o irq_regs.o + sha1.o lib-$(CONFIG_MMU) += ioremap.o lib-$(CONFIG_SMP) += cpumask.o lib-y += kobject.o kref.o kobject_uevent.o klist.o -obj-y += sort.o parser.o halfmd4.o iomap_copy.o debug_locks.o random32.o +obj-y += sort.o parser.o halfmd4.o iomap_copy.o debug_locks.o ifeq ($(CONFIG_DEBUG_KOBJECT),y) CFLAGS_kobject.o += -DDEBUG diff --git a/trunk/lib/bitmap.c b/trunk/lib/bitmap.c index 037fa9aa2ed7..d71e38c54ea5 100644 --- a/trunk/lib/bitmap.c +++ b/trunk/lib/bitmap.c @@ -316,11 +316,10 @@ int bitmap_scnprintf(char *buf, unsigned int buflen, EXPORT_SYMBOL(bitmap_scnprintf); /** - * __bitmap_parse - convert an ASCII hex string into a bitmap. - * @buf: pointer to buffer containing string. - * @buflen: buffer size in bytes. If string is smaller than this + * bitmap_parse - convert an ASCII hex string into a bitmap. + * @ubuf: pointer to buffer in user space containing string. + * @ubuflen: buffer size in bytes. If string is smaller than this * then it must be terminated with a \0. - * @is_user: location of buffer, 0 indicates kernel space * @maskp: pointer to bitmap array that will contain result. * @nmaskbits: size of bitmap, in bits. * @@ -331,13 +330,11 @@ EXPORT_SYMBOL(bitmap_scnprintf); * characters and for grouping errors such as "1,,5", ",44", "," and "". * Leading and trailing whitespace accepted, but not embedded whitespace. */ -int __bitmap_parse(const char *buf, unsigned int buflen, - int is_user, unsigned long *maskp, - int nmaskbits) +int bitmap_parse(const char __user *ubuf, unsigned int ubuflen, + unsigned long *maskp, int nmaskbits) { int c, old_c, totaldigits, ndigits, nchunks, nbits; u32 chunk; - const char __user *ubuf = buf; bitmap_zero(maskp, nmaskbits); @@ -346,15 +343,11 @@ int __bitmap_parse(const char *buf, unsigned int buflen, chunk = ndigits = 0; /* Get the next chunk of the bitmap */ - while (buflen) { + while (ubuflen) { old_c = c; - if (is_user) { - if (__get_user(c, ubuf++)) - return -EFAULT; - } - else - c = *buf++; - buflen--; + if (get_user(c, ubuf++)) + return -EFAULT; + ubuflen--; if (isspace(c)) continue; @@ -395,36 +388,11 @@ int __bitmap_parse(const char *buf, unsigned int buflen, nbits += (nchunks == 1) ? nbits_to_hold_value(chunk) : CHUNKSZ; if (nbits > nmaskbits) return -EOVERFLOW; - } while (buflen && c == ','); + } while (ubuflen && c == ','); return 0; } -EXPORT_SYMBOL(__bitmap_parse); - -/** - * bitmap_parse_user() - * - * @ubuf: pointer to user buffer containing string. - * @ulen: buffer size in bytes. If string is smaller than this - * then it must be terminated with a \0. - * @maskp: pointer to bitmap array that will contain result. - * @nmaskbits: size of bitmap, in bits. - * - * Wrapper for __bitmap_parse(), providing it with user buffer. - * - * We cannot have this as an inline function in bitmap.h because it needs - * linux/uaccess.h to get the access_ok() declaration and this causes - * cyclic dependencies. - */ -int bitmap_parse_user(const char __user *ubuf, - unsigned int ulen, unsigned long *maskp, - int nmaskbits) -{ - if (!access_ok(VERIFY_READ, ubuf, ulen)) - return -EFAULT; - return __bitmap_parse((const char *)ubuf, ulen, 1, maskp, nmaskbits); -} -EXPORT_SYMBOL(bitmap_parse_user); +EXPORT_SYMBOL(bitmap_parse); /* * bscnl_emit(buf, buflen, rbot, rtop, bp) diff --git a/trunk/lib/cpumask.c b/trunk/lib/cpumask.c index 3a67dc5ada7d..7a2a73f88d59 100644 --- a/trunk/lib/cpumask.c +++ b/trunk/lib/cpumask.c @@ -43,3 +43,19 @@ int __any_online_cpu(const cpumask_t *mask) return cpu; } EXPORT_SYMBOL(__any_online_cpu); + +#if MAX_NUMNODES > 1 +/* + * Find the highest possible node id. + */ +int highest_possible_node_id(void) +{ + unsigned int node; + unsigned int highest = 0; + + for_each_node_mask(node, node_possible_map) + highest = node; + return highest; +} +EXPORT_SYMBOL(highest_possible_node_id); +#endif diff --git a/trunk/lib/irq_regs.c b/trunk/lib/irq_regs.c deleted file mode 100644 index 753880a5440c..000000000000 --- a/trunk/lib/irq_regs.c +++ /dev/null @@ -1,17 +0,0 @@ -/* saved per-CPU IRQ register pointer - * - * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. - * Written by David Howells (dhowells@redhat.com) - * - * 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 - -#ifndef ARCH_HAS_OWN_IRQ_REGS -DEFINE_PER_CPU(struct pt_regs *, __irq_regs); -EXPORT_PER_CPU_SYMBOL(__irq_regs); -#endif diff --git a/trunk/lib/kobject.c b/trunk/lib/kobject.c index 744a4b102c7f..1699eb9161f3 100644 --- a/trunk/lib/kobject.c +++ b/trunk/lib/kobject.c @@ -119,7 +119,6 @@ char *kobject_get_path(struct kobject *kobj, gfp_t gfp_mask) return path; } -EXPORT_SYMBOL_GPL(kobject_get_path); /** * kobject_init - initialize object. @@ -310,56 +309,6 @@ int kobject_rename(struct kobject * kobj, const char *new_name) return error; } -/** - * kobject_move - move object to another parent - * @kobj: object in question. - * @new_parent: object's new parent - */ - -int kobject_move(struct kobject *kobj, struct kobject *new_parent) -{ - int error; - struct kobject *old_parent; - const char *devpath = NULL; - char *devpath_string = NULL; - char *envp[2]; - - kobj = kobject_get(kobj); - if (!kobj) - return -EINVAL; - new_parent = kobject_get(new_parent); - if (!new_parent) { - error = -EINVAL; - goto out; - } - /* old object path */ - devpath = kobject_get_path(kobj, GFP_KERNEL); - if (!devpath) { - error = -ENOMEM; - goto out; - } - devpath_string = kmalloc(strlen(devpath) + 15, GFP_KERNEL); - if (!devpath_string) { - error = -ENOMEM; - goto out; - } - sprintf(devpath_string, "DEVPATH_OLD=%s", devpath); - envp[0] = devpath_string; - envp[1] = NULL; - error = sysfs_move_dir(kobj, new_parent); - if (error) - goto out; - old_parent = kobj->parent; - kobj->parent = new_parent; - kobject_put(old_parent); - kobject_uevent_env(kobj, KOBJ_MOVE, envp); -out: - kobject_put(kobj); - kfree(devpath_string); - kfree(devpath); - return error; -} - /** * kobject_del - unlink kobject from hierarchy. * @kobj: object. diff --git a/trunk/lib/kobject_uevent.c b/trunk/lib/kobject_uevent.c index a1922765ff31..7f20e7b857cb 100644 --- a/trunk/lib/kobject_uevent.c +++ b/trunk/lib/kobject_uevent.c @@ -50,22 +50,18 @@ static char *action_to_string(enum kobject_action action) return "offline"; case KOBJ_ONLINE: return "online"; - case KOBJ_MOVE: - return "move"; default: return NULL; } } /** - * kobject_uevent_env - send an uevent with environmental data + * kobject_uevent - notify userspace by ending an uevent * - * @action: action that is happening (usually KOBJ_MOVE) + * @action: action that is happening (usually KOBJ_ADD and KOBJ_REMOVE) * @kobj: struct kobject that the action is happening to - * @envp_ext: pointer to environmental data */ -void kobject_uevent_env(struct kobject *kobj, enum kobject_action action, - char *envp_ext[]) +void kobject_uevent(struct kobject *kobj, enum kobject_action action) { char **envp; char *buffer; @@ -80,7 +76,6 @@ void kobject_uevent_env(struct kobject *kobj, enum kobject_action action, char *seq_buff; int i = 0; int retval; - int j; pr_debug("%s\n", __FUNCTION__); @@ -139,8 +134,7 @@ void kobject_uevent_env(struct kobject *kobj, enum kobject_action action, scratch += sprintf (scratch, "DEVPATH=%s", devpath) + 1; envp [i++] = scratch; scratch += sprintf(scratch, "SUBSYSTEM=%s", subsystem) + 1; - for (j = 0; envp_ext && envp_ext[j]; j++) - envp[i++] = envp_ext[j]; + /* just reserve the space, overwrite it after kset call has returned */ envp[i++] = seq_buff = scratch; scratch += strlen("SEQNUM=18446744073709551616") + 1; @@ -206,20 +200,6 @@ void kobject_uevent_env(struct kobject *kobj, enum kobject_action action, kfree(envp); return; } - -EXPORT_SYMBOL_GPL(kobject_uevent_env); - -/** - * kobject_uevent - notify userspace by ending an uevent - * - * @action: action that is happening (usually KOBJ_ADD and KOBJ_REMOVE) - * @kobj: struct kobject that the action is happening to - */ -void kobject_uevent(struct kobject *kobj, enum kobject_action action) -{ - kobject_uevent_env(kobj, action, NULL); -} - EXPORT_SYMBOL_GPL(kobject_uevent); /** diff --git a/trunk/lib/radix-tree.c b/trunk/lib/radix-tree.c index aa9bfd0bdbd1..637d55608de5 100644 --- a/trunk/lib/radix-tree.c +++ b/trunk/lib/radix-tree.c @@ -160,13 +160,13 @@ static inline int tag_get(struct radix_tree_node *node, unsigned int tag, static inline void root_tag_set(struct radix_tree_root *root, unsigned int tag) { - root->gfp_mask |= (__force gfp_t)(1 << (tag + __GFP_BITS_SHIFT)); + root->gfp_mask |= (1 << (tag + __GFP_BITS_SHIFT)); } static inline void root_tag_clear(struct radix_tree_root *root, unsigned int tag) { - root->gfp_mask &= (__force gfp_t)~(1 << (tag + __GFP_BITS_SHIFT)); + root->gfp_mask &= ~(1 << (tag + __GFP_BITS_SHIFT)); } static inline void root_tag_clear_all(struct radix_tree_root *root) @@ -176,7 +176,7 @@ static inline void root_tag_clear_all(struct radix_tree_root *root) static inline int root_tag_get(struct radix_tree_root *root, unsigned int tag) { - return (__force unsigned)root->gfp_mask & (1 << (tag + __GFP_BITS_SHIFT)); + return root->gfp_mask & (1 << (tag + __GFP_BITS_SHIFT)); } /* diff --git a/trunk/lib/random32.c b/trunk/lib/random32.c deleted file mode 100644 index 4a15ce51cea7..000000000000 --- a/trunk/lib/random32.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - This is a maximally equidistributed combined Tausworthe generator - based on code from GNU Scientific Library 1.5 (30 Jun 2004) - - x_n = (s1_n ^ s2_n ^ s3_n) - - s1_{n+1} = (((s1_n & 4294967294) <<12) ^ (((s1_n <<13) ^ s1_n) >>19)) - s2_{n+1} = (((s2_n & 4294967288) << 4) ^ (((s2_n << 2) ^ s2_n) >>25)) - s3_{n+1} = (((s3_n & 4294967280) <<17) ^ (((s3_n << 3) ^ s3_n) >>11)) - - The period of this generator is about 2^88. - - From: P. L'Ecuyer, "Maximally Equidistributed Combined Tausworthe - Generators", Mathematics of Computation, 65, 213 (1996), 203--213. - - This is available on the net from L'Ecuyer's home page, - - http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme.ps - ftp://ftp.iro.umontreal.ca/pub/simulation/lecuyer/papers/tausme.ps - - There is an erratum in the paper "Tables of Maximally - Equidistributed Combined LFSR Generators", Mathematics of - Computation, 68, 225 (1999), 261--269: - http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme2.ps - - ... the k_j most significant bits of z_j must be non- - zero, for each j. (Note: this restriction also applies to the - computer code given in [4], but was mistakenly not mentioned in - that paper.) - - This affects the seeding procedure by imposing the requirement - s1 > 1, s2 > 7, s3 > 15. - -*/ - -#include -#include -#include -#include - -struct rnd_state { - u32 s1, s2, s3; -}; - -static DEFINE_PER_CPU(struct rnd_state, net_rand_state); - -static u32 __random32(struct rnd_state *state) -{ -#define TAUSWORTHE(s,a,b,c,d) ((s&c)<>b) - - state->s1 = TAUSWORTHE(state->s1, 13, 19, 4294967294UL, 12); - state->s2 = TAUSWORTHE(state->s2, 2, 25, 4294967288UL, 4); - state->s3 = TAUSWORTHE(state->s3, 3, 11, 4294967280UL, 17); - - return (state->s1 ^ state->s2 ^ state->s3); -} - -static void __set_random32(struct rnd_state *state, unsigned long s) -{ - if (s == 0) - s = 1; /* default seed is 1 */ - -#define LCG(n) (69069 * n) - state->s1 = LCG(s); - state->s2 = LCG(state->s1); - state->s3 = LCG(state->s2); - - /* "warm it up" */ - __random32(state); - __random32(state); - __random32(state); - __random32(state); - __random32(state); - __random32(state); -} - -/** - * random32 - pseudo random number generator - * - * A 32 bit pseudo-random number is generated using a fast - * algorithm suitable for simulation. This algorithm is NOT - * considered safe for cryptographic use. - */ -u32 random32(void) -{ - unsigned long r; - struct rnd_state *state = &get_cpu_var(net_rand_state); - r = __random32(state); - put_cpu_var(state); - return r; -} -EXPORT_SYMBOL(random32); - -/** - * srandom32 - add entropy to pseudo random number generator - * @seed: seed value - * - * Add some additional seeding to the random32() pool. - * Note: this pool is per cpu so it only affects current CPU. - */ -void srandom32(u32 entropy) -{ - struct rnd_state *state = &get_cpu_var(net_rand_state); - __set_random32(state, state->s1 ^ entropy); - put_cpu_var(state); -} -EXPORT_SYMBOL(srandom32); - -/* - * Generate some initially weak seeding values to allow - * to start the random32() engine. - */ -static int __init random32_init(void) -{ - int i; - - for_each_possible_cpu(i) { - struct rnd_state *state = &per_cpu(net_rand_state,i); - __set_random32(state, i + jiffies); - } - return 0; -} -core_initcall(random32_init); - -/* - * Generate better values after random number generator - * is fully initalized. - */ -static int __init random32_reseed(void) -{ - int i; - unsigned long seed; - - for_each_possible_cpu(i) { - struct rnd_state *state = &per_cpu(net_rand_state,i); - - get_random_bytes(&seed, sizeof(seed)); - __set_random32(state, seed); - } - return 0; -} -late_initcall(random32_reseed); diff --git a/trunk/lib/rwsem-spinlock.c b/trunk/lib/rwsem-spinlock.c index c4cfd6c0342f..db4fed74b940 100644 --- a/trunk/lib/rwsem-spinlock.c +++ b/trunk/lib/rwsem-spinlock.c @@ -28,7 +28,7 @@ void __init_rwsem(struct rw_semaphore *sem, const char *name, * Make sure we are not reinitializing a held semaphore: */ debug_check_no_locks_freed((void *)sem, sizeof(*sem)); - lockdep_init_map(&sem->dep_map, name, key, 0); + lockdep_init_map(&sem->dep_map, name, key); #endif sem->activity = 0; spin_lock_init(&sem->wait_lock); diff --git a/trunk/lib/rwsem.c b/trunk/lib/rwsem.c index cdb4e3d05607..901d0e7da892 100644 --- a/trunk/lib/rwsem.c +++ b/trunk/lib/rwsem.c @@ -19,7 +19,7 @@ void __init_rwsem(struct rw_semaphore *sem, const char *name, * Make sure we are not reinitializing a held semaphore: */ debug_check_no_locks_freed((void *)sem, sizeof(*sem)); - lockdep_init_map(&sem->dep_map, name, key, 0); + lockdep_init_map(&sem->dep_map, name, key); #endif sem->count = RWSEM_UNLOCKED_VALUE; spin_lock_init(&sem->wait_lock); diff --git a/trunk/lib/spinlock_debug.c b/trunk/lib/spinlock_debug.c index b6c4f898197c..dafaf1de2491 100644 --- a/trunk/lib/spinlock_debug.c +++ b/trunk/lib/spinlock_debug.c @@ -20,7 +20,7 @@ void __spin_lock_init(spinlock_t *lock, const char *name, * Make sure we are not reinitializing a held lock: */ debug_check_no_locks_freed((void *)lock, sizeof(*lock)); - lockdep_init_map(&lock->dep_map, name, key, 0); + lockdep_init_map(&lock->dep_map, name, key); #endif lock->raw_lock = (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; lock->magic = SPINLOCK_MAGIC; @@ -38,7 +38,7 @@ void __rwlock_init(rwlock_t *lock, const char *name, * Make sure we are not reinitializing a held lock: */ debug_check_no_locks_freed((void *)lock, sizeof(*lock)); - lockdep_init_map(&lock->dep_map, name, key, 0); + lockdep_init_map(&lock->dep_map, name, key); #endif lock->raw_lock = (raw_rwlock_t) __RAW_RW_LOCK_UNLOCKED; lock->magic = RWLOCK_MAGIC; diff --git a/trunk/lib/string.c b/trunk/lib/string.c index a485d75962af..63077267367e 100644 --- a/trunk/lib/string.c +++ b/trunk/lib/string.c @@ -320,7 +320,7 @@ char *strstrip(char *s) return s; end = s + size - 1; - while (end >= s && isspace(*end)) + while (end != s && isspace(*end)) end--; *(end + 1) = '\0'; diff --git a/trunk/lib/textsearch.c b/trunk/lib/textsearch.c index 98bcadc01185..2cb4a437942e 100644 --- a/trunk/lib/textsearch.c +++ b/trunk/lib/textsearch.c @@ -40,7 +40,7 @@ * configuration according to the specified parameters. * (3) User starts the search(es) by calling _find() or _next() to * fetch subsequent occurrences. A state variable is provided - * to the algorihtm to store persistent variables. + * to the algorihtm to store persistant variables. * (4) Core eventually resets the search offset and forwards the find() * request to the algorithm. * (5) Algorithm calls get_next_block() provided by the user continously diff --git a/trunk/mm/Makefile b/trunk/mm/Makefile index f3c077eb0b8e..12b3a4eee88d 100644 --- a/trunk/mm/Makefile +++ b/trunk/mm/Makefile @@ -10,8 +10,7 @@ mmu-$(CONFIG_MMU) := fremap.o highmem.o madvise.o memory.o mincore.o \ obj-y := bootmem.o filemap.o mempool.o oom_kill.o fadvise.o \ page_alloc.o page-writeback.o pdflush.o \ readahead.o swap.o truncate.o vmscan.o \ - prio_tree.o util.o mmzone.o vmstat.o backing-dev.o \ - $(mmu-y) + prio_tree.o util.o mmzone.o vmstat.o $(mmu-y) ifeq ($(CONFIG_MMU)$(CONFIG_BLOCK),yy) obj-y += bounce.o diff --git a/trunk/mm/backing-dev.c b/trunk/mm/backing-dev.c deleted file mode 100644 index f50a2811f9dc..000000000000 --- a/trunk/mm/backing-dev.c +++ /dev/null @@ -1,69 +0,0 @@ - -#include -#include -#include -#include -#include - -static wait_queue_head_t congestion_wqh[2] = { - __WAIT_QUEUE_HEAD_INITIALIZER(congestion_wqh[0]), - __WAIT_QUEUE_HEAD_INITIALIZER(congestion_wqh[1]) - }; - - -void clear_bdi_congested(struct backing_dev_info *bdi, int rw) -{ - enum bdi_state bit; - wait_queue_head_t *wqh = &congestion_wqh[rw]; - - bit = (rw == WRITE) ? BDI_write_congested : BDI_read_congested; - clear_bit(bit, &bdi->state); - smp_mb__after_clear_bit(); - if (waitqueue_active(wqh)) - wake_up(wqh); -} -EXPORT_SYMBOL(clear_bdi_congested); - -void set_bdi_congested(struct backing_dev_info *bdi, int rw) -{ - enum bdi_state bit; - - bit = (rw == WRITE) ? BDI_write_congested : BDI_read_congested; - set_bit(bit, &bdi->state); -} -EXPORT_SYMBOL(set_bdi_congested); - -/** - * congestion_wait - wait for a backing_dev to become uncongested - * @rw: READ or WRITE - * @timeout: timeout in jiffies - * - * Waits for up to @timeout jiffies for a backing_dev (any backing_dev) to exit - * write congestion. If no backing_devs are congested then just wait for the - * next write to be completed. - */ -long congestion_wait(int rw, long timeout) -{ - long ret; - DEFINE_WAIT(wait); - wait_queue_head_t *wqh = &congestion_wqh[rw]; - - prepare_to_wait(wqh, &wait, TASK_UNINTERRUPTIBLE); - ret = io_schedule_timeout(timeout); - finish_wait(wqh, &wait); - return ret; -} -EXPORT_SYMBOL(congestion_wait); - -/** - * congestion_end - wake up sleepers on a congested backing_dev_info - * @rw: READ or WRITE - */ -void congestion_end(int rw) -{ - wait_queue_head_t *wqh = &congestion_wqh[rw]; - - if (waitqueue_active(wqh)) - wake_up(wqh); -} -EXPORT_SYMBOL(congestion_end); diff --git a/trunk/mm/filemap.c b/trunk/mm/filemap.c index 7b84dc814347..3464b681f844 100644 --- a/trunk/mm/filemap.c +++ b/trunk/mm/filemap.c @@ -75,8 +75,8 @@ generic_file_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, * ->mmap_sem * ->lock_page (access_process_vm) * - * ->i_mutex (generic_file_buffered_write) - * ->mmap_sem (fault_in_pages_readable->do_page_fault) + * ->mmap_sem + * ->i_mutex (msync) * * ->i_mutex * ->i_alloc_sem (various) @@ -467,15 +467,25 @@ int add_to_page_cache_lru(struct page *page, struct address_space *mapping, } #ifdef CONFIG_NUMA -struct page *__page_cache_alloc(gfp_t gfp) +struct page *page_cache_alloc(struct address_space *x) { if (cpuset_do_page_mem_spread()) { int n = cpuset_mem_spread_node(); - return alloc_pages_node(n, gfp, 0); + return alloc_pages_node(n, mapping_gfp_mask(x), 0); } - return alloc_pages(gfp, 0); + return alloc_pages(mapping_gfp_mask(x), 0); } -EXPORT_SYMBOL(__page_cache_alloc); +EXPORT_SYMBOL(page_cache_alloc); + +struct page *page_cache_alloc_cold(struct address_space *x) +{ + if (cpuset_do_page_mem_spread()) { + int n = cpuset_mem_spread_node(); + return alloc_pages_node(n, mapping_gfp_mask(x)|__GFP_COLD, 0); + } + return alloc_pages(mapping_gfp_mask(x)|__GFP_COLD, 0); +} +EXPORT_SYMBOL(page_cache_alloc_cold); #endif static int __sleep_on_page_lock(void *word) @@ -816,6 +826,7 @@ struct page * grab_cache_page_nowait(struct address_space *mapping, unsigned long index) { struct page *page = find_get_page(mapping, index); + gfp_t gfp_mask; if (page) { if (!TestSetPageLocked(page)) @@ -823,8 +834,9 @@ grab_cache_page_nowait(struct address_space *mapping, unsigned long index) page_cache_release(page); return NULL; } - page = __page_cache_alloc(mapping_gfp_mask(mapping) & ~__GFP_FS); - if (page && add_to_page_cache_lru(page, mapping, index, GFP_KERNEL)) { + gfp_mask = mapping_gfp_mask(mapping) & ~__GFP_FS; + page = alloc_pages(gfp_mask, 0); + if (page && add_to_page_cache_lru(page, mapping, index, gfp_mask)) { page_cache_release(page); page = NULL; } @@ -1872,10 +1884,11 @@ __grab_cache_page(struct address_space *mapping, unsigned long index, * if suid or (sgid and xgrp) * remove privs */ -int should_remove_suid(struct dentry *dentry) +int remove_suid(struct dentry *dentry) { mode_t mode = dentry->d_inode->i_mode; int kill = 0; + int result = 0; /* suid always must be killed */ if (unlikely(mode & S_ISUID)) @@ -1888,28 +1901,13 @@ int should_remove_suid(struct dentry *dentry) if (unlikely((mode & S_ISGID) && (mode & S_IXGRP))) kill |= ATTR_KILL_SGID; - if (unlikely(kill && !capable(CAP_FSETID))) - return kill; - - return 0; -} - -int __remove_suid(struct dentry *dentry, int kill) -{ - struct iattr newattrs; - - newattrs.ia_valid = ATTR_FORCE | kill; - return notify_change(dentry, &newattrs); -} - -int remove_suid(struct dentry *dentry) -{ - int kill = should_remove_suid(dentry); - - if (unlikely(kill)) - return __remove_suid(dentry, kill); + if (unlikely(kill && !capable(CAP_FSETID))) { + struct iattr newattrs; - return 0; + newattrs.ia_valid = ATTR_FORCE | kill; + result = notify_change(dentry, &newattrs); + } + return result; } EXPORT_SYMBOL(remove_suid); @@ -2224,7 +2222,7 @@ __generic_file_aio_write_nolock(struct kiocb *iocb, const struct iovec *iov, unsigned long nr_segs, loff_t *ppos) { struct file *file = iocb->ki_filp; - struct address_space * mapping = file->f_mapping; + const struct address_space * mapping = file->f_mapping; size_t ocount; /* original count */ size_t count; /* after file limit checks */ struct inode *inode = mapping->host; @@ -2277,11 +2275,8 @@ __generic_file_aio_write_nolock(struct kiocb *iocb, const struct iovec *iov, /* coalesce the iovecs and go direct-to-BIO for O_DIRECT */ if (unlikely(file->f_flags & O_DIRECT)) { - loff_t endbyte; - ssize_t written_buffered; - - written = generic_file_direct_write(iocb, iov, &nr_segs, pos, - ppos, count, ocount); + written = generic_file_direct_write(iocb, iov, + &nr_segs, pos, ppos, count, ocount); if (written < 0 || written == count) goto out; /* @@ -2290,46 +2285,10 @@ __generic_file_aio_write_nolock(struct kiocb *iocb, const struct iovec *iov, */ pos += written; count -= written; - written_buffered = generic_file_buffered_write(iocb, iov, - nr_segs, pos, ppos, count, - written); - /* - * If generic_file_buffered_write() retuned a synchronous error - * then we want to return the number of bytes which were - * direct-written, or the error code if that was zero. Note - * that this differs from normal direct-io semantics, which - * will return -EFOO even if some bytes were written. - */ - if (written_buffered < 0) { - err = written_buffered; - goto out; - } - - /* - * We need to ensure that the page cache pages are written to - * disk and invalidated to preserve the expected O_DIRECT - * semantics. - */ - endbyte = pos + written_buffered - written - 1; - err = do_sync_file_range(file, pos, endbyte, - SYNC_FILE_RANGE_WAIT_BEFORE| - SYNC_FILE_RANGE_WRITE| - SYNC_FILE_RANGE_WAIT_AFTER); - if (err == 0) { - written = written_buffered; - invalidate_mapping_pages(mapping, - pos >> PAGE_CACHE_SHIFT, - endbyte >> PAGE_CACHE_SHIFT); - } else { - /* - * We don't know how much we wrote, so just return - * the number of bytes which were direct-written - */ - } - } else { - written = generic_file_buffered_write(iocb, iov, nr_segs, - pos, ppos, count, written); } + + written = generic_file_buffered_write(iocb, iov, nr_segs, + pos, ppos, count, written); out: current->backing_dev_info = NULL; return written ? written : err; diff --git a/trunk/mm/hugetlb.c b/trunk/mm/hugetlb.c index a088f593a807..1d709ff528e1 100644 --- a/trunk/mm/hugetlb.c +++ b/trunk/mm/hugetlb.c @@ -356,8 +356,8 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src, return -ENOMEM; } -void __unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start, - unsigned long end) +void unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start, + unsigned long end) { struct mm_struct *mm = vma->vm_mm; unsigned long address; @@ -398,24 +398,6 @@ void __unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start, } } -void unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start, - unsigned long end) -{ - /* - * It is undesirable to test vma->vm_file as it should be non-null - * for valid hugetlb area. However, vm_file will be NULL in the error - * cleanup path of do_mmap_pgoff. When hugetlbfs ->mmap method fails, - * do_mmap_pgoff() nullifies vma->vm_file before calling this function - * to clean up. Since no pte has actually been setup, it is safe to - * do nothing in this case. - */ - if (vma->vm_file) { - spin_lock(&vma->vm_file->f_mapping->i_mmap_lock); - __unmap_hugepage_range(vma, start, end); - spin_unlock(&vma->vm_file->f_mapping->i_mmap_lock); - } -} - static int hugetlb_cow(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long address, pte_t *ptep, pte_t pte) { @@ -478,9 +460,6 @@ int hugetlb_no_page(struct mm_struct *mm, struct vm_area_struct *vma, retry: page = find_lock_page(mapping, idx); if (!page) { - size = i_size_read(mapping->host) >> HPAGE_SHIFT; - if (idx >= size) - goto out; if (hugetlb_get_quota(mapping)) goto out; page = alloc_huge_page(vma, address); diff --git a/trunk/mm/memory.c b/trunk/mm/memory.c index 156861fcac43..9cf3f341a28a 100644 --- a/trunk/mm/memory.c +++ b/trunk/mm/memory.c @@ -1086,7 +1086,6 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, default: BUG(); } - cond_resched(); } if (pages) { pages[i] = page; @@ -1452,7 +1451,6 @@ static inline void cow_user_page(struct page *dst, struct page *src, unsigned lo if (__copy_from_user_inatomic(kaddr, uaddr, PAGE_SIZE)) memset(kaddr, 0, PAGE_SIZE); kunmap_atomic(kaddr, KM_USER0); - flush_dcache_page(dst); return; } @@ -2171,13 +2169,11 @@ static int do_no_page(struct mm_struct *mm, struct vm_area_struct *vma, * after the next truncate_count read. */ - /* no page was available -- either SIGBUS, OOM or REFAULT */ - if (unlikely(new_page == NOPAGE_SIGBUS)) + /* no page was available -- either SIGBUS or OOM */ + if (new_page == NOPAGE_SIGBUS) return VM_FAULT_SIGBUS; - else if (unlikely(new_page == NOPAGE_OOM)) + if (new_page == NOPAGE_OOM) return VM_FAULT_OOM; - else if (unlikely(new_page == NOPAGE_REFAULT)) - return VM_FAULT_MINOR; /* * Should we do an early C-O-W break? diff --git a/trunk/mm/mempolicy.c b/trunk/mm/mempolicy.c index 617fb31086ee..25788b1b7fcf 100644 --- a/trunk/mm/mempolicy.c +++ b/trunk/mm/mempolicy.c @@ -727,7 +727,7 @@ int do_migrate_pages(struct mm_struct *mm, return -ENOSYS; } -static struct page *new_vma_page(struct page *page, unsigned long private, int **x) +static struct page *new_vma_page(struct page *page, unsigned long private) { return NULL; } diff --git a/trunk/mm/migrate.c b/trunk/mm/migrate.c index b4979d423d2b..ba2453f9483d 100644 --- a/trunk/mm/migrate.c +++ b/trunk/mm/migrate.c @@ -952,8 +952,7 @@ asmlinkage long sys_move_pages(pid_t pid, unsigned long nr_pages, goto out; pm[i].node = node; - } else - pm[i].node = 0; /* anything to not match MAX_NUMNODES */ + } } /* End marker */ pm[nr_pages].node = MAX_NUMNODES; diff --git a/trunk/mm/mmap.c b/trunk/mm/mmap.c index 7b40abd7cba2..eea8eefd51a8 100644 --- a/trunk/mm/mmap.c +++ b/trunk/mm/mmap.c @@ -900,6 +900,17 @@ unsigned long do_mmap_pgoff(struct file * file, unsigned long addr, int accountable = 1; unsigned long charged = 0, reqprot = prot; + if (file) { + if (is_file_hugepages(file)) + accountable = 0; + + if (!file->f_op || !file->f_op->mmap) + return -ENODEV; + + if ((prot & PROT_EXEC) && + (file->f_vfsmnt->mnt_flags & MNT_NOEXEC)) + return -EPERM; + } /* * Does the application expect PROT_READ to imply PROT_EXEC? * @@ -989,16 +1000,6 @@ unsigned long do_mmap_pgoff(struct file * file, unsigned long addr, case MAP_PRIVATE: if (!(file->f_mode & FMODE_READ)) return -EACCES; - if (file->f_vfsmnt->mnt_flags & MNT_NOEXEC) { - if (vm_flags & VM_EXEC) - return -EPERM; - vm_flags &= ~VM_MAYEXEC; - } - if (is_file_hugepages(file)) - accountable = 0; - - if (!file->f_op || !file->f_op->mmap) - return -ENODEV; break; default: @@ -1379,7 +1380,7 @@ get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, * Check if the given range is hugepage aligned, and * can be made suitable for hugepages. */ - ret = prepare_hugepage_range(addr, len, pgoff); + ret = prepare_hugepage_range(addr, len); } else { /* * Ensure that a normal request is not falling in a @@ -1880,9 +1881,6 @@ unsigned long do_brk(unsigned long addr, unsigned long len) if ((addr + len) > TASK_SIZE || (addr + len) < addr) return -EINVAL; - if (is_hugepage_only_range(mm, addr, len)) - return -EINVAL; - flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags; error = arch_mmap_check(addr, len, flags); diff --git a/trunk/mm/oom_kill.c b/trunk/mm/oom_kill.c index 2e3ce3a928b9..20f41b082e16 100644 --- a/trunk/mm/oom_kill.c +++ b/trunk/mm/oom_kill.c @@ -15,7 +15,6 @@ * kernel subsystems and hints as to where to find out what things do. */ -#include #include #include #include diff --git a/trunk/mm/page-writeback.c b/trunk/mm/page-writeback.c index 8d9b19f239c3..a0f339057449 100644 --- a/trunk/mm/page-writeback.c +++ b/trunk/mm/page-writeback.c @@ -222,7 +222,7 @@ static void balance_dirty_pages(struct address_space *mapping) if (pages_written >= write_chunk) break; /* We've done our duty */ } - congestion_wait(WRITE, HZ/10); + blk_congestion_wait(WRITE, HZ/10); } if (nr_reclaimable + global_page_state(NR_WRITEBACK) @@ -314,7 +314,7 @@ void throttle_vm_writeout(void) if (global_page_state(NR_UNSTABLE_NFS) + global_page_state(NR_WRITEBACK) <= dirty_thresh) break; - congestion_wait(WRITE, HZ/10); + blk_congestion_wait(WRITE, HZ/10); } } @@ -351,7 +351,7 @@ static void background_writeout(unsigned long _min_pages) min_pages -= MAX_WRITEBACK_PAGES - wbc.nr_to_write; if (wbc.nr_to_write > 0 || wbc.pages_skipped > 0) { /* Wrote less than expected */ - congestion_wait(WRITE, HZ/10); + blk_congestion_wait(WRITE, HZ/10); if (!wbc.encountered_congestion) break; } @@ -422,7 +422,7 @@ static void wb_kupdate(unsigned long arg) writeback_inodes(&wbc); if (wbc.nr_to_write > 0) { if (wbc.encountered_congestion) - congestion_wait(WRITE, HZ/10); + blk_congestion_wait(WRITE, HZ/10); else break; /* All the old data is written */ } @@ -955,6 +955,15 @@ int test_set_page_writeback(struct page *page) } EXPORT_SYMBOL(test_set_page_writeback); +/* + * Wakes up tasks that are being throttled due to writeback congestion + */ +void writeback_congestion_end(void) +{ + blk_congestion_end(WRITE); +} +EXPORT_SYMBOL(writeback_congestion_end); + /* * Return true if any of the pages in the mapping are marged with the * passed tag. diff --git a/trunk/mm/page_alloc.c b/trunk/mm/page_alloc.c index aa6fcc7ca66f..a8c003e7b3d5 100644 --- a/trunk/mm/page_alloc.c +++ b/trunk/mm/page_alloc.c @@ -39,7 +39,6 @@ #include #include #include -#include #include #include @@ -496,16 +495,17 @@ static void __free_pages_ok(struct page *page, unsigned int order) int i; int reserved = 0; + arch_free_page(page, order); + if (!PageHighMem(page)) + debug_check_no_locks_freed(page_address(page), + PAGE_SIZE<mapping = NULL; if (free_pages_check(page)) return; - if (!PageHighMem(page)) - debug_check_no_locks_freed(page_address(page), PAGE_SIZE); - arch_free_page(page, 0); kernel_map_pages(page, 1, 0); pcp = &zone_pcp(zone, get_cpu())->pcp[cold]; @@ -853,7 +852,7 @@ static struct page *buffered_rmqueue(struct zonelist *zonelist, pcp = &zone_pcp(zone, cpu)->pcp[cold]; local_irq_save(flags); if (!pcp->count) { - pcp->count = rmqueue_bulk(zone, 0, + pcp->count += rmqueue_bulk(zone, 0, pcp->batch, &pcp->list); if (unlikely(!pcp->count)) goto failed; @@ -1051,7 +1050,7 @@ __alloc_pages(gfp_t gfp_mask, unsigned int order, if (page) goto got_pg; if (gfp_mask & __GFP_NOFAIL) { - congestion_wait(WRITE, HZ/50); + blk_congestion_wait(WRITE, HZ/50); goto nofail_alloc; } } @@ -1114,7 +1113,7 @@ __alloc_pages(gfp_t gfp_mask, unsigned int order, do_retry = 1; } if (do_retry) { - congestion_wait(WRITE, HZ/50); + blk_congestion_wait(WRITE, HZ/50); goto rebalance; } @@ -1689,8 +1688,6 @@ void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone, for (pfn = start_pfn; pfn < end_pfn; pfn++) { if (!early_pfn_valid(pfn)) continue; - if (!early_pfn_in_nid(pfn, nid)) - continue; page = pfn_to_page(pfn); set_page_links(page, zone, nid, pfn); init_page_count(page); @@ -2261,7 +2258,7 @@ unsigned long __init __absent_pages_in_range(int nid, /* Account for ranges past physical memory on this node */ if (range_end_pfn > prev_end_pfn) - hole_pages += range_end_pfn - + hole_pages = range_end_pfn - max(range_start_pfn, prev_end_pfn); return hole_pages; @@ -2297,6 +2294,19 @@ unsigned long __init zone_absent_pages_in_node(int nid, return __absent_pages_in_range(nid, zone_start_pfn, zone_end_pfn); } +/* Return the zone index a PFN is in */ +int memmap_zone_idx(struct page *lmem_map) +{ + int i; + unsigned long phys_addr = virt_to_phys(lmem_map); + unsigned long pfn = phys_addr >> PAGE_SHIFT; + + for (i = 0; i < MAX_NR_ZONES; i++) + if (pfn < arch_zone_highest_possible_pfn[i]) + break; + + return i; +} #else static inline unsigned long zone_spanned_pages_in_node(int nid, unsigned long zone_type, @@ -2315,6 +2325,10 @@ static inline unsigned long zone_absent_pages_in_node(int nid, return zholes_size[zone_type]; } +static inline int memmap_zone_idx(struct page *lmem_map) +{ + return MAX_NR_ZONES; +} #endif static void __init calculate_node_totalpages(struct pglist_data *pgdat, @@ -2407,7 +2421,7 @@ static void __meminit free_area_init_core(struct pglist_data *pgdat, zone->zone_pgdat = pgdat; zone->free_pages = 0; - zone->prev_priority = DEF_PRIORITY; + zone->temp_priority = zone->prev_priority = DEF_PRIORITY; zone_pcp_init(zone); INIT_LIST_HEAD(&zone->active_list); @@ -2612,9 +2626,6 @@ unsigned long __init find_min_pfn_for_node(unsigned long nid) { int i; - /* Regions in the early_node_map can be in any order */ - sort_node_map(); - /* Assuming a sorted map, the first range found has the starting pfn */ for_each_active_range_index_in_nid(i, nid) return early_node_map[i].start_pfn; @@ -2683,6 +2694,9 @@ void __init free_area_init_nodes(unsigned long *max_zone_pfn) max(max_zone_pfn[i], arch_zone_lowest_possible_pfn[i]); } + /* Regions in the early_node_map can be in any order */ + sort_node_map(); + /* Print out the zone ranges */ printk("Zone PFN ranges:\n"); for (i = 0; i < MAX_NR_ZONES; i++) @@ -3122,19 +3136,3 @@ unsigned long page_to_pfn(struct page *page) EXPORT_SYMBOL(pfn_to_page); EXPORT_SYMBOL(page_to_pfn); #endif /* CONFIG_OUT_OF_LINE_PFN_TO_PAGE */ - -#if MAX_NUMNODES > 1 -/* - * Find the highest possible node id. - */ -int highest_possible_node_id(void) -{ - unsigned int node; - unsigned int highest = 0; - - for_each_node_mask(node, node_possible_map) - highest = node; - return highest; -} -EXPORT_SYMBOL(highest_possible_node_id); -#endif diff --git a/trunk/mm/readahead.c b/trunk/mm/readahead.c index 23cb61a01c6e..1ba736ac0367 100644 --- a/trunk/mm/readahead.c +++ b/trunk/mm/readahead.c @@ -173,8 +173,6 @@ static int read_pages(struct address_space *mapping, struct file *filp, if (mapping->a_ops->readpages) { ret = mapping->a_ops->readpages(filp, mapping, pages, nr_pages); - /* Clean up the remaining pages */ - put_pages_list(pages); goto out; } diff --git a/trunk/mm/rmap.c b/trunk/mm/rmap.c index d8a842a586db..e2155d791d99 100644 --- a/trunk/mm/rmap.c +++ b/trunk/mm/rmap.c @@ -21,21 +21,27 @@ * Lock ordering in mm: * * inode->i_mutex (while writing or truncating, not reading or faulting) - * inode->i_alloc_sem (vmtruncate_range) - * mm->mmap_sem - * page->flags PG_locked (lock_page) - * mapping->i_mmap_lock - * anon_vma->lock - * mm->page_table_lock or pte_lock - * zone->lru_lock (in mark_page_accessed, isolate_lru_page) - * swap_lock (in swap_duplicate, swap_info_get) - * mmlist_lock (in mmput, drain_mmlist and others) - * mapping->private_lock (in __set_page_dirty_buffers) - * inode_lock (in set_page_dirty's __mark_inode_dirty) - * sb_lock (within inode_lock in fs/fs-writeback.c) - * mapping->tree_lock (widely used, in set_page_dirty, - * in arch-dependent flush_dcache_mmap_lock, - * within inode_lock in __sync_single_inode) + * inode->i_alloc_sem + * + * When a page fault occurs in writing from user to file, down_read + * of mmap_sem nests within i_mutex; in sys_msync, i_mutex nests within + * down_read of mmap_sem; i_mutex and down_write of mmap_sem are never + * taken together; in truncation, i_mutex is taken outermost. + * + * mm->mmap_sem + * page->flags PG_locked (lock_page) + * mapping->i_mmap_lock + * anon_vma->lock + * mm->page_table_lock or pte_lock + * zone->lru_lock (in mark_page_accessed, isolate_lru_page) + * swap_lock (in swap_duplicate, swap_info_get) + * mmlist_lock (in mmput, drain_mmlist and others) + * mapping->private_lock (in __set_page_dirty_buffers) + * inode_lock (in set_page_dirty's __mark_inode_dirty) + * sb_lock (within inode_lock in fs/fs-writeback.c) + * mapping->tree_lock (widely used, in set_page_dirty, + * in arch-dependent flush_dcache_mmap_lock, + * within inode_lock in __sync_single_inode) */ #include @@ -570,14 +576,15 @@ void page_add_file_rmap(struct page *page) void page_remove_rmap(struct page *page) { if (atomic_add_negative(-1, &page->_mapcount)) { +#ifdef CONFIG_DEBUG_VM if (unlikely(page_mapcount(page) < 0)) { printk (KERN_EMERG "Eeek! page_mapcount(page) went negative! (%d)\n", page_mapcount(page)); printk (KERN_EMERG " page->flags = %lx\n", page->flags); printk (KERN_EMERG " page->count = %x\n", page_count(page)); printk (KERN_EMERG " page->mapping = %p\n", page->mapping); - BUG(); } - +#endif + BUG_ON(page_mapcount(page) < 0); /* * It would be tidy to reset the PageAnon mapping here, * but that might overwrite a racing page_add_anon_rmap diff --git a/trunk/mm/shmem.c b/trunk/mm/shmem.c index 4959535fc14c..bb8ca7ef7094 100644 --- a/trunk/mm/shmem.c +++ b/trunk/mm/shmem.c @@ -48,7 +48,6 @@ #include #include #include -#include #include #include @@ -1132,7 +1131,7 @@ static int shmem_getpage(struct inode *inode, unsigned long idx, page_cache_release(swappage); if (error == -ENOMEM) { /* let kswapd refresh zone for GFP_ATOMICs */ - congestion_wait(WRITE, HZ/50); + blk_congestion_wait(WRITE, HZ/50); } goto repeat; } @@ -1363,7 +1362,6 @@ shmem_get_inode(struct super_block *sb, int mode, dev_t dev) inode->i_mapping->a_ops = &shmem_aops; inode->i_mapping->backing_dev_info = &shmem_backing_dev_info; inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; - inode->i_generation = get_seconds(); info = SHMEM_I(inode); memset(info, 0, (char *)inode - (char *)info); spin_lock_init(&info->lock); @@ -1958,85 +1956,6 @@ static struct xattr_handler *shmem_xattr_handlers[] = { }; #endif -static struct dentry *shmem_get_parent(struct dentry *child) -{ - return ERR_PTR(-ESTALE); -} - -static int shmem_match(struct inode *ino, void *vfh) -{ - __u32 *fh = vfh; - __u64 inum = fh[2]; - inum = (inum << 32) | fh[1]; - return ino->i_ino == inum && fh[0] == ino->i_generation; -} - -static struct dentry *shmem_get_dentry(struct super_block *sb, void *vfh) -{ - struct dentry *de = NULL; - struct inode *inode; - __u32 *fh = vfh; - __u64 inum = fh[2]; - inum = (inum << 32) | fh[1]; - - inode = ilookup5(sb, (unsigned long)(inum+fh[0]), shmem_match, vfh); - if (inode) { - de = d_find_alias(inode); - iput(inode); - } - - return de? de: ERR_PTR(-ESTALE); -} - -static struct dentry *shmem_decode_fh(struct super_block *sb, __u32 *fh, - int len, int type, - int (*acceptable)(void *context, struct dentry *de), - void *context) -{ - if (len < 3) - return ERR_PTR(-ESTALE); - - return sb->s_export_op->find_exported_dentry(sb, fh, NULL, acceptable, - context); -} - -static int shmem_encode_fh(struct dentry *dentry, __u32 *fh, int *len, - int connectable) -{ - struct inode *inode = dentry->d_inode; - - if (*len < 3) - return 255; - - if (hlist_unhashed(&inode->i_hash)) { - /* Unfortunately insert_inode_hash is not idempotent, - * so as we hash inodes here rather than at creation - * time, we need a lock to ensure we only try - * to do it once - */ - static DEFINE_SPINLOCK(lock); - spin_lock(&lock); - if (hlist_unhashed(&inode->i_hash)) - __insert_inode_hash(inode, - inode->i_ino + inode->i_generation); - spin_unlock(&lock); - } - - fh[0] = inode->i_generation; - fh[1] = inode->i_ino; - fh[2] = ((__u64)inode->i_ino) >> 32; - - *len = 3; - return 1; -} - -static struct export_operations shmem_export_ops = { - .get_parent = shmem_get_parent, - .get_dentry = shmem_get_dentry, - .encode_fh = shmem_encode_fh, - .decode_fh = shmem_decode_fh, -}; - static int shmem_parse_options(char *options, int *mode, uid_t *uid, gid_t *gid, unsigned long *blocks, unsigned long *inodes, int *policy, nodemask_t *policy_nodes) @@ -2209,7 +2128,6 @@ static int shmem_fill_super(struct super_block *sb, &inodes, &policy, &policy_nodes)) return -EINVAL; } - sb->s_export_op = &shmem_export_ops; #else sb->s_flags |= MS_NOUSER; #endif diff --git a/trunk/mm/shmem_acl.c b/trunk/mm/shmem_acl.c index f5664c5b9eb1..c946bf468718 100644 --- a/trunk/mm/shmem_acl.c +++ b/trunk/mm/shmem_acl.c @@ -35,7 +35,7 @@ shmem_get_acl(struct inode *inode, int type) } /** - * shmem_set_acl - generic_acl_operations->setacl() operation + * shmem_get_acl - generic_acl_operations->setacl() operation */ static void shmem_set_acl(struct inode *inode, int type, struct posix_acl *acl) diff --git a/trunk/mm/slab.c b/trunk/mm/slab.c index 3c4a7e34eddc..e9a63b5a7fb9 100644 --- a/trunk/mm/slab.c +++ b/trunk/mm/slab.c @@ -883,7 +883,7 @@ static void init_reap_node(int cpu) if (node == MAX_NUMNODES) node = first_node(node_online_map); - per_cpu(reap_node, cpu) = node; + __get_cpu_var(reap_node) = node; } static void next_reap_node(void) @@ -1106,18 +1106,15 @@ static inline int cache_free_alien(struct kmem_cache *cachep, void *objp) int nodeid = slabp->nodeid; struct kmem_list3 *l3; struct array_cache *alien = NULL; - int node; - - node = numa_node_id(); /* * Make sure we are not freeing a object from another node to the array * cache on this cpu. */ - if (likely(slabp->nodeid == node)) + if (likely(slabp->nodeid == numa_node_id())) return 0; - l3 = cachep->nodelists[node]; + l3 = cachep->nodelists[numa_node_id()]; STATS_INC_NODEFREES(cachep); if (l3->alien && l3->alien[nodeid]) { alien = l3->alien[nodeid]; @@ -1328,6 +1325,7 @@ static void init_list(struct kmem_cache *cachep, struct kmem_list3 *list, { struct kmem_list3 *ptr; + BUG_ON(cachep->nodelists[nodeid] != list); ptr = kmalloc_node(sizeof(struct kmem_list3), GFP_KERNEL, nodeid); BUG_ON(!ptr); @@ -1354,7 +1352,6 @@ void __init kmem_cache_init(void) struct cache_names *names; int i; int order; - int node; for (i = 0; i < NUM_INIT_LISTS; i++) { kmem_list3_init(&initkmem_list3[i]); @@ -1389,14 +1386,12 @@ void __init kmem_cache_init(void) * 6) Resize the head arrays of the kmalloc caches to their final sizes. */ - node = numa_node_id(); - /* 1) create the cache_cache */ INIT_LIST_HEAD(&cache_chain); list_add(&cache_cache.next, &cache_chain); cache_cache.colour_off = cache_line_size(); cache_cache.array[smp_processor_id()] = &initarray_cache.cache; - cache_cache.nodelists[node] = &initkmem_list3[CACHE_CACHE]; + cache_cache.nodelists[numa_node_id()] = &initkmem_list3[CACHE_CACHE]; cache_cache.buffer_size = ALIGN(cache_cache.buffer_size, cache_line_size()); @@ -1501,18 +1496,19 @@ void __init kmem_cache_init(void) } /* 5) Replace the bootstrap kmem_list3's */ { - int nid; - + int node; /* Replace the static kmem_list3 structures for the boot cpu */ - init_list(&cache_cache, &initkmem_list3[CACHE_CACHE], node); + init_list(&cache_cache, &initkmem_list3[CACHE_CACHE], + numa_node_id()); - for_each_online_node(nid) { + for_each_online_node(node) { init_list(malloc_sizes[INDEX_AC].cs_cachep, - &initkmem_list3[SIZE_AC + nid], nid); + &initkmem_list3[SIZE_AC + node], node); if (INDEX_AC != INDEX_L3) { init_list(malloc_sizes[INDEX_L3].cs_cachep, - &initkmem_list3[SIZE_L3 + nid], nid); + &initkmem_list3[SIZE_L3 + node], + node); } } } @@ -2922,9 +2918,6 @@ static void *cache_alloc_refill(struct kmem_cache *cachep, gfp_t flags) int batchcount; struct kmem_list3 *l3; struct array_cache *ac; - int node; - - node = numa_node_id(); check_irq_off(); ac = cpu_cache_get(cachep); @@ -2938,7 +2931,7 @@ static void *cache_alloc_refill(struct kmem_cache *cachep, gfp_t flags) */ batchcount = BATCHREFILL_LIMIT; } - l3 = cachep->nodelists[node]; + l3 = cachep->nodelists[numa_node_id()]; BUG_ON(ac->avail > 0 || !l3); spin_lock(&l3->list_lock); @@ -2968,7 +2961,7 @@ static void *cache_alloc_refill(struct kmem_cache *cachep, gfp_t flags) STATS_SET_HIGH(cachep); ac->entry[ac->avail++] = slab_get_obj(cachep, slabp, - node); + numa_node_id()); } check_slabp(cachep, slabp); @@ -2987,7 +2980,7 @@ static void *cache_alloc_refill(struct kmem_cache *cachep, gfp_t flags) if (unlikely(!ac->avail)) { int x; - x = cache_grow(cachep, flags, node); + x = cache_grow(cachep, flags, numa_node_id()); /* cache_grow can reenable interrupts, then ac could change. */ ac = cpu_cache_get(cachep); @@ -3152,15 +3145,12 @@ void *fallback_alloc(struct kmem_cache *cache, gfp_t flags) struct zone **z; void *obj = NULL; - for (z = zonelist->zones; *z && !obj; z++) { - int nid = zone_to_nid(*z); - + for (z = zonelist->zones; *z && !obj; z++) if (zone_idx(*z) <= ZONE_NORMAL && - cpuset_zone_allowed(*z, flags) && - cache->nodelists[nid]) + cpuset_zone_allowed(*z, flags)) obj = __cache_alloc_node(cache, - flags | __GFP_THISNODE, nid); - } + flags | __GFP_THISNODE, + zone_to_nid(*z)); return obj; } diff --git a/trunk/mm/sparse.c b/trunk/mm/sparse.c index b3c82ba30012..86c52ab80878 100644 --- a/trunk/mm/sparse.c +++ b/trunk/mm/sparse.c @@ -211,7 +211,7 @@ static struct page *__kmalloc_section_memmap(unsigned long nr_pages) struct page *page, *ret; unsigned long memmap_size = sizeof(struct page) * nr_pages; - page = alloc_pages(GFP_KERNEL|__GFP_NOWARN, get_order(memmap_size)); + page = alloc_pages(GFP_KERNEL, get_order(memmap_size)); if (page) goto got_map_page; diff --git a/trunk/mm/truncate.c b/trunk/mm/truncate.c index e07b1e682c38..f4edbc179d14 100644 --- a/trunk/mm/truncate.c +++ b/trunk/mm/truncate.c @@ -96,6 +96,7 @@ invalidate_complete_page(struct address_space *mapping, struct page *page) return 0; ret = remove_mapping(mapping, page); + ClearPageUptodate(page); return ret; } @@ -301,7 +302,7 @@ invalidate_complete_page2(struct address_space *mapping, struct page *page) if (page->mapping != mapping) return 0; - if (PagePrivate(page) && !try_to_release_page(page, GFP_KERNEL)) + if (PagePrivate(page) && !try_to_release_page(page, 0)) return 0; write_lock_irq(&mapping->tree_lock); @@ -395,7 +396,6 @@ int invalidate_inode_pages2_range(struct address_space *mapping, pagevec_release(&pvec); cond_resched(); } - WARN_ON_ONCE(ret); return ret; } EXPORT_SYMBOL_GPL(invalidate_inode_pages2_range); diff --git a/trunk/mm/vmalloc.c b/trunk/mm/vmalloc.c index 86897ee792d6..750ab6ed13fc 100644 --- a/trunk/mm/vmalloc.c +++ b/trunk/mm/vmalloc.c @@ -160,15 +160,13 @@ int map_vm_area(struct vm_struct *area, pgprot_t prot, struct page ***pages) return err; } -static struct vm_struct *__get_vm_area_node(unsigned long size, unsigned long flags, - unsigned long start, unsigned long end, - int node, gfp_t gfp_mask) +struct vm_struct *__get_vm_area_node(unsigned long size, unsigned long flags, + unsigned long start, unsigned long end, int node) { struct vm_struct **p, *tmp, *area; unsigned long align = 1; unsigned long addr; - BUG_ON(in_interrupt()); if (flags & VM_IOREMAP) { int bit = fls(size); @@ -181,13 +179,16 @@ static struct vm_struct *__get_vm_area_node(unsigned long size, unsigned long fl } addr = ALIGN(start, align); size = PAGE_ALIGN(size); - if (unlikely(!size)) - return NULL; - area = kmalloc_node(sizeof(*area), gfp_mask & GFP_LEVEL_MASK, node); + area = kmalloc_node(sizeof(*area), GFP_KERNEL, node); if (unlikely(!area)) return NULL; + if (unlikely(!size)) { + kfree (area); + return NULL; + } + /* * We always allocate a guard page. */ @@ -235,7 +236,7 @@ static struct vm_struct *__get_vm_area_node(unsigned long size, unsigned long fl struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags, unsigned long start, unsigned long end) { - return __get_vm_area_node(size, flags, start, end, -1, GFP_KERNEL); + return __get_vm_area_node(size, flags, start, end, -1); } /** @@ -252,11 +253,9 @@ struct vm_struct *get_vm_area(unsigned long size, unsigned long flags) return __get_vm_area(size, flags, VMALLOC_START, VMALLOC_END); } -struct vm_struct *get_vm_area_node(unsigned long size, unsigned long flags, - int node, gfp_t gfp_mask) +struct vm_struct *get_vm_area_node(unsigned long size, unsigned long flags, int node) { - return __get_vm_area_node(size, flags, VMALLOC_START, VMALLOC_END, node, - gfp_mask); + return __get_vm_area_node(size, flags, VMALLOC_START, VMALLOC_END, node); } /* Caller must hold vmlist_lock */ @@ -429,11 +428,8 @@ void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask, if (array_size > PAGE_SIZE) { pages = __vmalloc_node(array_size, gfp_mask, PAGE_KERNEL, node); area->flags |= VM_VPAGES; - } else { - pages = kmalloc_node(array_size, - (gfp_mask & ~(__GFP_HIGHMEM | __GFP_ZERO)), - node); - } + } else + pages = kmalloc_node(array_size, (gfp_mask & ~__GFP_HIGHMEM), node); area->pages = pages; if (!area->pages) { remove_vm_area(area->addr); @@ -488,7 +484,7 @@ static void *__vmalloc_node(unsigned long size, gfp_t gfp_mask, pgprot_t prot, if (!size || (size >> PAGE_SHIFT) > num_physpages) return NULL; - area = get_vm_area_node(size, VM_ALLOC, node, gfp_mask); + area = get_vm_area_node(size, VM_ALLOC, node); if (!area) return NULL; @@ -529,12 +525,11 @@ void *vmalloc_user(unsigned long size) void *ret; ret = __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL); - if (ret) { - write_lock(&vmlist_lock); - area = __find_vm_area(ret); - area->flags |= VM_USERMAP; - write_unlock(&vmlist_lock); - } + write_lock(&vmlist_lock); + area = __find_vm_area(ret); + area->flags |= VM_USERMAP; + write_unlock(&vmlist_lock); + return ret; } EXPORT_SYMBOL(vmalloc_user); @@ -603,12 +598,11 @@ void *vmalloc_32_user(unsigned long size) void *ret; ret = __vmalloc(size, GFP_KERNEL | __GFP_ZERO, PAGE_KERNEL); - if (ret) { - write_lock(&vmlist_lock); - area = __find_vm_area(ret); - area->flags |= VM_USERMAP; - write_unlock(&vmlist_lock); - } + write_lock(&vmlist_lock); + area = __find_vm_area(ret); + area->flags |= VM_USERMAP; + write_unlock(&vmlist_lock); + return ret; } EXPORT_SYMBOL(vmalloc_32_user); diff --git a/trunk/mm/vmscan.c b/trunk/mm/vmscan.c index 518540a4a2a6..eca70310adb2 100644 --- a/trunk/mm/vmscan.c +++ b/trunk/mm/vmscan.c @@ -378,12 +378,6 @@ static pageout_t pageout(struct page *page, struct address_space *mapping) return PAGE_CLEAN; } -/* - * Attempt to detach a locked page from its ->mapping. If it is dirty or if - * someone else has a ref on the page, abort and return 0. If it was - * successfully detached, return 1. Assumes the caller has a single ref on - * this page. - */ int remove_mapping(struct address_space *mapping, struct page *page) { BUG_ON(!PageLocked(page)); @@ -723,20 +717,6 @@ static unsigned long shrink_inactive_list(unsigned long max_scan, return nr_reclaimed; } -/* - * We are about to scan this zone at a certain priority level. If that priority - * level is smaller (ie: more urgent) than the previous priority, then note - * that priority level within the zone. This is done so that when the next - * process comes in to scan this zone, it will immediately start out at this - * priority level rather than having to build up its own scanning priority. - * Here, this priority affects only the reclaim-mapped threshold. - */ -static inline void note_zone_scanning_priority(struct zone *zone, int priority) -{ - if (priority < zone->prev_priority) - zone->prev_priority = priority; -} - static inline int zone_is_near_oom(struct zone *zone) { return zone->pages_scanned >= (zone->nr_active + zone->nr_inactive)*3; @@ -760,7 +740,7 @@ static inline int zone_is_near_oom(struct zone *zone) * But we had to alter page->flags anyway. */ static void shrink_active_list(unsigned long nr_pages, struct zone *zone, - struct scan_control *sc, int priority) + struct scan_control *sc) { unsigned long pgmoved; int pgdeactivate = 0; @@ -784,7 +764,7 @@ static void shrink_active_list(unsigned long nr_pages, struct zone *zone, * `distress' is a measure of how much trouble we're having * reclaiming pages. 0 -> no problems. 100 -> great trouble. */ - distress = 100 >> min(zone->prev_priority, priority); + distress = 100 >> zone->prev_priority; /* * The point of this algorithm is to decide when to start @@ -936,7 +916,7 @@ static unsigned long shrink_zone(int priority, struct zone *zone, nr_to_scan = min(nr_active, (unsigned long)sc->swap_cluster_max); nr_active -= nr_to_scan; - shrink_active_list(nr_to_scan, zone, sc, priority); + shrink_active_list(nr_to_scan, zone, sc); } if (nr_inactive) { @@ -986,7 +966,9 @@ static unsigned long shrink_zones(int priority, struct zone **zones, if (!cpuset_zone_allowed(zone, __GFP_HARDWALL)) continue; - note_zone_scanning_priority(zone, priority); + zone->temp_priority = priority; + if (zone->prev_priority > priority) + zone->prev_priority = priority; if (zone->all_unreclaimable && priority != DEF_PRIORITY) continue; /* Let kswapd poll it */ @@ -1036,6 +1018,7 @@ unsigned long try_to_free_pages(struct zone **zones, gfp_t gfp_mask) if (!cpuset_zone_allowed(zone, __GFP_HARDWALL)) continue; + zone->temp_priority = DEF_PRIORITY; lru_pages += zone->nr_active + zone->nr_inactive; } @@ -1070,28 +1053,19 @@ unsigned long try_to_free_pages(struct zone **zones, gfp_t gfp_mask) /* Take a nap, wait for some writeback to complete */ if (sc.nr_scanned && priority < DEF_PRIORITY - 2) - congestion_wait(WRITE, HZ/10); + blk_congestion_wait(WRITE, HZ/10); } /* top priority shrink_caches still had more to do? don't OOM, then */ if (!sc.all_unreclaimable) ret = 1; out: - /* - * Now that we've scanned all the zones at this priority level, note - * that level within the zone so that the next thread which performs - * scanning of this zone will immediately start out at this priority - * level. This affects only the decision whether or not to bring - * mapped pages onto the inactive list. - */ - if (priority < 0) - priority = 0; for (i = 0; zones[i] != 0; i++) { struct zone *zone = zones[i]; if (!cpuset_zone_allowed(zone, __GFP_HARDWALL)) continue; - zone->prev_priority = priority; + zone->prev_priority = zone->temp_priority; } return ret; } @@ -1131,11 +1105,6 @@ static unsigned long balance_pgdat(pg_data_t *pgdat, int order) .swap_cluster_max = SWAP_CLUSTER_MAX, .swappiness = vm_swappiness, }; - /* - * temp_priority is used to remember the scanning priority at which - * this zone was successfully refilled to free_pages == pages_high. - */ - int temp_priority[MAX_NR_ZONES]; loop_again: total_scanned = 0; @@ -1143,8 +1112,11 @@ static unsigned long balance_pgdat(pg_data_t *pgdat, int order) sc.may_writepage = !laptop_mode; count_vm_event(PAGEOUTRUN); - for (i = 0; i < pgdat->nr_zones; i++) - temp_priority[i] = DEF_PRIORITY; + for (i = 0; i < pgdat->nr_zones; i++) { + struct zone *zone = pgdat->node_zones + i; + + zone->temp_priority = DEF_PRIORITY; + } for (priority = DEF_PRIORITY; priority >= 0; priority--) { int end_zone = 0; /* Inclusive. 0 = ZONE_DMA */ @@ -1205,9 +1177,10 @@ static unsigned long balance_pgdat(pg_data_t *pgdat, int order) if (!zone_watermark_ok(zone, order, zone->pages_high, end_zone, 0)) all_zones_ok = 0; - temp_priority[i] = priority; + zone->temp_priority = priority; + if (zone->prev_priority > priority) + zone->prev_priority = priority; sc.nr_scanned = 0; - note_zone_scanning_priority(zone, priority); nr_reclaimed += shrink_zone(priority, zone, &sc); reclaim_state->reclaimed_slab = 0; nr_slab = shrink_slab(sc.nr_scanned, GFP_KERNEL, @@ -1235,7 +1208,7 @@ static unsigned long balance_pgdat(pg_data_t *pgdat, int order) * another pass across the zones. */ if (total_scanned && priority < DEF_PRIORITY - 2) - congestion_wait(WRITE, HZ/10); + blk_congestion_wait(WRITE, HZ/10); /* * We do this so kswapd doesn't build up large priorities for @@ -1247,15 +1220,10 @@ static unsigned long balance_pgdat(pg_data_t *pgdat, int order) break; } out: - /* - * Note within each zone the priority level at which this zone was - * brought into a happy state. So that the next thread which scans this - * zone will start out at that priority level. - */ for (i = 0; i < pgdat->nr_zones; i++) { struct zone *zone = pgdat->node_zones + i; - zone->prev_priority = temp_priority[i]; + zone->prev_priority = zone->temp_priority; } if (!all_zones_ok) { cond_resched(); @@ -1384,7 +1352,7 @@ static unsigned long shrink_all_zones(unsigned long nr_pages, int pass, if (zone->nr_scan_active >= nr_pages || pass > 3) { zone->nr_scan_active = 0; nr_to_scan = min(nr_pages, zone->nr_active); - shrink_active_list(nr_to_scan, zone, sc, prio); + shrink_active_list(nr_to_scan, zone, sc); } } @@ -1484,7 +1452,7 @@ unsigned long shrink_all_memory(unsigned long nr_pages) goto out; if (sc.nr_scanned && prio < DEF_PRIORITY - 2) - congestion_wait(WRITE, HZ / 10); + blk_congestion_wait(WRITE, HZ / 10); } lru_pages = 0; @@ -1640,7 +1608,6 @@ static int __zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order) */ priority = ZONE_RECLAIM_PRIORITY; do { - note_zone_scanning_priority(zone, priority); nr_reclaimed += shrink_zone(priority, zone, &sc); priority--; } while (priority >= 0 && nr_reclaimed < nr_pages); diff --git a/trunk/mm/vmstat.c b/trunk/mm/vmstat.c index 8614e8f6743b..45b124e012f5 100644 --- a/trunk/mm/vmstat.c +++ b/trunk/mm/vmstat.c @@ -587,9 +587,11 @@ static int zoneinfo_show(struct seq_file *m, void *arg) seq_printf(m, "\n all_unreclaimable: %u" "\n prev_priority: %i" + "\n temp_priority: %i" "\n start_pfn: %lu", zone->all_unreclaimable, zone->prev_priority, + zone->temp_priority, zone->zone_start_pfn); spin_unlock_irqrestore(&zone->lock, flags); seq_putc(m, '\n'); diff --git a/trunk/net/8021q/vlan_dev.c b/trunk/net/8021q/vlan_dev.c index 60a508eb1945..da9cfe927158 100644 --- a/trunk/net/8021q/vlan_dev.c +++ b/trunk/net/8021q/vlan_dev.c @@ -62,7 +62,7 @@ int vlan_dev_rebuild_header(struct sk_buff *skb) default: printk(VLAN_DBG "%s: unable to resolve type %X addresses.\n", - dev->name, ntohs(veth->h_vlan_encapsulated_proto)); + dev->name, (int)veth->h_vlan_encapsulated_proto); memcpy(veth->h_source, dev->dev_addr, ETH_ALEN); break; diff --git a/trunk/net/Kconfig b/trunk/net/Kconfig index 67e39ad8b8b6..a81aca43932f 100644 --- a/trunk/net/Kconfig +++ b/trunk/net/Kconfig @@ -63,7 +63,6 @@ config INET if INET source "net/ipv4/Kconfig" source "net/ipv6/Kconfig" -source "net/netlabel/Kconfig" endif # if INET @@ -250,6 +249,8 @@ source "net/ieee80211/Kconfig" config WIRELESS_EXT bool +source "net/netlabel/Kconfig" + config FIB_RULES bool diff --git a/trunk/net/appletalk/ddp.c b/trunk/net/appletalk/ddp.c index 485e35c3b28b..708e2e0371af 100644 --- a/trunk/net/appletalk/ddp.c +++ b/trunk/net/appletalk/ddp.c @@ -1584,6 +1584,7 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr if (usat->sat_addr.s_net || usat->sat_addr.s_node == ATADDR_ANYNODE) { rt = atrtr_find(&usat->sat_addr); + dev = rt->dev; } else { struct atalk_addr at_hint; @@ -1591,6 +1592,7 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr at_hint.s_net = at->src_net; rt = atrtr_find(&at_hint); + dev = rt->dev; } if (!rt) return -ENETUNREACH; diff --git a/trunk/net/atm/atm_sysfs.c b/trunk/net/atm/atm_sysfs.c index 62f6ed1f2f98..c0a4ae28fcfa 100644 --- a/trunk/net/atm/atm_sysfs.c +++ b/trunk/net/atm/atm_sysfs.c @@ -141,7 +141,7 @@ static struct class atm_class = { int atm_register_sysfs(struct atm_dev *adev) { struct class_device *cdev = &adev->class_dev; - int i, j, err; + int i, err; cdev->class = &atm_class; class_set_devdata(cdev, adev); @@ -151,19 +151,10 @@ int atm_register_sysfs(struct atm_dev *adev) if (err < 0) return err; - for (i = 0; atm_attrs[i]; i++) { - err = class_device_create_file(cdev, atm_attrs[i]); - if (err) - goto err_out; - } + for (i = 0; atm_attrs[i]; i++) + class_device_create_file(cdev, atm_attrs[i]); return 0; - -err_out: - for (j = 0; j < i; j++) - class_device_remove_file(cdev, atm_attrs[j]); - class_device_del(cdev); - return err; } void atm_unregister_sysfs(struct atm_dev *adev) diff --git a/trunk/net/bluetooth/af_bluetooth.c b/trunk/net/bluetooth/af_bluetooth.c index 67df99e2e5c8..305a099b7477 100644 --- a/trunk/net/bluetooth/af_bluetooth.c +++ b/trunk/net/bluetooth/af_bluetooth.c @@ -48,56 +48,41 @@ #define BT_DBG(D...) #endif -#define VERSION "2.11" +#define VERSION "2.10" /* Bluetooth sockets */ #define BT_MAX_PROTO 8 static struct net_proto_family *bt_proto[BT_MAX_PROTO]; -static DEFINE_RWLOCK(bt_proto_lock); int bt_sock_register(int proto, struct net_proto_family *ops) { - int err = 0; - if (proto < 0 || proto >= BT_MAX_PROTO) return -EINVAL; - write_lock(&bt_proto_lock); - if (bt_proto[proto]) - err = -EEXIST; - else - bt_proto[proto] = ops; - - write_unlock(&bt_proto_lock); + return -EEXIST; - return err; + bt_proto[proto] = ops; + return 0; } EXPORT_SYMBOL(bt_sock_register); int bt_sock_unregister(int proto) { - int err = 0; - if (proto < 0 || proto >= BT_MAX_PROTO) return -EINVAL; - write_lock(&bt_proto_lock); - if (!bt_proto[proto]) - err = -ENOENT; - else - bt_proto[proto] = NULL; + return -ENOENT; - write_unlock(&bt_proto_lock); - - return err; + bt_proto[proto] = NULL; + return 0; } EXPORT_SYMBOL(bt_sock_unregister); static int bt_sock_create(struct socket *sock, int proto) { - int err; + int err = 0; if (proto < 0 || proto >= BT_MAX_PROTO) return -EINVAL; @@ -107,18 +92,11 @@ static int bt_sock_create(struct socket *sock, int proto) request_module("bt-proto-%d", proto); } #endif - err = -EPROTONOSUPPORT; - - read_lock(&bt_proto_lock); - if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) { err = bt_proto[proto]->create(sock, proto); module_put(bt_proto[proto]->owner); } - - read_unlock(&bt_proto_lock); - return err; } diff --git a/trunk/net/bluetooth/bnep/core.c b/trunk/net/bluetooth/bnep/core.c index 4d3424c2421c..2312d050eeed 100644 --- a/trunk/net/bluetooth/bnep/core.c +++ b/trunk/net/bluetooth/bnep/core.c @@ -528,10 +528,12 @@ static struct device *bnep_get_device(struct bnep_session *session) return NULL; conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst); + if (!conn) + return NULL; hci_dev_put(hdev); - return conn ? &conn->dev : NULL; + return &conn->dev; } int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock) diff --git a/trunk/net/bluetooth/bnep/sock.c b/trunk/net/bluetooth/bnep/sock.c index 5563db1bf526..28c55835422a 100644 --- a/trunk/net/bluetooth/bnep/sock.c +++ b/trunk/net/bluetooth/bnep/sock.c @@ -43,7 +43,6 @@ #include #include #include -#include #include #include @@ -147,56 +146,24 @@ static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long return 0; } -#ifdef CONFIG_COMPAT -static int bnep_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) -{ - if (cmd == BNEPGETCONNLIST) { - struct bnep_connlist_req cl; - uint32_t uci; - int err; - - if (get_user(cl.cnum, (uint32_t __user *) arg) || - get_user(uci, (u32 __user *) (arg + 4))) - return -EFAULT; - - cl.ci = compat_ptr(uci); - - if (cl.cnum <= 0) - return -EINVAL; - - err = bnep_get_connlist(&cl); - - if (!err && put_user(cl.cnum, (uint32_t __user *) arg)) - err = -EFAULT; - - return err; - } - - return bnep_sock_ioctl(sock, cmd, arg); -} -#endif - static const struct proto_ops bnep_sock_ops = { - .family = PF_BLUETOOTH, - .owner = THIS_MODULE, - .release = bnep_sock_release, - .ioctl = bnep_sock_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = bnep_sock_compat_ioctl, -#endif - .bind = sock_no_bind, - .getname = sock_no_getname, - .sendmsg = sock_no_sendmsg, - .recvmsg = sock_no_recvmsg, - .poll = sock_no_poll, - .listen = sock_no_listen, - .shutdown = sock_no_shutdown, - .setsockopt = sock_no_setsockopt, - .getsockopt = sock_no_getsockopt, - .connect = sock_no_connect, - .socketpair = sock_no_socketpair, - .accept = sock_no_accept, - .mmap = sock_no_mmap + .family = PF_BLUETOOTH, + .owner = THIS_MODULE, + .release = bnep_sock_release, + .ioctl = bnep_sock_ioctl, + .bind = sock_no_bind, + .getname = sock_no_getname, + .sendmsg = sock_no_sendmsg, + .recvmsg = sock_no_recvmsg, + .poll = sock_no_poll, + .listen = sock_no_listen, + .shutdown = sock_no_shutdown, + .setsockopt = sock_no_setsockopt, + .getsockopt = sock_no_getsockopt, + .connect = sock_no_connect, + .socketpair = sock_no_socketpair, + .accept = sock_no_accept, + .mmap = sock_no_mmap }; static struct proto bnep_proto = { @@ -214,7 +181,7 @@ static int bnep_sock_create(struct socket *sock, int protocol) if (sock->type != SOCK_RAW) return -ESOCKTNOSUPPORT; - sk = sk_alloc(PF_BLUETOOTH, GFP_ATOMIC, &bnep_proto, 1); + sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, &bnep_proto, 1); if (!sk) return -ENOMEM; diff --git a/trunk/net/bluetooth/cmtp/sock.c b/trunk/net/bluetooth/cmtp/sock.c index 53295d33dc5c..10ad7fd91d83 100644 --- a/trunk/net/bluetooth/cmtp/sock.c +++ b/trunk/net/bluetooth/cmtp/sock.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include @@ -138,43 +137,11 @@ static int cmtp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long return -EINVAL; } -#ifdef CONFIG_COMPAT -static int cmtp_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) -{ - if (cmd == CMTPGETCONNLIST) { - struct cmtp_connlist_req cl; - uint32_t uci; - int err; - - if (get_user(cl.cnum, (uint32_t __user *) arg) || - get_user(uci, (u32 __user *) (arg + 4))) - return -EFAULT; - - cl.ci = compat_ptr(uci); - - if (cl.cnum <= 0) - return -EINVAL; - - err = cmtp_get_connlist(&cl); - - if (!err && put_user(cl.cnum, (uint32_t __user *) arg)) - err = -EFAULT; - - return err; - } - - return cmtp_sock_ioctl(sock, cmd, arg); -} -#endif - static const struct proto_ops cmtp_sock_ops = { .family = PF_BLUETOOTH, .owner = THIS_MODULE, .release = cmtp_sock_release, .ioctl = cmtp_sock_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = cmtp_sock_compat_ioctl, -#endif .bind = sock_no_bind, .getname = sock_no_getname, .sendmsg = sock_no_sendmsg, @@ -205,7 +172,7 @@ static int cmtp_sock_create(struct socket *sock, int protocol) if (sock->type != SOCK_RAW) return -ESOCKTNOSUPPORT; - sk = sk_alloc(PF_BLUETOOTH, GFP_ATOMIC, &cmtp_proto, 1); + sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, &cmtp_proto, 1); if (!sk) return -ENOMEM; diff --git a/trunk/net/bluetooth/hci_conn.c b/trunk/net/bluetooth/hci_conn.c index 6cd5711fa28a..90e3a285a17e 100644 --- a/trunk/net/bluetooth/hci_conn.c +++ b/trunk/net/bluetooth/hci_conn.c @@ -51,7 +51,7 @@ #define BT_DBG(D...) #endif -void hci_acl_connect(struct hci_conn *conn) +static void hci_acl_connect(struct hci_conn *conn) { struct hci_dev *hdev = conn->hdev; struct inquiry_entry *ie; @@ -63,8 +63,6 @@ void hci_acl_connect(struct hci_conn *conn) conn->out = 1; conn->link_mode = HCI_LM_MASTER; - conn->attempt++; - memset(&cp, 0, sizeof(cp)); bacpy(&cp.bdaddr, &conn->dst); cp.pscan_rep_mode = 0x02; @@ -82,7 +80,7 @@ void hci_acl_connect(struct hci_conn *conn) cp.role_switch = 0x01; else cp.role_switch = 0x00; - + hci_send_cmd(hdev, OGF_LINK_CTL, OCF_CREATE_CONN, sizeof(cp), &cp); } diff --git a/trunk/net/bluetooth/hci_event.c b/trunk/net/bluetooth/hci_event.c index bb94e6da223c..d43d0c890975 100644 --- a/trunk/net/bluetooth/hci_event.c +++ b/trunk/net/bluetooth/hci_event.c @@ -57,7 +57,6 @@ static void hci_cc_link_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb) { __u8 status; - struct hci_conn *pend; BT_DBG("%s ocf 0x%x", hdev->name, ocf); @@ -72,15 +71,6 @@ static void hci_cc_link_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb clear_bit(HCI_INQUIRY, &hdev->flags); hci_req_complete(hdev, status); } - - hci_dev_lock(hdev); - - pend = hci_conn_hash_lookup_state(hdev, ACL_LINK, BT_CONNECT2); - if (pend) - hci_acl_connect(pend); - - hci_dev_unlock(hdev); - break; default: @@ -424,12 +414,9 @@ static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) if (status) { if (conn && conn->state == BT_CONNECT) { - if (status != 0x0c || conn->attempt > 2) { - conn->state = BT_CLOSED; - hci_proto_connect_cfm(conn, status); - hci_conn_del(conn); - } else - conn->state = BT_CONNECT2; + conn->state = BT_CLOSED; + hci_proto_connect_cfm(conn, status); + hci_conn_del(conn); } } else { if (!conn) { @@ -575,20 +562,11 @@ static void hci_cs_info_param(struct hci_dev *hdev, __u16 ocf, __u8 status) static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) { __u8 status = *((__u8 *) skb->data); - struct hci_conn *pend; BT_DBG("%s status %d", hdev->name, status); clear_bit(HCI_INQUIRY, &hdev->flags); hci_req_complete(hdev, status); - - hci_dev_lock(hdev); - - pend = hci_conn_hash_lookup_state(hdev, ACL_LINK, BT_CONNECT2); - if (pend) - hci_acl_connect(pend); - - hci_dev_unlock(hdev); } /* Inquiry Result */ @@ -750,7 +728,7 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *sk static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_conn_complete *ev = (struct hci_ev_conn_complete *) skb->data; - struct hci_conn *conn, *pend; + struct hci_conn *conn; BT_DBG("%s", hdev->name); @@ -823,10 +801,6 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s if (ev->status) hci_conn_del(conn); - pend = hci_conn_hash_lookup_state(hdev, ACL_LINK, BT_CONNECT2); - if (pend) - hci_acl_connect(pend); - hci_dev_unlock(hdev); } diff --git a/trunk/net/bluetooth/hci_sock.c b/trunk/net/bluetooth/hci_sock.c index 711a085eca5b..1a35d343e08a 100644 --- a/trunk/net/bluetooth/hci_sock.c +++ b/trunk/net/bluetooth/hci_sock.c @@ -120,13 +120,10 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb) if (!hci_test_bit(evt, &flt->event_mask)) continue; - if (flt->opcode && - ((evt == HCI_EV_CMD_COMPLETE && - flt->opcode != - get_unaligned((__u16 *)(skb->data + 3))) || - (evt == HCI_EV_CMD_STATUS && - flt->opcode != - get_unaligned((__u16 *)(skb->data + 4))))) + if (flt->opcode && ((evt == HCI_EV_CMD_COMPLETE && + flt->opcode != *(__u16 *)(skb->data + 3)) || + (evt == HCI_EV_CMD_STATUS && + flt->opcode != *(__u16 *)(skb->data + 4)))) continue; } @@ -621,7 +618,7 @@ static int hci_sock_create(struct socket *sock, int protocol) sock->ops = &hci_sock_ops; - sk = sk_alloc(PF_BLUETOOTH, GFP_ATOMIC, &hci_sk_proto, 1); + sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, &hci_sk_proto, 1); if (!sk) return -ENOMEM; diff --git a/trunk/net/bluetooth/hci_sysfs.c b/trunk/net/bluetooth/hci_sysfs.c index 3eeeb7a86e75..989b22d9042e 100644 --- a/trunk/net/bluetooth/hci_sysfs.c +++ b/trunk/net/bluetooth/hci_sysfs.c @@ -242,14 +242,10 @@ static void add_conn(void *data) struct hci_conn *conn = data; int i; - if (device_register(&conn->dev) < 0) { - BT_ERR("Failed to register connection device"); - return; - } + device_register(&conn->dev); for (i = 0; conn_attrs[i]; i++) - if (device_create_file(&conn->dev, conn_attrs[i]) < 0) - BT_ERR("Failed to create connection attribute"); + device_create_file(&conn->dev, conn_attrs[i]); } void hci_conn_add_sysfs(struct hci_conn *conn) @@ -259,9 +255,7 @@ void hci_conn_add_sysfs(struct hci_conn *conn) BT_DBG("conn %p", conn); - conn->dev.bus = &bt_bus; - conn->dev.parent = &hdev->dev; - + conn->dev.parent = &hdev->dev; conn->dev.release = bt_release; snprintf(conn->dev.bus_id, BUS_ID_SIZE, @@ -301,7 +295,11 @@ int hci_register_sysfs(struct hci_dev *hdev) BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type); dev->class = bt_class; - dev->parent = hdev->parent; + + if (hdev->parent) + dev->parent = hdev->parent; + else + dev->parent = &bt_platform->dev; strlcpy(dev->bus_id, hdev->name, BUS_ID_SIZE); @@ -314,8 +312,7 @@ int hci_register_sysfs(struct hci_dev *hdev) return err; for (i = 0; bt_attrs[i]; i++) - if (device_create_file(dev, bt_attrs[i]) < 0) - BT_ERR("Failed to create device attribute"); + device_create_file(dev, bt_attrs[i]); return 0; } diff --git a/trunk/net/bluetooth/hidp/core.c b/trunk/net/bluetooth/hidp/core.c index 66782010f82c..03b5dadb4951 100644 --- a/trunk/net/bluetooth/hidp/core.c +++ b/trunk/net/bluetooth/hidp/core.c @@ -507,13 +507,15 @@ static int hidp_session(void *arg) hidp_del_timer(session); - fput(session->intr_sock->file); - - wait_event_timeout(*(ctrl_sk->sk_sleep), - (ctrl_sk->sk_state == BT_CLOSED), msecs_to_jiffies(500)); + if (intr_sk->sk_state != BT_CONNECTED) + wait_event_timeout(*(ctrl_sk->sk_sleep), (ctrl_sk->sk_state == BT_CLOSED), HZ); fput(session->ctrl_sock->file); + wait_event_timeout(*(intr_sk->sk_sleep), (intr_sk->sk_state == BT_CLOSED), HZ); + + fput(session->intr_sock->file); + __hidp_unlink_session(session); if (session->input) { @@ -539,10 +541,12 @@ static struct device *hidp_get_device(struct hidp_session *session) return NULL; conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst); + if (!conn) + return NULL; hci_dev_put(hdev); - return conn ? &conn->dev : NULL; + return &conn->dev; } static inline void hidp_setup_input(struct hidp_session *session, struct hidp_connadd_req *req) diff --git a/trunk/net/bluetooth/hidp/sock.c b/trunk/net/bluetooth/hidp/sock.c index 407fba43c1b9..099646e4e2ef 100644 --- a/trunk/net/bluetooth/hidp/sock.c +++ b/trunk/net/bluetooth/hidp/sock.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include "hidp.h" @@ -144,88 +143,11 @@ static int hidp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long return -EINVAL; } -#ifdef CONFIG_COMPAT -struct compat_hidp_connadd_req { - int ctrl_sock; // Connected control socket - int intr_sock; // Connteted interrupt socket - __u16 parser; - __u16 rd_size; - compat_uptr_t rd_data; - __u8 country; - __u8 subclass; - __u16 vendor; - __u16 product; - __u16 version; - __u32 flags; - __u32 idle_to; - char name[128]; -}; - -static int hidp_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) -{ - if (cmd == HIDPGETCONNLIST) { - struct hidp_connlist_req cl; - uint32_t uci; - int err; - - if (get_user(cl.cnum, (uint32_t __user *) arg) || - get_user(uci, (u32 __user *) (arg + 4))) - return -EFAULT; - - cl.ci = compat_ptr(uci); - - if (cl.cnum <= 0) - return -EINVAL; - - err = hidp_get_connlist(&cl); - - if (!err && put_user(cl.cnum, (uint32_t __user *) arg)) - err = -EFAULT; - - return err; - } else if (cmd == HIDPCONNADD) { - struct compat_hidp_connadd_req ca; - struct hidp_connadd_req __user *uca; - - uca = compat_alloc_user_space(sizeof(*uca)); - - if (copy_from_user(&ca, (void *) arg, sizeof(ca))) - return -EFAULT; - - if (put_user(ca.ctrl_sock, &uca->ctrl_sock) || - put_user(ca.intr_sock, &uca->intr_sock) || - put_user(ca.parser, &uca->parser) || - put_user(ca.rd_size, &uca->parser) || - put_user(compat_ptr(ca.rd_data), &uca->rd_data) || - put_user(ca.country, &uca->country) || - put_user(ca.subclass, &uca->subclass) || - put_user(ca.vendor, &uca->vendor) || - put_user(ca.product, &uca->product) || - put_user(ca.version, &uca->version) || - put_user(ca.flags, &uca->flags) || - put_user(ca.idle_to, &uca->idle_to) || - copy_to_user(&uca->name[0], &ca.name[0], 128)) - return -EFAULT; - - arg = (unsigned long) uca; - - /* Fall through. We don't actually write back any _changes_ - to the structure anyway, so there's no need to copy back - into the original compat version */ - } - - return hidp_sock_ioctl(sock, cmd, arg); -} -#endif - static const struct proto_ops hidp_sock_ops = { .family = PF_BLUETOOTH, .owner = THIS_MODULE, .release = hidp_sock_release, .ioctl = hidp_sock_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = hidp_sock_compat_ioctl, -#endif .bind = sock_no_bind, .getname = sock_no_getname, .sendmsg = sock_no_sendmsg, @@ -256,7 +178,7 @@ static int hidp_sock_create(struct socket *sock, int protocol) if (sock->type != SOCK_RAW) return -ESOCKTNOSUPPORT; - sk = sk_alloc(PF_BLUETOOTH, GFP_ATOMIC, &hidp_proto, 1); + sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, &hidp_proto, 1); if (!sk) return -ENOMEM; diff --git a/trunk/net/bluetooth/l2cap.c b/trunk/net/bluetooth/l2cap.c index bbf78e6a7bc3..d56f60b392ac 100644 --- a/trunk/net/bluetooth/l2cap.c +++ b/trunk/net/bluetooth/l2cap.c @@ -559,7 +559,7 @@ static int l2cap_sock_create(struct socket *sock, int protocol) sock->ops = &l2cap_sock_ops; - sk = l2cap_sock_alloc(sock, protocol, GFP_ATOMIC); + sk = l2cap_sock_alloc(sock, protocol, GFP_KERNEL); if (!sk) return -ENOMEM; @@ -1353,12 +1353,12 @@ static inline int l2cap_conf_output(struct sock *sk, void **ptr) /* Configure output options and let the other side know * which ones we don't like. */ - if (pi->conf_mtu < pi->omtu) + if (pi->conf_mtu < pi->omtu) { + l2cap_add_conf_opt(ptr, L2CAP_CONF_MTU, 2, pi->omtu); result = L2CAP_CONF_UNACCEPT; - else + } else { pi->omtu = pi->conf_mtu; - - l2cap_add_conf_opt(ptr, L2CAP_CONF_MTU, 2, pi->omtu); + } BT_DBG("sk %p result %d", sk, result); return result; @@ -1533,9 +1533,6 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid))) return -ENOENT; - if (sk->sk_state == BT_DISCONN) - goto unlock; - l2cap_parse_conf_req(sk, req->data, cmd->len - sizeof(*req)); if (flags & 0x0001) { @@ -2219,8 +2216,7 @@ static int __init l2cap_init(void) goto error; } - if (class_create_file(bt_class, &class_attr_l2cap) < 0) - BT_ERR("Failed to create L2CAP info file"); + class_create_file(bt_class, &class_attr_l2cap); BT_INFO("L2CAP ver %s", VERSION); BT_INFO("L2CAP socket layer initialized"); diff --git a/trunk/net/bluetooth/rfcomm/core.c b/trunk/net/bluetooth/rfcomm/core.c index ddc4e9d5963e..468df3b953f6 100644 --- a/trunk/net/bluetooth/rfcomm/core.c +++ b/trunk/net/bluetooth/rfcomm/core.c @@ -2058,8 +2058,7 @@ static int __init rfcomm_init(void) kernel_thread(rfcomm_run, NULL, CLONE_KERNEL); - if (class_create_file(bt_class, &class_attr_rfcomm_dlc) < 0) - BT_ERR("Failed to create RFCOMM info file"); + class_create_file(bt_class, &class_attr_rfcomm_dlc); rfcomm_init_sockets(); diff --git a/trunk/net/bluetooth/rfcomm/sock.c b/trunk/net/bluetooth/rfcomm/sock.c index 544d65b7baa7..220fee04e7f2 100644 --- a/trunk/net/bluetooth/rfcomm/sock.c +++ b/trunk/net/bluetooth/rfcomm/sock.c @@ -336,8 +336,7 @@ static int rfcomm_sock_create(struct socket *sock, int protocol) sock->ops = &rfcomm_sock_ops; - sk = rfcomm_sock_alloc(sock, protocol, GFP_ATOMIC); - if (!sk) + if (!(sk = rfcomm_sock_alloc(sock, protocol, GFP_KERNEL))) return -ENOMEM; rfcomm_sock_init(sk, NULL); @@ -945,8 +944,7 @@ int __init rfcomm_init_sockets(void) if (err < 0) goto error; - if (class_create_file(bt_class, &class_attr_rfcomm) < 0) - BT_ERR("Failed to create RFCOMM info file"); + class_create_file(bt_class, &class_attr_rfcomm); BT_INFO("RFCOMM socket layer initialized"); diff --git a/trunk/net/bluetooth/rfcomm/tty.c b/trunk/net/bluetooth/rfcomm/tty.c index 1fb5d42f37ae..1958ad1b8541 100644 --- a/trunk/net/bluetooth/rfcomm/tty.c +++ b/trunk/net/bluetooth/rfcomm/tty.c @@ -172,10 +172,12 @@ static struct device *rfcomm_get_device(struct rfcomm_dev *dev) return NULL; conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &dev->dst); + if (!conn) + return NULL; hci_dev_put(hdev); - return conn ? &conn->dev : NULL; + return &conn->dev; } static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc) @@ -765,9 +767,6 @@ static void rfcomm_tty_set_termios(struct tty_struct *tty, struct termios *old) BT_DBG("tty %p termios %p", tty, old); - if (!dev || !dev->dlc || !dev->dlc->session) - return; - /* Handle turning off CRTSCTS */ if ((old->c_cflag & CRTSCTS) && !(new->c_cflag & CRTSCTS)) BT_DBG("Turning off CRTSCTS unsupported"); diff --git a/trunk/net/bluetooth/sco.c b/trunk/net/bluetooth/sco.c index 5d13d4f31753..7714a2ec3854 100644 --- a/trunk/net/bluetooth/sco.c +++ b/trunk/net/bluetooth/sco.c @@ -452,8 +452,7 @@ static int sco_sock_create(struct socket *sock, int protocol) sock->ops = &sco_sock_ops; - sk = sco_sock_alloc(sock, protocol, GFP_ATOMIC); - if (!sk) + if (!(sk = sco_sock_alloc(sock, protocol, GFP_KERNEL))) return -ENOMEM; sco_sock_init(sk, NULL); @@ -968,8 +967,7 @@ static int __init sco_init(void) goto error; } - if (class_create_file(bt_class, &class_attr_sco) < 0) - BT_ERR("Failed to create SCO info file"); + class_create_file(bt_class, &class_attr_sco); BT_INFO("SCO (Voice Link) ver %s", VERSION); BT_INFO("SCO socket layer initialized"); diff --git a/trunk/net/bridge/br_fdb.c b/trunk/net/bridge/br_fdb.c index d9f04864d15d..3a73b8c94271 100644 --- a/trunk/net/bridge/br_fdb.c +++ b/trunk/net/bridge/br_fdb.c @@ -128,10 +128,7 @@ void br_fdb_cleanup(unsigned long _data) mod_timer(&br->gc_timer, jiffies + HZ/10); } - -void br_fdb_delete_by_port(struct net_bridge *br, - const struct net_bridge_port *p, - int do_all) +void br_fdb_delete_by_port(struct net_bridge *br, struct net_bridge_port *p) { int i; @@ -145,8 +142,6 @@ void br_fdb_delete_by_port(struct net_bridge *br, if (f->dst != p) continue; - if (f->is_static && !do_all) - continue; /* * if multiple ports all have the same device address * then when one port is deleted, assign diff --git a/trunk/net/bridge/br_if.c b/trunk/net/bridge/br_if.c index f753c40c11d2..b1211d5342f6 100644 --- a/trunk/net/bridge/br_if.c +++ b/trunk/net/bridge/br_if.c @@ -163,7 +163,7 @@ static void del_nbp(struct net_bridge_port *p) br_stp_disable_port(p); spin_unlock_bh(&br->lock); - br_fdb_delete_by_port(br, p, 1); + br_fdb_delete_by_port(br, p); list_del_rcu(&p->list); @@ -448,7 +448,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) return 0; err2: - br_fdb_delete_by_port(br, p, 1); + br_fdb_delete_by_port(br, p); err1: kobject_del(&p->kobj); err0: diff --git a/trunk/net/bridge/br_ioctl.c b/trunk/net/bridge/br_ioctl.c index 4c61a7e0a86e..4e4119a12139 100644 --- a/trunk/net/bridge/br_ioctl.c +++ b/trunk/net/bridge/br_ioctl.c @@ -58,13 +58,12 @@ static int get_fdb_entries(struct net_bridge *br, void __user *userbuf, { int num; void *buf; - size_t size; + size_t size = maxnum * sizeof(struct __fdb_entry); - /* Clamp size to PAGE_SIZE, test maxnum to avoid overflow */ - if (maxnum > PAGE_SIZE/sizeof(struct __fdb_entry)) + if (size > PAGE_SIZE) { + size = PAGE_SIZE; maxnum = PAGE_SIZE/sizeof(struct __fdb_entry); - - size = maxnum * sizeof(struct __fdb_entry); + } buf = kmalloc(size, GFP_USER); if (!buf) diff --git a/trunk/net/bridge/br_private.h b/trunk/net/bridge/br_private.h index 74258d86f256..c491fb2f280e 100644 --- a/trunk/net/bridge/br_private.h +++ b/trunk/net/bridge/br_private.h @@ -143,7 +143,7 @@ extern void br_fdb_changeaddr(struct net_bridge_port *p, const unsigned char *newaddr); extern void br_fdb_cleanup(unsigned long arg); extern void br_fdb_delete_by_port(struct net_bridge *br, - const struct net_bridge_port *p, int do_all); + struct net_bridge_port *p); extern struct net_bridge_fdb_entry *__br_fdb_get(struct net_bridge *br, const unsigned char *addr); extern struct net_bridge_fdb_entry *br_fdb_get(struct net_bridge *br, diff --git a/trunk/net/bridge/br_stp_if.c b/trunk/net/bridge/br_stp_if.c index d294224592db..14cd025079af 100644 --- a/trunk/net/bridge/br_stp_if.c +++ b/trunk/net/bridge/br_stp_if.c @@ -113,8 +113,6 @@ void br_stp_disable_port(struct net_bridge_port *p) del_timer(&p->forward_delay_timer); del_timer(&p->hold_timer); - br_fdb_delete_by_port(br, p, 0); - br_configuration_update(br); br_port_state_selection(br); diff --git a/trunk/net/bridge/br_sysfs_br.c b/trunk/net/bridge/br_sysfs_br.c index de9d1a9473f2..96bcb2ff59ab 100644 --- a/trunk/net/bridge/br_sysfs_br.c +++ b/trunk/net/bridge/br_sysfs_br.c @@ -376,7 +376,7 @@ int br_sysfs_addbr(struct net_device *dev) err = sysfs_create_bin_file(brobj, &bridge_forward); if (err) { - pr_info("%s: can't create attribute file %s/%s\n", + pr_info("%s: can't create attribue file %s/%s\n", __FUNCTION__, dev->name, bridge_forward.attr.name); goto out2; } diff --git a/trunk/net/bridge/netfilter/ebtables.c b/trunk/net/bridge/netfilter/ebtables.c index 9f85666f29f7..3df55b2bd91d 100644 --- a/trunk/net/bridge/netfilter/ebtables.c +++ b/trunk/net/bridge/netfilter/ebtables.c @@ -86,7 +86,7 @@ static inline int ebt_do_match (struct ebt_entry_match *m, static inline int ebt_dev_check(char *entry, const struct net_device *device) { int i = 0; - const char *devname = device->name; + char *devname = device->name; if (*entry == '\0') return 0; diff --git a/trunk/net/compat.c b/trunk/net/compat.c index 52d32f1bc728..d5d69fa15d07 100644 --- a/trunk/net/compat.c +++ b/trunk/net/compat.c @@ -285,7 +285,8 @@ void scm_detach_fds_compat(struct msghdr *kmsg, struct scm_cookie *scm) if (i > 0) { int cmlen = CMSG_COMPAT_LEN(i * sizeof(int)); - err = put_user(SOL_SOCKET, &cm->cmsg_level); + if (!err) + err = put_user(SOL_SOCKET, &cm->cmsg_level); if (!err) err = put_user(SCM_RIGHTS, &cm->cmsg_type); if (!err) diff --git a/trunk/net/core/dev.c b/trunk/net/core/dev.c index 81c426adcd1e..4d891beab138 100644 --- a/trunk/net/core/dev.c +++ b/trunk/net/core/dev.c @@ -3502,6 +3502,8 @@ static int __init net_dev_init(void) BUG_ON(!dev_boot_phase); + net_random_init(); + if (dev_proc_init()) goto out; diff --git a/trunk/net/core/flow.c b/trunk/net/core/flow.c index b16d31ae5e54..f23e7e386543 100644 --- a/trunk/net/core/flow.c +++ b/trunk/net/core/flow.c @@ -85,14 +85,6 @@ static void flow_cache_new_hashrnd(unsigned long arg) add_timer(&flow_hash_rnd_timer); } -static void flow_entry_kill(int cpu, struct flow_cache_entry *fle) -{ - if (fle->object) - atomic_dec(fle->object_ref); - kmem_cache_free(flow_cachep, fle); - flow_count(cpu)--; -} - static void __flow_cache_shrink(int cpu, int shrink_to) { struct flow_cache_entry *fle, **flp; @@ -108,7 +100,10 @@ static void __flow_cache_shrink(int cpu, int shrink_to) } while ((fle = *flp) != NULL) { *flp = fle->next; - flow_entry_kill(cpu, fle); + if (fle->object) + atomic_dec(fle->object_ref); + kmem_cache_free(flow_cachep, fle); + flow_count(cpu)--; } } } @@ -225,33 +220,24 @@ void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir, nocache: { - int err; void *obj; atomic_t *obj_ref; - err = resolver(key, family, dir, &obj, &obj_ref); + resolver(key, family, dir, &obj, &obj_ref); if (fle) { - if (err) { - /* Force security policy check on next lookup */ - *head = fle->next; - flow_entry_kill(cpu, fle); - } else { - fle->genid = atomic_read(&flow_cache_genid); - - if (fle->object) - atomic_dec(fle->object_ref); - - fle->object = obj; - fle->object_ref = obj_ref; - if (obj) - atomic_inc(fle->object_ref); - } + fle->genid = atomic_read(&flow_cache_genid); + + if (fle->object) + atomic_dec(fle->object_ref); + + fle->object = obj; + fle->object_ref = obj_ref; + if (obj) + atomic_inc(fle->object_ref); } local_bh_enable(); - if (err) - obj = ERR_PTR(err); return obj; } } diff --git a/trunk/net/core/netpoll.c b/trunk/net/core/netpoll.c index 6589adb14cbf..ead5920c26d6 100644 --- a/trunk/net/core/netpoll.c +++ b/trunk/net/core/netpoll.c @@ -335,19 +335,13 @@ void netpoll_send_udp(struct netpoll *np, const char *msg, int len) memcpy(skb->data, msg, len); skb->len += len; - skb->h.uh = udph = (struct udphdr *) skb_push(skb, sizeof(*udph)); + udph = (struct udphdr *) skb_push(skb, sizeof(*udph)); udph->source = htons(np->local_port); udph->dest = htons(np->remote_port); udph->len = htons(udp_len); udph->check = 0; - udph->check = csum_tcpudp_magic(htonl(np->local_ip), - htonl(np->remote_ip), - udp_len, IPPROTO_UDP, - csum_partial((unsigned char *)udph, udp_len, 0)); - if (udph->check == 0) - udph->check = -1; - skb->nh.iph = iph = (struct iphdr *)skb_push(skb, sizeof(*iph)); + iph = (struct iphdr *)skb_push(skb, sizeof(*iph)); /* iph->version = 4; iph->ihl = 5; */ put_unaligned(0x45, (unsigned char *)iph); @@ -363,8 +357,8 @@ void netpoll_send_udp(struct netpoll *np, const char *msg, int len) iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl); eth = (struct ethhdr *) skb_push(skb, ETH_HLEN); - skb->mac.raw = skb->data; - skb->protocol = eth->h_proto = htons(ETH_P_IP); + + eth->h_proto = htons(ETH_P_IP); memcpy(eth->h_source, np->local_mac, 6); memcpy(eth->h_dest, np->remote_mac, 6); diff --git a/trunk/net/core/pktgen.c b/trunk/net/core/pktgen.c index 733d86d0a4fb..dd023fd28304 100644 --- a/trunk/net/core/pktgen.c +++ b/trunk/net/core/pktgen.c @@ -2304,12 +2304,6 @@ static void mpls_push(__be32 *mpls, struct pktgen_dev *pkt_dev) *mpls |= MPLS_STACK_BOTTOM; } -static inline __be16 build_tci(unsigned int id, unsigned int cfi, - unsigned int prio) -{ - return htons(id | (cfi << 12) | (prio << 13)); -} - static struct sk_buff *fill_packet_ipv4(struct net_device *odev, struct pktgen_dev *pkt_dev) { @@ -2359,16 +2353,16 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev, if (pkt_dev->vlan_id != 0xffff) { if(pkt_dev->svlan_id != 0xffff) { svlan_tci = (__be16 *)skb_put(skb, sizeof(__be16)); - *svlan_tci = build_tci(pkt_dev->svlan_id, - pkt_dev->svlan_cfi, - pkt_dev->svlan_p); + *svlan_tci = htons(pkt_dev->svlan_id); + *svlan_tci |= pkt_dev->svlan_p << 5; + *svlan_tci |= pkt_dev->svlan_cfi << 4; svlan_encapsulated_proto = (__be16 *)skb_put(skb, sizeof(__be16)); *svlan_encapsulated_proto = __constant_htons(ETH_P_8021Q); } vlan_tci = (__be16 *)skb_put(skb, sizeof(__be16)); - *vlan_tci = build_tci(pkt_dev->vlan_id, - pkt_dev->vlan_cfi, - pkt_dev->vlan_p); + *vlan_tci = htons(pkt_dev->vlan_id); + *vlan_tci |= pkt_dev->vlan_p << 5; + *vlan_tci |= pkt_dev->vlan_cfi << 4; vlan_encapsulated_proto = (__be16 *)skb_put(skb, sizeof(__be16)); *vlan_encapsulated_proto = __constant_htons(ETH_P_IP); } @@ -2695,16 +2689,16 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev, if (pkt_dev->vlan_id != 0xffff) { if(pkt_dev->svlan_id != 0xffff) { svlan_tci = (__be16 *)skb_put(skb, sizeof(__be16)); - *svlan_tci = build_tci(pkt_dev->svlan_id, - pkt_dev->svlan_cfi, - pkt_dev->svlan_p); + *svlan_tci = htons(pkt_dev->svlan_id); + *svlan_tci |= pkt_dev->svlan_p << 5; + *svlan_tci |= pkt_dev->svlan_cfi << 4; svlan_encapsulated_proto = (__be16 *)skb_put(skb, sizeof(__be16)); *svlan_encapsulated_proto = __constant_htons(ETH_P_8021Q); } vlan_tci = (__be16 *)skb_put(skb, sizeof(__be16)); - *vlan_tci = build_tci(pkt_dev->vlan_id, - pkt_dev->vlan_cfi, - pkt_dev->vlan_p); + *vlan_tci = htons(pkt_dev->vlan_id); + *vlan_tci |= pkt_dev->vlan_p << 5; + *vlan_tci |= pkt_dev->vlan_cfi << 4; vlan_encapsulated_proto = (__be16 *)skb_put(skb, sizeof(__be16)); *vlan_encapsulated_proto = __constant_htons(ETH_P_IPV6); } diff --git a/trunk/net/core/rtnetlink.c b/trunk/net/core/rtnetlink.c index 02f3c7947898..221e4038216b 100644 --- a/trunk/net/core/rtnetlink.c +++ b/trunk/net/core/rtnetlink.c @@ -602,7 +602,7 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) goto errout; } - err = rtnl_unicast(nskb, NETLINK_CB(skb).pid); + err = rtnl_unicast(skb, NETLINK_CB(skb).pid); errout: kfree(iw_buf); dev_put(dev); diff --git a/trunk/net/core/scm.c b/trunk/net/core/scm.c index 271cf060ef8c..649d01ef35b6 100644 --- a/trunk/net/core/scm.c +++ b/trunk/net/core/scm.c @@ -245,7 +245,8 @@ void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm) if (i > 0) { int cmlen = CMSG_LEN(i*sizeof(int)); - err = put_user(SOL_SOCKET, &cm->cmsg_level); + if (!err) + err = put_user(SOL_SOCKET, &cm->cmsg_level); if (!err) err = put_user(SCM_RIGHTS, &cm->cmsg_type); if (!err) diff --git a/trunk/net/core/skbuff.c b/trunk/net/core/skbuff.c index b8b106358040..3c23760c5827 100644 --- a/trunk/net/core/skbuff.c +++ b/trunk/net/core/skbuff.c @@ -639,7 +639,6 @@ struct sk_buff *pskb_copy(struct sk_buff *skb, gfp_t gfp_mask) n->csum = skb->csum; n->ip_summed = skb->ip_summed; - n->truesize += skb->data_len; n->data_len = skb->data_len; n->len = skb->len; @@ -1947,7 +1946,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, int features) do { struct sk_buff *nskb; skb_frag_t *frag; - int hsize; + int hsize, nsize; int k; int size; @@ -1958,10 +1957,11 @@ struct sk_buff *skb_segment(struct sk_buff *skb, int features) hsize = skb_headlen(skb) - offset; if (hsize < 0) hsize = 0; - if (hsize > len || !sg) - hsize = len; + nsize = hsize + doffset; + if (nsize > len + doffset || !sg) + nsize = len + doffset; - nskb = alloc_skb(hsize + doffset + headroom, GFP_ATOMIC); + nskb = alloc_skb(nsize + headroom, GFP_ATOMIC); if (unlikely(!nskb)) goto err; diff --git a/trunk/net/core/sock.c b/trunk/net/core/sock.c index ee6cd2541d35..b77e155cbe6c 100644 --- a/trunk/net/core/sock.c +++ b/trunk/net/core/sock.c @@ -823,7 +823,7 @@ static void inline sock_lock_init(struct sock *sk) 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); + af_family_keys + sk->sk_family); } /** @@ -1160,7 +1160,7 @@ static struct sk_buff *sock_alloc_send_pskb(struct sock *sk, goto failure; if (atomic_read(&sk->sk_wmem_alloc) < sk->sk_sndbuf) { - skb = alloc_skb(header_len, gfp_mask); + skb = alloc_skb(header_len, sk->sk_allocation); if (skb) { int npages; int i; diff --git a/trunk/net/core/utils.c b/trunk/net/core/utils.c index d93fe64f6693..94c5d761c830 100644 --- a/trunk/net/core/utils.c +++ b/trunk/net/core/utils.c @@ -30,6 +30,119 @@ #include #include +/* + This is a maximally equidistributed combined Tausworthe generator + based on code from GNU Scientific Library 1.5 (30 Jun 2004) + + x_n = (s1_n ^ s2_n ^ s3_n) + + s1_{n+1} = (((s1_n & 4294967294) <<12) ^ (((s1_n <<13) ^ s1_n) >>19)) + s2_{n+1} = (((s2_n & 4294967288) << 4) ^ (((s2_n << 2) ^ s2_n) >>25)) + s3_{n+1} = (((s3_n & 4294967280) <<17) ^ (((s3_n << 3) ^ s3_n) >>11)) + + The period of this generator is about 2^88. + + From: P. L'Ecuyer, "Maximally Equidistributed Combined Tausworthe + Generators", Mathematics of Computation, 65, 213 (1996), 203--213. + + This is available on the net from L'Ecuyer's home page, + + http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme.ps + ftp://ftp.iro.umontreal.ca/pub/simulation/lecuyer/papers/tausme.ps + + There is an erratum in the paper "Tables of Maximally + Equidistributed Combined LFSR Generators", Mathematics of + Computation, 68, 225 (1999), 261--269: + http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme2.ps + + ... the k_j most significant bits of z_j must be non- + zero, for each j. (Note: this restriction also applies to the + computer code given in [4], but was mistakenly not mentioned in + that paper.) + + This affects the seeding procedure by imposing the requirement + s1 > 1, s2 > 7, s3 > 15. + +*/ +struct nrnd_state { + u32 s1, s2, s3; +}; + +static DEFINE_PER_CPU(struct nrnd_state, net_rand_state); + +static u32 __net_random(struct nrnd_state *state) +{ +#define TAUSWORTHE(s,a,b,c,d) ((s&c)<>b) + + state->s1 = TAUSWORTHE(state->s1, 13, 19, 4294967294UL, 12); + state->s2 = TAUSWORTHE(state->s2, 2, 25, 4294967288UL, 4); + state->s3 = TAUSWORTHE(state->s3, 3, 11, 4294967280UL, 17); + + return (state->s1 ^ state->s2 ^ state->s3); +} + +static void __net_srandom(struct nrnd_state *state, unsigned long s) +{ + if (s == 0) + s = 1; /* default seed is 1 */ + +#define LCG(n) (69069 * n) + state->s1 = LCG(s); + state->s2 = LCG(state->s1); + state->s3 = LCG(state->s2); + + /* "warm it up" */ + __net_random(state); + __net_random(state); + __net_random(state); + __net_random(state); + __net_random(state); + __net_random(state); +} + + +unsigned long net_random(void) +{ + unsigned long r; + struct nrnd_state *state = &get_cpu_var(net_rand_state); + r = __net_random(state); + put_cpu_var(state); + return r; +} + + +void net_srandom(unsigned long entropy) +{ + struct nrnd_state *state = &get_cpu_var(net_rand_state); + __net_srandom(state, state->s1^entropy); + put_cpu_var(state); +} + +void __init net_random_init(void) +{ + int i; + + for_each_possible_cpu(i) { + struct nrnd_state *state = &per_cpu(net_rand_state,i); + __net_srandom(state, i+jiffies); + } +} + +static int net_random_reseed(void) +{ + int i; + unsigned long seed; + + for_each_possible_cpu(i) { + struct nrnd_state *state = &per_cpu(net_rand_state,i); + + get_random_bytes(&seed, sizeof(seed)); + __net_srandom(state, seed); + } + return 0; +} +late_initcall(net_random_reseed); + int net_msg_cost = 5*HZ; int net_msg_burst = 10; @@ -40,7 +153,10 @@ int net_ratelimit(void) { return __printk_ratelimit(net_msg_cost, net_msg_burst); } + +EXPORT_SYMBOL(net_random); EXPORT_SYMBOL(net_ratelimit); +EXPORT_SYMBOL(net_srandom); /* * Convert an ASCII string to binary IP. diff --git a/trunk/net/core/wireless.c b/trunk/net/core/wireless.c index cb1b8728d7ee..ffff0da46c6e 100644 --- a/trunk/net/core/wireless.c +++ b/trunk/net/core/wireless.c @@ -748,39 +748,11 @@ static int ioctl_standard_call(struct net_device * dev, int extra_size; int user_length = 0; int err; - int essid_compat = 0; /* Calculate space needed by arguments. Always allocate * for max space. Easier, and won't last long... */ extra_size = descr->max_tokens * descr->token_size; - /* Check need for ESSID compatibility for WE < 21 */ - switch (cmd) { - case SIOCSIWESSID: - case SIOCGIWESSID: - case SIOCSIWNICKN: - case SIOCGIWNICKN: - if (iwr->u.data.length == descr->max_tokens + 1) - essid_compat = 1; - else if (IW_IS_SET(cmd) && (iwr->u.data.length != 0)) { - char essid[IW_ESSID_MAX_SIZE + 1]; - - err = copy_from_user(essid, iwr->u.data.pointer, - iwr->u.data.length * - descr->token_size); - if (err) - return -EFAULT; - - if (essid[iwr->u.data.length - 1] == '\0') - essid_compat = 1; - } - break; - default: - break; - } - - iwr->u.data.length -= essid_compat; - /* Check what user space is giving us */ if(IW_IS_SET(cmd)) { /* Check NULL pointer */ @@ -823,8 +795,7 @@ static int ioctl_standard_call(struct net_device * dev, #endif /* WE_IOCTL_DEBUG */ /* Create the kernel buffer */ - /* kzalloc ensures NULL-termination for essid_compat */ - extra = kzalloc(extra_size, GFP_KERNEL); + extra = kmalloc(extra_size, GFP_KERNEL); if (extra == NULL) { return -ENOMEM; } @@ -848,8 +819,6 @@ static int ioctl_standard_call(struct net_device * dev, /* Call the handler */ ret = handler(dev, &info, &(iwr->u), extra); - iwr->u.data.length += essid_compat; - /* If we have something to return to the user */ if (!ret && IW_IS_GET(cmd)) { /* Check if there is enough buffer up there */ diff --git a/trunk/net/dccp/Kconfig b/trunk/net/dccp/Kconfig index ef8919cca74b..e2a095d0fd80 100644 --- a/trunk/net/dccp/Kconfig +++ b/trunk/net/dccp/Kconfig @@ -4,15 +4,15 @@ menu "DCCP Configuration (EXPERIMENTAL)" config IP_DCCP tristate "The DCCP Protocol (EXPERIMENTAL)" ---help--- - Datagram Congestion Control Protocol (RFC 4340) + Datagram Congestion Control Protocol - From http://www.ietf.org/rfc/rfc4340.txt: + From draft-ietf-dccp-spec-11 . The Datagram Congestion Control Protocol (DCCP) is a transport protocol that implements bidirectional, unicast connections of congestion-controlled, unreliable datagrams. It should be suitable for use by applications such as streaming media, Internet telephony, - and on-line games. + and on-line games To compile this protocol support as a module, choose M here: the module will be called dccp. diff --git a/trunk/net/dccp/ackvec.c b/trunk/net/dccp/ackvec.c index f8208874ac7d..4d176d33983f 100644 --- a/trunk/net/dccp/ackvec.c +++ b/trunk/net/dccp/ackvec.c @@ -113,7 +113,7 @@ int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb) memcpy(to, from, len); /* - * From RFC 4340, A.2: + * From draft-ietf-dccp-spec-11.txt: * * For each acknowledgement it sends, the HC-Receiver will add an * acknowledgement record. ack_seqno will equal the HC-Receiver @@ -224,7 +224,7 @@ static inline int dccp_ackvec_set_buf_head_state(struct dccp_ackvec *av, } /* - * Implements the RFC 4340, Appendix A + * Implements the draft-ietf-dccp-spec-11.txt Appendix A */ int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk, const u64 ackno, const u8 state) @@ -237,7 +237,7 @@ int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk, * We may well decide to do buffer compression, etc, but for now lets * just drop. * - * From Appendix A.1.1 (`New Packets'): + * From Appendix A: * * Of course, the circular buffer may overflow, either when the * HC-Sender is sending data at a very high rate, when the @@ -274,9 +274,9 @@ int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk, /* * A.1.2. Old Packets * - * When a packet with Sequence Number S <= buf_ackno - * arrives, the HC-Receiver will scan the table for - * the byte corresponding to S. (Indexing structures + * When a packet with Sequence Number S arrives, and + * S <= buf_ackno, the HC-Receiver will scan the table + * for the byte corresponding to S. (Indexing structures * could reduce the complexity of this scan.) */ u64 delta = dccp_delta_seqno(ackno, av->dccpav_buf_ackno); diff --git a/trunk/net/dccp/ackvec.h b/trunk/net/dccp/ackvec.h index cf8f20ce23a9..2424effac7f6 100644 --- a/trunk/net/dccp/ackvec.h +++ b/trunk/net/dccp/ackvec.h @@ -28,7 +28,8 @@ /** struct dccp_ackvec - ack vector * - * This data structure is the one defined in RFC 4340, Appendix A. + * This data structure is the one defined in the DCCP draft + * Appendix A. * * @dccpav_buf_head - circular buffer head * @dccpav_buf_tail - circular buffer tail diff --git a/trunk/net/dccp/ccids/Kconfig b/trunk/net/dccp/ccids/Kconfig index 8533dabfb9f8..32752f750447 100644 --- a/trunk/net/dccp/ccids/Kconfig +++ b/trunk/net/dccp/ccids/Kconfig @@ -22,11 +22,11 @@ config IP_DCCP_CCID2 for lost packets, would prefer CCID 2 to CCID 3. On-line games may also prefer CCID 2. - CCID 2 is further described in RFC 4341, - http://www.ietf.org/rfc/rfc4341.txt + CCID 2 is further described in: + http://www.icir.org/kohler/dccp/draft-ietf-dccp-ccid2-10.txt - This text was extracted from RFC 4340 (sec. 10.1), - http://www.ietf.org/rfc/rfc4340.txt + This text was extracted from: + http://www.icir.org/kohler/dccp/draft-ietf-dccp-spec-13.txt If in doubt, say M. @@ -53,14 +53,15 @@ config IP_DCCP_CCID3 suitable than CCID 2 for applications such streaming media where a relatively smooth sending rate is of importance. - CCID 3 is further described in RFC 4342, - http://www.ietf.org/rfc/rfc4342.txt + CCID 3 is further described in: + + http://www.icir.org/kohler/dccp/draft-ietf-dccp-ccid3-11.txt. The TFRC congestion control algorithms were initially described in RFC 3448. - This text was extracted from RFC 4340 (sec. 10.2), - http://www.ietf.org/rfc/rfc4340.txt + This text was extracted from: + http://www.icir.org/kohler/dccp/draft-ietf-dccp-spec-13.txt If in doubt, say M. diff --git a/trunk/net/dccp/ccids/ccid2.c b/trunk/net/dccp/ccids/ccid2.c index 162032baeac0..2efb505aeb35 100644 --- a/trunk/net/dccp/ccids/ccid2.c +++ b/trunk/net/dccp/ccids/ccid2.c @@ -23,7 +23,7 @@ */ /* - * This implementation should follow RFC 4341 + * This implementation should follow: draft-ietf-dccp-ccid2-10.txt * * BUGS: * - sequence number wrapping @@ -352,14 +352,14 @@ static void ccid2_hc_tx_packet_sent(struct sock *sk, int more, int len) #ifdef CONFIG_IP_DCCP_CCID2_DEBUG ccid2_pr_debug("pipe=%d\n", hctx->ccid2hctx_pipe); - ccid2_pr_debug("Sent: seq=%llu\n", (unsigned long long)seq); + ccid2_pr_debug("Sent: seq=%llu\n", seq); do { struct ccid2_seq *seqp = hctx->ccid2hctx_seqt; while (seqp != hctx->ccid2hctx_seqh) { ccid2_pr_debug("out seq=%llu acked=%d time=%lu\n", - (unsigned long long)seqp->ccid2s_seq, - seqp->ccid2s_acked, seqp->ccid2s_sent); + seqp->ccid2s_seq, seqp->ccid2s_acked, + seqp->ccid2s_sent); seqp = seqp->ccid2s_next; } } while (0); @@ -480,8 +480,7 @@ static inline void ccid2_new_ack(struct sock *sk, /* first measurement */ if (hctx->ccid2hctx_srtt == -1) { ccid2_pr_debug("R: %lu Time=%lu seq=%llu\n", - r, jiffies, - (unsigned long long)seqp->ccid2s_seq); + r, jiffies, seqp->ccid2s_seq); ccid2_change_srtt(hctx, r); hctx->ccid2hctx_rttvar = r >> 1; } else { @@ -637,9 +636,8 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) u64 ackno_end_rl; dccp_set_seqno(&ackno_end_rl, ackno - rl); - ccid2_pr_debug("ackvec start:%llu end:%llu\n", - (unsigned long long)ackno, - (unsigned long long)ackno_end_rl); + ccid2_pr_debug("ackvec start:%llu end:%llu\n", ackno, + ackno_end_rl); /* if the seqno we are analyzing is larger than the * current ackno, then move towards the tail of our * seqnos. @@ -674,7 +672,7 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) seqp->ccid2s_acked = 1; ccid2_pr_debug("Got ack for %llu\n", - (unsigned long long)seqp->ccid2s_seq); + seqp->ccid2s_seq); ccid2_hc_tx_dec_pipe(sk); } if (seqp == hctx->ccid2hctx_seqt) { @@ -720,7 +718,7 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) while (1) { if (!seqp->ccid2s_acked) { ccid2_pr_debug("Packet lost: %llu\n", - (unsigned long long)seqp->ccid2s_seq); + seqp->ccid2s_seq); /* XXX need to traverse from tail -> head in * order to detect multiple congestion events in * one ack vector. diff --git a/trunk/net/dccp/ccids/ccid3.c b/trunk/net/dccp/ccids/ccid3.c index cec23ad286de..67d2dc0e7c67 100644 --- a/trunk/net/dccp/ccids/ccid3.c +++ b/trunk/net/dccp/ccids/ccid3.c @@ -379,7 +379,8 @@ static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, int len) packet->dccphtx_seqno = dp->dccps_gss; /* * Check if win_count have changed - * Algorithm in "8.1. Window Counter Value" in RFC 4342. + * Algorithm in "8.1. Window Counter Valuer" in + * draft-ietf-dccp-ccid3-11.txt */ quarter_rtt = timeval_delta(&now, &hctx->ccid3hctx_t_last_win_count); if (likely(hctx->ccid3hctx_rtt > 8)) diff --git a/trunk/net/dccp/dccp.h b/trunk/net/dccp/dccp.h index 272e8584564e..0a21be437ed3 100644 --- a/trunk/net/dccp/dccp.h +++ b/trunk/net/dccp/dccp.h @@ -50,7 +50,7 @@ extern void dccp_time_wait(struct sock *sk, int state, int timeo); #define DCCP_TIMEWAIT_LEN (60 * HZ) /* how long to wait to destroy TIME-WAIT * state, about 60 seconds */ -/* RFC 1122, 4.2.3.1 initial RTO value */ +/* draft-ietf-dccp-spec-11.txt initial RTO value */ #define DCCP_TIMEOUT_INIT ((unsigned)(3 * HZ)) /* Maximal interval between probes for local resources. */ diff --git a/trunk/net/dccp/input.c b/trunk/net/dccp/input.c index 1d24881ac0ab..7f9dc6ac58c9 100644 --- a/trunk/net/dccp/input.c +++ b/trunk/net/dccp/input.c @@ -216,11 +216,11 @@ static int __dccp_rcv_established(struct sock *sk, struct sk_buff *skb, dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq, DCCP_PKT_SYNCACK); /* - * From RFC 4340, sec. 5.7 + * From the draft: * * As with DCCP-Ack packets, DCCP-Sync and DCCP-SyncAck packets * MAY have non-zero-length application data areas, whose - * contents receivers MUST ignore. + * contents * receivers MUST ignore. */ goto discard; } diff --git a/trunk/net/dccp/ipv4.c b/trunk/net/dccp/ipv4.c index e08e7688a263..bf692c1c116f 100644 --- a/trunk/net/dccp/ipv4.c +++ b/trunk/net/dccp/ipv4.c @@ -183,7 +183,7 @@ static inline void dccp_do_pmtu_discovery(struct sock *sk, dccp_sync_mss(sk, mtu); /* - * From RFC 4340, sec. 14.1: + * From: draft-ietf-dccp-spec-11.txt * * DCCP-Sync packets are the best choice for upward * probing, since DCCP-Sync probes do not risk application @@ -311,7 +311,7 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info) } if (sk->sk_state == DCCP_TIME_WAIT) { - inet_twsk_put(inet_twsk(sk)); + inet_twsk_put((struct inet_timewait_sock *)sk); return; } @@ -449,8 +449,6 @@ static inline u64 dccp_v4_init_sequence(const struct sock *sk, dccp_hdr(skb)->dccph_sport); } -static struct request_sock_ops dccp_request_sock_ops; - int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb) { struct inet_request_sock *ireq; @@ -491,7 +489,7 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb) if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1) goto drop; - req = reqsk_alloc(&dccp_request_sock_ops); + req = reqsk_alloc(sk->sk_prot->rsk_prot); if (req == NULL) goto drop; @@ -616,7 +614,7 @@ static struct sock *dccp_v4_hnd_req(struct sock *sk, struct sk_buff *skb) bh_lock_sock(nsk); return nsk; } - inet_twsk_put(inet_twsk(nsk)); + inet_twsk_put((struct inet_timewait_sock *)nsk); return NULL; } @@ -733,7 +731,7 @@ static void dccp_v4_ctl_send_reset(struct sk_buff *rxskb) dccp_hdr_reset(skb)->dccph_reset_code = DCCP_SKB_CB(rxskb)->dccpd_reset_code; - /* See "8.3.1. Abnormal Termination" in RFC 4340 */ + /* See "8.3.1. Abnormal Termination" in draft-ietf-dccp-spec-11 */ seqno = 0; if (DCCP_SKB_CB(rxskb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) dccp_set_seqno(&seqno, DCCP_SKB_CB(rxskb)->dccpd_ack_seq + 1); @@ -982,7 +980,7 @@ static int dccp_v4_rcv(struct sk_buff *skb) goto discard_it; do_time_wait: - inet_twsk_put(inet_twsk(sk)); + inet_twsk_put((struct inet_timewait_sock *)sk); goto no_dccp_socket; } diff --git a/trunk/net/dccp/ipv6.c b/trunk/net/dccp/ipv6.c index fc4242c0767c..7a47399cf31f 100644 --- a/trunk/net/dccp/ipv6.c +++ b/trunk/net/dccp/ipv6.c @@ -277,7 +277,7 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, __u64 seq; sk = inet6_lookup(&dccp_hashinfo, &hdr->daddr, dh->dccph_dport, - &hdr->saddr, dh->dccph_sport, inet6_iif(skb)); + &hdr->saddr, dh->dccph_sport, skb->dev->ifindex); if (sk == NULL) { ICMP6_INC_STATS_BH(__in6_dev_get(skb->dev), ICMP6_MIB_INERRORS); @@ -285,7 +285,7 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, } if (sk->sk_state == DCCP_TIME_WAIT) { - inet_twsk_put(inet_twsk(sk)); + inet_twsk_put((struct inet_timewait_sock *)sk); return; } @@ -550,7 +550,7 @@ static void dccp_v6_ctl_send_reset(struct sk_buff *rxskb) dccp_hdr_reset(skb)->dccph_reset_code = DCCP_SKB_CB(rxskb)->dccpd_reset_code; - /* See "8.3.1. Abnormal Termination" in RFC 4340 */ + /* See "8.3.1. Abnormal Termination" in draft-ietf-dccp-spec-11 */ seqno = 0; if (DCCP_SKB_CB(rxskb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) dccp_set_seqno(&seqno, DCCP_SKB_CB(rxskb)->dccpd_ack_seq + 1); @@ -663,7 +663,7 @@ static struct sock *dccp_v6_hnd_req(struct sock *sk,struct sk_buff *skb) bh_lock_sock(nsk); return nsk; } - inet_twsk_put(inet_twsk(nsk)); + inet_twsk_put((struct inet_timewait_sock *)nsk); return NULL; } @@ -672,6 +672,7 @@ static struct sock *dccp_v6_hnd_req(struct sock *sk,struct sk_buff *skb) static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb) { + struct inet_request_sock *ireq; struct dccp_sock dp; struct request_sock *req; struct dccp_request_sock *dreq; @@ -700,7 +701,7 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb) if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1) goto drop; - req = inet6_reqsk_alloc(&dccp6_request_sock_ops); + req = inet6_reqsk_alloc(sk->sk_prot->rsk_prot); if (req == NULL) goto drop; @@ -712,6 +713,7 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb) goto drop_and_free; ireq6 = inet6_rsk(req); + ireq = inet_rsk(req); ipv6_addr_copy(&ireq6->rmt_addr, &skb->nh.ipv6h->saddr); ipv6_addr_copy(&ireq6->loc_addr, &skb->nh.ipv6h->daddr); req->rcv_wnd = dccp_feat_default_sequence_window; @@ -995,10 +997,6 @@ static int dccp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) if (sk->sk_state == DCCP_OPEN) { /* Fast path */ if (dccp_rcv_established(sk, skb, dccp_hdr(skb), skb->len)) goto reset; - if (opt_skb) { - /* This is where we would goto ipv6_pktoptions. */ - __kfree_skb(opt_skb); - } return 0; } @@ -1023,10 +1021,6 @@ static int dccp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) if (dccp_rcv_state_process(sk, skb, dccp_hdr(skb), skb->len)) goto reset; - if (opt_skb) { - /* This is where we would goto ipv6_pktoptions. */ - __kfree_skb(opt_skb); - } return 0; reset: @@ -1115,7 +1109,7 @@ static int dccp_v6_rcv(struct sk_buff **pskb) goto discard_it; do_time_wait: - inet_twsk_put(inet_twsk(sk)); + inet_twsk_put((struct inet_timewait_sock *)sk); goto no_dccp_socket; } diff --git a/trunk/net/dccp/options.c b/trunk/net/dccp/options.c index fb0db1f7cd7b..07a34696ac97 100644 --- a/trunk/net/dccp/options.c +++ b/trunk/net/dccp/options.c @@ -215,7 +215,7 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb) elapsed_time); break; /* - * From RFC 4340, sec. 10.3: + * From draft-ietf-dccp-spec-11.txt: * * Option numbers 128 through 191 are for * options sent from the HC-Sender to the diff --git a/trunk/net/dccp/probe.c b/trunk/net/dccp/probe.c index fded1493c1dc..146496fce2e2 100644 --- a/trunk/net/dccp/probe.c +++ b/trunk/net/dccp/probe.c @@ -160,8 +160,6 @@ static __init int dccpprobe_init(void) init_waitqueue_head(&dccpw.wait); spin_lock_init(&dccpw.lock); dccpw.fifo = kfifo_alloc(bufsize, GFP_KERNEL, &dccpw.lock); - if (IS_ERR(dccpw.fifo)) - return PTR_ERR(dccpw.fifo); if (!proc_net_fops_create(procname, S_IRUSR, &dccpprobe_fops)) goto err0; diff --git a/trunk/net/decnet/af_decnet.c b/trunk/net/decnet/af_decnet.c index 21f20f21dd32..70e027375682 100644 --- a/trunk/net/decnet/af_decnet.c +++ b/trunk/net/decnet/af_decnet.c @@ -166,7 +166,7 @@ static struct hlist_head *dn_find_list(struct sock *sk) if (scp->addr.sdn_flags & SDF_WILD) return hlist_empty(&dn_wild_sk) ? &dn_wild_sk : NULL; - return &dn_sk_hash[dn_ntohs(scp->addrloc) & DN_SK_HASH_MASK]; + return &dn_sk_hash[scp->addrloc & DN_SK_HASH_MASK]; } /* @@ -180,7 +180,7 @@ static int check_port(__le16 port) if (port == 0) return -1; - sk_for_each(sk, node, &dn_sk_hash[dn_ntohs(port) & DN_SK_HASH_MASK]) { + sk_for_each(sk, node, &dn_sk_hash[port & DN_SK_HASH_MASK]) { struct dn_scp *scp = DN_SK(sk); if (scp->addrloc == port) return -1; @@ -194,12 +194,12 @@ static unsigned short port_alloc(struct sock *sk) static unsigned short port = 0x2000; unsigned short i_port = port; - while(check_port(dn_htons(++port)) != 0) { + while(check_port(++port) != 0) { if (port == i_port) return 0; } - scp->addrloc = dn_htons(port); + scp->addrloc = port; return 1; } @@ -418,7 +418,7 @@ struct sock *dn_find_by_skb(struct sk_buff *skb) struct dn_scp *scp; read_lock(&dn_hash_lock); - sk_for_each(sk, node, &dn_sk_hash[dn_ntohs(cb->dst_port) & DN_SK_HASH_MASK]) { + sk_for_each(sk, node, &dn_sk_hash[cb->dst_port & DN_SK_HASH_MASK]) { scp = DN_SK(sk); if (cb->src != dn_saddr2dn(&scp->peer)) continue; @@ -1016,14 +1016,13 @@ static void dn_access_copy(struct sk_buff *skb, struct accessdata_dn *acc) static void dn_user_copy(struct sk_buff *skb, struct optdata_dn *opt) { - unsigned char *ptr = skb->data; - u16 len = *ptr++; /* yes, it's 8bit on the wire */ - - BUG_ON(len > 16); /* we've checked the contents earlier */ - opt->opt_optl = dn_htons(len); - opt->opt_status = 0; - memcpy(opt->opt_data, ptr, len); - skb_pull(skb, len + 1); + unsigned char *ptr = skb->data; + + opt->opt_optl = *ptr++; + opt->opt_status = 0; + memcpy(opt->opt_data, ptr, opt->opt_optl); + skb_pull(skb, dn_ntohs(opt->opt_optl) + 1); + } static struct sk_buff *dn_wait_for_connect(struct sock *sk, long *timeo) @@ -1179,10 +1178,8 @@ static int dn_getname(struct socket *sock, struct sockaddr *uaddr,int *uaddr_len if (peer) { if ((sock->state != SS_CONNECTED && sock->state != SS_CONNECTING) && - scp->accept_mode == ACC_IMMED) { - release_sock(sk); + scp->accept_mode == ACC_IMMED) return -ENOTCONN; - } memcpy(sa, &scp->peer, sizeof(struct sockaddr_dn)); } else { diff --git a/trunk/net/decnet/dn_nsp_in.c b/trunk/net/decnet/dn_nsp_in.c index 7683d4f754d2..72ecc6e62ec4 100644 --- a/trunk/net/decnet/dn_nsp_in.c +++ b/trunk/net/decnet/dn_nsp_in.c @@ -360,9 +360,9 @@ static void dn_nsp_conn_conf(struct sock *sk, struct sk_buff *skb) scp->max_window = decnet_no_fc_max_cwnd; if (skb->len > 0) { - u16 dlen = *skb->data; + unsigned char dlen = *skb->data; if ((dlen <= 16) && (dlen <= skb->len)) { - scp->conndata_in.opt_optl = dn_htons(dlen); + scp->conndata_in.opt_optl = dn_htons((__u16)dlen); memcpy(scp->conndata_in.opt_data, skb->data + 1, dlen); } } @@ -404,9 +404,9 @@ static void dn_nsp_disc_init(struct sock *sk, struct sk_buff *skb) memset(scp->discdata_in.opt_data, 0, 16); if (skb->len > 0) { - u16 dlen = *skb->data; + unsigned char dlen = *skb->data; if ((dlen <= 16) && (dlen <= skb->len)) { - scp->discdata_in.opt_optl = dn_htons(dlen); + scp->discdata_in.opt_optl = dn_htons((__u16)dlen); memcpy(scp->discdata_in.opt_data, skb->data + 1, dlen); } } diff --git a/trunk/net/decnet/dn_nsp_out.c b/trunk/net/decnet/dn_nsp_out.c index b342e4e8f5f8..c2e21cd89b3c 100644 --- a/trunk/net/decnet/dn_nsp_out.c +++ b/trunk/net/decnet/dn_nsp_out.c @@ -526,7 +526,7 @@ void dn_send_conn_conf(struct sock *sk, gfp_t gfp) struct nsp_conn_init_msg *msg; __u8 len = (__u8)dn_ntohs(scp->conndata_out.opt_optl); - if ((skb = dn_alloc_skb(sk, 50 + len, gfp)) == NULL) + if ((skb = dn_alloc_skb(sk, 50 + dn_ntohs(scp->conndata_out.opt_optl), gfp)) == NULL) return; msg = (struct nsp_conn_init_msg *)skb_put(skb, sizeof(*msg)); diff --git a/trunk/net/decnet/dn_route.c b/trunk/net/decnet/dn_route.c index 23489f7232d2..dd0761e3d280 100644 --- a/trunk/net/decnet/dn_route.c +++ b/trunk/net/decnet/dn_route.c @@ -267,14 +267,9 @@ static void dn_dst_link_failure(struct sk_buff *skb) static inline int compare_keys(struct flowi *fl1, struct flowi *fl2) { - return ((fl1->nl_u.dn_u.daddr ^ fl2->nl_u.dn_u.daddr) | - (fl1->nl_u.dn_u.saddr ^ fl2->nl_u.dn_u.saddr) | -#ifdef CONFIG_DECNET_ROUTE_FWMARK - (fl1->nl_u.dn_u.fwmark ^ fl2->nl_u.dn_u.fwmark) | -#endif - (fl1->nl_u.dn_u.scope ^ fl2->nl_u.dn_u.scope) | - (fl1->oif ^ fl2->oif) | - (fl1->iif ^ fl2->iif)) == 0; + return memcmp(&fl1->nl_u.dn_u, &fl2->nl_u.dn_u, sizeof(fl1->nl_u.dn_u)) == 0 && + fl1->oif == fl2->oif && + fl1->iif == fl2->iif; } static int dn_insert_route(struct dn_route *rt, unsigned hash, struct dn_route **rp) @@ -1275,6 +1270,7 @@ static int dn_route_input_slow(struct sk_buff *skb) goto e_inval; res.type = RTN_LOCAL; + flags |= RTCF_DIRECTSRC; } else { __le16 src_map = fl.fld_src; free_res = 1; @@ -1345,7 +1341,7 @@ static int dn_route_input_slow(struct sk_buff *skb) goto make_route; /* Packet was intra-ethernet, so we know its on-link */ - if (cb->rt_flags & DN_RT_F_IE) { + if (cb->rt_flags | DN_RT_F_IE) { gateway = cb->src; flags |= RTCF_DIRECTSRC; goto make_route; diff --git a/trunk/net/decnet/dn_rules.c b/trunk/net/decnet/dn_rules.c index 590e0a72495c..3e0c882c90bf 100644 --- a/trunk/net/decnet/dn_rules.c +++ b/trunk/net/decnet/dn_rules.c @@ -124,8 +124,8 @@ static struct nla_policy dn_fib_rule_policy[FRA_MAX+1] __read_mostly = { static int dn_fib_rule_match(struct fib_rule *rule, struct flowi *fl, int flags) { struct dn_fib_rule *r = (struct dn_fib_rule *)rule; - __le16 daddr = fl->fld_dst; - __le16 saddr = fl->fld_src; + u16 daddr = fl->fld_dst; + u16 saddr = fl->fld_src; if (((saddr ^ r->src) & r->srcmask) || ((daddr ^ r->dst) & r->dstmask)) diff --git a/trunk/net/ieee80211/Kconfig b/trunk/net/ieee80211/Kconfig index a64be6cdf078..f7e84e9d13ad 100644 --- a/trunk/net/ieee80211/Kconfig +++ b/trunk/net/ieee80211/Kconfig @@ -32,7 +32,6 @@ config IEEE80211_CRYPT_WEP depends on IEEE80211 select CRYPTO select CRYPTO_ARC4 - select CRYPTO_ECB select CRC32 ---help--- Include software based cipher suites in support of IEEE @@ -59,7 +58,6 @@ config IEEE80211_CRYPT_TKIP depends on IEEE80211 && NET_RADIO select CRYPTO select CRYPTO_MICHAEL_MIC - select CRYPTO_ECB select CRC32 ---help--- Include software based cipher suites in support of IEEE 802.11i diff --git a/trunk/net/ieee80211/ieee80211_rx.c b/trunk/net/ieee80211/ieee80211_rx.c index 2759312a4204..770704183a1b 100644 --- a/trunk/net/ieee80211/ieee80211_rx.c +++ b/trunk/net/ieee80211/ieee80211_rx.c @@ -1078,12 +1078,12 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element while (length >= sizeof(*info_element)) { if (sizeof(*info_element) + info_element->len > length) { - IEEE80211_DEBUG_MGMT("Info elem: parse failed: " - "info_element->len + 2 > left : " - "info_element->len+2=%zd left=%d, id=%d.\n", - info_element->len + - sizeof(*info_element), - length, info_element->id); + IEEE80211_ERROR("Info elem: parse failed: " + "info_element->len + 2 > left : " + "info_element->len+2=%zd left=%d, id=%d.\n", + info_element->len + + sizeof(*info_element), + length, info_element->id); /* We stop processing but don't return an error here * because some misbehaviour APs break this rule. ie. * Orinoco AP1000. */ diff --git a/trunk/net/ieee80211/softmac/ieee80211softmac_assoc.c b/trunk/net/ieee80211/softmac/ieee80211softmac_assoc.c index cf51c87a971d..589f6d2c548a 100644 --- a/trunk/net/ieee80211/softmac/ieee80211softmac_assoc.c +++ b/trunk/net/ieee80211/softmac/ieee80211softmac_assoc.c @@ -48,7 +48,7 @@ ieee80211softmac_assoc(struct ieee80211softmac_device *mac, struct ieee80211soft dprintk(KERN_INFO PFX "sent association request!\n"); spin_lock_irqsave(&mac->lock, flags); - mac->associnfo.associated = 0; /* just to make sure */ + mac->associated = 0; /* just to make sure */ /* Set a timer for timeout */ /* FIXME: make timeout configurable */ @@ -62,22 +62,24 @@ ieee80211softmac_assoc_timeout(void *d) { struct ieee80211softmac_device *mac = (struct ieee80211softmac_device *)d; struct ieee80211softmac_network *n; + unsigned long flags; - mutex_lock(&mac->associnfo.mutex); + spin_lock_irqsave(&mac->lock, flags); /* we might race against ieee80211softmac_handle_assoc_response, * so make sure only one of us does something */ - if (!mac->associnfo.associating) - goto out; + if (!mac->associnfo.associating) { + spin_unlock_irqrestore(&mac->lock, flags); + return; + } mac->associnfo.associating = 0; mac->associnfo.bssvalid = 0; - mac->associnfo.associated = 0; + mac->associated = 0; n = ieee80211softmac_get_network_by_bssid_locked(mac, mac->associnfo.bssid); + spin_unlock_irqrestore(&mac->lock, flags); dprintk(KERN_INFO PFX "assoc request timed out!\n"); ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_TIMEOUT, n); -out: - mutex_unlock(&mac->associnfo.mutex); } void @@ -91,7 +93,7 @@ ieee80211softmac_disassoc(struct ieee80211softmac_device *mac) netif_carrier_off(mac->dev); - mac->associnfo.associated = 0; + mac->associated = 0; mac->associnfo.bssvalid = 0; mac->associnfo.associating = 0; ieee80211softmac_init_bss(mac); @@ -105,7 +107,7 @@ ieee80211softmac_send_disassoc_req(struct ieee80211softmac_device *mac, u16 reas { struct ieee80211softmac_network *found; - if (mac->associnfo.bssvalid && mac->associnfo.associated) { + if (mac->associnfo.bssvalid && mac->associated) { found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid); if (found) ieee80211softmac_send_mgt_frame(mac, found, IEEE80211_STYPE_DISASSOC, reason); @@ -194,18 +196,17 @@ ieee80211softmac_assoc_work(void *d) int bssvalid; unsigned long flags; - mutex_lock(&mac->associnfo.mutex); - - if (!mac->associnfo.associating) - goto out; - /* ieee80211_disassoc might clear this */ bssvalid = mac->associnfo.bssvalid; /* meh */ - if (mac->associnfo.associated) + if (mac->associated) ieee80211softmac_send_disassoc_req(mac, WLAN_REASON_DISASSOC_STA_HAS_LEFT); + spin_lock_irqsave(&mac->lock, flags); + mac->associnfo.associating = 1; + spin_unlock_irqrestore(&mac->lock, flags); + /* try to find the requested network in our list, if we found one already */ if (bssvalid || mac->associnfo.bssfixed) found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid); @@ -259,8 +260,10 @@ ieee80211softmac_assoc_work(void *d) if (!found) { if (mac->associnfo.scan_retry > 0) { + spin_lock_irqsave(&mac->lock, flags); mac->associnfo.scan_retry--; - + spin_unlock_irqrestore(&mac->lock, flags); + /* We know of no such network. Let's scan. * NB: this also happens if we had no memory to copy the network info... * Maybe we can hope to have more memory after scanning finishes ;) @@ -269,17 +272,19 @@ ieee80211softmac_assoc_work(void *d) ieee80211softmac_notify(mac->dev, IEEE80211SOFTMAC_EVENT_SCAN_FINISHED, ieee80211softmac_assoc_notify_scan, NULL); if (ieee80211softmac_start_scan(mac)) dprintk(KERN_INFO PFX "Associate: failed to initiate scan. Is device up?\n"); - goto out; + return; } else { + spin_lock_irqsave(&mac->lock, flags); mac->associnfo.associating = 0; - mac->associnfo.associated = 0; + mac->associated = 0; + spin_unlock_irqrestore(&mac->lock, flags); dprintk(KERN_INFO PFX "Unable to find matching network after scan!\n"); /* reset the retry counter for the next user request since we * break out and don't reschedule ourselves after this point. */ mac->associnfo.scan_retry = IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT; ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_NET_NOT_FOUND, NULL); - goto out; + return; } } @@ -292,7 +297,7 @@ ieee80211softmac_assoc_work(void *d) /* copy the ESSID for displaying it */ mac->associnfo.associate_essid.len = found->essid.len; memcpy(mac->associnfo.associate_essid.data, found->essid.data, IW_ESSID_MAX_SIZE + 1); - + /* we found a network! authenticate (if necessary) and associate to it. */ if (found->authenticating) { dprintk(KERN_INFO PFX "Already requested authentication, waiting...\n"); @@ -300,7 +305,7 @@ ieee80211softmac_assoc_work(void *d) mac->associnfo.assoc_wait = 1; ieee80211softmac_notify_internal(mac, IEEE80211SOFTMAC_EVENT_ANY, found, ieee80211softmac_assoc_notify_auth, NULL, GFP_KERNEL); } - goto out; + return; } if (!found->authenticated && !found->authenticating) { /* This relies on the fact that _auth_req only queues the work, @@ -316,14 +321,11 @@ ieee80211softmac_assoc_work(void *d) mac->associnfo.assoc_wait = 0; ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_FAILED, found); } - goto out; + return; } /* finally! now we can start associating */ mac->associnfo.assoc_wait = 0; ieee80211softmac_assoc(mac, found); - -out: - mutex_unlock(&mac->associnfo.mutex); } /* call this to do whatever is necessary when we're associated */ @@ -339,7 +341,7 @@ ieee80211softmac_associated(struct ieee80211softmac_device *mac, mac->bssinfo.supported_rates = net->supported_rates; ieee80211softmac_recalc_txrates(mac); - mac->associnfo.associated = 1; + mac->associated = 1; mac->associnfo.short_preamble_available = (cap & WLAN_CAPABILITY_SHORT_PREAMBLE) != 0; @@ -419,7 +421,7 @@ ieee80211softmac_handle_assoc_response(struct net_device * dev, dprintk(KERN_INFO PFX "associating failed (reason: 0x%x)!\n", status); mac->associnfo.associating = 0; mac->associnfo.bssvalid = 0; - mac->associnfo.associated = 0; + mac->associated = 0; ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_FAILED, network); } diff --git a/trunk/net/ieee80211/softmac/ieee80211softmac_io.c b/trunk/net/ieee80211/softmac/ieee80211softmac_io.c index b96931001b43..82bfddbf33a2 100644 --- a/trunk/net/ieee80211/softmac/ieee80211softmac_io.c +++ b/trunk/net/ieee80211/softmac/ieee80211softmac_io.c @@ -304,7 +304,7 @@ ieee80211softmac_auth(struct ieee80211_auth **pkt, 2 + /* Auth Transaction Seq */ 2 + /* Status Code */ /* Challenge Text IE */ - (is_shared_response ? 1 + 1 + net->challenge_len : 0) + is_shared_response ? 0 : 1 + 1 + net->challenge_len ); if (unlikely((*pkt) == NULL)) return 0; @@ -475,13 +475,8 @@ int ieee80211softmac_handle_beacon(struct net_device *dev, { struct ieee80211softmac_device *mac = ieee80211_priv(dev); - /* This might race, but we don't really care and it's not worth - * adding heavyweight locking in this fastpath. - */ - if (mac->associnfo.associated) { - if (memcmp(network->bssid, mac->associnfo.bssid, ETH_ALEN) == 0) - ieee80211softmac_process_erp(mac, network->erp_value); - } + if (mac->associated && memcmp(network->bssid, mac->associnfo.bssid, ETH_ALEN) == 0) + ieee80211softmac_process_erp(mac, network->erp_value); return 0; } diff --git a/trunk/net/ieee80211/softmac/ieee80211softmac_module.c b/trunk/net/ieee80211/softmac/ieee80211softmac_module.c index 33aff4f4a471..addea1cf73ae 100644 --- a/trunk/net/ieee80211/softmac/ieee80211softmac_module.c +++ b/trunk/net/ieee80211/softmac/ieee80211softmac_module.c @@ -57,7 +57,6 @@ struct net_device *alloc_ieee80211softmac(int sizeof_priv) INIT_LIST_HEAD(&softmac->network_list); INIT_LIST_HEAD(&softmac->events); - mutex_init(&softmac->associnfo.mutex); INIT_WORK(&softmac->associnfo.work, ieee80211softmac_assoc_work, softmac); INIT_WORK(&softmac->associnfo.timeout, ieee80211softmac_assoc_timeout, softmac); softmac->start_scan = ieee80211softmac_start_scan_implementation; diff --git a/trunk/net/ieee80211/softmac/ieee80211softmac_wx.c b/trunk/net/ieee80211/softmac/ieee80211softmac_wx.c index 23068a830f7d..2aa779d18f38 100644 --- a/trunk/net/ieee80211/softmac/ieee80211softmac_wx.c +++ b/trunk/net/ieee80211/softmac/ieee80211softmac_wx.c @@ -73,14 +73,13 @@ ieee80211softmac_wx_set_essid(struct net_device *net_dev, struct ieee80211softmac_network *n; struct ieee80211softmac_auth_queue_item *authptr; int length = 0; - - mutex_lock(&sm->associnfo.mutex); + unsigned long flags; /* Check if we're already associating to this or another network * If it's another network, cancel and start over with our new network * If it's our network, ignore the change, we're already doing it! */ - if((sm->associnfo.associating || sm->associnfo.associated) && + if((sm->associnfo.associating || sm->associated) && (data->essid.flags && data->essid.length)) { /* Get the associating network */ n = ieee80211softmac_get_network_by_bssid(sm, sm->associnfo.bssid); @@ -88,9 +87,10 @@ ieee80211softmac_wx_set_essid(struct net_device *net_dev, !memcmp(n->essid.data, extra, n->essid.len)) { dprintk(KERN_INFO PFX "Already associating or associated to "MAC_FMT"\n", MAC_ARG(sm->associnfo.bssid)); - goto out; + return 0; } else { dprintk(KERN_INFO PFX "Canceling existing associate request!\n"); + spin_lock_irqsave(&sm->lock,flags); /* Cancel assoc work */ cancel_delayed_work(&sm->associnfo.work); /* We don't have to do this, but it's a little cleaner */ @@ -98,13 +98,14 @@ ieee80211softmac_wx_set_essid(struct net_device *net_dev, cancel_delayed_work(&authptr->work); sm->associnfo.bssvalid = 0; sm->associnfo.bssfixed = 0; + spin_unlock_irqrestore(&sm->lock,flags); flush_scheduled_work(); - sm->associnfo.associating = 0; - sm->associnfo.associated = 0; } } + spin_lock_irqsave(&sm->lock, flags); + sm->associnfo.static_essid = 0; sm->associnfo.assoc_wait = 0; @@ -120,12 +121,10 @@ ieee80211softmac_wx_set_essid(struct net_device *net_dev, * If applicable, we have already copied the data in */ sm->associnfo.req_essid.len = length; - sm->associnfo.associating = 1; /* queue lower level code to do work (if necessary) */ schedule_work(&sm->associnfo.work); -out: - mutex_unlock(&sm->associnfo.mutex); + spin_unlock_irqrestore(&sm->lock, flags); return 0; } EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_essid); @@ -137,8 +136,10 @@ ieee80211softmac_wx_get_essid(struct net_device *net_dev, char *extra) { struct ieee80211softmac_device *sm = ieee80211_priv(net_dev); + unsigned long flags; - mutex_lock(&sm->associnfo.mutex); + /* avoid getting inconsistent information */ + spin_lock_irqsave(&sm->lock, flags); /* If all fails, return ANY (empty) */ data->essid.length = 0; data->essid.flags = 0; /* active */ @@ -151,13 +152,12 @@ ieee80211softmac_wx_get_essid(struct net_device *net_dev, } /* If we're associating/associated, return that */ - if (sm->associnfo.associated || sm->associnfo.associating) { + if (sm->associated || sm->associnfo.associating) { data->essid.length = sm->associnfo.associate_essid.len; data->essid.flags = 1; /* active */ memcpy(extra, sm->associnfo.associate_essid.data, sm->associnfo.associate_essid.len); } - mutex_unlock(&sm->associnfo.mutex); - + spin_unlock_irqrestore(&sm->lock, flags); return 0; } EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_essid); @@ -322,15 +322,15 @@ ieee80211softmac_wx_get_wap(struct net_device *net_dev, { struct ieee80211softmac_device *mac = ieee80211_priv(net_dev); int err = 0; + unsigned long flags; - mutex_lock(&mac->associnfo.mutex); + spin_lock_irqsave(&mac->lock, flags); if (mac->associnfo.bssvalid) memcpy(data->ap_addr.sa_data, mac->associnfo.bssid, ETH_ALEN); else memset(data->ap_addr.sa_data, 0xff, ETH_ALEN); data->ap_addr.sa_family = ARPHRD_ETHER; - mutex_unlock(&mac->associnfo.mutex); - + spin_unlock_irqrestore(&mac->lock, flags); return err; } EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_wap); @@ -342,27 +342,28 @@ ieee80211softmac_wx_set_wap(struct net_device *net_dev, char *extra) { struct ieee80211softmac_device *mac = ieee80211_priv(net_dev); + unsigned long flags; /* sanity check */ if (data->ap_addr.sa_family != ARPHRD_ETHER) { return -EINVAL; } - mutex_lock(&mac->associnfo.mutex); + spin_lock_irqsave(&mac->lock, flags); if (is_broadcast_ether_addr(data->ap_addr.sa_data)) { /* the bssid we have is not to be fixed any longer, * and we should reassociate to the best AP. */ mac->associnfo.bssfixed = 0; /* force reassociation */ mac->associnfo.bssvalid = 0; - if (mac->associnfo.associated) + if (mac->associated) schedule_work(&mac->associnfo.work); } else if (is_zero_ether_addr(data->ap_addr.sa_data)) { /* the bssid we have is no longer fixed */ mac->associnfo.bssfixed = 0; } else { if (!memcmp(mac->associnfo.bssid, data->ap_addr.sa_data, ETH_ALEN)) { - if (mac->associnfo.associating || mac->associnfo.associated) { + if (mac->associnfo.associating || mac->associated) { /* bssid unchanged and associated or associating - just return */ goto out; } @@ -377,8 +378,7 @@ ieee80211softmac_wx_set_wap(struct net_device *net_dev, } out: - mutex_unlock(&mac->associnfo.mutex); - + spin_unlock_irqrestore(&mac->lock, flags); return 0; } EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_wap); @@ -394,8 +394,7 @@ ieee80211softmac_wx_set_genie(struct net_device *dev, int err = 0; char *buf; int i; - - mutex_lock(&mac->associnfo.mutex); + spin_lock_irqsave(&mac->lock, flags); /* bleh. shouldn't be locked for that kmalloc... */ @@ -433,8 +432,6 @@ ieee80211softmac_wx_set_genie(struct net_device *dev, out: spin_unlock_irqrestore(&mac->lock, flags); - mutex_unlock(&mac->associnfo.mutex); - return err; } EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_genie); @@ -449,8 +446,7 @@ ieee80211softmac_wx_get_genie(struct net_device *dev, unsigned long flags; int err = 0; int space = wrqu->data.length; - - mutex_lock(&mac->associnfo.mutex); + spin_lock_irqsave(&mac->lock, flags); wrqu->data.length = 0; @@ -463,8 +459,6 @@ ieee80211softmac_wx_get_genie(struct net_device *dev, err = -E2BIG; } spin_unlock_irqrestore(&mac->lock, flags); - mutex_lock(&mac->associnfo.mutex); - return err; } EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_genie); @@ -479,13 +473,10 @@ ieee80211softmac_wx_set_mlme(struct net_device *dev, struct iw_mlme *mlme = (struct iw_mlme *)extra; u16 reason = cpu_to_le16(mlme->reason_code); struct ieee80211softmac_network *net; - int err = -EINVAL; - - mutex_lock(&mac->associnfo.mutex); if (memcmp(mac->associnfo.bssid, mlme->addr.sa_data, ETH_ALEN)) { printk(KERN_DEBUG PFX "wx_set_mlme: requested operation on net we don't use\n"); - goto out; + return -EINVAL; } switch (mlme->cmd) { @@ -493,22 +484,14 @@ ieee80211softmac_wx_set_mlme(struct net_device *dev, net = ieee80211softmac_get_network_by_bssid_locked(mac, mlme->addr.sa_data); if (!net) { printk(KERN_DEBUG PFX "wx_set_mlme: we should know the net here...\n"); - goto out; + return -EINVAL; } return ieee80211softmac_deauth_req(mac, net, reason); case IW_MLME_DISASSOC: ieee80211softmac_send_disassoc_req(mac, reason); - mac->associnfo.associated = 0; - mac->associnfo.associating = 0; - err = 0; - goto out; + return 0; default: - err = -EOPNOTSUPP; + return -EOPNOTSUPP; } - -out: - mutex_unlock(&mac->associnfo.mutex); - - return err; } EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_mlme); diff --git a/trunk/net/ipv4/cipso_ipv4.c b/trunk/net/ipv4/cipso_ipv4.c index 6460233407c7..a8e2e879a647 100644 --- a/trunk/net/ipv4/cipso_ipv4.c +++ b/trunk/net/ipv4/cipso_ipv4.c @@ -43,7 +43,6 @@ #include #include #include -#include #include struct cipso_v4_domhsh_entry { @@ -80,7 +79,7 @@ struct cipso_v4_map_cache_entry { unsigned char *key; size_t key_len; - struct netlbl_lsm_cache *lsm_data; + struct netlbl_lsm_cache lsm_data; u32 activity; struct list_head list; @@ -189,14 +188,13 @@ static void cipso_v4_doi_domhsh_free(struct rcu_head *entry) * @entry: the entry to free * * Description: - * This function frees the memory associated with a cache entry including the - * LSM cache data if there are no longer any users, i.e. reference count == 0. + * This function frees the memory associated with a cache entry. * */ static void cipso_v4_cache_entry_free(struct cipso_v4_map_cache_entry *entry) { - if (entry->lsm_data) - netlbl_secattr_cache_free(entry->lsm_data); + if (entry->lsm_data.free) + entry->lsm_data.free(entry->lsm_data.data); kfree(entry->key); kfree(entry); } @@ -317,8 +315,8 @@ static int cipso_v4_cache_check(const unsigned char *key, entry->key_len == key_len && memcmp(entry->key, key, key_len) == 0) { entry->activity += 1; - atomic_inc(&entry->lsm_data->refcount); - secattr->cache = entry->lsm_data; + secattr->cache.free = entry->lsm_data.free; + secattr->cache.data = entry->lsm_data.data; if (prev_entry == NULL) { spin_unlock_bh(&cipso_v4_cache[bkt].lock); return 0; @@ -385,8 +383,8 @@ int cipso_v4_cache_add(const struct sk_buff *skb, memcpy(entry->key, cipso_ptr, cipso_ptr_len); entry->key_len = cipso_ptr_len; entry->hash = cipso_v4_map_cache_hash(cipso_ptr, cipso_ptr_len); - atomic_inc(&secattr->cache->refcount); - entry->lsm_data = secattr->cache; + entry->lsm_data.free = secattr->cache.free; + entry->lsm_data.data = secattr->cache.data; bkt = entry->hash & (CIPSO_V4_CACHE_BUCKETBITS - 1); spin_lock_bh(&cipso_v4_cache[bkt].lock); @@ -773,15 +771,13 @@ static int cipso_v4_map_cat_rbm_valid(const struct cipso_v4_doi *doi_def, { int cat = -1; u32 bitmap_len_bits = bitmap_len * 8; - u32 cipso_cat_size; - u32 *cipso_array; + u32 cipso_cat_size = doi_def->map.std->cat.cipso_size; + u32 *cipso_array = doi_def->map.std->cat.cipso; switch (doi_def->type) { case CIPSO_V4_MAP_PASS: return 0; case CIPSO_V4_MAP_STD: - cipso_cat_size = doi_def->map.std->cat.cipso_size; - cipso_array = doi_def->map.std->cat.cipso; for (;;) { cat = cipso_v4_bitmap_walk(bitmap, bitmap_len_bits, @@ -827,21 +823,19 @@ static int cipso_v4_map_cat_rbm_hton(const struct cipso_v4_doi *doi_def, u32 net_spot_max = 0; u32 host_clen_bits = host_cat_len * 8; u32 net_clen_bits = net_cat_len * 8; - u32 host_cat_size; - u32 *host_cat_array; + u32 host_cat_size = doi_def->map.std->cat.local_size; + u32 *host_cat_array = doi_def->map.std->cat.local; switch (doi_def->type) { case CIPSO_V4_MAP_PASS: - net_spot_max = host_cat_len; - while (net_spot_max > 0 && host_cat[net_spot_max - 1] == 0) + net_spot_max = host_cat_len - 1; + while (net_spot_max > 0 && host_cat[net_spot_max] == 0) net_spot_max--; if (net_spot_max > net_cat_len) return -EINVAL; memcpy(net_cat, host_cat, net_spot_max); return net_spot_max; case CIPSO_V4_MAP_STD: - host_cat_size = doi_def->map.std->cat.local_size; - host_cat_array = doi_def->map.std->cat.local; for (;;) { host_spot = cipso_v4_bitmap_walk(host_cat, host_clen_bits, @@ -897,8 +891,8 @@ static int cipso_v4_map_cat_rbm_ntoh(const struct cipso_v4_doi *doi_def, int net_spot = -1; u32 net_clen_bits = net_cat_len * 8; u32 host_clen_bits = host_cat_len * 8; - u32 net_cat_size; - u32 *net_cat_array; + u32 net_cat_size = doi_def->map.std->cat.cipso_size; + u32 *net_cat_array = doi_def->map.std->cat.cipso; switch (doi_def->type) { case CIPSO_V4_MAP_PASS: @@ -907,8 +901,6 @@ static int cipso_v4_map_cat_rbm_ntoh(const struct cipso_v4_doi *doi_def, memcpy(host_cat, net_cat, net_cat_len); return net_cat_len; case CIPSO_V4_MAP_STD: - net_cat_size = doi_def->map.std->cat.cipso_size; - net_cat_array = doi_def->map.std->cat.cipso; for (;;) { net_spot = cipso_v4_bitmap_walk(net_cat, net_clen_bits, @@ -1307,8 +1299,7 @@ int cipso_v4_socket_setattr(const struct socket *sock, /* We can't use ip_options_get() directly because it makes a call to * ip_options_get_alloc() which allocates memory with GFP_KERNEL and - * we won't always have CAP_NET_RAW even though we _always_ want to - * set the IPOPT_CIPSO option. */ + * we can't block here. */ opt_len = (buf_len + 3) & ~3; opt = kzalloc(sizeof(*opt) + opt_len, GFP_ATOMIC); if (opt == NULL) { @@ -1318,9 +1309,11 @@ int cipso_v4_socket_setattr(const struct socket *sock, memcpy(opt->__data, buf, buf_len); opt->optlen = opt_len; opt->is_data = 1; - opt->cipso = sizeof(struct iphdr); kfree(buf); buf = NULL; + ret_val = ip_options_compile(opt, NULL); + if (ret_val != 0) + goto socket_setattr_failure; sk_inet = inet_sk(sk); if (sk_inet->is_icsk) { diff --git a/trunk/net/ipv4/fib_frontend.c b/trunk/net/ipv4/fib_frontend.c index af0190d8b6c0..9c399a70dd5d 100644 --- a/trunk/net/ipv4/fib_frontend.c +++ b/trunk/net/ipv4/fib_frontend.c @@ -482,7 +482,9 @@ static int rtm_to_fib_config(struct sk_buff *skb, struct nlmsghdr *nlh, memset(cfg, 0, sizeof(*cfg)); rtm = nlmsg_data(nlh); + cfg->fc_family = rtm->rtm_family; cfg->fc_dst_len = rtm->rtm_dst_len; + cfg->fc_src_len = rtm->rtm_src_len; cfg->fc_tos = rtm->rtm_tos; cfg->fc_table = rtm->rtm_table; cfg->fc_protocol = rtm->rtm_protocol; @@ -499,6 +501,9 @@ static int rtm_to_fib_config(struct sk_buff *skb, struct nlmsghdr *nlh, case RTA_DST: cfg->fc_dst = nla_get_be32(attr); break; + case RTA_SRC: + cfg->fc_src = nla_get_be32(attr); + break; case RTA_OIF: cfg->fc_oif = nla_get_u32(attr); break; diff --git a/trunk/net/ipv4/inetpeer.c b/trunk/net/ipv4/inetpeer.c index f072f3875af8..2b1a54b59c48 100644 --- a/trunk/net/ipv4/inetpeer.c +++ b/trunk/net/ipv4/inetpeer.c @@ -94,8 +94,10 @@ int inet_peer_minttl = 120 * HZ; /* TTL under high load: 120 sec */ int inet_peer_maxttl = 10 * 60 * HZ; /* usual time to live: 10 min */ static struct inet_peer *inet_peer_unused_head; -static struct inet_peer **inet_peer_unused_tailp = &inet_peer_unused_head; -static DEFINE_SPINLOCK(inet_peer_unused_lock); +/* Exported for inet_putpeer inline function. */ +struct inet_peer **inet_peer_unused_tailp = &inet_peer_unused_head; +DEFINE_SPINLOCK(inet_peer_unused_lock); +#define PEER_MAX_CLEANUP_WORK 30 static void peer_check_expire(unsigned long dummy); static DEFINE_TIMER(peer_periodic_timer, peer_check_expire, 0, 0); @@ -338,8 +340,7 @@ static int cleanup_once(unsigned long ttl) spin_lock_bh(&inet_peer_unused_lock); p = inet_peer_unused_head; if (p != NULL) { - __u32 delta = (__u32)jiffies - p->dtime; - if (delta < ttl) { + if (time_after(p->dtime + ttl, jiffies)) { /* Do not prune fresh entries. */ spin_unlock_bh(&inet_peer_unused_lock); return -1; @@ -431,7 +432,7 @@ struct inet_peer *inet_getpeer(__be32 daddr, int create) /* Called with local BH disabled. */ static void peer_check_expire(unsigned long dummy) { - unsigned long now = jiffies; + int i; int ttl; if (peer_total >= inet_peer_threshold) @@ -440,10 +441,7 @@ static void peer_check_expire(unsigned long dummy) ttl = inet_peer_maxttl - (inet_peer_maxttl - inet_peer_minttl) / HZ * peer_total / inet_peer_threshold * HZ; - while (!cleanup_once(ttl)) { - if (jiffies != now) - break; - } + for (i = 0; i < PEER_MAX_CLEANUP_WORK && !cleanup_once(ttl); i++); /* Trigger the timer after inet_peer_gc_mintime .. inet_peer_gc_maxtime * interval depending on the total number of entries (more entries, @@ -457,16 +455,3 @@ static void peer_check_expire(unsigned long dummy) peer_total / inet_peer_threshold * HZ; add_timer(&peer_periodic_timer); } - -void inet_putpeer(struct inet_peer *p) -{ - spin_lock_bh(&inet_peer_unused_lock); - if (atomic_dec_and_test(&p->refcnt)) { - p->unused_prevp = inet_peer_unused_tailp; - p->unused_next = NULL; - *inet_peer_unused_tailp = p; - inet_peer_unused_tailp = &p->unused_next; - p->dtime = (__u32)jiffies; - } - spin_unlock_bh(&inet_peer_unused_lock); -} diff --git a/trunk/net/ipv4/ip_gre.c b/trunk/net/ipv4/ip_gre.c index d5b5dec075b8..f5fba051df3d 100644 --- a/trunk/net/ipv4/ip_gre.c +++ b/trunk/net/ipv4/ip_gre.c @@ -611,8 +611,8 @@ static int ipgre_rcv(struct sk_buff *skb) * - When dealing with WCCPv2, Skip extra 4 bytes in GRE header */ if (flags == 0 && - skb->protocol == htons(ETH_P_WCCP)) { - skb->protocol = htons(ETH_P_IP); + skb->protocol == __constant_htons(ETH_P_WCCP)) { + skb->protocol = __constant_htons(ETH_P_IP); if ((*(h + offset) & 0xF0) != 0x40) offset += 4; } diff --git a/trunk/net/ipv4/ip_options.c b/trunk/net/ipv4/ip_options.c index 9f02917d6f45..8dabbfc31267 100644 --- a/trunk/net/ipv4/ip_options.c +++ b/trunk/net/ipv4/ip_options.c @@ -443,7 +443,7 @@ int ip_options_compile(struct ip_options * opt, struct sk_buff * skb) opt->router_alert = optptr - iph; break; case IPOPT_CIPSO: - if ((!skb && !capable(CAP_NET_RAW)) || opt->cipso) { + if (opt->cipso) { pp_ptr = optptr; goto error; } diff --git a/trunk/net/ipv4/ipconfig.c b/trunk/net/ipv4/ipconfig.c index 955a07abb91d..f8ce84759159 100644 --- a/trunk/net/ipv4/ipconfig.c +++ b/trunk/net/ipv4/ipconfig.c @@ -420,7 +420,7 @@ ic_rarp_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt { struct arphdr *rarp; unsigned char *rarp_ptr; - u32 sip, tip; + unsigned long sip, tip; unsigned char *sha, *tha; /* s for "source", t for "target" */ struct ic_device *d; diff --git a/trunk/net/ipv4/ipvs/ip_vs_ftp.c b/trunk/net/ipv4/ipvs/ip_vs_ftp.c index 687c1de1146f..e433cb0ff894 100644 --- a/trunk/net/ipv4/ipvs/ip_vs_ftp.c +++ b/trunk/net/ipv4/ipvs/ip_vs_ftp.c @@ -200,7 +200,7 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp, from = n_cp->vaddr; port = n_cp->vport; sprintf(buf,"%d,%d,%d,%d,%d,%d", NIPQUAD(from), - (ntohs(port)>>8)&255, ntohs(port)&255); + ntohs(port)&255, (ntohs(port)>>8)&255); buf_len = strlen(buf); /* @@ -274,7 +274,7 @@ static int ip_vs_ftp_in(struct ip_vs_app *app, struct ip_vs_conn *cp, while (data <= data_limit - 6) { if (strnicmp(data, "PASV\r\n", 6) == 0) { /* Passive mode on */ - IP_VS_DBG(7, "got PASV at %td of %td\n", + IP_VS_DBG(7, "got PASV at %zd of %zd\n", data - data_start, data_limit - data_start); cp->app_data = &ip_vs_ftp_pasv; diff --git a/trunk/net/ipv4/ipvs/ip_vs_proto_tcp.c b/trunk/net/ipv4/ipvs/ip_vs_proto_tcp.c index 6ff05c3a32e6..bfe779e74590 100644 --- a/trunk/net/ipv4/ipvs/ip_vs_proto_tcp.c +++ b/trunk/net/ipv4/ipvs/ip_vs_proto_tcp.c @@ -117,7 +117,7 @@ tcp_fast_csum_update(struct tcphdr *tcph, __be32 oldip, __be32 newip, { tcph->check = ip_vs_check_diff(~oldip, newip, - ip_vs_check_diff(oldport ^ htons(0xFFFF), + ip_vs_check_diff(oldport ^ htonl(0xFFFF), newport, tcph->check)); } diff --git a/trunk/net/ipv4/ipvs/ip_vs_proto_udp.c b/trunk/net/ipv4/ipvs/ip_vs_proto_udp.c index 691c8b637b29..54aa7603591f 100644 --- a/trunk/net/ipv4/ipvs/ip_vs_proto_udp.c +++ b/trunk/net/ipv4/ipvs/ip_vs_proto_udp.c @@ -122,10 +122,10 @@ udp_fast_csum_update(struct udphdr *uhdr, __be32 oldip, __be32 newip, { uhdr->check = ip_vs_check_diff(~oldip, newip, - ip_vs_check_diff(oldport ^ htons(0xFFFF), + ip_vs_check_diff(oldport ^ htonl(0xFFFF), newport, uhdr->check)); if (!uhdr->check) - uhdr->check = -1; + uhdr->check = htonl(0xFFFF); } static int @@ -173,7 +173,7 @@ udp_snat_handler(struct sk_buff **pskb, cp->protocol, (*pskb)->csum); if (udph->check == 0) - udph->check = -1; + udph->check = htonl(0xFFFF); IP_VS_DBG(11, "O-pkt: %s O-csum=%d (+%zd)\n", pp->name, udph->check, (char*)&(udph->check) - (char*)udph); @@ -228,7 +228,7 @@ udp_dnat_handler(struct sk_buff **pskb, cp->protocol, (*pskb)->csum); if (udph->check == 0) - udph->check = -1; + udph->check = 0xFFFF; (*pskb)->ip_summed = CHECKSUM_UNNECESSARY; } return 1; diff --git a/trunk/net/ipv4/netfilter/arp_tables.c b/trunk/net/ipv4/netfilter/arp_tables.c index 413c2d0a1f3d..17e1a687ab45 100644 --- a/trunk/net/ipv4/netfilter/arp_tables.c +++ b/trunk/net/ipv4/netfilter/arp_tables.c @@ -466,13 +466,7 @@ static inline int check_entry(struct arpt_entry *e, const char *name, unsigned i return -EINVAL; } - if (e->target_offset + sizeof(struct arpt_entry_target) > e->next_offset) - return -EINVAL; - t = arpt_get_target(e); - if (e->target_offset + t->u.target_size > e->next_offset) - return -EINVAL; - target = try_then_request_module(xt_find_target(NF_ARP, t->u.user.name, t->u.user.revision), "arpt_%s", t->u.user.name); @@ -627,18 +621,20 @@ static int translate_table(const char *name, } } + if (!mark_source_chains(newinfo, valid_hooks, entry0)) { + duprintf("Looping hook\n"); + return -ELOOP; + } + /* Finally, each sanity check must pass */ i = 0; ret = ARPT_ENTRY_ITERATE(entry0, newinfo->size, check_entry, name, size, &i); - if (ret != 0) - goto cleanup; - - ret = -ELOOP; - if (!mark_source_chains(newinfo, valid_hooks, entry0)) { - duprintf("Looping hook\n"); - goto cleanup; + if (ret != 0) { + ARPT_ENTRY_ITERATE(entry0, newinfo->size, + cleanup_entry, &i); + return ret; } /* And one copy for every other CPU */ @@ -647,9 +643,6 @@ static int translate_table(const char *name, memcpy(newinfo->entries[i], entry0, newinfo->size); } - return 0; -cleanup: - ARPT_ENTRY_ITERATE(entry0, newinfo->size, cleanup_entry, &i); return ret; } @@ -1203,8 +1196,6 @@ static int __init arp_tables_init(void) static void __exit arp_tables_fini(void) { nf_unregister_sockopt(&arpt_sockopts); - xt_unregister_target(&arpt_error_target); - xt_unregister_target(&arpt_standard_target); xt_proto_fini(NF_ARP); } diff --git a/trunk/net/ipv4/netfilter/ip_conntrack_core.c b/trunk/net/ipv4/netfilter/ip_conntrack_core.c index 8b848aa77bfc..143c4668538b 100644 --- a/trunk/net/ipv4/netfilter/ip_conntrack_core.c +++ b/trunk/net/ipv4/netfilter/ip_conntrack_core.c @@ -225,8 +225,10 @@ __ip_conntrack_expect_find(const struct ip_conntrack_tuple *tuple) struct ip_conntrack_expect *i; list_for_each_entry(i, &ip_conntrack_expect_list, list) { - if (ip_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask)) + if (ip_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask)) { + atomic_inc(&i->use); return i; + } } return NULL; } @@ -239,8 +241,6 @@ ip_conntrack_expect_find(const struct ip_conntrack_tuple *tuple) read_lock_bh(&ip_conntrack_lock); i = __ip_conntrack_expect_find(tuple); - if (i) - atomic_inc(&i->use); read_unlock_bh(&ip_conntrack_lock); return i; diff --git a/trunk/net/ipv4/netfilter/ip_conntrack_helper_h323.c b/trunk/net/ipv4/netfilter/ip_conntrack_helper_h323.c index 6cb9070cd0bc..7b7441202bfd 100644 --- a/trunk/net/ipv4/netfilter/ip_conntrack_helper_h323.c +++ b/trunk/net/ipv4/netfilter/ip_conntrack_helper_h323.c @@ -1417,7 +1417,7 @@ static int process_rcf(struct sk_buff **pskb, struct ip_conntrack *ct, DEBUGP ("ip_ct_ras: set RAS connection timeout to %u seconds\n", info->timeout); - ip_ct_refresh(ct, *pskb, info->timeout * HZ); + ip_ct_refresh_acct(ct, ctinfo, NULL, info->timeout * HZ); /* Set expect timeout */ read_lock_bh(&ip_conntrack_lock); @@ -1465,7 +1465,7 @@ static int process_urq(struct sk_buff **pskb, struct ip_conntrack *ct, info->sig_port[!dir] = 0; /* Give it 30 seconds for UCF or URJ */ - ip_ct_refresh(ct, *pskb, 30 * HZ); + ip_ct_refresh_acct(ct, ctinfo, NULL, 30 * HZ); return 0; } diff --git a/trunk/net/ipv4/netfilter/ip_conntrack_netlink.c b/trunk/net/ipv4/netfilter/ip_conntrack_netlink.c index 55f0ae641081..53b6dffea6c2 100644 --- a/trunk/net/ipv4/netfilter/ip_conntrack_netlink.c +++ b/trunk/net/ipv4/netfilter/ip_conntrack_netlink.c @@ -44,6 +44,13 @@ MODULE_LICENSE("GPL"); static char __initdata version[] = "0.90"; +#if 0 +#define DEBUGP printk +#else +#define DEBUGP(format, args...) +#endif + + static inline int ctnetlink_dump_tuples_proto(struct sk_buff *skb, const struct ip_conntrack_tuple *tuple, @@ -153,7 +160,6 @@ ctnetlink_dump_protoinfo(struct sk_buff *skb, const struct ip_conntrack *ct) return ret; nfattr_failure: - ip_conntrack_proto_put(proto); return -1; } @@ -392,6 +398,7 @@ static int ctnetlink_conntrack_event(struct notifier_block *this, static int ctnetlink_done(struct netlink_callback *cb) { + DEBUGP("entered %s\n", __FUNCTION__); if (cb->args[1]) ip_conntrack_put((struct ip_conntrack *)cb->args[1]); return 0; @@ -404,6 +411,9 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb) struct ip_conntrack_tuple_hash *h; struct list_head *i; + DEBUGP("entered %s, last bucket=%lu id=%u\n", __FUNCTION__, + cb->args[0], *id); + read_lock_bh(&ip_conntrack_lock); last = (struct ip_conntrack *)cb->args[1]; for (; cb->args[0] < ip_conntrack_htable_size; cb->args[0]++) { @@ -442,6 +452,7 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb) if (last) ip_conntrack_put(last); + DEBUGP("leaving, last bucket=%lu id=%u\n", cb->args[0], *id); return skb->len; } @@ -455,6 +466,8 @@ ctnetlink_parse_tuple_ip(struct nfattr *attr, struct ip_conntrack_tuple *tuple) { struct nfattr *tb[CTA_IP_MAX]; + DEBUGP("entered %s\n", __FUNCTION__); + nfattr_parse_nested(tb, CTA_IP_MAX, attr); if (nfattr_bad_size(tb, CTA_IP_MAX, cta_min_ip)) @@ -468,6 +481,8 @@ ctnetlink_parse_tuple_ip(struct nfattr *attr, struct ip_conntrack_tuple *tuple) return -EINVAL; tuple->dst.ip = *(__be32 *)NFA_DATA(tb[CTA_IP_V4_DST-1]); + DEBUGP("leaving\n"); + return 0; } @@ -488,6 +503,8 @@ ctnetlink_parse_tuple_proto(struct nfattr *attr, struct ip_conntrack_protocol *proto; int ret = 0; + DEBUGP("entered %s\n", __FUNCTION__); + nfattr_parse_nested(tb, CTA_PROTO_MAX, attr); if (nfattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto)) @@ -514,6 +531,8 @@ ctnetlink_parse_tuple(struct nfattr *cda[], struct ip_conntrack_tuple *tuple, struct nfattr *tb[CTA_TUPLE_MAX]; int err; + DEBUGP("entered %s\n", __FUNCTION__); + memset(tuple, 0, sizeof(*tuple)); nfattr_parse_nested(tb, CTA_TUPLE_MAX, cda[type-1]); @@ -538,6 +557,10 @@ ctnetlink_parse_tuple(struct nfattr *cda[], struct ip_conntrack_tuple *tuple, else tuple->dst.dir = IP_CT_DIR_ORIGINAL; + DUMP_TUPLE(tuple); + + DEBUGP("leaving\n"); + return 0; } @@ -554,6 +577,8 @@ static int ctnetlink_parse_nat_proto(struct nfattr *attr, struct nfattr *tb[CTA_PROTONAT_MAX]; struct ip_nat_protocol *npt; + DEBUGP("entered %s\n", __FUNCTION__); + nfattr_parse_nested(tb, CTA_PROTONAT_MAX, attr); if (nfattr_bad_size(tb, CTA_PROTONAT_MAX, cta_min_protonat)) @@ -572,6 +597,7 @@ static int ctnetlink_parse_nat_proto(struct nfattr *attr, ip_nat_proto_put(npt); + DEBUGP("leaving\n"); return 0; } @@ -587,6 +613,8 @@ ctnetlink_parse_nat(struct nfattr *nat, struct nfattr *tb[CTA_NAT_MAX]; int err; + DEBUGP("entered %s\n", __FUNCTION__); + memset(range, 0, sizeof(*range)); nfattr_parse_nested(tb, CTA_NAT_MAX, nat); @@ -612,6 +640,7 @@ ctnetlink_parse_nat(struct nfattr *nat, if (err < 0) return err; + DEBUGP("leaving\n"); return 0; } #endif @@ -621,6 +650,8 @@ ctnetlink_parse_help(struct nfattr *attr, char **helper_name) { struct nfattr *tb[CTA_HELP_MAX]; + DEBUGP("entered %s\n", __FUNCTION__); + nfattr_parse_nested(tb, CTA_HELP_MAX, attr); if (!tb[CTA_HELP_NAME-1]) @@ -648,6 +679,8 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb, struct ip_conntrack *ct; int err = 0; + DEBUGP("entered %s\n", __FUNCTION__); + if (nfattr_bad_size(cda, CTA_MAX, cta_min)) return -EINVAL; @@ -665,8 +698,10 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb, return err; h = ip_conntrack_find_get(&tuple, NULL); - if (!h) + if (!h) { + DEBUGP("tuple not found in conntrack hash\n"); return -ENOENT; + } ct = tuplehash_to_ctrack(h); @@ -681,6 +716,7 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb, ct->timeout.function((unsigned long)ct); ip_conntrack_put(ct); + DEBUGP("leaving\n"); return 0; } @@ -695,6 +731,8 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb, struct sk_buff *skb2 = NULL; int err = 0; + DEBUGP("entered %s\n", __FUNCTION__); + if (nlh->nlmsg_flags & NLM_F_DUMP) { struct nfgenmsg *msg = NLMSG_DATA(nlh); u32 rlen; @@ -732,9 +770,11 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb, return err; h = ip_conntrack_find_get(&tuple, NULL); - if (!h) + if (!h) { + DEBUGP("tuple not found in conntrack hash"); return -ENOENT; - + } + DEBUGP("tuple found\n"); ct = tuplehash_to_ctrack(h); err = -ENOMEM; @@ -755,6 +795,7 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb, if (err < 0) goto out; + DEBUGP("leaving\n"); return 0; free: @@ -825,6 +866,8 @@ ctnetlink_change_helper(struct ip_conntrack *ct, struct nfattr *cda[]) char *helpname; int err; + DEBUGP("entered %s\n", __FUNCTION__); + /* don't change helper of sibling connections */ if (ct->master) return -EINVAL; @@ -895,6 +938,8 @@ ctnetlink_change_conntrack(struct ip_conntrack *ct, struct nfattr *cda[]) { int err; + DEBUGP("entered %s\n", __FUNCTION__); + if (cda[CTA_HELP-1]) { err = ctnetlink_change_helper(ct, cda); if (err < 0) @@ -924,6 +969,7 @@ ctnetlink_change_conntrack(struct ip_conntrack *ct, struct nfattr *cda[]) ct->mark = ntohl(*(__be32 *)NFA_DATA(cda[CTA_MARK-1])); #endif + DEBUGP("all done\n"); return 0; } @@ -935,6 +981,8 @@ ctnetlink_create_conntrack(struct nfattr *cda[], struct ip_conntrack *ct; int err = -EINVAL; + DEBUGP("entered %s\n", __FUNCTION__); + ct = ip_conntrack_alloc(otuple, rtuple); if (ct == NULL || IS_ERR(ct)) return -ENOMEM; @@ -969,6 +1017,7 @@ ctnetlink_create_conntrack(struct nfattr *cda[], if (ct->helper) ip_conntrack_helper_put(ct->helper); + DEBUGP("conntrack with id %u inserted\n", ct->id); return 0; err: @@ -984,6 +1033,8 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb, struct ip_conntrack_tuple_hash *h = NULL; int err = 0; + DEBUGP("entered %s\n", __FUNCTION__); + if (nfattr_bad_size(cda, CTA_MAX, cta_min)) return -EINVAL; @@ -1007,6 +1058,7 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb, if (h == NULL) { write_unlock_bh(&ip_conntrack_lock); + DEBUGP("no such conntrack, create new\n"); err = -ENOENT; if (nlh->nlmsg_flags & NLM_F_CREATE) err = ctnetlink_create_conntrack(cda, &otuple, &rtuple); @@ -1022,6 +1074,7 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb, /* We manipulate the conntrack inside the global conntrack table lock, * so there's no need to increase the refcount */ + DEBUGP("conntrack found\n"); err = -EEXIST; if (!(nlh->nlmsg_flags & NLM_F_EXCL)) err = ctnetlink_change_conntrack(tuplehash_to_ctrack(h), cda); @@ -1196,6 +1249,8 @@ ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb) struct list_head *i; u_int32_t *id = (u_int32_t *) &cb->args[0]; + DEBUGP("entered %s, last id=%llu\n", __FUNCTION__, *id); + read_lock_bh(&ip_conntrack_lock); list_for_each_prev(i, &ip_conntrack_expect_list) { exp = (struct ip_conntrack_expect *) i; @@ -1211,6 +1266,8 @@ ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb) out: read_unlock_bh(&ip_conntrack_lock); + DEBUGP("leaving, last id=%llu\n", *id); + return skb->len; } @@ -1228,6 +1285,8 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb, struct sk_buff *skb2; int err = 0; + DEBUGP("entered %s\n", __FUNCTION__); + if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp)) return -EINVAL; @@ -1378,6 +1437,8 @@ ctnetlink_create_expect(struct nfattr *cda[]) struct ip_conntrack *ct; int err = 0; + DEBUGP("entered %s\n", __FUNCTION__); + /* caller guarantees that those three CTA_EXPECT_* exist */ err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE); if (err < 0) @@ -1429,6 +1490,8 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb, struct ip_conntrack_expect *exp; int err = 0; + DEBUGP("entered %s\n", __FUNCTION__); + if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp)) return -EINVAL; @@ -1457,6 +1520,8 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb, err = ctnetlink_change_expect(exp, cda); write_unlock_bh(&ip_conntrack_lock); + DEBUGP("leaving\n"); + return err; } diff --git a/trunk/net/ipv4/netfilter/ip_queue.c b/trunk/net/ipv4/netfilter/ip_queue.c index 97556cc2e4e0..7edad790478a 100644 --- a/trunk/net/ipv4/netfilter/ip_queue.c +++ b/trunk/net/ipv4/netfilter/ip_queue.c @@ -351,10 +351,9 @@ ipq_mangle_ipv4(ipq_verdict_msg_t *v, struct ipq_queue_entry *e) if (v->data_len < sizeof(*user_iph)) return 0; diff = v->data_len - e->skb->len; - if (diff < 0) { - if (pskb_trim(e->skb, v->data_len)) - return -ENOMEM; - } else if (diff > 0) { + if (diff < 0) + skb_trim(e->skb, v->data_len); + else if (diff > 0) { if (v->data_len > 0xFFFF) return -EINVAL; if (diff > skb_tailroom(e->skb)) { diff --git a/trunk/net/ipv4/netfilter/ip_tables.c b/trunk/net/ipv4/netfilter/ip_tables.c index 8a455439b128..78a44b01c035 100644 --- a/trunk/net/ipv4/netfilter/ip_tables.c +++ b/trunk/net/ipv4/netfilter/ip_tables.c @@ -547,18 +547,12 @@ check_entry(struct ipt_entry *e, const char *name, unsigned int size, return -EINVAL; } - if (e->target_offset + sizeof(struct ipt_entry_target) > e->next_offset) - return -EINVAL; - j = 0; ret = IPT_MATCH_ITERATE(e, check_match, name, &e->ip, e->comefrom, &j); if (ret != 0) goto cleanup_matches; t = ipt_get_target(e); - ret = -EINVAL; - if (e->target_offset + t->u.target_size > e->next_offset) - goto cleanup_matches; target = try_then_request_module(xt_find_target(AF_INET, t->u.user.name, t->u.user.revision), @@ -718,17 +712,19 @@ translate_table(const char *name, } } + if (!mark_source_chains(newinfo, valid_hooks, entry0)) + return -ELOOP; + /* Finally, each sanity check must pass */ i = 0; ret = IPT_ENTRY_ITERATE(entry0, newinfo->size, check_entry, name, size, &i); - if (ret != 0) - goto cleanup; - - ret = -ELOOP; - if (!mark_source_chains(newinfo, valid_hooks, entry0)) - goto cleanup; + if (ret != 0) { + IPT_ENTRY_ITERATE(entry0, newinfo->size, + cleanup_entry, &i); + return ret; + } /* And one copy for every other CPU */ for_each_possible_cpu(i) { @@ -736,9 +732,6 @@ translate_table(const char *name, memcpy(newinfo->entries[i], entry0, newinfo->size); } - return 0; -cleanup: - IPT_ENTRY_ITERATE(entry0, newinfo->size, cleanup_entry, &i); return ret; } @@ -1470,10 +1463,6 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e, return -EINVAL; } - if (e->target_offset + sizeof(struct compat_xt_entry_target) > - e->next_offset) - return -EINVAL; - off = 0; entry_offset = (void *)e - (void *)base; j = 0; @@ -1483,9 +1472,6 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e, goto cleanup_matches; t = ipt_get_target(e); - ret = -EINVAL; - if (e->target_offset + t->u.target_size > e->next_offset) - goto cleanup_matches; target = try_then_request_module(xt_find_target(AF_INET, t->u.user.name, t->u.user.revision), @@ -1527,7 +1513,7 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e, static inline int compat_copy_match_from_user(struct ipt_entry_match *m, void **dstptr, compat_uint_t *size, const char *name, - const struct ipt_ip *ip, unsigned int hookmask) + const struct ipt_ip *ip, unsigned int hookmask, int *i) { struct ipt_entry_match *dm; struct ipt_match *match; @@ -1540,13 +1526,22 @@ static inline int compat_copy_match_from_user(struct ipt_entry_match *m, ret = xt_check_match(match, AF_INET, dm->u.match_size - sizeof(*dm), name, hookmask, ip->proto, ip->invflags & IPT_INV_PROTO); - if (!ret && m->u.kernel.match->checkentry + if (ret) + goto err; + + if (m->u.kernel.match->checkentry && !m->u.kernel.match->checkentry(name, ip, match, dm->data, hookmask)) { duprintf("ip_tables: check failed for `%s'.\n", m->u.kernel.match->name); ret = -EINVAL; + goto err; } + (*i)++; + return 0; + +err: + module_put(m->u.kernel.match->me); return ret; } @@ -1558,18 +1553,19 @@ static int compat_copy_entry_from_user(struct ipt_entry *e, void **dstptr, struct ipt_target *target; struct ipt_entry *de; unsigned int origsize; - int ret, h; + int ret, h, j; ret = 0; origsize = *size; de = (struct ipt_entry *)*dstptr; memcpy(de, e, sizeof(struct ipt_entry)); + j = 0; *dstptr += sizeof(struct compat_ipt_entry); ret = IPT_MATCH_ITERATE(e, compat_copy_match_from_user, dstptr, size, - name, &de->ip, de->comefrom); + name, &de->ip, de->comefrom, &j); if (ret) - goto err; + goto cleanup_matches; de->target_offset = e->target_offset - (origsize - *size); t = ipt_get_target(e); target = t->u.kernel.target; @@ -1603,7 +1599,12 @@ static int compat_copy_entry_from_user(struct ipt_entry *e, void **dstptr, goto err; } ret = 0; + return ret; + err: + module_put(t->u.kernel.target->me); +cleanup_matches: + IPT_MATCH_ITERATE(e, cleanup_match, &j); return ret; } @@ -1617,7 +1618,7 @@ translate_compat_table(const char *name, unsigned int *hook_entries, unsigned int *underflows) { - unsigned int i, j; + unsigned int i; struct xt_table_info *newinfo, *info; void *pos, *entry0, *entry1; unsigned int size; @@ -1635,21 +1636,21 @@ translate_compat_table(const char *name, } duprintf("translate_compat_table: size %u\n", info->size); - j = 0; + i = 0; xt_compat_lock(AF_INET); /* Walk through entries, checking offsets. */ ret = IPT_ENTRY_ITERATE(entry0, total_size, check_compat_entry_size_and_hooks, info, &size, entry0, entry0 + total_size, - hook_entries, underflows, &j, name); + hook_entries, underflows, &i, name); if (ret != 0) goto out_unlock; ret = -EINVAL; - if (j != number) { + if (i != number) { duprintf("translate_compat_table: %u not %u entries\n", - j, number); + i, number); goto out_unlock; } @@ -1708,10 +1709,8 @@ translate_compat_table(const char *name, free_newinfo: xt_free_table_info(newinfo); out: - IPT_ENTRY_ITERATE(entry0, total_size, cleanup_entry, &j); return ret; out_unlock: - compat_flush_offsets(); xt_compat_unlock(AF_INET); goto out; } @@ -1933,9 +1932,6 @@ compat_do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) { int ret; - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - switch (cmd) { case IPT_SO_GET_INFO: ret = get_info(user, len, 1); diff --git a/trunk/net/ipv4/netfilter/ipt_ECN.c b/trunk/net/ipv4/netfilter/ipt_ECN.c index 1aa4517fbcdb..12a818a2462f 100644 --- a/trunk/net/ipv4/netfilter/ipt_ECN.c +++ b/trunk/net/ipv4/netfilter/ipt_ECN.c @@ -28,7 +28,7 @@ static inline int set_ect_ip(struct sk_buff **pskb, const struct ipt_ECN_info *einfo) { struct iphdr *iph = (*pskb)->nh.iph; - u_int16_t oldtos; + __be16 oldtos; if ((iph->tos & IPT_ECN_IP_MASK) != (einfo->ip_ect & IPT_ECN_IP_MASK)) { if (!skb_make_writable(pskb, sizeof(struct iphdr))) @@ -37,8 +37,8 @@ set_ect_ip(struct sk_buff **pskb, const struct ipt_ECN_info *einfo) oldtos = iph->tos; iph->tos &= ~IPT_ECN_IP_MASK; iph->tos |= (einfo->ip_ect & IPT_ECN_IP_MASK); - iph->check = nf_csum_update(htons(oldtos) ^ htons(0xFFFF), - htons(iph->tos), iph->check); + iph->check = nf_csum_update(oldtos ^ htons(0xFFFF), iph->tos, + iph->check); } return 1; } diff --git a/trunk/net/ipv4/netfilter/ipt_REJECT.c b/trunk/net/ipv4/netfilter/ipt_REJECT.c index 264763adc39b..ad0312d0e4fd 100644 --- a/trunk/net/ipv4/netfilter/ipt_REJECT.c +++ b/trunk/net/ipv4/netfilter/ipt_REJECT.c @@ -114,14 +114,6 @@ static void send_reset(struct sk_buff *oldskb, int hook) tcph->window = 0; tcph->urg_ptr = 0; - /* Adjust TCP checksum */ - tcph->check = 0; - tcph->check = tcp_v4_check(tcph, sizeof(struct tcphdr), - nskb->nh.iph->saddr, - nskb->nh.iph->daddr, - csum_partial((char *)tcph, - sizeof(struct tcphdr), 0)); - /* Set DF, id = 0 */ nskb->nh.iph->frag_off = htons(IP_DF); nskb->nh.iph->id = 0; @@ -137,8 +129,14 @@ static void send_reset(struct sk_buff *oldskb, int hook) if (ip_route_me_harder(&nskb, addr_type)) goto free_nskb; + /* Adjust TCP checksum */ nskb->ip_summed = CHECKSUM_NONE; - + tcph->check = 0; + tcph->check = tcp_v4_check(tcph, sizeof(struct tcphdr), + nskb->nh.iph->saddr, + nskb->nh.iph->daddr, + csum_partial((char *)tcph, + sizeof(struct tcphdr), 0)); /* Adjust IP TTL */ nskb->nh.iph->ttl = dst_metric(nskb->dst, RTAX_HOPLIMIT); diff --git a/trunk/net/ipv4/netfilter/ipt_TOS.c b/trunk/net/ipv4/netfilter/ipt_TOS.c index 83b80b3a5d2f..6b8b14ccc3d3 100644 --- a/trunk/net/ipv4/netfilter/ipt_TOS.c +++ b/trunk/net/ipv4/netfilter/ipt_TOS.c @@ -30,7 +30,7 @@ target(struct sk_buff **pskb, { const struct ipt_tos_target_info *tosinfo = targinfo; struct iphdr *iph = (*pskb)->nh.iph; - u_int16_t oldtos; + __be16 oldtos; if ((iph->tos & IPTOS_TOS_MASK) != tosinfo->tos) { if (!skb_make_writable(pskb, sizeof(struct iphdr))) @@ -38,8 +38,8 @@ target(struct sk_buff **pskb, iph = (*pskb)->nh.iph; oldtos = iph->tos; iph->tos = (iph->tos & IPTOS_PREC_MASK) | tosinfo->tos; - iph->check = nf_csum_update(htons(oldtos) ^ htons(0xFFFF), - htons(iph->tos), iph->check); + iph->check = nf_csum_update(oldtos ^ htons(0xFFFF), iph->tos, + iph->check); } return IPT_CONTINUE; } diff --git a/trunk/net/ipv4/raw.c b/trunk/net/ipv4/raw.c index 5c31dead2bdc..b430cf2a4f66 100644 --- a/trunk/net/ipv4/raw.c +++ b/trunk/net/ipv4/raw.c @@ -329,7 +329,7 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length, return err; } -static int raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg) +static void raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg) { struct iovec *iov; u8 __user *type = NULL; @@ -338,7 +338,7 @@ static int raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg) unsigned int i; if (!msg->msg_iov) - return 0; + return; for (i = 0; i < msg->msg_iovlen; i++) { iov = &msg->msg_iov[i]; @@ -360,9 +360,8 @@ static int raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg) code = iov->iov_base; if (type && code) { - if (get_user(fl->fl_icmp_type, type) || - get_user(fl->fl_icmp_code, code)) - return -EFAULT; + get_user(fl->fl_icmp_type, type); + get_user(fl->fl_icmp_code, code); probed = 1; } break; @@ -373,7 +372,6 @@ static int raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg) if (probed) break; } - return 0; } static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, @@ -482,11 +480,8 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, .proto = inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol, }; - if (!inet->hdrincl) { - err = raw_probe_proto_opt(&fl, msg); - if (err) - goto done; - } + if (!inet->hdrincl) + raw_probe_proto_opt(&fl, msg); security_sk_classify_flow(sk, &fl); err = ip_route_output_flow(&rt, &fl, sk, !(msg->msg_flags&MSG_DONTWAIT)); diff --git a/trunk/net/ipv4/route.c b/trunk/net/ipv4/route.c index 925ee4dfc32c..c41ddba02e9d 100644 --- a/trunk/net/ipv4/route.c +++ b/trunk/net/ipv4/route.c @@ -566,15 +566,9 @@ static inline u32 rt_score(struct rtable *rt) static inline int compare_keys(struct flowi *fl1, struct flowi *fl2) { - return ((fl1->nl_u.ip4_u.daddr ^ fl2->nl_u.ip4_u.daddr) | - (fl1->nl_u.ip4_u.saddr ^ fl2->nl_u.ip4_u.saddr) | -#ifdef CONFIG_IP_ROUTE_FWMARK - (fl1->nl_u.ip4_u.fwmark ^ fl2->nl_u.ip4_u.fwmark) | -#endif - (*(u16 *)&fl1->nl_u.ip4_u.tos ^ - *(u16 *)&fl2->nl_u.ip4_u.tos) | - (fl1->oif ^ fl2->oif) | - (fl1->iif ^ fl2->iif)) == 0; + return memcmp(&fl1->nl_u.ip4_u, &fl2->nl_u.ip4_u, sizeof(fl1->nl_u.ip4_u)) == 0 && + fl1->oif == fl2->oif && + fl1->iif == fl2->iif; } #ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED diff --git a/trunk/net/ipv4/sysctl_net_ipv4.c b/trunk/net/ipv4/sysctl_net_ipv4.c index 15061b314411..e82a5be894b5 100644 --- a/trunk/net/ipv4/sysctl_net_ipv4.c +++ b/trunk/net/ipv4/sysctl_net_ipv4.c @@ -129,6 +129,13 @@ static int sysctl_tcp_congestion_control(ctl_table *table, int __user *name, return ret; } +static int __init tcp_congestion_default(void) +{ + return tcp_set_default_congestion_control(CONFIG_DEFAULT_TCP_CONG); +} + +late_initcall(tcp_congestion_default); + ctl_table ipv4_table[] = { { .ctl_name = NET_IPV4_TCP_TIMESTAMPS, diff --git a/trunk/net/ipv4/tcp.c b/trunk/net/ipv4/tcp.c index c05e8edaf544..66e9a729f6df 100644 --- a/trunk/net/ipv4/tcp.c +++ b/trunk/net/ipv4/tcp.c @@ -2270,7 +2270,7 @@ void __init tcp_init(void) thash_entries, (num_physpages >= 128 * 1024) ? 13 : 15, - 0, + HASH_HIGHMEM, &tcp_hashinfo.ehash_size, NULL, 0); @@ -2286,7 +2286,7 @@ void __init tcp_init(void) tcp_hashinfo.ehash_size, (num_physpages >= 128 * 1024) ? 13 : 15, - 0, + HASH_HIGHMEM, &tcp_hashinfo.bhash_size, NULL, 64 * 1024); @@ -2316,10 +2316,9 @@ void __init tcp_init(void) sysctl_max_syn_backlog = 128; } - /* Allow no more than 3/4 kernel memory (usually less) allocated to TCP */ - sysctl_tcp_mem[0] = (1536 / sizeof (struct inet_bind_hashbucket)) << order; - sysctl_tcp_mem[1] = sysctl_tcp_mem[0] * 4 / 3; - sysctl_tcp_mem[2] = sysctl_tcp_mem[0] * 2; + sysctl_tcp_mem[0] = 768 << order; + sysctl_tcp_mem[1] = 1024 << order; + sysctl_tcp_mem[2] = 1536 << order; limit = ((unsigned long)sysctl_tcp_mem[1]) << (PAGE_SHIFT - 7); max_share = min(4UL*1024*1024, limit); diff --git a/trunk/net/ipv4/tcp_cong.c b/trunk/net/ipv4/tcp_cong.c index 1e2982f4acd4..af0aca1e6be6 100644 --- a/trunk/net/ipv4/tcp_cong.c +++ b/trunk/net/ipv4/tcp_cong.c @@ -131,14 +131,6 @@ int tcp_set_default_congestion_control(const char *name) return ret; } -/* Set default value from kernel configuration at bootup */ -static int __init tcp_congestion_default(void) -{ - return tcp_set_default_congestion_control(CONFIG_DEFAULT_TCP_CONG); -} -late_initcall(tcp_congestion_default); - - /* Get current default congestion control */ void tcp_get_default_congestion_control(char *name) { diff --git a/trunk/net/ipv4/tcp_cubic.c b/trunk/net/ipv4/tcp_cubic.c index 6ad184802266..a60ef38d75c6 100644 --- a/trunk/net/ipv4/tcp_cubic.c +++ b/trunk/net/ipv4/tcp_cubic.c @@ -190,7 +190,7 @@ static inline void bictcp_update(struct bictcp *ca, u32 cwnd) */ /* change the unit from HZ to bictcp_HZ */ - t = ((tcp_time_stamp + (ca->delay_min>>3) - ca->epoch_start) + t = ((tcp_time_stamp + ca->delay_min - ca->epoch_start) << BICTCP_HZ) / HZ; if (t < ca->bic_K) /* t - K */ @@ -259,7 +259,7 @@ static inline void measure_delay(struct sock *sk) (s32)(tcp_time_stamp - ca->epoch_start) < HZ) return; - delay = (tcp_time_stamp - tp->rx_opt.rcv_tsecr)<<3; + delay = tcp_time_stamp - tp->rx_opt.rcv_tsecr; if (delay == 0) delay = 1; @@ -366,7 +366,7 @@ static int __init cubictcp_register(void) beta_scale = 8*(BICTCP_BETA_SCALE+beta)/ 3 / (BICTCP_BETA_SCALE - beta); - cube_rtt_scale = (bic_scale * 10); /* 1024*c/rtt */ + cube_rtt_scale = (bic_scale << 3) / 10; /* 1024*c/rtt */ /* calculate the "K" for (wmax-cwnd) = c/rtt * K^3 * so K = cubic_root( (wmax-cwnd)*rtt/c ) diff --git a/trunk/net/ipv4/tcp_htcp.c b/trunk/net/ipv4/tcp_htcp.c index 283be3cb4667..682e7d5b6f2f 100644 --- a/trunk/net/ipv4/tcp_htcp.c +++ b/trunk/net/ipv4/tcp_htcp.c @@ -23,7 +23,7 @@ module_param(use_bandwidth_switch, int, 0644); MODULE_PARM_DESC(use_bandwidth_switch, "turn on/off bandwidth switcher"); struct htcp { - u32 alpha; /* Fixed point arith, << 7 */ + u16 alpha; /* Fixed point arith, << 7 */ u8 beta; /* Fixed point arith, << 7 */ u8 modeswitch; /* Delay modeswitch until we had at least one congestion event */ u32 last_cong; /* Time since last congestion event end */ diff --git a/trunk/net/ipv4/tcp_ipv4.c b/trunk/net/ipv4/tcp_ipv4.c index 22ef8bd26620..c83938b8fcb1 100644 --- a/trunk/net/ipv4/tcp_ipv4.c +++ b/trunk/net/ipv4/tcp_ipv4.c @@ -355,7 +355,7 @@ void tcp_v4_err(struct sk_buff *skb, u32 info) return; } if (sk->sk_state == TCP_TIME_WAIT) { - inet_twsk_put(inet_twsk(sk)); + inet_twsk_put((struct inet_timewait_sock *)sk); return; } @@ -373,7 +373,7 @@ void tcp_v4_err(struct sk_buff *skb, u32 info) seq = ntohl(th->seq); if (sk->sk_state != TCP_LISTEN && !between(seq, tp->snd_una, tp->snd_nxt)) { - NET_INC_STATS_BH(LINUX_MIB_OUTOFWINDOWICMPS); + NET_INC_STATS(LINUX_MIB_OUTOFWINDOWICMPS); goto out; } @@ -578,7 +578,7 @@ static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack, struct tcphdr *th = skb->h.th; struct { struct tcphdr th; - u32 tsopt[TCPOLEN_TSTAMP_ALIGNED >> 2]; + u32 tsopt[3]; } rep; struct ip_reply_arg arg; @@ -960,7 +960,7 @@ static struct sock *tcp_v4_hnd_req(struct sock *sk, struct sk_buff *skb) bh_lock_sock(nsk); return nsk; } - inet_twsk_put(inet_twsk(nsk)); + inet_twsk_put((struct inet_timewait_sock *)nsk); return NULL; } @@ -1154,24 +1154,26 @@ int tcp_v4_rcv(struct sk_buff *skb) do_time_wait: if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) { - inet_twsk_put(inet_twsk(sk)); + inet_twsk_put((struct inet_timewait_sock *) sk); goto discard_it; } if (skb->len < (th->doff << 2) || tcp_checksum_complete(skb)) { TCP_INC_STATS_BH(TCP_MIB_INERRS); - inet_twsk_put(inet_twsk(sk)); + inet_twsk_put((struct inet_timewait_sock *) sk); goto discard_it; } - switch (tcp_timewait_state_process(inet_twsk(sk), skb, th)) { + switch (tcp_timewait_state_process((struct inet_timewait_sock *)sk, + skb, th)) { case TCP_TW_SYN: { struct sock *sk2 = inet_lookup_listener(&tcp_hashinfo, skb->nh.iph->daddr, th->dest, inet_iif(skb)); if (sk2) { - inet_twsk_deschedule(inet_twsk(sk), &tcp_death_row); - inet_twsk_put(inet_twsk(sk)); + inet_twsk_deschedule((struct inet_timewait_sock *)sk, + &tcp_death_row); + inet_twsk_put((struct inet_timewait_sock *)sk); sk = sk2; goto process; } diff --git a/trunk/net/ipv4/tcp_output.c b/trunk/net/ipv4/tcp_output.c index ca406157724c..9a253faefc81 100644 --- a/trunk/net/ipv4/tcp_output.c +++ b/trunk/net/ipv4/tcp_output.c @@ -273,10 +273,10 @@ static void tcp_build_and_update_options(__be32 *ptr, struct tcp_sock *tp, __u32 tstamp) { if (tp->rx_opt.tstamp_ok) { - *ptr++ = htonl((TCPOPT_NOP << 24) | - (TCPOPT_NOP << 16) | - (TCPOPT_TIMESTAMP << 8) | - TCPOLEN_TIMESTAMP); + *ptr++ = __constant_htonl((TCPOPT_NOP << 24) | + (TCPOPT_NOP << 16) | + (TCPOPT_TIMESTAMP << 8) | + TCPOLEN_TIMESTAMP); *ptr++ = htonl(tstamp); *ptr++ = htonl(tp->rx_opt.ts_recent); } @@ -325,27 +325,18 @@ static void tcp_syn_build_options(__be32 *ptr, int mss, int ts, int sack, *ptr++ = htonl((TCPOPT_MSS << 24) | (TCPOLEN_MSS << 16) | mss); if (ts) { if(sack) - *ptr++ = htonl((TCPOPT_SACK_PERM << 24) | - (TCPOLEN_SACK_PERM << 16) | - (TCPOPT_TIMESTAMP << 8) | - TCPOLEN_TIMESTAMP); + *ptr++ = __constant_htonl((TCPOPT_SACK_PERM << 24) | (TCPOLEN_SACK_PERM << 16) | + (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP); else - *ptr++ = htonl((TCPOPT_NOP << 24) | - (TCPOPT_NOP << 16) | - (TCPOPT_TIMESTAMP << 8) | - TCPOLEN_TIMESTAMP); + *ptr++ = __constant_htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | + (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP); *ptr++ = htonl(tstamp); /* TSVAL */ *ptr++ = htonl(ts_recent); /* TSECR */ } else if(sack) - *ptr++ = htonl((TCPOPT_NOP << 24) | - (TCPOPT_NOP << 16) | - (TCPOPT_SACK_PERM << 8) | - TCPOLEN_SACK_PERM); + *ptr++ = __constant_htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | + (TCPOPT_SACK_PERM << 8) | TCPOLEN_SACK_PERM); if (offer_wscale) - *ptr++ = htonl((TCPOPT_NOP << 24) | - (TCPOPT_WINDOW << 16) | - (TCPOLEN_WINDOW << 8) | - (wscale)); + *ptr++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_WINDOW << 16) | (TCPOLEN_WINDOW << 8) | (wscale)); } /* This routine actually transmits TCP packets queued in by @@ -1096,14 +1087,10 @@ static int tcp_tso_should_defer(struct sock *sk, struct tcp_sock *tp, struct sk_ u32 send_win, cong_win, limit, in_flight; if (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN) - goto send_now; + return 0; if (icsk->icsk_ca_state != TCP_CA_Open) - goto send_now; - - /* Defer for less than two clock ticks. */ - if (!tp->tso_deferred && ((jiffies<<1)>>1) - (tp->tso_deferred>>1) > 1) - goto send_now; + return 0; in_flight = tcp_packets_in_flight(tp); @@ -1119,7 +1106,7 @@ static int tcp_tso_should_defer(struct sock *sk, struct tcp_sock *tp, struct sk_ /* If a full-sized TSO skb can be sent, do it. */ if (limit >= 65536) - goto send_now; + return 0; if (sysctl_tcp_tso_win_divisor) { u32 chunk = min(tp->snd_wnd, tp->snd_cwnd * tp->mss_cache); @@ -1129,7 +1116,7 @@ static int tcp_tso_should_defer(struct sock *sk, struct tcp_sock *tp, struct sk_ */ chunk /= sysctl_tcp_tso_win_divisor; if (limit >= chunk) - goto send_now; + return 0; } else { /* Different approach, try not to defer past a single * ACK. Receiver should ACK every other full sized @@ -1137,17 +1124,11 @@ static int tcp_tso_should_defer(struct sock *sk, struct tcp_sock *tp, struct sk_ * then send now. */ if (limit > tcp_max_burst(tp) * tp->mss_cache) - goto send_now; + return 0; } /* Ok, it looks like it is advisable to defer. */ - tp->tso_deferred = 1 | (jiffies<<1); - return 1; - -send_now: - tp->tso_deferred = 0; - return 0; } /* Create a new MTU probe if we are ready. diff --git a/trunk/net/ipv4/tcp_probe.c b/trunk/net/ipv4/tcp_probe.c index f230eeecf092..4be336f17883 100644 --- a/trunk/net/ipv4/tcp_probe.c +++ b/trunk/net/ipv4/tcp_probe.c @@ -156,8 +156,6 @@ static __init int tcpprobe_init(void) init_waitqueue_head(&tcpw.wait); spin_lock_init(&tcpw.lock); tcpw.fifo = kfifo_alloc(bufsize, GFP_KERNEL, &tcpw.lock); - if (IS_ERR(tcpw.fifo)) - return PTR_ERR(tcpw.fifo); if (!proc_net_fops_create(procname, S_IRUSR, &tcpprobe_fops)) goto err0; diff --git a/trunk/net/ipv4/udp.c b/trunk/net/ipv4/udp.c index 9e1bd374875e..865d75214a9a 100644 --- a/trunk/net/ipv4/udp.c +++ b/trunk/net/ipv4/udp.c @@ -928,32 +928,23 @@ static int udp_encap_rcv(struct sock * sk, struct sk_buff *skb) return 1; #else struct udp_sock *up = udp_sk(sk); - struct udphdr *uh; + struct udphdr *uh = skb->h.uh; struct iphdr *iph; int iphlen, len; - __u8 *udpdata; - __be32 *udpdata32; + __u8 *udpdata = (__u8 *)uh + sizeof(struct udphdr); + __be32 *udpdata32 = (__be32 *)udpdata; __u16 encap_type = up->encap_type; /* if we're overly short, let UDP handle it */ - len = skb->len - sizeof(struct udphdr); - if (len <= 0) + if (udpdata > skb->tail) return 1; /* if this is not encapsulated socket, then just return now */ if (!encap_type) return 1; - /* If this is a paged skb, make sure we pull up - * whatever data we need to look at. */ - if (!pskb_may_pull(skb, sizeof(struct udphdr) + min(len, 8))) - return 1; - - /* Now we can get the pointers */ - uh = skb->h.uh; - udpdata = (__u8 *)uh + sizeof(struct udphdr); - udpdata32 = (__be32 *)udpdata; + len = skb->tail - udpdata; switch (encap_type) { default: diff --git a/trunk/net/ipv4/xfrm4_policy.c b/trunk/net/ipv4/xfrm4_policy.c index 1bed0cdf53e3..7a7a00147e55 100644 --- a/trunk/net/ipv4/xfrm4_policy.c +++ b/trunk/net/ipv4/xfrm4_policy.c @@ -52,7 +52,7 @@ __xfrm4_find_bundle(struct flowi *fl, struct xfrm_policy *policy) xdst->u.rt.fl.fl4_dst == fl->fl4_dst && xdst->u.rt.fl.fl4_src == fl->fl4_src && xdst->u.rt.fl.fl4_tos == fl->fl4_tos && - xfrm_bundle_ok(policy, xdst, fl, AF_INET, 0)) { + xfrm_bundle_ok(xdst, fl, AF_INET, 0)) { dst_clone(dst); break; } diff --git a/trunk/net/ipv6/Kconfig b/trunk/net/ipv6/Kconfig index 6e48f52e197c..a460e8132b4d 100644 --- a/trunk/net/ipv6/Kconfig +++ b/trunk/net/ipv6/Kconfig @@ -153,19 +153,6 @@ config INET6_XFRM_MODE_ROUTEOPTIMIZATION ---help--- Support for MIPv6 route optimization mode. -config IPV6_SIT - tristate "IPv6: IPv6-in-IPv4 tunnel (SIT driver)" - depends on IPV6 - default y - ---help--- - Tunneling means encapsulating data of one protocol type within - another protocol and sending it over a channel that understands the - encapsulating protocol. This driver implements encapsulation of IPv6 - into IPv4 packets. This is useful if you want to connect two IPv6 - networks over an IPv4-only path. - - Saying M here will produce a module called sit.ko. If unsure, say Y. - config IPV6_TUNNEL tristate "IPv6: IPv6-in-IPv6 tunnel" select INET6_TUNNEL @@ -175,16 +162,9 @@ config IPV6_TUNNEL If unsure, say N. -config IPV6_MULTIPLE_TABLES - bool "IPv6: Multiple Routing Tables" - depends on IPV6 && EXPERIMENTAL - select FIB_RULES - ---help--- - Support multiple routing tables. - config IPV6_SUBTREES bool "IPv6: source address based routing" - depends on IPV6_MULTIPLE_TABLES + depends on IPV6 && EXPERIMENTAL ---help--- Enable routing by source address or prefix. @@ -196,6 +176,13 @@ config IPV6_SUBTREES If unsure, say N. +config IPV6_MULTIPLE_TABLES + bool "IPv6: Multiple Routing Tables" + depends on IPV6 && EXPERIMENTAL + select FIB_RULES + ---help--- + Support multiple routing tables. + config IPV6_ROUTE_FWMARK bool "IPv6: use netfilter MARK value as routing key" depends on IPV6_MULTIPLE_TABLES && NETFILTER diff --git a/trunk/net/ipv6/Makefile b/trunk/net/ipv6/Makefile index addcc011bc01..87274e47fe32 100644 --- a/trunk/net/ipv6/Makefile +++ b/trunk/net/ipv6/Makefile @@ -4,7 +4,7 @@ obj-$(CONFIG_IPV6) += ipv6.o -ipv6-objs := af_inet6.o anycast.o ip6_output.o ip6_input.o addrconf.o \ +ipv6-objs := af_inet6.o anycast.o ip6_output.o ip6_input.o addrconf.o sit.o \ route.o ip6_fib.o ipv6_sockglue.o ndisc.o udp.o raw.o \ protocol.o icmp.o mcast.o reassembly.o tcp_ipv6.o \ exthdrs.o sysctl_net_ipv6.o datagram.o proc.o \ @@ -29,7 +29,6 @@ obj-$(CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION) += xfrm6_mode_ro.o obj-$(CONFIG_INET6_XFRM_MODE_BEET) += xfrm6_mode_beet.o obj-$(CONFIG_NETFILTER) += netfilter/ -obj-$(CONFIG_IPV6_SIT) += sit.o obj-$(CONFIG_IPV6_TUNNEL) += ip6_tunnel.o obj-y += exthdrs_core.o diff --git a/trunk/net/ipv6/addrconf.c b/trunk/net/ipv6/addrconf.c index b312a5f7a759..e03c33b2465b 100644 --- a/trunk/net/ipv6/addrconf.c +++ b/trunk/net/ipv6/addrconf.c @@ -396,10 +396,8 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev) ndev->regen_timer.data = (unsigned long) ndev; if ((dev->flags&IFF_LOOPBACK) || dev->type == ARPHRD_TUNNEL || -#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE) - dev->type == ARPHRD_SIT || -#endif - dev->type == ARPHRD_NONE) { + dev->type == ARPHRD_NONE || + dev->type == ARPHRD_SIT) { printk(KERN_INFO "%s: Disabled Privacy Extensions\n", dev->name); @@ -1548,10 +1546,8 @@ addrconf_prefix_route(struct in6_addr *pfx, int plen, struct net_device *dev, This thing is done here expecting that the whole class of non-broadcast devices need not cloning. */ -#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE) if (dev->type == ARPHRD_SIT && (dev->flags & IFF_POINTOPOINT)) cfg.fc_flags |= RTF_NONEXTHOP; -#endif ip6_route_add(&cfg); } @@ -1573,7 +1569,6 @@ static void addrconf_add_mroute(struct net_device *dev) ip6_route_add(&cfg); } -#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE) static void sit_route_add(struct net_device *dev) { struct fib6_config cfg = { @@ -1587,7 +1582,6 @@ static void sit_route_add(struct net_device *dev) /* prefix length - 96 bits "::d.d.d.d" */ ip6_route_add(&cfg); } -#endif static void addrconf_add_lroute(struct net_device *dev) { @@ -1858,7 +1852,6 @@ int addrconf_set_dstaddr(void __user *arg) if (dev == NULL) goto err_exit; -#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE) if (dev->type == ARPHRD_SIT) { struct ifreq ifr; mm_segment_t oldfs; @@ -1888,7 +1881,6 @@ int addrconf_set_dstaddr(void __user *arg) err = dev_open(dev); } } -#endif err_exit: rtnl_unlock(); @@ -2018,7 +2010,6 @@ int addrconf_del_ifaddr(void __user *arg) return err; } -#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE) static void sit_add_v4_addrs(struct inet6_dev *idev) { struct inet6_ifaddr * ifp; @@ -2087,7 +2078,6 @@ static void sit_add_v4_addrs(struct inet6_dev *idev) } } } -#endif static void init_loopback(struct net_device *dev) { @@ -2151,7 +2141,6 @@ static void addrconf_dev_config(struct net_device *dev) addrconf_add_linklocal(idev, &addr); } -#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE) static void addrconf_sit_config(struct net_device *dev) { struct inet6_dev *idev; @@ -2177,7 +2166,6 @@ static void addrconf_sit_config(struct net_device *dev) } else sit_route_add(dev); } -#endif static inline int ipv6_inherit_linklocal(struct inet6_dev *idev, struct net_device *link_dev) @@ -2272,11 +2260,9 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, } switch(dev->type) { -#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE) case ARPHRD_SIT: addrconf_sit_config(dev); break; -#endif case ARPHRD_TUNNEL6: addrconf_ip6_tnl_config(dev); break; diff --git a/trunk/net/ipv6/af_inet6.c b/trunk/net/ipv6/af_inet6.c index 858cae29581c..e94eccb99707 100644 --- a/trunk/net/ipv6/af_inet6.c +++ b/trunk/net/ipv6/af_inet6.c @@ -850,6 +850,7 @@ static int __init inet6_init(void) err = addrconf_init(); if (err) goto addrconf_fail; + sit_init(); /* Init v6 extension headers. */ ipv6_rthdr_init(); @@ -926,6 +927,7 @@ static void __exit inet6_exit(void) mip6_fini(); #endif /* Cleanup code parts. */ + sit_cleanup(); ip6_flowlabel_cleanup(); addrconf_cleanup(); ip6_route_cleanup(); diff --git a/trunk/net/ipv6/fib6_rules.c b/trunk/net/ipv6/fib6_rules.c index 1896ecb52899..d8c1057e8b00 100644 --- a/trunk/net/ipv6/fib6_rules.c +++ b/trunk/net/ipv6/fib6_rules.c @@ -117,15 +117,12 @@ static int fib6_rule_match(struct fib_rule *rule, struct flowi *fl, int flags) { struct fib6_rule *r = (struct fib6_rule *) rule; - if (r->dst.plen && - !ipv6_prefix_equal(&fl->fl6_dst, &r->dst.addr, r->dst.plen)) + if (!ipv6_prefix_equal(&fl->fl6_dst, &r->dst.addr, r->dst.plen)) return 0; - if (r->src.plen) { - if (!(flags & RT6_LOOKUP_F_HAS_SADDR) || - !ipv6_prefix_equal(&fl->fl6_src, &r->src.addr, r->src.plen)) - return 0; - } + if ((flags & RT6_LOOKUP_F_HAS_SADDR) && + !ipv6_prefix_equal(&fl->fl6_src, &r->src.addr, r->src.plen)) + return 0; if (r->tclass && r->tclass != ((ntohl(fl->fl6_flowlabel) >> 20) & 0xff)) return 0; diff --git a/trunk/net/ipv6/ip6_fib.c b/trunk/net/ipv6/ip6_fib.c index f98ca30d7c1f..8fcae7a6510b 100644 --- a/trunk/net/ipv6/ip6_fib.c +++ b/trunk/net/ipv6/ip6_fib.c @@ -169,6 +169,7 @@ static __inline__ void rt6_release(struct rt6_info *rt) static struct fib6_table fib6_main_tbl = { .tb6_id = RT6_TABLE_MAIN, + .tb6_lock = RW_LOCK_UNLOCKED, .tb6_root = { .leaf = &ip6_null_entry, .fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO, @@ -186,12 +187,6 @@ static void fib6_link_table(struct fib6_table *tb) { unsigned int h; - /* - * Initialize table lock at a single place to give lockdep a key, - * tables aren't visible prior to being linked to the list. - */ - rwlock_init(&tb->tb6_lock); - h = tb->tb6_id & (FIB_TABLE_HASHSZ - 1); /* @@ -204,6 +199,7 @@ static void fib6_link_table(struct fib6_table *tb) #ifdef CONFIG_IPV6_MULTIPLE_TABLES static struct fib6_table fib6_local_tbl = { .tb6_id = RT6_TABLE_LOCAL, + .tb6_lock = RW_LOCK_UNLOCKED, .tb6_root = { .leaf = &ip6_null_entry, .fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO, @@ -217,6 +213,7 @@ static struct fib6_table *fib6_alloc_table(u32 id) table = kzalloc(sizeof(*table), GFP_ATOMIC); if (table != NULL) { table->tb6_id = id; + table->tb6_lock = RW_LOCK_UNLOCKED; table->tb6_root.leaf = &ip6_null_entry; table->tb6_root.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO; } diff --git a/trunk/net/ipv6/ip6_flowlabel.c b/trunk/net/ipv6/ip6_flowlabel.c index 6d4533b58dca..1d672b0547f2 100644 --- a/trunk/net/ipv6/ip6_flowlabel.c +++ b/trunk/net/ipv6/ip6_flowlabel.c @@ -330,10 +330,8 @@ fl_create(struct in6_flowlabel_req *freq, char __user *optval, int optlen, int * fl->share = freq->flr_share; addr_type = ipv6_addr_type(&freq->flr_dst); if ((addr_type&IPV6_ADDR_MAPPED) - || addr_type == IPV6_ADDR_ANY) { - err = -EINVAL; + || addr_type == IPV6_ADDR_ANY) goto done; - } ipv6_addr_copy(&fl->dst, &freq->flr_dst); atomic_set(&fl->users, 1); switch (fl->share) { @@ -589,8 +587,6 @@ static struct ip6_flowlabel *ip6fl_get_next(struct seq_file *seq, struct ip6_flo while (!fl) { if (++state->bucket <= FL_HASH_MASK) fl = fl_ht[state->bucket]; - else - break; } return fl; } @@ -627,13 +623,9 @@ static void ip6fl_seq_stop(struct seq_file *seq, void *v) read_unlock_bh(&ip6_fl_lock); } -static int ip6fl_seq_show(struct seq_file *seq, void *v) +static void ip6fl_fl_seq_show(struct seq_file *seq, struct ip6_flowlabel *fl) { - if (v == SEQ_START_TOKEN) - seq_printf(seq, "%-5s %-1s %-6s %-6s %-6s %-8s %-32s %s\n", - "Label", "S", "Owner", "Users", "Linger", "Expires", "Dst", "Opt"); - else { - struct ip6_flowlabel *fl = v; + while(fl) { seq_printf(seq, "%05X %-1d %-6d %-6d %-6ld %-8ld " NIP6_SEQFMT " %-4d\n", (unsigned)ntohl(fl->label), @@ -644,7 +636,17 @@ static int ip6fl_seq_show(struct seq_file *seq, void *v) (long)(fl->expires - jiffies)/HZ, NIP6(fl->dst), fl->opt ? fl->opt->opt_nflen : 0); + fl = fl->next; } +} + +static int ip6fl_seq_show(struct seq_file *seq, void *v) +{ + if (v == SEQ_START_TOKEN) + seq_printf(seq, "%-5s %-1s %-6s %-6s %-6s %-8s %-32s %s\n", + "Label", "S", "Owner", "Users", "Linger", "Expires", "Dst", "Opt"); + else + ip6fl_fl_seq_show(seq, v); return 0; } diff --git a/trunk/net/ipv6/ip6_tunnel.c b/trunk/net/ipv6/ip6_tunnel.c index b9f40290d12a..84d7ebdb9d21 100644 --- a/trunk/net/ipv6/ip6_tunnel.c +++ b/trunk/net/ipv6/ip6_tunnel.c @@ -542,7 +542,6 @@ ip6ip6_rcv(struct sk_buff *skb) skb->dev = t->dev; dst_release(skb->dst); skb->dst = NULL; - nf_reset(skb); if (t->parms.flags & IP6_TNL_F_RCV_DSCP_COPY) ipv6_copy_dscp(ipv6h, skb->nh.ipv6h); ip6ip6_ecn_decapsulate(ipv6h, skb); @@ -1150,20 +1149,6 @@ static int __init ip6_tunnel_init(void) return err; } -static void __exit ip6ip6_destroy_tunnels(void) -{ - int h; - struct ip6_tnl *t; - - for (h = 0; h < HASH_SIZE; h++) { - while ((t = tnls_r_l[h]) != NULL) - unregister_netdevice(t->dev); - } - - t = tnls_wc[0]; - unregister_netdevice(t->dev); -} - /** * ip6_tunnel_cleanup - free resources and unregister protocol **/ @@ -1173,9 +1158,7 @@ static void __exit ip6_tunnel_cleanup(void) if (xfrm6_tunnel_deregister(&ip6ip6_handler)) printk(KERN_INFO "ip6ip6 close: can't deregister tunnel\n"); - rtnl_lock(); - ip6ip6_destroy_tunnels(); - rtnl_unlock(); + unregister_netdev(ip6ip6_fb_tnl_dev); } module_init(ip6_tunnel_init); diff --git a/trunk/net/ipv6/ndisc.c b/trunk/net/ipv6/ndisc.c index 73eb8c33e9f0..0304b5fe8d6a 100644 --- a/trunk/net/ipv6/ndisc.c +++ b/trunk/net/ipv6/ndisc.c @@ -967,6 +967,8 @@ static void ndisc_recv_na(struct sk_buff *skb) ipv6_devconf.forwarding && ipv6_devconf.proxy_ndp && pneigh_lookup(&nd_tbl, &msg->target, dev, 0)) { /* XXX: idev->cnf.prixy_ndp */ + WARN_ON(skb->dst != NULL && + ((struct rt6_info *)skb->dst)->rt6i_idev); goto out; } @@ -1742,7 +1744,6 @@ int __init ndisc_init(struct net_proto_family *ops) void ndisc_cleanup(void) { - unregister_netdevice_notifier(&ndisc_netdev_notifier); #ifdef CONFIG_SYSCTL neigh_sysctl_unregister(&nd_tbl.parms); #endif diff --git a/trunk/net/ipv6/netfilter/Kconfig b/trunk/net/ipv6/netfilter/Kconfig index d7c45a9c15fe..4bc4e5b33794 100644 --- a/trunk/net/ipv6/netfilter/Kconfig +++ b/trunk/net/ipv6/netfilter/Kconfig @@ -40,7 +40,7 @@ config IP6_NF_QUEUE To compile it as a module, choose M here. If unsure, say N. config IP6_NF_IPTABLES - tristate "IP6 tables support (required for filtering)" + tristate "IP6 tables support (required for filtering/masq/NAT)" depends on NETFILTER_XTABLES help ip6tables is a general, extensible packet identification framework. diff --git a/trunk/net/ipv6/netfilter/ip6_queue.c b/trunk/net/ipv6/netfilter/ip6_queue.c index 9fec832ee08b..9510c24ca8d2 100644 --- a/trunk/net/ipv6/netfilter/ip6_queue.c +++ b/trunk/net/ipv6/netfilter/ip6_queue.c @@ -349,10 +349,9 @@ ipq_mangle_ipv6(ipq_verdict_msg_t *v, struct ipq_queue_entry *e) if (v->data_len < sizeof(*user_iph)) return 0; diff = v->data_len - e->skb->len; - if (diff < 0) { - if (pskb_trim(e->skb, v->data_len)) - return -ENOMEM; - } else if (diff > 0) { + if (diff < 0) + skb_trim(e->skb, v->data_len); + else if (diff > 0) { if (v->data_len > 0xFFFF) return -EINVAL; if (diff > skb_tailroom(e->skb)) { diff --git a/trunk/net/ipv6/netfilter/ip6_tables.c b/trunk/net/ipv6/netfilter/ip6_tables.c index 204e02162d49..4ab368fa0b8f 100644 --- a/trunk/net/ipv6/netfilter/ip6_tables.c +++ b/trunk/net/ipv6/netfilter/ip6_tables.c @@ -111,7 +111,7 @@ ip6_packet_match(const struct sk_buff *skb, const char *outdev, const struct ip6t_ip6 *ip6info, unsigned int *protoff, - int *fragoff, int *hotdrop) + int *fragoff) { size_t i; unsigned long ret; @@ -169,11 +169,9 @@ ip6_packet_match(const struct sk_buff *skb, unsigned short _frag_off; protohdr = ipv6_find_hdr(skb, protoff, -1, &_frag_off); - if (protohdr < 0) { - if (_frag_off == 0) - *hotdrop = 1; + if (protohdr < 0) return 0; - } + *fragoff = _frag_off; dprintf("Packet protocol %hi ?= %s%hi.\n", @@ -292,7 +290,7 @@ ip6t_do_table(struct sk_buff **pskb, IP_NF_ASSERT(e); IP_NF_ASSERT(back); if (ip6_packet_match(*pskb, indev, outdev, &e->ipv6, - &protoff, &offset, &hotdrop)) { + &protoff, &offset)) { struct ip6t_entry_target *t; if (IP6T_MATCH_ITERATE(e, do_match, @@ -586,19 +584,12 @@ check_entry(struct ip6t_entry *e, const char *name, unsigned int size, return -EINVAL; } - if (e->target_offset + sizeof(struct ip6t_entry_target) > - e->next_offset) - return -EINVAL; - j = 0; ret = IP6T_MATCH_ITERATE(e, check_match, name, &e->ipv6, e->comefrom, &j); if (ret != 0) goto cleanup_matches; t = ip6t_get_target(e); - ret = -EINVAL; - if (e->target_offset + t->u.target_size > e->next_offset) - goto cleanup_matches; target = try_then_request_module(xt_find_target(AF_INET6, t->u.user.name, t->u.user.revision), @@ -758,17 +749,19 @@ translate_table(const char *name, } } + if (!mark_source_chains(newinfo, valid_hooks, entry0)) + return -ELOOP; + /* Finally, each sanity check must pass */ i = 0; ret = IP6T_ENTRY_ITERATE(entry0, newinfo->size, check_entry, name, size, &i); - if (ret != 0) - goto cleanup; - - ret = -ELOOP; - if (!mark_source_chains(newinfo, valid_hooks, entry0)) - goto cleanup; + if (ret != 0) { + IP6T_ENTRY_ITERATE(entry0, newinfo->size, + cleanup_entry, &i); + return ret; + } /* And one copy for every other CPU */ for_each_possible_cpu(i) { @@ -776,9 +769,6 @@ translate_table(const char *name, memcpy(newinfo->entries[i], entry0, newinfo->size); } - return 0; -cleanup: - IP6T_ENTRY_ITERATE(entry0, newinfo->size, cleanup_entry, &i); return ret; } @@ -1448,9 +1438,6 @@ static void __exit ip6_tables_fini(void) * If target header is found, its offset is set in *offset and return protocol * number. Otherwise, return -1. * - * If the first fragment doesn't contain the final protocol header or - * NEXTHDR_NONE it is considered invalid. - * * Note that non-1st fragment is special case that "the protocol number * of last header" is "next header" field in Fragment header. In this case, * *offset is meaningless and fragment offset is stored in *fragoff if fragoff @@ -1474,12 +1461,12 @@ int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, if ((!ipv6_ext_hdr(nexthdr)) || nexthdr == NEXTHDR_NONE) { if (target < 0) break; - return -ENOENT; + return -1; } hp = skb_header_pointer(skb, start, sizeof(_hdr), &_hdr); if (hp == NULL) - return -EBADMSG; + return -1; if (nexthdr == NEXTHDR_FRAGMENT) { unsigned short _frag_off, *fp; fp = skb_header_pointer(skb, @@ -1488,18 +1475,18 @@ int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, sizeof(_frag_off), &_frag_off); if (fp == NULL) - return -EBADMSG; + return -1; _frag_off = ntohs(*fp) & ~0x7; if (_frag_off) { if (target < 0 && ((!ipv6_ext_hdr(hp->nexthdr)) || - hp->nexthdr == NEXTHDR_NONE)) { + nexthdr == NEXTHDR_NONE)) { if (fragoff) *fragoff = _frag_off; return hp->nexthdr; } - return -ENOENT; + return -1; } hdrlen = 8; } else if (nexthdr == NEXTHDR_AUTH) diff --git a/trunk/net/ipv6/netfilter/ip6t_ah.c b/trunk/net/ipv6/netfilter/ip6t_ah.c index 46486645eb75..ec1b1608156c 100644 --- a/trunk/net/ipv6/netfilter/ip6t_ah.c +++ b/trunk/net/ipv6/netfilter/ip6t_ah.c @@ -54,14 +54,9 @@ match(const struct sk_buff *skb, const struct ip6t_ah *ahinfo = matchinfo; unsigned int ptr; unsigned int hdrlen = 0; - int err; - err = ipv6_find_hdr(skb, &ptr, NEXTHDR_AUTH, NULL); - if (err < 0) { - if (err != -ENOENT) - *hotdrop = 1; + if (ipv6_find_hdr(skb, &ptr, NEXTHDR_AUTH, NULL) < 0) return 0; - } ah = skb_header_pointer(skb, ptr, sizeof(_ah), &_ah); if (ah == NULL) { diff --git a/trunk/net/ipv6/netfilter/ip6t_frag.c b/trunk/net/ipv6/netfilter/ip6t_frag.c index cd22eaaccdca..78d9c8b9e28a 100644 --- a/trunk/net/ipv6/netfilter/ip6t_frag.c +++ b/trunk/net/ipv6/netfilter/ip6t_frag.c @@ -52,14 +52,9 @@ match(const struct sk_buff *skb, struct frag_hdr _frag, *fh; const struct ip6t_frag *fraginfo = matchinfo; unsigned int ptr; - int err; - err = ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT, NULL); - if (err < 0) { - if (err != -ENOENT) - *hotdrop = 1; + if (ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT, NULL) < 0) return 0; - } fh = skb_header_pointer(skb, ptr, sizeof(_frag), &_frag); if (fh == NULL) { diff --git a/trunk/net/ipv6/netfilter/ip6t_hbh.c b/trunk/net/ipv6/netfilter/ip6t_hbh.c index 3f25babe0440..d32a205e3af2 100644 --- a/trunk/net/ipv6/netfilter/ip6t_hbh.c +++ b/trunk/net/ipv6/netfilter/ip6t_hbh.c @@ -65,14 +65,9 @@ match(const struct sk_buff *skb, u8 _opttype, *tp = NULL; u8 _optlen, *lp = NULL; unsigned int optlen; - int err; - err = ipv6_find_hdr(skb, &ptr, match->data, NULL); - if (err < 0) { - if (err != -ENOENT) - *hotdrop = 1; + if (ipv6_find_hdr(skb, &ptr, match->data, NULL) < 0) return 0; - } oh = skb_header_pointer(skb, ptr, sizeof(_optsh), &_optsh); if (oh == NULL) { diff --git a/trunk/net/ipv6/netfilter/ip6t_rt.c b/trunk/net/ipv6/netfilter/ip6t_rt.c index 54d7d14134fd..bcb2e168a5bc 100644 --- a/trunk/net/ipv6/netfilter/ip6t_rt.c +++ b/trunk/net/ipv6/netfilter/ip6t_rt.c @@ -58,14 +58,9 @@ match(const struct sk_buff *skb, unsigned int hdrlen = 0; unsigned int ret = 0; struct in6_addr *ap, _addr; - int err; - err = ipv6_find_hdr(skb, &ptr, NEXTHDR_ROUTING, NULL); - if (err < 0) { - if (err != -ENOENT) - *hotdrop = 1; + if (ipv6_find_hdr(skb, &ptr, NEXTHDR_ROUTING, NULL) < 0) return 0; - } rh = skb_header_pointer(skb, ptr, sizeof(_route), &_route); if (rh == NULL) { diff --git a/trunk/net/ipv6/raw.c b/trunk/net/ipv6/raw.c index d6dedc4aec77..d09329ca3267 100644 --- a/trunk/net/ipv6/raw.c +++ b/trunk/net/ipv6/raw.c @@ -604,7 +604,7 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length, return err; } -static int rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg) +static void rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg) { struct iovec *iov; u8 __user *type = NULL; @@ -616,7 +616,7 @@ static int rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg) int i; if (!msg->msg_iov) - return 0; + return; for (i = 0; i < msg->msg_iovlen; i++) { iov = &msg->msg_iov[i]; @@ -638,9 +638,8 @@ static int rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg) code = iov->iov_base; if (type && code) { - if (get_user(fl->fl_icmp_type, type) || - get_user(fl->fl_icmp_code, code)) - return -EFAULT; + get_user(fl->fl_icmp_type, type); + get_user(fl->fl_icmp_code, code); probed = 1; } break; @@ -651,8 +650,7 @@ static int rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg) /* check if type field is readable or not. */ if (iov->iov_len > 2 - len) { u8 __user *p = iov->iov_base; - if (get_user(fl->fl_mh_type, &p[2 - len])) - return -EFAULT; + get_user(fl->fl_mh_type, &p[2 - len]); probed = 1; } else len += iov->iov_len; @@ -666,7 +664,6 @@ static int rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg) if (probed) break; } - return 0; } static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, @@ -790,9 +787,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, opt = ipv6_fixup_options(&opt_space, opt); fl.proto = proto; - err = rawv6_probe_proto_opt(&fl, msg); - if (err) - goto out; + rawv6_probe_proto_opt(&fl, msg); ipv6_addr_copy(&fl.fl6_dst, daddr); if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr)) diff --git a/trunk/net/ipv6/route.c b/trunk/net/ipv6/route.c index b39ae99122d5..d6b4b4f48d18 100644 --- a/trunk/net/ipv6/route.c +++ b/trunk/net/ipv6/route.c @@ -141,10 +141,6 @@ struct rt6_info ip6_null_entry = { #ifdef CONFIG_IPV6_MULTIPLE_TABLES -static int ip6_pkt_prohibit(struct sk_buff *skb); -static int ip6_pkt_prohibit_out(struct sk_buff *skb); -static int ip6_pkt_blk_hole(struct sk_buff *skb); - struct rt6_info ip6_prohibit_entry = { .u = { .dst = { @@ -154,8 +150,8 @@ struct rt6_info ip6_prohibit_entry = { .obsolete = -1, .error = -EACCES, .metrics = { [RTAX_HOPLIMIT - 1] = 255, }, - .input = ip6_pkt_prohibit, - .output = ip6_pkt_prohibit_out, + .input = ip6_pkt_discard, + .output = ip6_pkt_discard_out, .ops = &ip6_dst_ops, .path = (struct dst_entry*)&ip6_prohibit_entry, } @@ -174,8 +170,8 @@ struct rt6_info ip6_blk_hole_entry = { .obsolete = -1, .error = -EINVAL, .metrics = { [RTAX_HOPLIMIT - 1] = 255, }, - .input = ip6_pkt_blk_hole, - .output = ip6_pkt_blk_hole, + .input = ip6_pkt_discard, + .output = ip6_pkt_discard_out, .ops = &ip6_dst_ops, .path = (struct dst_entry*)&ip6_blk_hole_entry, } @@ -330,8 +326,6 @@ static int inline rt6_check_neigh(struct rt6_info *rt) read_lock_bh(&neigh->lock); if (neigh->nud_state & NUD_VALID) m = 2; - else if (!(neigh->nud_state & NUD_FAILED)) - m = 1; read_unlock_bh(&neigh->lock); } return m; @@ -349,7 +343,9 @@ static int rt6_score_route(struct rt6_info *rt, int oif, m |= IPV6_DECODE_PREF(IPV6_EXTRACT_PREF(rt->rt6i_flags)) << 2; #endif n = rt6_check_neigh(rt); - if (!n && (strict & RT6_LOOKUP_F_REACHABLE)) + if (n > 1) + m |= 16; + else if (!n && strict & RT6_LOOKUP_F_REACHABLE) return -1; return m; } @@ -380,11 +376,10 @@ static struct rt6_info *rt6_select(struct rt6_info **head, int oif, continue; if (m > mpri) { - if (strict & RT6_LOOKUP_F_REACHABLE) - rt6_probe(match); + rt6_probe(match); match = rt; mpri = m; - } else if (strict & RT6_LOOKUP_F_REACHABLE) { + } else { rt6_probe(rt); } } @@ -489,7 +484,7 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len, do { \ if (rt == &ip6_null_entry) { \ struct fib6_node *pn; \ - while (1) { \ + while (fn) { \ if (fn->fn_flags & RTN_TL_ROOT) \ goto out; \ pn = fn->parent; \ @@ -534,17 +529,13 @@ struct rt6_info *rt6_lookup(struct in6_addr *daddr, struct in6_addr *saddr, .nl_u = { .ip6_u = { .daddr = *daddr, + /* TODO: saddr */ }, }, }; struct dst_entry *dst; int flags = strict ? RT6_LOOKUP_F_IFACE : 0; - if (saddr) { - memcpy(&fl.fl6_src, saddr, sizeof(*saddr)); - flags |= RT6_LOOKUP_F_HAS_SADDR; - } - dst = fib6_rule_lookup(&fl, flags, ip6_pol_route_lookup); if (dst->error == 0) return (struct rt6_info *) dst; @@ -623,6 +614,8 @@ static struct rt6_info *rt6_alloc_clone(struct rt6_info *ort, struct in6_addr *d ipv6_addr_copy(&rt->rt6i_dst.addr, daddr); rt->rt6i_dst.plen = 128; rt->rt6i_flags |= RTF_CACHE; + if (rt->rt6i_flags & RTF_REJECT) + rt->u.dst.error = ort->u.dst.error; rt->u.dst.flags |= DST_HOST; rt->rt6i_nexthop = neigh_clone(ort->rt6i_nexthop); } @@ -637,7 +630,7 @@ static struct rt6_info *ip6_pol_route_input(struct fib6_table *table, int strict = 0; int attempts = 3; int err; - int reachable = ipv6_devconf.forwarding ? 0 : RT6_LOOKUP_F_REACHABLE; + int reachable = RT6_LOOKUP_F_REACHABLE; strict |= flags & RT6_LOOKUP_F_IFACE; @@ -704,7 +697,6 @@ static struct rt6_info *ip6_pol_route_input(struct fib6_table *table, void ip6_route_input(struct sk_buff *skb) { struct ipv6hdr *iph = skb->nh.ipv6h; - int flags = RT6_LOOKUP_F_HAS_SADDR; struct flowi fl = { .iif = skb->dev->ifindex, .nl_u = { @@ -719,9 +711,7 @@ void ip6_route_input(struct sk_buff *skb) }, .proto = iph->nexthdr, }; - - if (rt6_need_strict(&iph->daddr)) - flags |= RT6_LOOKUP_F_IFACE; + int flags = rt6_need_strict(&iph->daddr) ? RT6_LOOKUP_F_IFACE : 0; skb->dst = fib6_rule_lookup(&fl, flags, ip6_pol_route_input); } @@ -734,7 +724,7 @@ static struct rt6_info *ip6_pol_route_output(struct fib6_table *table, int strict = 0; int attempts = 3; int err; - int reachable = ipv6_devconf.forwarding ? 0 : RT6_LOOKUP_F_REACHABLE; + int reachable = RT6_LOOKUP_F_REACHABLE; strict |= flags & RT6_LOOKUP_F_IFACE; @@ -804,9 +794,6 @@ struct dst_entry * ip6_route_output(struct sock *sk, struct flowi *fl) if (rt6_need_strict(&fl->fl6_dst)) flags |= RT6_LOOKUP_F_IFACE; - if (!ipv6_addr_any(&fl->fl6_src)) - flags |= RT6_LOOKUP_F_HAS_SADDR; - return fib6_rule_lookup(fl, flags, ip6_pol_route_output); } @@ -1358,7 +1345,6 @@ static struct rt6_info *ip6_route_redirect(struct in6_addr *dest, struct in6_addr *gateway, struct net_device *dev) { - int flags = RT6_LOOKUP_F_HAS_SADDR; struct ip6rd_flowi rdfl = { .fl = { .oif = dev->ifindex, @@ -1371,9 +1357,7 @@ static struct rt6_info *ip6_route_redirect(struct in6_addr *dest, }, .gateway = *gateway, }; - - if (rt6_need_strict(dest)) - flags |= RT6_LOOKUP_F_IFACE; + int flags = rt6_need_strict(dest) ? RT6_LOOKUP_F_IFACE : 0; return (struct rt6_info *)fib6_rule_lookup((struct flowi *)&rdfl, flags, __ip6_route_redirect); } @@ -1543,7 +1527,6 @@ static struct rt6_info * ip6_rt_copy(struct rt6_info *ort) rt->u.dst.output = ort->u.dst.output; memcpy(rt->u.dst.metrics, ort->u.dst.metrics, RTAX_MAX*sizeof(u32)); - rt->u.dst.error = ort->u.dst.error; rt->u.dst.dev = ort->u.dst.dev; if (rt->u.dst.dev) dev_hold(rt->u.dst.dev); @@ -1747,50 +1730,24 @@ int ipv6_route_ioctl(unsigned int cmd, void __user *arg) * Drop the packet on the floor */ -static inline int ip6_pkt_drop(struct sk_buff *skb, int code) +static int ip6_pkt_discard(struct sk_buff *skb) { int type = ipv6_addr_type(&skb->nh.ipv6h->daddr); if (type == IPV6_ADDR_ANY || type == IPV6_ADDR_RESERVED) IP6_INC_STATS(IPSTATS_MIB_INADDRERRORS); IP6_INC_STATS(IPSTATS_MIB_OUTNOROUTES); - icmpv6_send(skb, ICMPV6_DEST_UNREACH, code, 0, skb->dev); + icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_NOROUTE, 0, skb->dev); kfree_skb(skb); return 0; } -static int ip6_pkt_discard(struct sk_buff *skb) -{ - return ip6_pkt_drop(skb, ICMPV6_NOROUTE); -} - static int ip6_pkt_discard_out(struct sk_buff *skb) { skb->dev = skb->dst->dev; return ip6_pkt_discard(skb); } -#ifdef CONFIG_IPV6_MULTIPLE_TABLES - -static int ip6_pkt_prohibit(struct sk_buff *skb) -{ - return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED); -} - -static int ip6_pkt_prohibit_out(struct sk_buff *skb) -{ - skb->dev = skb->dst->dev; - return ip6_pkt_prohibit(skb); -} - -static int ip6_pkt_blk_hole(struct sk_buff *skb) -{ - kfree_skb(skb); - return 0; -} - -#endif - /* * Allocate a dst for local (unicast / anycast) address. */ diff --git a/trunk/net/ipv6/sit.c b/trunk/net/ipv6/sit.c index be699f85b2c7..836eecd7e62b 100644 --- a/trunk/net/ipv6/sit.c +++ b/trunk/net/ipv6/sit.c @@ -850,8 +850,3 @@ int __init sit_init(void) inet_del_protocol(&sit_protocol, IPPROTO_IPV6); goto out; } - -module_init(sit_init); -module_exit(sit_cleanup); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("sit0"); diff --git a/trunk/net/ipv6/tcp_ipv6.c b/trunk/net/ipv6/tcp_ipv6.c index 4c2a7c0cafef..3b6575478fcc 100644 --- a/trunk/net/ipv6/tcp_ipv6.c +++ b/trunk/net/ipv6/tcp_ipv6.c @@ -329,7 +329,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, } if (sk->sk_state == TCP_TIME_WAIT) { - inet_twsk_put(inet_twsk(sk)); + inet_twsk_put((struct inet_timewait_sock *)sk); return; } @@ -653,7 +653,7 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 int tot_len = sizeof(struct tcphdr); if (ts) - tot_len += TCPOLEN_TSTAMP_ALIGNED; + tot_len += 3*4; buff = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr) + tot_len, GFP_ATOMIC); @@ -749,7 +749,7 @@ static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb) bh_lock_sock(nsk); return nsk; } - inet_twsk_put(inet_twsk(nsk)); + inet_twsk_put((struct inet_timewait_sock *)nsk); return NULL; } @@ -1283,17 +1283,18 @@ static int tcp_v6_rcv(struct sk_buff **pskb) do_time_wait: if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) { - inet_twsk_put(inet_twsk(sk)); + inet_twsk_put((struct inet_timewait_sock *)sk); goto discard_it; } if (skb->len < (th->doff<<2) || tcp_checksum_complete(skb)) { TCP_INC_STATS_BH(TCP_MIB_INERRS); - inet_twsk_put(inet_twsk(sk)); + inet_twsk_put((struct inet_timewait_sock *)sk); goto discard_it; } - switch (tcp_timewait_state_process(inet_twsk(sk), skb, th)) { + switch (tcp_timewait_state_process((struct inet_timewait_sock *)sk, + skb, th)) { case TCP_TW_SYN: { struct sock *sk2; diff --git a/trunk/net/ipv6/udp.c b/trunk/net/ipv6/udp.c index c83f23e51c46..e0c3934a7e4b 100644 --- a/trunk/net/ipv6/udp.c +++ b/trunk/net/ipv6/udp.c @@ -242,13 +242,14 @@ static void udpv6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, { struct ipv6_pinfo *np; struct ipv6hdr *hdr = (struct ipv6hdr*)skb->data; + struct net_device *dev = skb->dev; struct in6_addr *saddr = &hdr->saddr; struct in6_addr *daddr = &hdr->daddr; struct udphdr *uh = (struct udphdr*)(skb->data+offset); struct sock *sk; int err; - sk = udp_v6_lookup(daddr, uh->dest, saddr, uh->source, inet6_iif(skb)); + sk = udp_v6_lookup(daddr, uh->dest, saddr, uh->source, dev->ifindex); if (sk == NULL) return; @@ -347,7 +348,7 @@ static void udpv6_mcast_deliver(struct udphdr *uh, read_lock(&udp_hash_lock); sk = sk_head(&udp_hash[ntohs(uh->dest) & (UDP_HTABLE_SIZE - 1)]); - dif = inet6_iif(skb); + dif = skb->dev->ifindex; sk = udp_v6_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif); if (!sk) { kfree_skb(skb); @@ -428,7 +429,7 @@ static int udpv6_rcv(struct sk_buff **pskb) * check socket cache ... must talk to Alan about his plans * for sock caches... i'll skip this for now. */ - sk = udp_v6_lookup(saddr, uh->source, daddr, uh->dest, inet6_iif(skb)); + sk = udp_v6_lookup(saddr, uh->source, daddr, uh->dest, dev->ifindex); if (sk == NULL) { if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) diff --git a/trunk/net/ipv6/xfrm6_policy.c b/trunk/net/ipv6/xfrm6_policy.c index d400f8fae129..6a252e2134d1 100644 --- a/trunk/net/ipv6/xfrm6_policy.c +++ b/trunk/net/ipv6/xfrm6_policy.c @@ -25,14 +25,12 @@ static struct dst_ops xfrm6_dst_ops; static struct xfrm_policy_afinfo xfrm6_policy_afinfo; -static int xfrm6_dst_lookup(struct xfrm_dst **xdst, struct flowi *fl) +static int xfrm6_dst_lookup(struct xfrm_dst **dst, struct flowi *fl) { - struct dst_entry *dst = ip6_route_output(NULL, fl); - int err = dst->error; - if (!err) - *xdst = (struct xfrm_dst *) dst; - else - dst_release(dst); + int err = 0; + *dst = (struct xfrm_dst*)ip6_route_output(NULL, fl); + if (!*dst) + err = -ENETUNREACH; return err; } @@ -75,7 +73,7 @@ __xfrm6_find_bundle(struct flowi *fl, struct xfrm_policy *policy) xdst->u.rt6.rt6i_src.plen); if (ipv6_addr_equal(&xdst->u.rt6.rt6i_dst.addr, &fl_dst_prefix) && ipv6_addr_equal(&xdst->u.rt6.rt6i_src.addr, &fl_src_prefix) && - xfrm_bundle_ok(policy, xdst, fl, AF_INET6, + xfrm_bundle_ok(xdst, fl, AF_INET6, (xdst->u.rt6.rt6i_dst.plen != 128 || xdst->u.rt6.rt6i_src.plen != 128))) { dst_clone(dst); diff --git a/trunk/net/ipv6/xfrm6_tunnel.c b/trunk/net/ipv6/xfrm6_tunnel.c index 7931e4f898d4..7af227bb1551 100644 --- a/trunk/net/ipv6/xfrm6_tunnel.c +++ b/trunk/net/ipv6/xfrm6_tunnel.c @@ -135,7 +135,7 @@ u32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr) x6spi = __xfrm6_tunnel_spi_lookup(saddr); spi = x6spi ? x6spi->spi : 0; read_unlock_bh(&xfrm6_tunnel_spi_lock); - return htonl(spi); + return spi; } EXPORT_SYMBOL(xfrm6_tunnel_spi_lookup); @@ -210,7 +210,7 @@ u32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr) spi = __xfrm6_tunnel_alloc_spi(saddr); write_unlock_bh(&xfrm6_tunnel_spi_lock); - return htonl(spi); + return spi; } EXPORT_SYMBOL(xfrm6_tunnel_alloc_spi); diff --git a/trunk/net/ipx/af_ipx.c b/trunk/net/ipx/af_ipx.c index 76c661566dfd..bef3f61569f7 100644 --- a/trunk/net/ipx/af_ipx.c +++ b/trunk/net/ipx/af_ipx.c @@ -83,13 +83,13 @@ DEFINE_SPINLOCK(ipx_interfaces_lock); struct ipx_interface *ipx_primary_net; struct ipx_interface *ipx_internal_net; -extern int ipxrtr_add_route(__be32 network, struct ipx_interface *intrfc, +extern int ipxrtr_add_route(__u32 network, struct ipx_interface *intrfc, unsigned char *node); extern void ipxrtr_del_routes(struct ipx_interface *intrfc); extern int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx, struct iovec *iov, int len, int noblock); extern int ipxrtr_route_skb(struct sk_buff *skb); -extern struct ipx_route *ipxrtr_lookup(__be32 net); +extern struct ipx_route *ipxrtr_lookup(__u32 net); extern int ipxrtr_ioctl(unsigned int cmd, void __user *arg); #undef IPX_REFCNT_DEBUG @@ -177,7 +177,7 @@ static void ipxitf_clear_primary_net(void) } static struct ipx_interface *__ipxitf_find_using_phys(struct net_device *dev, - __be16 datalink) + unsigned short datalink) { struct ipx_interface *i; @@ -190,7 +190,7 @@ static struct ipx_interface *__ipxitf_find_using_phys(struct net_device *dev, } static struct ipx_interface *ipxitf_find_using_phys(struct net_device *dev, - __be16 datalink) + unsigned short datalink) { struct ipx_interface *i; @@ -202,7 +202,7 @@ static struct ipx_interface *ipxitf_find_using_phys(struct net_device *dev, return i; } -struct ipx_interface *ipxitf_find_using_net(__be32 net) +struct ipx_interface *ipxitf_find_using_net(__u32 net) { struct ipx_interface *i; @@ -237,7 +237,7 @@ static void ipxitf_insert_socket(struct ipx_interface *intrfc, struct sock *sk) /* caller must hold intrfc->if_sklist_lock */ static struct sock *__ipxitf_find_socket(struct ipx_interface *intrfc, - __be16 port) + unsigned short port) { struct sock *s; struct hlist_node *node; @@ -252,7 +252,7 @@ static struct sock *__ipxitf_find_socket(struct ipx_interface *intrfc, /* caller must hold a reference to intrfc */ static struct sock *ipxitf_find_socket(struct ipx_interface *intrfc, - __be16 port) + unsigned short port) { struct sock *s; @@ -268,7 +268,7 @@ static struct sock *ipxitf_find_socket(struct ipx_interface *intrfc, #ifdef CONFIG_IPX_INTERN static struct sock *ipxitf_find_internal_socket(struct ipx_interface *intrfc, unsigned char *ipx_node, - __be16 port) + unsigned short port) { struct sock *s; struct hlist_node *node; @@ -600,10 +600,10 @@ int ipxitf_send(struct ipx_interface *intrfc, struct sk_buff *skb, char *node) /* see if we need to include the netnum in the route list */ if (IPX_SKB_CB(skb)->last_hop.index >= 0) { - __be32 *last_hop = (__be32 *)(((u8 *) skb->data) + + u32 *last_hop = (u32 *)(((u8 *) skb->data) + sizeof(struct ipxhdr) + IPX_SKB_CB(skb)->last_hop.index * - sizeof(__be32)); + sizeof(u32)); *last_hop = IPX_SKB_CB(skb)->last_hop.netnum; IPX_SKB_CB(skb)->last_hop.index = -1; } @@ -772,7 +772,7 @@ static void ipxitf_discover_netnum(struct ipx_interface *intrfc, } else { printk(KERN_WARNING "IPX: Network number collision " "%lx\n %s %s and %s %s\n", - (unsigned long) ntohl(cb->ipx_source_net), + (unsigned long) htonl(cb->ipx_source_net), ipx_device_name(i), ipx_frame_name(i->if_dlink_type), ipx_device_name(intrfc), @@ -812,7 +812,7 @@ static int ipxitf_pprop(struct ipx_interface *intrfc, struct sk_buff *skb) int i, rc = -EINVAL; struct ipx_interface *ifcs; char *c; - __be32 *l; + u32 *l; /* Illegal packet - too many hops or too short */ /* We decide to throw it away: no broadcasting, no local processing. @@ -833,7 +833,7 @@ static int ipxitf_pprop(struct ipx_interface *intrfc, struct sk_buff *skb) goto out; c = ((u8 *) ipx) + sizeof(struct ipxhdr); - l = (__be32 *) c; + l = (u32 *) c; /* Don't broadcast packet if already seen this net */ for (i = 0; i < IPX_SKB_CB(skb)->ipx_tctrl; i++) @@ -855,7 +855,7 @@ static int ipxitf_pprop(struct ipx_interface *intrfc, struct sk_buff *skb) /* That aren't in the list */ if (ifcs == intrfc) continue; - l = (__be32 *) c; + l = (__u32 *) c; /* don't consider the last entry in the packet list, * it is our netnum, and it is not there yet */ for (i = 0; i < IPX_SKB_CB(skb)->ipx_tctrl; i++) @@ -885,8 +885,8 @@ static void ipxitf_insert(struct ipx_interface *intrfc) ipx_primary_net = intrfc; } -static struct ipx_interface *ipxitf_alloc(struct net_device *dev, __be32 netnum, - __be16 dlink_type, +static struct ipx_interface *ipxitf_alloc(struct net_device *dev, __u32 netnum, + unsigned short dlink_type, struct datalink_proto *dlink, unsigned char internal, int ipx_offset) @@ -960,7 +960,7 @@ static __be16 ipx_map_frame_type(unsigned char type) static int ipxitf_create(struct ipx_interface_definition *idef) { struct net_device *dev; - __be16 dlink_type = 0; + unsigned short dlink_type = 0; struct datalink_proto *datalink = NULL; struct ipx_interface *intrfc; int rc; @@ -1073,7 +1073,7 @@ static int ipxitf_create(struct ipx_interface_definition *idef) static int ipxitf_delete(struct ipx_interface_definition *idef) { struct net_device *dev = NULL; - __be16 dlink_type = 0; + unsigned short dlink_type = 0; struct ipx_interface *intrfc; int rc = 0; @@ -1110,7 +1110,7 @@ static int ipxitf_delete(struct ipx_interface_definition *idef) } static struct ipx_interface *ipxitf_auto_create(struct net_device *dev, - __be16 dlink_type) + unsigned short dlink_type) { struct ipx_interface *intrfc = NULL; struct datalink_proto *datalink; @@ -1122,7 +1122,7 @@ static struct ipx_interface *ipxitf_auto_create(struct net_device *dev, if (dev->addr_len > IPX_NODE_LEN) goto out; - switch (ntohs(dlink_type)) { + switch (htons(dlink_type)) { case ETH_P_IPX: datalink = pEII_datalink; break; case ETH_P_802_2: datalink = p8022_datalink; break; case ETH_P_SNAP: datalink = pSNAP_datalink; break; @@ -1234,27 +1234,27 @@ static int ipxitf_ioctl(unsigned int cmd, void __user *arg) /* Note: We assume ipx_tctrl==0 and htons(length)==ipx_pktsize */ /* This functions should *not* mess with packet contents */ -__be16 ipx_cksum(struct ipxhdr *packet, int length) +__u16 ipx_cksum(struct ipxhdr *packet, int length) { /* * NOTE: sum is a net byte order quantity, which optimizes the * loop. This only works on big and little endian machines. (I * don't know of a machine that isn't.) */ - /* handle the first 3 words separately; checksum should be skipped - * and ipx_tctrl masked out */ - __u16 *p = (__u16 *)packet; - __u32 sum = p[1] + (p[2] & (__force u16)htons(0x00ff)); - __u32 i = (length >> 1) - 3; /* Number of remaining complete words */ - - /* Loop through them */ - p += 3; - while (i--) + /* start at ipx_dest - We skip the checksum field and start with + * ipx_type before the loop, not considering ipx_tctrl in the calc */ + __u16 *p = (__u16 *)&packet->ipx_dest; + __u32 i = (length >> 1) - 1; /* Number of complete words */ + __u32 sum = packet->ipx_type << sizeof(packet->ipx_tctrl); + + /* Loop through all complete words except the checksum field, + * ipx_type (accounted above) and ipx_tctrl (not used in the cksum) */ + while (--i) sum += *p++; /* Add on the last part word if it exists */ if (packet->ipx_pktsize & htons(1)) - sum += (__force u16)htons(0xff00) & *p; + sum += ntohs(0xff00) & *p; /* Do final fixup */ sum = (sum & 0xffff) + (sum >> 16); @@ -1263,17 +1263,10 @@ __be16 ipx_cksum(struct ipxhdr *packet, int length) if (sum >= 0x10000) sum++; - /* - * Leave 0 alone; we don't want 0xffff here. Note that we can't get - * here with 0x10000, so this check is the same as ((__u16)sum) - */ - if (sum) - sum = ~sum; - - return (__force __be16)sum; + return ~sum; } -const char *ipx_frame_name(__be16 frame) +const char *ipx_frame_name(unsigned short frame) { char* rc = "None"; @@ -1408,7 +1401,7 @@ static int ipx_release(struct socket *sock) /* caller must hold a reference to intrfc */ -static __be16 ipx_first_free_socketnum(struct ipx_interface *intrfc) +static unsigned short ipx_first_free_socketnum(struct ipx_interface *intrfc) { unsigned short socketNum = intrfc->if_sknum; @@ -1417,7 +1410,7 @@ static __be16 ipx_first_free_socketnum(struct ipx_interface *intrfc) if (socketNum < IPX_MIN_EPHEMERAL_SOCKET) socketNum = IPX_MIN_EPHEMERAL_SOCKET; - while (__ipxitf_find_socket(intrfc, htons(socketNum))) + while (__ipxitf_find_socket(intrfc, ntohs(socketNum))) if (socketNum > IPX_MAX_EPHEMERAL_SOCKET) socketNum = IPX_MIN_EPHEMERAL_SOCKET; else @@ -1426,7 +1419,7 @@ static __be16 ipx_first_free_socketnum(struct ipx_interface *intrfc) spin_unlock_bh(&intrfc->if_sklist_lock); intrfc->if_sknum = socketNum; - return htons(socketNum); + return ntohs(socketNum); } static int ipx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) @@ -1480,7 +1473,7 @@ static int ipx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) ipxs->port)) { SOCK_DEBUG(sk, "IPX: bind failed because port %X in use.\n", - ntohs(addr->sipx_port)); + ntohs((int)addr->sipx_port)); goto out_put; } } else { @@ -1495,7 +1488,7 @@ static int ipx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) if (ipxitf_find_socket(intrfc, addr->sipx_port)) { SOCK_DEBUG(sk, "IPX: bind failed because port %X in use.\n", - ntohs(addr->sipx_port)); + ntohs((int)addr->sipx_port)); goto out_put; } } @@ -1672,7 +1665,7 @@ static int ipx_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_ty intrfc = ipxitf_find_using_phys(dev, pt->type); if (!intrfc) { if (ipxcfg_auto_create_interfaces && - IPX_SKB_CB(skb)->ipx_dest_net) { + ntohl(IPX_SKB_CB(skb)->ipx_dest_net)) { intrfc = ipxitf_auto_create(dev, pt->type); if (intrfc) ipxitf_hold(intrfc); diff --git a/trunk/net/ipx/ipx_proc.c b/trunk/net/ipx/ipx_proc.c index b7463dfca63e..4c0c71206e54 100644 --- a/trunk/net/ipx/ipx_proc.c +++ b/trunk/net/ipx/ipx_proc.c @@ -260,22 +260,22 @@ static int ipx_seq_socket_show(struct seq_file *seq, void *v) ipxs = ipx_sk(s); #ifdef CONFIG_IPX_INTERN seq_printf(seq, "%08lX:%02X%02X%02X%02X%02X%02X:%04X ", - (unsigned long)ntohl(ipxs->intrfc->if_netnum), + (unsigned long)htonl(ipxs->intrfc->if_netnum), ipxs->node[0], ipxs->node[1], ipxs->node[2], ipxs->node[3], - ipxs->node[4], ipxs->node[5], ntohs(ipxs->port)); + ipxs->node[4], ipxs->node[5], htons(ipxs->port)); #else - seq_printf(seq, "%08lX:%04X ", (unsigned long) ntohl(ipxs->intrfc->if_netnum), - ntohs(ipxs->port)); + seq_printf(seq, "%08lX:%04X ", (unsigned long) htonl(ipxs->intrfc->if_netnum), + htons(ipxs->port)); #endif /* CONFIG_IPX_INTERN */ if (s->sk_state != TCP_ESTABLISHED) seq_printf(seq, "%-28s", "Not_Connected"); else { seq_printf(seq, "%08lX:%02X%02X%02X%02X%02X%02X:%04X ", - (unsigned long)ntohl(ipxs->dest_addr.net), + (unsigned long)htonl(ipxs->dest_addr.net), ipxs->dest_addr.node[0], ipxs->dest_addr.node[1], ipxs->dest_addr.node[2], ipxs->dest_addr.node[3], ipxs->dest_addr.node[4], ipxs->dest_addr.node[5], - ntohs(ipxs->dest_addr.sock)); + htons(ipxs->dest_addr.sock)); } seq_printf(seq, "%08X %08X %02X %03d\n", diff --git a/trunk/net/ipx/ipx_route.c b/trunk/net/ipx/ipx_route.c index 68560ee0d797..a30dbb1e08fb 100644 --- a/trunk/net/ipx/ipx_route.c +++ b/trunk/net/ipx/ipx_route.c @@ -19,17 +19,17 @@ DEFINE_RWLOCK(ipx_routes_lock); extern struct ipx_interface *ipx_internal_net; -extern __be16 ipx_cksum(struct ipxhdr *packet, int length); -extern struct ipx_interface *ipxitf_find_using_net(__be32 net); +extern __u16 ipx_cksum(struct ipxhdr *packet, int length); +extern struct ipx_interface *ipxitf_find_using_net(__u32 net); extern int ipxitf_demux_socket(struct ipx_interface *intrfc, struct sk_buff *skb, int copy); extern int ipxitf_demux_socket(struct ipx_interface *intrfc, struct sk_buff *skb, int copy); extern int ipxitf_send(struct ipx_interface *intrfc, struct sk_buff *skb, char *node); -extern struct ipx_interface *ipxitf_find_using_net(__be32 net); +extern struct ipx_interface *ipxitf_find_using_net(__u32 net); -struct ipx_route *ipxrtr_lookup(__be32 net) +struct ipx_route *ipxrtr_lookup(__u32 net) { struct ipx_route *r; @@ -48,7 +48,7 @@ struct ipx_route *ipxrtr_lookup(__be32 net) /* * Caller must hold a reference to intrfc */ -int ipxrtr_add_route(__be32 network, struct ipx_interface *intrfc, +int ipxrtr_add_route(__u32 network, struct ipx_interface *intrfc, unsigned char *node) { struct ipx_route *rt; @@ -118,7 +118,7 @@ static int ipxrtr_create(struct ipx_route_definition *rd) return rc; } -static int ipxrtr_delete(__be32 net) +static int ipxrtr_delete(__u32 net) { struct ipx_route *r, *tmp; int rc; @@ -238,7 +238,7 @@ int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx, /* Apply checksum. Not allowed on 802.3 links. */ if (sk->sk_no_check || intrfc->if_dlink_type == htons(IPX_FRAME_8023)) - ipx->ipx_checksum = htons(0xFFFF); + ipx->ipx_checksum = 0xFFFF; else ipx->ipx_checksum = ipx_cksum(ipx, len + sizeof(struct ipxhdr)); diff --git a/trunk/net/irda/irias_object.c b/trunk/net/irda/irias_object.c index 56292ab7d652..a154b1d71c0f 100644 --- a/trunk/net/irda/irias_object.c +++ b/trunk/net/irda/irias_object.c @@ -43,7 +43,7 @@ struct ias_value irias_missing = { IAS_MISSING, 0, 0, 0, {0}}; * * Faster, check boundary... Jean II */ -static char *strndup(char *str, size_t max) +static char *strndup(char *str, int max) { char *new_str; int len; diff --git a/trunk/net/irda/irlmp.c b/trunk/net/irda/irlmp.c index fede83763095..5073261b9d0c 100644 --- a/trunk/net/irda/irlmp.c +++ b/trunk/net/irda/irlmp.c @@ -1678,8 +1678,7 @@ static int irlmp_slsap_inuse(__u8 slsap_sel) * every IrLAP connection and check every LSAP associated with each * the connection. */ - spin_lock_irqsave_nested(&irlmp->links->hb_spinlock, flags, - SINGLE_DEPTH_NESTING); + spin_lock_irqsave(&irlmp->links->hb_spinlock, flags); lap = (struct lap_cb *) hashbin_get_first(irlmp->links); while (lap != NULL) { IRDA_ASSERT(lap->magic == LMP_LAP_MAGIC, goto errlap;); diff --git a/trunk/net/key/af_key.c b/trunk/net/key/af_key.c index 20ff7cca1d07..ff98e70b0931 100644 --- a/trunk/net/key/af_key.c +++ b/trunk/net/key/af_key.c @@ -2928,6 +2928,11 @@ static struct xfrm_policy *pfkey_compile_policy(struct sock *sk, int opt, if (*dir) goto out; } + else { + *dir = security_xfrm_sock_policy_alloc(xp, sk); + if (*dir) + goto out; + } *dir = pol->sadb_x_policy_dir-1; return xp; diff --git a/trunk/net/netfilter/Kconfig b/trunk/net/netfilter/Kconfig index f619c6527266..ce94732b8e23 100644 --- a/trunk/net/netfilter/Kconfig +++ b/trunk/net/netfilter/Kconfig @@ -209,9 +209,7 @@ config NETFILTER_XT_TARGET_SECMARK config NETFILTER_XT_TARGET_CONNSECMARK tristate '"CONNSECMARK" target support' - depends on NETFILTER_XTABLES && \ - ((NF_CONNTRACK && NF_CONNTRACK_SECMARK) || \ - (IP_NF_CONNTRACK && IP_NF_CONNTRACK_SECMARK)) + depends on NETFILTER_XTABLES && (NF_CONNTRACK_SECMARK || IP_NF_CONNTRACK_SECMARK) help The CONNSECMARK target copies security markings from packets to connections, and restores security markings from connections diff --git a/trunk/net/netfilter/nf_conntrack_core.c b/trunk/net/netfilter/nf_conntrack_core.c index de0567b1f422..093b3ddc513c 100644 --- a/trunk/net/netfilter/nf_conntrack_core.c +++ b/trunk/net/netfilter/nf_conntrack_core.c @@ -469,8 +469,10 @@ __nf_conntrack_expect_find(const struct nf_conntrack_tuple *tuple) struct nf_conntrack_expect *i; list_for_each_entry(i, &nf_conntrack_expect_list, list) { - if (nf_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask)) + if (nf_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask)) { + atomic_inc(&i->use); return i; + } } return NULL; } @@ -483,8 +485,6 @@ nf_conntrack_expect_find(const struct nf_conntrack_tuple *tuple) read_lock_bh(&nf_conntrack_lock); i = __nf_conntrack_expect_find(tuple); - if (i) - atomic_inc(&i->use); read_unlock_bh(&nf_conntrack_lock); return i; @@ -893,6 +893,12 @@ __nf_conntrack_alloc(const struct nf_conntrack_tuple *orig, memset(conntrack, 0, nf_ct_cache[features].size); conntrack->features = features; + if (helper) { + struct nf_conn_help *help = nfct_help(conntrack); + NF_CT_ASSERT(help); + help->helper = helper; + } + atomic_set(&conntrack->ct_general.use, 1); conntrack->ct_general.destroy = destroy_conntrack; conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple = *orig; @@ -976,13 +982,8 @@ init_conntrack(const struct nf_conntrack_tuple *tuple, #endif nf_conntrack_get(&conntrack->master->ct_general); NF_CT_STAT_INC(expect_new); - } else { - struct nf_conn_help *help = nfct_help(conntrack); - - if (help) - help->helper = __nf_ct_helper_find(&repl_tuple); + } else NF_CT_STAT_INC(new); - } /* Overload tuple linked list to put us in unconfirmed list. */ list_add(&conntrack->tuplehash[IP_CT_DIR_ORIGINAL].list, &unconfirmed); @@ -1519,10 +1520,9 @@ get_next_corpse(int (*iter)(struct nf_conn *i, void *data), if (iter(ct, data)) goto found; } - write_unlock_bh(&nf_conntrack_lock); return NULL; found: - atomic_inc(&ct->ct_general.use); + atomic_inc(&nf_ct_tuplehash_to_ctrack(h)->ct_general.use); write_unlock_bh(&nf_conntrack_lock); return ct; } diff --git a/trunk/net/netfilter/nf_conntrack_netlink.c b/trunk/net/netfilter/nf_conntrack_netlink.c index ab67c2be2b5d..1721f7c78c77 100644 --- a/trunk/net/netfilter/nf_conntrack_netlink.c +++ b/trunk/net/netfilter/nf_conntrack_netlink.c @@ -47,6 +47,13 @@ MODULE_LICENSE("GPL"); static char __initdata version[] = "0.93"; +#if 0 +#define DEBUGP printk +#else +#define DEBUGP(format, args...) +#endif + + static inline int ctnetlink_dump_tuples_proto(struct sk_buff *skb, const struct nf_conntrack_tuple *tuple, @@ -161,7 +168,6 @@ ctnetlink_dump_protoinfo(struct sk_buff *skb, const struct nf_conn *ct) return ret; nfattr_failure: - nf_ct_proto_put(proto); return -1; } @@ -404,6 +410,7 @@ static int ctnetlink_done(struct netlink_callback *cb) { if (cb->args[1]) nf_ct_put((struct nf_conn *)cb->args[1]); + DEBUGP("entered %s\n", __FUNCTION__); return 0; } @@ -418,6 +425,9 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb) struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh); u_int8_t l3proto = nfmsg->nfgen_family; + DEBUGP("entered %s, last bucket=%lu id=%u\n", __FUNCTION__, + cb->args[0], *id); + read_lock_bh(&nf_conntrack_lock); last = (struct nf_conn *)cb->args[1]; for (; cb->args[0] < nf_conntrack_htable_size; cb->args[0]++) { @@ -461,6 +471,7 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb) if (last) nf_ct_put(last); + DEBUGP("leaving, last bucket=%lu id=%u\n", cb->args[0], *id); return skb->len; } @@ -471,6 +482,8 @@ ctnetlink_parse_tuple_ip(struct nfattr *attr, struct nf_conntrack_tuple *tuple) struct nf_conntrack_l3proto *l3proto; int ret = 0; + DEBUGP("entered %s\n", __FUNCTION__); + nfattr_parse_nested(tb, CTA_IP_MAX, attr); l3proto = nf_ct_l3proto_find_get(tuple->src.l3num); @@ -480,6 +493,8 @@ ctnetlink_parse_tuple_ip(struct nfattr *attr, struct nf_conntrack_tuple *tuple) nf_ct_l3proto_put(l3proto); + DEBUGP("leaving\n"); + return ret; } @@ -495,6 +510,8 @@ ctnetlink_parse_tuple_proto(struct nfattr *attr, struct nf_conntrack_protocol *proto; int ret = 0; + DEBUGP("entered %s\n", __FUNCTION__); + nfattr_parse_nested(tb, CTA_PROTO_MAX, attr); if (nfattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto)) @@ -521,6 +538,8 @@ ctnetlink_parse_tuple(struct nfattr *cda[], struct nf_conntrack_tuple *tuple, struct nfattr *tb[CTA_TUPLE_MAX]; int err; + DEBUGP("entered %s\n", __FUNCTION__); + memset(tuple, 0, sizeof(*tuple)); nfattr_parse_nested(tb, CTA_TUPLE_MAX, cda[type-1]); @@ -547,6 +566,10 @@ ctnetlink_parse_tuple(struct nfattr *cda[], struct nf_conntrack_tuple *tuple, else tuple->dst.dir = IP_CT_DIR_ORIGINAL; + NF_CT_DUMP_TUPLE(tuple); + + DEBUGP("leaving\n"); + return 0; } @@ -563,6 +586,8 @@ static int ctnetlink_parse_nat_proto(struct nfattr *attr, struct nfattr *tb[CTA_PROTONAT_MAX]; struct ip_nat_protocol *npt; + DEBUGP("entered %s\n", __FUNCTION__); + nfattr_parse_nested(tb, CTA_PROTONAT_MAX, attr); if (nfattr_bad_size(tb, CTA_PROTONAT_MAX, cta_min_protonat)) @@ -581,6 +606,7 @@ static int ctnetlink_parse_nat_proto(struct nfattr *attr, ip_nat_proto_put(npt); + DEBUGP("leaving\n"); return 0; } @@ -596,6 +622,8 @@ ctnetlink_parse_nat(struct nfattr *nat, struct nfattr *tb[CTA_NAT_MAX]; int err; + DEBUGP("entered %s\n", __FUNCTION__); + memset(range, 0, sizeof(*range)); nfattr_parse_nested(tb, CTA_NAT_MAX, nat); @@ -621,6 +649,7 @@ ctnetlink_parse_nat(struct nfattr *nat, if (err < 0) return err; + DEBUGP("leaving\n"); return 0; } #endif @@ -630,6 +659,8 @@ ctnetlink_parse_help(struct nfattr *attr, char **helper_name) { struct nfattr *tb[CTA_HELP_MAX]; + DEBUGP("entered %s\n", __FUNCTION__); + nfattr_parse_nested(tb, CTA_HELP_MAX, attr); if (!tb[CTA_HELP_NAME-1]) @@ -659,6 +690,8 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb, u_int8_t u3 = nfmsg->nfgen_family; int err = 0; + DEBUGP("entered %s\n", __FUNCTION__); + if (nfattr_bad_size(cda, CTA_MAX, cta_min)) return -EINVAL; @@ -676,8 +709,10 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb, return err; h = nf_conntrack_find_get(&tuple, NULL); - if (!h) + if (!h) { + DEBUGP("tuple not found in conntrack hash\n"); return -ENOENT; + } ct = nf_ct_tuplehash_to_ctrack(h); @@ -692,6 +727,7 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb, ct->timeout.function((unsigned long)ct); nf_ct_put(ct); + DEBUGP("leaving\n"); return 0; } @@ -708,6 +744,8 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb, u_int8_t u3 = nfmsg->nfgen_family; int err = 0; + DEBUGP("entered %s\n", __FUNCTION__); + if (nlh->nlmsg_flags & NLM_F_DUMP) { u32 rlen; @@ -741,9 +779,11 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb, return err; h = nf_conntrack_find_get(&tuple, NULL); - if (!h) + if (!h) { + DEBUGP("tuple not found in conntrack hash"); return -ENOENT; - + } + DEBUGP("tuple found\n"); ct = nf_ct_tuplehash_to_ctrack(h); err = -ENOMEM; @@ -764,6 +804,7 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb, if (err < 0) goto out; + DEBUGP("leaving\n"); return 0; free: @@ -835,6 +876,8 @@ ctnetlink_change_helper(struct nf_conn *ct, struct nfattr *cda[]) char *helpname; int err; + DEBUGP("entered %s\n", __FUNCTION__); + if (!help) { /* FIXME: we need to reallocate and rehash */ return -EBUSY; @@ -911,6 +954,8 @@ ctnetlink_change_conntrack(struct nf_conn *ct, struct nfattr *cda[]) { int err; + DEBUGP("entered %s\n", __FUNCTION__); + if (cda[CTA_HELP-1]) { err = ctnetlink_change_helper(ct, cda); if (err < 0) @@ -940,6 +985,7 @@ ctnetlink_change_conntrack(struct nf_conn *ct, struct nfattr *cda[]) ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1])); #endif + DEBUGP("all done\n"); return 0; } @@ -950,7 +996,8 @@ ctnetlink_create_conntrack(struct nfattr *cda[], { struct nf_conn *ct; int err = -EINVAL; - struct nf_conn_help *help; + + DEBUGP("entered %s\n", __FUNCTION__); ct = nf_conntrack_alloc(otuple, rtuple); if (ct == NULL || IS_ERR(ct)) @@ -978,16 +1025,10 @@ ctnetlink_create_conntrack(struct nfattr *cda[], ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1])); #endif - help = nfct_help(ct); - if (help) - help->helper = nf_ct_helper_find_get(rtuple); - add_timer(&ct->timeout); nf_conntrack_hash_insert(ct); - if (help && help->helper) - nf_ct_helper_put(help->helper); - + DEBUGP("conntrack with id %u inserted\n", ct->id); return 0; err: @@ -1005,6 +1046,8 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb, u_int8_t u3 = nfmsg->nfgen_family; int err = 0; + DEBUGP("entered %s\n", __FUNCTION__); + if (nfattr_bad_size(cda, CTA_MAX, cta_min)) return -EINVAL; @@ -1028,6 +1071,7 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb, if (h == NULL) { write_unlock_bh(&nf_conntrack_lock); + DEBUGP("no such conntrack, create new\n"); err = -ENOENT; if (nlh->nlmsg_flags & NLM_F_CREATE) err = ctnetlink_create_conntrack(cda, &otuple, &rtuple); @@ -1043,6 +1087,7 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb, /* We manipulate the conntrack inside the global conntrack table lock, * so there's no need to increase the refcount */ + DEBUGP("conntrack found\n"); err = -EEXIST; if (!(nlh->nlmsg_flags & NLM_F_EXCL)) err = ctnetlink_change_conntrack(nf_ct_tuplehash_to_ctrack(h), cda); @@ -1223,6 +1268,8 @@ ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb) struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh); u_int8_t l3proto = nfmsg->nfgen_family; + DEBUGP("entered %s, last id=%llu\n", __FUNCTION__, *id); + read_lock_bh(&nf_conntrack_lock); list_for_each_prev(i, &nf_conntrack_expect_list) { exp = (struct nf_conntrack_expect *) i; @@ -1240,6 +1287,8 @@ ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb) out: read_unlock_bh(&nf_conntrack_lock); + DEBUGP("leaving, last id=%llu\n", *id); + return skb->len; } @@ -1259,6 +1308,8 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb, u_int8_t u3 = nfmsg->nfgen_family; int err = 0; + DEBUGP("entered %s\n", __FUNCTION__); + if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp)) return -EINVAL; @@ -1409,6 +1460,8 @@ ctnetlink_create_expect(struct nfattr *cda[], u_int8_t u3) struct nf_conn_help *help; int err = 0; + DEBUGP("entered %s\n", __FUNCTION__); + /* caller guarantees that those three CTA_EXPECT_* exist */ err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE, u3); if (err < 0) @@ -1463,6 +1516,8 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb, u_int8_t u3 = nfmsg->nfgen_family; int err = 0; + DEBUGP("entered %s\n", __FUNCTION__); + if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp)) return -EINVAL; @@ -1491,6 +1546,8 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb, err = ctnetlink_change_expect(exp, cda); write_unlock_bh(&nf_conntrack_lock); + DEBUGP("leaving\n"); + return err; } diff --git a/trunk/net/netfilter/nfnetlink_log.c b/trunk/net/netfilter/nfnetlink_log.c index 1e5207b80fe5..b59d3b2bde21 100644 --- a/trunk/net/netfilter/nfnetlink_log.c +++ b/trunk/net/netfilter/nfnetlink_log.c @@ -427,7 +427,7 @@ __build_packet_message(struct nfulnl_instance *inst, nfmsg->version = NFNETLINK_V0; nfmsg->res_id = htons(inst->group_num); - pmsg.hw_protocol = skb->protocol; + pmsg.hw_protocol = htons(skb->protocol); pmsg.hook = hooknum; NFA_PUT(inst->skb, NFULA_PACKET_HDR, sizeof(pmsg), &pmsg); @@ -544,7 +544,7 @@ __build_packet_message(struct nfulnl_instance *inst, } /* global sequence number */ if (inst->flags & NFULNL_CFG_F_SEQ_GLOBAL) { - tmp_uint = htonl(atomic_inc_return(&global_seq)); + tmp_uint = atomic_inc_return(&global_seq); NFA_PUT(inst->skb, NFULA_SEQ_GLOBAL, sizeof(tmp_uint), &tmp_uint); } @@ -878,7 +878,7 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb, params = NFA_DATA(nfula[NFULA_CFG_MODE-1]); nfulnl_set_mode(inst, params->copy_mode, - ntohl(params->copy_range)); + ntohs(params->copy_range)); } if (nfula[NFULA_CFG_TIMEOUT-1]) { @@ -896,8 +896,8 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb, } if (nfula[NFULA_CFG_QTHRESH-1]) { - __be32 qthresh = - *(__be32 *)NFA_DATA(nfula[NFULA_CFG_QTHRESH-1]); + u_int32_t qthresh = + *(u_int16_t *)NFA_DATA(nfula[NFULA_CFG_QTHRESH-1]); nfulnl_set_qthresh(inst, ntohl(qthresh)); } diff --git a/trunk/net/netfilter/nfnetlink_queue.c b/trunk/net/netfilter/nfnetlink_queue.c index e815a9aa6e95..8eb2473d83e1 100644 --- a/trunk/net/netfilter/nfnetlink_queue.c +++ b/trunk/net/netfilter/nfnetlink_queue.c @@ -414,7 +414,7 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue, nfmsg->res_id = htons(queue->queue_num); pmsg.packet_id = htonl(entry->id); - pmsg.hw_protocol = entskb->protocol; + pmsg.hw_protocol = htons(entskb->protocol); pmsg.hook = entinf->hook; NFA_PUT(skb, NFQA_PACKET_HDR, sizeof(pmsg), &pmsg); @@ -622,10 +622,9 @@ nfqnl_mangle(void *data, int data_len, struct nfqnl_queue_entry *e) int diff; diff = data_len - e->skb->len; - if (diff < 0) { - if (pskb_trim(e->skb, data_len)) - return -ENOMEM; - } else if (diff > 0) { + if (diff < 0) + skb_trim(e->skb, data_len); + else if (diff > 0) { if (data_len > 0xFFFF) return -EINVAL; if (diff > skb_tailroom(e->skb)) { diff --git a/trunk/net/netfilter/xt_NFQUEUE.c b/trunk/net/netfilter/xt_NFQUEUE.c index 39e117502bd7..db9b896e57c8 100644 --- a/trunk/net/netfilter/xt_NFQUEUE.c +++ b/trunk/net/netfilter/xt_NFQUEUE.c @@ -68,7 +68,7 @@ static int __init xt_nfqueue_init(void) static void __exit xt_nfqueue_fini(void) { - xt_unregister_targets(xt_nfqueue_target, ARRAY_SIZE(xt_nfqueue_target)); + xt_register_targets(xt_nfqueue_target, ARRAY_SIZE(xt_nfqueue_target)); } module_init(xt_nfqueue_init); diff --git a/trunk/net/netfilter/xt_connmark.c b/trunk/net/netfilter/xt_connmark.c index a8f03057dbde..92a5726ef237 100644 --- a/trunk/net/netfilter/xt_connmark.c +++ b/trunk/net/netfilter/xt_connmark.c @@ -147,7 +147,7 @@ static int __init xt_connmark_init(void) static void __exit xt_connmark_fini(void) { - xt_unregister_matches(xt_connmark_match, ARRAY_SIZE(xt_connmark_match)); + xt_register_matches(xt_connmark_match, ARRAY_SIZE(xt_connmark_match)); } module_init(xt_connmark_init); diff --git a/trunk/net/netlabel/Kconfig b/trunk/net/netlabel/Kconfig index 56958c85f2b4..9f7121ae13e9 100644 --- a/trunk/net/netlabel/Kconfig +++ b/trunk/net/netlabel/Kconfig @@ -4,7 +4,7 @@ config NETLABEL bool "NetLabel subsystem support" - depends on SECURITY + depends on NET && SECURITY default n ---help--- NetLabel provides support for explicit network packet labeling diff --git a/trunk/net/netlabel/netlabel_kapi.c b/trunk/net/netlabel/netlabel_kapi.c index ff971103fd0c..54fb7de3c2b1 100644 --- a/trunk/net/netlabel/netlabel_kapi.c +++ b/trunk/net/netlabel/netlabel_kapi.c @@ -200,7 +200,7 @@ void netlbl_cache_invalidate(void) int netlbl_cache_add(const struct sk_buff *skb, const struct netlbl_lsm_secattr *secattr) { - if (secattr->cache == NULL) + if (secattr->cache.data == NULL) return -ENOMSG; if (CIPSO_V4_OPTEXIST(skb)) diff --git a/trunk/net/netlink/af_netlink.c b/trunk/net/netlink/af_netlink.c index d527c8977b1f..d56e0d21f919 100644 --- a/trunk/net/netlink/af_netlink.c +++ b/trunk/net/netlink/af_netlink.c @@ -1075,9 +1075,8 @@ static int netlink_getsockopt(struct socket *sock, int level, int optname, return -EINVAL; len = sizeof(int); val = nlk->flags & NETLINK_RECV_PKTINFO ? 1 : 0; - if (put_user(len, optlen) || - put_user(val, optval)) - return -EFAULT; + put_user(len, optlen); + put_user(val, optval); err = 0; break; default: diff --git a/trunk/net/sched/sch_htb.c b/trunk/net/sched/sch_htb.c index 4b52fa78935a..bb3ddd4784b1 100644 --- a/trunk/net/sched/sch_htb.c +++ b/trunk/net/sched/sch_htb.c @@ -786,10 +786,11 @@ static long htb_do_events(struct htb_sched *q, int level) for (i = 0; i < 500; i++) { struct htb_class *cl; long diff; - struct rb_node *p = rb_first(&q->wait_pq[level]); - + struct rb_node *p = q->wait_pq[level].rb_node; if (!p) return 0; + while (p->rb_left) + p = p->rb_left; cl = rb_entry(p, struct htb_class, pq_node); if (time_after(cl->pq_key, q->jiffies)) { @@ -1284,7 +1285,8 @@ static void htb_destroy_class(struct Qdisc *sch, struct htb_class *cl) struct htb_class, sibling)); /* note: this delete may happen twice (see htb_delete) */ - hlist_del_init(&cl->hlist); + if (!hlist_unhashed(&cl->hlist)) + hlist_del(&cl->hlist); list_del(&cl->sibling); if (cl->prio_activity) @@ -1332,7 +1334,8 @@ static int htb_delete(struct Qdisc *sch, unsigned long arg) sch_tree_lock(sch); /* delete from hash and active; remainder in destroy_class */ - hlist_del_init(&cl->hlist); + if (!hlist_unhashed(&cl->hlist)) + hlist_del(&cl->hlist); if (cl->prio_activity) htb_deactivate(q, cl); diff --git a/trunk/net/sched/sch_netem.c b/trunk/net/sched/sch_netem.c index 0441876aa1e7..45939bafbdf8 100644 --- a/trunk/net/sched/sch_netem.c +++ b/trunk/net/sched/sch_netem.c @@ -4,7 +4,7 @@ * 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. + * 2 of the License, or (at your option) any later version. * * Many of the algorithms and ideas for this came from * NIST Net which is not copyrighted. @@ -170,8 +170,6 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) return NET_XMIT_BYPASS; } - skb_orphan(skb); - /* * If we need to duplicate packet, then re-insert at top of the * qdisc tree, since parent queuer expects that only one diff --git a/trunk/net/sctp/associola.c b/trunk/net/sctp/associola.c index ed0445fe85e7..27329ce9c311 100644 --- a/trunk/net/sctp/associola.c +++ b/trunk/net/sctp/associola.c @@ -346,18 +346,11 @@ void sctp_association_free(struct sctp_association *asoc) struct list_head *pos, *temp; int i; - /* Only real associations count against the endpoint, so - * don't bother for if this is a temporary association. - */ - if (!asoc->temp) { - list_del(&asoc->asocs); + list_del(&asoc->asocs); - /* Decrement the backlog value for a TCP-style listening - * socket. - */ - if (sctp_style(sk, TCP) && sctp_sstate(sk, LISTENING)) - sk->sk_ack_backlog--; - } + /* Decrement the backlog value for a TCP-style listening socket. */ + if (sctp_style(sk, TCP) && sctp_sstate(sk, LISTENING)) + sk->sk_ack_backlog--; /* Mark as dead, so other users can know this structure is * going away. diff --git a/trunk/net/sctp/endpointola.c b/trunk/net/sctp/endpointola.c index 9b6b394b66f6..35c49ff2d062 100644 --- a/trunk/net/sctp/endpointola.c +++ b/trunk/net/sctp/endpointola.c @@ -144,13 +144,6 @@ void sctp_endpoint_add_asoc(struct sctp_endpoint *ep, { struct sock *sk = ep->base.sk; - /* If this is a temporary association, don't bother - * since we'll be removing it shortly and don't - * want anyone to find it anyway. - */ - if (asoc->temp) - return; - /* Now just add it to our list of asocs */ list_add_tail(&asoc->asocs, &ep->asocs); diff --git a/trunk/net/sctp/input.c b/trunk/net/sctp/input.c index 6d82f400d13c..64f630102532 100644 --- a/trunk/net/sctp/input.c +++ b/trunk/net/sctp/input.c @@ -135,9 +135,6 @@ int sctp_rcv(struct sk_buff *skb) SCTP_INC_STATS_BH(SCTP_MIB_INSCTPPACKS); - if (skb_linearize(skb)) - goto discard_it; - sh = (struct sctphdr *) skb->h.raw; /* Pull up the IP and SCTP headers. */ @@ -771,9 +768,6 @@ static void __sctp_hash_established(struct sctp_association *asoc) /* Add an association to the hash. Local BH-safe. */ void sctp_hash_established(struct sctp_association *asoc) { - if (asoc->temp) - return; - sctp_local_bh_disable(); __sctp_hash_established(asoc); sctp_local_bh_enable(); @@ -807,9 +801,6 @@ static void __sctp_unhash_established(struct sctp_association *asoc) /* Remove association from the hash table. Local BH-safe. */ void sctp_unhash_established(struct sctp_association *asoc) { - if (asoc->temp) - return; - sctp_local_bh_disable(); __sctp_unhash_established(asoc); sctp_local_bh_enable(); diff --git a/trunk/net/sctp/ipv6.c b/trunk/net/sctp/ipv6.c index 78071c6e6cf1..249e5033c1a8 100644 --- a/trunk/net/sctp/ipv6.c +++ b/trunk/net/sctp/ipv6.c @@ -215,17 +215,17 @@ static struct dst_entry *sctp_v6_get_dst(struct sctp_association *asoc, } dst = ip6_route_output(NULL, &fl); - if (!dst->error) { + if (dst) { struct rt6_info *rt; rt = (struct rt6_info *)dst; SCTP_DEBUG_PRINTK( "rt6_dst:" NIP6_FMT " rt6_src:" NIP6_FMT "\n", NIP6(rt->rt6i_dst.addr), NIP6(rt->rt6i_src.addr)); - return dst; + } else { + SCTP_DEBUG_PRINTK("NO ROUTE\n"); } - SCTP_DEBUG_PRINTK("NO ROUTE\n"); - dst_release(dst); - return NULL; + + return dst; } /* Returns the number of consecutive initial bits that match in the 2 ipv6 diff --git a/trunk/net/sctp/proc.c b/trunk/net/sctp/proc.c index 7f49e769080e..a356d8d310a9 100644 --- a/trunk/net/sctp/proc.c +++ b/trunk/net/sctp/proc.c @@ -344,7 +344,7 @@ static int sctp_assocs_seq_show(struct seq_file *seq, void *v) assoc, sk, sctp_sk(sk)->type, sk->sk_state, assoc->state, hash, assoc->assoc_id, assoc->sndbuf_used, - atomic_read(&assoc->rmem_alloc), + (sk->sk_rcvbuf - assoc->rwnd), sock_i_uid(sk), sock_i_ino(sk), epb->bind_addr.port, assoc->peer.port); diff --git a/trunk/net/sctp/protocol.c b/trunk/net/sctp/protocol.c index 5b4f82fd98f8..fac7674438a4 100644 --- a/trunk/net/sctp/protocol.c +++ b/trunk/net/sctp/protocol.c @@ -591,7 +591,7 @@ static struct sock *sctp_v4_create_accept_sk(struct sock *sk, newinet->dport = htons(asoc->peer.port); newinet->daddr = asoc->peer.primary_addr.v4.sin_addr.s_addr; newinet->pmtudisc = inet->pmtudisc; - newinet->id = asoc->next_tsn ^ jiffies; + newinet->id = 0; newinet->uc_ttl = -1; newinet->mc_loop = 1; diff --git a/trunk/net/sctp/socket.c b/trunk/net/sctp/socket.c index 935bc9187fd8..3fe906d65069 100644 --- a/trunk/net/sctp/socket.c +++ b/trunk/net/sctp/socket.c @@ -821,7 +821,7 @@ static int sctp_send_asconf_del_ip(struct sock *sk, * addrs is a pointer to an array of one or more socket addresses. Each * address is contained in its appropriate structure (i.e. struct * sockaddr_in or struct sockaddr_in6) the family of the address type - * must be used to distinguish the address length (note that this + * must be used to distengish the address length (note that this * representation is termed a "packed array" of addresses). The caller * specifies the number of addresses in the array with addrcnt. * @@ -3372,7 +3372,6 @@ SCTP_STATIC int sctp_do_peeloff(struct sctp_association *asoc, { struct sock *sk = asoc->base.sk; struct socket *sock; - struct inet_sock *inetsk; int err = 0; /* An association cannot be branched off from an already peeled-off @@ -3390,14 +3389,6 @@ SCTP_STATIC int sctp_do_peeloff(struct sctp_association *asoc, * asoc to the newsk. */ sctp_sock_migrate(sk, sock->sk, asoc, SCTP_SOCKET_UDP_HIGH_BANDWIDTH); - - /* Make peeled-off sockets more like 1-1 accepted sockets. - * Set the daddr and initialize id to something more random - */ - inetsk = inet_sk(sock->sk); - inetsk->daddr = asoc->peer.primary_addr.v4.sin_addr.s_addr; - inetsk->id = asoc->next_tsn ^ jiffies; - *sockp = sock; return err; @@ -5371,20 +5362,6 @@ static void sctp_wfree(struct sk_buff *skb) sctp_association_put(asoc); } -/* Do accounting for the receive space on the socket. - * Accounting for the association is done in ulpevent.c - * We set this as a destructor for the cloned data skbs so that - * accounting is done at the correct time. - */ -void sctp_sock_rfree(struct sk_buff *skb) -{ - struct sock *sk = skb->sk; - struct sctp_ulpevent *event = sctp_skb2event(skb); - - atomic_sub(event->rmem_len, &sk->sk_rmem_alloc); -} - - /* Helper function to wait for space in the sndbuf. */ static int sctp_wait_for_sndbuf(struct sctp_association *asoc, long *timeo_p, size_t msg_len) @@ -5657,10 +5634,10 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk, sctp_skb_for_each(skb, &oldsk->sk_receive_queue, tmp) { event = sctp_skb2event(skb); if (event->asoc == assoc) { - sctp_sock_rfree(skb); + sock_rfree(skb); __skb_unlink(skb, &oldsk->sk_receive_queue); __skb_queue_tail(&newsk->sk_receive_queue, skb); - sctp_skb_set_owner_r(skb, newsk); + skb_set_owner_r(skb, newsk); } } @@ -5688,10 +5665,10 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk, sctp_skb_for_each(skb, &oldsp->pd_lobby, tmp) { event = sctp_skb2event(skb); if (event->asoc == assoc) { - sctp_sock_rfree(skb); + sock_rfree(skb); __skb_unlink(skb, &oldsp->pd_lobby); __skb_queue_tail(queue, skb); - sctp_skb_set_owner_r(skb, newsk); + skb_set_owner_r(skb, newsk); } } diff --git a/trunk/net/sctp/ulpevent.c b/trunk/net/sctp/ulpevent.c index a015283a9087..ee236784a6bb 100644 --- a/trunk/net/sctp/ulpevent.c +++ b/trunk/net/sctp/ulpevent.c @@ -55,13 +55,10 @@ static void sctp_ulpevent_release_frag_data(struct sctp_ulpevent *event); /* Initialize an ULP event from an given skb. */ -SCTP_STATIC void sctp_ulpevent_init(struct sctp_ulpevent *event, - int msg_flags, - unsigned int len) +SCTP_STATIC void sctp_ulpevent_init(struct sctp_ulpevent *event, int msg_flags) { memset(event, 0, sizeof(struct sctp_ulpevent)); event->msg_flags = msg_flags; - event->rmem_len = len; } /* Create a new sctp_ulpevent. */ @@ -76,7 +73,7 @@ SCTP_STATIC struct sctp_ulpevent *sctp_ulpevent_new(int size, int msg_flags, goto fail; event = sctp_skb2event(skb); - sctp_ulpevent_init(event, msg_flags, skb->truesize); + sctp_ulpevent_init(event, msg_flags); return event; @@ -104,16 +101,17 @@ static inline void sctp_ulpevent_set_owner(struct sctp_ulpevent *event, sctp_association_hold((struct sctp_association *)asoc); skb = sctp_event2skb(event); event->asoc = (struct sctp_association *)asoc; - atomic_add(event->rmem_len, &event->asoc->rmem_alloc); - sctp_skb_set_owner_r(skb, asoc->base.sk); + atomic_add(skb->truesize, &event->asoc->rmem_alloc); + skb_set_owner_r(skb, asoc->base.sk); } /* A simple destructor to give up the reference to the association. */ static inline void sctp_ulpevent_release_owner(struct sctp_ulpevent *event) { struct sctp_association *asoc = event->asoc; + struct sk_buff *skb = sctp_event2skb(event); - atomic_sub(event->rmem_len, &asoc->rmem_alloc); + atomic_sub(skb->truesize, &asoc->rmem_alloc); sctp_association_put(asoc); } @@ -374,7 +372,7 @@ struct sctp_ulpevent *sctp_ulpevent_make_remote_error( /* Embed the event fields inside the cloned skb. */ event = sctp_skb2event(skb); - sctp_ulpevent_init(event, MSG_NOTIFICATION, skb->truesize); + sctp_ulpevent_init(event, MSG_NOTIFICATION); sre = (struct sctp_remote_error *) skb_push(skb, sizeof(struct sctp_remote_error)); @@ -466,7 +464,7 @@ struct sctp_ulpevent *sctp_ulpevent_make_send_failed( /* Embed the event fields inside the cloned skb. */ event = sctp_skb2event(skb); - sctp_ulpevent_init(event, MSG_NOTIFICATION, skb->truesize); + sctp_ulpevent_init(event, MSG_NOTIFICATION); ssf = (struct sctp_send_failed *) skb_push(skb, sizeof(struct sctp_send_failed)); @@ -684,11 +682,8 @@ struct sctp_ulpevent *sctp_ulpevent_make_rcvmsg(struct sctp_association *asoc, /* Embed the event fields inside the cloned skb. */ event = sctp_skb2event(skb); - /* Initialize event with flags 0 and correct length - * Since this is a clone of the original skb, only account for - * the data of this chunk as other chunks will be accounted separately. - */ - sctp_ulpevent_init(event, 0, skb->len + sizeof(struct sk_buff)); + /* Initialize event with flags 0. */ + sctp_ulpevent_init(event, 0); sctp_ulpevent_receive_data(event, asoc); diff --git a/trunk/net/sctp/ulpqueue.c b/trunk/net/sctp/ulpqueue.c index e1d144275f97..575e556aeb3e 100644 --- a/trunk/net/sctp/ulpqueue.c +++ b/trunk/net/sctp/ulpqueue.c @@ -309,7 +309,7 @@ static struct sctp_ulpevent *sctp_make_reassembled_event(struct sk_buff_head *qu if (!new) return NULL; /* try again later */ - sctp_skb_set_owner_r(new, f_frag->sk); + new->sk = f_frag->sk; skb_shinfo(new)->frag_list = pos; } else diff --git a/trunk/net/sunrpc/auth_gss/svcauth_gss.c b/trunk/net/sunrpc/auth_gss/svcauth_gss.c index 1f0f079ffa65..447d9aef4605 100644 --- a/trunk/net/sunrpc/auth_gss/svcauth_gss.c +++ b/trunk/net/sunrpc/auth_gss/svcauth_gss.c @@ -1146,11 +1146,10 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp) return ret; } -static __be32 * +u32 * svcauth_gss_prepare_to_wrap(struct xdr_buf *resbuf, struct gss_svc_data *gsd) { - __be32 *p; - u32 verf_len; + u32 *p, verf_len; p = gsd->verf_start; gsd->verf_start = NULL; diff --git a/trunk/net/sunrpc/pmap_clnt.c b/trunk/net/sunrpc/pmap_clnt.c index e52afab413de..919d5ba7ca0a 100644 --- a/trunk/net/sunrpc/pmap_clnt.c +++ b/trunk/net/sunrpc/pmap_clnt.c @@ -101,13 +101,11 @@ void rpc_getport(struct rpc_task *task) /* Autobind on cloned rpc clients is discouraged */ BUG_ON(clnt->cl_parent != clnt); - /* Put self on queue before sending rpcbind request, in case - * pmap_getport_done completes before we return from rpc_run_task */ - rpc_sleep_on(&xprt->binding, task, NULL, NULL); - - status = -EACCES; /* tell caller to check again */ - if (xprt_test_and_set_binding(xprt)) - goto bailout_nofree; + if (xprt_test_and_set_binding(xprt)) { + task->tk_status = -EACCES; /* tell caller to check again */ + rpc_sleep_on(&xprt->binding, task, NULL, NULL); + return; + } /* Someone else may have bound if we slept */ status = 0; @@ -136,6 +134,8 @@ void rpc_getport(struct rpc_task *task) goto bailout; rpc_release_task(child); + rpc_sleep_on(&xprt->binding, task, NULL, NULL); + task->tk_xprt->stat.bind_count++; return; diff --git a/trunk/net/sunrpc/svc.c b/trunk/net/sunrpc/svc.c index eb44ec929ca1..c2c8bb20d07f 100644 --- a/trunk/net/sunrpc/svc.c +++ b/trunk/net/sunrpc/svc.c @@ -282,10 +282,7 @@ __svc_create(struct svc_program *prog, unsigned int bufsize, int npools, serv->sv_program = prog; serv->sv_nrthreads = 1; serv->sv_stats = prog->pg_stats; - if (bufsize > RPCSVC_MAXPAYLOAD) - bufsize = RPCSVC_MAXPAYLOAD; - serv->sv_max_payload = bufsize? bufsize : 4096; - serv->sv_max_mesg = roundup(serv->sv_max_payload + PAGE_SIZE, PAGE_SIZE); + serv->sv_bufsz = bufsize? bufsize : 4096; serv->sv_shutdown = shutdown; xdrsize = 0; while (prog) { @@ -417,9 +414,9 @@ svc_init_buffer(struct svc_rqst *rqstp, unsigned int size) int pages; int arghi; - pages = size / PAGE_SIZE + 1; /* extra page as we hold both request and reply. - * We assume one is at most one page - */ + if (size > RPCSVC_MAXPAYLOAD) + size = RPCSVC_MAXPAYLOAD; + pages = 2 + (size+ PAGE_SIZE -1) / PAGE_SIZE; arghi = 0; BUG_ON(pages > RPCSVC_MAXPAGES); while (pages) { @@ -466,7 +463,7 @@ __svc_create_thread(svc_thread_fn func, struct svc_serv *serv, if (!(rqstp->rq_argp = kmalloc(serv->sv_xdrsize, GFP_KERNEL)) || !(rqstp->rq_resp = kmalloc(serv->sv_xdrsize, GFP_KERNEL)) - || !svc_init_buffer(rqstp, serv->sv_max_mesg)) + || !svc_init_buffer(rqstp, serv->sv_bufsz)) goto out_thread; serv->sv_nrthreads++; @@ -828,11 +825,6 @@ svc_process(struct svc_rqst *rqstp) *statp = procp->pc_func(rqstp, rqstp->rq_argp, rqstp->rq_resp); /* Encode reply */ - if (*statp == rpc_drop_reply) { - if (procp->pc_release) - procp->pc_release(rqstp, NULL, rqstp->rq_resp); - goto dropit; - } if (*statp == rpc_success && (xdr = procp->pc_encode) && !xdr(rqstp, resv->iov_base+resv->iov_len, rqstp->rq_resp)) { dprintk("svc: failed to encode reply\n"); @@ -946,8 +938,8 @@ u32 svc_max_payload(const struct svc_rqst *rqstp) if (rqstp->rq_sock->sk_sock->type == SOCK_DGRAM) max = RPCSVC_MAXPAYLOAD_UDP; - if (rqstp->rq_server->sv_max_payload < max) - max = rqstp->rq_server->sv_max_payload; + if (rqstp->rq_server->sv_bufsz < max) + max = rqstp->rq_server->sv_bufsz; return max; } EXPORT_SYMBOL_GPL(svc_max_payload); diff --git a/trunk/net/sunrpc/svcauth.c b/trunk/net/sunrpc/svcauth.c index ee9bb1522d5e..8f2320aded5c 100644 --- a/trunk/net/sunrpc/svcauth.c +++ b/trunk/net/sunrpc/svcauth.c @@ -126,7 +126,6 @@ void auth_domain_put(struct auth_domain *dom) if (atomic_dec_and_lock(&dom->ref.refcount, &auth_domain_lock)) { hlist_del(&dom->hash); dom->flavour->domain_release(dom); - spin_unlock(&auth_domain_lock); } } @@ -148,8 +147,10 @@ auth_domain_lookup(char *name, struct auth_domain *new) return hp; } } - if (new) + if (new) { hlist_add_head(&new->hash, head); + kref_get(&new->ref); + } spin_unlock(&auth_domain_lock); return new; } diff --git a/trunk/net/sunrpc/svcsock.c b/trunk/net/sunrpc/svcsock.c index 64ca1f61dd94..b39e7e2b648f 100644 --- a/trunk/net/sunrpc/svcsock.c +++ b/trunk/net/sunrpc/svcsock.c @@ -192,13 +192,13 @@ svc_sock_enqueue(struct svc_sock *svsk) svsk->sk_pool = pool; set_bit(SOCK_NOSPACE, &svsk->sk_sock->flags); - if (((atomic_read(&svsk->sk_reserved) + serv->sv_max_mesg)*2 + if (((atomic_read(&svsk->sk_reserved) + serv->sv_bufsz)*2 > svc_sock_wspace(svsk)) && !test_bit(SK_CLOSE, &svsk->sk_flags) && !test_bit(SK_CONN, &svsk->sk_flags)) { /* Don't enqueue while not enough space for reply */ dprintk("svc: socket %p no space, %d*2 > %ld, not enqueued\n", - svsk->sk_sk, atomic_read(&svsk->sk_reserved)+serv->sv_max_mesg, + svsk->sk_sk, atomic_read(&svsk->sk_reserved)+serv->sv_bufsz, svc_sock_wspace(svsk)); svsk->sk_pool = NULL; clear_bit(SK_BUSY, &svsk->sk_flags); @@ -220,7 +220,7 @@ svc_sock_enqueue(struct svc_sock *svsk) rqstp, rqstp->rq_sock); rqstp->rq_sock = svsk; atomic_inc(&svsk->sk_inuse); - rqstp->rq_reserved = serv->sv_max_mesg; + rqstp->rq_reserved = serv->sv_bufsz; atomic_add(rqstp->rq_reserved, &svsk->sk_reserved); BUG_ON(svsk->sk_pool != pool); wake_up(&rqstp->rq_wait); @@ -299,15 +299,9 @@ void svc_reserve(struct svc_rqst *rqstp, int space) static inline void svc_sock_put(struct svc_sock *svsk) { - if (atomic_dec_and_test(&svsk->sk_inuse) && - test_bit(SK_DEAD, &svsk->sk_flags)) { + if (atomic_dec_and_test(&svsk->sk_inuse) && test_bit(SK_DEAD, &svsk->sk_flags)) { dprintk("svc: releasing dead socket\n"); - if (svsk->sk_sock->file) - sockfd_put(svsk->sk_sock); - else - sock_release(svsk->sk_sock); - if (svsk->sk_info_authunix != NULL) - svcauth_unix_info_release(svsk->sk_info_authunix); + sock_release(svsk->sk_sock); kfree(svsk); } } @@ -645,8 +639,8 @@ svc_udp_recvfrom(struct svc_rqst *rqstp) * which will access the socket. */ svc_sock_setbufsize(svsk->sk_sock, - (serv->sv_nrthreads+3) * serv->sv_max_mesg, - (serv->sv_nrthreads+3) * serv->sv_max_mesg); + (serv->sv_nrthreads+3) * serv->sv_bufsz, + (serv->sv_nrthreads+3) * serv->sv_bufsz); if ((rqstp->rq_deferred = svc_deferred_dequeue(svsk))) { svc_sock_received(svsk); @@ -755,8 +749,8 @@ svc_udp_init(struct svc_sock *svsk) * svc_udp_recvfrom will re-adjust if necessary */ svc_sock_setbufsize(svsk->sk_sock, - 3 * svsk->sk_server->sv_max_mesg, - 3 * svsk->sk_server->sv_max_mesg); + 3 * svsk->sk_server->sv_bufsz, + 3 * svsk->sk_server->sv_bufsz); set_bit(SK_DATA, &svsk->sk_flags); /* might have come in before data_ready set up */ set_bit(SK_CHNGBUF, &svsk->sk_flags); @@ -979,7 +973,7 @@ svc_tcp_recvfrom(struct svc_rqst *rqstp) return 0; } - if (svsk->sk_sk->sk_state == TCP_LISTEN) { + if (test_bit(SK_CONN, &svsk->sk_flags)) { svc_tcp_accept(svsk); svc_sock_received(svsk); return 0; @@ -999,8 +993,8 @@ svc_tcp_recvfrom(struct svc_rqst *rqstp) * as soon a a complete request arrives. */ svc_sock_setbufsize(svsk->sk_sock, - (serv->sv_nrthreads+3) * serv->sv_max_mesg, - 3 * serv->sv_max_mesg); + (serv->sv_nrthreads+3) * serv->sv_bufsz, + 3 * serv->sv_bufsz); clear_bit(SK_DATA, &svsk->sk_flags); @@ -1038,7 +1032,7 @@ svc_tcp_recvfrom(struct svc_rqst *rqstp) } svsk->sk_reclen &= 0x7fffffff; dprintk("svc: TCP record, %d bytes\n", svsk->sk_reclen); - if (svsk->sk_reclen > serv->sv_max_mesg) { + if (svsk->sk_reclen > serv->sv_bufsz) { printk(KERN_NOTICE "RPC: bad TCP reclen 0x%08lx (large)\n", (unsigned long) svsk->sk_reclen); goto err_delete; @@ -1177,8 +1171,8 @@ svc_tcp_init(struct svc_sock *svsk) * svc_tcp_recvfrom will re-adjust if necessary */ svc_sock_setbufsize(svsk->sk_sock, - 3 * svsk->sk_server->sv_max_mesg, - 3 * svsk->sk_server->sv_max_mesg); + 3 * svsk->sk_server->sv_bufsz, + 3 * svsk->sk_server->sv_bufsz); set_bit(SK_CHNGBUF, &svsk->sk_flags); set_bit(SK_DATA, &svsk->sk_flags); @@ -1240,7 +1234,7 @@ svc_recv(struct svc_rqst *rqstp, long timeout) /* now allocate needed pages. If we get a failure, sleep briefly */ - pages = (serv->sv_max_mesg + PAGE_SIZE) / PAGE_SIZE; + pages = 2 + (serv->sv_bufsz + PAGE_SIZE -1) / PAGE_SIZE; for (i=0; i < pages ; i++) while (rqstp->rq_pages[i] == NULL) { struct page *p = alloc_page(GFP_KERNEL); @@ -1269,7 +1263,7 @@ svc_recv(struct svc_rqst *rqstp, long timeout) if ((svsk = svc_sock_dequeue(pool)) != NULL) { rqstp->rq_sock = svsk; atomic_inc(&svsk->sk_inuse); - rqstp->rq_reserved = serv->sv_max_mesg; + rqstp->rq_reserved = serv->sv_bufsz; atomic_add(rqstp->rq_reserved, &svsk->sk_reserved); } else { /* No data pending. Go to sleep */ @@ -1610,13 +1604,20 @@ svc_delete_socket(struct svc_sock *svsk) if (test_bit(SK_TEMP, &svsk->sk_flags)) serv->sv_tmpcnt--; - /* This atomic_inc should be needed - svc_delete_socket - * should have the semantic of dropping a reference. - * But it doesn't yet.... - */ - atomic_inc(&svsk->sk_inuse); - spin_unlock_bh(&serv->sv_lock); - svc_sock_put(svsk); + if (!atomic_read(&svsk->sk_inuse)) { + spin_unlock_bh(&serv->sv_lock); + if (svsk->sk_sock->file) + sockfd_put(svsk->sk_sock); + else + sock_release(svsk->sk_sock); + if (svsk->sk_info_authunix != NULL) + svcauth_unix_info_release(svsk->sk_info_authunix); + kfree(svsk); + } else { + spin_unlock_bh(&serv->sv_lock); + dprintk(KERN_NOTICE "svc: server socket destroy delayed\n"); + /* svsk->sk_server = NULL; */ + } } /* diff --git a/trunk/net/sunrpc/xprtsock.c b/trunk/net/sunrpc/xprtsock.c index 757fc91ef25d..28100e019225 100644 --- a/trunk/net/sunrpc/xprtsock.c +++ b/trunk/net/sunrpc/xprtsock.c @@ -1366,7 +1366,7 @@ int xs_setup_udp(struct rpc_xprt *xprt, struct rpc_timeout *to) if (xprt->slot == NULL) return -ENOMEM; - if (ntohs(addr->sin_port) != 0) + if (ntohs(addr->sin_port != 0)) xprt_set_bound(xprt); xprt->port = xs_get_random_port(); diff --git a/trunk/net/tipc/bearer.c b/trunk/net/tipc/bearer.c index 39744a33bd36..75a5968c2139 100644 --- a/trunk/net/tipc/bearer.c +++ b/trunk/net/tipc/bearer.c @@ -2,7 +2,7 @@ * net/tipc/bearer.c: TIPC bearer code * * Copyright (c) 1996-2006, Ericsson AB - * Copyright (c) 2004-2006, Wind River Systems + * Copyright (c) 2004-2005, Wind River Systems * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -191,14 +191,14 @@ void tipc_media_addr_printf(struct print_buf *pb, struct tipc_media_addr *a) if ((i < media_count) && (m_ptr->addr2str != NULL)) { char addr_str[MAX_ADDR_STR]; - tipc_printf(pb, "%s(%s)", m_ptr->name, + tipc_printf(pb, "%s(%s) ", m_ptr->name, m_ptr->addr2str(a, addr_str, sizeof(addr_str))); } else { unchar *addr = (unchar *)&a->dev_addr; - tipc_printf(pb, "UNKNOWN(%u)", media_type); + tipc_printf(pb, "UNKNOWN(%u):", media_type); for (i = 0; i < (sizeof(*a) - sizeof(a->type)); i++) { - tipc_printf(pb, "-%02x", addr[i]); + tipc_printf(pb, "%02x ", addr[i]); } } } diff --git a/trunk/net/tipc/config.c b/trunk/net/tipc/config.c index ed1351ed05e1..285e1bc2d880 100644 --- a/trunk/net/tipc/config.c +++ b/trunk/net/tipc/config.c @@ -2,7 +2,7 @@ * net/tipc/config.c: TIPC configuration management code * * Copyright (c) 2002-2006, Ericsson AB - * Copyright (c) 2004-2006, Wind River Systems + * Copyright (c) 2004-2005, Wind River Systems * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -613,8 +613,7 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_net_id); break; default: - rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED - " (unknown command)"); + rep_tlv_buf = NULL; break; } diff --git a/trunk/net/tipc/core.c b/trunk/net/tipc/core.c index 6f5b7ee31180..0539a8362858 100644 --- a/trunk/net/tipc/core.c +++ b/trunk/net/tipc/core.c @@ -57,7 +57,7 @@ void tipc_socket_stop(void); int tipc_netlink_start(void); void tipc_netlink_stop(void); -#define TIPC_MOD_VER "1.6.2" +#define TIPC_MOD_VER "1.6.1" #ifndef CONFIG_TIPC_ZONES #define CONFIG_TIPC_ZONES 3 @@ -90,7 +90,7 @@ int tipc_random; atomic_t tipc_user_count = ATOMIC_INIT(0); const char tipc_alphabet[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_."; + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_"; /* configurable TIPC parameters */ diff --git a/trunk/net/tipc/core.h b/trunk/net/tipc/core.h index 4638947c2326..762aac2572be 100644 --- a/trunk/net/tipc/core.h +++ b/trunk/net/tipc/core.h @@ -65,7 +65,7 @@ #define assert(i) BUG_ON(!(i)) struct tipc_msg; -extern struct print_buf *TIPC_NULL, *TIPC_CONS, *TIPC_LOG; +extern struct print_buf *TIPC_CONS, *TIPC_LOG; extern struct print_buf *TIPC_TEE(struct print_buf *, struct print_buf *); void tipc_msg_print(struct print_buf*,struct tipc_msg *,const char*); void tipc_printf(struct print_buf *, const char *fmt, ...); @@ -83,9 +83,9 @@ void tipc_dump(struct print_buf*,const char *fmt, ...); #define warn(fmt, arg...) tipc_printf(TIPC_OUTPUT, KERN_WARNING "TIPC: " fmt, ## arg) #define info(fmt, arg...) tipc_printf(TIPC_OUTPUT, KERN_NOTICE "TIPC: " fmt, ## arg) -#define dbg(fmt, arg...) do {if (DBG_OUTPUT != TIPC_NULL) tipc_printf(DBG_OUTPUT, fmt, ## arg);} while(0) -#define msg_dbg(msg, txt) do {if (DBG_OUTPUT != TIPC_NULL) tipc_msg_print(DBG_OUTPUT, msg, txt);} while(0) -#define dump(fmt, arg...) do {if (DBG_OUTPUT != TIPC_NULL) tipc_dump(DBG_OUTPUT, fmt, ##arg);} while(0) +#define dbg(fmt, arg...) do {if (DBG_OUTPUT) tipc_printf(DBG_OUTPUT, fmt, ## arg);} while(0) +#define msg_dbg(msg, txt) do {if (DBG_OUTPUT) tipc_msg_print(DBG_OUTPUT, msg, txt);} while(0) +#define dump(fmt, arg...) do {if (DBG_OUTPUT) tipc_dump(DBG_OUTPUT, fmt, ##arg);} while(0) /* @@ -94,11 +94,11 @@ void tipc_dump(struct print_buf*,const char *fmt, ...); * here, or on a per .c file basis, by redefining these symbols. The following * print buffer options are available: * - * TIPC_NULL : null buffer (i.e. print nowhere) - * TIPC_CONS : system console - * TIPC_LOG : TIPC log buffer - * &buf : user-defined buffer (struct print_buf *) - * TIPC_TEE(&buf_a,&buf_b) : list of buffers (eg. TIPC_TEE(TIPC_CONS,TIPC_LOG)) + * NULL : Output to null print buffer (i.e. print nowhere) + * TIPC_CONS : Output to system console + * TIPC_LOG : Output to TIPC log buffer + * &buf : Output to user-defined buffer (struct print_buf *) + * TIPC_TEE(&buf_a,&buf_b) : Output to two print buffers (eg. TIPC_TEE(TIPC_CONS,TIPC_LOG) ) */ #ifndef TIPC_OUTPUT @@ -106,7 +106,7 @@ void tipc_dump(struct print_buf*,const char *fmt, ...); #endif #ifndef DBG_OUTPUT -#define DBG_OUTPUT TIPC_NULL +#define DBG_OUTPUT NULL #endif #else @@ -136,7 +136,7 @@ void tipc_dump(struct print_buf*,const char *fmt, ...); #define TIPC_OUTPUT TIPC_CONS #undef DBG_OUTPUT -#define DBG_OUTPUT TIPC_NULL +#define DBG_OUTPUT NULL #endif @@ -275,15 +275,11 @@ static inline void k_term_timer(struct timer_list *timer) /* * TIPC message buffer code * - * TIPC message buffer headroom reserves space for a link-level header - * (in case the message is sent off-node), + * TIPC message buffer headroom leaves room for 14 byte Ethernet header, * while ensuring TIPC header is word aligned for quicker access - * - * The largest header currently supported is 18 bytes, which is used when - * the standard 14 byte Ethernet header has 4 added bytes for VLAN info */ -#define BUF_HEADROOM 20u +#define BUF_HEADROOM 16u struct tipc_skb_cb { void *handle; diff --git a/trunk/net/tipc/dbg.c b/trunk/net/tipc/dbg.c index d8af4c28695d..55130655e1ed 100644 --- a/trunk/net/tipc/dbg.c +++ b/trunk/net/tipc/dbg.c @@ -1,8 +1,8 @@ /* - * net/tipc/dbg.c: TIPC print buffer routines for debugging + * net/tipc/dbg.c: TIPC print buffer routines for debuggign * * Copyright (c) 1996-2006, Ericsson AB - * Copyright (c) 2005-2006, Wind River Systems + * Copyright (c) 2005, Wind River Systems * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -38,11 +38,10 @@ #include "config.h" #include "dbg.h" -static char print_string[TIPC_PB_MAX_STR]; -static DEFINE_SPINLOCK(print_lock); +#define MAX_STRING 512 -static struct print_buf null_buf = { NULL, 0, NULL, NULL }; -struct print_buf *TIPC_NULL = &null_buf; +static char print_string[MAX_STRING]; +static DEFINE_SPINLOCK(print_lock); static struct print_buf cons_buf = { NULL, 0, NULL, NULL }; struct print_buf *TIPC_CONS = &cons_buf; @@ -63,83 +62,68 @@ struct print_buf *TIPC_LOG = &log_buf; /* * Locking policy when using print buffers. * - * The following routines use 'print_lock' for protection: - * 1) tipc_printf() - to protect its print buffer(s) and 'print_string' - * 2) TIPC_TEE() - to protect its print buffer(s) - * 3) tipc_dump() - to protect its print buffer(s) and 'print_string' - * 4) tipc_log_XXX() - to protect TIPC_LOG - * - * All routines of the form tipc_printbuf_XXX() rely on the caller to prevent - * simultaneous use of the print buffer(s) being manipulated. + * 1) Routines of the form printbuf_XXX() rely on the caller to prevent + * simultaneous use of the print buffer(s) being manipulated. + * 2) tipc_printf() uses 'print_lock' to prevent simultaneous use of + * 'print_string' and to protect its print buffer(s). + * 3) TIPC_TEE() uses 'print_lock' to protect its print buffer(s). + * 4) Routines of the form log_XXX() uses 'print_lock' to protect TIPC_LOG. */ /** * tipc_printbuf_init - initialize print buffer to empty - * @pb: pointer to print buffer structure - * @raw: pointer to character array used by print buffer - * @size: size of character array - * - * Makes the print buffer a null device that discards anything written to it - * if the character array is too small (or absent). */ -void tipc_printbuf_init(struct print_buf *pb, char *raw, u32 size) +void tipc_printbuf_init(struct print_buf *pb, char *raw, u32 sz) { - pb->buf = raw; - pb->crs = raw; - pb->size = size; - pb->next = NULL; + if (!pb || !raw || (sz < (MAX_STRING + 1))) + return; - if (size < TIPC_PB_MIN_SIZE) { - pb->buf = NULL; - } else if (raw) { - pb->buf[0] = 0; - pb->buf[size-1] = ~0; - } + pb->crs = pb->buf = raw; + pb->size = sz; + pb->next = NULL; + pb->buf[0] = 0; + pb->buf[sz-1] = ~0; } /** * tipc_printbuf_reset - reinitialize print buffer to empty state - * @pb: pointer to print buffer structure */ void tipc_printbuf_reset(struct print_buf *pb) { - tipc_printbuf_init(pb, pb->buf, pb->size); + if (pb && pb->buf) + tipc_printbuf_init(pb, pb->buf, pb->size); } /** * tipc_printbuf_empty - test if print buffer is in empty state - * @pb: pointer to print buffer structure - * - * Returns non-zero if print buffer is empty. */ int tipc_printbuf_empty(struct print_buf *pb) { - return (!pb->buf || (pb->crs == pb->buf)); + return (!pb || !pb->buf || (pb->crs == pb->buf)); } /** * tipc_printbuf_validate - check for print buffer overflow - * @pb: pointer to print buffer structure * * Verifies that a print buffer has captured all data written to it. * If data has been lost, linearize buffer and prepend an error message * - * Returns length of print buffer data string (including trailing NUL) + * Returns length of print buffer data string (including trailing NULL) */ int tipc_printbuf_validate(struct print_buf *pb) { - char *err = "\n\n*** PRINT BUFFER OVERFLOW ***\n\n"; + char *err = " *** PRINT BUFFER WRAPPED AROUND ***\n"; char *cp_buf; struct print_buf cb; - if (!pb->buf) + if (!pb || !pb->buf) return 0; - if (pb->buf[pb->size - 1] == 0) { + if (pb->buf[pb->size - 1] == '\0') { cp_buf = kmalloc(pb->size, GFP_ATOMIC); if (cp_buf != NULL){ tipc_printbuf_init(&cb, cp_buf, pb->size); @@ -157,8 +141,6 @@ int tipc_printbuf_validate(struct print_buf *pb) /** * tipc_printbuf_move - move print buffer contents to another print buffer - * @pb_to: pointer to destination print buffer structure - * @pb_from: pointer to source print buffer structure * * Current contents of destination print buffer (if any) are discarded. * Source print buffer becomes empty if a successful move occurs. @@ -170,22 +152,21 @@ void tipc_printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from) /* Handle the cases where contents can't be moved */ - if (!pb_to->buf) + if (!pb_to || !pb_to->buf) return; - if (!pb_from->buf) { + if (!pb_from || !pb_from->buf) { tipc_printbuf_reset(pb_to); return; } if (pb_to->size < pb_from->size) { tipc_printbuf_reset(pb_to); - tipc_printf(pb_to, "*** PRINT BUFFER MOVE ERROR ***"); + tipc_printf(pb_to, "*** PRINT BUFFER OVERFLOW ***"); return; } /* Copy data from char after cursor to end (if used) */ - len = pb_from->buf + pb_from->size - pb_from->crs - 2; if ((pb_from->buf[pb_from->size-1] == 0) && (len > 0)) { strcpy(pb_to->buf, pb_from->crs + 1); @@ -194,7 +175,6 @@ void tipc_printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from) pb_to->crs = pb_to->buf; /* Copy data from start to cursor (always) */ - len = pb_from->crs - pb_from->buf; strcpy(pb_to->crs, pb_from->buf); pb_to->crs += len; @@ -204,8 +184,6 @@ void tipc_printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from) /** * tipc_printf - append formatted output to print buffer chain - * @pb: pointer to chain of print buffers (may be NULL) - * @fmt: formatted info to be printed */ void tipc_printf(struct print_buf *pb, const char *fmt, ...) @@ -217,8 +195,8 @@ void tipc_printf(struct print_buf *pb, const char *fmt, ...) spin_lock_bh(&print_lock); FORMAT(print_string, chars_to_add, fmt); - if (chars_to_add >= TIPC_PB_MAX_STR) - strcpy(print_string, "*** PRINT BUFFER STRING TOO LONG ***"); + if (chars_to_add >= MAX_STRING) + strcpy(print_string, "*** STRING TOO LONG ***"); while (pb) { if (pb == TIPC_CONS) @@ -228,10 +206,6 @@ void tipc_printf(struct print_buf *pb, const char *fmt, ...) if (chars_to_add <= chars_left) { strcpy(pb->crs, print_string); pb->crs += chars_to_add; - } else if (chars_to_add >= (pb->size - 1)) { - strcpy(pb->buf, print_string + chars_to_add + 1 - - pb->size); - pb->crs = pb->buf + pb->size - 1; } else { strcpy(pb->buf, print_string + chars_left); save_char = print_string[chars_left]; @@ -250,10 +224,6 @@ void tipc_printf(struct print_buf *pb, const char *fmt, ...) /** * TIPC_TEE - perform next output operation on both print buffers - * @b0: pointer to chain of print buffers (may be NULL) - * @b1: pointer to print buffer to add to chain - * - * Returns pointer to print buffer chain. */ struct print_buf *TIPC_TEE(struct print_buf *b0, struct print_buf *b1) @@ -262,6 +232,8 @@ struct print_buf *TIPC_TEE(struct print_buf *b0, struct print_buf *b1) if (!b0 || (b0 == b1)) return b1; + if (!b1) + return b0; spin_lock_bh(&print_lock); while (pb->next) { @@ -284,7 +256,7 @@ static void print_to_console(char *crs, int len) int rest = len; while (rest > 0) { - int sz = rest < TIPC_PB_MAX_STR ? rest : TIPC_PB_MAX_STR; + int sz = rest < MAX_STRING ? rest : MAX_STRING; char c = crs[sz]; crs[sz] = 0; @@ -303,48 +275,36 @@ static void printbuf_dump(struct print_buf *pb) { int len; - if (!pb->buf) { - printk("*** PRINT BUFFER NOT ALLOCATED ***"); - return; - } - /* Dump print buffer from char after cursor to end (if used) */ - len = pb->buf + pb->size - pb->crs - 2; if ((pb->buf[pb->size - 1] == 0) && (len > 0)) print_to_console(pb->crs + 1, len); /* Dump print buffer from start to cursor (always) */ - len = pb->crs - pb->buf; print_to_console(pb->buf, len); } /** * tipc_dump - dump non-console print buffer(s) to console - * @pb: pointer to chain of print buffers */ void tipc_dump(struct print_buf *pb, const char *fmt, ...) { - struct print_buf *pb_next; int len; spin_lock_bh(&print_lock); - FORMAT(print_string, len, fmt); - printk(print_string); + FORMAT(TIPC_CONS->buf, len, fmt); + printk(TIPC_CONS->buf); for (; pb; pb = pb->next) { - if (pb != TIPC_CONS) { - printk("\n---- Start of %s log dump ----\n\n", - (pb == TIPC_LOG) ? "global" : "local"); - printbuf_dump(pb); - tipc_printbuf_reset(pb); - printk("\n---- End of dump ----\n"); - } - pb_next = pb->next; - pb->next = NULL; - pb = pb_next; + if (pb == TIPC_CONS) + continue; + printk("\n---- Start of dump,%s log ----\n\n", + (pb == TIPC_LOG) ? "global" : "local"); + printbuf_dump(pb); + tipc_printbuf_reset(pb); + printk("\n-------- End of dump --------\n"); } spin_unlock_bh(&print_lock); } @@ -364,8 +324,7 @@ void tipc_log_stop(void) } /** - * tipc_log_reinit - (re)initialize TIPC log print buffer - * @log_size: print buffer size to use + * tipc_log_reinit - set TIPC log print buffer to specified size */ void tipc_log_reinit(int log_size) @@ -373,11 +332,10 @@ void tipc_log_reinit(int log_size) tipc_log_stop(); if (log_size) { - if (log_size < TIPC_PB_MIN_SIZE) - log_size = TIPC_PB_MIN_SIZE; + if (log_size <= MAX_STRING) + log_size = MAX_STRING + 1; spin_lock_bh(&print_lock); - tipc_printbuf_init(TIPC_LOG, kmalloc(log_size, GFP_ATOMIC), - log_size); + tipc_printbuf_init(TIPC_LOG, kmalloc(log_size, GFP_ATOMIC), log_size); spin_unlock_bh(&print_lock); } } diff --git a/trunk/net/tipc/dbg.h b/trunk/net/tipc/dbg.h index 467c0bc78a79..227f050d2a52 100644 --- a/trunk/net/tipc/dbg.h +++ b/trunk/net/tipc/dbg.h @@ -2,7 +2,7 @@ * net/tipc/dbg.h: Include file for TIPC print buffer routines * * Copyright (c) 1997-2006, Ericsson AB - * Copyright (c) 2005-2006, Wind River Systems + * Copyright (c) 2005, Wind River Systems * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -37,14 +37,6 @@ #ifndef _TIPC_DBG_H #define _TIPC_DBG_H -/** - * struct print_buf - TIPC print buffer structure - * @buf: pointer to character array containing print buffer contents - * @size: size of character array - * @crs: pointer to first unused space in character array (i.e. final NUL) - * @next: used to link print buffers when printing to more than one at a time - */ - struct print_buf { char *buf; u32 size; @@ -52,10 +44,7 @@ struct print_buf { struct print_buf *next; }; -#define TIPC_PB_MIN_SIZE 64 /* minimum size for a print buffer's array */ -#define TIPC_PB_MAX_STR 512 /* max printable string (with trailing NUL) */ - -void tipc_printbuf_init(struct print_buf *pb, char *buf, u32 size); +void tipc_printbuf_init(struct print_buf *pb, char *buf, u32 sz); void tipc_printbuf_reset(struct print_buf *pb); int tipc_printbuf_empty(struct print_buf *pb); int tipc_printbuf_validate(struct print_buf *pb); diff --git a/trunk/net/tipc/discover.c b/trunk/net/tipc/discover.c index 3b0cd12f37da..ee94de92ae99 100644 --- a/trunk/net/tipc/discover.c +++ b/trunk/net/tipc/discover.c @@ -131,28 +131,6 @@ static struct sk_buff *tipc_disc_init_msg(u32 type, return buf; } -/** - * disc_dupl_alert - issue node address duplication alert - * @b_ptr: pointer to bearer detecting duplication - * @node_addr: duplicated node address - * @media_addr: media address advertised by duplicated node - */ - -static void disc_dupl_alert(struct bearer *b_ptr, u32 node_addr, - struct tipc_media_addr *media_addr) -{ - char node_addr_str[16]; - char media_addr_str[64]; - struct print_buf pb; - - addr_string_fill(node_addr_str, node_addr); - tipc_printbuf_init(&pb, media_addr_str, sizeof(media_addr_str)); - tipc_media_addr_printf(&pb, media_addr); - tipc_printbuf_validate(&pb); - warn("Duplicate %s using %s seen on <%s>\n", - node_addr_str, media_addr_str, b_ptr->publ.name); -} - /** * tipc_disc_recv_msg - handle incoming link setup message (request or response) * @buf: buffer containing message @@ -179,11 +157,8 @@ void tipc_disc_recv_msg(struct sk_buff *buf) return; if (!tipc_addr_node_valid(orig)) return; - if (orig == tipc_own_addr) { - if (memcmp(&media_addr, &b_ptr->publ.addr, sizeof(media_addr))) - disc_dupl_alert(b_ptr, tipc_own_addr, &media_addr); + if (orig == tipc_own_addr) return; - } if (!in_scope(dest, tipc_own_addr)) return; if (is_slave(tipc_own_addr) && is_slave(orig)) @@ -195,8 +170,7 @@ void tipc_disc_recv_msg(struct sk_buff *buf) struct sk_buff *rbuf; struct tipc_media_addr *addr; struct node *n_ptr = tipc_node_find(orig); - int link_fully_up; - + int link_up; dbg(" in own cluster\n"); if (n_ptr == NULL) { n_ptr = tipc_node_create(orig); @@ -216,19 +190,14 @@ void tipc_disc_recv_msg(struct sk_buff *buf) } addr = &link->media_addr; if (memcmp(addr, &media_addr, sizeof(*addr))) { - if (tipc_link_is_up(link) || (!link->started)) { - disc_dupl_alert(b_ptr, orig, &media_addr); - spin_unlock_bh(&n_ptr->lock); - return; - } warn("Resetting link <%s>, peer interface address changed\n", link->name); memcpy(addr, &media_addr, sizeof(*addr)); tipc_link_reset(link); } - link_fully_up = (link->state == WORKING_WORKING); + link_up = tipc_link_is_up(link); spin_unlock_bh(&n_ptr->lock); - if ((type == DSC_RESP_MSG) || link_fully_up) + if ((type == DSC_RESP_MSG) || link_up) return; rbuf = tipc_disc_init_msg(DSC_RESP_MSG, 1, orig, b_ptr); if (rbuf != NULL) { diff --git a/trunk/net/tipc/link.c b/trunk/net/tipc/link.c index 1bb983c8130b..53bc8cb5adbc 100644 --- a/trunk/net/tipc/link.c +++ b/trunk/net/tipc/link.c @@ -132,7 +132,7 @@ static void link_print(struct link *l_ptr, struct print_buf *buf, * allow the output from multiple links to be intermixed. For this reason * routines of the form "dbg_link_XXX()" have been created that will capture * debug info into a link's personal print buffer, which can then be dumped - * into the TIPC system log (TIPC_LOG) upon request. + * into the TIPC system log (LOG) upon request. * * To enable per-link debugging, use LINK_LOG_BUF_SIZE to specify the size * of the print buffer used by each link. If LINK_LOG_BUF_SIZE is set to 0, @@ -141,7 +141,7 @@ static void link_print(struct link *l_ptr, struct print_buf *buf, * when there is only a single link in the system being debugged. * * Notes: - * - When enabled, LINK_LOG_BUF_SIZE should be set to at least TIPC_PB_MIN_SIZE + * - When enabled, LINK_LOG_BUF_SIZE should be set to at least 1000 (bytes) * - "l_ptr" must be valid when using dbg_link_XXX() macros */ @@ -159,13 +159,13 @@ static void link_print(struct link *l_ptr, struct print_buf *buf, static void dbg_print_link(struct link *l_ptr, const char *str) { - if (DBG_OUTPUT != TIPC_NULL) + if (DBG_OUTPUT) link_print(l_ptr, DBG_OUTPUT, str); } static void dbg_print_buf_chain(struct sk_buff *root_buf) { - if (DBG_OUTPUT != TIPC_NULL) { + if (DBG_OUTPUT) { struct sk_buff *buf = root_buf; while (buf) { diff --git a/trunk/net/tipc/name_distr.c b/trunk/net/tipc/name_distr.c index 03bd659c43ca..f0b063bcc2a9 100644 --- a/trunk/net/tipc/name_distr.c +++ b/trunk/net/tipc/name_distr.c @@ -122,7 +122,7 @@ void tipc_named_publish(struct publication *publ) struct sk_buff *buf; struct distr_item *item; - list_add_tail(&publ->local_list, &publ_root); + list_add(&publ->local_list, &publ_root); publ_cnt++; buf = named_prepare_buf(PUBLICATION, ITEM_SIZE, 0); diff --git a/trunk/net/tipc/node.c b/trunk/net/tipc/node.c index 886bda5e88db..fc6d09630ccd 100644 --- a/trunk/net/tipc/node.c +++ b/trunk/net/tipc/node.c @@ -648,7 +648,7 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space) return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE " (network address)"); - if (tipc_mode != TIPC_NET_MODE) + if (!tipc_nodes) return tipc_cfg_reply_none(); /* Get space for all unicast links + multicast link */ diff --git a/trunk/net/tipc/port.c b/trunk/net/tipc/port.c index b7f3199523ca..b9c8c6b9e94f 100644 --- a/trunk/net/tipc/port.c +++ b/trunk/net/tipc/port.c @@ -505,13 +505,8 @@ static void port_timeout(unsigned long ref) struct port *p_ptr = tipc_port_lock(ref); struct sk_buff *buf = NULL; - if (!p_ptr) - return; - - if (!p_ptr->publ.connected) { - tipc_port_unlock(p_ptr); + if (!p_ptr || !p_ptr->publ.connected) return; - } /* Last probe answered ? */ if (p_ptr->probing_state == PROBING) { @@ -1136,12 +1131,11 @@ int tipc_publish(u32 ref, unsigned int scope, struct tipc_name_seq const *seq) int res = -EINVAL; p_ptr = tipc_port_lock(ref); - if (!p_ptr) - return -EINVAL; - dbg("tipc_publ %u, p_ptr = %x, conn = %x, scope = %x, " "lower = %u, upper = %u\n", ref, p_ptr, p_ptr->publ.connected, scope, seq->lower, seq->upper); + if (!p_ptr) + return -EINVAL; if (p_ptr->publ.connected) goto exit; if (seq->lower > seq->upper) diff --git a/trunk/net/tipc/socket.c b/trunk/net/tipc/socket.c index 2a6a5a6b4c12..32d778448a00 100644 --- a/trunk/net/tipc/socket.c +++ b/trunk/net/tipc/socket.c @@ -2,7 +2,7 @@ * net/tipc/socket.c: TIPC socket API * * Copyright (c) 2001-2006, Ericsson AB - * Copyright (c) 2004-2006, Wind River Systems + * Copyright (c) 2004-2005, Wind River Systems * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -629,9 +629,6 @@ static int send_stream(struct kiocb *iocb, struct socket *sock, return -ENOTCONN; } - if (unlikely(m->msg_name)) - return -EISCONN; - /* * Send each iovec entry using one or more messages * @@ -644,8 +641,6 @@ static int send_stream(struct kiocb *iocb, struct socket *sock, curr_iovlen = m->msg_iovlen; my_msg.msg_iov = &my_iov; my_msg.msg_iovlen = 1; - my_msg.msg_flags = m->msg_flags; - my_msg.msg_name = NULL; bytes_sent = 0; while (curr_iovlen--) { @@ -946,7 +941,7 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock, int sz_to_copy; int sz_copied = 0; int needed; - char __user *crs = m->msg_iov->iov_base; + char *crs = m->msg_iov->iov_base; unsigned char *buf_crs; u32 err; int res; @@ -1208,8 +1203,7 @@ static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf) atomic_inc(&tipc_queue_size); skb_queue_tail(&sock->sk->sk_receive_queue, buf); - if (waitqueue_active(sock->sk->sk_sleep)) - wake_up_interruptible(sock->sk->sk_sleep); + wake_up_interruptible(sock->sk->sk_sleep); return TIPC_OK; } @@ -1224,8 +1218,7 @@ static void wakeupdispatch(struct tipc_port *tport) { struct tipc_sock *tsock = (struct tipc_sock *)tport->usr_handle; - if (waitqueue_active(tsock->sk.sk_sleep)) - wake_up_interruptible(tsock->sk.sk_sleep); + wake_up_interruptible(tsock->sk.sk_sleep); } /** @@ -1503,7 +1496,7 @@ static int setsockopt(struct socket *sock, return -ENOPROTOOPT; if (ol < sizeof(value)) return -EINVAL; - if ((res = get_user(value, (u32 __user *)ov))) + if ((res = get_user(value, (u32 *)ov))) return res; if (down_interruptible(&tsock->sem)) @@ -1548,7 +1541,7 @@ static int setsockopt(struct socket *sock, */ static int getsockopt(struct socket *sock, - int lvl, int opt, char __user *ov, int __user *ol) + int lvl, int opt, char __user *ov, int *ol) { struct tipc_sock *tsock = tipc_sk(sock->sk); int len; diff --git a/trunk/net/tipc/subscr.c b/trunk/net/tipc/subscr.c index 7a918f12a5df..c51600ba5f4a 100644 --- a/trunk/net/tipc/subscr.c +++ b/trunk/net/tipc/subscr.c @@ -155,7 +155,7 @@ void tipc_subscr_report_overlap(struct subscription *sub, sub->seq.upper, found_lower, found_upper); if (!tipc_subscr_overlap(sub, found_lower, found_upper)) return; - if (!must && !(sub->filter & TIPC_SUB_PORTS)) + if (!must && (sub->filter != TIPC_SUB_PORTS)) return; subscr_send_event(sub, found_lower, found_upper, event, port_ref, node); } @@ -176,13 +176,6 @@ static void subscr_timeout(struct subscription *sub) if (subscriber == NULL) return; - /* Validate timeout (in case subscription is being cancelled) */ - - if (sub->timeout == TIPC_WAIT_FOREVER) { - tipc_ref_unlock(subscriber_ref); - return; - } - /* Unlink subscription from name table */ tipc_nametbl_unsubscribe(sub); @@ -205,20 +198,6 @@ static void subscr_timeout(struct subscription *sub) atomic_dec(&topsrv.subscription_count); } -/** - * subscr_del - delete a subscription within a subscription list - * - * Called with subscriber locked. - */ - -static void subscr_del(struct subscription *sub) -{ - tipc_nametbl_unsubscribe(sub); - list_del(&sub->subscription_list); - kfree(sub); - atomic_dec(&topsrv.subscription_count); -} - /** * subscr_terminate - terminate communication with a subscriber * @@ -248,9 +227,12 @@ static void subscr_terminate(struct subscriber *subscriber) k_cancel_timer(&sub->timer); k_term_timer(&sub->timer); } - dbg("Term: Removing sub %u,%u,%u from subscriber %x list\n", + tipc_nametbl_unsubscribe(sub); + list_del(&sub->subscription_list); + dbg("Term: Removed sub %u,%u,%u from subscriber %x list\n", sub->seq.type, sub->seq.lower, sub->seq.upper, subscriber); - subscr_del(sub); + kfree(sub); + atomic_dec(&topsrv.subscription_count); } /* Sever connection to subscriber */ @@ -270,49 +252,6 @@ static void subscr_terminate(struct subscriber *subscriber) kfree(subscriber); } -/** - * subscr_cancel - handle subscription cancellation request - * - * Called with subscriber locked. Routine must temporarily release this lock - * to enable the subscription timeout routine to finish without deadlocking; - * the lock is then reclaimed to allow caller to release it upon return. - * - * Note that fields of 's' use subscriber's endianness! - */ - -static void subscr_cancel(struct tipc_subscr *s, - struct subscriber *subscriber) -{ - struct subscription *sub; - struct subscription *sub_temp; - int found = 0; - - /* Find first matching subscription, exit if not found */ - - list_for_each_entry_safe(sub, sub_temp, &subscriber->subscription_list, - subscription_list) { - if (!memcmp(s, &sub->evt.s, sizeof(struct tipc_subscr))) { - found = 1; - break; - } - } - if (!found) - return; - - /* Cancel subscription timer (if used), then delete subscription */ - - if (sub->timeout != TIPC_WAIT_FOREVER) { - sub->timeout = TIPC_WAIT_FOREVER; - spin_unlock_bh(subscriber->lock); - k_cancel_timer(&sub->timer); - k_term_timer(&sub->timer); - spin_lock_bh(subscriber->lock); - } - dbg("Cancel: removing sub %u,%u,%u from subscriber %x list\n", - sub->seq.type, sub->seq.lower, sub->seq.upper, subscriber); - subscr_del(sub); -} - /** * subscr_subscribe - create subscription for subscriber * @@ -324,21 +263,6 @@ static void subscr_subscribe(struct tipc_subscr *s, { struct subscription *sub; - /* Determine/update subscriber's endianness */ - - if (s->filter & (TIPC_SUB_PORTS | TIPC_SUB_SERVICE)) - subscriber->swap = 0; - else - subscriber->swap = 1; - - /* Detect & process a subscription cancellation request */ - - if (s->filter & htohl(TIPC_SUB_CANCEL, subscriber->swap)) { - s->filter &= ~htohl(TIPC_SUB_CANCEL, subscriber->swap); - subscr_cancel(s, subscriber); - return; - } - /* Refuse subscription if global limit exceeded */ if (atomic_read(&topsrv.subscription_count) >= tipc_max_subscriptions) { @@ -357,6 +281,13 @@ static void subscr_subscribe(struct tipc_subscr *s, return; } + /* Determine/update subscriber's endianness */ + + if ((s->filter == TIPC_SUB_PORTS) || (s->filter == TIPC_SUB_SERVICE)) + subscriber->swap = 0; + else + subscriber->swap = 1; + /* Initialize subscription object */ memset(sub, 0, sizeof(*sub)); @@ -365,8 +296,8 @@ static void subscr_subscribe(struct tipc_subscr *s, sub->seq.upper = htohl(s->seq.upper, subscriber->swap); sub->timeout = htohl(s->timeout, subscriber->swap); sub->filter = htohl(s->filter, subscriber->swap); - if ((!(sub->filter & TIPC_SUB_PORTS) - == !(sub->filter & TIPC_SUB_SERVICE)) + if ((((sub->filter != TIPC_SUB_PORTS) + && (sub->filter != TIPC_SUB_SERVICE))) || (sub->seq.lower > sub->seq.upper)) { warn("Subscription rejected, illegal request\n"); kfree(sub); diff --git a/trunk/net/wanrouter/af_wanpipe.c b/trunk/net/wanrouter/af_wanpipe.c index c2059733e15a..6f39faa15832 100644 --- a/trunk/net/wanrouter/af_wanpipe.c +++ b/trunk/net/wanrouter/af_wanpipe.c @@ -13,7 +13,7 @@ * Due Credit: * Wanpipe socket layer is based on Packet and * the X25 socket layers. The above sockets were -* used for the specific use of Sangoma Technologies +* used for the specific use of Sangoma Technoloiges * API programs. * Packet socket Authors: Ross Biro, Fred N. van Kempen and * Alan Cox. @@ -23,7 +23,7 @@ * Apr 25, 2000 Nenad Corbic o Added the ability to send zero length packets. * Mar 13, 2000 Nenad Corbic o Added a tx buffer check via ioctl call. * Mar 06, 2000 Nenad Corbic o Fixed the corrupt sock lcn problem. -* Server and client application can run +* Server and client applicaton can run * simultaneously without conflicts. * Feb 29, 2000 Nenad Corbic o Added support for PVC protocols, such as * CHDLC, Frame Relay and HDLC API. diff --git a/trunk/net/wanrouter/wanmain.c b/trunk/net/wanrouter/wanmain.c index 316211d9f17d..9479659277ae 100644 --- a/trunk/net/wanrouter/wanmain.c +++ b/trunk/net/wanrouter/wanmain.c @@ -3,7 +3,7 @@ * * This module is completely hardware-independent and provides * the following common services for the WAN Link Drivers: -* o WAN device management (registering, unregistering) +* o WAN device managenment (registering, unregistering) * o Network interface management * o Physical connection management (dial-up, incoming calls) * o Logical connection management (switched virtual circuits) diff --git a/trunk/net/xfrm/xfrm_policy.c b/trunk/net/xfrm/xfrm_policy.c index 7736b23c3f03..2a7861661f14 100644 --- a/trunk/net/xfrm/xfrm_policy.c +++ b/trunk/net/xfrm/xfrm_policy.c @@ -883,32 +883,30 @@ int xfrm_policy_walk(u8 type, int (*func)(struct xfrm_policy *, int, int, void*) } EXPORT_SYMBOL(xfrm_policy_walk); -/* - * Find policy to apply to this flow. - * - * Returns 0 if policy found, else an -errno. - */ +/* Find policy to apply to this flow. */ + static int xfrm_policy_match(struct xfrm_policy *pol, struct flowi *fl, u8 type, u16 family, int dir) { struct xfrm_selector *sel = &pol->selector; - int match, ret = -ESRCH; + int match; if (pol->family != family || pol->type != type) - return ret; + return 0; match = xfrm_selector_match(sel, fl, family); - if (match) - ret = security_xfrm_policy_lookup(pol, fl->secid, dir); + if (match) { + if (!security_xfrm_policy_lookup(pol, fl->secid, dir)) + return 1; + } - return ret; + return 0; } static struct xfrm_policy *xfrm_policy_lookup_bytype(u8 type, struct flowi *fl, u16 family, u8 dir) { - int err; struct xfrm_policy *pol, *ret; xfrm_address_t *daddr, *saddr; struct hlist_node *entry; @@ -924,15 +922,7 @@ static struct xfrm_policy *xfrm_policy_lookup_bytype(u8 type, struct flowi *fl, chain = policy_hash_direct(daddr, saddr, family, dir); ret = NULL; hlist_for_each_entry(pol, entry, chain, bydst) { - err = xfrm_policy_match(pol, fl, type, family, dir); - if (err) { - if (err == -ESRCH) - continue; - else { - ret = ERR_PTR(err); - goto fail; - } - } else { + if (xfrm_policy_match(pol, fl, type, family, dir)) { ret = pol; priority = ret->priority; break; @@ -940,53 +930,36 @@ static struct xfrm_policy *xfrm_policy_lookup_bytype(u8 type, struct flowi *fl, } chain = &xfrm_policy_inexact[dir]; hlist_for_each_entry(pol, entry, chain, bydst) { - err = xfrm_policy_match(pol, fl, type, family, dir); - if (err) { - if (err == -ESRCH) - continue; - else { - ret = ERR_PTR(err); - goto fail; - } - } else if (pol->priority < priority) { + if (xfrm_policy_match(pol, fl, type, family, dir) && + pol->priority < priority) { ret = pol; break; } } if (ret) xfrm_pol_hold(ret); -fail: read_unlock_bh(&xfrm_policy_lock); return ret; } -static int xfrm_policy_lookup(struct flowi *fl, u16 family, u8 dir, +static void xfrm_policy_lookup(struct flowi *fl, u16 family, u8 dir, void **objp, atomic_t **obj_refp) { struct xfrm_policy *pol; - int err = 0; #ifdef CONFIG_XFRM_SUB_POLICY pol = xfrm_policy_lookup_bytype(XFRM_POLICY_TYPE_SUB, fl, family, dir); - if (IS_ERR(pol)) { - err = PTR_ERR(pol); - pol = NULL; - } - if (pol || err) + if (pol) goto end; #endif pol = xfrm_policy_lookup_bytype(XFRM_POLICY_TYPE_MAIN, fl, family, dir); - if (IS_ERR(pol)) { - err = PTR_ERR(pol); - pol = NULL; - } + #ifdef CONFIG_XFRM_SUB_POLICY end: #endif if ((*objp = (void *) pol) != NULL) *obj_refp = &pol->refcnt; - return err; } static inline int policy_to_flow_dir(int dir) @@ -1016,16 +989,12 @@ static struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir, struc sk->sk_family); int err = 0; - if (match) { - err = security_xfrm_policy_lookup(pol, fl->secid, - policy_to_flow_dir(dir)); - if (!err) - xfrm_pol_hold(pol); - else if (err == -ESRCH) - pol = NULL; - else - pol = ERR_PTR(err); - } else + if (match) + err = security_xfrm_policy_lookup(pol, fl->secid, policy_to_flow_dir(dir)); + + if (match && !err) + xfrm_pol_hold(pol); + else pol = NULL; } read_unlock_bh(&xfrm_policy_lock); @@ -1317,11 +1286,8 @@ int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl, pol_dead = 0; xfrm_nr = 0; - if (sk && sk->sk_policy[1]) { + if (sk && sk->sk_policy[1]) policy = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl); - if (IS_ERR(policy)) - return PTR_ERR(policy); - } if (!policy) { /* To accelerate a bit... */ @@ -1331,8 +1297,6 @@ int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl, policy = flow_cache_lookup(fl, dst_orig->ops->family, dir, xfrm_policy_lookup); - if (IS_ERR(policy)) - return PTR_ERR(policy); } if (!policy) @@ -1379,10 +1343,6 @@ int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl, fl, family, XFRM_POLICY_OUT); if (pols[1]) { - if (IS_ERR(pols[1])) { - err = PTR_ERR(pols[1]); - goto error; - } if (pols[1]->action == XFRM_POLICY_BLOCK) { err = -EPERM; goto error; @@ -1614,19 +1574,13 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, } pol = NULL; - if (sk && sk->sk_policy[dir]) { + if (sk && sk->sk_policy[dir]) pol = xfrm_sk_policy_lookup(sk, dir, &fl); - if (IS_ERR(pol)) - return 0; - } if (!pol) pol = flow_cache_lookup(&fl, family, fl_dir, xfrm_policy_lookup); - if (IS_ERR(pol)) - return 0; - if (!pol) { if (skb->sp && secpath_has_nontransport(skb->sp, 0, &xerr_idx)) { xfrm_secpath_reject(xerr_idx, skb, &fl); @@ -1645,8 +1599,6 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, &fl, family, XFRM_POLICY_IN); if (pols[1]) { - if (IS_ERR(pols[1])) - return 0; pols[1]->curlft.use_time = (unsigned long)xtime.tv_sec; npols ++; } @@ -1754,7 +1706,7 @@ static struct dst_entry *xfrm_dst_check(struct dst_entry *dst, u32 cookie) static int stale_bundle(struct dst_entry *dst) { - return !xfrm_bundle_ok(NULL, (struct xfrm_dst *)dst, NULL, AF_UNSPEC, 0); + return !xfrm_bundle_ok((struct xfrm_dst *)dst, NULL, AF_UNSPEC, 0); } void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev) @@ -1876,8 +1828,7 @@ EXPORT_SYMBOL(xfrm_init_pmtu); * still valid. */ -int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *first, - struct flowi *fl, int family, int strict) +int xfrm_bundle_ok(struct xfrm_dst *first, struct flowi *fl, int family, int strict) { struct dst_entry *dst = &first->u.dst; struct xfrm_dst *last; @@ -1894,7 +1845,7 @@ int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *first, if (fl && !xfrm_selector_match(&dst->xfrm->sel, fl, family)) return 0; - if (fl && !security_xfrm_flow_state_match(fl, dst->xfrm, pol)) + if (fl && !security_xfrm_flow_state_match(fl, dst->xfrm)) return 0; if (dst->xfrm->km.state != XFRM_STATE_VALID) return 0; diff --git a/trunk/net/xfrm/xfrm_state.c b/trunk/net/xfrm/xfrm_state.c index 899de9ed22a6..39b8bf3a9ded 100644 --- a/trunk/net/xfrm/xfrm_state.c +++ b/trunk/net/xfrm/xfrm_state.c @@ -505,14 +505,6 @@ __xfrm_state_locate(struct xfrm_state *x, int use_spi, int family) x->id.proto, family); } -static void xfrm_hash_grow_check(int have_hash_collision) -{ - if (have_hash_collision && - (xfrm_state_hmask + 1) < xfrm_state_hashmax && - xfrm_state_num > xfrm_state_hmask) - schedule_work(&xfrm_hash_work); -} - struct xfrm_state * xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, struct flowi *fl, struct xfrm_tmpl *tmpl, @@ -606,8 +598,6 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, x->lft.hard_add_expires_seconds = XFRM_ACQ_EXPIRES; x->timer.expires = jiffies + XFRM_ACQ_EXPIRES*HZ; add_timer(&x->timer); - xfrm_state_num++; - xfrm_hash_grow_check(x->bydst.next != NULL); } else { x->km.state = XFRM_STATE_DEAD; xfrm_state_put(x); @@ -652,7 +642,10 @@ static void __xfrm_state_insert(struct xfrm_state *x) xfrm_state_num++; - xfrm_hash_grow_check(x->bydst.next != NULL); + if (x->bydst.next != NULL && + (xfrm_state_hmask + 1) < xfrm_state_hashmax && + xfrm_state_num > xfrm_state_hmask) + schedule_work(&xfrm_hash_work); } /* xfrm_state_lock is held */ @@ -760,10 +753,6 @@ static struct xfrm_state *__find_acq_core(unsigned short family, u8 mode, u32 re h = xfrm_src_hash(daddr, saddr, family); hlist_add_head(&x->bysrc, xfrm_state_bysrc+h); wake_up(&km_waitq); - - xfrm_state_num++; - - xfrm_hash_grow_check(x->bydst.next != NULL); } return x; diff --git a/trunk/net/xfrm/xfrm_user.c b/trunk/net/xfrm/xfrm_user.c index 2ee14f8a1908..d54b3a70d5df 100644 --- a/trunk/net/xfrm/xfrm_user.c +++ b/trunk/net/xfrm/xfrm_user.c @@ -323,7 +323,7 @@ static void copy_from_user_state(struct xfrm_state *x, struct xfrm_usersa_info * x->props.replay_window = p->replay_window; x->props.reqid = p->reqid; x->props.family = p->family; - memcpy(&x->props.saddr, &p->saddr, sizeof(x->props.saddr)); + x->props.saddr = p->saddr; x->props.flags = p->flags; } @@ -495,7 +495,6 @@ static struct xfrm_state *xfrm_user_state_lookup(struct xfrm_usersa_id *p, goto out; } - err = -ESRCH; x = xfrm_state_lookup_byaddr(&p->daddr, saddr, p->proto, p->family); } @@ -546,7 +545,7 @@ static void copy_to_user_state(struct xfrm_state *x, struct xfrm_usersa_info *p) memcpy(&p->lft, &x->lft, sizeof(p->lft)); memcpy(&p->curlft, &x->curlft, sizeof(p->curlft)); memcpy(&p->stats, &x->stats, sizeof(p->stats)); - memcpy(&p->saddr, &x->props.saddr, sizeof(p->saddr)); + p->saddr = x->props.saddr; p->mode = x->props.mode; p->replay_window = x->props.replay_window; p->reqid = x->props.reqid; @@ -1928,9 +1927,6 @@ static int xfrm_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *xt, len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr); len += NLMSG_SPACE(sizeof(struct xfrm_user_acquire)); len += RTA_SPACE(xfrm_user_sec_ctx_size(xp)); -#ifdef CONFIG_XFRM_SUB_POLICY - len += RTA_SPACE(sizeof(struct xfrm_userpolicy_type)); -#endif skb = alloc_skb(len, GFP_ATOMIC); if (skb == NULL) return -ENOMEM; @@ -1996,6 +1992,15 @@ static struct xfrm_policy *xfrm_compile_policy(struct sock *sk, int opt, xp->type = XFRM_POLICY_TYPE_MAIN; copy_templates(xp, ut, nr); + if (!xp->security) { + int err = security_xfrm_sock_policy_alloc(xp, sk); + if (err) { + kfree(xp); + *dir = err; + return NULL; + } + } + *dir = p->dir; return xp; @@ -2038,9 +2043,6 @@ static int xfrm_exp_policy_notify(struct xfrm_policy *xp, int dir, struct km_eve len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr); len += NLMSG_SPACE(sizeof(struct xfrm_user_polexpire)); len += RTA_SPACE(xfrm_user_sec_ctx_size(xp)); -#ifdef CONFIG_XFRM_SUB_POLICY - len += RTA_SPACE(sizeof(struct xfrm_userpolicy_type)); -#endif skb = alloc_skb(len, GFP_ATOMIC); if (skb == NULL) return -ENOMEM; @@ -2067,9 +2069,6 @@ static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, struct km_event * len += RTA_SPACE(headlen); headlen = sizeof(*id); } -#ifdef CONFIG_XFRM_SUB_POLICY - len += RTA_SPACE(sizeof(struct xfrm_userpolicy_type)); -#endif len += NLMSG_SPACE(headlen); skb = alloc_skb(len, GFP_ATOMIC); @@ -2116,12 +2115,10 @@ static int xfrm_notify_policy_flush(struct km_event *c) struct nlmsghdr *nlh; struct sk_buff *skb; unsigned char *b; - int len = 0; #ifdef CONFIG_XFRM_SUB_POLICY struct xfrm_userpolicy_type upt; - len += RTA_SPACE(sizeof(struct xfrm_userpolicy_type)); #endif - len += NLMSG_LENGTH(0); + int len = NLMSG_LENGTH(0); skb = alloc_skb(len, GFP_ATOMIC); if (skb == NULL) diff --git a/trunk/scripts/Makefile.headersinst b/trunk/scripts/Makefile.headersinst index 4241e0dfeeaf..6a026f69b563 100644 --- a/trunk/scripts/Makefile.headersinst +++ b/trunk/scripts/Makefile.headersinst @@ -168,7 +168,7 @@ $(objhdr-y) $(header-y) $(unifdef-y): $(KBUILDFILES) $(call cmd,gen) else -$(objhdr-y) : $(INSTALL_HDR_PATH)/$(_dst)/%.h: $(objtree)/$(obj)/%.h $(KBUILDFILES) +$(objhdr-y) : $(INSTALL_HDR_PATH)/$(_dst)/%.h: $(srctree)/$(obj)/%.h $(KBUILDFILES) $(call cmd,o_hdr_install) $(header-y) : $(INSTALL_HDR_PATH)/$(_dst)/%.h: $(srctree)/$(obj)/%.h $(KBUILDFILES) diff --git a/trunk/scripts/Makefile.modpost b/trunk/scripts/Makefile.modpost index 65e0a79c36cf..6c5469b1473b 100644 --- a/trunk/scripts/Makefile.modpost +++ b/trunk/scripts/Makefile.modpost @@ -44,7 +44,7 @@ include scripts/Kbuild.include include scripts/Makefile.lib kernelsymfile := $(objtree)/Module.symvers -modulesymfile := $(firstword $(KBUILD_EXTMOD))/Module.symvers +modulesymfile := $(KBUILD_EXTMOD)/Module.symvers # Step 1), find all modules listed in $(MODVERDIR)/ __modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod))) diff --git a/trunk/scripts/basic/docproc.c b/trunk/scripts/basic/docproc.c index d6071cbf13d7..4ab6cbf09225 100644 --- a/trunk/scripts/basic/docproc.c +++ b/trunk/scripts/basic/docproc.c @@ -250,7 +250,7 @@ void intfunc(char * filename) { docfunctions(filename, NOFUNCTION); } void extfunc(char * filename) { docfunctions(filename, FUNCTION); } /* - * Document specific function(s) in a file. + * Document spåecific function(s) in a file. * Call kernel-doc with the following parameters: * kernel-doc -docbook -function function1 [-function function2] */ diff --git a/trunk/scripts/gen_initramfs_list.sh b/trunk/scripts/gen_initramfs_list.sh index 4c723fd18648..331c079f029b 100644 --- a/trunk/scripts/gen_initramfs_list.sh +++ b/trunk/scripts/gen_initramfs_list.sh @@ -158,7 +158,7 @@ unknown_option() { } list_header() { - : + echo "deps_initramfs := \\" } header() { @@ -227,7 +227,6 @@ arg="$1" case "$arg" in "-l") # files included in initramfs - used by kbuild dep_list="list_" - echo "deps_initramfs := \\" shift ;; "-o") # generate gzipped cpio image named $1 diff --git a/trunk/scripts/kconfig/.gitignore b/trunk/scripts/kconfig/.gitignore index b49584c932cc..e8ad1f6b3da4 100644 --- a/trunk/scripts/kconfig/.gitignore +++ b/trunk/scripts/kconfig/.gitignore @@ -6,8 +6,6 @@ lex.*.c *.tab.c *.tab.h zconf.hash.c -*.moc -lkc_defs.h # # configuration programs diff --git a/trunk/scripts/kconfig/lxdialog/dialog.h b/trunk/scripts/kconfig/lxdialog/dialog.h index fd695e1070f7..8dea47f9d3e4 100644 --- a/trunk/scripts/kconfig/lxdialog/dialog.h +++ b/trunk/scripts/kconfig/lxdialog/dialog.h @@ -24,7 +24,6 @@ #include #include #include -#include #ifdef __sun__ #define CURS_MACROS diff --git a/trunk/scripts/kconfig/lxdialog/util.c b/trunk/scripts/kconfig/lxdialog/util.c index d54440fc166c..ebc781b493d7 100644 --- a/trunk/scripts/kconfig/lxdialog/util.c +++ b/trunk/scripts/kconfig/lxdialog/util.c @@ -221,14 +221,16 @@ static void init_dialog_colors(void) */ static void color_setup(const char *theme) { - int use_color; - - use_color = set_theme(theme); - if (use_color && has_colors()) { - start_color(); - init_dialog_colors(); - } else + if (set_theme(theme)) { + if (has_colors()) { /* Terminal supports color? */ + start_color(); + init_dialog_colors(); + } + } + else + { set_mono_theme(); + } } /* diff --git a/trunk/scripts/kconfig/qconf.cc b/trunk/scripts/kconfig/qconf.cc index 338bdea96541..393f3749f330 100644 --- a/trunk/scripts/kconfig/qconf.cc +++ b/trunk/scripts/kconfig/qconf.cc @@ -1259,7 +1259,6 @@ void ConfigSearchWindow::search(void) * Construct the complete config widget */ ConfigMainWindow::ConfigMainWindow(void) - : searchWindow(0) { QMenuBar* menu; bool ok; diff --git a/trunk/scripts/kernel-doc b/trunk/scripts/kernel-doc index 187f5de4612c..00d1ad19b2cc 100755 --- a/trunk/scripts/kernel-doc +++ b/trunk/scripts/kernel-doc @@ -1262,9 +1262,7 @@ sub output_intro_text(%) { } ## -# generic output function for all types (function, struct/union, typedef, enum); -# calls the generated, variable output_ function name based on -# functype and output_mode +# generic output function for typedefs sub output_declaration { no strict 'refs'; my $name = shift; @@ -1280,7 +1278,8 @@ sub output_declaration { } ## -# generic output function - calls the right one based on current output mode. +# generic output function - calls the right one based +# on current output mode. sub output_intro { no strict 'refs'; my $func = "output_intro_".$output_mode; @@ -1519,9 +1518,6 @@ sub dump_function($$) { $prototype =~ s/^asmlinkage +//; $prototype =~ s/^inline +//; $prototype =~ s/^__inline__ +//; - $prototype =~ s/^__inline +//; - $prototype =~ s/^__always_inline +//; - $prototype =~ s/^noinline +//; $prototype =~ s/__devinit +//; $prototype =~ s/^#define +//; #ak added $prototype =~ s/__attribute__ \(\([a-z,]*\)\)//; @@ -1782,9 +1778,8 @@ sub process_file($) { $in_doc_sect = 1; $contents = $newcontents; if ($contents ne "") { - while ((substr($contents, 0, 1) eq " ") || - substr($contents, 0, 1) eq "\t") { - $contents = substr($contents, 1); + if (substr($contents, 0, 1) eq " ") { + $contents = substr($contents, 1); } $contents .= "\n"; } diff --git a/trunk/scripts/mod/modpost.c b/trunk/scripts/mod/modpost.c index 2e1141623147..41277963f47a 100644 --- a/trunk/scripts/mod/modpost.c +++ b/trunk/scripts/mod/modpost.c @@ -921,8 +921,6 @@ static int init_section_ref_ok(const char *name) ".fixup", ".smp_locks", ".plt", /* seen on ARCH=um build on x86_64. Harmless */ - "__ftr_fixup", /* powerpc cpu feature fixup */ - "__fw_ftr_fixup", /* powerpc firmware feature fixup */ NULL }; /* Start of section names */ diff --git a/trunk/security/dummy.c b/trunk/security/dummy.c index 43874c1e6e23..aeee70565509 100644 --- a/trunk/security/dummy.c +++ b/trunk/security/dummy.c @@ -881,8 +881,7 @@ static int dummy_xfrm_state_pol_flow_match(struct xfrm_state *x, return 1; } -static int dummy_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm, - struct xfrm_policy *xp) +static int dummy_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm) { return 1; } diff --git a/trunk/security/selinux/avc.c b/trunk/security/selinux/avc.c index 74c0319c417e..a300702da527 100644 --- a/trunk/security/selinux/avc.c +++ b/trunk/security/selinux/avc.c @@ -32,7 +32,12 @@ #include "avc.h" #include "avc_ss.h" -static const struct av_perm_to_string av_perm_to_string[] = { +static const struct av_perm_to_string +{ + u16 tclass; + u32 value; + const char *name; +} av_perm_to_string[] = { #define S_(c, v, s) { c, v, s }, #include "av_perm_to_string.h" #undef S_ @@ -52,21 +57,17 @@ static const char *class_to_string[] = { #undef TE_ #undef S_ -static const struct av_inherit av_inherit[] = { +static const struct av_inherit +{ + u16 tclass; + const char **common_pts; + u32 common_base; +} av_inherit[] = { #define S_(c, i, b) { c, common_##i##_perm_to_string, b }, #include "av_inherit.h" #undef S_ }; -const struct selinux_class_perm selinux_class_perm = { - av_perm_to_string, - ARRAY_SIZE(av_perm_to_string), - class_to_string, - ARRAY_SIZE(class_to_string), - av_inherit, - ARRAY_SIZE(av_inherit) -}; - #define AVC_CACHE_SLOTS 512 #define AVC_DEF_CACHE_THRESHOLD 512 #define AVC_CACHE_RECLAIM 16 diff --git a/trunk/security/selinux/hooks.c b/trunk/security/selinux/hooks.c index 28ee187ed224..e9969a2fc846 100644 --- a/trunk/security/selinux/hooks.c +++ b/trunk/security/selinux/hooks.c @@ -1754,8 +1754,7 @@ static inline void flush_unauthorized_files(struct files_struct * files) get_file(devnull); } else { devnull = dentry_open(dget(selinux_null), mntget(selinuxfs_mount), O_RDWR); - if (IS_ERR(devnull)) { - devnull = NULL; + if (!devnull) { put_unused_fd(fd); fput(file); continue; @@ -3314,13 +3313,7 @@ static int selinux_socket_getpeername(struct socket *sock) static int selinux_socket_setsockopt(struct socket *sock,int level,int optname) { - int err; - - err = socket_has_perm(current, sock, SOCKET__SETOPT); - if (err) - return err; - - return selinux_netlbl_socket_setsockopt(sock, level, optname); + return socket_has_perm(current, sock, SOCKET__SETOPT); } static int selinux_socket_getsockopt(struct socket *sock, int level, diff --git a/trunk/security/selinux/include/avc_ss.h b/trunk/security/selinux/include/avc_ss.h index ff869e8b6f4a..450a2831e2e3 100644 --- a/trunk/security/selinux/include/avc_ss.h +++ b/trunk/security/selinux/include/avc_ss.h @@ -10,29 +10,5 @@ int avc_ss_reset(u32 seqno); -struct av_perm_to_string -{ - u16 tclass; - u32 value; - const char *name; -}; - -struct av_inherit -{ - u16 tclass; - const char **common_pts; - u32 common_base; -}; - -struct selinux_class_perm -{ - const struct av_perm_to_string *av_perm_to_string; - u32 av_pts_len; - const char **class_to_string; - u32 cts_len; - const struct av_inherit *av_inherit; - u32 av_inherit_len; -}; - #endif /* _SELINUX_AVC_SS_H_ */ diff --git a/trunk/security/selinux/include/selinux_netlabel.h b/trunk/security/selinux/include/selinux_netlabel.h index 9de10cc2cef2..ecab4bddaaf4 100644 --- a/trunk/security/selinux/include/selinux_netlabel.h +++ b/trunk/security/selinux/include/selinux_netlabel.h @@ -53,9 +53,6 @@ void selinux_netlbl_sk_security_init(struct sk_security_struct *ssec, void selinux_netlbl_sk_clone_security(struct sk_security_struct *ssec, struct sk_security_struct *newssec); int selinux_netlbl_inode_permission(struct inode *inode, int mask); -int selinux_netlbl_socket_setsockopt(struct socket *sock, - int level, - int optname); #else static inline void selinux_netlbl_cache_invalidate(void) { @@ -117,13 +114,6 @@ static inline int selinux_netlbl_inode_permission(struct inode *inode, { return 0; } - -static inline int selinux_netlbl_socket_setsockopt(struct socket *sock, - int level, - int optname) -{ - return 0; -} #endif /* CONFIG_NETLABEL */ #endif diff --git a/trunk/security/selinux/include/xfrm.h b/trunk/security/selinux/include/xfrm.h index 526b28019aca..81eb59890162 100644 --- a/trunk/security/selinux/include/xfrm.h +++ b/trunk/security/selinux/include/xfrm.h @@ -19,8 +19,7 @@ int selinux_xfrm_state_delete(struct xfrm_state *x); int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir); int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, struct xfrm_policy *xp, struct flowi *fl); -int selinux_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm, - struct xfrm_policy *xp); +int selinux_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm); /* diff --git a/trunk/security/selinux/ss/ebitmap.c b/trunk/security/selinux/ss/ebitmap.c index d539346ab3a2..cfed1d30fa6a 100644 --- a/trunk/security/selinux/ss/ebitmap.c +++ b/trunk/security/selinux/ss/ebitmap.c @@ -93,15 +93,11 @@ int ebitmap_export(const struct ebitmap *src, size_t bitmap_byte; unsigned char bitmask; - if (src->highbit == 0) { - *dst = NULL; - *dst_len = 0; - return 0; - } - bitmap_len = src->highbit / 8; if (src->highbit % 7) bitmap_len += 1; + if (bitmap_len == 0) + return -EINVAL; bitmap = kzalloc((bitmap_len & ~(sizeof(MAPTYPE) - 1)) + sizeof(MAPTYPE), diff --git a/trunk/security/selinux/ss/hashtab.c b/trunk/security/selinux/ss/hashtab.c index 77b530c3bbce..24e5ec957630 100644 --- a/trunk/security/selinux/ss/hashtab.c +++ b/trunk/security/selinux/ss/hashtab.c @@ -8,8 +8,8 @@ #include #include "hashtab.h" -struct hashtab *hashtab_create(u32 (*hash_value)(struct hashtab *h, const void *key), - int (*keycmp)(struct hashtab *h, const void *key1, const void *key2), +struct hashtab *hashtab_create(u32 (*hash_value)(struct hashtab *h, void *key), + int (*keycmp)(struct hashtab *h, void *key1, void *key2), u32 size) { struct hashtab *p; @@ -71,7 +71,7 @@ int hashtab_insert(struct hashtab *h, void *key, void *datum) return 0; } -void *hashtab_search(struct hashtab *h, const void *key) +void *hashtab_search(struct hashtab *h, void *key) { u32 hvalue; struct hashtab_node *cur; diff --git a/trunk/security/selinux/ss/hashtab.h b/trunk/security/selinux/ss/hashtab.h index 7e2ff3e3c6d2..4cc85816a718 100644 --- a/trunk/security/selinux/ss/hashtab.h +++ b/trunk/security/selinux/ss/hashtab.h @@ -22,9 +22,9 @@ struct hashtab { struct hashtab_node **htable; /* hash table */ u32 size; /* number of slots in hash table */ u32 nel; /* number of elements in hash table */ - u32 (*hash_value)(struct hashtab *h, const void *key); + u32 (*hash_value)(struct hashtab *h, void *key); /* hash function */ - int (*keycmp)(struct hashtab *h, const void *key1, const void *key2); + int (*keycmp)(struct hashtab *h, void *key1, void *key2); /* key comparison function */ }; @@ -39,8 +39,8 @@ struct hashtab_info { * Returns NULL if insufficent space is available or * the new hash table otherwise. */ -struct hashtab *hashtab_create(u32 (*hash_value)(struct hashtab *h, const void *key), - int (*keycmp)(struct hashtab *h, const void *key1, const void *key2), +struct hashtab *hashtab_create(u32 (*hash_value)(struct hashtab *h, void *key), + int (*keycmp)(struct hashtab *h, void *key1, void *key2), u32 size); /* @@ -59,7 +59,7 @@ int hashtab_insert(struct hashtab *h, void *k, void *d); * Returns NULL if no entry has the specified key or * the datum of the entry otherwise. */ -void *hashtab_search(struct hashtab *h, const void *k); +void *hashtab_search(struct hashtab *h, void *k); /* * Destroys the specified hash table. diff --git a/trunk/security/selinux/ss/mls.c b/trunk/security/selinux/ss/mls.c index 2cca8e251624..c713af23250a 100644 --- a/trunk/security/selinux/ss/mls.c +++ b/trunk/security/selinux/ss/mls.c @@ -640,13 +640,8 @@ int mls_export_cat(const struct context *context, { int rc = -EPERM; - if (!selinux_mls_enabled) { - *low = NULL; - *low_len = 0; - *high = NULL; - *high_len = 0; + if (!selinux_mls_enabled) return 0; - } if (low != NULL) { rc = ebitmap_export(&context->range.level[0].cat, @@ -666,16 +661,10 @@ int mls_export_cat(const struct context *context, return 0; export_cat_failure: - if (low != NULL) { + if (low != NULL) kfree(*low); - *low = NULL; - *low_len = 0; - } - if (high != NULL) { + if (high != NULL) kfree(*high); - *high = NULL; - *high_len = 0; - } return rc; } diff --git a/trunk/security/selinux/ss/policydb.c b/trunk/security/selinux/ss/policydb.c index ba48961f9d05..b18895302555 100644 --- a/trunk/security/selinux/ss/policydb.c +++ b/trunk/security/selinux/ss/policydb.c @@ -618,7 +618,6 @@ void policydb_destroy(struct policydb *p) c = c->next; ocontext_destroy(ctmp,i); } - p->ocontexts[i] = NULL; } g = p->genfs; @@ -634,7 +633,6 @@ void policydb_destroy(struct policydb *p) g = g->next; kfree(gtmp); } - p->genfs = NULL; cond_policydb_destroy(p); diff --git a/trunk/security/selinux/ss/services.c b/trunk/security/selinux/ss/services.c index 408820486af0..0c219a1b3243 100644 --- a/trunk/security/selinux/ss/services.c +++ b/trunk/security/selinux/ss/services.c @@ -17,13 +17,9 @@ * * Added support for NetLabel * - * Updated: Chad Sellers - * - * Added validation of kernel classes and permissions - * * Copyright (C) 2006 Hewlett-Packard Development Company, L.P. * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc. - * Copyright (C) 2003 - 2004, 2006 Tresys Technology, LLC + * Copyright (C) 2003 - 2004 Tresys Technology, LLC * Copyright (C) 2003 Red Hat, Inc., James Morris * 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 @@ -57,11 +53,6 @@ extern void selnl_notify_policyload(u32 seqno); unsigned int policydb_loaded_version; -/* - * This is declared in avc.c - */ -extern const struct selinux_class_perm selinux_class_perm; - static DEFINE_RWLOCK(policy_rwlock); #define POLICY_RDLOCK read_lock(&policy_rwlock) #define POLICY_WRLOCK write_lock_irq(&policy_rwlock) @@ -1028,112 +1019,86 @@ int security_change_sid(u32 ssid, } /* - * Verify that each kernel class that is defined in the - * policy is correct + * Verify that each permission that is defined under the + * existing policy is still defined with the same value + * in the new policy. */ -static int validate_classes(struct policydb *p) +static int validate_perm(void *key, void *datum, void *p) { - int i, j; - struct class_datum *cladatum; - struct perm_datum *perdatum; - u32 nprim, tmp, common_pts_len, perm_val, pol_val; - u16 class_val; - const struct selinux_class_perm *kdefs = &selinux_class_perm; - const char *def_class, *def_perm, *pol_class; - struct symtab *perms; - - for (i = 1; i < kdefs->cts_len; i++) { - def_class = kdefs->class_to_string[i]; - if (i > p->p_classes.nprim) { - printk(KERN_INFO - "security: class %s not defined in policy\n", - def_class); - continue; - } - pol_class = p->p_class_val_to_name[i-1]; - if (strcmp(pol_class, def_class)) { - printk(KERN_ERR - "security: class %d is incorrect, found %s but should be %s\n", - i, pol_class, def_class); - return -EINVAL; - } + struct hashtab *h; + struct perm_datum *perdatum, *perdatum2; + int rc = 0; + + + h = p; + perdatum = datum; + + perdatum2 = hashtab_search(h, key); + if (!perdatum2) { + printk(KERN_ERR "security: permission %s disappeared", + (char *)key); + rc = -ENOENT; + goto out; } - for (i = 0; i < kdefs->av_pts_len; i++) { - class_val = kdefs->av_perm_to_string[i].tclass; - perm_val = kdefs->av_perm_to_string[i].value; - def_perm = kdefs->av_perm_to_string[i].name; - if (class_val > p->p_classes.nprim) - continue; - pol_class = p->p_class_val_to_name[class_val-1]; - cladatum = hashtab_search(p->p_classes.table, pol_class); - BUG_ON(!cladatum); - perms = &cladatum->permissions; - nprim = 1 << (perms->nprim - 1); - if (perm_val > nprim) { - printk(KERN_INFO - "security: permission %s in class %s not defined in policy\n", - def_perm, pol_class); - continue; - } - perdatum = hashtab_search(perms->table, def_perm); - if (perdatum == NULL) { - printk(KERN_ERR - "security: permission %s in class %s not found in policy\n", - def_perm, pol_class); - return -EINVAL; - } - pol_val = 1 << (perdatum->value - 1); - if (pol_val != perm_val) { - printk(KERN_ERR - "security: permission %s in class %s has incorrect value\n", - def_perm, pol_class); - return -EINVAL; - } + if (perdatum->value != perdatum2->value) { + printk(KERN_ERR "security: the value of permission %s changed", + (char *)key); + rc = -EINVAL; } - for (i = 0; i < kdefs->av_inherit_len; i++) { - class_val = kdefs->av_inherit[i].tclass; - if (class_val > p->p_classes.nprim) - continue; - pol_class = p->p_class_val_to_name[class_val-1]; - cladatum = hashtab_search(p->p_classes.table, pol_class); - BUG_ON(!cladatum); - if (!cladatum->comdatum) { - printk(KERN_ERR - "security: class %s should have an inherits clause but does not\n", - pol_class); - return -EINVAL; - } - tmp = kdefs->av_inherit[i].common_base; - common_pts_len = 0; - while (!(tmp & 0x01)) { - common_pts_len++; - tmp >>= 1; - } - perms = &cladatum->comdatum->permissions; - for (j = 0; j < common_pts_len; j++) { - def_perm = kdefs->av_inherit[i].common_pts[j]; - if (j >= perms->nprim) { - printk(KERN_INFO - "security: permission %s in class %s not defined in policy\n", - def_perm, pol_class); - continue; - } - perdatum = hashtab_search(perms->table, def_perm); - if (perdatum == NULL) { - printk(KERN_ERR - "security: permission %s in class %s not found in policy\n", - def_perm, pol_class); - return -EINVAL; - } - if (perdatum->value != j + 1) { - printk(KERN_ERR - "security: permission %s in class %s has incorrect value\n", - def_perm, pol_class); - return -EINVAL; - } +out: + return rc; +} + +/* + * Verify that each class that is defined under the + * existing policy is still defined with the same + * attributes in the new policy. + */ +static int validate_class(void *key, void *datum, void *p) +{ + struct policydb *newp; + struct class_datum *cladatum, *cladatum2; + int rc; + + newp = p; + cladatum = datum; + + cladatum2 = hashtab_search(newp->p_classes.table, key); + if (!cladatum2) { + printk(KERN_ERR "security: class %s disappeared\n", + (char *)key); + rc = -ENOENT; + goto out; + } + if (cladatum->value != cladatum2->value) { + printk(KERN_ERR "security: the value of class %s changed\n", + (char *)key); + rc = -EINVAL; + goto out; + } + if ((cladatum->comdatum && !cladatum2->comdatum) || + (!cladatum->comdatum && cladatum2->comdatum)) { + printk(KERN_ERR "security: the inherits clause for the access " + "vector definition for class %s changed\n", (char *)key); + rc = -EINVAL; + goto out; + } + if (cladatum->comdatum) { + rc = hashtab_map(cladatum->comdatum->permissions.table, validate_perm, + cladatum2->comdatum->permissions.table); + if (rc) { + printk(" in the access vector definition for class " + "%s\n", (char *)key); + goto out; } } - return 0; + rc = hashtab_map(cladatum->permissions.table, validate_perm, + cladatum2->permissions.table); + if (rc) + printk(" in access vector definition for class %s\n", + (char *)key); +out: + return rc; } /* Clone the SID into the new SID table. */ @@ -1278,16 +1243,6 @@ int security_load_policy(void *data, size_t len) avtab_cache_destroy(); return -EINVAL; } - /* Verify that the kernel defined classes are correct. */ - if (validate_classes(&policydb)) { - printk(KERN_ERR - "security: the definition of a class is incorrect\n"); - LOAD_UNLOCK; - sidtab_destroy(&sidtab); - policydb_destroy(&policydb); - avtab_cache_destroy(); - return -EINVAL; - } policydb_loaded_version = policydb.policyvers; ss_initialized = 1; seqno = ++latest_granting; @@ -1310,10 +1265,10 @@ int security_load_policy(void *data, size_t len) sidtab_init(&newsidtab); - /* Verify that the kernel defined classes are correct. */ - if (validate_classes(&newpolicydb)) { - printk(KERN_ERR - "security: the definition of a class is incorrect\n"); + /* Verify that the existing classes did not change. */ + if (hashtab_map(policydb.p_classes.table, validate_class, &newpolicydb)) { + printk(KERN_ERR "security: the definition of an existing " + "class changed\n"); rc = -EINVAL; goto err; } @@ -2217,12 +2172,7 @@ struct netlbl_cache { */ static void selinux_netlbl_cache_free(const void *data) { - struct netlbl_cache *cache; - - if (data == NULL) - return; - - cache = NETLBL_CACHE(data); + struct netlbl_cache *cache = NETLBL_CACHE(data); switch (cache->type) { case NETLBL_CACHE_T_MLS: ebitmap_destroy(&cache->data.mls_label.level[0].cat); @@ -2247,20 +2197,17 @@ static void selinux_netlbl_cache_add(struct sk_buff *skb, struct context *ctx) struct netlbl_lsm_secattr secattr; netlbl_secattr_init(&secattr); - secattr.cache = netlbl_secattr_cache_alloc(GFP_ATOMIC); - if (secattr.cache == NULL) - goto netlbl_cache_add_return; cache = kzalloc(sizeof(*cache), GFP_ATOMIC); if (cache == NULL) - goto netlbl_cache_add_return; - secattr.cache->free = selinux_netlbl_cache_free; - secattr.cache->data = (void *)cache; + goto netlbl_cache_add_failure; + secattr.cache.free = selinux_netlbl_cache_free; + secattr.cache.data = (void *)cache; cache->type = NETLBL_CACHE_T_MLS; if (ebitmap_cpy(&cache->data.mls_label.level[0].cat, &ctx->range.level[0].cat) != 0) - goto netlbl_cache_add_return; + goto netlbl_cache_add_failure; cache->data.mls_label.level[1].cat.highbit = cache->data.mls_label.level[0].cat.highbit; cache->data.mls_label.level[1].cat.node = @@ -2268,10 +2215,13 @@ static void selinux_netlbl_cache_add(struct sk_buff *skb, struct context *ctx) cache->data.mls_label.level[0].sens = ctx->range.level[0].sens; cache->data.mls_label.level[1].sens = ctx->range.level[0].sens; - netlbl_cache_add(skb, &secattr); + if (netlbl_cache_add(skb, &secattr) != 0) + goto netlbl_cache_add_failure; + + return; -netlbl_cache_add_return: - netlbl_secattr_destroy(&secattr); +netlbl_cache_add_failure: + netlbl_secattr_destroy(&secattr, 1); } /** @@ -2313,8 +2263,8 @@ static int selinux_netlbl_secattr_to_sid(struct sk_buff *skb, POLICY_RDLOCK; - if (secattr->cache) { - cache = NETLBL_CACHE(secattr->cache->data); + if (secattr->cache.data) { + cache = NETLBL_CACHE(secattr->cache.data); switch (cache->type) { case NETLBL_CACHE_T_SID: *sid = cache->data.sid; @@ -2381,7 +2331,7 @@ static int selinux_netlbl_secattr_to_sid(struct sk_buff *skb, selinux_netlbl_cache_add(skb, &ctx_new); ebitmap_destroy(&ctx_new.range.level[0].cat); } else { - *sid = SECSID_NULL; + *sid = SECINITSID_UNLABELED; rc = 0; } @@ -2419,7 +2369,7 @@ static int selinux_netlbl_skbuff_getsid(struct sk_buff *skb, &secattr, base_sid, sid); - netlbl_secattr_destroy(&secattr); + netlbl_secattr_destroy(&secattr, 0); return rc; } @@ -2444,33 +2394,31 @@ static int selinux_netlbl_socket_setsid(struct socket *sock, u32 sid) if (!ss_initialized) return 0; - netlbl_secattr_init(&secattr); - POLICY_RDLOCK; ctx = sidtab_search(&sidtab, sid); if (ctx == NULL) goto netlbl_socket_setsid_return; + netlbl_secattr_init(&secattr); secattr.domain = kstrdup(policydb.p_type_val_to_name[ctx->type - 1], GFP_ATOMIC); mls_export_lvl(ctx, &secattr.mls_lvl, NULL); secattr.mls_lvl_vld = 1; - rc = mls_export_cat(ctx, - &secattr.mls_cat, - &secattr.mls_cat_len, - NULL, - NULL); - if (rc != 0) - goto netlbl_socket_setsid_return; + mls_export_cat(ctx, + &secattr.mls_cat, + &secattr.mls_cat_len, + NULL, + NULL); rc = netlbl_socket_setattr(sock, &secattr); if (rc == 0) sksec->nlbl_state = NLBL_LABELED; + netlbl_secattr_destroy(&secattr, 0); + netlbl_socket_setsid_return: POLICY_RDUNLOCK; - netlbl_secattr_destroy(&secattr); return rc; } @@ -2566,10 +2514,10 @@ void selinux_netlbl_sock_graft(struct sock *sk, struct socket *sock) if (netlbl_sock_getattr(sk, &secattr) == 0 && selinux_netlbl_secattr_to_sid(NULL, &secattr, - SECINITSID_UNLABELED, + sksec->sid, &nlbl_peer_sid) == 0) sksec->peer_sid = nlbl_peer_sid; - netlbl_secattr_destroy(&secattr); + netlbl_secattr_destroy(&secattr, 0); sksec->nlbl_state = NLBL_REQUIRE; @@ -2599,6 +2547,9 @@ u32 selinux_netlbl_inet_conn_request(struct sk_buff *skb, u32 sock_sid) if (rc != 0) return SECSID_NULL; + if (peer_sid == SECINITSID_UNLABELED) + return SECSID_NULL; + return peer_sid; } @@ -2660,13 +2611,11 @@ int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec, u32 netlbl_sid; u32 recv_perm; - rc = selinux_netlbl_skbuff_getsid(skb, - SECINITSID_UNLABELED, - &netlbl_sid); + rc = selinux_netlbl_skbuff_getsid(skb, SECINITSID_NETMSG, &netlbl_sid); if (rc != 0) return rc; - if (netlbl_sid == SECSID_NULL) + if (netlbl_sid == SECINITSID_UNLABELED) return 0; switch (sksec->sclass) { @@ -2704,6 +2653,10 @@ int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec, u32 selinux_netlbl_socket_getpeersec_stream(struct socket *sock) { struct sk_security_struct *sksec = sock->sk->sk_security; + + if (sksec->peer_sid == SECINITSID_UNLABELED) + return SECSID_NULL; + return sksec->peer_sid; } @@ -2719,49 +2672,18 @@ u32 selinux_netlbl_socket_getpeersec_stream(struct socket *sock) u32 selinux_netlbl_socket_getpeersec_dgram(struct sk_buff *skb) { int peer_sid; + struct sock *sk = skb->sk; + struct inode_security_struct *isec; - if (selinux_netlbl_skbuff_getsid(skb, - SECINITSID_UNLABELED, - &peer_sid) != 0) + if (sk == NULL || sk->sk_socket == NULL) return SECSID_NULL; - return peer_sid; -} - -/** - * selinux_netlbl_socket_setsockopt - Do not allow users to remove a NetLabel - * @sock: the socket - * @level: the socket level or protocol - * @optname: the socket option name - * - * Description: - * Check the setsockopt() call and if the user is trying to replace the IP - * options on a socket and a NetLabel is in place for the socket deny the - * access; otherwise allow the access. Returns zero when the access is - * allowed, -EACCES when denied, and other negative values on error. - * - */ -int selinux_netlbl_socket_setsockopt(struct socket *sock, - int level, - int optname) -{ - int rc = 0; - struct inode *inode = SOCK_INODE(sock); - struct sk_security_struct *sksec = sock->sk->sk_security; - struct inode_security_struct *isec = inode->i_security; - struct netlbl_lsm_secattr secattr; - - mutex_lock(&isec->lock); - if (level == IPPROTO_IP && optname == IP_OPTIONS && - sksec->nlbl_state == NLBL_LABELED) { - netlbl_secattr_init(&secattr); - rc = netlbl_socket_getattr(sock, &secattr); - if (rc == 0 && (secattr.cache || secattr.mls_lvl_vld)) - rc = -EACCES; - netlbl_secattr_destroy(&secattr); - } - mutex_unlock(&isec->lock); + isec = SOCK_INODE(sk->sk_socket)->i_security; + if (selinux_netlbl_skbuff_getsid(skb, isec->sid, &peer_sid) != 0) + return SECSID_NULL; + if (peer_sid == SECINITSID_UNLABELED) + return SECSID_NULL; - return rc; + return peer_sid; } #endif /* CONFIG_NETLABEL */ diff --git a/trunk/security/selinux/ss/symtab.c b/trunk/security/selinux/ss/symtab.c index 837658a98a54..24a10d36d3b6 100644 --- a/trunk/security/selinux/ss/symtab.c +++ b/trunk/security/selinux/ss/symtab.c @@ -9,9 +9,9 @@ #include #include "symtab.h" -static unsigned int symhash(struct hashtab *h, const void *key) +static unsigned int symhash(struct hashtab *h, void *key) { - const char *p, *keyp; + char *p, *keyp; unsigned int size; unsigned int val; @@ -23,9 +23,9 @@ static unsigned int symhash(struct hashtab *h, const void *key) return val & (h->size - 1); } -static int symcmp(struct hashtab *h, const void *key1, const void *key2) +static int symcmp(struct hashtab *h, void *key1, void *key2) { - const char *keyp1, *keyp2; + char *keyp1, *keyp2; keyp1 = key1; keyp2 = key2; diff --git a/trunk/security/selinux/xfrm.c b/trunk/security/selinux/xfrm.c index 675b995a67c3..3e742b850af6 100644 --- a/trunk/security/selinux/xfrm.c +++ b/trunk/security/selinux/xfrm.c @@ -77,8 +77,8 @@ static inline int selinux_authorizable_xfrm(struct xfrm_state *x) */ int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir) { - int rc; - u32 sel_sid; + int rc = 0; + u32 sel_sid = SECINITSID_UNLABELED; struct xfrm_sec_ctx *ctx; /* Context sid is either set to label or ANY_ASSOC */ @@ -88,21 +88,11 @@ int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir) sel_sid = ctx->ctx_sid; } - else - /* - * All flows should be treated as polmatch'ing an - * otherwise applicable "non-labeled" policy. This - * would prevent inadvertent "leaks". - */ - return 0; rc = avc_has_perm(fl_secid, sel_sid, SECCLASS_ASSOCIATION, ASSOCIATION__POLMATCH, NULL); - if (rc == -EACCES) - rc = -ESRCH; - return rc; } @@ -118,20 +108,15 @@ int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, struct xfrm_policy * u32 pol_sid; int err; - if (xp->security) { - if (!x->security) - /* unlabeled SA and labeled policy can't match */ - return 0; - else - state_sid = x->security->ctx_sid; + if (x->security) + state_sid = x->security->ctx_sid; + else + state_sid = SECINITSID_UNLABELED; + + if (xp->security) pol_sid = xp->security->ctx_sid; - } else - if (x->security) - /* unlabeled policy and labeled SA can't match */ - return 0; - else - /* unlabeled policy and unlabeled SA match all flows */ - return 1; + else + pol_sid = SECINITSID_UNLABELED; err = avc_has_perm(state_sid, pol_sid, SECCLASS_ASSOCIATION, ASSOCIATION__POLMATCH, @@ -140,11 +125,7 @@ int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, struct xfrm_policy * if (err) return 0; - err = avc_has_perm(fl->secid, state_sid, SECCLASS_ASSOCIATION, - ASSOCIATION__SENDTO, - NULL)? 0:1; - - return err; + return selinux_xfrm_flow_state_match(fl, x); } /* @@ -152,22 +133,12 @@ int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, struct xfrm_policy * * can use a given security association. */ -int selinux_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm, - struct xfrm_policy *xp) +int selinux_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm) { int rc = 0; u32 sel_sid = SECINITSID_UNLABELED; struct xfrm_sec_ctx *ctx; - if (!xp->security) - if (!xfrm->security) - return 1; - else - return 0; - else - if (!xfrm->security) - return 0; - /* Context sid is either set to label or ANY_ASSOC */ if ((ctx = xfrm->security)) { if (!selinux_authorizable_ctx(ctx)) diff --git a/trunk/sound/Kconfig b/trunk/sound/Kconfig index 95949b6806ac..e0d791a98452 100644 --- a/trunk/sound/Kconfig +++ b/trunk/sound/Kconfig @@ -64,11 +64,11 @@ source "sound/arm/Kconfig" source "sound/mips/Kconfig" -# the following will depend on the order of config. +# the following will depenend on the order of config. # here assuming USB is defined before ALSA source "sound/usb/Kconfig" -# the following will depend on the order of config. +# the following will depenend on the order of config. # here assuming PCMCIA is defined before ALSA source "sound/pcmcia/Kconfig" diff --git a/trunk/sound/aoa/codecs/snd-aoa-codec-tas.c b/trunk/sound/aoa/codecs/snd-aoa-codec-tas.c index 9de8485ba3f5..2ef55a17917c 100644 --- a/trunk/sound/aoa/codecs/snd-aoa-codec-tas.c +++ b/trunk/sound/aoa/codecs/snd-aoa-codec-tas.c @@ -514,15 +514,9 @@ static int tas_snd_capture_source_put(struct snd_kcontrol *kcontrol, mutex_lock(&tas->mtx); oldacr = tas->acr; - /* - * Despite what the data sheet says in one place, the - * TAS_ACR_B_MONAUREAL bit forces mono output even when - * input A (line in) is selected. - */ - tas->acr &= ~(TAS_ACR_INPUT_B | TAS_ACR_B_MONAUREAL); + tas->acr &= ~TAS_ACR_INPUT_B; if (ucontrol->value.enumerated.item[0]) - tas->acr |= TAS_ACR_INPUT_B | TAS_ACR_B_MONAUREAL | - TAS_ACR_B_MON_SEL_RIGHT; + tas->acr |= TAS_ACR_INPUT_B; if (oldacr == tas->acr) { mutex_unlock(&tas->mtx); return 0; @@ -692,7 +686,8 @@ static int tas_reset_init(struct tas *tas) if (tas_write_reg(tas, TAS_REG_MCS, 1, &tmp)) goto outerr; - tas->acr |= TAS_ACR_ANALOG_PDOWN; + tas->acr |= TAS_ACR_ANALOG_PDOWN | TAS_ACR_B_MONAUREAL | + TAS_ACR_B_MON_SEL_RIGHT; if (tas_write_reg(tas, TAS_REG_ACR, 1, &tas->acr)) goto outerr; diff --git a/trunk/sound/aoa/core/snd-aoa-gpio-feature.c b/trunk/sound/aoa/core/snd-aoa-gpio-feature.c index 40eb47eccf9a..7c26089527f6 100644 --- a/trunk/sound/aoa/core/snd-aoa-gpio-feature.c +++ b/trunk/sound/aoa/core/snd-aoa-gpio-feature.c @@ -283,7 +283,9 @@ static void ftr_gpio_exit(struct gpio_runtime *rt) mutex_destroy(&rt->line_out_notify.mutex); } -static irqreturn_t ftr_handle_notify_irq(int xx, void *data) +static irqreturn_t ftr_handle_notify_irq(int xx, + void *data, + struct pt_regs *regs) { struct gpio_notification *notif = data; diff --git a/trunk/sound/aoa/soundbus/i2sbus/i2sbus-core.c b/trunk/sound/aoa/soundbus/i2sbus/i2sbus-core.c index e593a1333fe3..23190aa6bc7b 100644 --- a/trunk/sound/aoa/soundbus/i2sbus/i2sbus-core.c +++ b/trunk/sound/aoa/soundbus/i2sbus/i2sbus-core.c @@ -93,7 +93,7 @@ static void i2sbus_release_dev(struct device *dev) kfree(i2sdev); } -static irqreturn_t i2sbus_bus_intr(int irq, void *devid) +static irqreturn_t i2sbus_bus_intr(int irq, void *devid, struct pt_regs *regs) { struct i2sbus_dev *dev = devid; u32 intreg; @@ -165,7 +165,8 @@ static int i2sbus_add_dev(struct macio_dev *macio, static const char *rnames[] = { "i2sbus: %s (control)", "i2sbus: %s (tx)", "i2sbus: %s (rx)" }; - static irq_handler_t ints[] = { + static irqreturn_t (*ints[])(int irq, void *devid, + struct pt_regs *regs) = { i2sbus_bus_intr, i2sbus_tx_intr, i2sbus_rx_intr diff --git a/trunk/sound/aoa/soundbus/i2sbus/i2sbus-pcm.c b/trunk/sound/aoa/soundbus/i2sbus/i2sbus-pcm.c index 5eff30b10201..3049015a04f1 100644 --- a/trunk/sound/aoa/soundbus/i2sbus/i2sbus-pcm.c +++ b/trunk/sound/aoa/soundbus/i2sbus/i2sbus-pcm.c @@ -642,13 +642,13 @@ static inline void handle_interrupt(struct i2sbus_dev *i2sdev, int in) spin_unlock(&i2sdev->low_lock); } -irqreturn_t i2sbus_tx_intr(int irq, void *devid) +irqreturn_t i2sbus_tx_intr(int irq, void *devid, struct pt_regs *regs) { handle_interrupt((struct i2sbus_dev *)devid, 0); return IRQ_HANDLED; } -irqreturn_t i2sbus_rx_intr(int irq, void *devid) +irqreturn_t i2sbus_rx_intr(int irq, void *devid, struct pt_regs * regs) { handle_interrupt((struct i2sbus_dev *)devid, 1); return IRQ_HANDLED; diff --git a/trunk/sound/aoa/soundbus/i2sbus/i2sbus.h b/trunk/sound/aoa/soundbus/i2sbus/i2sbus.h index ec20ee615d7f..0c69d209be50 100644 --- a/trunk/sound/aoa/soundbus/i2sbus/i2sbus.h +++ b/trunk/sound/aoa/soundbus/i2sbus/i2sbus.h @@ -97,9 +97,9 @@ i2sbus_attach_codec(struct soundbus_dev *dev, struct snd_card *card, extern void i2sbus_detach_codec(struct soundbus_dev *dev, void *data); extern irqreturn_t -i2sbus_tx_intr(int irq, void *devid); +i2sbus_tx_intr(int irq, void *devid, struct pt_regs *regs); extern irqreturn_t -i2sbus_rx_intr(int irq, void *devid); +i2sbus_rx_intr(int irq, void *devid, struct pt_regs *regs); /* control specific functions */ extern int i2sbus_control_init(struct macio_dev* dev, diff --git a/trunk/sound/arm/aaci.c b/trunk/sound/arm/aaci.c index 53675cf4de44..8435fdd1c87c 100644 --- a/trunk/sound/arm/aaci.c +++ b/trunk/sound/arm/aaci.c @@ -221,7 +221,7 @@ static void aaci_fifo_irq(struct aaci *aaci, u32 mask) } } -static irqreturn_t aaci_irq(int irq, void *devid) +static irqreturn_t aaci_irq(int irq, void *devid, struct pt_regs *regs) { struct aaci *aaci = devid; u32 mask; diff --git a/trunk/sound/arm/pxa2xx-ac97.c b/trunk/sound/arm/pxa2xx-ac97.c index dede954b2c65..599aff8290e8 100644 --- a/trunk/sound/arm/pxa2xx-ac97.c +++ b/trunk/sound/arm/pxa2xx-ac97.c @@ -152,7 +152,7 @@ static void pxa2xx_ac97_reset(struct snd_ac97 *ac97) GCR |= GCR_SDONE_IE|GCR_CDONE_IE; } -static irqreturn_t pxa2xx_ac97_irq(int irq, void *dev_id) +static irqreturn_t pxa2xx_ac97_irq(int irq, void *dev_id, struct pt_regs *regs) { long status; diff --git a/trunk/sound/arm/pxa2xx-pcm.c b/trunk/sound/arm/pxa2xx-pcm.c index e8cf904b8358..4938ef10b813 100644 --- a/trunk/sound/arm/pxa2xx-pcm.c +++ b/trunk/sound/arm/pxa2xx-pcm.c @@ -137,7 +137,7 @@ static int pxa2xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) return ret; } -static void pxa2xx_pcm_dma_irq(int dma_ch, void *dev_id) +static void pxa2xx_pcm_dma_irq(int dma_ch, void *dev_id, struct pt_regs *regs) { struct snd_pcm_substream *substream = dev_id; struct pxa2xx_runtime_data *rtd = substream->runtime->private_data; diff --git a/trunk/sound/core/control.c b/trunk/sound/core/control.c index 48ef0a09a7a7..6973a9686b67 100644 --- a/trunk/sound/core/control.c +++ b/trunk/sound/core/control.c @@ -1018,6 +1018,10 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file, } switch (info->type) { case SNDRV_CTL_ELEM_TYPE_BOOLEAN: + private_size = sizeof(char); + if (info->count > 128) + return -EINVAL; + break; case SNDRV_CTL_ELEM_TYPE_INTEGER: private_size = sizeof(long); if (info->count > 128) diff --git a/trunk/sound/core/hwdep.c b/trunk/sound/core/hwdep.c index 46b47689362c..9aa9d94891f0 100644 --- a/trunk/sound/core/hwdep.c +++ b/trunk/sound/core/hwdep.c @@ -158,7 +158,6 @@ static int snd_hwdep_release(struct inode *inode, struct file * file) { int err = -ENXIO; struct snd_hwdep *hw = file->private_data; - struct module *mod = hw->card->module; mutex_lock(&hw->open_mutex); if (hw->ops.release) { err = hw->ops.release(hw, file); @@ -168,7 +167,7 @@ static int snd_hwdep_release(struct inode *inode, struct file * file) hw->used--; snd_card_file_remove(hw->card, file); mutex_unlock(&hw->open_mutex); - module_put(mod); + module_put(hw->card->module); return err; } diff --git a/trunk/sound/core/hwdep_compat.c b/trunk/sound/core/hwdep_compat.c index 3827c0ceec8f..938f77580966 100644 --- a/trunk/sound/core/hwdep_compat.c +++ b/trunk/sound/core/hwdep_compat.c @@ -33,7 +33,7 @@ struct snd_hwdep_dsp_image32 { static int snd_hwdep_dsp_load_compat(struct snd_hwdep *hw, struct snd_hwdep_dsp_image32 __user *src) { - struct snd_hwdep_dsp_image __user *dst; + struct snd_hwdep_dsp_image *dst; compat_caddr_t ptr; u32 val; diff --git a/trunk/sound/core/info.c b/trunk/sound/core/info.c index 0b4aab3225e5..e43662b33f16 100644 --- a/trunk/sound/core/info.c +++ b/trunk/sound/core/info.c @@ -120,10 +120,7 @@ int snd_iprintf(struct snd_info_buffer *buffer, char *fmt,...) len = buffer->len - buffer->size; va_start(args, fmt); for (;;) { - va_list ap; - va_copy(ap, args); - res = vsnprintf(buffer->buffer + buffer->curr, len, fmt, ap); - va_end(ap); + res = vsnprintf(buffer->buffer + buffer->curr, len, fmt, args); if (res < len) break; err = resize_info_buffer(buffer, buffer->len + PAGE_SIZE); diff --git a/trunk/sound/core/init.c b/trunk/sound/core/init.c index 6152a7554dfd..d7607a25acdf 100644 --- a/trunk/sound/core/init.c +++ b/trunk/sound/core/init.c @@ -33,10 +33,10 @@ #include #include -static DEFINE_SPINLOCK(shutdown_lock); -static LIST_HEAD(shutdown_files); - -static struct file_operations snd_shutdown_f_ops; +struct snd_shutdown_f_ops { + struct file_operations f_ops; + struct snd_shutdown_f_ops *next; +}; static unsigned int snd_cards_lock; /* locked for registering/using */ struct snd_card *snd_cards[SNDRV_CARDS]; @@ -198,25 +198,6 @@ static ssize_t snd_disconnect_write(struct file *file, const char __user *buf, return -ENODEV; } -static int snd_disconnect_release(struct inode *inode, struct file *file) -{ - struct snd_monitor_file *df = NULL, *_df; - - spin_lock(&shutdown_lock); - list_for_each_entry(_df, &shutdown_files, shutdown_list) { - if (_df->file == file) { - df = _df; - break; - } - } - spin_unlock(&shutdown_lock); - - if (likely(df)) - return df->disconnected_f_op->release(inode, file); - - panic("%s(%p, %p) failed!", __FUNCTION__, inode, file); -} - static unsigned int snd_disconnect_poll(struct file * file, poll_table * wait) { return POLLERR | POLLNVAL; @@ -238,22 +219,6 @@ static int snd_disconnect_fasync(int fd, struct file *file, int on) return -ENODEV; } -static struct file_operations snd_shutdown_f_ops = -{ - .owner = THIS_MODULE, - .llseek = snd_disconnect_llseek, - .read = snd_disconnect_read, - .write = snd_disconnect_write, - .release = snd_disconnect_release, - .poll = snd_disconnect_poll, - .unlocked_ioctl = snd_disconnect_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = snd_disconnect_ioctl, -#endif - .mmap = snd_disconnect_mmap, - .fasync = snd_disconnect_fasync -}; - /** * snd_card_disconnect - disconnect all APIs from the file-operations (user space) * @card: soundcard structure @@ -269,6 +234,9 @@ int snd_card_disconnect(struct snd_card *card) { struct snd_monitor_file *mfile; struct file *file; + struct snd_shutdown_f_ops *s_f_ops; + struct file_operations *f_ops; + const struct file_operations *old_f_ops; int err; spin_lock(&card->files_lock); @@ -293,14 +261,34 @@ int snd_card_disconnect(struct snd_card *card) /* it's critical part, use endless loop */ /* we have no room to fail */ - mfile->disconnected_f_op = mfile->file->f_op; + s_f_ops = kmalloc(sizeof(struct snd_shutdown_f_ops), GFP_ATOMIC); + if (s_f_ops == NULL) + panic("Atomic allocation failed for snd_shutdown_f_ops!"); + + f_ops = &s_f_ops->f_ops; + + memset(f_ops, 0, sizeof(*f_ops)); + f_ops->owner = file->f_op->owner; + f_ops->release = file->f_op->release; + f_ops->llseek = snd_disconnect_llseek; + f_ops->read = snd_disconnect_read; + f_ops->write = snd_disconnect_write; + f_ops->poll = snd_disconnect_poll; + f_ops->unlocked_ioctl = snd_disconnect_ioctl; +#ifdef CONFIG_COMPAT + f_ops->compat_ioctl = snd_disconnect_ioctl; +#endif + f_ops->mmap = snd_disconnect_mmap; + f_ops->fasync = snd_disconnect_fasync; - spin_lock(&shutdown_lock); - list_add(&mfile->shutdown_list, &shutdown_files); - spin_unlock(&shutdown_lock); + s_f_ops->next = card->s_f_ops; + card->s_f_ops = s_f_ops; + + f_ops = fops_get(f_ops); - fops_get(&snd_shutdown_f_ops); - mfile->file->f_op = &snd_shutdown_f_ops; + old_f_ops = file->f_op; + file->f_op = f_ops; /* must be atomic */ + fops_put(old_f_ops); mfile = mfile->next; } @@ -338,6 +326,8 @@ EXPORT_SYMBOL(snd_card_disconnect); */ static int snd_card_do_free(struct snd_card *card) { + struct snd_shutdown_f_ops *s_f_ops; + #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE) if (snd_mixer_oss_notify_callback) snd_mixer_oss_notify_callback(card, SND_MIXER_OSS_NOTIFY_FREE); @@ -361,8 +351,11 @@ static int snd_card_do_free(struct snd_card *card) snd_printk(KERN_WARNING "unable to free card info\n"); /* Not fatal error */ } - if (card->dev) - device_unregister(card->dev); + while (card->s_f_ops) { + s_f_ops = card->s_f_ops; + card->s_f_ops = s_f_ops->next; + kfree(s_f_ops); + } kfree(card); return 0; } @@ -497,12 +490,6 @@ int snd_card_register(struct snd_card *card) int err; snd_assert(card != NULL, return -EINVAL); - if (!card->dev) { - card->dev = device_create(sound_class, card->parent, 0, - "card%i", card->number); - if (IS_ERR(card->dev)) - card->dev = NULL; - } if ((err = snd_device_register_all(card)) < 0) return err; mutex_lock(&snd_card_mutex); @@ -683,7 +670,6 @@ int snd_card_file_add(struct snd_card *card, struct file *file) if (mfile == NULL) return -ENOMEM; mfile->file = file; - mfile->disconnected_f_op = NULL; mfile->next = NULL; spin_lock(&card->files_lock); if (card->shutdown) { @@ -730,12 +716,6 @@ int snd_card_file_remove(struct snd_card *card, struct file *file) pfile = mfile; mfile = mfile->next; } - if (mfile && mfile->disconnected_f_op) { - fops_put(mfile->disconnected_f_op); - spin_lock(&shutdown_lock); - list_del(&mfile->shutdown_list); - spin_unlock(&shutdown_lock); - } if (card->files == NULL) last_close = 1; spin_unlock(&card->files_lock); diff --git a/trunk/sound/core/oss/pcm_oss.c b/trunk/sound/core/oss/pcm_oss.c index e0821eb3d851..505b23ec4058 100644 --- a/trunk/sound/core/oss/pcm_oss.c +++ b/trunk/sound/core/oss/pcm_oss.c @@ -2359,8 +2359,7 @@ static int snd_pcm_oss_release(struct inode *inode, struct file *file) substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE]; snd_assert(substream != NULL, return -ENXIO); pcm = substream->pcm; - if (!pcm->card->shutdown) - snd_pcm_oss_sync(pcm_oss_file); + snd_pcm_oss_sync(pcm_oss_file); mutex_lock(&pcm->open_mutex); snd_pcm_oss_release_file(pcm_oss_file); mutex_unlock(&pcm->open_mutex); diff --git a/trunk/sound/core/pcm.c b/trunk/sound/core/pcm.c index 5ac6e19ccb41..fbbbcd20c4cc 100644 --- a/trunk/sound/core/pcm.c +++ b/trunk/sound/core/pcm.c @@ -910,8 +910,7 @@ void snd_pcm_detach_substream(struct snd_pcm_substream *substream) substream->pstr->substream_opened--; } -static ssize_t show_pcm_class(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t show_pcm_class(struct class_device *class_device, char *buf) { struct snd_pcm *pcm; const char *str; @@ -922,7 +921,7 @@ static ssize_t show_pcm_class(struct device *dev, [SNDRV_PCM_CLASS_DIGITIZER] = "digitizer", }; - if (! (pcm = dev_get_drvdata(dev)) || + if (! (pcm = class_get_devdata(class_device)) || pcm->dev_class > SNDRV_PCM_CLASS_LAST) str = "none"; else @@ -930,7 +929,7 @@ static ssize_t show_pcm_class(struct device *dev, return snprintf(buf, PAGE_SIZE, "%s\n", str); } -static struct device_attribute pcm_attrs = +static struct class_device_attribute pcm_attrs = __ATTR(pcm_class, S_IRUGO, show_pcm_class, NULL); static int snd_pcm_dev_register(struct snd_device *device) diff --git a/trunk/sound/core/pcm_native.c b/trunk/sound/core/pcm_native.c index 66e24b5da469..37b4b10850ae 100644 --- a/trunk/sound/core/pcm_native.c +++ b/trunk/sound/core/pcm_native.c @@ -1310,8 +1310,7 @@ static int snd_pcm_pre_prepare(struct snd_pcm_substream *substream, int f_flags) { struct snd_pcm_runtime *runtime = substream->runtime; - if (runtime->status->state == SNDRV_PCM_STATE_OPEN || - runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED) + if (runtime->status->state == SNDRV_PCM_STATE_OPEN) return -EBADFD; if (snd_pcm_running(substream)) return -EBUSY; @@ -1569,8 +1568,7 @@ static int snd_pcm_drop(struct snd_pcm_substream *substream) runtime = substream->runtime; card = substream->pcm->card; - if (runtime->status->state == SNDRV_PCM_STATE_OPEN || - runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED) + if (runtime->status->state == SNDRV_PCM_STATE_OPEN) return -EBADFD; snd_power_lock(card); diff --git a/trunk/sound/core/rtctimer.c b/trunk/sound/core/rtctimer.c index 9f7b32e1ccde..412dd62b654e 100644 --- a/trunk/sound/core/rtctimer.c +++ b/trunk/sound/core/rtctimer.c @@ -22,10 +22,13 @@ #include #include +#include +#include #include #include #include #include +#include #if defined(CONFIG_RTC) || defined(CONFIG_RTC_MODULE) @@ -47,9 +50,7 @@ static int rtctimer_stop(struct snd_timer *t); * The hardware dependent description for this timer. */ static struct snd_timer_hardware rtc_hw = { - .flags = SNDRV_TIMER_HW_AUTO | - SNDRV_TIMER_HW_FIRST | - SNDRV_TIMER_HW_TASKLET, + .flags = SNDRV_TIMER_HW_FIRST|SNDRV_TIMER_HW_AUTO, .ticks = 100000000L, /* FIXME: XXX */ .open = rtctimer_open, .close = rtctimer_close, @@ -59,7 +60,6 @@ static struct snd_timer_hardware rtc_hw = { static int rtctimer_freq = RTC_FREQ; /* frequency */ static struct snd_timer *rtctimer; -static struct tasklet_struct rtc_tasklet; static rtc_task_t rtc_task; @@ -81,7 +81,6 @@ rtctimer_close(struct snd_timer *t) rtc_task_t *rtc = t->private_data; if (rtc) { rtc_unregister(rtc); - tasklet_kill(&rtc_tasklet); t->private_data = NULL; } return 0; @@ -106,17 +105,12 @@ rtctimer_stop(struct snd_timer *timer) return 0; } -static void rtctimer_tasklet(unsigned long data) -{ - snd_timer_interrupt((struct snd_timer *)data, 1); -} - /* * interrupt */ static void rtctimer_interrupt(void *private_data) { - tasklet_hi_schedule(private_data); + snd_timer_interrupt(private_data, 1); } @@ -145,11 +139,9 @@ static int __init rtctimer_init(void) timer->hw = rtc_hw; timer->hw.resolution = NANO_SEC / rtctimer_freq; - tasklet_init(&rtc_tasklet, rtctimer_tasklet, (unsigned long)timer); - /* set up RTC callback */ rtc_task.func = rtctimer_interrupt; - rtc_task.private_data = &rtc_tasklet; + rtc_task.private_data = timer; err = snd_timer_global_register(timer); if (err < 0) { diff --git a/trunk/sound/core/sound.c b/trunk/sound/core/sound.c index 282742022de6..efa476c5210a 100644 --- a/trunk/sound/core/sound.c +++ b/trunk/sound/core/sound.c @@ -61,6 +61,9 @@ EXPORT_SYMBOL(snd_ecards_limit); static struct snd_minor *snd_minors[SNDRV_OS_MINORS]; static DEFINE_MUTEX(sound_mutex); +extern struct class *sound_class; + + #ifdef CONFIG_KMOD /** @@ -265,10 +268,11 @@ int snd_register_device(int type, struct snd_card *card, int dev, snd_minors[minor] = preg; if (card) device = card->dev; - preg->dev = device_create(sound_class, device, MKDEV(major, minor), - "%s", name); - if (preg->dev) - dev_set_drvdata(preg->dev, private_data); + preg->class_dev = class_device_create(sound_class, NULL, + MKDEV(major, minor), + device, "%s", name); + if (preg->class_dev) + class_set_devdata(preg->class_dev, private_data); mutex_unlock(&sound_mutex); return 0; @@ -316,7 +320,7 @@ int snd_unregister_device(int type, struct snd_card *card, int dev) return -EINVAL; } - device_destroy(sound_class, MKDEV(major, minor)); + class_device_destroy(sound_class, MKDEV(major, minor)); kfree(snd_minors[minor]); snd_minors[minor] = NULL; @@ -327,15 +331,15 @@ int snd_unregister_device(int type, struct snd_card *card, int dev) EXPORT_SYMBOL(snd_unregister_device); int snd_add_device_sysfs_file(int type, struct snd_card *card, int dev, - struct device_attribute *attr) + const struct class_device_attribute *attr) { int minor, ret = -EINVAL; - struct device *d; + struct class_device *cdev; mutex_lock(&sound_mutex); minor = find_snd_minor(type, card, dev); - if (minor >= 0 && (d = snd_minors[minor]->dev) != NULL) - ret = device_create_file(d, attr); + if (minor >= 0 && (cdev = snd_minors[minor]->class_dev) != NULL) + ret = class_device_create_file(cdev, attr); mutex_unlock(&sound_mutex); return ret; diff --git a/trunk/sound/drivers/mpu401/mpu401_uart.c b/trunk/sound/drivers/mpu401/mpu401_uart.c index 3daa9fa56c0b..4bf07ca9b17d 100644 --- a/trunk/sound/drivers/mpu401/mpu401_uart.c +++ b/trunk/sound/drivers/mpu401/mpu401_uart.c @@ -125,10 +125,12 @@ static void _snd_mpu401_uart_interrupt(struct snd_mpu401 *mpu) * snd_mpu401_uart_interrupt - generic MPU401-UART interrupt handler * @irq: the irq number * @dev_id: mpu401 instance + * @regs: the reigster * * Processes the interrupt for MPU401-UART i/o. */ -irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id) +irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { struct snd_mpu401 *mpu = dev_id; @@ -144,10 +146,12 @@ EXPORT_SYMBOL(snd_mpu401_uart_interrupt); * snd_mpu401_uart_interrupt_tx - generic MPU401-UART transmit irq handler * @irq: the irq number * @dev_id: mpu401 instance + * @regs: the reigster * * Processes the interrupt for MPU401-UART output. */ -irqreturn_t snd_mpu401_uart_interrupt_tx(int irq, void *dev_id) +irqreturn_t snd_mpu401_uart_interrupt_tx(int irq, void *dev_id, + struct pt_regs *regs) { struct snd_mpu401 *mpu = dev_id; diff --git a/trunk/sound/drivers/mtpav.c b/trunk/sound/drivers/mtpav.c index a9ff391258e7..e064d6c5685b 100644 --- a/trunk/sound/drivers/mtpav.c +++ b/trunk/sound/drivers/mtpav.c @@ -570,7 +570,7 @@ static void snd_mtpav_read_bytes(struct mtpav *mcrd) } while (sbyt & SIGS_BYTE); } -static irqreturn_t snd_mtpav_irqh(int irq, void *dev_id) +static irqreturn_t snd_mtpav_irqh(int irq, void *dev_id, struct pt_regs *regs) { struct mtpav *mcard = dev_id; diff --git a/trunk/sound/drivers/mts64.c b/trunk/sound/drivers/mts64.c index 5327c6f841f4..ab8d4effcf9e 100644 --- a/trunk/sound/drivers/mts64.c +++ b/trunk/sound/drivers/mts64.c @@ -838,7 +838,7 @@ static int __devinit snd_mts64_rawmidi_create(struct snd_card *card) /********************************************************************* * parport stuff *********************************************************************/ -static void snd_mts64_interrupt(int irq, void *private) +static void snd_mts64_interrupt(int irq, void *private, struct pt_regs *r) { struct mts64 *mts = ((struct snd_card*)private)->private_data; u16 ret; diff --git a/trunk/sound/drivers/serial-u16550.c b/trunk/sound/drivers/serial-u16550.c index 74028b2219c2..52afb4bd2079 100644 --- a/trunk/sound/drivers/serial-u16550.c +++ b/trunk/sound/drivers/serial-u16550.c @@ -292,7 +292,7 @@ static void snd_uart16550_io_loop(snd_uart16550_t * uart) * Note that some devices need OUT2 to be set before they will generate * interrupts at all. (Possibly tied to an internal pull-up on CTS?) */ -static irqreturn_t snd_uart16550_interrupt(int irq, void *dev_id) +static irqreturn_t snd_uart16550_interrupt(int irq, void *dev_id, struct pt_regs *regs) { snd_uart16550_t *uart; diff --git a/trunk/sound/drivers/vx/vx_core.c b/trunk/sound/drivers/vx/vx_core.c index ed19bc17400b..a60168268ddd 100644 --- a/trunk/sound/drivers/vx/vx_core.c +++ b/trunk/sound/drivers/vx/vx_core.c @@ -537,7 +537,7 @@ static void vx_interrupt(unsigned long private_data) /** * snd_vx_irq_handler - interrupt handler */ -irqreturn_t snd_vx_irq_handler(int irq, void *dev) +irqreturn_t snd_vx_irq_handler(int irq, void *dev, struct pt_regs *regs) { struct vx_core *chip = dev; diff --git a/trunk/sound/isa/Kconfig b/trunk/sound/isa/Kconfig index 57371f1a441f..557c4de22960 100644 --- a/trunk/sound/isa/Kconfig +++ b/trunk/sound/isa/Kconfig @@ -13,7 +13,6 @@ config SND_CS4231_LIB config SND_ADLIB tristate "AdLib FM card" - depends on SND select SND_OPL3_LIB help Say Y here to include support for AdLib FM cards. diff --git a/trunk/sound/isa/ad1816a/ad1816a.c b/trunk/sound/isa/ad1816a/ad1816a.c index 59034507175b..b33a5fb59ec2 100644 --- a/trunk/sound/isa/ad1816a/ad1816a.c +++ b/trunk/sound/isa/ad1816a/ad1816a.c @@ -120,8 +120,6 @@ static int __devinit snd_card_ad1816a_pnp(int dev, struct snd_card_ad1816a *acar struct pnp_resource_table *cfg = kmalloc(sizeof(*cfg), GFP_KERNEL); int err; - if (!cfg) - return -ENOMEM; acard->dev = pnp_request_card_device(card, id->devs[0].id, NULL); if (acard->dev == NULL) { kfree(cfg); diff --git a/trunk/sound/isa/ad1816a/ad1816a_lib.c b/trunk/sound/isa/ad1816a/ad1816a_lib.c index b524e0d9ee44..fd9b61eda0f3 100644 --- a/trunk/sound/isa/ad1816a/ad1816a_lib.c +++ b/trunk/sound/isa/ad1816a/ad1816a_lib.c @@ -315,7 +315,7 @@ static snd_pcm_uframes_t snd_ad1816a_capture_pointer(struct snd_pcm_substream *s } -static irqreturn_t snd_ad1816a_interrupt(int irq, void *dev_id) +static irqreturn_t snd_ad1816a_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct snd_ad1816a *chip = dev_id; unsigned char status; diff --git a/trunk/sound/isa/ad1848/ad1848_lib.c b/trunk/sound/isa/ad1848/ad1848_lib.c index 666b3bcc19f0..a6fbd5d1d62f 100644 --- a/trunk/sound/isa/ad1848/ad1848_lib.c +++ b/trunk/sound/isa/ad1848/ad1848_lib.c @@ -583,7 +583,7 @@ static int snd_ad1848_capture_prepare(struct snd_pcm_substream *substream) return 0; } -static irqreturn_t snd_ad1848_interrupt(int irq, void *dev_id) +static irqreturn_t snd_ad1848_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct snd_ad1848 *chip = dev_id; diff --git a/trunk/sound/isa/cmi8330.c b/trunk/sound/isa/cmi8330.c index d1f6dfcec46e..3c1e9fd56fe0 100644 --- a/trunk/sound/isa/cmi8330.c +++ b/trunk/sound/isa/cmi8330.c @@ -289,8 +289,6 @@ static int __devinit snd_cmi8330_pnp(int dev, struct snd_cmi8330 *acard, struct pnp_resource_table * cfg = kmalloc(sizeof(struct pnp_resource_table), GFP_KERNEL); int err; - if (!cfg) - return -ENOMEM; acard->cap = pnp_request_card_device(card, id->devs[0].id, NULL); if (acard->cap == NULL) { kfree(cfg); diff --git a/trunk/sound/isa/cs423x/cs4231_lib.c b/trunk/sound/isa/cs423x/cs4231_lib.c index 75c7c5f01989..fbb20176cca4 100644 --- a/trunk/sound/isa/cs423x/cs4231_lib.c +++ b/trunk/sound/isa/cs423x/cs4231_lib.c @@ -920,7 +920,7 @@ static void snd_cs4231_overrange(struct snd_cs4231 *chip) chip->capture_substream->runtime->overrange++; } -irqreturn_t snd_cs4231_interrupt(int irq, void *dev_id) +irqreturn_t snd_cs4231_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct snd_cs4231 *chip = dev_id; unsigned char status; diff --git a/trunk/sound/isa/es1688/es1688_lib.c b/trunk/sound/isa/es1688/es1688_lib.c index a2ab99f2ac35..7e985d3bc510 100644 --- a/trunk/sound/isa/es1688/es1688_lib.c +++ b/trunk/sound/isa/es1688/es1688_lib.c @@ -479,7 +479,7 @@ static int snd_es1688_capture_trigger(struct snd_pcm_substream *substream, return snd_es1688_trigger(chip, cmd, 0x0f); } -static irqreturn_t snd_es1688_interrupt(int irq, void *dev_id) +static irqreturn_t snd_es1688_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct snd_es1688 *chip = dev_id; diff --git a/trunk/sound/isa/es18xx.c b/trunk/sound/isa/es18xx.c index 725c115ff97d..85818200333f 100644 --- a/trunk/sound/isa/es18xx.c +++ b/trunk/sound/isa/es18xx.c @@ -754,7 +754,7 @@ static int snd_es18xx_playback_trigger(struct snd_pcm_substream *substream, return snd_es18xx_playback2_trigger(chip, substream, cmd); } -static irqreturn_t snd_es18xx_interrupt(int irq, void *dev_id) +static irqreturn_t snd_es18xx_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct snd_es18xx *chip = dev_id; unsigned char status; @@ -799,7 +799,7 @@ static irqreturn_t snd_es18xx_interrupt(int irq, void *dev_id) /* MPU */ if ((status & MPU_IRQ) && chip->rmidi) - snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data); + snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data, regs); /* Hardware volume */ if (status & HWV_IRQ) { @@ -2154,7 +2154,6 @@ static int __devinit snd_audiodrive_pnpc(int dev, struct snd_audiodrive *acard, } /* Control port initialization */ if (pnp_activate_dev(acard->devc) < 0) { - kfree(cfg); snd_printk(KERN_ERR PFX "PnP control configure failure (out of resources?)\n"); return -EAGAIN; } diff --git a/trunk/sound/isa/gus/gus_irq.c b/trunk/sound/isa/gus/gus_irq.c index 537d3cfe41f3..42db37552efb 100644 --- a/trunk/sound/isa/gus/gus_irq.c +++ b/trunk/sound/isa/gus/gus_irq.c @@ -30,7 +30,7 @@ #define STAT_ADD(x) while (0) { ; } #endif -irqreturn_t snd_gus_interrupt(int irq, void *dev_id) +irqreturn_t snd_gus_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct snd_gus_card * gus = dev_id; unsigned char status; diff --git a/trunk/sound/isa/gus/gusmax.c b/trunk/sound/isa/gus/gusmax.c index c1c69e3cbfd0..ac11cae8589a 100644 --- a/trunk/sound/isa/gus/gusmax.c +++ b/trunk/sound/isa/gus/gusmax.c @@ -105,9 +105,9 @@ static int __init snd_gusmax_detect(struct snd_gus_card * gus) return 0; } -static irqreturn_t snd_gusmax_interrupt(int irq, void *dev_id) +static irqreturn_t snd_gusmax_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct snd_gusmax *maxcard = dev_id; + struct snd_gusmax *maxcard = (struct snd_gusmax *) dev_id; int loop, max = 5; int handled = 0; @@ -115,12 +115,12 @@ static irqreturn_t snd_gusmax_interrupt(int irq, void *dev_id) loop = 0; if (inb(maxcard->gus_status_reg)) { handled = 1; - snd_gus_interrupt(irq, maxcard->gus); + snd_gus_interrupt(irq, maxcard->gus, regs); loop++; } if (inb(maxcard->pcm_status_reg) & 0x01) { /* IRQ bit is set? */ handled = 1; - snd_cs4231_interrupt(irq, maxcard->cs4231); + snd_cs4231_interrupt(irq, maxcard->cs4231, regs); loop++; } } while (loop && --max > 0); diff --git a/trunk/sound/isa/gus/interwave.c b/trunk/sound/isa/gus/interwave.c index 4ec2d79431fc..ea69f25506fb 100644 --- a/trunk/sound/isa/gus/interwave.c +++ b/trunk/sound/isa/gus/interwave.c @@ -299,9 +299,9 @@ static int __devinit snd_interwave_detect(struct snd_interwave *iwcard, return -ENODEV; } -static irqreturn_t snd_interwave_interrupt(int irq, void *dev_id) +static irqreturn_t snd_interwave_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct snd_interwave *iwcard = dev_id; + struct snd_interwave *iwcard = (struct snd_interwave *) dev_id; int loop, max = 5; int handled = 0; @@ -309,12 +309,12 @@ static irqreturn_t snd_interwave_interrupt(int irq, void *dev_id) loop = 0; if (inb(iwcard->gus_status_reg)) { handled = 1; - snd_gus_interrupt(irq, iwcard->gus); + snd_gus_interrupt(irq, iwcard->gus, regs); loop++; } if (inb(iwcard->pcm_status_reg) & 0x01) { /* IRQ bit is set? */ handled = 1; - snd_cs4231_interrupt(irq, iwcard->cs4231); + snd_cs4231_interrupt(irq, iwcard->cs4231, regs); loop++; } } while (loop && --max > 0); @@ -564,8 +564,6 @@ static int __devinit snd_interwave_pnp(int dev, struct snd_interwave *iwcard, struct pnp_resource_table * cfg = kmalloc(sizeof(struct pnp_resource_table), GFP_KERNEL); int err; - if (!cfg) - return -ENOMEM; iwcard->dev = pnp_request_card_device(card, id->devs[0].id, NULL); if (iwcard->dev == NULL) { kfree(cfg); diff --git a/trunk/sound/isa/opl3sa2.c b/trunk/sound/isa/opl3sa2.c index 419b4ebbf00e..da92bf6c392b 100644 --- a/trunk/sound/isa/opl3sa2.c +++ b/trunk/sound/isa/opl3sa2.c @@ -294,7 +294,7 @@ static int __devinit snd_opl3sa2_detect(struct snd_opl3sa2 *chip) return 0; } -static irqreturn_t snd_opl3sa2_interrupt(int irq, void *dev_id) +static irqreturn_t snd_opl3sa2_interrupt(int irq, void *dev_id, struct pt_regs *regs) { unsigned short status; struct snd_opl3sa2 *chip = dev_id; @@ -312,12 +312,12 @@ static irqreturn_t snd_opl3sa2_interrupt(int irq, void *dev_id) if ((status & 0x10) && chip->rmidi != NULL) { handled = 1; - snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data); + snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data, regs); } if (status & 0x07) { /* TI,CI,PI */ handled = 1; - snd_cs4231_interrupt(irq, chip->cs4231); + snd_cs4231_interrupt(irq, chip->cs4231, regs); } if (status & 0x40) { /* hardware volume change */ diff --git a/trunk/sound/isa/opti9xx/opti92x-ad1848.c b/trunk/sound/isa/opti9xx/opti92x-ad1848.c index df227377c333..9d528ae00bff 100644 --- a/trunk/sound/isa/opti9xx/opti92x-ad1848.c +++ b/trunk/sound/isa/opti9xx/opti92x-ad1848.c @@ -1090,7 +1090,7 @@ static void snd_opti93x_overrange(struct snd_opti93x *chip) spin_unlock_irqrestore(&chip->lock, flags); } -static irqreturn_t snd_opti93x_interrupt(int irq, void *dev_id) +static irqreturn_t snd_opti93x_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct snd_opti93x *codec = dev_id; unsigned char status; @@ -1683,8 +1683,6 @@ static int __init snd_card_opti9xx_pnp(struct snd_opti9xx *chip, struct pnp_card struct pnp_resource_table *cfg = kmalloc(sizeof(*cfg), GFP_KERNEL); int err; - if (!cfg) - return -ENOMEM; chip->dev = pnp_request_card_device(card, pid->devs[0].id, NULL); if (chip->dev == NULL) { kfree(cfg); diff --git a/trunk/sound/isa/sb/es968.c b/trunk/sound/isa/sb/es968.c index d4b218726ce7..d4d65b84265a 100644 --- a/trunk/sound/isa/sb/es968.c +++ b/trunk/sound/isa/sb/es968.c @@ -70,7 +70,8 @@ MODULE_DEVICE_TABLE(pnp_card, snd_es968_pnpids); #define DRIVER_NAME "snd-card-es968" -static irqreturn_t snd_card_es968_interrupt(int irq, void *dev_id) +static irqreturn_t snd_card_es968_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { struct snd_sb *chip = dev_id; diff --git a/trunk/sound/isa/sb/sb16_main.c b/trunk/sound/isa/sb/sb16_main.c index 383911b9e74d..f183f1845a36 100644 --- a/trunk/sound/isa/sb/sb16_main.c +++ b/trunk/sound/isa/sb/sb16_main.c @@ -395,7 +395,7 @@ static int snd_sb16_capture_trigger(struct snd_pcm_substream *substream, return result; } -irqreturn_t snd_sb16dsp_interrupt(int irq, void *dev_id) +irqreturn_t snd_sb16dsp_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct snd_sb *chip = dev_id; unsigned char status; @@ -405,7 +405,7 @@ irqreturn_t snd_sb16dsp_interrupt(int irq, void *dev_id) status = snd_sbmixer_read(chip, SB_DSP4_IRQSTATUS); spin_unlock(&chip->mixer_lock); if ((status & SB_IRQTYPE_MPUIN) && chip->rmidi_callback) - chip->rmidi_callback(irq, chip->rmidi->private_data); + chip->rmidi_callback(irq, chip->rmidi->private_data, regs); if (status & SB_IRQTYPE_8BIT) { ok = 0; if (chip->mode & SB_MODE_PLAYBACK_8) { diff --git a/trunk/sound/isa/sb/sb8.c b/trunk/sound/isa/sb/sb8.c index 268ebd34703e..141400c01426 100644 --- a/trunk/sound/isa/sb/sb8.c +++ b/trunk/sound/isa/sb/sb8.c @@ -63,7 +63,7 @@ struct snd_sb8 { struct snd_sb *chip; }; -static irqreturn_t snd_sb8_interrupt(int irq, void *dev_id) +static irqreturn_t snd_sb8_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct snd_sb *chip = dev_id; diff --git a/trunk/sound/isa/sb/sb_common.c b/trunk/sound/isa/sb/sb_common.c index c62a9e3d2ae4..f17de2bdd9e0 100644 --- a/trunk/sound/isa/sb/sb_common.c +++ b/trunk/sound/isa/sb/sb_common.c @@ -205,7 +205,7 @@ static int snd_sbdsp_dev_free(struct snd_device *device) int snd_sbdsp_create(struct snd_card *card, unsigned long port, int irq, - irq_handler_t irq_handler, + irqreturn_t (*irq_handler)(int, void *, struct pt_regs *), int dma8, int dma16, unsigned short hardware, diff --git a/trunk/sound/isa/sgalaxy.c b/trunk/sound/isa/sgalaxy.c index 4fcd0f4e868c..8742fa517491 100644 --- a/trunk/sound/isa/sgalaxy.c +++ b/trunk/sound/isa/sgalaxy.c @@ -109,7 +109,7 @@ static int __init snd_sgalaxy_sbdsp_command(unsigned long port, unsigned char va return 0; } -static irqreturn_t snd_sgalaxy_dummy_interrupt(int irq, void *dev_id) +static irqreturn_t snd_sgalaxy_dummy_interrupt(int irq, void *dev_id, struct pt_regs *regs) { return IRQ_NONE; } diff --git a/trunk/sound/isa/wavefront/wavefront.c b/trunk/sound/isa/wavefront/wavefront.c index 85db535aea9b..a8f8d2fa9d76 100644 --- a/trunk/sound/isa/wavefront/wavefront.c +++ b/trunk/sound/isa/wavefront/wavefront.c @@ -263,7 +263,9 @@ snd_wavefront_pnp (int dev, snd_wavefront_card_t *acard, struct pnp_card_link *c #endif /* CONFIG_PNP */ -static irqreturn_t snd_wavefront_ics2115_interrupt(int irq, void *dev_id) +static irqreturn_t snd_wavefront_ics2115_interrupt(int irq, + void *dev_id, + struct pt_regs *regs) { snd_wavefront_card_t *acard; diff --git a/trunk/sound/mips/au1x00.c b/trunk/sound/mips/au1x00.c index 8a61a1191861..ff6e6fc198a1 100644 --- a/trunk/sound/mips/au1x00.c +++ b/trunk/sound/mips/au1x00.c @@ -220,7 +220,7 @@ au1000_dma_start(struct audio_stream *stream) } static irqreturn_t -au1000_dma_interrupt(int irq, void *dev_id) +au1000_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct audio_stream *stream = (struct audio_stream *) dev_id; struct snd_pcm_substream *substream = stream->substream; diff --git a/trunk/sound/oss/ad1816.c b/trunk/sound/oss/ad1816.c index caabf31193f7..29057836c644 100644 --- a/trunk/sound/oss/ad1816.c +++ b/trunk/sound/oss/ad1816.c @@ -521,7 +521,7 @@ static struct audio_driver ad1816_audio_driver = /* Interrupt handler */ -static irqreturn_t ad1816_interrupt (int irq, void *dev_id) +static irqreturn_t ad1816_interrupt (int irq, void *dev_id, struct pt_regs *dummy) { unsigned char status; ad1816_info *devc = (ad1816_info *)dev_id; diff --git a/trunk/sound/oss/ad1848.c b/trunk/sound/oss/ad1848.c index 0ffa9970bf0f..257b7536fb18 100644 --- a/trunk/sound/oss/ad1848.c +++ b/trunk/sound/oss/ad1848.c @@ -195,7 +195,7 @@ static void ad1848_halt(int dev); static void ad1848_halt_input(int dev); static void ad1848_halt_output(int dev); static void ad1848_trigger(int dev, int bits); -static irqreturn_t adintr(int irq, void *dev_id); +static irqreturn_t adintr(int irq, void *dev_id, struct pt_regs *dummy); #ifndef EXCLUDE_TIMERS static int ad1848_tmr_install(int dev); @@ -2196,7 +2196,7 @@ void ad1848_unload(int io_base, int irq, int dma_playback, int dma_capture, int printk(KERN_ERR "ad1848: Can't find device to be unloaded. Base=%x\n", io_base); } -static irqreturn_t adintr(int irq, void *dev_id) +static irqreturn_t adintr(int irq, void *dev_id, struct pt_regs *dummy) { unsigned char status; ad1848_info *devc; diff --git a/trunk/sound/oss/ad1889.c b/trunk/sound/oss/ad1889.c index 09263d72a519..f56f870b4840 100644 --- a/trunk/sound/oss/ad1889.c +++ b/trunk/sound/oss/ad1889.c @@ -929,7 +929,7 @@ static struct pci_device_id ad1889_id_tbl[] = { }; MODULE_DEVICE_TABLE(pci, ad1889_id_tbl); -static irqreturn_t ad1889_interrupt(int irq, void *dev_id) +static irqreturn_t ad1889_interrupt(int irq, void *dev_id, struct pt_regs *regs) { u32 stat; ad1889_dev_t *dev = (ad1889_dev_t *)dev_id; diff --git a/trunk/sound/oss/btaudio.c b/trunk/sound/oss/btaudio.c index 6ad384114239..324a81fd3a3b 100644 --- a/trunk/sound/oss/btaudio.c +++ b/trunk/sound/oss/btaudio.c @@ -824,7 +824,7 @@ static char *irq_name[] = { "", "", "", "OFLOW", "", "", "", "", "", "", "", "RISCI", "FBUS", "FTRGT", "FDSR", "PPERR", "RIPERR", "PABORT", "OCERR", "SCERR" }; -static irqreturn_t btaudio_irq(int irq, void *dev_id) +static irqreturn_t btaudio_irq(int irq, void *dev_id, struct pt_regs * regs) { int count = 0; u32 stat,astat; diff --git a/trunk/sound/oss/cs46xx.c b/trunk/sound/oss/cs46xx.c index b1c5d8286e40..43193581f836 100644 --- a/trunk/sound/oss/cs46xx.c +++ b/trunk/sound/oss/cs46xx.c @@ -779,7 +779,7 @@ static unsigned int cs_set_adc_rate(struct cs_state *state, unsigned int rate) rate = 48000 / 9; /* - * We cannot capture at at rate greater than the Input Rate (48000). + * We can not capture at at rate greater than the Input Rate (48000). * Return an error if an attempt is made to stray outside that limit. */ if (rate > 48000) @@ -1613,7 +1613,7 @@ static void cs_handle_midi(struct cs_card *card) wake_up(&card->midi.owait); } -static irqreturn_t cs_interrupt(int irq, void *dev_id) +static irqreturn_t cs_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct cs_card *card = (struct cs_card *)dev_id; /* Single channel card */ @@ -4754,8 +4754,8 @@ static int cs_hardware_init(struct cs_card *card) mdelay(5 * cs_laptop_wait); /* Shouldnt be needed ?? */ /* -* If we are resuming under 2.2.x then we cannot schedule a timeout, -* so just spin the CPU. +* If we are resuming under 2.2.x then we can not schedule a timeout. +* so, just spin the CPU. */ if (card->pm.flags & CS46XX_PM_IDLE) { /* diff --git a/trunk/sound/oss/dmasound/dmasound_atari.c b/trunk/sound/oss/dmasound/dmasound_atari.c index 285239d64b82..dc31373069a5 100644 --- a/trunk/sound/oss/dmasound/dmasound_atari.c +++ b/trunk/sound/oss/dmasound/dmasound_atari.c @@ -133,7 +133,7 @@ static int FalconSetFormat(int format); static int FalconSetVolume(int volume); static void AtaPlayNextFrame(int index); static void AtaPlay(void); -static irqreturn_t AtaInterrupt(int irq, void *dummy); +static irqreturn_t AtaInterrupt(int irq, void *dummy, struct pt_regs *fp); /*** Mid level stuff *********************************************************/ @@ -1257,7 +1257,7 @@ static void AtaPlay(void) } -static irqreturn_t AtaInterrupt(int irq, void *dummy) +static irqreturn_t AtaInterrupt(int irq, void *dummy, struct pt_regs *fp) { #if 0 /* ++TeSche: if you should want to test this... */ diff --git a/trunk/sound/oss/dmasound/dmasound_awacs.c b/trunk/sound/oss/dmasound/dmasound_awacs.c index 37773b1deea5..9ae659f82430 100644 --- a/trunk/sound/oss/dmasound/dmasound_awacs.c +++ b/trunk/sound/oss/dmasound/dmasound_awacs.c @@ -281,9 +281,9 @@ static int PMacSetFormat(int format); static int PMacSetVolume(int volume); static void PMacPlay(void); static void PMacRecord(void); -static irqreturn_t pmac_awacs_tx_intr(int irq, void *devid); -static irqreturn_t pmac_awacs_rx_intr(int irq, void *devid); -static irqreturn_t pmac_awacs_intr(int irq, void *devid); +static irqreturn_t pmac_awacs_tx_intr(int irq, void *devid, struct pt_regs *regs); +static irqreturn_t pmac_awacs_rx_intr(int irq, void *devid, struct pt_regs *regs); +static irqreturn_t pmac_awacs_intr(int irq, void *devid, struct pt_regs *regs); static void awacs_write(int val); static int awacs_get_volume(int reg, int lshift); static int awacs_volume_setter(int volume, int n, int mute, int lshift); @@ -398,7 +398,7 @@ read_audio_gpio(int gpio_addr) * Headphone interrupt via GPIO (Tumbler, Snapper, DACA) */ static irqreturn_t -headphone_intr(int irq, void *devid) +headphone_intr(int irq, void *devid, struct pt_regs *regs) { unsigned long flags; @@ -465,7 +465,7 @@ tas_dmasound_init(void) val = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, gpio_headphone_detect, 0); pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, gpio_headphone_detect, val | 0x80); /* Trigger it */ - headphone_intr(0, NULL); + headphone_intr(0,NULL,NULL); } } if (!gpio_headphone_irq) { @@ -1037,7 +1037,7 @@ static void PMacRecord(void) */ static irqreturn_t -pmac_awacs_tx_intr(int irq, void *devid) +pmac_awacs_tx_intr(int irq, void *devid, struct pt_regs *regs) { int i = write_sq.front; int stat; @@ -1129,7 +1129,7 @@ printk("dmasound_pmac: tx-irq: xfer died - patching it up...\n") ; static irqreturn_t -pmac_awacs_rx_intr(int irq, void *devid) +pmac_awacs_rx_intr(int irq, void *devid, struct pt_regs *regs) { int stat ; /* For some reason on my PowerBook G3, I get one interrupt @@ -1212,7 +1212,7 @@ printk("dmasound_pmac: rx-irq: DIED - attempting resurection\n"); static irqreturn_t -pmac_awacs_intr(int irq, void *devid) +pmac_awacs_intr(int irq, void *devid, struct pt_regs *regs) { int ctrl; int status; @@ -1499,7 +1499,7 @@ static int awacs_sleep_notify(struct pmu_sleep_notifier *self, int when) write_audio_gpio(gpio_audio_reset, !gpio_audio_reset_pol); msleep(150); tas_leave_sleep(); /* Stub for now */ - headphone_intr(0, NULL); + headphone_intr(0,NULL,NULL); break; case AWACS_DACA: msleep(10); /* Check this !!! */ diff --git a/trunk/sound/oss/dmasound/dmasound_paula.c b/trunk/sound/oss/dmasound/dmasound_paula.c index 90fc058e1159..68e1d8f6c359 100644 --- a/trunk/sound/oss/dmasound/dmasound_paula.c +++ b/trunk/sound/oss/dmasound/dmasound_paula.c @@ -82,7 +82,7 @@ static int AmiSetVolume(int volume); static int AmiSetTreble(int treble); static void AmiPlayNextFrame(int index); static void AmiPlay(void); -static irqreturn_t AmiInterrupt(int irq, void *dummy); +static irqreturn_t AmiInterrupt(int irq, void *dummy, struct pt_regs *fp); #ifdef CONFIG_HEARTBEAT @@ -556,7 +556,7 @@ static void AmiPlay(void) } -static irqreturn_t AmiInterrupt(int irq, void *dummy) +static irqreturn_t AmiInterrupt(int irq, void *dummy, struct pt_regs *fp) { int minframes = 1; diff --git a/trunk/sound/oss/dmasound/dmasound_q40.c b/trunk/sound/oss/dmasound/dmasound_q40.c index b3379dd7ca5e..e2081f32b0c4 100644 --- a/trunk/sound/oss/dmasound/dmasound_q40.c +++ b/trunk/sound/oss/dmasound/dmasound_q40.c @@ -48,8 +48,8 @@ static int Q40SetFormat(int format); static int Q40SetVolume(int volume); static void Q40PlayNextFrame(int index); static void Q40Play(void); -static irqreturn_t Q40StereoInterrupt(int irq, void *dummy); -static irqreturn_t Q40MonoInterrupt(int irq, void *dummy); +static irqreturn_t Q40StereoInterrupt(int irq, void *dummy, struct pt_regs *fp); +static irqreturn_t Q40MonoInterrupt(int irq, void *dummy, struct pt_regs *fp); static void Q40Interrupt(void); @@ -451,7 +451,7 @@ static void Q40Play(void) spin_unlock_irqrestore(&dmasound.lock, flags); } -static irqreturn_t Q40StereoInterrupt(int irq, void *dummy) +static irqreturn_t Q40StereoInterrupt(int irq, void *dummy, struct pt_regs *fp) { spin_lock(&dmasound.lock); if (q40_sc>1){ @@ -463,7 +463,7 @@ static irqreturn_t Q40StereoInterrupt(int irq, void *dummy) spin_unlock(&dmasound.lock); return IRQ_HANDLED; } -static irqreturn_t Q40MonoInterrupt(int irq, void *dummy) +static irqreturn_t Q40MonoInterrupt(int irq, void *dummy, struct pt_regs *fp) { spin_lock(&dmasound.lock); if (q40_sc>0){ diff --git a/trunk/sound/oss/emu10k1/irqmgr.c b/trunk/sound/oss/emu10k1/irqmgr.c index fb2ce638f01c..d19b464ba01b 100644 --- a/trunk/sound/oss/emu10k1/irqmgr.c +++ b/trunk/sound/oss/emu10k1/irqmgr.c @@ -37,7 +37,7 @@ /* Interrupt handler */ -irqreturn_t emu10k1_interrupt(int irq, void *dev_id) +irqreturn_t emu10k1_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct emu10k1_card *card = (struct emu10k1_card *) dev_id; u32 irqstatus, irqstatus_tmp; diff --git a/trunk/sound/oss/emu10k1/main.c b/trunk/sound/oss/emu10k1/main.c index 6c59df7b0001..c4ce94d6e10c 100644 --- a/trunk/sound/oss/emu10k1/main.c +++ b/trunk/sound/oss/emu10k1/main.c @@ -167,7 +167,7 @@ extern struct file_operations emu10k1_midi_fops; static struct midi_operations emu10k1_midi_operations; #endif -extern irqreturn_t emu10k1_interrupt(int, void *); +extern irqreturn_t emu10k1_interrupt(int, void *, struct pt_regs *s); static int __devinit emu10k1_audio_init(struct emu10k1_card *card) { diff --git a/trunk/sound/oss/es1371.c b/trunk/sound/oss/es1371.c index ddf6b0a0bca5..a2ffe723dad5 100644 --- a/trunk/sound/oss/es1371.c +++ b/trunk/sound/oss/es1371.c @@ -1100,9 +1100,9 @@ static void es1371_handle_midi(struct es1371_state *s) outb((s->midi.ocnt > 0) ? UCTRL_RXINTEN | UCTRL_ENA_TXINT : UCTRL_RXINTEN, s->io+ES1371_REG_UART_CONTROL); } -static irqreturn_t es1371_interrupt(int irq, void *dev_id) +static irqreturn_t es1371_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct es1371_state *s = dev_id; + struct es1371_state *s = (struct es1371_state *)dev_id; unsigned int intsrc, sctl; /* fastpath out, to ease interrupt sharing */ diff --git a/trunk/sound/oss/hal2.c b/trunk/sound/oss/hal2.c index 784bdd707055..80ab402dae9a 100644 --- a/trunk/sound/oss/hal2.c +++ b/trunk/sound/oss/hal2.c @@ -370,9 +370,9 @@ static void hal2_adc_interrupt(struct hal2_codec *adc) wake_up(&adc->dma_wait); } -static irqreturn_t hal2_interrupt(int irq, void *dev_id) +static irqreturn_t hal2_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct hal2_card *hal2 = dev_id; + struct hal2_card *hal2 = (struct hal2_card*)dev_id; irqreturn_t ret = IRQ_NONE; /* decide what caused this interrupt */ diff --git a/trunk/sound/oss/i810_audio.c b/trunk/sound/oss/i810_audio.c index 240cc7939b69..ddcddc2347f7 100644 --- a/trunk/sound/oss/i810_audio.c +++ b/trunk/sound/oss/i810_audio.c @@ -1523,9 +1523,9 @@ static void i810_channel_interrupt(struct i810_card *card) #endif } -static irqreturn_t i810_interrupt(int irq, void *dev_id) +static irqreturn_t i810_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct i810_card *card = dev_id; + struct i810_card *card = (struct i810_card *)dev_id; u32 status; spin_lock(&card->lock); diff --git a/trunk/sound/oss/mpu401.c b/trunk/sound/oss/mpu401.c index e96220541971..162d07cc489f 100644 --- a/trunk/sound/oss/mpu401.c +++ b/trunk/sound/oss/mpu401.c @@ -432,10 +432,10 @@ static void mpu401_input_loop(struct mpu_config *devc) devc->m_busy = 0; } -static irqreturn_t mpuintr(int irq, void *dev_id) +static irqreturn_t mpuintr(int irq, void *dev_id, struct pt_regs *dummy) { struct mpu_config *devc; - int dev = (int)(unsigned long) dev_id; + int dev = (int) dev_id; int handled = 0; devc = &dev_conf[dev]; diff --git a/trunk/sound/oss/mpu401.h b/trunk/sound/oss/mpu401.h index 0ad1e9ee74f7..84c0e9522ef7 100644 --- a/trunk/sound/oss/mpu401.h +++ b/trunk/sound/oss/mpu401.h @@ -3,9 +3,10 @@ int probe_uart401 (struct address_info *hw_config, struct module *owner); void unload_uart401 (struct address_info *hw_config); -irqreturn_t uart401intr (int irq, void *dev_id); +irqreturn_t uart401intr (int irq, void *dev_id, struct pt_regs * dummy); /* From mpu401.c */ int probe_mpu401(struct address_info *hw_config, struct resource *ports); int attach_mpu401(struct address_info * hw_config, struct module *owner); void unload_mpu401(struct address_info *hw_info); + diff --git a/trunk/sound/oss/msnd_pinnacle.c b/trunk/sound/oss/msnd_pinnacle.c index d5146790f5e3..6d7763dae895 100644 --- a/trunk/sound/oss/msnd_pinnacle.c +++ b/trunk/sound/oss/msnd_pinnacle.c @@ -1087,7 +1087,7 @@ static __inline__ void eval_dsp_msg(register WORD wMessage) } } -static irqreturn_t intr(int irq, void *dev_id) +static irqreturn_t intr(int irq, void *dev_id, struct pt_regs *regs) { /* Send ack to DSP */ msnd_inb(dev.io + HP_RXL); diff --git a/trunk/sound/oss/nec_vrc5477.c b/trunk/sound/oss/nec_vrc5477.c index da9728e17727..6f7f2f0423e4 100644 --- a/trunk/sound/oss/nec_vrc5477.c +++ b/trunk/sound/oss/nec_vrc5477.c @@ -848,7 +848,7 @@ static inline void vrc5477_ac97_dac_interrupt(struct vrc5477_ac97_state *s) wake_up_interruptible(&dac->wait); } -static irqreturn_t vrc5477_ac97_interrupt(int irq, void *dev_id) +static irqreturn_t vrc5477_ac97_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct vrc5477_ac97_state *s = (struct vrc5477_ac97_state *)dev_id; u32 irqStatus; diff --git a/trunk/sound/oss/nm256.h b/trunk/sound/oss/nm256.h index 1dade9033995..21e07b5081f2 100644 --- a/trunk/sound/oss/nm256.h +++ b/trunk/sound/oss/nm256.h @@ -115,7 +115,7 @@ struct nm256_info int has_irq; /* The card interrupt service routine. */ - irq_handler_t introutine; + irqreturn_t (*introutine) (int, void *, struct pt_regs *); /* Current audio config, cached. */ struct sinfo { diff --git a/trunk/sound/oss/nm256_audio.c b/trunk/sound/oss/nm256_audio.c index 44cd15505001..7760dddf2b32 100644 --- a/trunk/sound/oss/nm256_audio.c +++ b/trunk/sound/oss/nm256_audio.c @@ -45,8 +45,8 @@ static struct audio_driver nm256_audio_driver; static int nm256_grabInterrupt (struct nm256_info *card); static int nm256_releaseInterrupt (struct nm256_info *card); -static irqreturn_t nm256_interrupt (int irq, void *dev_id); -static irqreturn_t nm256_interrupt_zx (int irq, void *dev_id); +static irqreturn_t nm256_interrupt (int irq, void *dev_id, struct pt_regs *dummy); +static irqreturn_t nm256_interrupt_zx (int irq, void *dev_id, struct pt_regs *dummy); /* These belong in linux/pci.h. */ #define PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO 0x8005 @@ -526,7 +526,7 @@ nm256_initHw (struct nm256_info *card) */ static irqreturn_t -nm256_interrupt (int irq, void *dev_id) +nm256_interrupt (int irq, void *dev_id, struct pt_regs *dummy) { struct nm256_info *card = (struct nm256_info *)dev_id; u16 status; @@ -629,7 +629,7 @@ nm256_interrupt (int irq, void *dev_id) */ static irqreturn_t -nm256_interrupt_zx (int irq, void *dev_id) +nm256_interrupt_zx (int irq, void *dev_id, struct pt_regs *dummy) { struct nm256_info *card = (struct nm256_info *)dev_id; u32 status; diff --git a/trunk/sound/oss/pas2_card.c b/trunk/sound/oss/pas2_card.c index 25f3a22c52ee..4ebb9638746e 100644 --- a/trunk/sound/oss/pas2_card.c +++ b/trunk/sound/oss/pas2_card.c @@ -88,7 +88,7 @@ void pas_write(unsigned char data, int ioaddr) /******************* Begin of the Interrupt Handler ********************/ -static irqreturn_t pasintr(int irq, void *dev_id) +static irqreturn_t pasintr(int irq, void *dev_id, struct pt_regs *dummy) { int status; diff --git a/trunk/sound/oss/sb_common.c b/trunk/sound/oss/sb_common.c index 440537c72604..bbe5b7596d0e 100644 --- a/trunk/sound/oss/sb_common.c +++ b/trunk/sound/oss/sb_common.c @@ -132,7 +132,7 @@ static void sb_intr (sb_devc *devc) if (src & 4) /* MPU401 interrupt */ if(devc->midi_irq_cookie) - uart401intr(devc->irq, devc->midi_irq_cookie); + uart401intr(devc->irq, devc->midi_irq_cookie, NULL); if (!(src & 3)) return; /* Not a DSP interrupt */ @@ -200,7 +200,7 @@ static void pci_intr(sb_devc *devc) sb_intr(devc); } -static irqreturn_t sbintr(int irq, void *dev_id) +static irqreturn_t sbintr(int irq, void *dev_id, struct pt_regs *dummy) { sb_devc *devc = dev_id; diff --git a/trunk/sound/oss/sh_dac_audio.c b/trunk/sound/oss/sh_dac_audio.c index 51f554154c48..83ff8a71f716 100644 --- a/trunk/sound/oss/sh_dac_audio.c +++ b/trunk/sound/oss/sh_dac_audio.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #define MODNAME "sh_dac_audio" @@ -263,7 +263,7 @@ struct file_operations dac_audio_fops = { .release = dac_audio_release, }; -static irqreturn_t timer1_interrupt(int irq, void *dev) +static irqreturn_t timer1_interrupt(int irq, void *dev, struct pt_regs *regs) { unsigned long timer_status; diff --git a/trunk/sound/oss/soundcard.c b/trunk/sound/oss/soundcard.c index 75c5e745705f..2344d09c7114 100644 --- a/trunk/sound/oss/soundcard.c +++ b/trunk/sound/oss/soundcard.c @@ -557,17 +557,17 @@ static int __init oss_init(void) sound_dmap_flag = (dmabuf > 0 ? 1 : 0); for (i = 0; i < sizeof (dev_list) / sizeof *dev_list; i++) { - device_create(sound_class, NULL, - MKDEV(SOUND_MAJOR, dev_list[i].minor), - "%s", dev_list[i].name); + class_device_create(sound_class, NULL, + MKDEV(SOUND_MAJOR, dev_list[i].minor), + NULL, "%s", dev_list[i].name); if (!dev_list[i].num) continue; for (j = 1; j < *dev_list[i].num; j++) - device_create(sound_class, NULL, - MKDEV(SOUND_MAJOR, dev_list[i].minor + (j*0x10)), - "%s%d", dev_list[i].name, j); + class_device_create(sound_class, NULL, + MKDEV(SOUND_MAJOR, dev_list[i].minor + (j*0x10)), + NULL, "%s%d", dev_list[i].name, j); } if (sound_nblocks >= 1024) @@ -581,11 +581,11 @@ static void __exit oss_cleanup(void) int i, j; for (i = 0; i < sizeof (dev_list) / sizeof *dev_list; i++) { - device_destroy(sound_class, MKDEV(SOUND_MAJOR, dev_list[i].minor)); + class_device_destroy(sound_class, MKDEV(SOUND_MAJOR, dev_list[i].minor)); if (!dev_list[i].num) continue; for (j = 1; j < *dev_list[i].num; j++) - device_destroy(sound_class, MKDEV(SOUND_MAJOR, dev_list[i].minor + (j*0x10))); + class_device_destroy(sound_class, MKDEV(SOUND_MAJOR, dev_list[i].minor + (j*0x10))); } unregister_sound_special(1); diff --git a/trunk/sound/oss/swarm_cs4297a.c b/trunk/sound/oss/swarm_cs4297a.c index 471c274c5000..3edf8d4ac998 100644 --- a/trunk/sound/oss/swarm_cs4297a.c +++ b/trunk/sound/oss/swarm_cs4297a.c @@ -2505,7 +2505,7 @@ static /*const */ struct file_operations cs4297a_audio_fops = { .release = cs4297a_release, }; -static void cs4297a_interrupt(int irq, void *dev_id) +static void cs4297a_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct cs4297a_state *s = (struct cs4297a_state *) dev_id; u32 status; diff --git a/trunk/sound/oss/trident.c b/trunk/sound/oss/trident.c index 7a363a178afd..147c816a1f22 100644 --- a/trunk/sound/oss/trident.c +++ b/trunk/sound/oss/trident.c @@ -1811,7 +1811,7 @@ cyber_address_interrupt(struct trident_card *card) } static irqreturn_t -trident_interrupt(int irq, void *dev_id) +trident_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct trident_card *card = (struct trident_card *) dev_id; u32 event; diff --git a/trunk/sound/oss/uart401.c b/trunk/sound/oss/uart401.c index a446b826d5fc..8e18b6e25818 100644 --- a/trunk/sound/oss/uart401.c +++ b/trunk/sound/oss/uart401.c @@ -96,7 +96,7 @@ static void uart401_input_loop(uart401_devc * devc) printk(KERN_WARNING "Too much work in interrupt on uart401 (0x%X). UART jabbering ??\n", devc->base); } -irqreturn_t uart401intr(int irq, void *dev_id) +irqreturn_t uart401intr(int irq, void *dev_id, struct pt_regs *dummy) { uart401_devc *devc = dev_id; diff --git a/trunk/sound/oss/uart6850.c b/trunk/sound/oss/uart6850.c index f3f914aa92ee..501d3e654a67 100644 --- a/trunk/sound/oss/uart6850.c +++ b/trunk/sound/oss/uart6850.c @@ -104,7 +104,7 @@ static void uart6850_input_loop(void) } } -static irqreturn_t m6850intr(int irq, void *dev_id) +static irqreturn_t m6850intr(int irq, void *dev_id, struct pt_regs *dummy) { if (input_avail()) uart6850_input_loop(); diff --git a/trunk/sound/oss/via82cxxx_audio.c b/trunk/sound/oss/via82cxxx_audio.c index 17837d4b5ed3..2fec42fc3482 100644 --- a/trunk/sound/oss/via82cxxx_audio.c +++ b/trunk/sound/oss/via82cxxx_audio.c @@ -1912,7 +1912,7 @@ static void via_intr_channel (struct via_info *card, struct via_channel *chan) } -static irqreturn_t via_interrupt(int irq, void *dev_id) +static irqreturn_t via_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct via_info *card = dev_id; u32 status32; @@ -1927,7 +1927,7 @@ static irqreturn_t via_interrupt(int irq, void *dev_id) { #ifdef CONFIG_MIDI_VIA82CXXX if (card->midi_devc) - uart401intr(irq, card->midi_devc); + uart401intr(irq, card->midi_devc, regs); #endif return IRQ_HANDLED; } @@ -1950,7 +1950,7 @@ static irqreturn_t via_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -static irqreturn_t via_new_interrupt(int irq, void *dev_id) +static irqreturn_t via_new_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct via_info *card = dev_id; u32 status32; diff --git a/trunk/sound/oss/vidc.c b/trunk/sound/oss/vidc.c index bb4a0969f461..8932d89408ef 100644 --- a/trunk/sound/oss/vidc.c +++ b/trunk/sound/oss/vidc.c @@ -372,7 +372,7 @@ static void vidc_audio_trigger(int dev, int enable_bits) adev->flags |= DMA_ACTIVE; dma_interrupt = vidc_audio_dma_interrupt; - vidc_sound_dma_irq(0, NULL); + vidc_sound_dma_irq(0, NULL, NULL); iomd_writeb(DMA_CR_E | 0x10, IOMD_SD0CR); local_irq_restore(flags); diff --git a/trunk/sound/oss/vidc.h b/trunk/sound/oss/vidc.h index 0d1424751ecd..d5b8064dc565 100644 --- a/trunk/sound/oss/vidc.h +++ b/trunk/sound/oss/vidc.h @@ -33,7 +33,7 @@ extern unsigned long vidc_fill_2x16_s(unsigned long ibuf, unsigned long iend, * DMA Interrupt handler */ -extern irqreturn_t vidc_sound_dma_irq(int irqnr, void *ref); +extern irqreturn_t vidc_sound_dma_irq(int irqnr, void *ref, struct pt_regs *regs); /* * Filler routine pointer diff --git a/trunk/sound/oss/vwsnd.c b/trunk/sound/oss/vwsnd.c index 6dfb9f4b03ec..5f140c7586b3 100644 --- a/trunk/sound/oss/vwsnd.c +++ b/trunk/sound/oss/vwsnd.c @@ -2233,12 +2233,12 @@ static void vwsnd_audio_write_intr(vwsnd_dev_t *devc, unsigned int status) pcm_output(devc, underflown, 0); } -static irqreturn_t vwsnd_audio_intr(int irq, void *dev_id) +static irqreturn_t vwsnd_audio_intr(int irq, void *dev_id, struct pt_regs *regs) { - vwsnd_dev_t *devc = dev_id; + vwsnd_dev_t *devc = (vwsnd_dev_t *) dev_id; unsigned int status; - DBGEV("(irq=%d, dev_id=0x%p)\n", irq, dev_id); + DBGEV("(irq=%d, dev_id=0x%p, regs=0x%p)\n", irq, dev_id, regs); status = li_get_clear_intr_status(&devc->lith); vwsnd_audio_read_intr(devc, status); diff --git a/trunk/sound/oss/waveartist.c b/trunk/sound/oss/waveartist.c index c5bf363d32c2..59a2f28eb5a5 100644 --- a/trunk/sound/oss/waveartist.c +++ b/trunk/sound/oss/waveartist.c @@ -833,7 +833,7 @@ static struct audio_driver waveartist_audio_driver = { static irqreturn_t -waveartist_intr(int irq, void *dev_id) +waveartist_intr(int irq, void *dev_id, struct pt_regs *regs) { wavnc_info *devc = (wavnc_info *)dev_id; int irqstatus, status; diff --git a/trunk/sound/parisc/harmony.c b/trunk/sound/parisc/harmony.c index cf603337b321..ce73f3eae78c 100644 --- a/trunk/sound/parisc/harmony.c +++ b/trunk/sound/parisc/harmony.c @@ -193,7 +193,7 @@ harmony_set_control(struct snd_harmony *h) } static irqreturn_t -snd_harmony_interrupt(int irq, void *dev) +snd_harmony_interrupt(int irq, void *dev, struct pt_regs *regs) { u32 dstatus; struct snd_harmony *h = dev; diff --git a/trunk/sound/pci/ac97/ac97_codec.c b/trunk/sound/pci/ac97/ac97_codec.c index 6577b2325357..a79e91850ba3 100644 --- a/trunk/sound/pci/ac97/ac97_codec.c +++ b/trunk/sound/pci/ac97/ac97_codec.c @@ -570,7 +570,8 @@ int snd_ac97_put_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value ac97->power_up &= ~(1 << (reg>>1)); else ac97->power_up |= 1 << (reg>>1); - update_power_regs(ac97); + if (power_save) + update_power_regs(ac97); } #endif return err; @@ -2336,7 +2337,10 @@ int snd_ac97_update_power(struct snd_ac97 *ac97, int reg, int powerup) } } - if (power_save && !powerup && ac97->power_workq) + if (! power_save) + return 0; + + if (! powerup && ac97->power_workq) /* adjust power-down bits after two seconds delay * (for avoiding loud click noises for many (OSS) apps * that open/close frequently) diff --git a/trunk/sound/pci/ac97/ac97_patch.c b/trunk/sound/pci/ac97/ac97_patch.c index 15be6ba87c82..dc28b111a06d 100644 --- a/trunk/sound/pci/ac97/ac97_patch.c +++ b/trunk/sound/pci/ac97/ac97_patch.c @@ -530,7 +530,7 @@ AC97_ENUM("ALC Headphone Mux", wm9711_enum[1]), AC97_SINGLE("ALC Headphone Volume", AC97_VIDEO, 7, 7, 1), AC97_SINGLE("Out3 Switch", AC97_AUX, 15, 1, 1), -AC97_SINGLE("Out3 ZC Switch", AC97_AUX, 7, 1, 0), +AC97_SINGLE("Out3 ZC Switch", AC97_AUX, 7, 1, 1), AC97_ENUM("Out3 Mux", wm9711_enum[2]), AC97_ENUM("Out3 LR Mux", wm9711_enum[3]), AC97_SINGLE("Out3 Volume", AC97_AUX, 0, 31, 1), @@ -575,14 +575,13 @@ AC97_SINGLE("Playback Attenuate (-6dB) Switch", AC97_MASTER_TONE, 6, 1, 0), AC97_SINGLE("ADC Switch", AC97_REC_GAIN, 15, 1, 1), AC97_ENUM("Capture Volume Steps", wm9711_enum[6]), -AC97_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 63, 1), +AC97_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 15, 1), AC97_SINGLE("Capture ZC Switch", AC97_REC_GAIN, 7, 1, 0), AC97_SINGLE("Mic 1 to Phone Switch", AC97_MIC, 14, 1, 1), AC97_SINGLE("Mic 2 to Phone Switch", AC97_MIC, 13, 1, 1), AC97_ENUM("Mic Select Source", wm9711_enum[7]), -AC97_SINGLE("Mic 1 Volume", AC97_MIC, 8, 31, 1), -AC97_SINGLE("Mic 2 Volume", AC97_MIC, 0, 31, 1), +AC97_SINGLE("Mic 1 Volume", AC97_MIC, 8, 32, 1), AC97_SINGLE("Mic 20dB Boost Switch", AC97_MIC, 7, 1, 0), AC97_SINGLE("Master ZC Switch", AC97_MASTER, 7, 1, 0), diff --git a/trunk/sound/pci/ad1889.c b/trunk/sound/pci/ad1889.c index cbf8331c3d33..0786d0edaca5 100644 --- a/trunk/sound/pci/ad1889.c +++ b/trunk/sound/pci/ad1889.c @@ -596,7 +596,9 @@ static struct snd_pcm_ops snd_ad1889_capture_ops = { }; static irqreturn_t -snd_ad1889_interrupt(int irq, void *dev_id) +snd_ad1889_interrupt(int irq, + void *dev_id, + struct pt_regs *regs) { unsigned long st; struct snd_ad1889 *chip = dev_id; diff --git a/trunk/sound/pci/ali5451/ali5451.c b/trunk/sound/pci/ali5451/ali5451.c index a7edd56542d4..74668398eac5 100644 --- a/trunk/sound/pci/ali5451/ali5451.c +++ b/trunk/sound/pci/ali5451/ali5451.c @@ -1047,7 +1047,9 @@ static void snd_ali_interrupt(struct snd_ali * codec) } -static irqreturn_t snd_ali_card_interrupt(int irq, void *dev_id) +static irqreturn_t snd_ali_card_interrupt(int irq, + void *dev_id, + struct pt_regs *regs) { struct snd_ali *codec = dev_id; @@ -2032,10 +2034,8 @@ static int ali_suspend(struct pci_dev *pci, pm_message_t state) outl(0xffffffff, ALI_REG(chip, ALI_STOP)); spin_unlock_irq(&chip->reg_lock); - pci_disable_device(pci); pci_save_state(pci); - pci_set_power_state(pci, pci_choose_state(pci, state)); return 0; } @@ -2050,15 +2050,8 @@ static int ali_resume(struct pci_dev *pci) if (! im) return 0; - pci_set_power_state(pci, PCI_D0); pci_restore_state(pci); - if (pci_enable_device(pci) < 0) { - printk(KERN_ERR "ali5451: pci_enable_device failed, " - "disabling device\n"); - snd_card_disconnect(card); - return -EIO; - } - pci_set_master(pci); + pci_enable_device(pci); spin_lock_irq(&chip->reg_lock); diff --git a/trunk/sound/pci/als300.c b/trunk/sound/pci/als300.c index 95f70f3cc37e..96cfb8ae5055 100644 --- a/trunk/sound/pci/als300.c +++ b/trunk/sound/pci/als300.c @@ -204,7 +204,8 @@ static int snd_als300_dev_free(struct snd_device *device) return snd_als300_free(chip); } -static irqreturn_t snd_als300_interrupt(int irq, void *dev_id) +static irqreturn_t snd_als300_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { u8 status; struct snd_als300 *chip = dev_id; @@ -235,7 +236,8 @@ static irqreturn_t snd_als300_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -static irqreturn_t snd_als300plus_interrupt(int irq, void *dev_id) +static irqreturn_t snd_als300plus_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { u8 general, mpu, dram; struct snd_als300 *chip = dev_id; @@ -768,9 +770,9 @@ static int snd_als300_suspend(struct pci_dev *pci, pm_message_t state) snd_pcm_suspend_all(chip->pcm); snd_ac97_suspend(chip->ac97); + pci_set_power_state(pci, PCI_D3hot); pci_disable_device(pci); pci_save_state(pci); - pci_set_power_state(pci, pci_choose_state(pci, state)); return 0; } @@ -779,14 +781,9 @@ static int snd_als300_resume(struct pci_dev *pci) struct snd_card *card = pci_get_drvdata(pci); struct snd_als300 *chip = card->private_data; - pci_set_power_state(pci, PCI_D0); pci_restore_state(pci); - if (pci_enable_device(pci) < 0) { - printk(KERN_ERR "als300: pci_enable_device failed, " - "disabling device\n"); - snd_card_disconnect(card); - return -EIO; - } + pci_enable_device(pci); + pci_set_power_state(pci, PCI_D0); pci_set_master(pci); snd_als300_init(chip); diff --git a/trunk/sound/pci/als4000.c b/trunk/sound/pci/als4000.c index 8fb55d3b454b..9e596f750cbd 100644 --- a/trunk/sound/pci/als4000.c +++ b/trunk/sound/pci/als4000.c @@ -385,7 +385,7 @@ static snd_pcm_uframes_t snd_als4000_playback_pointer(struct snd_pcm_substream * * SB IRQ status. * And do we *really* need the lock here for *reading* SB_DSP4_IRQSTATUS?? * */ -static irqreturn_t snd_als4000_interrupt(int irq, void *dev_id) +static irqreturn_t snd_als4000_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct snd_sb *chip = dev_id; unsigned gcr_status; @@ -399,7 +399,7 @@ static irqreturn_t snd_als4000_interrupt(int irq, void *dev_id) if ((gcr_status & 0x40) && (chip->capture_substream)) /* capturing */ snd_pcm_period_elapsed(chip->capture_substream); if ((gcr_status & 0x10) && (chip->rmidi)) /* MPU401 interrupt */ - snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data); + snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data, regs); /* release the gcr */ outb(gcr_status, chip->alt_port + 0xe); @@ -804,9 +804,9 @@ static int snd_als4000_suspend(struct pci_dev *pci, pm_message_t state) snd_pcm_suspend_all(chip->pcm); snd_sbmixer_suspend(chip); + pci_set_power_state(pci, PCI_D3hot); pci_disable_device(pci); pci_save_state(pci); - pci_set_power_state(pci, pci_choose_state(pci, state)); return 0; } @@ -816,14 +816,9 @@ static int snd_als4000_resume(struct pci_dev *pci) struct snd_card_als4000 *acard = card->private_data; struct snd_sb *chip = acard->chip; - pci_set_power_state(pci, PCI_D0); pci_restore_state(pci); - if (pci_enable_device(pci) < 0) { - printk(KERN_ERR "als4000: pci_enable_device failed, " - "disabling device\n"); - snd_card_disconnect(card); - return -EIO; - } + pci_enable_device(pci); + pci_set_power_state(pci, PCI_D0); pci_set_master(pci); snd_als4000_configure(chip); diff --git a/trunk/sound/pci/atiixp.c b/trunk/sound/pci/atiixp.c index e3e99f396711..347e25ff073d 100644 --- a/trunk/sound/pci/atiixp.c +++ b/trunk/sound/pci/atiixp.c @@ -1300,7 +1300,7 @@ static int __devinit snd_atiixp_pcm_new(struct atiixp *chip) /* * interrupt handler */ -static irqreturn_t snd_atiixp_interrupt(int irq, void *dev_id) +static irqreturn_t snd_atiixp_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct atiixp *chip = dev_id; unsigned int status; @@ -1442,9 +1442,9 @@ static int snd_atiixp_suspend(struct pci_dev *pci, pm_message_t state) snd_atiixp_aclink_down(chip); snd_atiixp_chip_stop(chip); + pci_set_power_state(pci, PCI_D3hot); pci_disable_device(pci); pci_save_state(pci); - pci_set_power_state(pci, pci_choose_state(pci, state)); return 0; } @@ -1454,14 +1454,9 @@ static int snd_atiixp_resume(struct pci_dev *pci) struct atiixp *chip = card->private_data; int i; - pci_set_power_state(pci, PCI_D0); pci_restore_state(pci); - if (pci_enable_device(pci) < 0) { - printk(KERN_ERR "atiixp: pci_enable_device failed, " - "disabling device\n"); - snd_card_disconnect(card); - return -EIO; - } + pci_enable_device(pci); + pci_set_power_state(pci, PCI_D0); pci_set_master(pci); snd_atiixp_aclink_reset(chip); diff --git a/trunk/sound/pci/atiixp_modem.c b/trunk/sound/pci/atiixp_modem.c index dc54f2c68ed7..a89d67c4598b 100644 --- a/trunk/sound/pci/atiixp_modem.c +++ b/trunk/sound/pci/atiixp_modem.c @@ -1017,7 +1017,7 @@ static int __devinit snd_atiixp_pcm_new(struct atiixp_modem *chip) /* * interrupt handler */ -static irqreturn_t snd_atiixp_interrupt(int irq, void *dev_id) +static irqreturn_t snd_atiixp_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct atiixp_modem *chip = dev_id; unsigned int status; @@ -1128,9 +1128,9 @@ static int snd_atiixp_suspend(struct pci_dev *pci, pm_message_t state) snd_atiixp_aclink_down(chip); snd_atiixp_chip_stop(chip); + pci_set_power_state(pci, PCI_D3hot); pci_disable_device(pci); pci_save_state(pci); - pci_set_power_state(pci, pci_choose_state(pci, state)); return 0; } @@ -1140,14 +1140,9 @@ static int snd_atiixp_resume(struct pci_dev *pci) struct atiixp_modem *chip = card->private_data; int i; - pci_set_power_state(pci, PCI_D0); pci_restore_state(pci); - if (pci_enable_device(pci) < 0) { - printk(KERN_ERR "atiixp-modem: pci_enable_device failed, " - "disabling device\n"); - snd_card_disconnect(card); - return -EIO; - } + pci_enable_device(pci); + pci_set_power_state(pci, PCI_D0); pci_set_master(pci); snd_atiixp_aclink_reset(chip); diff --git a/trunk/sound/pci/au88x0/au88x0.c b/trunk/sound/pci/au88x0/au88x0.c index 6ed5ad59f5b5..ef189d7f09d3 100644 --- a/trunk/sound/pci/au88x0/au88x0.c +++ b/trunk/sound/pci/au88x0/au88x0.c @@ -128,7 +128,6 @@ static int snd_vortex_dev_free(struct snd_device *device) // Take down PCI interface. synchronize_irq(vortex->irq); free_irq(vortex->irq, vortex); - iounmap(vortex->mmio); pci_release_regions(vortex->pci_dev); pci_disable_device(vortex->pci_dev); kfree(vortex); diff --git a/trunk/sound/pci/au88x0/au88x0.h b/trunk/sound/pci/au88x0/au88x0.h index 5ccf0b1ec670..b1cfc3c79d07 100644 --- a/trunk/sound/pci/au88x0/au88x0.h +++ b/trunk/sound/pci/au88x0/au88x0.h @@ -236,7 +236,8 @@ static void vortex_spdif_init(vortex_t * vortex, int spdif_sr, int spdif_mode); static int vortex_core_init(vortex_t * card); static int vortex_core_shutdown(vortex_t * card); static void vortex_enable_int(vortex_t * card); -static irqreturn_t vortex_interrupt(int irq, void *dev_id); +static irqreturn_t vortex_interrupt(int irq, void *dev_id, + struct pt_regs *regs); static int vortex_alsafmt_aspfmt(int alsafmt); /* Connection stuff. */ diff --git a/trunk/sound/pci/au88x0/au88x0_core.c b/trunk/sound/pci/au88x0/au88x0_core.c index 4a336eaae9d2..5299cce583d3 100644 --- a/trunk/sound/pci/au88x0/au88x0_core.c +++ b/trunk/sound/pci/au88x0/au88x0_core.c @@ -2385,7 +2385,7 @@ static void vortex_disable_int(vortex_t * card) hwread(card->mmio, VORTEX_CTRL) & ~CTRL_IRQ_ENABLE); } -static irqreturn_t vortex_interrupt(int irq, void *dev_id) +static irqreturn_t vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs) { vortex_t *vortex = dev_id; int i, handled; @@ -2462,7 +2462,7 @@ static irqreturn_t vortex_interrupt(int irq, void *dev_id) } if (source & IRQ_MIDI) { snd_mpu401_uart_interrupt(vortex->irq, - vortex->rmidi->private_data); + vortex->rmidi->private_data, regs); handled = 1; } diff --git a/trunk/sound/pci/azt3328.c b/trunk/sound/pci/azt3328.c index 2414ee630756..bac8e9cfd921 100644 --- a/trunk/sound/pci/azt3328.c +++ b/trunk/sound/pci/azt3328.c @@ -1191,7 +1191,7 @@ snd_azf3328_capture_pointer(struct snd_pcm_substream *substream) } static irqreturn_t -snd_azf3328_interrupt(int irq, void *dev_id) +snd_azf3328_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct snd_azf3328 *chip = dev_id; u8 status, which; @@ -1256,7 +1256,7 @@ snd_azf3328_interrupt(int irq, void *dev_id) /* MPU401 has less critical IRQ requirements * than timer and playback/recording, right? */ if (status & IRQ_MPU401) { - snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data); + snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data, regs); /* hmm, do we have to ack the IRQ here somehow? * If so, then I don't know how... */ @@ -1903,9 +1903,9 @@ snd_azf3328_suspend(struct pci_dev *pci, pm_message_t state) for (reg = 0; reg < AZF_IO_SIZE_SYNTH_PM / 2; reg++) chip->saved_regs_synth[reg] = inw(chip->synth_port + reg * 2); + pci_set_power_state(pci, PCI_D3hot); pci_disable_device(pci); pci_save_state(pci); - pci_set_power_state(pci, pci_choose_state(pci, state)); return 0; } @@ -1916,14 +1916,9 @@ snd_azf3328_resume(struct pci_dev *pci) struct snd_azf3328 *chip = card->private_data; int reg; - pci_set_power_state(pci, PCI_D0); pci_restore_state(pci); - if (pci_enable_device(pci) < 0) { - printk(KERN_ERR "azt3328: pci_enable_device failed, " - "disabling device\n"); - snd_card_disconnect(card); - return -EIO; - } + pci_enable_device(pci); + pci_set_power_state(pci, PCI_D0); pci_set_master(pci); for (reg = 0; reg < AZF_IO_SIZE_IO2_PM / 2; reg++) diff --git a/trunk/sound/pci/bt87x.c b/trunk/sound/pci/bt87x.c index d33a37086df9..97a280a246cb 100644 --- a/trunk/sound/pci/bt87x.c +++ b/trunk/sound/pci/bt87x.c @@ -269,7 +269,7 @@ static void snd_bt87x_pci_error(struct snd_bt87x *chip, unsigned int status) } } -static irqreturn_t snd_bt87x_interrupt(int irq, void *dev_id) +static irqreturn_t snd_bt87x_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct snd_bt87x *chip = dev_id; unsigned int status, irq_status; diff --git a/trunk/sound/pci/ca0106/ca0106_main.c b/trunk/sound/pci/ca0106/ca0106_main.c index 6fa4a302f7de..12bbbb6afd2d 100644 --- a/trunk/sound/pci/ca0106/ca0106_main.c +++ b/trunk/sound/pci/ca0106/ca0106_main.c @@ -1058,7 +1058,8 @@ static int snd_ca0106_dev_free(struct snd_device *device) return snd_ca0106_free(chip); } -static irqreturn_t snd_ca0106_interrupt(int irq, void *dev_id) +static irqreturn_t snd_ca0106_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { unsigned int status; diff --git a/trunk/sound/pci/cmipci.c b/trunk/sound/pci/cmipci.c index 0093cd1f92db..876b64464b6f 100644 --- a/trunk/sound/pci/cmipci.c +++ b/trunk/sound/pci/cmipci.c @@ -1294,7 +1294,7 @@ static int snd_cmipci_capture_spdif_hw_free(struct snd_pcm_substream *subs) /* * interrupt handler */ -static irqreturn_t snd_cmipci_interrupt(int irq, void *dev_id) +static irqreturn_t snd_cmipci_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct cmipci *cm = dev_id; unsigned int status, mask = 0; @@ -1315,7 +1315,7 @@ static irqreturn_t snd_cmipci_interrupt(int irq, void *dev_id) spin_unlock(&cm->reg_lock); if (cm->rmidi && (status & CM_UARTINT)) - snd_mpu401_uart_interrupt(irq, cm->rmidi->private_data); + snd_mpu401_uart_interrupt(irq, cm->rmidi->private_data, regs); if (cm->pcm) { if ((status & CM_CHINT0) && cm->channel[0].running) @@ -3122,9 +3122,9 @@ static int snd_cmipci_suspend(struct pci_dev *pci, pm_message_t state) /* disable ints */ snd_cmipci_write(cm, CM_REG_INT_HLDCLR, 0); + pci_set_power_state(pci, PCI_D3hot); pci_disable_device(pci); pci_save_state(pci); - pci_set_power_state(pci, pci_choose_state(pci, state)); return 0; } @@ -3134,14 +3134,9 @@ static int snd_cmipci_resume(struct pci_dev *pci) struct cmipci *cm = card->private_data; int i; - pci_set_power_state(pci, PCI_D0); pci_restore_state(pci); - if (pci_enable_device(pci) < 0) { - printk(KERN_ERR "cmipci: pci_enable_device failed, " - "disabling device\n"); - snd_card_disconnect(card); - return -EIO; - } + pci_enable_device(pci); + pci_set_power_state(pci, PCI_D0); pci_set_master(pci); /* reset / initialize to a sane state */ diff --git a/trunk/sound/pci/cs4281.c b/trunk/sound/pci/cs4281.c index 0905fa88129d..1990430a21c1 100644 --- a/trunk/sound/pci/cs4281.c +++ b/trunk/sound/pci/cs4281.c @@ -493,7 +493,7 @@ struct cs4281 { }; -static irqreturn_t snd_cs4281_interrupt(int irq, void *dev_id); +static irqreturn_t snd_cs4281_interrupt(int irq, void *dev_id, struct pt_regs *regs); static struct pci_device_id snd_cs4281_ids[] = { { 0x1013, 0x6005, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* CS4281 */ @@ -1814,7 +1814,7 @@ static int __devinit snd_cs4281_midi(struct cs4281 * chip, int device, * Interrupt handler */ -static irqreturn_t snd_cs4281_interrupt(int irq, void *dev_id) +static irqreturn_t snd_cs4281_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct cs4281 *chip = dev_id; unsigned int status, dma, val; @@ -2050,7 +2050,6 @@ static int cs4281_suspend(struct pci_dev *pci, pm_message_t state) pci_disable_device(pci); pci_save_state(pci); - pci_set_power_state(pci, pci_choose_state(pci, state)); return 0; } @@ -2061,14 +2060,8 @@ static int cs4281_resume(struct pci_dev *pci) unsigned int i; u32 ulCLK; - pci_set_power_state(pci, PCI_D0); pci_restore_state(pci); - if (pci_enable_device(pci) < 0) { - printk(KERN_ERR "cs4281: pci_enable_device failed, " - "disabling device\n"); - snd_card_disconnect(card); - return -EIO; - } + pci_enable_device(pci); pci_set_master(pci); ulCLK = snd_cs4281_peekBA0(chip, BA0_CLKCR1); diff --git a/trunk/sound/pci/cs46xx/cs46xx_lib.c b/trunk/sound/pci/cs46xx/cs46xx_lib.c index 2807b9756ef0..4851847180d2 100644 --- a/trunk/sound/pci/cs46xx/cs46xx_lib.c +++ b/trunk/sound/pci/cs46xx/cs46xx_lib.c @@ -1149,7 +1149,7 @@ static int snd_cs46xx_capture_prepare(struct snd_pcm_substream *substream) return 0; } -static irqreturn_t snd_cs46xx_interrupt(int irq, void *dev_id) +static irqreturn_t snd_cs46xx_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct snd_cs46xx *chip = dev_id; u32 status1; @@ -3687,10 +3687,8 @@ int snd_cs46xx_suspend(struct pci_dev *pci, pm_message_t state) /* disable CLKRUN */ chip->active_ctrl(chip, -chip->amplifier); chip->amplifier = amp_saved; /* restore the status */ - pci_disable_device(pci); pci_save_state(pci); - pci_set_power_state(pci, pci_choose_state(pci, state)); return 0; } @@ -3700,16 +3698,9 @@ int snd_cs46xx_resume(struct pci_dev *pci) struct snd_cs46xx *chip = card->private_data; int amp_saved; - pci_set_power_state(pci, PCI_D0); pci_restore_state(pci); - if (pci_enable_device(pci) < 0) { - printk(KERN_ERR "cs46xx: pci_enable_device failed, " - "disabling device\n"); - snd_card_disconnect(card); - return -EIO; - } + pci_enable_device(pci); pci_set_master(pci); - amp_saved = chip->amplifier; chip->amplifier = 0; chip->active_ctrl(chip, 1); /* force to on */ diff --git a/trunk/sound/pci/cs5535audio/cs5535audio.c b/trunk/sound/pci/cs5535audio/cs5535audio.c index 2441238f2004..64c7826e8b8c 100644 --- a/trunk/sound/pci/cs5535audio/cs5535audio.c +++ b/trunk/sound/pci/cs5535audio/cs5535audio.c @@ -203,7 +203,8 @@ static void process_bm1_irq(struct cs5535audio *cs5535au) } } -static irqreturn_t snd_cs5535audio_interrupt(int irq, void *dev_id) +static irqreturn_t snd_cs5535audio_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { u16 acc_irq_stat; u8 bm_stat; diff --git a/trunk/sound/pci/cs5535audio/cs5535audio_pm.c b/trunk/sound/pci/cs5535audio/cs5535audio_pm.c index 3e4d198a4502..aad0e69db9c1 100644 --- a/trunk/sound/pci/cs5535audio/cs5535audio_pm.c +++ b/trunk/sound/pci/cs5535audio/cs5535audio_pm.c @@ -73,10 +73,9 @@ int snd_cs5535audio_suspend(struct pci_dev *pci, pm_message_t state) snd_ac97_suspend(cs5535au->ac97); /* save important regs, then disable aclink in hw */ snd_cs5535audio_stop_hardware(cs5535au); - pci_disable_device(pci); pci_save_state(pci); - pci_set_power_state(pci, pci_choose_state(pci, state)); + return 0; } @@ -88,14 +87,8 @@ int snd_cs5535audio_resume(struct pci_dev *pci) int timeout; int i; - pci_set_power_state(pci, PCI_D0); pci_restore_state(pci); - if (pci_enable_device(pci) < 0) { - printk(KERN_ERR "cs5535audio: pci_enable_device failed, " - "disabling device\n"); - snd_card_disconnect(card); - return -EIO; - } + pci_enable_device(pci); pci_set_master(pci); /* set LNK_WRM_RST to reset AC link */ diff --git a/trunk/sound/pci/echoaudio/echoaudio.c b/trunk/sound/pci/echoaudio/echoaudio.c index e5e88fe54de0..c3dafa29054f 100644 --- a/trunk/sound/pci/echoaudio/echoaudio.c +++ b/trunk/sound/pci/echoaudio/echoaudio.c @@ -1818,7 +1818,8 @@ static struct snd_kcontrol_new snd_echo_channels_info __devinitdata = { IRQ Handler ******************************************************************************/ -static irqreturn_t snd_echo_interrupt(int irq, void *dev_id) +static irqreturn_t snd_echo_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { struct echoaudio *chip = dev_id; struct snd_pcm_substream *substream; diff --git a/trunk/sound/pci/emu10k1/emu10k1.c b/trunk/sound/pci/emu10k1/emu10k1.c index 55caf341933a..493ec0816bb3 100644 --- a/trunk/sound/pci/emu10k1/emu10k1.c +++ b/trunk/sound/pci/emu10k1/emu10k1.c @@ -226,9 +226,9 @@ static int snd_emu10k1_suspend(struct pci_dev *pci, pm_message_t state) snd_emu10k1_done(emu); + pci_set_power_state(pci, PCI_D3hot); pci_disable_device(pci); pci_save_state(pci); - pci_set_power_state(pci, pci_choose_state(pci, state)); return 0; } @@ -237,16 +237,11 @@ static int snd_emu10k1_resume(struct pci_dev *pci) struct snd_card *card = pci_get_drvdata(pci); struct snd_emu10k1 *emu = card->private_data; - pci_set_power_state(pci, PCI_D0); pci_restore_state(pci); - if (pci_enable_device(pci) < 0) { - printk(KERN_ERR "emu10k1: pci_enable_device failed, " - "disabling device\n"); - snd_card_disconnect(card); - return -EIO; - } + pci_enable_device(pci); + pci_set_power_state(pci, PCI_D0); pci_set_master(pci); - + snd_emu10k1_resume_init(emu); snd_emu10k1_efx_resume(emu); snd_ac97_resume(emu->ac97); diff --git a/trunk/sound/pci/emu10k1/emu10k1_main.c b/trunk/sound/pci/emu10k1/emu10k1_main.c index 8bc4ffa6220d..be65d4db8e27 100644 --- a/trunk/sound/pci/emu10k1/emu10k1_main.c +++ b/trunk/sound/pci/emu10k1/emu10k1_main.c @@ -956,7 +956,6 @@ static struct snd_emu_chip_details emu_chip_details[] = { .ca0151_chip = 1, .spk71 = 1, .spdif_bug = 1, - .adc_1361t = 1, /* 24 bit capture instead of 16bit. Fixes ALSA bug#324 */ .ac97_chip = 1} , {.vendor = 0x1102, .device = 0x0004, .revision = 0x04, .driver = "Audigy2", .name = "Audigy 2 [Unknown]", @@ -1462,8 +1461,8 @@ void snd_emu10k1_resume_regs(struct snd_emu10k1 *emu) /* resore for spdif */ if (emu->audigy) - outl(emu->saved_a_iocfg, emu->port + A_IOCFG); - outl(emu->saved_hcfg, emu->port + HCFG); + outl(emu->port + A_IOCFG, emu->saved_a_iocfg); + outl(emu->port + HCFG, emu->saved_hcfg); val = emu->saved_ptr; for (reg = saved_regs; *reg != 0xff; reg++) diff --git a/trunk/sound/pci/emu10k1/emu10k1x.c b/trunk/sound/pci/emu10k1/emu10k1x.c index c46905a11175..da1610a571b8 100644 --- a/trunk/sound/pci/emu10k1/emu10k1x.c +++ b/trunk/sound/pci/emu10k1/emu10k1x.c @@ -780,7 +780,8 @@ static int snd_emu10k1x_dev_free(struct snd_device *device) return snd_emu10k1x_free(chip); } -static irqreturn_t snd_emu10k1x_interrupt(int irq, void *dev_id) +static irqreturn_t snd_emu10k1x_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { unsigned int status; diff --git a/trunk/sound/pci/emu10k1/irq.c b/trunk/sound/pci/emu10k1/irq.c index 4f18f7e8bcfb..1076af4c3669 100644 --- a/trunk/sound/pci/emu10k1/irq.c +++ b/trunk/sound/pci/emu10k1/irq.c @@ -30,7 +30,7 @@ #include #include -irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id) +irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct snd_emu10k1 *emu = dev_id; unsigned int status, status2, orig_status, orig_status2; diff --git a/trunk/sound/pci/ens1370.c b/trunk/sound/pci/ens1370.c index d2a811f222c9..a8a601fc781f 100644 --- a/trunk/sound/pci/ens1370.c +++ b/trunk/sound/pci/ens1370.c @@ -444,7 +444,7 @@ struct ensoniq { #endif }; -static irqreturn_t snd_audiopci_interrupt(int irq, void *dev_id); +static irqreturn_t snd_audiopci_interrupt(int irq, void *dev_id, struct pt_regs *regs); static struct pci_device_id snd_audiopci_ids[] = { #ifdef CHIP1370 @@ -2072,10 +2072,9 @@ static int snd_ensoniq_suspend(struct pci_dev *pci, pm_message_t state) udelay(100); snd_ak4531_suspend(ensoniq->u.es1370.ak4531); #endif - + pci_set_power_state(pci, PCI_D3hot); pci_disable_device(pci); pci_save_state(pci); - pci_set_power_state(pci, pci_choose_state(pci, state)); return 0; } @@ -2084,14 +2083,9 @@ static int snd_ensoniq_resume(struct pci_dev *pci) struct snd_card *card = pci_get_drvdata(pci); struct ensoniq *ensoniq = card->private_data; - pci_set_power_state(pci, PCI_D0); pci_restore_state(pci); - if (pci_enable_device(pci) < 0) { - printk(KERN_ERR DRIVER_NAME ": pci_enable_device failed, " - "disabling device\n"); - snd_card_disconnect(card); - return -EIO; - } + pci_enable_device(pci); + pci_set_power_state(pci, PCI_D0); pci_set_master(pci); snd_ensoniq_chip_init(ensoniq); @@ -2410,7 +2404,7 @@ static int __devinit snd_ensoniq_midi(struct ensoniq * ensoniq, int device, * Interrupt handler */ -static irqreturn_t snd_audiopci_interrupt(int irq, void *dev_id) +static irqreturn_t snd_audiopci_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct ensoniq *ensoniq = dev_id; unsigned int status, sctrl; diff --git a/trunk/sound/pci/es1938.c b/trunk/sound/pci/es1938.c index 1a8d36df4b5d..3ce5a4e7e31f 100644 --- a/trunk/sound/pci/es1938.c +++ b/trunk/sound/pci/es1938.c @@ -241,7 +241,7 @@ struct es1938 { #endif }; -static irqreturn_t snd_es1938_interrupt(int irq, void *dev_id); +static irqreturn_t snd_es1938_interrupt(int irq, void *dev_id, struct pt_regs *regs); static struct pci_device_id snd_es1938_ids[] = { { 0x125d, 0x1969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Solo-1 */ @@ -1481,14 +1481,10 @@ static int es1938_suspend(struct pci_dev *pci, pm_message_t state) *d = snd_es1938_reg_read(chip, *s); outb(0x00, SLIO_REG(chip, IRQCONTROL)); /* disable irqs */ - if (chip->irq >= 0) { - synchronize_irq(chip->irq); + if (chip->irq >= 0) free_irq(chip->irq, chip); - chip->irq = -1; - } pci_disable_device(pci); pci_save_state(pci); - pci_set_power_state(pci, pci_choose_state(pci, state)); return 0; } @@ -1498,22 +1494,10 @@ static int es1938_resume(struct pci_dev *pci) struct es1938 *chip = card->private_data; unsigned char *s, *d; - pci_set_power_state(pci, PCI_D0); pci_restore_state(pci); - if (pci_enable_device(pci) < 0) { - printk(KERN_ERR "es1938: pci_enable_device failed, " - "disabling device\n"); - snd_card_disconnect(card); - return -EIO; - } - - if (request_irq(pci->irq, snd_es1938_interrupt, - IRQF_DISABLED|IRQF_SHARED, "ES1938", chip)) { - printk(KERN_ERR "es1938: unable to grab IRQ %d, " - "disabling device\n", pci->irq); - snd_card_disconnect(card); - return -EIO; - } + pci_enable_device(pci); + request_irq(pci->irq, snd_es1938_interrupt, + IRQF_DISABLED|IRQF_SHARED, "ES1938", chip); chip->irq = pci->irq; snd_es1938_chip_init(chip); @@ -1572,10 +1556,8 @@ static int snd_es1938_free(struct es1938 *chip) snd_es1938_free_gameport(chip); - if (chip->irq >= 0) { - synchronize_irq(chip->irq); + if (chip->irq >= 0) free_irq(chip->irq, chip); - } pci_release_regions(chip->pci); pci_disable_device(chip->pci); kfree(chip); @@ -1620,7 +1602,6 @@ static int __devinit snd_es1938_create(struct snd_card *card, spin_lock_init(&chip->mixer_lock); chip->card = card; chip->pci = pci; - chip->irq = -1; if ((err = pci_request_regions(pci, "ESS Solo-1")) < 0) { kfree(chip); pci_disable_device(pci); @@ -1661,7 +1642,7 @@ static int __devinit snd_es1938_create(struct snd_card *card, /* -------------------------------------------------------------------- * Interrupt handler * -------------------------------------------------------------------- */ -static irqreturn_t snd_es1938_interrupt(int irq, void *dev_id) +static irqreturn_t snd_es1938_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct es1938 *chip = dev_id; unsigned char status, audiostatus; @@ -1733,7 +1714,7 @@ static irqreturn_t snd_es1938_interrupt(int irq, void *dev_id) // snd_es1938_mixer_bits(chip, ESSSB_IREG_MPU401CONTROL, 0x40, 0); /* ack? */ if (chip->rmidi) { handled = 1; - snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data); + snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data, regs); } } return IRQ_RETVAL(handled); diff --git a/trunk/sound/pci/es1968.c b/trunk/sound/pci/es1968.c index 092da53e1464..f3c40385c87d 100644 --- a/trunk/sound/pci/es1968.c +++ b/trunk/sound/pci/es1968.c @@ -432,6 +432,46 @@ MODULE_PARM_DESC(joystick, "Enable joystick."); #define ESM_MODE_PLAY 0 #define ESM_MODE_CAPTURE 1 +/* acpi states */ +enum { + ACPI_D0=0, + ACPI_D1, + ACPI_D2, + ACPI_D3 +}; + +/* bits in the acpi masks */ +#define ACPI_12MHZ ( 1 << 15) +#define ACPI_24MHZ ( 1 << 14) +#define ACPI_978 ( 1 << 13) +#define ACPI_SPDIF ( 1 << 12) +#define ACPI_GLUE ( 1 << 11) +#define ACPI__10 ( 1 << 10) /* reserved */ +#define ACPI_PCIINT ( 1 << 9) +#define ACPI_HV ( 1 << 8) /* hardware volume */ +#define ACPI_GPIO ( 1 << 7) +#define ACPI_ASSP ( 1 << 6) +#define ACPI_SB ( 1 << 5) /* sb emul */ +#define ACPI_FM ( 1 << 4) /* fm emul */ +#define ACPI_RB ( 1 << 3) /* ringbus / aclink */ +#define ACPI_MIDI ( 1 << 2) +#define ACPI_GP ( 1 << 1) /* game port */ +#define ACPI_WP ( 1 << 0) /* wave processor */ + +#define ACPI_ALL (0xffff) +#define ACPI_SLEEP (~(ACPI_SPDIF|ACPI_ASSP|ACPI_SB|ACPI_FM| \ + ACPI_MIDI|ACPI_GP|ACPI_WP)) +#define ACPI_NONE (ACPI__10) + +/* these masks indicate which units we care about at + which states */ +static u16 acpi_state_mask[] = { + [ACPI_D0] = ACPI_ALL, + [ACPI_D1] = ACPI_SLEEP, + [ACPI_D2] = ACPI_SLEEP, + [ACPI_D3] = ACPI_NONE +}; + /* APU use in the driver */ enum snd_enum_apu_type { @@ -550,7 +590,7 @@ struct es1968 { #endif }; -static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id); +static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id, struct pt_regs *regs); static struct pci_device_id snd_es1968_ids[] = { /* Maestro 1 */ @@ -1922,7 +1962,7 @@ static void es1968_update_hw_volume(unsigned long private_data) /* * interrupt handler */ -static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id) +static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct es1968 *chip = dev_id; u32 event; @@ -1939,7 +1979,7 @@ static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id) outb(0xFF, chip->io_port + 0x1A); if ((event & ESM_MPU401_IRQ) && chip->rmidi) { - snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data); + snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data, regs); } if (event & ESM_SOUND_IRQ) { @@ -2119,6 +2159,21 @@ static void snd_es1968_reset(struct es1968 *chip) udelay(10); } +/* + * power management + */ +static void snd_es1968_set_acpi(struct es1968 *chip, int state) +{ + u16 active_mask = acpi_state_mask[state]; + + pci_set_power_state(chip->pci, state); + /* make sure the units we care about are on + XXX we might want to do this before state flipping? */ + pci_write_config_word(chip->pci, 0x54, ~ active_mask); + pci_write_config_word(chip->pci, 0x56, ~ active_mask); +} + + /* * initialize maestro chip */ @@ -2141,6 +2196,9 @@ static void snd_es1968_chip_init(struct es1968 *chip) * IRQs. */ + /* do config work at full power */ + snd_es1968_set_acpi(chip, ACPI_D0); + /* Config Reg A */ pci_read_config_word(pci, ESM_CONFIG_A, &w); @@ -2339,10 +2397,9 @@ static int es1968_suspend(struct pci_dev *pci, pm_message_t state) snd_pcm_suspend_all(chip->pcm); snd_ac97_suspend(chip->ac97); snd_es1968_bob_stop(chip); - + snd_es1968_set_acpi(chip, ACPI_D3); pci_disable_device(pci); pci_save_state(pci); - pci_set_power_state(pci, pci_choose_state(pci, state)); return 0; } @@ -2356,16 +2413,9 @@ static int es1968_resume(struct pci_dev *pci) return 0; /* restore all our config */ - pci_set_power_state(pci, PCI_D0); pci_restore_state(pci); - if (pci_enable_device(pci) < 0) { - printk(KERN_ERR "es1968: pci_enable_device failed, " - "disabling device\n"); - snd_card_disconnect(card); - return -EIO; - } + pci_enable_device(pci); pci_set_master(pci); - snd_es1968_chip_init(chip); /* need to restore the base pointers.. */ @@ -2464,6 +2514,7 @@ static int snd_es1968_free(struct es1968 *chip) if (chip->irq >= 0) free_irq(chip->irq, (void *)chip); snd_es1968_free_gameport(chip); + snd_es1968_set_acpi(chip, ACPI_D3); chip->master_switch = NULL; chip->master_volume = NULL; pci_release_regions(chip->pci); diff --git a/trunk/sound/pci/fm801.c b/trunk/sound/pci/fm801.c index 77e3d5c18302..bdfda1997d5b 100644 --- a/trunk/sound/pci/fm801.c +++ b/trunk/sound/pci/fm801.c @@ -520,7 +520,7 @@ static snd_pcm_uframes_t snd_fm801_capture_pointer(struct snd_pcm_substream *sub return bytes_to_frames(substream->runtime, ptr); } -static irqreturn_t snd_fm801_interrupt(int irq, void *dev_id) +static irqreturn_t snd_fm801_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct fm801 *chip = dev_id; unsigned short status; @@ -561,7 +561,7 @@ static irqreturn_t snd_fm801_interrupt(int irq, void *dev_id) snd_pcm_period_elapsed(chip->capture_substream); } if (chip->rmidi && (status & FM801_IRQ_MPU)) - snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data); + snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data, regs); if (status & FM801_IRQ_VOLUME) ;/* TODO */ @@ -1531,9 +1531,9 @@ static int snd_fm801_suspend(struct pci_dev *pci, pm_message_t state) chip->saved_regs[i] = inw(chip->port + saved_regs[i]); /* FIXME: tea575x suspend */ + pci_set_power_state(pci, PCI_D3hot); pci_disable_device(pci); pci_save_state(pci); - pci_set_power_state(pci, pci_choose_state(pci, state)); return 0; } @@ -1543,14 +1543,9 @@ static int snd_fm801_resume(struct pci_dev *pci) struct fm801 *chip = card->private_data; int i; - pci_set_power_state(pci, PCI_D0); pci_restore_state(pci); - if (pci_enable_device(pci) < 0) { - printk(KERN_ERR "fm801: pci_enable_device failed, " - "disabling device\n"); - snd_card_disconnect(card); - return -EIO; - } + pci_enable_device(pci); + pci_set_power_state(pci, PCI_D0); pci_set_master(pci); snd_fm801_chip_init(chip, 1); diff --git a/trunk/sound/pci/hda/hda_intel.c b/trunk/sound/pci/hda/hda_intel.c index e35cfd326df2..e9d4cb4d07e1 100644 --- a/trunk/sound/pci/hda/hda_intel.c +++ b/trunk/sound/pci/hda/hda_intel.c @@ -55,7 +55,7 @@ static char *model; static int position_fix; static int probe_mask = -1; static int single_cmd; -static int enable_msi; +static int disable_msi; module_param(index, int, 0444); MODULE_PARM_DESC(index, "Index value for Intel HD audio interface."); @@ -69,8 +69,8 @@ module_param(probe_mask, int, 0444); MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1)."); module_param(single_cmd, bool, 0444); MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs (for debugging only)."); -module_param(enable_msi, int, 0); -MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)"); +module_param(disable_msi, int, 0); +MODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)"); /* just for backward compatibility */ @@ -86,7 +86,6 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6}," "{ATI, SB450}," "{ATI, SB600}," "{ATI, RS600}," - "{ATI, RS690}," "{VIA, VT8251}," "{VIA, VT8237A}," "{SiS, SIS966}," @@ -337,7 +336,6 @@ struct azx { unsigned int initialized :1; unsigned int single_cmd :1; unsigned int polling_mode :1; - unsigned int msi :1; }; /* driver types */ @@ -398,7 +396,6 @@ static char *driver_short_names[] __devinitdata = { */ #define upper_32bit(addr) (sizeof(addr) > 4 ? (u32)((addr) >> 32) : (u32)0) -static int azx_acquire_irq(struct azx *chip, int do_disconnect); /* * Interface for HD codec @@ -538,18 +535,6 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec) schedule_timeout_interruptible(1); } while (time_after_eq(timeout, jiffies)); - if (chip->msi) { - snd_printk(KERN_WARNING "hda_intel: No response from codec, " - "disabling MSI...\n"); - free_irq(chip->irq, chip); - chip->irq = -1; - pci_disable_msi(chip->pci); - chip->msi = 0; - if (azx_acquire_irq(chip, 1) < 0) - return -1; - goto again; - } - if (!chip->polling_mode) { snd_printk(KERN_WARNING "hda_intel: azx_get_response timeout, " "switching to polling mode...\n"); @@ -826,7 +811,7 @@ static void azx_init_chip(struct azx *chip) /* * interrupt handler */ -static irqreturn_t azx_interrupt(int irq, void *dev_id) +static irqreturn_t azx_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct azx *chip = dev_id; struct azx_dev *azx_dev; @@ -1378,20 +1363,6 @@ static int __devinit azx_init_stream(struct azx *chip) return 0; } -static int azx_acquire_irq(struct azx *chip, int do_disconnect) -{ - if (request_irq(chip->pci->irq, azx_interrupt, IRQF_DISABLED|IRQF_SHARED, - "HDA Intel", chip)) { - printk(KERN_ERR "hda-intel: unable to grab IRQ %d, " - "disabling device\n", chip->pci->irq); - if (do_disconnect) - snd_card_disconnect(chip->card); - return -1; - } - chip->irq = chip->pci->irq; - return 0; -} - #ifdef CONFIG_PM /* @@ -1408,16 +1379,12 @@ static int azx_suspend(struct pci_dev *pci, pm_message_t state) snd_pcm_suspend_all(chip->pcm[i]); snd_hda_suspend(chip->bus, state); azx_free_cmd_io(chip); - if (chip->irq >= 0) { - synchronize_irq(chip->irq); + if (chip->irq >= 0) free_irq(chip->irq, chip); - chip->irq = -1; - } - if (chip->msi) + if (!disable_msi) pci_disable_msi(chip->pci); pci_disable_device(pci); pci_save_state(pci); - pci_set_power_state(pci, pci_choose_state(pci, state)); return 0; } @@ -1426,20 +1393,15 @@ static int azx_resume(struct pci_dev *pci) struct snd_card *card = pci_get_drvdata(pci); struct azx *chip = card->private_data; - pci_set_power_state(pci, PCI_D0); pci_restore_state(pci); - if (pci_enable_device(pci) < 0) { - printk(KERN_ERR "hda-intel: pci_enable_device failed, " - "disabling device\n"); - snd_card_disconnect(card); - return -EIO; - } + pci_enable_device(pci); + if (!disable_msi) + pci_enable_msi(pci); + /* FIXME: need proper error handling */ + request_irq(pci->irq, azx_interrupt, IRQF_DISABLED|IRQF_SHARED, + "HDA Intel", chip); + chip->irq = pci->irq; pci_set_master(pci); - if (chip->msi) - if (pci_enable_msi(pci) < 0) - chip->msi = 0; - if (azx_acquire_irq(chip, 1) < 0) - return -EIO; azx_init_chip(chip); snd_hda_resume(chip->bus); snd_power_change_state(card, SNDRV_CTL_POWER_D0); @@ -1469,14 +1431,15 @@ static int azx_free(struct azx *chip) /* disable position buffer */ azx_writel(chip, DPLBASE, 0); azx_writel(chip, DPUBASE, 0); + + synchronize_irq(chip->irq); } if (chip->irq >= 0) { - synchronize_irq(chip->irq); free_irq(chip->irq, (void*)chip); + if (!disable_msi) + pci_disable_msi(chip->pci); } - if (chip->msi) - pci_disable_msi(chip->pci); if (chip->remap_addr) iounmap(chip->remap_addr); @@ -1531,7 +1494,6 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, chip->pci = pci; chip->irq = -1; chip->driver_type = driver_type; - chip->msi = enable_msi; chip->position_fix = position_fix; chip->single_cmd = single_cmd; @@ -1561,14 +1523,16 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, goto errout; } - if (chip->msi) - if (pci_enable_msi(pci) < 0) - chip->msi = 0; + if (!disable_msi) + pci_enable_msi(pci); - if (azx_acquire_irq(chip, 0) < 0) { + if (request_irq(pci->irq, azx_interrupt, IRQF_DISABLED|IRQF_SHARED, + "HDA Intel", (void*)chip)) { + snd_printk(KERN_ERR SFX "unable to grab IRQ %d\n", pci->irq); err = -EBUSY; goto errout; } + chip->irq = pci->irq; pci_set_master(pci); synchronize_irq(chip->irq); @@ -1713,13 +1677,11 @@ static struct pci_device_id azx_ids[] = { { 0x1002, 0x437b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATI }, /* ATI SB450 */ { 0x1002, 0x4383, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATI }, /* ATI SB600 */ { 0x1002, 0x793b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RS600 HDMI */ - { 0x1002, 0x7919, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RS690 HDMI */ { 0x1106, 0x3288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_VIA }, /* VIA VT8251/VT8237A */ { 0x1039, 0x7502, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_SIS }, /* SIS966 */ { 0x10b9, 0x5461, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ULI }, /* ULI M5461 */ { 0x10de, 0x026c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA 026c */ { 0x10de, 0x0371, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA 0371 */ - { 0x10de, 0x03f0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA 03f0 */ { 0, } }; MODULE_DEVICE_TABLE(pci, azx_ids); diff --git a/trunk/sound/pci/hda/patch_analog.c b/trunk/sound/pci/hda/patch_analog.c index edd22dec8286..511df07fa2a3 100644 --- a/trunk/sound/pci/hda/patch_analog.c +++ b/trunk/sound/pci/hda/patch_analog.c @@ -818,8 +818,6 @@ static struct hda_board_config ad1986a_cfg_tbl[] = { .config = AD1986A_LAPTOP_EAPD }, /* ASUS A6J */ { .pci_subvendor = 0x1043, .pci_subdevice = 0x11f7, .config = AD1986A_LAPTOP_EAPD }, /* ASUS U5A */ - { .pci_subvendor = 0x1043, .pci_subdevice = 0x1263, - .config = AD1986A_LAPTOP_EAPD }, /* ASUS U5F */ { .pci_subvendor = 0x1043, .pci_subdevice = 0x1297, .config = AD1986A_LAPTOP_EAPD }, /* ASUS Z62F */ { .pci_subvendor = 0x103c, .pci_subdevice = 0x30af, diff --git a/trunk/sound/pci/hda/patch_atihdmi.c b/trunk/sound/pci/hda/patch_atihdmi.c index 7333f275decd..a27440ffd1c8 100644 --- a/trunk/sound/pci/hda/patch_atihdmi.c +++ b/trunk/sound/pci/hda/patch_atihdmi.c @@ -161,6 +161,5 @@ static int patch_atihdmi(struct hda_codec *codec) */ struct hda_codec_preset snd_hda_preset_atihdmi[] = { { .id = 0x1002793c, .name = "ATI RS600 HDMI", .patch = patch_atihdmi }, - { .id = 0x1002791a, .name = "ATI RS690 HDMI", .patch = patch_atihdmi }, {} /* terminator */ }; diff --git a/trunk/sound/pci/hda/patch_realtek.c b/trunk/sound/pci/hda/patch_realtek.c index fb961448db19..d08d2e399c8f 100644 --- a/trunk/sound/pci/hda/patch_realtek.c +++ b/trunk/sound/pci/hda/patch_realtek.c @@ -1799,7 +1799,7 @@ static int alc_build_pcms(struct hda_codec *codec) /* SPDIF for stream index #1 */ if (spec->multiout.dig_out_nid || spec->dig_in_nid) { codec->num_pcms = 2; - info = spec->pcm_rec + 1; + info++; info->name = spec->stream_name_digital; if (spec->multiout.dig_out_nid && spec->stream_digital_playback) { @@ -1820,7 +1820,7 @@ static int alc_build_pcms(struct hda_codec *codec) if (spec->num_adc_nids > 1 && spec->stream_analog_capture && spec->adc_nids) { codec->num_pcms = 3; - info = spec->pcm_rec + 2; + info++; info->name = spec->stream_name_analog; /* No playback stream for second PCM */ info->stream[SNDRV_PCM_STREAM_PLAYBACK] = alc_pcm_null_playback; @@ -5076,10 +5076,6 @@ static struct hda_board_config alc883_cfg_tbl[] = { { .modelname = "acer", .config = ALC883_ACER }, { .pci_subvendor = 0x1025, .pci_subdevice = 0/*0x0102*/, .config = ALC883_ACER }, - { .pci_subvendor = 0x1025, .pci_subdevice = 0x0102, - .config = ALC883_ACER }, - { .pci_subvendor = 0x1025, .pci_subdevice = 0x009f, - .config = ALC883_ACER }, { .modelname = "auto", .config = ALC883_AUTO }, {} }; @@ -5870,7 +5866,7 @@ static struct hda_board_config alc262_cfg_tbl[] = { { .pci_subvendor = 0x10cf, .pci_subdevice = 0x1397, .config = ALC262_FUJITSU }, { .modelname = "hp-bpc", .config = ALC262_HP_BPC }, - { .pci_subvendor = 0x103c, .pci_subdevice = 0x280c, + { .pci_subvendor = 0x103c, .pci_subdevice = 0x208c, .config = ALC262_HP_BPC }, /* xw4400 */ { .pci_subvendor = 0x103c, .pci_subdevice = 0x3014, .config = ALC262_HP_BPC }, /* xw6400 */ diff --git a/trunk/sound/pci/hda/patch_si3054.c b/trunk/sound/pci/hda/patch_si3054.c index cc87dff1eb56..76ec3d75fa9e 100644 --- a/trunk/sound/pci/hda/patch_si3054.c +++ b/trunk/sound/pci/hda/patch_si3054.c @@ -297,13 +297,8 @@ static int patch_si3054(struct hda_codec *codec) struct hda_codec_preset snd_hda_preset_si3054[] = { { .id = 0x163c3055, .name = "Si3054", .patch = patch_si3054 }, { .id = 0x163c3155, .name = "Si3054", .patch = patch_si3054 }, - { .id = 0x11c11040, .name = "Si3054", .patch = patch_si3054 }, { .id = 0x11c13026, .name = "Si3054", .patch = patch_si3054 }, - { .id = 0x11c13055, .name = "Si3054", .patch = patch_si3054 }, - { .id = 0x11c13155, .name = "Si3054", .patch = patch_si3054 }, - { .id = 0x10573055, .name = "Si3054", .patch = patch_si3054 }, { .id = 0x10573057, .name = "Si3054", .patch = patch_si3054 }, - { .id = 0x10573155, .name = "Si3054", .patch = patch_si3054 }, {} }; diff --git a/trunk/sound/pci/hda/patch_sigmatel.c b/trunk/sound/pci/hda/patch_sigmatel.c index fe51ef3e49d2..731b7b97ee71 100644 --- a/trunk/sound/pci/hda/patch_sigmatel.c +++ b/trunk/sound/pci/hda/patch_sigmatel.c @@ -336,13 +336,6 @@ static struct hda_board_config stac9200_cfg_tbl[] = { .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x2668, /* DFI LanParty */ .config = STAC_REF }, - /* Dell laptops have BIOS problem */ - { .pci_subvendor = PCI_VENDOR_ID_DELL, .pci_subdevice = 0x01b5, - .config = STAC_REF }, /* Dell Inspiron 630m */ - { .pci_subvendor = PCI_VENDOR_ID_DELL, .pci_subdevice = 0x01c2, - .config = STAC_REF }, /* Dell Latitude D620 */ - { .pci_subvendor = PCI_VENDOR_ID_DELL, .pci_subdevice = 0x01cb, - .config = STAC_REF }, /* Dell Latitude 120L */ {} /* terminator */ }; @@ -598,6 +591,13 @@ static struct hda_board_config stac9205_cfg_tbl[] = { .pci_subvendor = PCI_VENDOR_ID_INTEL, .pci_subdevice = 0x2668, /* DFI LanParty */ .config = STAC_REF }, /* SigmaTel reference board */ + /* Dell laptops have BIOS problem */ + { .pci_subvendor = PCI_VENDOR_ID_DELL, .pci_subdevice = 0x01b5, + .config = STAC_REF }, /* Dell Inspiron 630m */ + { .pci_subvendor = PCI_VENDOR_ID_DELL, .pci_subdevice = 0x01c2, + .config = STAC_REF }, /* Dell Latitude D620 */ + { .pci_subvendor = PCI_VENDOR_ID_DELL, .pci_subdevice = 0x01cb, + .config = STAC_REF }, /* Dell Latitude 120L */ {} /* terminator */ }; diff --git a/trunk/sound/pci/ice1712/ice1712.c b/trunk/sound/pci/ice1712/ice1712.c index 8a576b78bee5..dc69392eafa3 100644 --- a/trunk/sound/pci/ice1712/ice1712.c +++ b/trunk/sound/pci/ice1712/ice1712.c @@ -420,7 +420,7 @@ static void snd_ice1712_set_input_clock_source(struct snd_ice1712 *ice, int spdi * Interrupt handler */ -static irqreturn_t snd_ice1712_interrupt(int irq, void *dev_id) +static irqreturn_t snd_ice1712_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct snd_ice1712 *ice = dev_id; unsigned char status; @@ -433,7 +433,7 @@ static irqreturn_t snd_ice1712_interrupt(int irq, void *dev_id) handled = 1; if (status & ICE1712_IRQ_MPU1) { if (ice->rmidi[0]) - snd_mpu401_uart_interrupt(irq, ice->rmidi[0]->private_data); + snd_mpu401_uart_interrupt(irq, ice->rmidi[0]->private_data, regs); outb(ICE1712_IRQ_MPU1, ICEREG(ice, IRQSTAT)); status &= ~ICE1712_IRQ_MPU1; } @@ -441,7 +441,7 @@ static irqreturn_t snd_ice1712_interrupt(int irq, void *dev_id) outb(ICE1712_IRQ_TIMER, ICEREG(ice, IRQSTAT)); if (status & ICE1712_IRQ_MPU2) { if (ice->rmidi[1]) - snd_mpu401_uart_interrupt(irq, ice->rmidi[1]->private_data); + snd_mpu401_uart_interrupt(irq, ice->rmidi[1]->private_data, regs); outb(ICE1712_IRQ_MPU2, ICEREG(ice, IRQSTAT)); status &= ~ICE1712_IRQ_MPU2; } diff --git a/trunk/sound/pci/ice1712/ice1724.c b/trunk/sound/pci/ice1712/ice1724.c index e9cbfdf37059..71d6aedc0749 100644 --- a/trunk/sound/pci/ice1712/ice1724.c +++ b/trunk/sound/pci/ice1712/ice1724.c @@ -218,7 +218,7 @@ static unsigned int snd_vt1724_get_gpio_data(struct snd_ice1712 *ice) * Interrupt handler */ -static irqreturn_t snd_vt1724_interrupt(int irq, void *dev_id) +static irqreturn_t snd_vt1724_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct snd_ice1712 *ice = dev_id; unsigned char status; @@ -236,7 +236,7 @@ static irqreturn_t snd_vt1724_interrupt(int irq, void *dev_id) */ if ((status & VT1724_IRQ_MPU_RX)||(status & VT1724_IRQ_MPU_TX)) { if (ice->rmidi[0]) - snd_mpu401_uart_interrupt(irq, ice->rmidi[0]->private_data); + snd_mpu401_uart_interrupt(irq, ice->rmidi[0]->private_data, regs); outb(status & (VT1724_IRQ_MPU_RX|VT1724_IRQ_MPU_TX), ICEREG1724(ice, IRQSTAT)); status &= ~(VT1724_IRQ_MPU_RX|VT1724_IRQ_MPU_TX); } diff --git a/trunk/sound/pci/intel8x0.c b/trunk/sound/pci/intel8x0.c index 9c1bce7afa86..72dbaedcbdf5 100644 --- a/trunk/sound/pci/intel8x0.c +++ b/trunk/sound/pci/intel8x0.c @@ -801,7 +801,7 @@ static inline void snd_intel8x0_update(struct intel8x0 *chip, struct ichdev *ich status & (ICH_FIFOE | ICH_BCIS | ICH_LVBCI)); } -static irqreturn_t snd_intel8x0_interrupt(int irq, void *dev_id) +static irqreturn_t snd_intel8x0_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct intel8x0 *chip = dev_id; struct ichdev *ichdev; @@ -1961,12 +1961,6 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = { .name = "Tyan Thunder K8WE", .type = AC97_TUNE_HP_ONLY }, - { - .subvendor = 0x10f7, - .subdevice = 0x834c, - .name = "Panasonic CF-R4", - .type = AC97_TUNE_HP_ONLY, - }, { .subvendor = 0x110a, .subdevice = 0x0056, @@ -2482,14 +2476,10 @@ static int intel8x0_suspend(struct pci_dev *pci, pm_message_t state) if (chip->device_type == DEVICE_INTEL_ICH4) chip->sdm_saved = igetbyte(chip, ICHREG(SDM)); - if (chip->irq >= 0) { - synchronize_irq(chip->irq); + if (chip->irq >= 0) free_irq(chip->irq, chip); - chip->irq = -1; - } pci_disable_device(pci); pci_save_state(pci); - pci_set_power_state(pci, pci_choose_state(pci, state)); return 0; } @@ -2499,22 +2489,11 @@ static int intel8x0_resume(struct pci_dev *pci) struct intel8x0 *chip = card->private_data; int i; - pci_set_power_state(pci, PCI_D0); pci_restore_state(pci); - if (pci_enable_device(pci) < 0) { - printk(KERN_ERR "intel8x0: pci_enable_device failed, " - "disabling device\n"); - snd_card_disconnect(card); - return -EIO; - } + pci_enable_device(pci); pci_set_master(pci); - if (request_irq(pci->irq, snd_intel8x0_interrupt, - IRQF_DISABLED|IRQF_SHARED, card->shortname, chip)) { - printk(KERN_ERR "intel8x0: unable to grab IRQ %d, " - "disabling device\n", pci->irq); - snd_card_disconnect(card); - return -EIO; - } + request_irq(pci->irq, snd_intel8x0_interrupt, IRQF_DISABLED|IRQF_SHARED, + card->shortname, chip); chip->irq = pci->irq; synchronize_irq(chip->irq); snd_intel8x0_chip_init(chip, 0); diff --git a/trunk/sound/pci/intel8x0m.c b/trunk/sound/pci/intel8x0m.c index bd467c501123..268e2f7241ea 100644 --- a/trunk/sound/pci/intel8x0m.c +++ b/trunk/sound/pci/intel8x0m.c @@ -511,7 +511,7 @@ static inline void snd_intel8x0_update(struct intel8x0m *chip, struct ichdev *ic iputbyte(chip, port + ichdev->roff_sr, ICH_FIFOE | ICH_BCIS | ICH_LVBCI); } -static irqreturn_t snd_intel8x0_interrupt(int irq, void *dev_id) +static irqreturn_t snd_intel8x0_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct intel8x0m *chip = dev_id; struct ichdev *ichdev; @@ -1045,14 +1045,10 @@ static int intel8x0m_suspend(struct pci_dev *pci, pm_message_t state) for (i = 0; i < chip->pcm_devs; i++) snd_pcm_suspend_all(chip->pcm[i]); snd_ac97_suspend(chip->ac97); - if (chip->irq >= 0) { - synchronize_irq(chip->irq); + if (chip->irq >= 0) free_irq(chip->irq, chip); - chip->irq = -1; - } pci_disable_device(pci); pci_save_state(pci); - pci_set_power_state(pci, pci_choose_state(pci, state)); return 0; } @@ -1061,22 +1057,11 @@ static int intel8x0m_resume(struct pci_dev *pci) struct snd_card *card = pci_get_drvdata(pci); struct intel8x0m *chip = card->private_data; - pci_set_power_state(pci, PCI_D0); pci_restore_state(pci); - if (pci_enable_device(pci) < 0) { - printk(KERN_ERR "intel8x0m: pci_enable_device failed, " - "disabling device\n"); - snd_card_disconnect(card); - return -EIO; - } + pci_enable_device(pci); pci_set_master(pci); - if (request_irq(pci->irq, snd_intel8x0_interrupt, - IRQF_DISABLED|IRQF_SHARED, card->shortname, chip)) { - printk(KERN_ERR "intel8x0m: unable to grab IRQ %d, " - "disabling device\n", pci->irq); - snd_card_disconnect(card); - return -EIO; - } + request_irq(pci->irq, snd_intel8x0_interrupt, IRQF_DISABLED|IRQF_SHARED, + card->shortname, chip); chip->irq = pci->irq; snd_intel8x0_chip_init(chip, 0); snd_ac97_resume(chip->ac97); diff --git a/trunk/sound/pci/korg1212/korg1212.c b/trunk/sound/pci/korg1212/korg1212.c index fa8cd8cecc21..cfea51f44784 100644 --- a/trunk/sound/pci/korg1212/korg1212.c +++ b/trunk/sound/pci/korg1212/korg1212.c @@ -1119,11 +1119,14 @@ static void snd_korg1212_OnDSPDownloadComplete(struct snd_korg1212 *korg1212) snd_korg1212_setCardState(korg1212, K1212_STATE_DSP_COMPLETE); } -static irqreturn_t snd_korg1212_interrupt(int irq, void *dev_id) +static irqreturn_t snd_korg1212_interrupt(int irq, void *dev_id, struct pt_regs *regs) { u32 doorbellValue; struct snd_korg1212 *korg1212 = dev_id; + if(irq != korg1212->irq) + return IRQ_NONE; + doorbellValue = readl(korg1212->inDoorbellPtr); if (!doorbellValue) @@ -1137,6 +1140,7 @@ static irqreturn_t snd_korg1212_interrupt(int irq, void *dev_id) korg1212->inIRQ++; + switch (doorbellValue) { case K1212_DB_DSPDownloadDone: K1212_DEBUG_PRINTK("K1212_DEBUG: IRQ DNLD count - %ld, %x, [%s].\n", diff --git a/trunk/sound/pci/maestro3.c b/trunk/sound/pci/maestro3.c index 8cab342bbaaf..45214b3b81be 100644 --- a/trunk/sound/pci/maestro3.c +++ b/trunk/sound/pci/maestro3.c @@ -1685,7 +1685,8 @@ static void snd_m3_update_hw_volume(unsigned long private_data) spin_unlock_irqrestore(&chip->ac97_lock, flags); } -static irqreturn_t snd_m3_interrupt(int irq, void *dev_id) +static irqreturn_t +snd_m3_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct snd_m3 *chip = dev_id; u8 status; @@ -2589,9 +2590,12 @@ static int m3_suspend(struct pci_dev *pci, pm_message_t state) chip->suspend_mem[index++] = snd_m3_assp_read(chip, MEMTYPE_INTERNAL_DATA, i); + /* power down apci registers */ + snd_m3_outw(chip, 0xffff, 0x54); + snd_m3_outw(chip, 0xffff, 0x56); + pci_disable_device(pci); pci_save_state(pci); - pci_set_power_state(pci, pci_choose_state(pci, state)); return 0; } @@ -2604,14 +2608,8 @@ static int m3_resume(struct pci_dev *pci) if (chip->suspend_mem == NULL) return 0; - pci_set_power_state(pci, PCI_D0); pci_restore_state(pci); - if (pci_enable_device(pci) < 0) { - printk(KERN_ERR "maestor3: pci_enable_device failed, " - "disabling device\n"); - snd_card_disconnect(card); - return -EIO; - } + pci_enable_device(pci); pci_set_master(pci); /* first lets just bring everything back. .*/ diff --git a/trunk/sound/pci/mixart/mixart_core.c b/trunk/sound/pci/mixart/mixart_core.c index d54457317b14..406ac3a9d42a 100644 --- a/trunk/sound/pci/mixart/mixart_core.c +++ b/trunk/sound/pci/mixart/mixart_core.c @@ -408,7 +408,7 @@ void snd_mixart_msg_tasklet(unsigned long arg) } -irqreturn_t snd_mixart_interrupt(int irq, void *dev_id) +irqreturn_t snd_mixart_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct mixart_mgr *mgr = dev_id; int err; diff --git a/trunk/sound/pci/mixart/mixart_core.h b/trunk/sound/pci/mixart/mixart_core.h index c919b734756f..1fe2bcfcc57c 100644 --- a/trunk/sound/pci/mixart/mixart_core.h +++ b/trunk/sound/pci/mixart/mixart_core.h @@ -563,7 +563,7 @@ int snd_mixart_send_msg(struct mixart_mgr *mgr, struct mixart_msg *request, int int snd_mixart_send_msg_wait_notif(struct mixart_mgr *mgr, struct mixart_msg *request, u32 notif_event); int snd_mixart_send_msg_nonblock(struct mixart_mgr *mgr, struct mixart_msg *request); -irqreturn_t snd_mixart_interrupt(int irq, void *dev_id); +irqreturn_t snd_mixart_interrupt(int irq, void *dev_id, struct pt_regs *regs); void snd_mixart_msg_tasklet(unsigned long arg); void snd_mixart_reset_board(struct mixart_mgr *mgr); diff --git a/trunk/sound/pci/nm256/nm256.c b/trunk/sound/pci/nm256/nm256.c index 945d21bf187e..101eee0aa018 100644 --- a/trunk/sound/pci/nm256/nm256.c +++ b/trunk/sound/pci/nm256/nm256.c @@ -236,7 +236,7 @@ struct nm256 { int irq; int irq_acks; - irq_handler_t interrupt; + irqreturn_t (*interrupt)(int, void *, struct pt_regs *); int badintrcount; /* counter to check bogus interrupts */ struct mutex irq_mutex; @@ -1004,7 +1004,7 @@ snd_nm256_intr_check(struct nm256 *chip) */ static irqreturn_t -snd_nm256_interrupt(int irq, void *dev_id) +snd_nm256_interrupt(int irq, void *dev_id, struct pt_regs *dummy) { struct nm256 *chip = dev_id; u16 status; @@ -1069,7 +1069,7 @@ snd_nm256_interrupt(int irq, void *dev_id) */ static irqreturn_t -snd_nm256_interrupt_zx(int irq, void *dev_id) +snd_nm256_interrupt_zx(int irq, void *dev_id, struct pt_regs *dummy) { struct nm256 *chip = dev_id; u32 status; @@ -1390,7 +1390,6 @@ static int nm256_suspend(struct pci_dev *pci, pm_message_t state) chip->coeffs_current = 0; pci_disable_device(pci); pci_save_state(pci); - pci_set_power_state(pci, pci_choose_state(pci, state)); return 0; } @@ -1402,17 +1401,8 @@ static int nm256_resume(struct pci_dev *pci) /* Perform a full reset on the hardware */ chip->in_resume = 1; - - pci_set_power_state(pci, PCI_D0); pci_restore_state(pci); - if (pci_enable_device(pci) < 0) { - printk(KERN_ERR "nm256: pci_enable_device failed, " - "disabling device\n"); - snd_card_disconnect(card); - return -EIO; - } - pci_set_master(pci); - + pci_enable_device(pci); snd_nm256_init_chip(chip); /* restore ac97 */ diff --git a/trunk/sound/pci/pcxhr/pcxhr_core.c b/trunk/sound/pci/pcxhr/pcxhr_core.c index 0ff8dc36fde3..c40f59062684 100644 --- a/trunk/sound/pci/pcxhr/pcxhr_core.c +++ b/trunk/sound/pci/pcxhr/pcxhr_core.c @@ -1131,7 +1131,7 @@ static void pcxhr_update_timer_pos(struct pcxhr_mgr *mgr, } -irqreturn_t pcxhr_interrupt(int irq, void *dev_id) +irqreturn_t pcxhr_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct pcxhr_mgr *mgr = dev_id; unsigned int reg; diff --git a/trunk/sound/pci/pcxhr/pcxhr_core.h b/trunk/sound/pci/pcxhr/pcxhr_core.h index d9a4ab609875..e7415d6d1826 100644 --- a/trunk/sound/pci/pcxhr/pcxhr_core.h +++ b/trunk/sound/pci/pcxhr/pcxhr_core.h @@ -194,7 +194,7 @@ int pcxhr_write_io_num_reg_cont(struct pcxhr_mgr *mgr, unsigned int mask, /* interrupt handling */ -irqreturn_t pcxhr_interrupt(int irq, void *dev_id); +irqreturn_t pcxhr_interrupt(int irq, void *dev_id, struct pt_regs *regs); void pcxhr_msg_tasklet(unsigned long arg); #endif /* __SOUND_PCXHR_CORE_H */ diff --git a/trunk/sound/pci/riptide/riptide.c b/trunk/sound/pci/riptide/riptide.c index 56e0c01123e7..fe210c853442 100644 --- a/trunk/sound/pci/riptide/riptide.c +++ b/trunk/sound/pci/riptide/riptide.c @@ -1178,9 +1178,9 @@ static int riptide_suspend(struct pci_dev *pci, pm_message_t state) snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); snd_pcm_suspend_all(chip->pcm); snd_ac97_suspend(chip->ac97); + pci_set_power_state(pci, PCI_D3hot); pci_disable_device(pci); pci_save_state(pci); - pci_set_power_state(pci, pci_choose_state(pci, state)); return 0; } @@ -1189,14 +1189,9 @@ static int riptide_resume(struct pci_dev *pci) struct snd_card *card = pci_get_drvdata(pci); struct snd_riptide *chip = card->private_data; - pci_set_power_state(pci, PCI_D0); pci_restore_state(pci); - if (pci_enable_device(pci) < 0) { - printk(KERN_ERR "riptide: pci_enable_device failed, " - "disabling device\n"); - snd_card_disconnect(card); - return -EIO; - } + pci_enable_device(pci); + pci_set_power_state(pci, PCI_D0); pci_set_master(pci); snd_riptide_initialize(chip); snd_ac97_resume(chip->ac97); @@ -1741,7 +1736,7 @@ snd_riptide_pcm(struct snd_riptide *chip, int device, struct snd_pcm **rpcm) } static irqreturn_t -snd_riptide_interrupt(int irq, void *dev_id) +snd_riptide_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct snd_riptide *chip = dev_id; struct cmdif *cif = chip->cif; @@ -1756,7 +1751,8 @@ snd_riptide_interrupt(int irq, void *dev_id) if (chip->rmidi && IS_MPUIRQ(cif->hwport)) { chip->handled_irqs++; snd_mpu401_uart_interrupt(irq, - chip->rmidi->private_data); + chip->rmidi->private_data, + regs); } SET_AIACK(cif->hwport); } diff --git a/trunk/sound/pci/rme32.c b/trunk/sound/pci/rme32.c index dc8d1302e22d..2a71499242fa 100644 --- a/trunk/sound/pci/rme32.c +++ b/trunk/sound/pci/rme32.c @@ -818,7 +818,8 @@ static void snd_rme32_pcm_stop(struct rme32 * rme32, int to_pause) writel(0, rme32->iobase + RME32_IO_RESET_POS); } -static irqreturn_t snd_rme32_interrupt(int irq, void *dev_id) +static irqreturn_t +snd_rme32_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct rme32 *rme32 = (struct rme32 *) dev_id; diff --git a/trunk/sound/pci/rme96.c b/trunk/sound/pci/rme96.c index 106110a89a4c..f8de7c997017 100644 --- a/trunk/sound/pci/rme96.c +++ b/trunk/sound/pci/rme96.c @@ -1117,7 +1117,8 @@ snd_rme96_capture_stop(struct rme96 *rme96) static irqreturn_t snd_rme96_interrupt(int irq, - void *dev_id) + void *dev_id, + struct pt_regs *regs) { struct rme96 *rme96 = (struct rme96 *)dev_id; diff --git a/trunk/sound/pci/rme9652/hdsp.c b/trunk/sound/pci/rme9652/hdsp.c index 694aa057ed49..d3e07de433b0 100644 --- a/trunk/sound/pci/rme9652/hdsp.c +++ b/trunk/sound/pci/rme9652/hdsp.c @@ -3603,7 +3603,7 @@ static void hdsp_midi_tasklet(unsigned long arg) snd_hdsp_midi_input_read (&hdsp->midi[1]); } -static irqreturn_t snd_hdsp_interrupt(int irq, void *dev_id) +static irqreturn_t snd_hdsp_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct hdsp *hdsp = (struct hdsp *) dev_id; unsigned int status; diff --git a/trunk/sound/pci/rme9652/hdspm.c b/trunk/sound/pci/rme9652/hdspm.c index 7055d893855d..7d03ae066d53 100644 --- a/trunk/sound/pci/rme9652/hdspm.c +++ b/trunk/sound/pci/rme9652/hdspm.c @@ -2556,7 +2556,8 @@ static int snd_hdspm_set_defaults(struct hdspm * hdspm) interupt ------------------------------------------------------------*/ -static irqreturn_t snd_hdspm_interrupt(int irq, void *dev_id) +static irqreturn_t snd_hdspm_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { struct hdspm *hdspm = (struct hdspm *) dev_id; unsigned int status; diff --git a/trunk/sound/pci/rme9652/rme9652.c b/trunk/sound/pci/rme9652/rme9652.c index cf0427b4bfde..fc15f61ad5d1 100644 --- a/trunk/sound/pci/rme9652/rme9652.c +++ b/trunk/sound/pci/rme9652/rme9652.c @@ -1882,7 +1882,7 @@ static void snd_rme9652_set_defaults(struct snd_rme9652 *rme9652) rme9652_set_rate(rme9652, 48000); } -static irqreturn_t snd_rme9652_interrupt(int irq, void *dev_id) +static irqreturn_t snd_rme9652_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct snd_rme9652 *rme9652 = (struct snd_rme9652 *) dev_id; diff --git a/trunk/sound/pci/sonicvibes.c b/trunk/sound/pci/sonicvibes.c index f9b8afabda9c..e5d4def1aa6f 100644 --- a/trunk/sound/pci/sonicvibes.c +++ b/trunk/sound/pci/sonicvibes.c @@ -580,7 +580,7 @@ static int snd_sonicvibes_trigger(struct sonicvibes * sonic, int what, int cmd) return result; } -static irqreturn_t snd_sonicvibes_interrupt(int irq, void *dev_id) +static irqreturn_t snd_sonicvibes_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct sonicvibes *sonic = dev_id; unsigned char status; @@ -601,7 +601,7 @@ static irqreturn_t snd_sonicvibes_interrupt(int irq, void *dev_id) } if (sonic->rmidi) { if (status & SV_MIDI_IRQ) - snd_mpu401_uart_interrupt(irq, sonic->rmidi->private_data); + snd_mpu401_uart_interrupt(irq, sonic->rmidi->private_data, regs); } if (status & SV_UD_IRQ) { unsigned char udreg; diff --git a/trunk/sound/pci/trident/trident_main.c b/trunk/sound/pci/trident/trident_main.c index 1fbc4321122f..ebbe12d78d8c 100644 --- a/trunk/sound/pci/trident/trident_main.c +++ b/trunk/sound/pci/trident/trident_main.c @@ -52,7 +52,8 @@ static int snd_trident_pcm_mixer_build(struct snd_trident *trident, static int snd_trident_pcm_mixer_free(struct snd_trident *trident, struct snd_trident_voice * voice, struct snd_pcm_substream *substream); -static irqreturn_t snd_trident_interrupt(int irq, void *dev_id); +static irqreturn_t snd_trident_interrupt(int irq, void *dev_id, + struct pt_regs *regs); static int snd_trident_sis_reset(struct snd_trident *trident); static void snd_trident_clear_voices(struct snd_trident * trident, @@ -3736,7 +3737,7 @@ static int snd_trident_free(struct snd_trident *trident) ---------------------------------------------------------------------------*/ -static irqreturn_t snd_trident_interrupt(int irq, void *dev_id) +static irqreturn_t snd_trident_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct snd_trident *trident = dev_id; unsigned int audio_int, chn_int, stimer, channel, mask, tmp; @@ -3824,7 +3825,7 @@ static irqreturn_t snd_trident_interrupt(int irq, void *dev_id) } if (audio_int & MPU401_IRQ) { if (trident->rmidi) { - snd_mpu401_uart_interrupt(irq, trident->rmidi->private_data); + snd_mpu401_uart_interrupt(irq, trident->rmidi->private_data, regs); } else { inb(TRID_REG(trident, T4D_MPUR0)); } @@ -3966,9 +3967,15 @@ int snd_trident_suspend(struct pci_dev *pci, pm_message_t state) snd_ac97_suspend(trident->ac97); snd_ac97_suspend(trident->ac97_sec); + switch (trident->device) { + case TRIDENT_DEVICE_ID_DX: + case TRIDENT_DEVICE_ID_NX: + break; /* TODO */ + case TRIDENT_DEVICE_ID_SI7018: + break; + } pci_disable_device(pci); pci_save_state(pci); - pci_set_power_state(pci, pci_choose_state(pci, state)); return 0; } @@ -3977,15 +3984,9 @@ int snd_trident_resume(struct pci_dev *pci) struct snd_card *card = pci_get_drvdata(pci); struct snd_trident *trident = card->private_data; - pci_set_power_state(pci, PCI_D0); pci_restore_state(pci); - if (pci_enable_device(pci) < 0) { - printk(KERN_ERR "trident: pci_enable_device failed, " - "disabling device\n"); - snd_card_disconnect(card); - return -EIO; - } - pci_set_master(pci); + pci_enable_device(pci); + pci_set_master(pci); /* to be sure */ switch (trident->device) { case TRIDENT_DEVICE_ID_DX: diff --git a/trunk/sound/pci/via82xx.c b/trunk/sound/pci/via82xx.c index 92b0736c0fdb..6db3d4cc4d8d 100644 --- a/trunk/sound/pci/via82xx.c +++ b/trunk/sound/pci/via82xx.c @@ -613,7 +613,7 @@ static void snd_via82xx_channel_reset(struct via82xx *chip, struct viadev *viade * Interrupt handler * Used for 686 and 8233A */ -static irqreturn_t snd_via686_interrupt(int irq, void *dev_id) +static irqreturn_t snd_via686_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct via82xx *chip = dev_id; unsigned int status; @@ -623,7 +623,7 @@ static irqreturn_t snd_via686_interrupt(int irq, void *dev_id) if (! (status & chip->intr_mask)) { if (chip->rmidi) /* check mpu401 interrupt */ - return snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data); + return snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data, regs); return IRQ_NONE; } @@ -659,7 +659,7 @@ static irqreturn_t snd_via686_interrupt(int irq, void *dev_id) /* * Interrupt handler */ -static irqreturn_t snd_via8233_interrupt(int irq, void *dev_id) +static irqreturn_t snd_via8233_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct via82xx *chip = dev_id; unsigned int status; @@ -2185,9 +2185,9 @@ static int snd_via82xx_suspend(struct pci_dev *pci, pm_message_t state) chip->capture_src_saved[1] = inb(chip->port + VIA_REG_CAPTURE_CHANNEL + 0x10); } + pci_set_power_state(pci, PCI_D3hot); pci_disable_device(pci); pci_save_state(pci); - pci_set_power_state(pci, pci_choose_state(pci, state)); return 0; } @@ -2197,15 +2197,9 @@ static int snd_via82xx_resume(struct pci_dev *pci) struct via82xx *chip = card->private_data; int i; - pci_set_power_state(pci, PCI_D0); pci_restore_state(pci); - if (pci_enable_device(pci) < 0) { - printk(KERN_ERR "via82xx: pci_enable_device failed, " - "disabling device\n"); - snd_card_disconnect(card); - return -EIO; - } - pci_set_master(pci); + pci_enable_device(pci); + pci_set_power_state(pci, PCI_D0); snd_via82xx_chip_init(chip); diff --git a/trunk/sound/pci/via82xx_modem.c b/trunk/sound/pci/via82xx_modem.c index feb27c966256..016f9dac253f 100644 --- a/trunk/sound/pci/via82xx_modem.c +++ b/trunk/sound/pci/via82xx_modem.c @@ -475,7 +475,7 @@ static void snd_via82xx_channel_reset(struct via82xx_modem *chip, struct viadev * Interrupt handler */ -static irqreturn_t snd_via82xx_interrupt(int irq, void *dev_id) +static irqreturn_t snd_via82xx_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct via82xx_modem *chip = dev_id; unsigned int status; @@ -1032,10 +1032,9 @@ static int snd_via82xx_suspend(struct pci_dev *pci, pm_message_t state) snd_via82xx_channel_reset(chip, &chip->devs[i]); synchronize_irq(chip->irq); snd_ac97_suspend(chip->ac97); - + pci_set_power_state(pci, PCI_D3hot); pci_disable_device(pci); pci_save_state(pci); - pci_set_power_state(pci, pci_choose_state(pci, state)); return 0; } @@ -1045,14 +1044,9 @@ static int snd_via82xx_resume(struct pci_dev *pci) struct via82xx_modem *chip = card->private_data; int i; - pci_set_power_state(pci, PCI_D0); pci_restore_state(pci); - if (pci_enable_device(pci) < 0) { - printk(KERN_ERR "via82xx-modem: pci_enable_device failed, " - "disabling device\n"); - snd_card_disconnect(card); - return -EIO; - } + pci_enable_device(pci); + pci_set_power_state(pci, PCI_D0); pci_set_master(pci); snd_via82xx_chip_init(chip); diff --git a/trunk/sound/pci/vx222/vx222.c b/trunk/sound/pci/vx222/vx222.c index af49e8aabf55..e7cd8acab59a 100644 --- a/trunk/sound/pci/vx222/vx222.c +++ b/trunk/sound/pci/vx222/vx222.c @@ -266,9 +266,9 @@ static int snd_vx222_suspend(struct pci_dev *pci, pm_message_t state) int err; err = snd_vx_suspend(&vx->core, state); + pci_set_power_state(pci, PCI_D3hot); pci_disable_device(pci); pci_save_state(pci); - pci_set_power_state(pci, pci_choose_state(pci, state)); return err; } @@ -277,14 +277,9 @@ static int snd_vx222_resume(struct pci_dev *pci) struct snd_card *card = pci_get_drvdata(pci); struct snd_vx222 *vx = card->private_data; - pci_set_power_state(pci, PCI_D0); pci_restore_state(pci); - if (pci_enable_device(pci) < 0) { - printk(KERN_ERR "vx222: pci_enable_device failed, " - "disabling device\n"); - snd_card_disconnect(card); - return -EIO; - } + pci_enable_device(pci); + pci_set_power_state(pci, PCI_D0); pci_set_master(pci); return snd_vx_resume(&vx->core); } diff --git a/trunk/sound/pci/ymfpci/ymfpci_main.c b/trunk/sound/pci/ymfpci/ymfpci_main.c index a40c1085fd20..24f6fc52f898 100644 --- a/trunk/sound/pci/ymfpci/ymfpci_main.c +++ b/trunk/sound/pci/ymfpci/ymfpci_main.c @@ -753,7 +753,7 @@ static void snd_ymfpci_irq_wait(struct snd_ymfpci *chip) } } -static irqreturn_t snd_ymfpci_interrupt(int irq, void *dev_id) +static irqreturn_t snd_ymfpci_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct snd_ymfpci *chip = dev_id; u32 status, nvoice, mode; @@ -799,7 +799,7 @@ static irqreturn_t snd_ymfpci_interrupt(int irq, void *dev_id) snd_ymfpci_writew(chip, YDSXGR_INTFLAG, status); if (chip->rawmidi) - snd_mpu401_uart_interrupt(irq, chip->rawmidi->private_data); + snd_mpu401_uart_interrupt(irq, chip->rawmidi->private_data, regs); return IRQ_HANDLED; } @@ -2218,7 +2218,6 @@ int snd_ymfpci_suspend(struct pci_dev *pci, pm_message_t state) snd_ymfpci_disable_dsp(chip); pci_disable_device(pci); pci_save_state(pci); - pci_set_power_state(pci, pci_choose_state(pci, state)); return 0; } @@ -2228,14 +2227,8 @@ int snd_ymfpci_resume(struct pci_dev *pci) struct snd_ymfpci *chip = card->private_data; unsigned int i; - pci_set_power_state(pci, PCI_D0); pci_restore_state(pci); - if (pci_enable_device(pci) < 0) { - printk(KERN_ERR "ymfpci: pci_enable_device failed, " - "disabling device\n"); - snd_card_disconnect(card); - return -EIO; - } + pci_enable_device(pci); pci_set_master(pci); snd_ymfpci_aclink_reset(pci); snd_ymfpci_codec_ready(chip, 0); diff --git a/trunk/sound/pcmcia/pdaudiocf/pdaudiocf.h b/trunk/sound/pcmcia/pdaudiocf/pdaudiocf.h index 206e2f5a113f..9a14a4f64bd3 100644 --- a/trunk/sound/pcmcia/pdaudiocf/pdaudiocf.h +++ b/trunk/sound/pcmcia/pdaudiocf/pdaudiocf.h @@ -138,7 +138,7 @@ int snd_pdacf_suspend(struct snd_pdacf *chip, pm_message_t state); int snd_pdacf_resume(struct snd_pdacf *chip); #endif int snd_pdacf_pcm_new(struct snd_pdacf *chip); -irqreturn_t pdacf_interrupt(int irq, void *dev); +irqreturn_t pdacf_interrupt(int irq, void *dev, struct pt_regs *regs); void pdacf_tasklet(unsigned long private_data); void pdacf_reinit(struct snd_pdacf *chip, int resume); diff --git a/trunk/sound/pcmcia/pdaudiocf/pdaudiocf_irq.c b/trunk/sound/pcmcia/pdaudiocf/pdaudiocf_irq.c index 5bd69206ba65..7c5f21e45cb4 100644 --- a/trunk/sound/pcmcia/pdaudiocf/pdaudiocf_irq.c +++ b/trunk/sound/pcmcia/pdaudiocf/pdaudiocf_irq.c @@ -22,12 +22,11 @@ #include #include "pdaudiocf.h" #include -#include /* * */ -irqreturn_t pdacf_interrupt(int irq, void *dev) +irqreturn_t pdacf_interrupt(int irq, void *dev, struct pt_regs *regs) { struct snd_pdacf *chip = dev; unsigned short stat; @@ -46,7 +45,7 @@ irqreturn_t pdacf_interrupt(int irq, void *dev) if (!(stat & PDAUDIOCF_IRQAKM)) stat |= PDAUDIOCF_IRQAKM; /* check rate */ } - if (get_irq_regs() != NULL) + if (regs != NULL) snd_ak4117_check_rate_and_errors(chip->ak4117, 0); return IRQ_HANDLED; } diff --git a/trunk/sound/ppc/pmac.c b/trunk/sound/ppc/pmac.c index c64af55865d4..641430631505 100644 --- a/trunk/sound/ppc/pmac.c +++ b/trunk/sound/ppc/pmac.c @@ -713,7 +713,7 @@ void snd_pmac_beep_dma_stop(struct snd_pmac *chip) * interrupt handlers */ static irqreturn_t -snd_pmac_tx_intr(int irq, void *devid) +snd_pmac_tx_intr(int irq, void *devid, struct pt_regs *regs) { struct snd_pmac *chip = devid; snd_pmac_pcm_update(chip, &chip->playback); @@ -722,7 +722,7 @@ snd_pmac_tx_intr(int irq, void *devid) static irqreturn_t -snd_pmac_rx_intr(int irq, void *devid) +snd_pmac_rx_intr(int irq, void *devid, struct pt_regs *regs) { struct snd_pmac *chip = devid; snd_pmac_pcm_update(chip, &chip->capture); @@ -731,7 +731,7 @@ snd_pmac_rx_intr(int irq, void *devid) static irqreturn_t -snd_pmac_ctrl_intr(int irq, void *devid) +snd_pmac_ctrl_intr(int irq, void *devid, struct pt_regs *regs) { struct snd_pmac *chip = devid; int ctrl = in_le32(&chip->awacs->control); diff --git a/trunk/sound/ppc/tumbler.c b/trunk/sound/ppc/tumbler.c index 2fbe1d183fce..cdff53e4a17e 100644 --- a/trunk/sound/ppc/tumbler.c +++ b/trunk/sound/ppc/tumbler.c @@ -1017,7 +1017,7 @@ static void tumbler_update_automute(struct snd_pmac *chip, int do_notify) /* interrupt - headphone plug changed */ -static irqreturn_t headphone_intr(int irq, void *devid) +static irqreturn_t headphone_intr(int irq, void *devid, struct pt_regs *regs) { struct snd_pmac *chip = devid; if (chip->update_automute && chip->initialized) { diff --git a/trunk/sound/sound_core.c b/trunk/sound/sound_core.c index 8f1ced4ab34c..5322c50c9617 100644 --- a/trunk/sound/sound_core.c +++ b/trunk/sound/sound_core.c @@ -170,8 +170,8 @@ static int sound_insert_unit(struct sound_unit **list, const struct file_operati else sprintf(s->name, "sound/%s%d", name, r / SOUND_STEP); - device_create(sound_class, dev, MKDEV(SOUND_MAJOR, s->unit_minor), - s->name+6); + class_device_create(sound_class, NULL, MKDEV(SOUND_MAJOR, s->unit_minor), + dev, s->name+6); return r; fail: @@ -193,7 +193,7 @@ static void sound_remove_unit(struct sound_unit **list, int unit) p = __sound_remove_unit(list, unit); spin_unlock(&sound_loader_lock); if (p) { - device_destroy(sound_class, MKDEV(SOUND_MAJOR, p->unit_minor)); + class_device_destroy(sound_class, MKDEV(SOUND_MAJOR, p->unit_minor)); kfree(p); } } diff --git a/trunk/sound/sparc/amd7930.c b/trunk/sound/sparc/amd7930.c index c899786f30f5..be0bd503f013 100644 --- a/trunk/sound/sparc/amd7930.c +++ b/trunk/sound/sparc/amd7930.c @@ -491,7 +491,7 @@ static void __amd7930_update_map(struct snd_amd7930 *amd) __amd7930_write_map(amd); } -static irqreturn_t snd_amd7930_interrupt(int irq, void *dev_id) +static irqreturn_t snd_amd7930_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct snd_amd7930 *amd = dev_id; unsigned int elapsed; diff --git a/trunk/sound/sparc/cs4231.c b/trunk/sound/sparc/cs4231.c index edeb3d3c4c7e..9a06c3bd6944 100644 --- a/trunk/sound/sparc/cs4231.c +++ b/trunk/sound/sparc/cs4231.c @@ -1753,7 +1753,7 @@ static int __init cs4231_attach_finish(struct snd_card *card, struct snd_cs4231 #ifdef SBUS_SUPPORT -static irqreturn_t snd_cs4231_sbus_interrupt(int irq, void *dev_id) +static irqreturn_t snd_cs4231_sbus_interrupt(int irq, void *dev_id, struct pt_regs *regs) { unsigned long flags; unsigned char status; diff --git a/trunk/sound/sparc/dbri.c b/trunk/sound/sparc/dbri.c index 4ceb09d215d8..5a97be689b40 100644 --- a/trunk/sound/sparc/dbri.c +++ b/trunk/sound/sparc/dbri.c @@ -1903,7 +1903,8 @@ static void dbri_process_interrupt_buffer(struct snd_dbri * dbri) } } -static irqreturn_t snd_dbri_interrupt(int irq, void *dev_id) +static irqreturn_t snd_dbri_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { struct snd_dbri *dbri = dev_id; static int errcnt = 0; diff --git a/trunk/sound/usb/usbaudio.c b/trunk/sound/usb/usbaudio.c index 67202b9eeb77..a42acf6d7b68 100644 --- a/trunk/sound/usb/usbaudio.c +++ b/trunk/sound/usb/usbaudio.c @@ -653,7 +653,7 @@ static struct snd_urb_ops audio_urb_ops_high_speed[2] = { /* * complete callback from data urb */ -static void snd_complete_urb(struct urb *urb) +static void snd_complete_urb(struct urb *urb, struct pt_regs *regs) { struct snd_urb_ctx *ctx = (struct snd_urb_ctx *)urb->context; struct snd_usb_substream *subs = ctx->subs; @@ -676,7 +676,7 @@ static void snd_complete_urb(struct urb *urb) /* * complete callback from sync urb */ -static void snd_complete_sync_urb(struct urb *urb) +static void snd_complete_sync_urb(struct urb *urb, struct pt_regs *regs) { struct snd_urb_ctx *ctx = (struct snd_urb_ctx *)urb->context; struct snd_usb_substream *subs = ctx->subs; @@ -1469,8 +1469,7 @@ static int snd_usb_hw_free(struct snd_pcm_substream *substream) subs->cur_audiofmt = NULL; subs->cur_rate = 0; subs->period_bytes = 0; - if (!subs->stream->chip->shutdown) - release_substream_urbs(subs, 0); + release_substream_urbs(subs, 0); return snd_pcm_free_vmalloc_buffer(substream); } diff --git a/trunk/sound/usb/usbmidi.c b/trunk/sound/usb/usbmidi.c index 24f5a26c5f0c..0dcf78adb99a 100644 --- a/trunk/sound/usb/usbmidi.c +++ b/trunk/sound/usb/usbmidi.c @@ -223,7 +223,7 @@ static void dump_urb(const char *type, const u8 *data, int length) /* * Processes the data read from the device. */ -static void snd_usbmidi_in_urb_complete(struct urb* urb) +static void snd_usbmidi_in_urb_complete(struct urb* urb, struct pt_regs *regs) { struct snd_usb_midi_in_endpoint* ep = urb->context; @@ -247,7 +247,7 @@ static void snd_usbmidi_in_urb_complete(struct urb* urb) snd_usbmidi_submit_urb(urb, GFP_ATOMIC); } -static void snd_usbmidi_out_urb_complete(struct urb* urb) +static void snd_usbmidi_out_urb_complete(struct urb* urb, struct pt_regs *regs) { struct snd_usb_midi_out_endpoint* ep = urb->context; @@ -981,7 +981,7 @@ void snd_usbmidi_disconnect(struct list_head* p) if (umidi->usb_protocol_ops->finish_out_endpoint) umidi->usb_protocol_ops->finish_out_endpoint(ep->out); } - if (ep->in) + if (ep->in && ep->in->urb) usb_kill_urb(ep->in->urb); } } diff --git a/trunk/sound/usb/usbmixer.c b/trunk/sound/usb/usbmixer.c index e74eb1bc8d87..e516d6adbb22 100644 --- a/trunk/sound/usb/usbmixer.c +++ b/trunk/sound/usb/usbmixer.c @@ -1620,7 +1620,8 @@ static void snd_usb_mixer_free(struct usb_mixer_interface *mixer) kfree(mixer->urb->transfer_buffer); usb_free_urb(mixer->urb); } - usb_free_urb(mixer->rc_urb); + if (mixer->rc_urb) + usb_free_urb(mixer->rc_urb); kfree(mixer->rc_setup_packet); kfree(mixer); } @@ -1709,7 +1710,7 @@ static void snd_usb_mixer_memory_change(struct usb_mixer_interface *mixer, } } -static void snd_usb_mixer_status_complete(struct urb *urb) +static void snd_usb_mixer_status_complete(struct urb *urb, struct pt_regs *regs) { struct usb_mixer_interface *mixer = urb->context; @@ -1771,7 +1772,8 @@ static int snd_usb_mixer_status_create(struct usb_mixer_interface *mixer) return 0; } -static void snd_usb_soundblaster_remote_complete(struct urb *urb) +static void snd_usb_soundblaster_remote_complete(struct urb *urb, + struct pt_regs *regs) { struct usb_mixer_interface *mixer = urb->context; const struct rc_config *rc = mixer->rc_cfg; @@ -2055,6 +2057,8 @@ void snd_usb_mixer_disconnect(struct list_head *p) struct usb_mixer_interface *mixer; mixer = list_entry(p, struct usb_mixer_interface, list); - usb_kill_urb(mixer->urb); - usb_kill_urb(mixer->rc_urb); + if (mixer->urb) + usb_kill_urb(mixer->urb); + if (mixer->rc_urb) + usb_kill_urb(mixer->rc_urb); } diff --git a/trunk/sound/usb/usx2y/usbusx2y.c b/trunk/sound/usb/usx2y/usbusx2y.c index e011fcacce92..cfec38d7839b 100644 --- a/trunk/sound/usb/usx2y/usbusx2y.c +++ b/trunk/sound/usb/usx2y/usbusx2y.c @@ -172,7 +172,7 @@ static void snd_usX2Y_card_private_free(struct snd_card *card); /* * pipe 4 is used for switching the lamps, setting samplerate, volumes .... */ -static void i_usX2Y_Out04Int(struct urb *urb) +static void i_usX2Y_Out04Int(struct urb *urb, struct pt_regs *regs) { #ifdef CONFIG_SND_DEBUG if (urb->status) { @@ -184,7 +184,7 @@ static void i_usX2Y_Out04Int(struct urb *urb) #endif } -static void i_usX2Y_In04Int(struct urb *urb) +static void i_usX2Y_In04Int(struct urb *urb, struct pt_regs *regs) { int err = 0; struct usX2Ydev *usX2Y = urb->context; diff --git a/trunk/sound/usb/usx2y/usbusx2yaudio.c b/trunk/sound/usb/usx2y/usbusx2yaudio.c index 367f8a32a665..f6bd0dee563c 100644 --- a/trunk/sound/usb/usx2y/usbusx2yaudio.c +++ b/trunk/sound/usb/usx2y/usbusx2yaudio.c @@ -306,7 +306,7 @@ static void usX2Y_error_sequence(struct usX2Ydev *usX2Y, usX2Y_clients_stop(usX2Y); } -static void i_usX2Y_urb_complete(struct urb *urb) +static void i_usX2Y_urb_complete(struct urb *urb, struct pt_regs *regs) { struct snd_usX2Y_substream *subs = urb->context; struct usX2Ydev *usX2Y = subs->usX2Y; @@ -322,7 +322,7 @@ static void i_usX2Y_urb_complete(struct urb *urb) usX2Y_error_urb_status(usX2Y, subs, urb); return; } - if (likely(urb->start_frame == usX2Y->wait_iso_frame)) + if (likely((0xFFFF & urb->start_frame) == usX2Y->wait_iso_frame)) subs->completed_urb = urb; else { usX2Y_error_sequence(usX2Y, subs, urb); @@ -335,9 +335,13 @@ static void i_usX2Y_urb_complete(struct urb *urb) atomic_read(&capsubs->state) >= state_PREPARED && (playbacksubs->completed_urb || atomic_read(&playbacksubs->state) < state_PREPARED)) { - if (!usX2Y_usbframe_complete(capsubs, playbacksubs, urb->start_frame)) - usX2Y->wait_iso_frame += nr_of_packs(); - else { + if (!usX2Y_usbframe_complete(capsubs, playbacksubs, urb->start_frame)) { + if (nr_of_packs() <= urb->start_frame && + urb->start_frame <= (2 * nr_of_packs() - 1)) // uhci and ohci + usX2Y->wait_iso_frame = urb->start_frame - nr_of_packs(); + else + usX2Y->wait_iso_frame += nr_of_packs(); + } else { snd_printdd("\n"); usX2Y_clients_stop(usX2Y); } @@ -346,7 +350,7 @@ static void i_usX2Y_urb_complete(struct urb *urb) } static void usX2Y_urbs_set_complete(struct usX2Ydev * usX2Y, - void (*complete)(struct urb *)) + void (*complete)(struct urb *, struct pt_regs *)) { int s, u; for (s = 0; s < 4; s++) { @@ -366,7 +370,7 @@ static void usX2Y_subs_startup_finish(struct usX2Ydev * usX2Y) usX2Y->prepare_subs = NULL; } -static void i_usX2Y_subs_startup(struct urb *urb) +static void i_usX2Y_subs_startup(struct urb *urb, struct pt_regs *regs) { struct snd_usX2Y_substream *subs = urb->context; struct usX2Ydev *usX2Y = subs->usX2Y; @@ -378,7 +382,7 @@ static void i_usX2Y_subs_startup(struct urb *urb) wake_up(&usX2Y->prepare_wait_queue); } - i_usX2Y_urb_complete(urb); + i_usX2Y_urb_complete(urb, regs); } static void usX2Y_subs_prepare(struct snd_usX2Y_substream *subs) @@ -491,6 +495,7 @@ static int usX2Y_urbs_start(struct snd_usX2Y_substream *subs) if (subs != NULL && atomic_read(&subs->state) >= state_PREPARED) goto start; } + usX2Y->wait_iso_frame = -1; start: usX2Y_subs_startup(subs); @@ -511,9 +516,10 @@ static int usX2Y_urbs_start(struct snd_usX2Y_substream *subs) snd_printk (KERN_ERR "cannot submit datapipe for urb %d, err = %d\n", i, err); err = -EPIPE; goto cleanup; - } else - if (i == 0) + } else { + if (0 > usX2Y->wait_iso_frame) usX2Y->wait_iso_frame = urb->start_frame; + } urb->transfer_flags = 0; } else { atomic_set(&subs->state, state_STARTING1); @@ -657,7 +663,7 @@ static struct s_c2 SetRate48000[] = }; #define NOOF_SETRATE_URBS ARRAY_SIZE(SetRate48000) -static void i_usX2Y_04Int(struct urb *urb) +static void i_usX2Y_04Int(struct urb *urb, struct pt_regs *regs) { struct usX2Ydev *usX2Y = urb->context; diff --git a/trunk/sound/usb/usx2y/usx2yhwdeppcm.c b/trunk/sound/usb/usx2y/usx2yhwdeppcm.c index 8f3e35e24e72..88b72b52590f 100644 --- a/trunk/sound/usb/usx2y/usx2yhwdeppcm.c +++ b/trunk/sound/usb/usx2y/usx2yhwdeppcm.c @@ -226,7 +226,7 @@ static inline int usX2Y_usbpcm_usbframe_complete(struct snd_usX2Y_substream *cap } -static void i_usX2Y_usbpcm_urb_complete(struct urb *urb) +static void i_usX2Y_usbpcm_urb_complete(struct urb *urb, struct pt_regs *regs) { struct snd_usX2Y_substream *subs = urb->context; struct usX2Ydev *usX2Y = subs->usX2Y; @@ -243,7 +243,7 @@ static void i_usX2Y_usbpcm_urb_complete(struct urb *urb) usX2Y_error_urb_status(usX2Y, subs, urb); return; } - if (likely(urb->start_frame == usX2Y->wait_iso_frame)) + if (likely((0xFFFF & urb->start_frame) == usX2Y->wait_iso_frame)) subs->completed_urb = urb; else { usX2Y_error_sequence(usX2Y, subs, urb); @@ -256,9 +256,13 @@ static void i_usX2Y_usbpcm_urb_complete(struct urb *urb) if (capsubs->completed_urb && atomic_read(&capsubs->state) >= state_PREPARED && (NULL == capsubs2 || capsubs2->completed_urb) && (playbacksubs->completed_urb || atomic_read(&playbacksubs->state) < state_PREPARED)) { - if (!usX2Y_usbpcm_usbframe_complete(capsubs, capsubs2, playbacksubs, urb->start_frame)) - usX2Y->wait_iso_frame += nr_of_packs(); - else { + if (!usX2Y_usbpcm_usbframe_complete(capsubs, capsubs2, playbacksubs, urb->start_frame)) { + if (nr_of_packs() <= urb->start_frame && + urb->start_frame <= (2 * nr_of_packs() - 1)) // uhci and ohci + usX2Y->wait_iso_frame = urb->start_frame - nr_of_packs(); + else + usX2Y->wait_iso_frame += nr_of_packs(); + } else { snd_printdd("\n"); usX2Y_clients_stop(usX2Y); } @@ -290,7 +294,7 @@ static void usX2Y_usbpcm_subs_startup_finish(struct usX2Ydev * usX2Y) usX2Y->prepare_subs = NULL; } -static void i_usX2Y_usbpcm_subs_startup(struct urb *urb) +static void i_usX2Y_usbpcm_subs_startup(struct urb *urb, struct pt_regs *regs) { struct snd_usX2Y_substream *subs = urb->context; struct usX2Ydev *usX2Y = subs->usX2Y; @@ -307,7 +311,7 @@ static void i_usX2Y_usbpcm_subs_startup(struct urb *urb) wake_up(&usX2Y->prepare_wait_queue); } - i_usX2Y_usbpcm_urb_complete(urb); + i_usX2Y_usbpcm_urb_complete(urb, regs); } /* @@ -429,6 +433,7 @@ static int usX2Y_usbpcm_urbs_start(struct snd_usX2Y_substream *subs) if (subs != NULL && atomic_read(&subs->state) >= state_PREPARED) goto start; } + usX2Y->wait_iso_frame = -1; start: usX2Y_usbpcm_subs_startup(subs); @@ -454,7 +459,7 @@ static int usX2Y_usbpcm_urbs_start(struct snd_usX2Y_substream *subs) goto cleanup; } else { snd_printdd("%i\n", urb->start_frame); - if (u == 0) + if (0 > usX2Y->wait_iso_frame) usX2Y->wait_iso_frame = urb->start_frame; } urb->transfer_flags = 0; @@ -627,7 +632,7 @@ static int usX2Y_pcms_lock_check(struct snd_card *card) for (s = 0; s < 2; ++s) { struct snd_pcm_substream *substream; substream = pcm->streams[s].substream; - if (substream && SUBSTREAM_BUSY(substream)) + if (SUBSTREAM_BUSY(substream)) err = -EBUSY; } } diff --git a/trunk/usr/Makefile b/trunk/usr/Makefile index 382702ad663b..e338e7bedb29 100644 --- a/trunk/usr/Makefile +++ b/trunk/usr/Makefile @@ -20,7 +20,7 @@ $(obj)/initramfs_data.o: $(obj)/initramfs_data.cpio.gz FORCE hostprogs-y := gen_init_cpio initramfs := $(CONFIG_SHELL) $(srctree)/scripts/gen_initramfs_list.sh ramfs-input := $(if $(filter-out "",$(CONFIG_INITRAMFS_SOURCE)), \ - $(shell echo $(CONFIG_INITRAMFS_SOURCE)),-d) + $(CONFIG_INITRAMFS_SOURCE),-d) ramfs-args := \ $(if $(CONFIG_INITRAMFS_ROOT_UID), -u $(CONFIG_INITRAMFS_ROOT_UID)) \ $(if $(CONFIG_INITRAMFS_ROOT_GID), -g $(CONFIG_INITRAMFS_ROOT_GID))